Add support for cleaning in Ironic driver

Ironic added a new state between deleting and available called cleaning
where tasks like erasing drives occur after each delete. This patch
ensures that instances can be considered deleted in Nova as soon as a
node enters cleaning state, otherwise, instances could be stuck in
deleting state in Nova for hours or days.

This is necessary to implement the Ironic cleaning spec:
https://blueprints.launchpad.net/ironic/+spec/implement-cleaning-states

Closes-Bug: 1174153
Change-Id: Ie04823c40efc08f887429a6b8e6219558c3e4efa
This commit is contained in:
Josh Gachnang 2015-03-04 15:26:54 -08:00
parent 590957007e
commit 597507d66b
2 changed files with 27 additions and 2 deletions

View File

@ -992,6 +992,24 @@ class IronicDriverTestCase(test.NoDBTestCase):
mock_cleanup_deploy.assert_called_with(self.ctx, node, instance,
network_info)
@mock.patch.object(FAKE_CLIENT, 'node')
@mock.patch.object(ironic_driver.IronicDriver, '_cleanup_deploy')
def test_destroy_cleaning(self, mock_cleanup_deploy, mock_node):
node_uuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
network_info = 'foo'
node = ironic_utils.get_test_node(
driver='fake', uuid=node_uuid,
provision_state=ironic_states.CLEANING)
instance = fake_instance.fake_instance_obj(self.ctx, node=node_uuid)
mock_node.get_by_instance_uuid.return_value = node
self.driver.destroy(self.ctx, instance, network_info, None)
self.assertFalse(mock_node.set_provision_state.called)
mock_node.get_by_instance_uuid.assert_called_with(instance.uuid)
mock_cleanup_deploy.assert_called_with(self.ctx, node, instance,
network_info)
@mock.patch.object(FAKE_CLIENT.node, 'set_provision_state')
@mock.patch.object(ironic_driver, '_validate_instance_and_node')
def test_destroy_trigger_undeploy_fail(self, fake_validate, mock_sps):

View File

@ -757,9 +757,16 @@ class IronicDriver(virt_driver.ComputeDriver):
def _wait_for_provision_state():
node = _validate_instance_and_node(ironicclient, instance)
if node.provision_state in (ironic_states.NOSTATE,
ironic_states.CLEANING,
ironic_states.CLEANFAIL,
ironic_states.AVAILABLE):
LOG.debug("Ironic node %(node)s is now unprovisioned",
dict(node=node.uuid), instance=instance)
# From a user standpoint, the node is unprovisioned. If a node
# gets into CLEANFAIL state, it must be fixed in Ironic, but we
# can consider the instance unprovisioned.
LOG.debug("Ironic node %(node)s is in state %(state)s, "
"instance is now unprovisioned.",
dict(node=node.uuid, state=node.provision_state),
instance=instance)
raise loopingcall.LoopingCallDone()
if data['tries'] >= CONF.ironic.api_max_retries: