summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <lars.wirzenius@codethink.co.uk>2012-02-15 16:36:06 +0000
committerLars Wirzenius <lars.wirzenius@codethink.co.uk>2012-02-16 20:30:10 +0000
commit370588a06395f5c90c8fab115cb9748be105d664 (patch)
treece06c015c0b71bef4176e567161860b9515dad35
parent1587e1a66564c29ee206758e27a1fbddf8c1f5d5 (diff)
downloadmorph-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-xmorph34
-rw-r--r--morphlib/builder.py31
2 files changed, 53 insertions, 12 deletions
diff --git a/morph b/morph
index c3ac7c1d..5cbb40f6 100755
--- a/morph
+++ b/morph
@@ -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)