diff options
author | Adam Coldrick <adam.coldrick@codethink.co.uk> | 2015-01-28 15:53:27 +0000 |
---|---|---|
committer | Adam Coldrick <adam.coldrick@codethink.co.uk> | 2015-02-06 12:57:49 +0000 |
commit | 3f7e38a7f2721a404ebbfb130b51fa639a9e7360 (patch) | |
tree | 94ce5fd63b3364dba0b0e9c00b63cac4094e4aa7 /morphlib/plugins/deploy_plugin.py | |
parent | 1701ee47ee9261ce52d8509f1fff1ad8a4e3134b (diff) | |
download | morph-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.py | 38 |
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, |