diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-08-06 21:57:50 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-08-06 21:57:50 +0000 |
| commit | fd49eeed59781a2522fc6641d9bfde684b73d540 (patch) | |
| tree | 12d879d20d19dc057f4c02271e1b3581ce63837e | |
| parent | 97afc00aadc10d9302d0fe8577e83de82a41a4c8 (diff) | |
| parent | 2ee42aafde64af6d64a1f34a6204fd80e7dd01fd (diff) | |
Merge "Reduce db access in prep_resize in the compute manager."
| -rw-r--r-- | nova/compute/manager.py | 44 | ||||
| -rw-r--r-- | nova/compute/rpcapi.py | 12 | ||||
| -rw-r--r-- | nova/scheduler/chance.py | 7 | ||||
| -rw-r--r-- | nova/scheduler/driver.py | 17 | ||||
| -rw-r--r-- | nova/scheduler/filter_scheduler.py | 7 | ||||
| -rw-r--r-- | nova/tests/compute/test_compute.py | 49 | ||||
| -rw-r--r-- | nova/tests/compute/test_rpcapi.py | 5 |
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') |
