summaryrefslogtreecommitdiff
path: root/morphlib/plugins/deploy_plugin.py
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-02-06 12:57:49 +0000
commit3f7e38a7f2721a404ebbfb130b51fa639a9e7360 (patch)
tree94ce5fd63b3364dba0b0e9c00b63cac4094e4aa7 /morphlib/plugins/deploy_plugin.py
parent1701ee47ee9261ce52d8509f1fff1ad8a4e3134b (diff)
downloadmorph-3f7e38a7f2721a404ebbfb130b51fa639a9e7360.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/plugins/deploy_plugin.py')
-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 87fd259f..4f78d126 100644
--- a/morphlib/plugins/deploy_plugin.py
+++ b/morphlib/plugins/deploy_plugin.py
@@ -438,6 +438,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)
@@ -501,6 +503,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
@@ -538,9 +543,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')
@@ -562,18 +580,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,