summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell Bryant <rbryant@redhat.com>2012-07-27 11:05:46 -0400
committerRussell Bryant <rbryant@redhat.com>2012-07-30 16:58:24 -0400
commit0e16133db77b434f8dc5b298ef8166aa05013630 (patch)
tree131f602d2a883edd9c37146753357481914d1dfc
parent115fea1f9fa0fdb93f344a8ef9dc8ce9ba3cf6e9 (diff)
Send a full instance in rebuild_instance.
Change the rebuild_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. This patch also includes fixes for a couple of places that were getting the instance name using the old instance.name syntax. It must be instance['name']. These no-db-messaging patches are making it so more code paths have an instance as a dict (received over rpc) instead of the SQLAlchemy model (looked up from the db on the compute node). Part of blueprint no-db-messaging. Change-Id: I21647a5a5cbf71a2c498f6fee2e4adbe30b8f2ea
-rw-r--r--nova/compute/manager.py41
-rw-r--r--nova/compute/rpcapi.py8
-rw-r--r--nova/compute/utils.py2
-rw-r--r--nova/tests/compute/test_compute.py17
-rw-r--r--nova/tests/compute/test_rpcapi.py6
-rw-r--r--nova/virt/libvirt/firewall.py4
6 files changed, 43 insertions, 35 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 1bcc23a13..b2c9b86f4 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -272,7 +272,7 @@ def _get_image_meta(context, image_ref):
class ComputeManager(manager.SchedulerDependentManager):
"""Manages the running instances from creation to destruction."""
- RPC_API_VERSION = '1.23'
+ RPC_API_VERSION = '1.24'
def __init__(self, compute_driver=None, *args, **kwargs):
"""Load configuration options and connect to the hypervisor."""
@@ -974,41 +974,42 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@checks_instance_lock
@wrap_instance_fault
- def rebuild_instance(self, context, instance_uuid, orig_image_ref,
- image_ref, **kwargs):
+ def rebuild_instance(self, context, orig_image_ref,
+ image_ref, instance=None, instance_uuid=None, **kwargs):
"""Destroy and re-make this instance.
A 'rebuild' effectively purges all existing data from the system and
remakes the VM with given 'metadata' and 'personalities'.
:param context: `nova.RequestContext` object
- :param instance_uuid: Instance Identifier (UUID)
+ :param instance_uuid: (Deprecated) Instance Identifier (UUID)
+ :param instance: Instance dict
:param orig_image_ref: Original image_ref before rebuild
:param image_ref: New image_ref for rebuild
:param injected_files: Files to inject
:param new_pass: password to set on rebuilt instance
"""
+ context = context.elevated()
+
+ if not instance:
+ instance = self.db.instance_get_by_uuid(context, instance_uuid)
+
try:
- self._rebuild_instance(context, instance_uuid, orig_image_ref,
+ self._rebuild_instance(context, instance, orig_image_ref,
image_ref, kwargs)
except exception.ImageNotFound:
LOG.error(_('Cannot rebuild instance because the given image does '
'not exist.'),
- context=context, instance_uuid=instance_uuid)
- self._set_instance_error_state(context, instance_uuid)
+ context=context, instance=instance)
+ self._set_instance_error_state(context, instance['uuid'])
except Exception as exc:
LOG.error(_('Cannot rebuild instance: %(exc)s'), locals(),
- context=context, instance_uuid=instance_uuid)
- self._set_instance_error_state(context, instance_uuid)
+ context=context, instance=instance)
+ self._set_instance_error_state(context, instance['uuid'])
- def _rebuild_instance(self, context, instance_uuid, orig_image_ref,
+ def _rebuild_instance(self, context, instance, orig_image_ref,
image_ref, kwargs):
- context = context.elevated()
-
- LOG.audit(_("Rebuilding instance"), context=context,
- instance_uuid=instance_uuid)
-
- instance = self.db.instance_get_by_uuid(context, instance_uuid)
+ LOG.audit(_("Rebuilding instance"), context=context, instance=instance)
image_meta = _get_image_meta(context, image_ref)
@@ -1027,7 +1028,7 @@ class ComputeManager(manager.SchedulerDependentManager):
current_power_state = self._get_power_state(context, instance)
self._instance_update(context,
- instance_uuid,
+ instance['uuid'],
power_state=current_power_state,
task_state=task_states.REBUILDING)
@@ -1035,7 +1036,7 @@ class ComputeManager(manager.SchedulerDependentManager):
self.driver.destroy(instance, self._legacy_nw_info(network_info))
instance = self._instance_update(context,
- instance_uuid,
+ instance['uuid'],
task_state=task_states.\
REBUILD_BLOCK_DEVICE_MAPPING)
@@ -1045,7 +1046,7 @@ class ComputeManager(manager.SchedulerDependentManager):
device_info = self._setup_block_device_mapping(context, instance)
instance = self._instance_update(context,
- instance_uuid,
+ instance['uuid'],
task_state=task_states.\
REBUILD_SPAWNING)
# pull in new password here since the original password isn't in the db
@@ -1057,7 +1058,7 @@ class ComputeManager(manager.SchedulerDependentManager):
current_power_state = self._get_power_state(context, instance)
instance = self._instance_update(context,
- instance_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 1b9f86ca0..11f95f749 100644
--- a/nova/compute/rpcapi.py
+++ b/nova/compute/rpcapi.py
@@ -90,6 +90,8 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
power_on_instance() and start_instance()
1.23 - Remove instance_id, add instance argument to
pre_live_migration()
+ 1.24 - Remove instance_uuid, add instance argument to
+ rebuild_instance()
'''
BASE_RPC_API_VERSION = '1.0'
@@ -287,11 +289,13 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
def rebuild_instance(self, ctxt, instance, new_pass, injected_files,
image_ref, orig_image_ref):
+ instance_p = jsonutils.to_primitive(instance)
self.cast(ctxt, self.make_msg('rebuild_instance',
- instance_uuid=instance['uuid'], new_pass=new_pass,
+ instance=instance_p, new_pass=new_pass,
injected_files=injected_files, image_ref=image_ref,
orig_image_ref=orig_image_ref),
- topic=_compute_topic(self.topic, ctxt, None, instance))
+ topic=_compute_topic(self.topic, ctxt, None, instance),
+ version='1.24')
def refresh_provider_fw_rules(self, ctxt, host):
self.cast(ctxt, self.make_msg('refresh_provider_fw_rules'),
diff --git a/nova/compute/utils.py b/nova/compute/utils.py
index d3beea68c..6d2fb2202 100644
--- a/nova/compute/utils.py
+++ b/nova/compute/utils.py
@@ -56,7 +56,7 @@ def notify_usage_exists(context, instance_ref, current_period=False,
if system_metadata is None:
try:
system_metadata = db.instance_system_metadata_get(
- context, instance_ref.uuid)
+ context, instance_ref['uuid'])
except exception.NotFound:
system_metadata = {}
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index 848376da1..8ce9212d7 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -526,13 +526,13 @@ class ComputeTestCase(BaseTestCase):
def test_rebuild(self):
"""Ensure instance can be rebuilt"""
- instance = self._create_fake_instance()
+ instance = jsonutils.to_primitive(self._create_fake_instance())
instance_uuid = instance['uuid']
image_ref = instance['image_ref']
self.compute.run_instance(self.context, instance_uuid)
- self.compute.rebuild_instance(self.context, instance_uuid,
- image_ref, image_ref)
+ self.compute.rebuild_instance(self.context, image_ref, image_ref,
+ instance=instance)
self.compute.terminate_instance(self.context, instance_uuid)
def test_rebuild_launch_time(self):
@@ -540,14 +540,14 @@ class ComputeTestCase(BaseTestCase):
old_time = datetime.datetime(2012, 4, 1)
cur_time = datetime.datetime(2012, 12, 21, 12, 21)
timeutils.set_time_override(old_time)
- instance = self._create_fake_instance()
+ instance = jsonutils.to_primitive(self._create_fake_instance())
instance_uuid = instance['uuid']
image_ref = instance['image_ref']
self.compute.run_instance(self.context, instance_uuid)
timeutils.set_time_override(cur_time)
- self.compute.rebuild_instance(self.context, instance_uuid,
- image_ref, image_ref)
+ self.compute.rebuild_instance(self.context, image_ref, image_ref,
+ instance=instance)
instance = db.instance_get_by_uuid(self.context, instance_uuid)
self.assertEquals(cur_time, instance['launched_at'])
self.compute.terminate_instance(self.context, instance_uuid)
@@ -1143,7 +1143,10 @@ class ComputeTestCase(BaseTestCase):
password = "new_password"
- self.compute._rebuild_instance(self.context, inst_ref['uuid'],
+ instance = db.instance_get_by_uuid(self.context, inst_ref['uuid'])
+
+ self.compute._rebuild_instance(self.context.elevated(),
+ jsonutils.to_primitive(instance),
image_ref, new_image_ref, dict(new_pass=password))
instance = db.instance_get_by_uuid(self.context, inst_ref['uuid'])
diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py
index 8620f81be..79b33f25d 100644
--- a/nova/tests/compute/test_rpcapi.py
+++ b/nova/tests/compute/test_rpcapi.py
@@ -57,8 +57,8 @@ class ComputeRpcAPITestCase(test.TestCase):
'inject_file', 'inject_network_info', 'pause_instance',
'post_live_migration_at_destination', 'power_off_instance',
'power_on_instance', 'pre_live_migration', 'reboot_instance',
- 'start_instance', 'stop_instance', 'suspend_instance',
- 'unpause_instance'
+ 'rebuild_instance', 'start_instance', 'stop_instance',
+ 'suspend_instance', 'unpause_instance'
]
if 'rpcapi_class' in kwargs:
@@ -235,7 +235,7 @@ class ComputeRpcAPITestCase(test.TestCase):
self._test_compute_api('rebuild_instance', 'cast',
instance=self.fake_instance, new_pass='pass',
injected_files='files', image_ref='ref',
- orig_image_ref='orig_ref')
+ orig_image_ref='orig_ref', version='1.24')
def refresh_provider_fw_rules(self):
self._test_compute_api('refresh_provider_fw_rules', 'cast',
diff --git a/nova/virt/libvirt/firewall.py b/nova/virt/libvirt/firewall.py
index b373a3b90..9077188a8 100644
--- a/nova/virt/libvirt/firewall.py
+++ b/nova/virt/libvirt/firewall.py
@@ -160,7 +160,7 @@ class NWFilterFirewall(base_firewall.FirewallDriver):
def unfilter_instance(self, instance, network_info):
"""Clear out the nwfilter rules."""
- instance_name = instance.name
+ instance_name = instance['name']
for (network, mapping) in network_info:
nic_id = mapping['mac'].replace(':', '')
instance_filter_name = self._instance_filter_name(instance, nic_id)
@@ -219,7 +219,7 @@ class NWFilterFirewall(base_firewall.FirewallDriver):
try:
self._conn.nwfilterLookupByName(instance_filter_name)
except libvirt.libvirtError:
- name = instance.name
+ name = instance['name']
LOG.debug(_('The nwfilter(%(instance_filter_name)s) for'
'%(name)s is not found.') % locals(),
instance=instance)