node_set_provision_state wait/timeout support

Addition of wait/timeout support for node_set_provision_state to
block the method until the machine has entered the desired state.

Combined with this, node_set_provision_state will now return the
state of the machine as opposed to just passing through the default
from the ironicclient node set provision state call.

Change-Id: I3e0bfe9e4612291dc77bd683479f7f99aef50d0a
This commit is contained in:
Julia Kreger 2015-08-23 19:53:15 -04:00
parent 137458fc1c
commit 80f2a21bc0
2 changed files with 113 additions and 10 deletions

View File

@ -3741,7 +3741,12 @@ class OperatorCloud(OpenStackCloud):
"ironic node %s failed to validate. "
"(deploy: %s, power: %s)" % (ifaces.deploy, ifaces.power))
def node_set_provision_state(self, name_or_id, state, configdrive=None):
def node_set_provision_state(self,
name_or_id,
state,
configdrive=None,
wait=False,
timeout=3600):
"""Set Node Provision State
Enables a user to provision a Machine and optionally define a
@ -3758,19 +3763,39 @@ class OperatorCloud(OpenStackCloud):
configuration drive file and post the
file contents to the API for
deployment.
:param boolean wait: A boolean value, defaulted to false, to control
if the method will wait for the desire end state
to be reached before returning.
:param integer timeout: Integer value, defaulting to 3600 seconds,
representing the amount of time to wait for
the desire end state to be reached.
:raises: OpenStackCloudException on operation error.
:returns: Per the API, no value should be returned with a successful
operation.
:returns: Dictonary representing the current state of the machine
upon exit of the method.
"""
try:
return meta.obj_to_dict(
self.manager.submitTask(
_tasks.MachineSetProvision(node_uuid=name_or_id,
state=state,
configdrive=configdrive))
)
machine = self.manager.submitTask(
_tasks.MachineSetProvision(node_uuid=name_or_id,
state=state,
configdrive=configdrive))
if wait:
for count in _utils._iterate_timeout(
timeout,
"Timeout waiting for node transition to "
"target state of '%s'" % state):
machine = self.get_machine(name_or_id)
if state in machine['provision_state']:
break
if ("available" in machine['provision_state'] and
"provide" in state):
break
else:
machine = self.get_machine(name_or_id)
return machine
except Exception as e:
raise OpenStackCloudException(
"Baremetal machine node failed change provision"

View File

@ -660,17 +660,95 @@ class TestShadeOperator(base.TestCase):
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
def test_node_set_provision_state(self, mock_client):
class active_node_state:
provision_state = "active"
active_return_value = dict(
provision_state="active")
mock_client.node.set_provision_state.return_value = None
mock_client.node.get.return_value = active_node_state
node_id = 'node01'
return_value = self.cloud.node_set_provision_state(
node_id,
'active',
configdrive='http://127.0.0.1/file.iso')
self.assertEqual({}, return_value)
self.assertEqual(active_return_value, return_value)
mock_client.node.set_provision_state.assert_called_with(
node_uuid='node01',
state='active',
configdrive='http://127.0.0.1/file.iso')
self.assertTrue(mock_client.node.get.called)
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
def test_node_set_provision_state_wait_timeout(self, mock_client):
class deploying_node_state:
provision_state = "deploying"
class active_node_state:
provision_state = "active"
class managable_node_state:
provision_state = "managable"
class available_node_state:
provision_state = "available"
active_return_value = dict(
provision_state="active")
mock_client.node.get.return_value = active_node_state
mock_client.node.set_provision_state.return_value = None
node_id = 'node01'
return_value = self.cloud.node_set_provision_state(
node_id,
'active',
configdrive='http://127.0.0.1/file.iso',
wait=True)
self.assertEqual(active_return_value, return_value)
mock_client.node.set_provision_state.assert_called_with(
node_uuid='node01',
state='active',
configdrive='http://127.0.0.1/file.iso')
self.assertTrue(mock_client.node.get.called)
mock_client.mock_reset()
mock_client.node.get.return_value = deploying_node_state
self.assertRaises(
shade.OpenStackCloudException,
self.cloud.node_set_provision_state,
node_id,
'active',
configdrive='http://127.0.0.1/file.iso',
wait=True,
timeout=0.001)
self.assertTrue(mock_client.node.get.called)
mock_client.node.set_provision_state.assert_called_with(
node_uuid='node01',
state='active',
configdrive='http://127.0.0.1/file.iso')
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
def test_node_set_provision_state_wait_provide(self, mock_client):
class managable_node_state:
provision_state = "managable"
class available_node_state:
provision_state = "available"
node_provide_return_value = dict(
provision_state="available")
mock_client.node.get.side_effect = iter([
managable_node_state,
available_node_state])
return_value = self.cloud.node_set_provision_state(
'test_node',
'provide',
wait=True)
self.assertEqual(mock_client.node.get.call_count, 2)
self.assertDictEqual(node_provide_return_value, return_value)
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
def test_activate_node(self, mock_client):