Allow disabling clean up on deployment failure

Change-Id: Iaa9e7ec1c2cd2b71047388e51255ec69d52d6a83
This commit is contained in:
Dmitry Tantsur 2019-05-16 13:01:24 +02:00
parent 814611f022
commit 4920cc26a3
5 changed files with 42 additions and 8 deletions

View File

@ -80,7 +80,8 @@ def _do_deploy(api, args, formatter):
swap_size_mb=args.swap_size,
config=config,
netboot=args.netboot,
wait=wait)
wait=wait,
clean_up_on_failure=not args.no_clean_up)
formatter.deploy(instance)
@ -174,6 +175,8 @@ def _parse_args(args, config):
deploy.add_argument('--user-name', help='Name of the admin user to create')
deploy.add_argument('--passwordless-sudo', action='store_true',
help='allow password-less sudo for the user')
deploy.add_argument('--no-clean-up', help='Prevent clean up on failure',
action='store_true')
undeploy = subparsers.add_parser('undeploy')
undeploy.set_defaults(func=_do_undeploy)

View File

@ -319,6 +319,9 @@ class Provisioner(_utils.GetNodeMixin):
:meth:`reserve_node` for that.
:param wait: How many seconds to wait for the deployment to finish,
None to return immediately.
:param clean_up_on_failure: If True, then on failure the node is
cleared of instance information, VIFs are detached, created ports
and allocations are deleted.
:return: :py:class:`metalsmith.Instance` object with the current
status of provisioning. If ``wait`` is not ``None``, provisioning
is already finished.
@ -386,12 +389,13 @@ class Provisioner(_utils.GetNodeMixin):
except Exception:
exc_info = sys.exc_info()
try:
LOG.error('Deploy attempt failed on node %s, cleaning up',
_utils.log_res(node))
self._clean_up(node, nics=nics)
except Exception:
LOG.exception('Clean up failed')
if clean_up_on_failure:
try:
LOG.error('Deploy attempt failed on node %s, cleaning up',
_utils.log_res(node))
self._clean_up(node, nics=nics)
except Exception:
LOG.exception('Clean up failed')
six.reraise(*exc_info)

View File

@ -56,7 +56,8 @@ class TestDeploy(testtools.TestCase):
swap_size_mb=None,
config=mock.ANY,
netboot=False,
wait=1800)
wait=1800,
clean_up_on_failure=True)
provision_defaults.update(provision_args)
_cmd.main(args)
@ -502,6 +503,11 @@ class TestDeploy(testtools.TestCase):
'--swap-size', '4096', '--resource-class', 'compute']
self._check(mock_pr, args, {}, {'swap_size_mb': 4096})
def test_no_clean_up(self, mock_pr):
args = ['deploy', '--network', 'mynet', '--image', 'myimg',
'--resource-class', 'compute', '--no-clean-up']
self._check(mock_pr, args, {}, {'clean_up_on_failure': False})
@mock.patch.object(_provisioner, 'Provisioner', autospec=True)
@mock.patch.object(_cmd.os_config, 'OpenStackConfig', autospec=True)

View File

@ -1074,6 +1074,22 @@ abcd image
calls, any_order=True)
self.api.baremetal.delete_allocation.assert_called_once_with('id2')
def test_deploy_failure_no_cleanup(self):
self.node.allocation_id = 'id2'
self.api.baremetal.set_node_provision_state.side_effect = (
RuntimeError('boom'))
self.assertRaisesRegex(RuntimeError, 'boom',
self.pr.provision_node, self.node,
'image', [{'network': 'n1'}, {'port': 'p1'}],
wait=3600, clean_up_on_failure=False)
self.assertEqual(1, self.api.baremetal.update_node.call_count)
self.assertFalse(
self.api.baremetal.wait_for_nodes_provision_state.called)
self.assertFalse(self.api.network.delete_port.called)
self.assertFalse(self.api.baremetal.detach_vif_from_node.called)
self.assertFalse(self.api.baremetal.delete_allocation.called)
def test_port_creation_failure(self):
self.api.network.create_port.side_effect = RuntimeError('boom')
self.assertRaisesRegex(RuntimeError, 'boom',

View File

@ -0,0 +1,5 @@
---
features:
- |
Allows disabling clean up on failure via the new ``clean_up_on_failure``
argument and ``--no-clean-up`` flag.