summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2013-08-09 14:01:25 +0000
committerRichard Maw <richard.maw@codethink.co.uk>2013-08-13 14:21:57 +0000
commitba76c590965932dd3af7093fbf33894c97290cf7 (patch)
tree3964c754b993a16d093f6c44628ddc9571cfa414
parent70f66833fc407d72e4bae53c50580d4066152761 (diff)
downloaddefinitions-ba76c590965932dd3af7093fbf33894c97290cf7.tar.gz
deploy: Always cleanup deploy tempdir on failure
When a configuration extension or write extension fails, then it should abort then, not continue to run other configuration extensions. There was a period where this didn't happen, due to a missing feature of cliapp that was assumed to be there, so failure to run these extensions was not noticed. This has since been fixed, but this would cause deploy to fail to clean up its temporary directories. Now it will cleanup the contents of the temporary directory after any failures after it has been created. A small amount of re-ordering was performed to make this easier.
-rw-r--r--morphlib/plugins/deploy_plugin.py97
1 files changed, 52 insertions, 45 deletions
diff --git a/morphlib/plugins/deploy_plugin.py b/morphlib/plugins/deploy_plugin.py
index 092441ec..8530cb57 100644
--- a/morphlib/plugins/deploy_plugin.py
+++ b/morphlib/plugins/deploy_plugin.py
@@ -283,58 +283,65 @@ class DeployPlugin(cliapp.Plugin):
if push:
self.other.delete_remote_build_refs(build_repos)
- # Unpack the artifact (tarball) to a temporary directory.
- self.app.status(msg='Unpacking system for configuration')
+ # Create a tempdir for this deployment to work in
deploy_tempdir = tempfile.mkdtemp(
dir=os.path.join(self.app.settings['tempdir'], 'deployments'))
- system_tree = tempfile.mkdtemp(dir=deploy_tempdir)
-
- if build_command.lac.has(artifact):
- f = build_command.lac.get(artifact)
- elif build_command.rac.has(artifact):
- f = build_command.rac.get(artifact)
- else:
- raise cliapp.AppException('Deployment failed as system is not yet'
- ' built.\nPlease ensure system is built'
- ' before deployment.')
- tf = tarfile.open(fileobj=f)
- tf.extractall(path=system_tree)
-
- self.app.status(
- msg='System unpacked at %(system_tree)s',
- system_tree=system_tree)
-
- # Extensions get a private tempdir so we can more easily clean
- # up any files an extension left behind
- deploy_private_tempdir = tempfile.mkdtemp(dir=deploy_tempdir)
- env['TMPDIR'] = deploy_private_tempdir
-
- # Run configuration extensions.
- self.app.status(msg='Configure system')
- names = artifact.source.morphology['configuration-extensions']
- for name in names:
+ try:
+ # Create a tempdir to extract the rootfs in
+ system_tree = tempfile.mkdtemp(dir=deploy_tempdir)
+
+ # Extensions get a private tempdir so we can more easily clean
+ # up any files an extension left behind
+ deploy_private_tempdir = tempfile.mkdtemp(dir=deploy_tempdir)
+ env['TMPDIR'] = deploy_private_tempdir
+
+ # Unpack the artifact (tarball) to a temporary directory.
+ self.app.status(msg='Unpacking system for configuration')
+
+ if build_command.lac.has(artifact):
+ f = build_command.lac.get(artifact)
+ elif build_command.rac.has(artifact):
+ f = build_command.rac.get(artifact)
+ else:
+ raise cliapp.AppException('Deployment failed as system is'
+ ' not yet built.\nPlease ensure'
+ ' the system is built before'
+ ' deployment.')
+ tf = tarfile.open(fileobj=f)
+ tf.extractall(path=system_tree)
+
+ self.app.status(
+ msg='System unpacked at %(system_tree)s',
+ system_tree=system_tree)
+
+
+ # Run configuration extensions.
+ self.app.status(msg='Configure system')
+ names = artifact.source.morphology['configuration-extensions']
+ for name in names:
+ self._run_extension(
+ root_repo_dir,
+ build_ref,
+ name,
+ '.configure',
+ [system_tree],
+ env)
+
+ # Run write extension.
+ self.app.status(msg='Writing to device')
self._run_extension(
root_repo_dir,
build_ref,
- name,
- '.configure',
- [system_tree],
+ deployment_type,
+ '.write',
+ [system_tree, location],
env)
-
- # Run write extension.
- self.app.status(msg='Writing to device')
- self._run_extension(
- root_repo_dir,
- build_ref,
- deployment_type,
- '.write',
- [system_tree, location],
- env)
-
- # Cleanup.
- self.app.status(msg='Cleaning up')
- shutil.rmtree(deploy_tempdir)
+
+ finally:
+ # Cleanup.
+ self.app.status(msg='Cleaning up')
+ shutil.rmtree(deploy_tempdir)
self.app.status(msg='Finished deployment')