Allow disabling clean up on deployment failure
Change-Id: Iaa9e7ec1c2cd2b71047388e51255ec69d52d6a83
This commit is contained in:
parent
814611f022
commit
4920cc26a3
@ -80,7 +80,8 @@ def _do_deploy(api, args, formatter):
|
|||||||
swap_size_mb=args.swap_size,
|
swap_size_mb=args.swap_size,
|
||||||
config=config,
|
config=config,
|
||||||
netboot=args.netboot,
|
netboot=args.netboot,
|
||||||
wait=wait)
|
wait=wait,
|
||||||
|
clean_up_on_failure=not args.no_clean_up)
|
||||||
formatter.deploy(instance)
|
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('--user-name', help='Name of the admin user to create')
|
||||||
deploy.add_argument('--passwordless-sudo', action='store_true',
|
deploy.add_argument('--passwordless-sudo', action='store_true',
|
||||||
help='allow password-less sudo for the user')
|
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 = subparsers.add_parser('undeploy')
|
||||||
undeploy.set_defaults(func=_do_undeploy)
|
undeploy.set_defaults(func=_do_undeploy)
|
||||||
|
@ -319,6 +319,9 @@ class Provisioner(_utils.GetNodeMixin):
|
|||||||
:meth:`reserve_node` for that.
|
:meth:`reserve_node` for that.
|
||||||
:param wait: How many seconds to wait for the deployment to finish,
|
:param wait: How many seconds to wait for the deployment to finish,
|
||||||
None to return immediately.
|
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
|
:return: :py:class:`metalsmith.Instance` object with the current
|
||||||
status of provisioning. If ``wait`` is not ``None``, provisioning
|
status of provisioning. If ``wait`` is not ``None``, provisioning
|
||||||
is already finished.
|
is already finished.
|
||||||
@ -386,12 +389,13 @@ class Provisioner(_utils.GetNodeMixin):
|
|||||||
except Exception:
|
except Exception:
|
||||||
exc_info = sys.exc_info()
|
exc_info = sys.exc_info()
|
||||||
|
|
||||||
try:
|
if clean_up_on_failure:
|
||||||
LOG.error('Deploy attempt failed on node %s, cleaning up',
|
try:
|
||||||
_utils.log_res(node))
|
LOG.error('Deploy attempt failed on node %s, cleaning up',
|
||||||
self._clean_up(node, nics=nics)
|
_utils.log_res(node))
|
||||||
except Exception:
|
self._clean_up(node, nics=nics)
|
||||||
LOG.exception('Clean up failed')
|
except Exception:
|
||||||
|
LOG.exception('Clean up failed')
|
||||||
|
|
||||||
six.reraise(*exc_info)
|
six.reraise(*exc_info)
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ class TestDeploy(testtools.TestCase):
|
|||||||
swap_size_mb=None,
|
swap_size_mb=None,
|
||||||
config=mock.ANY,
|
config=mock.ANY,
|
||||||
netboot=False,
|
netboot=False,
|
||||||
wait=1800)
|
wait=1800,
|
||||||
|
clean_up_on_failure=True)
|
||||||
provision_defaults.update(provision_args)
|
provision_defaults.update(provision_args)
|
||||||
|
|
||||||
_cmd.main(args)
|
_cmd.main(args)
|
||||||
@ -502,6 +503,11 @@ class TestDeploy(testtools.TestCase):
|
|||||||
'--swap-size', '4096', '--resource-class', 'compute']
|
'--swap-size', '4096', '--resource-class', 'compute']
|
||||||
self._check(mock_pr, args, {}, {'swap_size_mb': 4096})
|
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(_provisioner, 'Provisioner', autospec=True)
|
||||||
@mock.patch.object(_cmd.os_config, 'OpenStackConfig', autospec=True)
|
@mock.patch.object(_cmd.os_config, 'OpenStackConfig', autospec=True)
|
||||||
|
@ -1074,6 +1074,22 @@ abcd image
|
|||||||
calls, any_order=True)
|
calls, any_order=True)
|
||||||
self.api.baremetal.delete_allocation.assert_called_once_with('id2')
|
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):
|
def test_port_creation_failure(self):
|
||||||
self.api.network.create_port.side_effect = RuntimeError('boom')
|
self.api.network.create_port.side_effect = RuntimeError('boom')
|
||||||
self.assertRaisesRegex(RuntimeError, 'boom',
|
self.assertRaisesRegex(RuntimeError, 'boom',
|
||||||
|
5
releasenotes/notes/no-clean-up-03bfaee6bbb112fb.yaml
Normal file
5
releasenotes/notes/no-clean-up-03bfaee6bbb112fb.yaml
Normal 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.
|
Loading…
Reference in New Issue
Block a user