diff options
author | Adam Coldrick <adam.coldrick@codethink.co.uk> | 2015-01-28 15:53:27 +0000 |
---|---|---|
committer | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2015-04-20 14:07:40 +0000 |
commit | 3fb6281192630670b735d6c6af243afbf8e01282 (patch) | |
tree | ab970b53a564c0ccb09a7b166df017843e6974e2 /morphlib/plugins/deploy_plugin.py | |
parent | ddba1d3cc38ea98bb811b72780386b584e26c7c4 (diff) | |
download | morph-3fb6281192630670b735d6c6af243afbf8e01282.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.
Change-Id: Iafcb78feaa1d6d37be4f52420c03d5b96d5c81ee
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 ea84d9ec..35082e68 100644 --- a/morphlib/plugins/deploy_plugin.py +++ b/morphlib/plugins/deploy_plugin.py @@ -419,6 +419,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) @@ -467,6 +469,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 @@ -529,9 +534,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') @@ -553,18 +571,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, |