summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2011-12-08 08:33:37 +0000
committerRichard Maw <richard.maw@codethink.co.uk>2011-12-08 09:56:29 +0000
commit007f2e556796f749ab24d79106cd0f1da46b00c3 (patch)
treee80221342522d9f5b0d7ab361143004461d06965
parent38d6f5c1b3cb4890d105fdda07f87e0f78522e21 (diff)
downloadmorph-007f2e556796f749ab24d79106cd0f1da46b00c3.tar.gz
Make the install parts of morphs run as sudo
Then fix all the places where this broke things because they didn't have the required permissions. This is a potential security risk of course, it would be preferable if the install commands were run in a fakeroot session and only the final image building was run as root, but it needs to work first
-rwxr-xr-xmorph4
-rw-r--r--morphlib/bins.py9
-rw-r--r--morphlib/builder.py21
-rw-r--r--morphlib/execute.py8
4 files changed, 31 insertions, 11 deletions
diff --git a/morph b/morph
index eda5cf58..562e6d4a 100755
--- a/morph
+++ b/morph
@@ -68,7 +68,9 @@ class Morph(cliapp.Application):
self.msg('Building %s - %s - %s' % (repo, ref, filename))
builder.build(repo, ref, filename)
- tempdir.remove()
+ # we may not have permission to tempdir.remove()
+ ex = morphlib.execute.Execute('.', lambda msg: None)
+ ex.runv(["rm", "-rf", tempdir.dirname], as_root=True)
if args:
raise cliapp.AppException('Extra args on command line: %s' % args)
diff --git a/morphlib/bins.py b/morphlib/bins.py
index d8cbf8e0..2fbe6d98 100644
--- a/morphlib/bins.py
+++ b/morphlib/bins.py
@@ -95,9 +95,11 @@ def create_chunk(rootdir, chunk_filename, regexps, dump_memory_profile=None):
for filename in reversed(include):
if os.path.isdir(filename) and not os.path.islink(filename):
if not os.listdir(filename):
- os.rmdir(filename)
+ #os.rmdir(filename) doesn't have permission
+ ex.runv(['rmdir', filename], as_root=True)
else:
- os.remove(filename)
+ #os.remove(filename) doesn't have permission
+ ex.runv(['rm', filename], as_root=True)
dump_memory_profile('after removing in create_chunks')
@@ -118,5 +120,6 @@ def unpack_binary(filename, dirname):
logging.debug('Unpacking %s into %s' % (filename, dirname))
ex = morphlib.execute.Execute(dirname, msg=lambda s: None)
- ex.runv(['tar', '-xvf', filename])
+ # tar must be run as root, as it is creating a real image now
+ ex.runv(['tar', '-xvf', filename], as_root=True)
diff --git a/morphlib/builder.py b/morphlib/builder.py
index 734ef171..938b3207 100644
--- a/morphlib/builder.py
+++ b/morphlib/builder.py
@@ -76,7 +76,12 @@ class BinaryBlob(object):
dirname = os.path.join(self.destdir, 'baserock')
filename = os.path.join(dirname, '%s.meta' % blob_name)
if not os.path.exists(dirname):
- os.mkdir(dirname)
+ # os.mkdir(dirname) won't work as we may not have permission
+ # so run a shell command as root to do it
+ ex = morphlib.execute.Execute(self.builddir, self.msg)
+ ex.runv(['install', '--directory', '--mode=777', dirname],
+ as_root=True)
+
with open(filename, 'w') as f:
json.dump(meta, f, indent=4)
f.write('\n')
@@ -228,7 +233,7 @@ class Chunk(BinaryBlob):
self.run_in_parallel('build', bs['build-commands'])
self.run_sequentially('test', bs['test-commands'])
self.run_sequentially('install', bs['install-commands'],
- as_fakeroot=True)
+ as_root=True)
def build_using_commands(self):
self.msg('Building using explicit commands')
@@ -236,7 +241,7 @@ class Chunk(BinaryBlob):
self.run_in_parallel('build', self.morph.build_commands)
self.run_sequentially('test', self.morph.test_commands)
self.run_sequentially('install', self.morph.install_commands,
- as_fakeroot=True)
+ as_root=True)
def run_in_parallel(self, what, commands):
self.msg('commands: %s' % what)
@@ -244,13 +249,13 @@ class Chunk(BinaryBlob):
self.ex.run(commands)
self.build_watch.stop(what)
- def run_sequentially(self, what, commands, as_fakeroot=False):
+ def run_sequentially(self, what, commands, as_fakeroot=False, as_root=False):
self.msg ('commands: %s' % what)
self.build_watch.start(what)
flags = self.ex.env['MAKEFLAGS']
self.ex.env['MAKEFLAGS'] = '-j1'
logging.debug('Setting MAKEFLAGS=%s' % self.ex.env['MAKEFLAGS'])
- self.ex.run(commands, as_fakeroot=as_fakeroot)
+ self.ex.run(commands, as_fakeroot=as_fakeroot, as_root=as_root)
self.ex.env['MAKEFLAGS'] = flags
logging.debug('Restore MAKEFLAGS=%s' % self.ex.env['MAKEFLAGS'])
self.build_watch.stop(what)
@@ -373,6 +378,12 @@ class System(BinaryBlob):
as_root=True)
self.build_watch.stop('unpack-strata')
+ # horrible hack to make sure we can write to fstab as any of
+ # the strata could have created /etc, only fhs-dirs creates it
+ # with the good permission
+ self.ex.runv(['chmod', 'a=rwx', self.tempdir.join('mnt/etc/')],
+ as_root=True)
+
# Create fstab.
self.build_watch.start('create-fstab')
fstab = self.tempdir.join('mnt/etc/fstab')
diff --git a/morphlib/execute.py b/morphlib/execute.py
index afad1317..f4cb2b94 100644
--- a/morphlib/execute.py
+++ b/morphlib/execute.py
@@ -55,7 +55,9 @@ class Execute(object):
self.msg('# %s' % command)
argv = ['sh', '-c', command]
if as_root:
- argv = ['sudo'] + argv # pragma: no cover
+ argv = (['sudo'] +
+ ["%s=%s" % x for x in self.env.iteritems()] +
+ argv) # pragma: no cover
elif as_fakeroot:
argv = ['fakeroot'] + argv
logging.debug('run: argv=%s' % repr(argv))
@@ -85,7 +87,9 @@ class Execute(object):
'''
if as_root:
- argv = ['sudo'] + argv # pragma: no cover
+ argv = (['sudo'] +
+ ["%s=%s" % x for x in self.env.iteritems()] +
+ argv) # pragma: no cover
elif as_fakeroot:
argv = ['fakeroot'] + argv
logging.debug('runv: argv=%s' % repr(argv))