diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-01-11 01:15:48 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-01-11 01:15:48 +0000 |
| commit | a4e290a0f17b1f773a9d53255857d19b02164bcd (patch) | |
| tree | 4e3cf39413a3a5dc0853410144be1fa2be1066c9 | |
| parent | bda08f6a0713951db60adf62e44739bdea093b17 (diff) | |
| parent | 5731852f91c32fe09db541888d3fee9e3139fc43 (diff) | |
Merge "Move update_instance_info_cache to conductor."
| -rw-r--r-- | nova/compute/manager.py | 15 | ||||
| -rw-r--r-- | nova/conductor/api.py | 9 | ||||
| -rw-r--r-- | nova/conductor/manager.py | 6 | ||||
| -rw-r--r-- | nova/conductor/rpcapi.py | 8 | ||||
| -rw-r--r-- | nova/network/api.py | 30 | ||||
| -rw-r--r-- | nova/network/quantumv2/api.py | 14 | ||||
| -rw-r--r-- | nova/tests/compute/test_compute.py | 43 | ||||
| -rw-r--r-- | nova/tests/conductor/test_conductor.py | 11 |
8 files changed, 101 insertions, 35 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 9b743acc7..f138a3708 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -593,9 +593,15 @@ class ComputeManager(manager.SchedulerDependentManager): def _get_instance_nw_info(self, context, instance): """Get a list of dictionaries of network data of an instance.""" - # get the network info from network + # Get the network info from network API, but don't let it + # update the cache, as that will hit the DB. We'll update + # the cache ourselves via the conductor. network_info = self.network_api.get_instance_nw_info(context, - instance) + instance, update_cache=False) + cache = {'network_info': network_info.json()} + self.conductor_api.instance_info_cache_update(context, + instance, + cache) return network_info def _legacy_nw_info(self, network_info): @@ -1407,8 +1413,7 @@ class ComputeManager(manager.SchedulerDependentManager): expected_task_state=task_states.REBUILDING) instance['injected_files'] = injected_files - network_info = self.network_api.get_instance_nw_info(context, - instance) + network_info = self._get_instance_nw_info(context, instance) if bdms is None: capi = self.conductor_api bdms = capi.block_device_mapping_get_all_by_instance( @@ -3002,7 +3007,7 @@ class ComputeManager(manager.SchedulerDependentManager): try: # Call to network API to get instance info.. this will # force an update to the instance's info_cache - self.network_api.get_instance_nw_info(context, instance) + self._get_instance_nw_info(context, instance) LOG.debug(_('Updated the info_cache for instance'), instance=instance) except Exception: diff --git a/nova/conductor/api.py b/nova/conductor/api.py index 4a72f81e0..04a4f3d9c 100644 --- a/nova/conductor/api.py +++ b/nova/conductor/api.py @@ -107,6 +107,11 @@ class LocalAPI(object): return self._manager.instance_get_active_by_window( context, begin, end, project_id, host) + def instance_info_cache_update(self, context, instance, values): + return self._manager.instance_info_cache_update(context, + instance, + values) + def instance_info_cache_delete(self, context, instance): return self._manager.instance_info_cache_delete(context, instance) @@ -291,6 +296,10 @@ class API(object): return self.conductor_rpcapi.instance_get_active_by_window( context, begin, end, project_id, host) + def instance_info_cache_update(self, context, instance, values): + return self.conductor_rpcapi.instance_info_cache_update(context, + instance, values) + def instance_info_cache_delete(self, context, instance): return self.conductor_rpcapi.instance_info_cache_delete(context, instance) diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 3c26f320e..fb583d0ce 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -43,7 +43,7 @@ datetime_fields = ['launched_at', 'terminated_at'] class ConductorManager(manager.SchedulerDependentManager): """Mission: TBD.""" - RPC_API_VERSION = '1.25' + RPC_API_VERSION = '1.26' def __init__(self, *args, **kwargs): super(ConductorManager, self).__init__(service_name='conductor', @@ -229,6 +229,10 @@ class ConductorManager(manager.SchedulerDependentManager): def instance_info_cache_delete(self, context, instance): self.db.instance_info_cache_delete(context, instance['uuid']) + def instance_info_cache_update(self, context, instance, values): + self.db.instance_info_cache_update(context, instance['uuid'], + values) + def instance_type_get(self, context, instance_type_id): result = self.db.instance_type_get(context, instance_type_id) return jsonutils.to_primitive(result) diff --git a/nova/conductor/rpcapi.py b/nova/conductor/rpcapi.py index 6b91de167..8850bca01 100644 --- a/nova/conductor/rpcapi.py +++ b/nova/conductor/rpcapi.py @@ -58,6 +58,7 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy): Un-Deprecate instance_get_all_by_host 1.24 - Added instance_get 1.25 - Added action_event_start and action_event_finish + 1.26 - Added instance_info_cache_update """ BASE_RPC_API_VERSION = '1.0' @@ -270,3 +271,10 @@ class ConductorAPI(nova.openstack.common.rpc.proxy.RpcProxy): def action_event_finish(self, context, values): msg = self.make_msg('action_event_finish', values=values) return self.call(context, msg, version='1.25') + + def instance_info_cache_update(self, context, instance, values): + instance_p = jsonutils.to_primitive(instance) + msg = self.make_msg('instance_info_cache_update', + instance=instance_p, + values=values) + return self.call(context, msg, version='1.26') diff --git a/nova/network/api.py b/nova/network/api.py index ec58e1101..25680e656 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -50,11 +50,8 @@ def refresh_cache(f): msg = _('instance is a required argument to use @refresh_cache') raise Exception(msg) - # get nw_info from return if possible, otherwise call for it - nw_info = res if isinstance(res, network_model.NetworkInfo) else None - - update_instance_cache_with_nw_info(self, context, instance, nw_info, - *args, **kwargs) + update_instance_cache_with_nw_info(self, context, instance, + nw_info=res) # return the original function's return value return res @@ -62,20 +59,18 @@ def refresh_cache(f): def update_instance_cache_with_nw_info(api, context, instance, - nw_info=None, - *args, - **kwargs): + nw_info=None): try: - nw_info = nw_info or api._get_instance_nw_info(context, instance) - + if not isinstance(nw_info, network_model.NetworkInfo): + nw_info = None + if not nw_info: + nw_info = api._get_instance_nw_info(context, instance) # update cache cache = {'network_info': nw_info.json()} api.db.instance_info_cache_update(context, instance['uuid'], cache) - except Exception as e: + except Exception: LOG.exception(_('Failed storing info cache'), instance=instance) - LOG.debug(_('args: %s') % (args or {})) - LOG.debug(_('kwargs: %s') % (kwargs or {})) class API(base.Base): @@ -243,10 +238,13 @@ class API(base.Base): associations['project'] = project self.network_rpcapi.associate(context, network_uuid, associations) - @refresh_cache - def get_instance_nw_info(self, context, instance): + def get_instance_nw_info(self, context, instance, update_cache=True): """Returns all network info related to an instance.""" - return self._get_instance_nw_info(context, instance) + result = self._get_instance_nw_info(context, instance) + if update_cache: + update_instance_cache_with_nw_info(self, context, instance, + result) + return result def _get_instance_nw_info(self, context, instance): """Returns all network info related to an instance.""" diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py index 064ae0427..51386b4fd 100644 --- a/nova/network/quantumv2/api.py +++ b/nova/network/quantumv2/api.py @@ -19,7 +19,7 @@ from nova.compute import api as compute_api from nova.db import base from nova import exception -from nova.network.api import refresh_cache +from nova.network import api as network_api from nova.network import model as network_model from nova.network import quantumv2 from nova.openstack.common import cfg @@ -57,6 +57,9 @@ LOG = logging.getLogger(__name__) NET_EXTERNAL = 'router:external' +refresh_cache = network_api.refresh_cache +update_instance_info_cache = network_api.update_instance_cache_with_nw_info + class API(base.Base): """API for interacting with the quantum 2.x API.""" @@ -181,9 +184,12 @@ class API(base.Base): self.trigger_security_group_members_refresh(context, instance) self.trigger_instance_remove_security_group_refresh(context, instance) - @refresh_cache - def get_instance_nw_info(self, context, instance, networks=None): - return self._get_instance_nw_info(context, instance, networks) + def get_instance_nw_info(self, context, instance, networks=None, + update_cache=True): + result = self._get_instance_nw_info(context, instance, networks) + if update_cache: + update_instance_info_cache(self, context, instance, result) + return result def _get_instance_nw_info(self, context, instance, networks=None): LOG.debug(_('get_instance_nw_info() for %s'), diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index ecd3f29d7..28c026da3 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -2782,6 +2782,31 @@ class ComputeTestCase(BaseTestCase): val = self.compute._running_deleted_instances('context') self.assertEqual(val, [instance1]) + def test_get_instance_nw_info(self): + fake_network.unset_stub_network_methods(self.stubs) + + fake_instance = 'fake-instance' + fake_nw_info = network_model.NetworkInfo() + + self.mox.StubOutWithMock(self.compute.network_api, + 'get_instance_nw_info') + self.mox.StubOutWithMock(fake_nw_info, 'json') + self.mox.StubOutWithMock(self.compute.conductor_api, + 'instance_info_cache_update') + + self.compute.network_api.get_instance_nw_info(self.context, + fake_instance, update_cache=False).AndReturn(fake_nw_info) + fake_nw_info.json().AndReturn('fake-nw-info') + expected_cache = {'network_info': 'fake-nw-info'} + self.compute.conductor_api.instance_info_cache_update(self.context, + fake_instance, expected_cache) + + self.mox.ReplayAll() + + result = self.compute._get_instance_nw_info(self.context, + fake_instance) + self.assertEqual(fake_nw_info, result) + def test_heal_instance_info_cache(self): # Update on every call for the test self.flags(heal_instance_info_cache_interval=-1) @@ -2813,27 +2838,27 @@ class ComputeTestCase(BaseTestCase): # and is ignored. However, the below increment of # 'get_nw_info' won't happen, and you'll get an assert # failure checking it below. - self.assertEqual(instance, call_info['expected_instance']) + self.assertEqual(call_info['expected_instance'], instance) call_info['get_nw_info'] += 1 self.stubs.Set(self.compute.conductor_api, 'instance_get_all_by_host', fake_instance_get_all_by_host) - self.stubs.Set(db, 'instance_get_by_uuid', + self.stubs.Set(self.compute.conductor_api, 'instance_get_by_uuid', fake_instance_get_by_uuid) - self.stubs.Set(self.compute.network_api, 'get_instance_nw_info', + self.stubs.Set(self.compute, '_get_instance_nw_info', fake_get_instance_nw_info) call_info['expected_instance'] = instances[0] self.compute._heal_instance_info_cache(ctxt) - self.assertEqual(call_info['get_all_by_host'], 1) - self.assertEqual(call_info['get_by_uuid'], 0) - self.assertEqual(call_info['get_nw_info'], 1) + self.assertEqual(1, call_info['get_all_by_host']) + self.assertEqual(0, call_info['get_by_uuid']) + self.assertEqual(1, call_info['get_nw_info']) call_info['expected_instance'] = instances[1] self.compute._heal_instance_info_cache(ctxt) - self.assertEqual(call_info['get_all_by_host'], 1) - self.assertEqual(call_info['get_by_uuid'], 1) - self.assertEqual(call_info['get_nw_info'], 2) + self.assertEqual(1, call_info['get_all_by_host']) + self.assertEqual(1, call_info['get_by_uuid']) + self.assertEqual(2, call_info['get_nw_info']) # Make an instance switch hosts instances[2]['host'] = 'not-me' diff --git a/nova/tests/conductor/test_conductor.py b/nova/tests/conductor/test_conductor.py index 3e7f33e85..ffe09c95e 100644 --- a/nova/tests/conductor/test_conductor.py +++ b/nova/tests/conductor/test_conductor.py @@ -324,6 +324,17 @@ class _BaseTestCase(object): self.conductor.instance_info_cache_delete(self.context, {'uuid': 'fake-uuid'}) + def test_instance_info_cache_update(self): + fake_values = {'key1': 'val1', 'key2': 'val2'} + fake_instance = {'uuid': 'fake-uuid'} + self.mox.StubOutWithMock(db, 'instance_info_cache_update') + db.instance_info_cache_update(self.context, 'fake-uuid', + fake_values) + self.mox.ReplayAll() + self.conductor.instance_info_cache_update(self.context, + fake_instance, + fake_values) + def test_instance_type_get(self): self.mox.StubOutWithMock(db, 'instance_type_get') db.instance_type_get(self.context, 'fake-id').AndReturn('fake-type') |
