summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-01-11 01:15:48 +0000
committerGerrit Code Review <review@openstack.org>2013-01-11 01:15:48 +0000
commita4e290a0f17b1f773a9d53255857d19b02164bcd (patch)
tree4e3cf39413a3a5dc0853410144be1fa2be1066c9
parentbda08f6a0713951db60adf62e44739bdea093b17 (diff)
parent5731852f91c32fe09db541888d3fee9e3139fc43 (diff)
Merge "Move update_instance_info_cache to conductor."
-rw-r--r--nova/compute/manager.py15
-rw-r--r--nova/conductor/api.py9
-rw-r--r--nova/conductor/manager.py6
-rw-r--r--nova/conductor/rpcapi.py8
-rw-r--r--nova/network/api.py30
-rw-r--r--nova/network/quantumv2/api.py14
-rw-r--r--nova/tests/compute/test_compute.py43
-rw-r--r--nova/tests/conductor/test_conductor.py11
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')