From a2634251b06bdf0b917d21b458e868722de7c541 Mon Sep 17 00:00:00 2001 From: Richard Maw Date: Thu, 8 Dec 2011 15:06:01 +0000 Subject: Made some sudo commands into fakeroot commands Some commands can remain as fakeroot if they share the same fakeroot This can be done with the -i and -s parameters to fakeroot Now the Execute objects contain a reference to the file that stores their state, so fake commands' fake state is recognised by later commands The creating a system image definitely needs to be sudo though. Morph needs to create some files as part of the process, so unfortunately the equivalent to 'echo foo | sudo tee bar >/dev/null' is being used. They could be created with sufficient permissions, written then have better permissions set, but it seemed neater this way A better solution may be to have a subprogram that does the system image creation Putting files into the staging area for building other chunks is currently sudo, but shouldn't have to be. Rather than having a fakeroot per Execute object, it may be better to have a global one, though this would prevent concurrent use of fakeroot. --- morphlib/builder.py | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) (limited to 'morphlib/builder.py') diff --git a/morphlib/builder.py b/morphlib/builder.py index 938b3207..26693ac7 100644 --- a/morphlib/builder.py +++ b/morphlib/builder.py @@ -76,11 +76,7 @@ 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) 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) + os.mkdir(dirname) with open(filename, 'w') as f: json.dump(meta, f, indent=4) @@ -233,7 +229,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_root=True) + as_fakeroot=True) def build_using_commands(self): self.msg('Building using explicit commands') @@ -241,7 +237,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_root=True) + as_fakeroot=True) def run_in_parallel(self, what, commands): self.msg('commands: %s' % what) @@ -271,7 +267,7 @@ class Chunk(BinaryBlob): filename = self.filename(chunk_name) self.msg('Creating binary for %s' % chunk_name) morphlib.bins.create_chunk(self.destdir, filename, patterns, - self.dump_memory_profile) + self.ex, self.dump_memory_profile) ret[chunk_name] = filename self.build_watch.stop('create-chunks') files = os.listdir(self.destdir) @@ -298,16 +294,18 @@ class Stratum(BinaryBlob): def build(self): os.mkdir(self.destdir) + ex = morphlib.execute.Execute(self.destdir, self.msg) self.build_watch.start('unpack-chunks') for chunk_name, filename in self.built: self.msg('Unpacking chunk %s' % chunk_name) - morphlib.bins.unpack_binary(filename, self.destdir) + morphlib.bins.unpack_binary(filename, self.destdir, ex, + as_fakeroot=True) self.build_watch.stop('unpack-chunks') self.prepare_binary_metadata(self.morph.name) self.build_watch.start('create-binary') self.msg('Creating binary for %s' % self.morph.name) filename = self.filename(self.morph.name) - morphlib.bins.create_stratum(self.destdir, filename) + morphlib.bins.create_stratum(self.destdir, filename, ex) self.build_watch.stop('create-binary') return { self.morph.name: filename } @@ -378,35 +376,29 @@ 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') - with open(fstab, 'w') as f: - f.write('proc /proc proc defaults 0 0\n') - f.write('sysfs /sys sysfs defaults 0 0\n') - f.write('/dev/sda1 / ext4 errors=remount-ro 0 1\n') + # sorry about the hack, I wish I knew a better way + self.ex.runv(['tee', fstab], feed_stdin=''' +proc /proc proc defaults 0 0 +sysfs /sys sysfs defaults 0 0 +/dev/sda1 / ext4 errors=remount-ro 0 1 +''', as_root=True, stdout=open(os.devnull,'w')) self.build_watch.stop('create-fstab') # Install extlinux bootloader. self.build_watch.start('install-bootloader') conf = os.path.join(mount_point, 'extlinux.conf') logging.debug('configure extlinux %s' % conf) - f = open(conf, 'w') - f.write(''' + self.ex.runv(['tee', conf], feed_stdin=''' default linux timeout 1 label linux kernel /vmlinuz append root=/dev/sda1 init=/bin/sh quiet rw -''') - f.close() +''', as_root=True, stdout=open(os.devnull, 'w')) self.ex.runv(['extlinux', '--install', mount_point], as_root=True) @@ -557,10 +549,13 @@ class Builder(object): return if self.settings['bootstrap']: self.msg('Unpacking chunk %s onto system' % chunk_name) - morphlib.bins.unpack_binary(chunk_filename, '/') + ex = morphlib.execute.Execute('/', self.msg) + morphlib.bins.unpack_binary(chunk_filename, '/', ex, as_root=True) else: self.msg('Unpacking chunk %s into staging' % chunk_name) - morphlib.bins.unpack_binary(chunk_filename, staging_dir) + ex = morphlib.execute.Execute(staging_dir, self.msg) + morphlib.bins.unpack_binary(chunk_filename, staging_dir, ex, + as_root=True) def complete_dict_key(self, dict_key, name, repo, ref): '''Fill in default fields of a cache's dict key.''' -- cgit v1.2.1