diff options
author | Paul Sherwood <paul.sherwood@codethink.co.uk> | 2014-10-27 13:28:53 +0000 |
---|---|---|
committer | Paul Sherwood <paul.sherwood@codethink.co.uk> | 2014-10-27 13:28:53 +0000 |
commit | 79c06711f47d39bdff6d84c2736d88b99ef35b9c (patch) | |
tree | 4a0774f36f9034d8d3a1d7f4d010fad7a80f2cd8 /morphlib/builder2.py | |
parent | ee8b0047ae5a5e7c64f32197cdf20d552a49cd9e (diff) | |
parent | 5e823a4f36f30c59a473f22f824dfd6f6c66c89f (diff) | |
download | morph-79c06711f47d39bdff6d84c2736d88b99ef35b9c.tar.gz |
Merge branch 'master' of git://git.baserock.org/baserock/baserock/morph into HEAD
Diffstat (limited to 'morphlib/builder2.py')
-rw-r--r-- | morphlib/builder2.py | 80 |
1 files changed, 56 insertions, 24 deletions
diff --git a/morphlib/builder2.py b/morphlib/builder2.py index 9cd3a074..8615ed59 100644 --- a/morphlib/builder2.py +++ b/morphlib/builder2.py @@ -28,6 +28,7 @@ import time import traceback import subprocess import tempfile +import textwrap import gzip import cliapp @@ -341,6 +342,7 @@ class ChunkBuilder(BuilderBase): relative_builddir = self.staging_area.relative(builddir) relative_destdir = self.staging_area.relative(destdir) + ccache_dir = self.staging_area.ccache_dir(self.source) extra_env = { 'DESTDIR': relative_destdir } steps = [ @@ -390,7 +392,8 @@ class ChunkBuilder(BuilderBase): cwd=relative_builddir, stdout=stdout or subprocess.PIPE, stderr=subprocess.STDOUT, - logfile=logfilepath) + logfile=logfilepath, + ccache_dir=ccache_dir) if stdout: stdout.flush() @@ -644,6 +647,53 @@ class SystemBuilder(BuilderBase): # pragma: no cover os.chmod(os_release_file, 0644) + def _chroot_runcmd(self, rootdir, to_mount, env, *args): + # We need to do mounts in a different namespace. Unfortunately + # this means we have to in-line the mount commands in the + # command-line. + command = textwrap.dedent(r''' + mount --make-rprivate / + rootdir="$1" + shift + ''') + cmdargs = [rootdir] + + # We need to mount all the specified mounts in the namespace, + # we don't need to unmount them before exiting, as they'll be + # unmounted when the namespace is no longer used. + command += textwrap.dedent(r''' + while true; do + case "$1" in + --) + shift + break + ;; + *) + mount_point="$1" + mount_type="$2" + mount_source="$3" + shift 3 + path="$rootdir/$mount_point" + mount -t "$mount_type" "$mount_source" "$path" + ;; + esac + done + ''') + for mount_opts in to_mount: + cmdargs.extend(mount_opts) + cmdargs.append('--') + + command += textwrap.dedent(r''' + exec chroot "$rootdir" "$@" + ''') + cmdargs.extend(args) + + # The single - is just a shell convention to fill $0 when using -c, + # since ordinarily $0 contains the program name. + cmdline = ['unshare', '--mount', '--', 'sh', '-ec', command, '-'] + cmdline.extend(cmdargs) + self.app.runcmd(cmdline, env=env) + def run_system_integration_commands(self, rootdir): # pragma: no cover ''' Run the system integration commands ''' @@ -655,44 +705,26 @@ class SystemBuilder(BuilderBase): # pragma: no cover 'PATH': '/bin:/usr/bin:/sbin:/usr/sbin' } - self.app.status(msg='Running the system integration commands', - error=True) + self.app.status(msg='Running the system integration commands') - mounted = [] to_mount = ( ('proc', 'proc', 'none'), ('dev/shm', 'tmpfs', 'none'), + ('tmp', 'tmpfs', 'none'), ) - try: for mount_point, mount_type, source in to_mount: - logging.debug('Mounting %s in system root filesystem' - % mount_point) path = os.path.join(rootdir, mount_point) if not os.path.exists(path): os.makedirs(path) - morphlib.fsutils.mount(self.app.runcmd, source, path, - mount_type) - mounted.append(path) - - # The single - is just a shell convention to fill $0 when using -c, - # since ordinarily $0 contains the program name. - # -- is used to indicate the end of options for run-parts, - # we don't want SYSTEM_INTEGRATION_PATH to be interpreted - # as an option if it happens to begin with a - - self.app.runcmd(['chroot', rootdir, 'sh', '-c', - 'cd / && run-parts -- "$1"', '-', SYSTEM_INTEGRATION_PATH], - env=env) + for bin in sorted(os.listdir(sys_integration_dir)): + self._chroot_runcmd(rootdir, to_mount, env, + os.path.join(SYSTEM_INTEGRATION_PATH, bin)) except BaseException, e: self.app.status( msg='Error while running system integration commands', error=True) raise - finally: - for mount_path in reversed(mounted): - logging.debug('Unmounting %s in system root filesystem' - % mount_path) - morphlib.fsutils.unmount(self.app.runcmd, mount_path) class Builder(object): # pragma: no cover |