Make compute manager use conductor for stopping instances
During _sync_power_states, the manager will call to compute_api to stop instances as necessary. This takes a database hit, which isn't allowed. This directs that call through conductor, following the pattern of late. Fixes bug 1123219 Change-Id: I5d789dd73390cb1c41a245f6594b1c3aecf7efde
This commit is contained in:
parent
9994a9161d
commit
959e65f320
|
@ -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."),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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."""
|
||||
|
|
Loading…
Reference in New Issue