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:
Dan Smith 2013-02-12 12:34:39 -05:00
parent 9994a9161d
commit 959e65f320
5 changed files with 33 additions and 4 deletions

View File

@ -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."),

View File

@ -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)

View File

@ -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)

View File

@ -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')

View File

@ -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."""