Merge "Add a looping call to wait for power action completed"
This commit is contained in:
commit
d6e02c6740
|
@ -240,16 +240,32 @@ class EngineManager(base_manager.BaseEngineManager):
|
||||||
|
|
||||||
return self._instance_states(context, instance)
|
return self._instance_states(context, instance)
|
||||||
|
|
||||||
def _set_power_state(self, context, instance, state):
|
def _wait_for_power_state(self, instance):
|
||||||
ironic.set_power_state(self.ironicclient, instance.node_uuid, state)
|
"""Wait for the node to complete a power state change."""
|
||||||
LOG.info(_LI('Successfully set ironic node power state: %s'),
|
try:
|
||||||
state)
|
node = ironic.get_node_by_instance(self.ironicclient,
|
||||||
|
instance.uuid)
|
||||||
|
except ironic_exc.NotFound:
|
||||||
|
LOG.debug("While waiting for node to complete a power state "
|
||||||
|
"change, it dissociate with the instance.",
|
||||||
|
instance=instance)
|
||||||
|
raise exception.NodeNotFound()
|
||||||
|
|
||||||
|
if node.target_power_state == ironic_states.NOSTATE:
|
||||||
|
raise loopingcall.LoopingCallDone()
|
||||||
|
|
||||||
def set_power_state(self, context, instance, state):
|
def set_power_state(self, context, instance, state):
|
||||||
"""Get an instance states."""
|
"""Set power state for the specified instance."""
|
||||||
LOG.debug("set power state...")
|
LOG.debug('Power %(state)s called for instance %(instance)s',
|
||||||
|
{'state': state,
|
||||||
|
'instance': instance})
|
||||||
|
ironic.set_power_state(self.ironicclient, instance.node_uuid, state)
|
||||||
|
|
||||||
return self._set_power_state(context, instance, state)
|
timer = loopingcall.FixedIntervalLoopingCall(
|
||||||
|
self._wait_for_power_state, instance)
|
||||||
|
timer.start(interval=CONF.ironic.api_retry_interval).wait()
|
||||||
|
LOG.info(_LI('Successfully set node power state: %s'),
|
||||||
|
state, instance=instance)
|
||||||
|
|
||||||
@messaging.expected_exceptions(exception.NodeNotFound)
|
@messaging.expected_exceptions(exception.NodeNotFound)
|
||||||
def get_ironic_node(self, context, instance_uuid, fields):
|
def get_ironic_node(self, context, instance_uuid, fields):
|
||||||
|
|
|
@ -71,8 +71,7 @@ class EngineAPI(object):
|
||||||
def set_power_state(self, context, instance, state):
|
def set_power_state(self, context, instance, state):
|
||||||
"""Signal to engine service to perform power action on instance."""
|
"""Signal to engine service to perform power action on instance."""
|
||||||
cctxt = self.client.prepare(topic=self.topic, server=CONF.host)
|
cctxt = self.client.prepare(topic=self.topic, server=CONF.host)
|
||||||
# need return?
|
return cctxt.cast(context, 'set_power_state',
|
||||||
return cctxt.call(context, 'set_power_state',
|
|
||||||
instance=instance, state=state)
|
instance=instance, state=state)
|
||||||
|
|
||||||
def get_ironic_node(self, context, instance_uuid, fields):
|
def get_ironic_node(self, context, instance_uuid, fields):
|
||||||
|
|
|
@ -148,10 +148,14 @@ class ManageInstanceTestCase(mgr_utils.ServiceSetUpMixin,
|
||||||
|
|
||||||
self.assertFalse(destroy_inst_mock.called)
|
self.assertFalse(destroy_inst_mock.called)
|
||||||
|
|
||||||
|
@mock.patch.object(ironic, 'get_node_by_instance')
|
||||||
@mock.patch.object(ironic, 'set_power_state')
|
@mock.patch.object(ironic, 'set_power_state')
|
||||||
def test_change_instance_power_state(self, set_power_mock,
|
def test_change_instance_power_state(
|
||||||
refresh_cache_mock):
|
self, set_power_mock, get_node_mock, refresh_cache_mock):
|
||||||
instance = obj_utils.create_test_instance(self.context)
|
instance = obj_utils.create_test_instance(self.context)
|
||||||
|
fake_node = mock.MagicMock()
|
||||||
|
fake_node.target_power_state = ironic_states.NOSTATE
|
||||||
|
get_node_mock.return_value = fake_node
|
||||||
refresh_cache_mock.side_effect = None
|
refresh_cache_mock.side_effect = None
|
||||||
self._start_service()
|
self._start_service()
|
||||||
|
|
||||||
|
@ -161,6 +165,7 @@ class ManageInstanceTestCase(mgr_utils.ServiceSetUpMixin,
|
||||||
|
|
||||||
set_power_mock.assert_called_once_with(mock.ANY, instance.node_uuid,
|
set_power_mock.assert_called_once_with(mock.ANY, instance.node_uuid,
|
||||||
ironic_states.POWER_ON)
|
ironic_states.POWER_ON)
|
||||||
|
get_node_mock.assert_called_once_with(mock.ANY, instance.uuid)
|
||||||
|
|
||||||
@mock.patch.object(ironic, 'get_node_states')
|
@mock.patch.object(ironic, 'get_node_states')
|
||||||
def test_get_instance_states(self, get_states_mock, refresh_cache_mock):
|
def test_get_instance_states(self, get_states_mock, refresh_cache_mock):
|
||||||
|
|
|
@ -124,7 +124,7 @@ class RPCAPITestCase(base.DbTestCase):
|
||||||
|
|
||||||
def test_set_power_state(self):
|
def test_set_power_state(self):
|
||||||
self._test_rpcapi('set_power_state',
|
self._test_rpcapi('set_power_state',
|
||||||
'call',
|
'cast',
|
||||||
version='1.0',
|
version='1.0',
|
||||||
instance=self.fake_instance_obj,
|
instance=self.fake_instance_obj,
|
||||||
state='power on')
|
state='power on')
|
||||||
|
|
Loading…
Reference in New Issue