From d030e29f5b0ba215789739e443f25ca1c80bc3da Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Fri, 20 Jul 2012 10:45:04 -0400 Subject: Include name in a primitive Instance. This ensures that the name of an instance will be present in the result of jsonutils.to_primitive(Instance). The name isn't a column. It's a property that gets generated dynamically by the Instance class. Part of blueprint no-db-messaging. Change-Id: I45914ed55f2c037ee2efd7775bd57fbde36a2116 --- nova/db/sqlalchemy/models.py | 20 ++++++++++++++++---- nova/tests/compute/test_rpcapi.py | 15 +++++++++------ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 3ad6e71dd..5f7e85511 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -76,11 +76,17 @@ class NovaBase(object): return getattr(self, key, default) def __iter__(self): - self._i = iter(object_mapper(self).columns) + columns = dict(object_mapper(self).columns).keys() + # NOTE(russellb): Allow models to specify other keys that can be looked + # up, beyond the actual db columns. An example would be the 'name' + # property for an Instance. + if hasattr(self, '_extra_keys'): + columns.extend(self._extra_keys()) + self._i = iter(columns) return self def next(self): - n = self._i.next().name + n = self._i.next() return n, getattr(self, n) def update(self, values): @@ -183,12 +189,15 @@ class Instance(BASE, NovaBase): except TypeError: # Support templates like "uuid-%(uuid)s", etc. info = {} - for key, value in self.iteritems(): + # NOTE(russellb): Don't use self.iteritems() here, as it will + # result in infinite recursion on the name property. + for column in iter(object_mapper(self).columns): + key = column.name # prevent recursion if someone specifies %(name)s # %(name)s will not be valid. if key == 'name': continue - info[key] = value + info[key] = self[key] try: base_name = FLAGS.instance_name_template % info except KeyError: @@ -197,6 +206,9 @@ class Instance(BASE, NovaBase): base_name += "-rescue" return base_name + def _extra_keys(self): + return ['name'] + user_id = Column(String(255)) project_id = Column(String(255)) diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index d1d633023..96b103393 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -20,7 +20,9 @@ Unit Tests for nova.compute.rpcapi from nova.compute import rpcapi as compute_rpcapi from nova import context +from nova import db from nova import flags +from nova.openstack.common import jsonutils from nova.openstack.common import rpc from nova import test @@ -31,17 +33,18 @@ FLAGS = flags.FLAGS class ComputeRpcAPITestCase(test.TestCase): def setUp(self): - self.fake_instance = { - 'uuid': 'fake_uuid', - 'host': 'fake_host', - 'name': 'fake_name', - 'id': 'fake_id', - } + self.context = context.get_admin_context() + inst = db.instance_create(self.context, {'host': 'fake_host', + 'instance_type_id': 1}) + self.fake_instance = jsonutils.to_primitive(inst) super(ComputeRpcAPITestCase, self).setUp() def tearDown(self): super(ComputeRpcAPITestCase, self).tearDown() + def test_serialized_instance_has_name(self): + self.assertTrue('name' in self.fake_instance) + def _test_compute_api(self, method, rpc_method, **kwargs): ctxt = context.RequestContext('fake_user', 'fake_project') if 'rpcapi_class' in kwargs: -- cgit From 6aac5f1308aa3e360204bd8f4dcfe90522f6db2e Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Fri, 20 Jul 2012 10:56:29 -0400 Subject: Convert reboot_instance to take a full instance. Convert the reboot_instance method in the compute rpc API to take a full instance via rpc instead of just the instance UUID. This cuts down on database access needed by nova-compute. Part of blueprint no-db-messaging. Change-Id: Id2c455f66966a9b446e5bbbe542ed3a2b0655289 --- nova/compute/manager.py | 14 +++++++------- nova/compute/rpcapi.py | 8 ++++++-- nova/tests/compute/test_compute.py | 17 ++++++++++------- nova/tests/compute/test_rpcapi.py | 8 ++++++-- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 3e66bd20f..067bc584b 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -297,7 +297,7 @@ def _get_additional_capabilities(): class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" - RPC_API_VERSION = '1.3' + RPC_API_VERSION = '1.4' def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -1090,18 +1090,19 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock @wrap_instance_fault - def reboot_instance(self, context, instance_uuid, reboot_type="SOFT"): + def reboot_instance(self, context, instance=None, instance_uuid=None, + reboot_type="SOFT"): """Reboot an instance on this host.""" LOG.audit(_("Rebooting instance"), context=context, instance_uuid=instance_uuid) context = context.elevated() - instance = self.db.instance_get_by_uuid(context, instance_uuid) + if not instance: + instance = self.db.instance_get_by_uuid(context, instance_uuid) self._notify_about_instance_usage(context, instance, "reboot.start") current_power_state = self._get_power_state(context, instance) - self._instance_update(context, - instance_uuid, + self._instance_update(context, instance['uuid'], power_state=current_power_state, vm_state=vm_states.ACTIVE) @@ -1125,8 +1126,7 @@ class ComputeManager(manager.SchedulerDependentManager): # Fall through and reset task_state to None current_power_state = self._get_power_state(context, instance) - self._instance_update(context, - instance_uuid, + self._instance_update(context, instance['uuid'], power_state=current_power_state, vm_state=vm_states.ACTIVE, task_state=None) diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index e637c9f64..296ee476c 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -20,6 +20,7 @@ Client side of the compute RPC API. from nova import exception from nova import flags +from nova.openstack.common import jsonutils from nova.openstack.common import rpc from nova.openstack.common.rpc import common as rpc_common import nova.openstack.common.rpc.proxy @@ -58,6 +59,7 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): 1.1 - Adds get_host_uptime() 1.2 - Adds check_can_live_migrate_[destination|source] 1.3 - Adds change_instance_metadata() + 1.4 - Remove instance_uuid, add instance argument to reboot_instance() ''' BASE_RPC_API_VERSION = '1.0' @@ -235,9 +237,11 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): disk=disk), _compute_topic(self.topic, ctxt, host, None)) def reboot_instance(self, ctxt, instance, reboot_type): + instance_p = jsonutils.to_primitive(instance) self.cast(ctxt, self.make_msg('reboot_instance', - instance_uuid=instance['uuid'], reboot_type=reboot_type), - topic=_compute_topic(self.topic, ctxt, None, instance)) + instance=instance_p, reboot_type=reboot_type), + topic=_compute_topic(self.topic, ctxt, None, instance), + version='1.4') def rebuild_instance(self, ctxt, instance, new_pass, injected_files, image_ref, orig_image_ref): diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index f6bc0ee4f..93eb644c6 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -40,6 +40,7 @@ from nova import db from nova import exception from nova import flags from nova.openstack.common import importutils +from nova.openstack.common import jsonutils from nova.openstack.common import log as logging from nova.openstack.common.notifier import test_notifier from nova.openstack.common import policy as common_policy @@ -539,8 +540,9 @@ class ComputeTestCase(BaseTestCase): {'task_state': task_states.REBOOTING}) reboot_type = "SOFT" - self.compute.reboot_instance(self.context, instance['uuid'], - reboot_type) + self.compute.reboot_instance(self.context, + instance=jsonutils.to_primitive(instance), + reboot_type=reboot_type) inst_ref = db.instance_get_by_uuid(self.context, instance['uuid']) self.assertEqual(inst_ref['power_state'], power_state.RUNNING) @@ -556,8 +558,9 @@ class ComputeTestCase(BaseTestCase): {'task_state': task_states.REBOOTING_HARD}) reboot_type = "HARD" - self.compute.reboot_instance(self.context, instance['uuid'], - reboot_type) + self.compute.reboot_instance(self.context, + instance=jsonutils.to_primitive(instance), + reboot_type=reboot_type) inst_ref = db.instance_get_by_uuid(self.context, instance['uuid']) self.assertEqual(inst_ref['power_state'], power_state.RUNNING) @@ -1018,7 +1021,7 @@ class ComputeTestCase(BaseTestCase): self.compute.terminate_instance(self.context, instance['uuid']) def test_get_lock(self): - instance = self._create_fake_instance() + instance = jsonutils.to_primitive(self._create_fake_instance()) self.assertFalse(self.compute._get_lock(self.context, instance['uuid'])) db.instance_update(self.context, instance['uuid'], {'locked': True}) @@ -1037,13 +1040,13 @@ class ComputeTestCase(BaseTestCase): # decorator should return False (fail) with locked nonadmin context self.compute.lock_instance(self.context, instance_uuid) ret_val = self.compute.reboot_instance(non_admin_context, - instance_uuid) + instance=jsonutils.to_primitive(instance)) self.assertEqual(ret_val, False) # decorator should return None (success) with unlocked nonadmin context self.compute.unlock_instance(self.context, instance_uuid) ret_val = self.compute.reboot_instance(non_admin_context, - instance_uuid) + instance=jsonutils.to_primitive(instance)) self.assertEqual(ret_val, None) self.compute.terminate_instance(self.context, instance_uuid) diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index 96b103393..080128f47 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -47,6 +47,9 @@ class ComputeRpcAPITestCase(test.TestCase): def _test_compute_api(self, method, rpc_method, **kwargs): ctxt = context.RequestContext('fake_user', 'fake_project') + + methods_with_instance = ['reboot_instance'] + if 'rpcapi_class' in kwargs: rpcapi_class = kwargs['rpcapi_class'] del kwargs['rpcapi_class'] @@ -65,7 +68,8 @@ class ComputeRpcAPITestCase(test.TestCase): del expected_msg['args']['host'] if 'destination' in expected_msg['args']: del expected_msg['args']['destination'] - if 'instance' in expected_msg['args']: + if 'instance' in expected_msg['args'] and (method not in + methods_with_instance): instance = expected_msg['args']['instance'] del expected_msg['args']['instance'] if method in ['rollback_live_migration_at_destination', @@ -219,7 +223,7 @@ class ComputeRpcAPITestCase(test.TestCase): def test_reboot_instance(self): self._test_compute_api('reboot_instance', 'cast', - instance=self.fake_instance, reboot_type='type') + instance=self.fake_instance, reboot_type='type', version='1.4') def test_rebuild_instance(self): self._test_compute_api('rebuild_instance', 'cast', -- cgit From f5289971b7da19111ca6a68bb46c1108ea46664b Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Fri, 20 Jul 2012 13:50:00 -0400 Subject: Don't use rpc to lock/unlock an instance. Instead of converting this method to send a full instance over rpc instead of just an instance UUID, this patch removes the usage of rpc for this operation entirely. All it's doing is a database update. RPC is expensive, so cut out the middle-man. One functional difference with this approach is that the db update is now synchronous on the API node, instead of kicking off an async message to a compute node to handle it. This seems fine, though. Part of blueprint no-db-messaging. Change-Id: I15ceb7625425ab097eebd5b7dd3606a171329f97 --- nova/compute/api.py | 19 +++++++++++++++++-- nova/compute/manager.py | 14 ++++++++++++-- nova/compute/rpcapi.py | 10 ---------- nova/tests/compute/test_compute.py | 5 +++-- nova/tests/compute/test_rpcapi.py | 8 -------- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 7cdb8d167..0571c7313 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -130,6 +130,15 @@ class API(base.Base): self.compute_rpcapi = compute_rpcapi.ComputeAPI() super(API, self).__init__(**kwargs) + def _instance_update(self, context, instance_uuid, **kwargs): + """Update an instance in the database using kwargs as value.""" + + (old_ref, instance_ref) = self.db.instance_update_and_get_original( + context, instance_uuid, kwargs) + notifications.send_update(context, old_ref, instance_ref) + + return instance_ref + def _check_injected_file_quota(self, context, injected_files): """Enforce quota limits on injected files. @@ -1531,12 +1540,18 @@ class API(base.Base): @wrap_check_policy def lock(self, context, instance): """Lock the given instance.""" - self.compute_rpcapi.lock_instance(context, instance=instance) + context = context.elevated() + instance_uuid = instance['uuid'] + LOG.debug(_('Locking'), context=context, instance_uuid=instance_uuid) + self._instance_update(context, instance_uuid, locked=True) @wrap_check_policy def unlock(self, context, instance): """Unlock the given instance.""" - self.compute_rpcapi.unlock_instance(context, instance=instance) + context = context.elevated() + instance_uuid = instance['uuid'] + LOG.debug(_('Unlocking'), context=context, instance_uuid=instance_uuid) + self._instance_update(context, instance_uuid, locked=False) @wrap_check_policy def get_lock(self, context, instance): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 067bc584b..cced8509b 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1821,7 +1821,12 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @wrap_instance_fault def lock_instance(self, context, instance_uuid): - """Lock the given instance.""" + """Lock the given instance. + + This isn't actually used in the current code. The same thing is now + done directly in nova.compute.api. This must stay here for backwards + compatibility of the rpc API. + """ context = context.elevated() LOG.debug(_('Locking'), context=context, instance_uuid=instance_uuid) @@ -1830,7 +1835,12 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @wrap_instance_fault def unlock_instance(self, context, instance_uuid): - """Unlock the given instance.""" + """Unlock the given instance. + + This isn't actually used in the current code. The same thing is now + done directly in nova.compute.api. This must stay here for backwards + compatibility of the rpc API. + """ context = context.elevated() LOG.debug(_('Unlocking'), context=context, instance_uuid=instance_uuid) diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index 296ee476c..e480ee20d 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -203,11 +203,6 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): instance_uuid=instance['uuid']), topic=_compute_topic(self.topic, ctxt, None, instance)) - def lock_instance(self, ctxt, instance): - self.cast(ctxt, self.make_msg('lock_instance', - instance_uuid=instance['uuid']), - topic=_compute_topic(self.topic, ctxt, None, instance)) - def post_live_migration_at_destination(self, ctxt, instance, block_migration, host): return self.call(ctxt, @@ -365,11 +360,6 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): instance_uuid=instance['uuid']), topic=_compute_topic(self.topic, ctxt, None, instance)) - def unlock_instance(self, ctxt, instance): - self.cast(ctxt, self.make_msg('unlock_instance', - instance_uuid=instance['uuid']), - topic=_compute_topic(self.topic, ctxt, None, instance)) - def unpause_instance(self, ctxt, instance): self.cast(ctxt, self.make_msg('unpause_instance', instance_uuid=instance['uuid']), diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 93eb644c6..c9110176d 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -213,6 +213,7 @@ class ComputeTestCase(BaseTestCase): fake_get_nw_info) self.stubs.Set(nova.network.API, 'allocate_for_instance', fake_get_nw_info) + self.compute_api = compute.API() def tearDown(self): super(ComputeTestCase, self).tearDown() @@ -1038,13 +1039,13 @@ class ComputeTestCase(BaseTestCase): is_admin=False) # decorator should return False (fail) with locked nonadmin context - self.compute.lock_instance(self.context, instance_uuid) + self.compute_api.lock(self.context, instance) ret_val = self.compute.reboot_instance(non_admin_context, instance=jsonutils.to_primitive(instance)) self.assertEqual(ret_val, False) # decorator should return None (success) with unlocked nonadmin context - self.compute.unlock_instance(self.context, instance_uuid) + self.compute_api.unlock(self.context, instance) ret_val = self.compute.reboot_instance(non_admin_context, instance=jsonutils.to_primitive(instance)) self.assertEqual(ret_val, None) diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index 080128f47..488119116 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -195,10 +195,6 @@ class ComputeRpcAPITestCase(test.TestCase): self._test_compute_api('inject_network_info', 'cast', instance=self.fake_instance) - def test_lock_instance(self): - self._test_compute_api('lock_instance', 'cast', - instance=self.fake_instance) - def test_post_live_migration_at_destination(self): self._test_compute_api('post_live_migration_at_destination', 'call', instance=self.fake_instance, block_migration='block_migration', @@ -318,10 +314,6 @@ class ComputeRpcAPITestCase(test.TestCase): self._test_compute_api('terminate_instance', 'cast', instance=self.fake_instance) - def test_unlock_instance(self): - self._test_compute_api('unlock_instance', 'cast', - instance=self.fake_instance) - def test_unpause_instance(self): self._test_compute_api('unpause_instance', 'cast', instance=self.fake_instance) -- cgit From 94018d1f753d62ba75f3262f2c2fcdb1ee7f731b Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Fri, 20 Jul 2012 14:08:10 -0400 Subject: Send a full instance via rpc for (un)pause_instance. Change the pause_instance and unpause_instance methods of the compute rpc API to take a full instance over rpc instead of just the instance UUID. This cuts down on database access needed by nova-compute. Part of blueprint no-db-messaging. Change-Id: Ia7e31428c7d2edb9a0c4d0958f1c7774742ea1cd --- nova/compute/manager.py | 28 +++++++++++++++------------- nova/compute/rpcapi.py | 14 ++++++++++---- nova/tests/compute/test_compute.py | 9 ++++++--- nova/tests/compute/test_rpcapi.py | 8 +++++--- 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index cced8509b..9ebfe496b 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -297,7 +297,7 @@ def _get_additional_capabilities(): class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" - RPC_API_VERSION = '1.4' + RPC_API_VERSION = '1.5' def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -1713,17 +1713,18 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock @wrap_instance_fault - def pause_instance(self, context, instance_uuid): + def pause_instance(self, context, instance=None, instance_uuid=None): """Pause an instance on this host.""" context = context.elevated() - instance_ref = self.db.instance_get_by_uuid(context, instance_uuid) + if not instance: + instance = self.db.instance_get_by_uuid(context, instance_uuid) - LOG.audit(_('Pausing'), context=context, instance=instance_ref) - self.driver.pause(instance_ref) + LOG.audit(_('Pausing'), context=context, instance=instance) + self.driver.pause(instance) - current_power_state = self._get_power_state(context, instance_ref) + current_power_state = self._get_power_state(context, instance) self._instance_update(context, - instance_ref['uuid'], + instance['uuid'], power_state=current_power_state, vm_state=vm_states.PAUSED, task_state=None) @@ -1731,17 +1732,18 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock @wrap_instance_fault - def unpause_instance(self, context, instance_uuid): + def unpause_instance(self, context, instance=None, instance_uuid=None): """Unpause a paused instance on this host.""" context = context.elevated() - instance_ref = self.db.instance_get_by_uuid(context, instance_uuid) + if not instance: + instance = self.db.instance_get_by_uuid(context, instance_uuid) - LOG.audit(_('Unpausing'), context=context, instance=instance_ref) - self.driver.unpause(instance_ref) + LOG.audit(_('Unpausing'), context=context, instance=instance) + self.driver.unpause(instance) - current_power_state = self._get_power_state(context, instance_ref) + current_power_state = self._get_power_state(context, instance) self._instance_update(context, - instance_ref['uuid'], + instance['uuid'], power_state=current_power_state, vm_state=vm_states.ACTIVE, task_state=None) diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index e480ee20d..d5de04452 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -60,6 +60,8 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): 1.2 - Adds check_can_live_migrate_[destination|source] 1.3 - Adds change_instance_metadata() 1.4 - Remove instance_uuid, add instance argument to reboot_instance() + 1.5 - Remove instance_uuid, add instance argument to pause_instance(), + unpause_instance() ''' BASE_RPC_API_VERSION = '1.0' @@ -211,9 +213,11 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): _compute_topic(self.topic, ctxt, host, None)) def pause_instance(self, ctxt, instance): + instance_p = jsonutils.to_primitive(instance) self.cast(ctxt, self.make_msg('pause_instance', - instance_uuid=instance['uuid']), - topic=_compute_topic(self.topic, ctxt, None, instance)) + instance=instance_p), + topic=_compute_topic(self.topic, ctxt, None, instance), + version='1.5') def power_off_instance(self, ctxt, instance): self.cast(ctxt, self.make_msg('power_off_instance', @@ -361,9 +365,11 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): topic=_compute_topic(self.topic, ctxt, None, instance)) def unpause_instance(self, ctxt, instance): + instance_p = jsonutils.to_primitive(instance) self.cast(ctxt, self.make_msg('unpause_instance', - instance_uuid=instance['uuid']), - topic=_compute_topic(self.topic, ctxt, None, instance)) + instance=instance_p), + topic=_compute_topic(self.topic, ctxt, None, instance), + version='1.5') def unrescue_instance(self, ctxt, instance): self.cast(ctxt, self.make_msg('unrescue_instance', diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index c9110176d..0c4d07e8e 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -492,8 +492,10 @@ class ComputeTestCase(BaseTestCase): instance = self._create_fake_instance() instance_uuid = instance['uuid'] self.compute.run_instance(self.context, instance_uuid) - self.compute.pause_instance(self.context, instance_uuid) - self.compute.unpause_instance(self.context, instance_uuid) + self.compute.pause_instance(self.context, + instance=jsonutils.to_primitive(instance)) + self.compute.unpause_instance(self.context, + instance=jsonutils.to_primitive(instance)) self.compute.terminate_instance(self.context, instance_uuid) def test_suspend(self): @@ -2544,7 +2546,8 @@ class ComputeAPITestCase(BaseTestCase): self.assertEqual(instance['task_state'], None) - self.compute.pause_instance(self.context, instance_uuid) + self.compute.pause_instance(self.context, + instance=jsonutils.to_primitive(instance)) # set the state that the instance gets when pause finishes instance = db.instance_update(self.context, instance['uuid'], {'vm_state': vm_states.PAUSED}) diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index 488119116..72942d352 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -48,7 +48,9 @@ class ComputeRpcAPITestCase(test.TestCase): def _test_compute_api(self, method, rpc_method, **kwargs): ctxt = context.RequestContext('fake_user', 'fake_project') - methods_with_instance = ['reboot_instance'] + methods_with_instance = [ + 'pause_instance', 'reboot_instance', 'unpause_instance' + ] if 'rpcapi_class' in kwargs: rpcapi_class = kwargs['rpcapi_class'] @@ -202,7 +204,7 @@ class ComputeRpcAPITestCase(test.TestCase): def test_pause_instance(self): self._test_compute_api('pause_instance', 'cast', - instance=self.fake_instance) + instance=self.fake_instance, version='1.5') def test_power_off_instance(self): self._test_compute_api('power_off_instance', 'cast', @@ -316,7 +318,7 @@ class ComputeRpcAPITestCase(test.TestCase): def test_unpause_instance(self): self._test_compute_api('unpause_instance', 'cast', - instance=self.fake_instance) + instance=self.fake_instance, version='1.5') def test_unrescue_instance(self): self._test_compute_api('unrescue_instance', 'cast', -- cgit From 1d0362929d2bbb39a5665b0d0ce9972ca66c643b Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Fri, 20 Jul 2012 15:58:49 -0400 Subject: Send a full instance via rpc for suspend_instance. Change the suspend_instance method of the compute rpc API to take a full instance over rpc instead of just the instance UUID. This cuts down on database access needed by nova-compute. Part of blueprint no-db-messaging. Change-Id: If881fb419a52a2486b2e7b85b4d58a17f72c48a6 --- nova/compute/manager.py | 17 +++++++++-------- nova/compute/rpcapi.py | 7 +++++-- nova/tests/compute/test_compute.py | 3 ++- nova/tests/compute/test_rpcapi.py | 5 +++-- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 9ebfe496b..368556dea 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -297,7 +297,7 @@ def _get_additional_capabilities(): class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" - RPC_API_VERSION = '1.5' + RPC_API_VERSION = '1.6' def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -1783,22 +1783,23 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock @wrap_instance_fault - def suspend_instance(self, context, instance_uuid): + def suspend_instance(self, context, instance=None, instance_uuid=None): """Suspend the given instance.""" context = context.elevated() - instance_ref = self.db.instance_get_by_uuid(context, instance_uuid) + if not instance: + instance = self.db.instance_get_by_uuid(context, instance_uuid) - LOG.audit(_('Suspending'), context=context, instance=instance_ref) - self.driver.suspend(instance_ref) + LOG.audit(_('Suspending'), context=context, instance=instance) + self.driver.suspend(instance) - current_power_state = self._get_power_state(context, instance_ref) + current_power_state = self._get_power_state(context, instance) self._instance_update(context, - instance_ref['uuid'], + instance['uuid'], power_state=current_power_state, vm_state=vm_states.SUSPENDED, task_state=None) - self._notify_about_instance_usage(context, instance_ref, 'suspend') + self._notify_about_instance_usage(context, instance, 'suspend') @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index d5de04452..c893bb0d5 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -62,6 +62,7 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): 1.4 - Remove instance_uuid, add instance argument to reboot_instance() 1.5 - Remove instance_uuid, add instance argument to pause_instance(), unpause_instance() + 1.6 - Remove instance_uuid, add instance argument to suspend_instance() ''' BASE_RPC_API_VERSION = '1.0' @@ -355,9 +356,11 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): topic=_compute_topic(self.topic, ctxt, None, instance)) def suspend_instance(self, ctxt, instance): + instance_p = jsonutils.to_primitive(instance) self.cast(ctxt, self.make_msg('suspend_instance', - instance_uuid=instance['uuid']), - topic=_compute_topic(self.topic, ctxt, None, instance)) + instance=instance_p), + topic=_compute_topic(self.topic, ctxt, None, instance), + version='1.6') def terminate_instance(self, ctxt, instance): self.cast(ctxt, self.make_msg('terminate_instance', diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 0c4d07e8e..63af3813b 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -503,7 +503,8 @@ class ComputeTestCase(BaseTestCase): instance = self._create_fake_instance() instance_uuid = instance['uuid'] self.compute.run_instance(self.context, instance_uuid) - self.compute.suspend_instance(self.context, instance_uuid) + self.compute.suspend_instance(self.context, + instance=jsonutils.to_primitive(instance)) self.compute.resume_instance(self.context, instance_uuid) self.compute.terminate_instance(self.context, instance_uuid) diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index 72942d352..5c0fcd006 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -49,7 +49,8 @@ class ComputeRpcAPITestCase(test.TestCase): ctxt = context.RequestContext('fake_user', 'fake_project') methods_with_instance = [ - 'pause_instance', 'reboot_instance', 'unpause_instance' + 'pause_instance', 'reboot_instance', 'suspend_instance', + 'unpause_instance' ] if 'rpcapi_class' in kwargs: @@ -310,7 +311,7 @@ class ComputeRpcAPITestCase(test.TestCase): def test_suspend_instance(self): self._test_compute_api('suspend_instance', 'cast', - instance=self.fake_instance) + instance=self.fake_instance, version='1.6') def test_terminate_instance(self): self._test_compute_api('terminate_instance', 'cast', -- cgit From a43909352f2ef8c4a3fc540f8952ab2defa09ad6 Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Fri, 20 Jul 2012 16:03:18 -0400 Subject: Send a full instance via rpc for get_console_output. Change the get_console_output method of the compute rpc API to take a full instance over rpc instead of just the instance UUID. This cuts down on database access needed by nova-compute. Part of blueprint no-db-messaging. Change-Id: I114081fceddc2c7226aab9bd560f3664000a43af --- nova/compute/manager.py | 12 +++++++----- nova/compute/rpcapi.py | 8 ++++++-- nova/tests/compute/test_compute.py | 9 ++++----- nova/tests/compute/test_rpcapi.py | 6 +++--- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 368556dea..bb75efc5a 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -297,7 +297,7 @@ def _get_additional_capabilities(): class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" - RPC_API_VERSION = '1.6' + RPC_API_VERSION = '1.7' def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -1885,14 +1885,16 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @wrap_instance_fault - def get_console_output(self, context, instance_uuid, tail_length=None): + def get_console_output(self, context, instance=None, instance_uuid=None, + tail_length=None): """Send the console output for the given instance.""" context = context.elevated() - instance_ref = self.db.instance_get_by_uuid(context, instance_uuid) + if not instance: + instance = self.db.instance_get_by_uuid(context, instance_uuid) LOG.audit(_("Get console output"), context=context, - instance=instance_ref) - output = self.driver.get_console_output(instance_ref) + instance=instance) + output = self.driver.get_console_output(instance) if tail_length is not None: output = self._tail_log(output, tail_length) diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index c893bb0d5..4d5e495d6 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -63,6 +63,8 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): 1.5 - Remove instance_uuid, add instance argument to pause_instance(), unpause_instance() 1.6 - Remove instance_uuid, add instance argument to suspend_instance() + 1.7 - Remove instance_uuid, add instance argument to + get_console_output() ''' BASE_RPC_API_VERSION = '1.0' @@ -149,9 +151,11 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): topic=_compute_topic(self.topic, ctxt, host, None)) def get_console_output(self, ctxt, instance, tail_length): + instance_p = jsonutils.to_primitive(instance) return self.call(ctxt, self.make_msg('get_console_output', - instance_uuid=instance['uuid'], tail_length=tail_length), - topic=_compute_topic(self.topic, ctxt, None, instance)) + instance=instance_p, tail_length=tail_length), + topic=_compute_topic(self.topic, ctxt, None, instance), + version='1.7') def get_console_pool_info(self, ctxt, console_type, host): return self.call(ctxt, self.make_msg('get_console_pool_info', diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 63af3813b..1c8784bfd 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -769,7 +769,7 @@ class ComputeTestCase(BaseTestCase): self.compute.run_instance(self.context, instance['uuid']) output = self.compute.get_console_output(self.context, - instance['uuid']) + instance=jsonutils.to_primitive(instance)) self.assertEqual(output, 'FAKE CONSOLE OUTPUT\nANOTHER\nLAST LINE') self.compute.terminate_instance(self.context, instance['uuid']) @@ -779,8 +779,7 @@ class ComputeTestCase(BaseTestCase): self.compute.run_instance(self.context, instance['uuid']) output = self.compute.get_console_output(self.context, - instance['uuid'], - tail_length=2) + instance=jsonutils.to_primitive(instance), tail_length=2) self.assertEqual(output, 'ANOTHER\nLAST LINE') self.compute.terminate_instance(self.context, instance['uuid']) @@ -3678,9 +3677,9 @@ class ComputeAPITestCase(BaseTestCase): self.mox.StubOutWithMock(rpc, 'call') rpc_msg = {'method': 'get_console_output', - 'args': {'instance_uuid': fake_instance['uuid'], + 'args': {'instance': fake_instance, 'tail_length': fake_tail_length}, - 'version': compute_rpcapi.ComputeAPI.BASE_RPC_API_VERSION} + 'version': '1.7'} rpc.call(self.context, 'compute.%s' % fake_instance['host'], rpc_msg, None).AndReturn(fake_console_output) diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index 5c0fcd006..87682eb45 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -49,8 +49,8 @@ class ComputeRpcAPITestCase(test.TestCase): ctxt = context.RequestContext('fake_user', 'fake_project') methods_with_instance = [ - 'pause_instance', 'reboot_instance', 'suspend_instance', - 'unpause_instance' + 'get_console_output', 'pause_instance', 'reboot_instance', + 'suspend_instance', 'unpause_instance' ] if 'rpcapi_class' in kwargs: @@ -161,7 +161,7 @@ class ComputeRpcAPITestCase(test.TestCase): def test_get_console_output(self): self._test_compute_api('get_console_output', 'call', - instance=self.fake_instance, tail_length='tl') + instance=self.fake_instance, tail_length='tl', version='1.7') def test_get_console_pool_info(self): self._test_compute_api('get_console_pool_info', 'call', -- cgit From 5547d08b28a7edc3e162174670cca892ae15e290 Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Wed, 25 Jul 2012 14:02:35 -0400 Subject: Send a full instance via rpc for add_fixed_ip_to_instance. Change the add_fixed_ip_to_instance method of the compute rpc API to take a full instance over rpc instead of just the instance UUID. This cuts down on database access needed by nova-compute. Part of blueprint no-db-messaging. Change-Id: I21d91e6c95dca47390b306517eeb4155defc4e65 --- nova/compute/manager.py | 20 +++++++++++--------- nova/compute/rpcapi.py | 8 ++++++-- nova/tests/compute/test_compute.py | 5 +++-- nova/tests/compute/test_rpcapi.py | 6 +++--- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index bb75efc5a..097905788 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -297,7 +297,7 @@ def _get_additional_capabilities(): class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" - RPC_API_VERSION = '1.7' + RPC_API_VERSION = '1.8' def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -1666,26 +1666,28 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock @wrap_instance_fault - def add_fixed_ip_to_instance(self, context, instance_uuid, network_id): + def add_fixed_ip_to_instance(self, context, network_id, instance=None, + instance_uuid=None): """Calls network_api to add new fixed_ip to instance then injects the new network info and resets instance networking. """ - instance_ref = self.db.instance_get_by_uuid(context, instance_uuid) + if not instance: + instance = self.db.instance_get_by_uuid(context, instance_uuid) self._notify_about_instance_usage( - context, instance_ref, "create_ip.start") + context, instance, "create_ip.start") - instance_id = instance_ref['id'] + instance_id = instance['id'] self.network_api.add_fixed_ip_to_instance(context, - instance_ref, + instance, network_id) network_info = self.inject_network_info(context, - instance_ref['uuid']) - self.reset_network(context, instance_ref['uuid']) + instance['uuid']) + self.reset_network(context, instance['uuid']) self._notify_about_instance_usage( - context, instance_ref, "create_ip.end", network_info=network_info) + context, instance, "create_ip.end", network_info=network_info) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index 4d5e495d6..726b520b5 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -65,6 +65,8 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): 1.6 - Remove instance_uuid, add instance argument to suspend_instance() 1.7 - Remove instance_uuid, add instance argument to get_console_output() + 1.8 - Remove instance_uuid, add instance argument to + add_fixed_ip_to_instance() ''' BASE_RPC_API_VERSION = '1.0' @@ -88,9 +90,11 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): topic=_compute_topic(self.topic, ctxt, host, None)) def add_fixed_ip_to_instance(self, ctxt, instance, network_id): + instance_p = jsonutils.to_primitive(instance) self.cast(ctxt, self.make_msg('add_fixed_ip_to_instance', - instance_uuid=instance['uuid'], network_id=network_id), - topic=_compute_topic(self.topic, ctxt, None, instance)) + instance=instance_p, network_id=network_id), + topic=_compute_topic(self.topic, ctxt, None, instance), + version='1.8') def attach_volume(self, ctxt, instance, volume_id, mountpoint): self.cast(ctxt, self.make_msg('attach_volume', diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 1c8784bfd..c0356dda6 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -850,11 +850,12 @@ class ComputeTestCase(BaseTestCase): self.stubs.Set(nova.compute.manager.ComputeManager, 'reset_network', dummy) - instance = self._create_fake_instance() + instance = jsonutils.to_primitive(self._create_fake_instance()) instance_uuid = instance['uuid'] self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) - self.compute.add_fixed_ip_to_instance(self.context, instance_uuid, 1) + self.compute.add_fixed_ip_to_instance(self.context, network_id=1, + instance=instance) self.assertEquals(len(test_notifier.NOTIFICATIONS), 2) self.compute.terminate_instance(self.context, instance_uuid) diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index 87682eb45..b5319d257 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -49,8 +49,8 @@ class ComputeRpcAPITestCase(test.TestCase): ctxt = context.RequestContext('fake_user', 'fake_project') methods_with_instance = [ - 'get_console_output', 'pause_instance', 'reboot_instance', - 'suspend_instance', 'unpause_instance' + 'add_fixed_ip_to_instance', 'get_console_output', 'pause_instance', + 'reboot_instance', 'suspend_instance', 'unpause_instance' ] if 'rpcapi_class' in kwargs: @@ -122,7 +122,7 @@ class ComputeRpcAPITestCase(test.TestCase): def test_add_fixed_ip_to_instance(self): self._test_compute_api('add_fixed_ip_to_instance', 'cast', - instance=self.fake_instance, network_id='id') + instance=self.fake_instance, network_id='id', version='1.8') def test_attach_volume(self): self._test_compute_api('attach_volume', 'cast', -- cgit From 8dac75fa0b6bb16adfdca2198703031249722f3d Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Wed, 25 Jul 2012 14:19:40 -0400 Subject: Send a full instance via rpc for attach_volume. Change the attach_volume method of the compute rpc API to take a full instance over rpc instead of just the instance UUID. This cuts down on database access needed by nova-compute. Part of blueprint no-db-messaging. Change-Id: I85ad29e84b5e97a3f918059b10e2309312756050 --- nova/compute/manager.py | 22 ++++++++++++---------- nova/compute/rpcapi.py | 7 +++++-- nova/tests/compute/test_rpcapi.py | 8 +++++--- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 097905788..afe8cae51 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -297,7 +297,7 @@ def _get_additional_capabilities(): class ComputeManager(manager.SchedulerDependentManager): """Manages the running instances from creation to destruction.""" - RPC_API_VERSION = '1.8' + RPC_API_VERSION = '1.9' def __init__(self, compute_driver=None, *args, **kwargs): """Load configuration options and connect to the hypervisor.""" @@ -1961,15 +1961,17 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock @wrap_instance_fault - def attach_volume(self, context, instance_uuid, volume_id, mountpoint): + def attach_volume(self, context, volume_id, mountpoint, instance_uuid=None, + instance=None): """Attach a volume to an instance.""" volume = self.volume_api.get(context, volume_id) context = context.elevated() - instance_ref = self.db.instance_get_by_uuid(context, instance_uuid) + if not instance: + instance = self.db.instance_get_by_uuid(context, instance_uuid) LOG.audit(_('Attaching volume %(volume_id)s to %(mountpoint)s'), - locals(), context=context, instance=instance_ref) + locals(), context=context, instance=instance) try: - connector = self.driver.get_volume_connector(instance_ref) + connector = self.driver.get_volume_connector(instance) connection_info = self.volume_api.initialize_connection(context, volume, connector) @@ -1978,28 +1980,28 @@ class ComputeManager(manager.SchedulerDependentManager): msg = _("Failed to connect to volume %(volume_id)s " "while attaching at %(mountpoint)s") LOG.exception(msg % locals(), context=context, - instance=instance_ref) + instance=instance) self.volume_api.unreserve_volume(context, volume) try: self.driver.attach_volume(connection_info, - instance_ref['name'], + instance['name'], mountpoint) except Exception: # pylint: disable=W0702 with excutils.save_and_reraise_exception(): msg = _("Failed to attach volume %(volume_id)s " "at %(mountpoint)s") LOG.exception(msg % locals(), context=context, - instance=instance_ref) + instance=instance) self.volume_api.terminate_connection(context, volume, connector) self.volume_api.attach(context, volume, - instance_ref['uuid'], + instance['uuid'], mountpoint) values = { - 'instance_uuid': instance_ref['uuid'], + 'instance_uuid': instance['uuid'], 'connection_info': jsonutils.dumps(connection_info), 'device_name': mountpoint, 'delete_on_termination': False, diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py index 726b520b5..b11b17144 100644 --- a/nova/compute/rpcapi.py +++ b/nova/compute/rpcapi.py @@ -67,6 +67,7 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): get_console_output() 1.8 - Remove instance_uuid, add instance argument to add_fixed_ip_to_instance() + 1.9 - Remove instance_uuid, add instance argument to attach_volume() ''' BASE_RPC_API_VERSION = '1.0' @@ -97,10 +98,12 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): version='1.8') def attach_volume(self, ctxt, instance, volume_id, mountpoint): + instance_p = jsonutils.to_primitive(instance) self.cast(ctxt, self.make_msg('attach_volume', - instance_uuid=instance['uuid'], volume_id=volume_id, + instance=instance_p, volume_id=volume_id, mountpoint=mountpoint), - topic=_compute_topic(self.topic, ctxt, None, instance)) + topic=_compute_topic(self.topic, ctxt, None, instance), + version='1.9') def check_can_live_migrate_destination(self, ctxt, instance, destination, block_migration, disk_over_commit): diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index b5319d257..ee74f2c6b 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -49,8 +49,9 @@ class ComputeRpcAPITestCase(test.TestCase): ctxt = context.RequestContext('fake_user', 'fake_project') methods_with_instance = [ - 'add_fixed_ip_to_instance', 'get_console_output', 'pause_instance', - 'reboot_instance', 'suspend_instance', 'unpause_instance' + 'add_fixed_ip_to_instance', 'attach_volume', 'get_console_output', + 'pause_instance', 'reboot_instance', 'suspend_instance', + 'unpause_instance' ] if 'rpcapi_class' in kwargs: @@ -126,7 +127,8 @@ class ComputeRpcAPITestCase(test.TestCase): def test_attach_volume(self): self._test_compute_api('attach_volume', 'cast', - instance=self.fake_instance, volume_id='id', mountpoint='mp') + instance=self.fake_instance, volume_id='id', mountpoint='mp', + version='1.9') def test_check_can_live_migrate_destination(self): self._test_compute_api('check_can_live_migrate_destination', 'call', -- cgit