diff options
author | Lars Wirzenius <lars.wirzenius@codethink.co.uk> | 2012-02-15 16:36:06 +0000 |
---|---|---|
committer | Lars Wirzenius <lars.wirzenius@codethink.co.uk> | 2012-02-16 20:30:10 +0000 |
commit | 370588a06395f5c90c8fab115cb9748be105d664 (patch) | |
tree | ce06c015c0b71bef4176e567161860b9515dad35 | |
parent | 1587e1a66564c29ee206758e27a1fbddf8c1f5d5 (diff) | |
download | morph-370588a06395f5c90c8fab115cb9748be105d664.tar.gz |
Build non-bootstrap chunks inside a staging chroot
This adds options --staging-filler and --staging-chroot.
The wisdom of these options needs to be re-considered at
some point, but for now they're OK.
-rwxr-xr-x | morph | 34 | ||||
-rw-r--r-- | morphlib/builder.py | 31 |
2 files changed, 53 insertions, 12 deletions
@@ -65,6 +65,16 @@ class Morph(cliapp.Application): 'do not cache repositories of submodules and ' 'unpack them into the build directory') + self.settings.string_list(['staging-filler'], + 'unpack BLOB into staging area for ' + 'non-bootstrap builds (this will ' + 'eventually be replaced with proper ' + 'build dependencies)', + metavar='BLOB') + self.settings.boolean(['staging-chroot'], + 'build things in a staging chroot ' + '(require real root to use)') + self.settings.boolean(['test-console'], 'show what the system outputs on the serial ' 'console during tests') @@ -94,17 +104,25 @@ class Morph(cliapp.Application): ''' - tempdir = morphlib.tempdir.Tempdir(self.settings['tempdir']) - morph_loader = MorphologyLoader(self.settings) - source_manager = morphlib.sourcemanager.SourceManager(self) - builder = morphlib.builder.Builder(tempdir, self, morph_loader, - source_manager) if not os.path.exists(self.settings['cachedir']): os.mkdir(self.settings['cachedir']) ret = [] while len(args) >= 3: + tempdir = morphlib.tempdir.Tempdir(self.settings['tempdir']) + morph_loader = MorphologyLoader(self.settings) + source_manager = morphlib.sourcemanager.SourceManager(self) + builder = morphlib.builder.Builder(tempdir, self, morph_loader, + source_manager) + + # Unpack manually specified build dependencies. + staging = tempdir.join('staging') + os.mkdir(staging) + ex = morphlib.execute.Execute('/', self.msg) + for bin in self.settings['staging-filler']: + morphlib.bins.unpack_binary(bin, staging, ex) + repo, ref, filename = args[:3] args = args[3:] @@ -119,9 +137,9 @@ class Morph(cliapp.Application): # build things in this order ret.append(builder.build(blobs, order)) - # we may not have permission to tempdir.remove() - ex = morphlib.execute.Execute('.', lambda msg: None) - ex.runv(["rm", "-rf", tempdir.dirname]) + # we may not have permission to tempdir.remove() + ex = morphlib.execute.Execute('.', lambda msg: None) + ex.runv(["rm", "-rf", tempdir.dirname]) if args: raise cliapp.AppException('Extra args on command line: %s' % args) diff --git a/morphlib/builder.py b/morphlib/builder.py index 53b330d0..e93c8e79 100644 --- a/morphlib/builder.py +++ b/morphlib/builder.py @@ -362,7 +362,7 @@ class ChunkBuilder(BlobBuilder): def run_in_parallel(self, what, commands): self.msg('commands: %s' % what) with self.build_watch(what): - self.ex.run(commands) + self.run_commands(commands) def run_sequentially(self, what, commands): self.msg ('commands: %s' % what) @@ -370,10 +370,32 @@ class ChunkBuilder(BlobBuilder): flags = self.ex.env['MAKEFLAGS'] self.ex.env['MAKEFLAGS'] = '-j1' logging.debug('Setting MAKEFLAGS=%s' % self.ex.env['MAKEFLAGS']) - self.ex.run(commands) + self.run_commands(commands) self.ex.env['MAKEFLAGS'] = flags logging.debug('Restore MAKEFLAGS=%s' % self.ex.env['MAKEFLAGS']) + def run_commands(self, commands): + if self.settings['staging-chroot']: + ex = morphlib.execute.Execute(self.staging, self.msg) + ex.env.clear() + for key in self.ex.env: + ex.env[key] = self.ex.env[key] + assert self.builddir.startswith(self.staging + '/') + builddir = self.builddir[len(self.staging):] + for cmd in commands: + script = os.path.join(self.staging, 'temp.sh') + with open(script, 'w') as f: + f.write('#!/bin/sh\n') + f.write('set -ex\n') + f.write('cd %s\n' % builddir) + f.write('%s\n' % cmd) + os.chmod(script, 0555) + chroot_cmd = '/usr/sbin/chroot %s ./temp.sh' % self.staging + ex.run([chroot_cmd]) + os.remove(script) + else: + self.ex.run(commands) + def create_chunks(self): chunks = [] with self.build_watch('create-chunks'): @@ -657,9 +679,10 @@ class Builder(object): logging.debug('cache id: %s' % repr(cache_id)) self.dump_memory_profile('after computing cache id') - builder.builddir = self.tempdir.join('%s.build' % blob.morph.name) - builder.destdir = self.tempdir.join('%s.inst' % blob.morph.name) builder.staging = self.tempdir.join('staging') + s = builder.staging + builder.builddir = os.path.join(s, '%s.build' % blob.morph.name) + builder.destdir = os.path.join(s, '%s.inst' % blob.morph.name) builder.settings = self.settings builder.real_msg = self.msg builder.cache_prefix = self.cachedir.name(cache_id) |