summaryrefslogtreecommitdiff
path: root/morphlib/stagingarea.py
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2013-02-22 19:07:13 +0000
committerSam Thursfield <sam.thursfield@codethink.co.uk>2013-03-13 15:20:02 +0000
commitece7f823de6bd61a0676edf71a9525697848824e (patch)
tree98c408d5960915f0cb5b98a941e2dc6508047f8b /morphlib/stagingarea.py
parent6a61dd9cc1fe8a3ccd2128fb628ed929fd496ad0 (diff)
downloadmorph-ece7f823de6bd61a0676edf71a9525697848824e.tar.gz
Refactor build process
Reorganise the build_artifact() and build_artifacts() functions to allow more complex work when setting up chunk builds in build_artifact(). The staging area now holds the BuildEnvironment object (the environment variables that should be set during build). This makes sense because all build commands should be run inside the staging area and therefore through the StagingArea object. The BuildEnvironment object is now considered immutable after it is created. The environment is used in cache key computation when computing what artifacts are required; if it changes after that point we risk either computing different artifact keys for the same artifact or missing data in the cache key that should be included in the hash. Better to force changes into a separate 'extra_env' variable.
Diffstat (limited to 'morphlib/stagingarea.py')
-rw-r--r--morphlib/stagingarea.py52
1 files changed, 36 insertions, 16 deletions
diff --git a/morphlib/stagingarea.py b/morphlib/stagingarea.py
index 24d4ebf9..ee3e444f 100644
--- a/morphlib/stagingarea.py
+++ b/morphlib/stagingarea.py
@@ -35,7 +35,9 @@ class StagingArea(object):
'''
- def __init__(self, app, dirname):
+ _base_path = ['/sbin', '/usr/sbin', '/bin', '/usr/bin']
+
+ def __init__(self, app, dirname, build_env, use_chroot=True, extra_env={}):
self._app = app
self.dirname = dirname
self.builddirname = None
@@ -43,6 +45,17 @@ class StagingArea(object):
self.mounted = None
self._bind_readonly_mount = None
+ self.use_chroot = use_chroot
+ self.env = build_env.env
+ self.env.update(extra_env)
+
+ if use_chroot:
+ path = build_env.extra_path + self._base_path
+ else:
+ full_path = [self.relative(p) for p in build_env.extra_path]
+ path = full_path + os.environ['PATH'].split(':')
+ self.env['PATH'] = ':'.join(path)
+
# Wrapper to be overridden by unit tests.
def _mkdir(self, dirname): # pragma: no cover
os.mkdir(dirname)
@@ -75,6 +88,9 @@ class StagingArea(object):
def relative(self, filename):
'''Return a filename relative to the staging area.'''
+ if not self.use_chroot:
+ return filename
+
dirname = self.dirname
if not dirname.endswith('/'):
dirname += '/'
@@ -190,8 +206,7 @@ class StagingArea(object):
if not os.path.isdir(ccache_repodir):
os.mkdir(ccache_repodir)
# Get the destination path
- ccache_destdir= os.path.join(self.tempdir,
- 'tmp', 'ccache')
+ ccache_destdir= os.path.join(self.dirname, 'tmp', 'ccache')
# Make sure that the destination exists. We'll create /tmp if necessary
# to avoid breaking when faced with an empty staging area.
if not os.path.isdir(ccache_destdir):
@@ -247,14 +262,20 @@ class StagingArea(object):
def runcmd(self, argv, **kwargs): # pragma: no cover
'''Run a command in a chroot in the staging area.'''
+ assert 'env' not in kwargs
+ kwargs['env'] = self.env
+ if 'extra_env' in kwargs:
+ kwargs['env'].update(kwargs['extra_env'])
+ del kwargs['extra_env']
+
+ if self.use_chroot:
+ cwd = kwargs.get('cwd') or '/'
+ if 'cwd' in kwargs:
+ cwd = kwargs['cwd']
+ del kwargs['cwd']
+ else:
+ cwd = '/'
- cwd = kwargs.get('cwd') or '/'
- if 'cwd' in kwargs:
- cwd = kwargs['cwd']
- del kwargs['cwd']
- else:
- cwd = '/'
- if self._app.settings['staging-chroot']:
not_readonly_dirs = [self.builddirname, self.destdirname,
'dev', 'proc', 'tmp']
dirs = os.listdir(self.dirname)
@@ -265,12 +286,11 @@ class StagingArea(object):
for entry in dirs:
real_argv += ['--mount-readonly', '/'+entry]
-
real_argv += [self.dirname]
- else:
- real_argv = ['chroot', '/']
- real_argv += ['sh', '-c', 'cd "$1" && shift && exec "$@"', '--', cwd]
- real_argv += argv
+ real_argv += ['sh', '-c', 'cd "$1" && shift && exec "$@"', '--', cwd]
+ real_argv += argv
- return self._app.runcmd(real_argv, **kwargs)
+ return self._app.runcmd(real_argv, **kwargs)
+ else:
+ return self._app.runcmd(argv, **kwargs)