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-03-03 18:41:48 +0000
commit6e5a68c799061737d32fd36dcd565fe7e30b4804 (patch)
tree4503c9d4347a997b069c1112dc9165bd137bf734 /morphlib
parent31e429d1f59a9f6ebc80ae4da72cc186a3b7383e (diff)
downloadmorph-6e5a68c799061737d32fd36dcd565fe7e30b4804.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 6d506a21..f3432456 100644
--- a/morphlib/plugins/deploy_plugin.py
+++ b/morphlib/plugins/deploy_plugin.py
@@ -440,6 +440,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)
@@ -503,6 +505,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
@@ -540,9 +545,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')
@@ -564,18 +582,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,