summaryrefslogtreecommitdiff
path: root/morphlib
diff options
context:
space:
mode:
authorAdam Coldrick <adam.coldrick@codethink.co.uk>2015-01-28 15:53:27 +0000
committerAdam Coldrick <adam.coldrick@codethink.co.uk>2015-04-10 13:52:24 +0000
commit92986d324758a999be83cf3af4272058492f991b (patch)
tree8554d85208217b7cbecf986e00f861b96605c833 /morphlib
parentee1a75379cb067a37d807218f04b866d496ac7e4 (diff)
downloadmorph-92986d324758a999be83cf3af4272058492f991b.tar.gz
Use overlayfs when deploying
When deploying, configuration extensions are run against the unpacked tarball of a system created by a build. If we are to use OSTree to store systems (rather than tarballs) this will not be possible as the result of `ostree checkout` would be read-only. To solve this, we use overlayfs to mount the unpacked tarball underneath a temporary directory somewhere, and run the configuration extensions on that mount point. This means that the changes are made in the temporary directory rather than directly on the tarball.
Diffstat (limited to 'morphlib')
-rw-r--r--morphlib/plugins/deploy_plugin.py38
1 files changed, 34 insertions, 4 deletions
diff --git a/morphlib/plugins/deploy_plugin.py b/morphlib/plugins/deploy_plugin.py
index 63cc4688..576b007c 100644
--- a/morphlib/plugins/deploy_plugin.py
+++ b/morphlib/plugins/deploy_plugin.py
@@ -439,6 +439,8 @@ class DeployPlugin(cliapp.Plugin):
system_status_prefix = '%s[%s]' % (old_status_prefix, system['morph'])
self.app.status_prefix = system_status_prefix
try:
+ system_tree = None
+
# Find the artifact to build
morph = morphlib.util.sanitise_morphology_path(system['morph'])
srcpool = build_command.create_source_pool(build_repo, ref, morph)
@@ -502,6 +504,9 @@ class DeployPlugin(cliapp.Plugin):
system_tree, deploy_location)
finally:
self.app.status_prefix = system_status_prefix
+ if system_tree and os.path.exists(system_tree):
+ morphlib.fsutils.unmount(self.app.runcmd, system_tree)
+ shutil.rmtree(system_tree)
finally:
self.app.status_prefix = old_status_prefix
@@ -539,9 +544,22 @@ class DeployPlugin(cliapp.Plugin):
artifact, deployment_type, location, env):
# deployment_type, location and env are only used for saving metadata
- # Create a tempdir to extract the rootfs in
- system_tree = tempfile.mkdtemp(dir=deploy_tempdir)
+ deployment_dir = tempfile.mkdtemp(dir=deploy_tempdir)
+ # Create a tempdir to extract the rootfs in
+ system_tree = tempfile.mkdtemp(dir=deployment_dir)
+
+ # Create temporary directory for overlayfs
+ overlay_dir = os.path.join(deployment_dir,
+ '%s-upperdir' % artifact.name)
+ if not os.path.exists(overlay_dir):
+ os.makedirs(overlay_dir)
+ work_dir = os.path.join(deployment_dir, '%s-workdir' % artifact.name)
+ if not os.path.exists(work_dir):
+ os.makedirs(work_dir)
+
+ deploy_tree = os.path.join(deployment_dir,
+ 'overlay-deploy-%s' % artifact.name)
try:
# Unpack the artifact (tarball) to a temporary directory.
self.app.status(msg='Unpacking system for configuration')
@@ -563,18 +581,30 @@ class DeployPlugin(cliapp.Plugin):
msg='System unpacked at %(system_tree)s',
system_tree=system_tree)
+ options = '-olowerdir=%s,upperdir=%s,workdir=%s' % \
+ (system_tree, overlay_dir, work_dir)
+ morphlib.fsutils.mount(self.app.runcmd,
+ 'overlay-deploy-%s' % artifact.name,
+ deploy_tree, fstype='overlay',
+ options=options)
+
self.app.status(
msg='Writing deployment metadata file')
metadata = self.create_metadata(
artifact, root_repo_dir, deployment_type, location, env)
metadata_path = os.path.join(
- system_tree, 'baserock', 'deployment.meta')
+ deploy_tree, 'baserock', 'deployment.meta')
with morphlib.savefile.SaveFile(metadata_path, 'w') as f:
json.dump(metadata, f, indent=4,
sort_keys=True, encoding='unicode-escape')
- return system_tree
+ return deploy_tree
except Exception:
shutil.rmtree(system_tree)
+ shutil.rmtree(overlay_dir)
+ shutil.rmtree(work_dir)
+ if deploy_tree and os.path.exists(deploy_tree):
+ morphlib.fsutils.unmount(self.app.runcmd, deploy_tree)
+ shutil.rmtree(deploy_tree)
raise
def run_deploy_commands(self, deploy_tempdir, env, artifact, root_repo_dir,