summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorRussell Bryant <rbryant@redhat.com>2012-08-02 15:34:00 -0400
committerRussell Bryant <rbryant@redhat.com>2012-08-06 15:09:33 -0400
commit2ee42aafde64af6d64a1f34a6204fd80e7dd01fd (patch)
treefac26bea8720c878cd8b899002cf16249f3db3a6 /nova
parent6b42978eb4bf740f148a6bb200b331660755b53b (diff)
Reduce db access in prep_resize in the compute manager.
This patch changes the arguments passed to prep_resize in the compute manager. Previously it took instance and instance_type IDs. It now receives a full dict for both of these. This cuts down on database access needed on the compute node. This method was not previously in the compute rpcapi module, so it has been added there. The scheduler had a bit of work done ot get it to use the rpcapi module for prep_resize, as well. Part of blueprint no-db-messaging. Change-Id: Idadbf4fc624d5d1b128f758a46c61b3c840b9898
Diffstat (limited to 'nova')
-rw-r--r--nova/compute/manager.py44
-rw-r--r--nova/compute/rpcapi.py12
-rw-r--r--nova/scheduler/chance.py7
-rw-r--r--nova/scheduler/driver.py17
-rw-r--r--nova/scheduler/filter_scheduler.py7
-rw-r--r--nova/tests/compute/test_compute.py49
-rw-r--r--nova/tests/compute/test_rpcapi.py5
7 files changed, 96 insertions, 45 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 22f30d66b..a8d325b4b 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -273,7 +273,7 @@ def _get_image_meta(context, image_ref):
class ComputeManager(manager.SchedulerDependentManager):
"""Manages the running instances from creation to destruction."""
- RPC_API_VERSION = '1.37'
+ RPC_API_VERSION = '1.38'
def __init__(self, compute_driver=None, *args, **kwargs):
"""Load configuration options and connect to the hypervisor."""
@@ -1481,7 +1481,8 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@checks_instance_lock
@wrap_instance_fault
- def prep_resize(self, context, instance_uuid, instance_type_id, image):
+ def prep_resize(self, context, image, instance=None, instance_uuid=None,
+ instance_type=None, instance_type_id=None):
"""Initiates the process of moving a running instance to another host.
Possibly changes the RAM and disk size in the process.
@@ -1489,44 +1490,49 @@ class ComputeManager(manager.SchedulerDependentManager):
"""
context = context.elevated()
- instance_ref = self.db.instance_get_by_uuid(context, instance_uuid)
- with self.error_out_instance_on_exception(context, instance_uuid):
+ if not instance:
+ instance = self.db.instance_get_by_uuid(context, instance_uuid)
+
+ if not instance_type:
+ instance_type = instance_types.get_instance_type(instance_type_id)
+
+ with self.error_out_instance_on_exception(context, instance['uuid']):
compute_utils.notify_usage_exists(
- context, instance_ref, current_period=True)
+ context, instance, current_period=True)
self._notify_about_instance_usage(
- context, instance_ref, "resize.prep.start")
+ context, instance, "resize.prep.start")
- same_host = instance_ref['host'] == FLAGS.host
+ same_host = instance['host'] == FLAGS.host
if same_host and not FLAGS.allow_resize_to_same_host:
- self._set_instance_error_state(context, instance_uuid)
+ self._set_instance_error_state(context, instance['uuid'])
msg = _('destination same as source!')
raise exception.MigrationError(msg)
- old_instance_type_id = instance_ref['instance_type_id']
+ # TODO(russellb): no-db-compute: Send the old instance type info
+ # that is needed via rpc so db access isn't required here.
+ old_instance_type_id = instance['instance_type_id']
old_instance_type = instance_types.get_instance_type(
old_instance_type_id)
- new_instance_type = instance_types.get_instance_type(
- instance_type_id)
migration_ref = self.db.migration_create(context,
- {'instance_uuid': instance_ref['uuid'],
- 'source_compute': instance_ref['host'],
+ {'instance_uuid': instance['uuid'],
+ 'source_compute': instance['host'],
'dest_compute': FLAGS.host,
'dest_host': self.driver.get_host_ip_addr(),
'old_instance_type_id': old_instance_type['id'],
- 'new_instance_type_id': instance_type_id,
+ 'new_instance_type_id': instance_type['id'],
'status': 'pre-migrating'})
- LOG.audit(_('Migrating'), context=context, instance=instance_ref)
- self.compute_rpcapi.resize_instance(context, instance_ref,
+ LOG.audit(_('Migrating'), context=context, instance=instance)
+ self.compute_rpcapi.resize_instance(context, instance,
migration_ref['id'], image)
extra_usage_info = dict(
- new_instance_type=new_instance_type['name'],
- new_instance_type_id=new_instance_type['id'])
+ new_instance_type=instance_type['name'],
+ new_instance_type_id=instance_type['id'])
self._notify_about_instance_usage(
- context, instance_ref, "resize.prep.end",
+ context, instance, "resize.prep.end",
extra_usage_info=extra_usage_info)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py
index aa3d32e34..517cfca4d 100644
--- a/nova/compute/rpcapi.py
+++ b/nova/compute/rpcapi.py
@@ -113,6 +113,10 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
change_instance_metadata()
1.37 - Remove instance_uuid, add instance argument to
terminate_instance()
+ 1.38 - Changes to prep_resize():
+ - remove instance_uuid, add instance
+ - remove instance_type_id, add instance_type
+ - remove topic, it was unused
'''
BASE_RPC_API_VERSION = '1.0'
@@ -308,6 +312,14 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
disk=disk), _compute_topic(self.topic, ctxt, host, None),
version='1.23')
+ def prep_resize(self, ctxt, image, instance, instance_type, host):
+ instance_p = jsonutils.to_primitive(instance)
+ instance_type_p = jsonutils.to_primitive(instance_type)
+ self.cast(ctxt, self.make_msg('prep_resize',
+ instance=instance_p, instance_type=instance_type_p,
+ image=image), _compute_topic(self.topic, ctxt, host, None),
+ version='1.38')
+
def reboot_instance(self, ctxt, instance, reboot_type):
instance_p = jsonutils.to_primitive(instance)
self.cast(ctxt, self.make_msg('reboot_instance',
diff --git a/nova/scheduler/chance.py b/nova/scheduler/chance.py
index 1be86dda6..0cdcff09e 100644
--- a/nova/scheduler/chance.py
+++ b/nova/scheduler/chance.py
@@ -86,6 +86,7 @@ class ChanceScheduler(driver.Scheduler):
"""Select a target for resize."""
host = self._schedule(context, 'compute', request_spec,
filter_properties)
- driver.cast_to_compute_host(context, host, 'prep_resize',
- instance_uuid=instance['uuid'],
- instance_type_id=instance_type['id'], image=image)
+ updated_instance = driver.instance_update_db(context, instance['uuid'],
+ host.host_state.host)
+ self.compute_rpcapi.prep_resize(context, image, updated_instance,
+ instance_type, host)
diff --git a/nova/scheduler/driver.py b/nova/scheduler/driver.py
index c701d8051..8f98a3ffc 100644
--- a/nova/scheduler/driver.py
+++ b/nova/scheduler/driver.py
@@ -70,15 +70,24 @@ def cast_to_volume_host(context, host, method, update_db=True, **kwargs):
LOG.debug(_("Casted '%(method)s' to volume '%(host)s'") % locals())
+def instance_update_db(context, instance_uuid, host):
+ '''Set the host and scheduled_at fields of an Instance.
+
+ :returns: An Instance with the updated fields set properly.
+ '''
+ now = timeutils.utcnow()
+ values = {'host': host, 'scheduled_at': now}
+ return db.instance_update(context, instance_uuid, values)
+
+
def cast_to_compute_host(context, host, method, update_db=True, **kwargs):
"""Cast request to a compute host queue"""
if update_db:
instance_uuid = kwargs.get('instance_uuid', None)
- if instance_uuid is not None:
- now = timeutils.utcnow()
- db.instance_update(context, instance_uuid,
- {'host': host, 'scheduled_at': now})
+ if instance_uuid:
+ instance_update_db(context, instance_uuid, host)
+
rpc.cast(context,
rpc.queue_get_for(context, 'compute', host),
{"method": method, "args": kwargs})
diff --git a/nova/scheduler/filter_scheduler.py b/nova/scheduler/filter_scheduler.py
index 63405541b..f77acfd19 100644
--- a/nova/scheduler/filter_scheduler.py
+++ b/nova/scheduler/filter_scheduler.py
@@ -118,9 +118,10 @@ class FilterScheduler(driver.Scheduler):
host = hosts.pop(0)
# Forward off to the host
- driver.cast_to_compute_host(context, host.host_state.host,
- 'prep_resize', instance_uuid=instance['uuid'],
- instance_type_id=instance_type['id'], image=image)
+ updated_instance = driver.instance_update_db(context, instance['uuid'],
+ host.host_state.host)
+ self.compute_rpcapi.prep_resize(context, image, updated_instance,
+ instance_type, host.host_state.host)
def _provision_resource(self, context, weighted_host, request_spec,
reservations, filter_properties, kwargs):
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index efb241b75..5d41cd7c6 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -1146,7 +1146,8 @@ class ComputeTestCase(BaseTestCase):
context = self.context.elevated()
instance = jsonutils.to_primitive(self._create_fake_instance())
- self.compute.prep_resize(context, instance['uuid'], 1, {})
+ self.compute.prep_resize(context, instance=instance, instance_type={},
+ image={})
migration_ref = db.migration_get_by_instance_and_status(context,
instance['uuid'], 'pre-migrating')
self.compute.finish_resize(context,
@@ -1167,7 +1168,8 @@ class ComputeTestCase(BaseTestCase):
context = self.context.elevated()
instance = jsonutils.to_primitive(self._create_fake_instance())
- self.compute.prep_resize(context, instance['uuid'], 1, {})
+ self.compute.prep_resize(context, instance=instance, instance_type={},
+ image={})
migration_ref = db.migration_get_by_instance_and_status(context,
instance['uuid'], 'pre-migrating')
@@ -1250,12 +1252,14 @@ class ComputeTestCase(BaseTestCase):
context = self.context.elevated()
old_type_id = instance_types.get_instance_type_by_name(
'm1.tiny')['id']
- new_type_id = instance_types.get_instance_type_by_name(
- 'm1.small')['id']
+ new_type = instance_types.get_instance_type_by_name('m1.small')
+ new_type = jsonutils.to_primitive(new_type)
+ new_type_id = new_type['id']
self.compute.run_instance(self.context, instance['uuid'])
db.instance_update(self.context, instance['uuid'], {'host': 'foo'})
- self.compute.prep_resize(context, instance['uuid'], new_type_id, {})
+ self.compute.prep_resize(context, instance=instance,
+ instance_type=new_type, image={})
migration_ref = db.migration_get_by_instance_and_status(context,
instance['uuid'],
'pre-migrating')
@@ -1304,7 +1308,9 @@ class ComputeTestCase(BaseTestCase):
test_notifier.NOTIFICATIONS = []
db.instance_update(self.context, instance['uuid'], {'host': 'foo'})
- self.compute.prep_resize(context, instance['uuid'], 1, {})
+ self.compute.prep_resize(context,
+ instance=jsonutils.to_primitive(instance),
+ instance_type={}, image={})
db.migration_get_by_instance_and_status(context,
instance['uuid'],
'pre-migrating')
@@ -1343,12 +1349,15 @@ class ComputeTestCase(BaseTestCase):
context = self.context.elevated()
self.compute.run_instance(self.context, instance['uuid'])
- db.instance_update(self.context, instance['uuid'], {'host': 'foo'})
+ new_instance = db.instance_update(self.context, instance['uuid'],
+ {'host': 'foo'})
self.assertRaises(exception.MigrationError, self.compute.prep_resize,
- context, instance['uuid'], 1, {})
+ context,
+ instance=jsonutils.to_primitive(new_instance),
+ instance_type={}, image={})
self.compute.terminate_instance(context,
- instance=jsonutils.to_primitive(instance))
+ instance=jsonutils.to_primitive(new_instance))
def test_resize_instance_driver_error(self):
"""Ensure instance status set to Error on resize error"""
@@ -1364,7 +1373,8 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance['uuid'])
db.instance_update(self.context, instance['uuid'], {'host': 'foo'})
- self.compute.prep_resize(context, instance['uuid'], 1, {})
+ self.compute.prep_resize(context, instance=instance,
+ instance_type={}, image={})
migration_ref = db.migration_get_by_instance_and_status(context,
instance['uuid'], 'pre-migrating')
@@ -1385,7 +1395,8 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance['uuid'])
db.instance_update(self.context, instance['uuid'],
{'host': 'foo'})
- self.compute.prep_resize(context, instance['uuid'], 1, {})
+ self.compute.prep_resize(context, instance=instance,
+ instance_type={}, image={})
migration_ref = db.migration_get_by_instance_and_status(context,
instance['uuid'], 'pre-migrating')
self.compute.resize_instance(context, migration_ref['id'], {},
@@ -1413,11 +1424,14 @@ class ComputeTestCase(BaseTestCase):
inst_ref['instance_type_id'])
self.assertEqual(instance_type_ref['flavorid'], '1')
- db.instance_update(self.context, instance['uuid'], {'host': 'foo'})
+ new_inst_ref = db.instance_update(self.context, instance['uuid'],
+ {'host': 'foo'})
new_instance_type_ref = db.instance_type_get_by_flavor_id(context, 3)
- self.compute.prep_resize(context, inst_ref['uuid'],
- new_instance_type_ref['id'], {})
+ self.compute.prep_resize(context,
+ instance=jsonutils.to_primitive(new_inst_ref),
+ instance_type=jsonutils.to_primitive(new_instance_type_ref),
+ image={})
migration_ref = db.migration_get_by_instance_and_status(context,
inst_ref['uuid'], 'pre-migrating')
@@ -1465,7 +1479,9 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance['uuid'])
instance = db.instance_get_by_uuid(self.context, instance['uuid'])
self.assertRaises(exception.MigrationError, self.compute.prep_resize,
- self.context, instance['uuid'], 1, {})
+ self.context,
+ instance=jsonutils.to_primitive(instance),
+ instance_type={}, image={})
self.compute.terminate_instance(self.context,
instance=jsonutils.to_primitive(instance))
@@ -1482,7 +1498,8 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, inst_ref['uuid'])
db.instance_update(self.context, inst_ref['uuid'], {'host': 'foo'})
- self.compute.prep_resize(context, inst_ref['uuid'], 1, {})
+ self.compute.prep_resize(context, instance=inst_ref, instance_type={},
+ image={})
migration_ref = db.migration_get_by_instance_and_status(context,
inst_ref['uuid'], 'pre-migrating')
self.assertRaises(test.TestingException, self.compute.resize_instance,
diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py
index a1062ea57..94b44b345 100644
--- a/nova/tests/compute/test_rpcapi.py
+++ b/nova/tests/compute/test_rpcapi.py
@@ -210,6 +210,11 @@ class ComputeRpcAPITestCase(test.TestCase):
instance=self.fake_instance, block_migration='block_migration',
disk='disk', host='host', version='1.23')
+ def test_prep_resize(self):
+ self._test_compute_api('prep_resize', 'cast',
+ instance=self.fake_instance, instance_type='fake_type',
+ image='fake_image', host='host', version='1.38')
+
def test_reboot_instance(self):
self._test_compute_api('reboot_instance', 'cast',
instance=self.fake_instance, reboot_type='type', version='1.4')