diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 4bb08aa16239..8927e682aef2 100755 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -3436,7 +3436,7 @@ class ComputeManager(manager.SchedulerDependentManager): # Note(maoy): here we call the API instead of # brutally updating the vm_state in the database # to allow all the hooks and checks to be performed. - self.compute_api.stop(context, db_instance) + self.conductor_api.compute_stop(context, db_instance) except Exception: # Note(maoy): there is no need to propagate the error # because the same power_state will be retrieved next @@ -3449,7 +3449,7 @@ class ComputeManager(manager.SchedulerDependentManager): LOG.warn(_("Instance is suspended unexpectedly. Calling " "the stop API."), instance=db_instance) try: - self.compute_api.stop(context, db_instance) + self.conductor_api.compute_stop(context, db_instance) except Exception: LOG.exception(_("error during stop() in " "sync_power_state."), @@ -3479,7 +3479,7 @@ class ComputeManager(manager.SchedulerDependentManager): try: # Note(maoy): this assumes that the stop API is # idempotent. - self.compute_api.stop(context, db_instance) + self.conductor_api.compute_stop(context, db_instance) except Exception: LOG.exception(_("error during stop() in " "sync_power_state."), diff --git a/nova/conductor/api.py b/nova/conductor/api.py index 435cc062aa62..9026eb8a2cc4 100644 --- a/nova/conductor/api.py +++ b/nova/conductor/api.py @@ -328,6 +328,9 @@ class LocalAPI(object): def get_ec2_ids(self, context, instance): return self._manager.get_ec2_ids(context, instance) + def compute_stop(self, context, instance, do_cast=True): + return self._manager.compute_stop(context, instance, do_cast) + class API(object): """Conductor API that does updates via RPC to the ConductorManager.""" @@ -654,3 +657,6 @@ class API(object): def get_ec2_ids(self, context, instance): return self.conductor_rpcapi.get_ec2_ids(context, instance) + + def compute_stop(self, context, instance, do_cast=True): + return self.conductor_rpcapi.compute_stop(context, instance, do_cast) diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index e8a0cbc280b7..a986b0415478 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -48,13 +48,14 @@ datetime_fields = ['launched_at', 'terminated_at'] class ConductorManager(manager.SchedulerDependentManager): """Mission: TBD.""" - RPC_API_VERSION = '1.42' + RPC_API_VERSION = '1.43' def __init__(self, *args, **kwargs): super(ConductorManager, self).__init__(service_name='conductor', *args, **kwargs) self.security_group_api = compute_api.SecurityGroupAPI() self._network_api = None + self._compute_api = None self.quotas = quota.QUOTAS @property @@ -66,6 +67,12 @@ class ConductorManager(manager.SchedulerDependentManager): self._network_api = network.API() return self._network_api + @property + def compute_api(self): + if self._compute_api is None: + self._compute_api = compute_api.API() + return self._compute_api + def ping(self, context, arg): return jsonutils.to_primitive({'service': 'conductor', 'arg': arg}) @@ -406,3 +413,6 @@ class ConductorManager(manager.SchedulerDependentManager): ec2_ids['%s-id' % image_type] = ec2_id return ec2_ids + + def compute_stop(self, context, instance, do_cast=True): + self.compute_api.stop(context, instance, do_cast) diff --git a/nova/conductor/rpcapi.py b/nova/conductor/rpcapi.py index d832b4f312bb..b82f2b8e1efb 100644 --- a/nova/conductor/rpcapi.py +++ b/nova/conductor/rpcapi.py @@ -79,6 +79,7 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy): instance_floating_address_get_all, quota_commit, quota_rollback 1.42 - Added get_ec2_ids, aggregate_metadata_get_by_host + 1.43 - Added compute_stop """ BASE_RPC_API_VERSION = '1.0' @@ -420,3 +421,9 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy): instance_p = jsonutils.to_primitive(instance) msg = self.make_msg('get_ec2_ids', instance=instance_p) return self.call(context, msg, version='1.42') + + def compute_stop(self, context, instance, do_cast=True): + instance_p = jsonutils.to_primitive(instance) + msg = self.make_msg('compute_stop', instance=instance_p, + do_cast=do_cast) + return self.call(context, msg, version='1.43') diff --git a/nova/tests/conductor/test_conductor.py b/nova/tests/conductor/test_conductor.py index 41554e79a1da..ed733599b22f 100644 --- a/nova/tests/conductor/test_conductor.py +++ b/nova/tests/conductor/test_conductor.py @@ -580,6 +580,12 @@ class _BaseTestCase(object): result = self.conductor.get_ec2_ids(self.context, inst) self.assertEqual(result, expected) + def test_compute_stop(self): + self.mox.StubOutWithMock(self.conductor_manager.compute_api, 'stop') + self.conductor_manager.compute_api.stop(self.context, 'instance', True) + self.mox.ReplayAll() + self.conductor.compute_stop(self.context, 'instance') + class ConductorTestCase(_BaseTestCase, test.TestCase): """Conductor Manager Tests."""