diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-03-08 21:44:01 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-03-08 21:44:01 +0000 |
| commit | f9b0b9f2d33fe97f241415e248b690a61b9f8098 (patch) | |
| tree | 2ba8832685d7b0360ea8f1a1a2167f35c2564753 | |
| parent | 63cf1277666c25e4d1ce560c5800a5117d5a7b4d (diff) | |
| parent | 5f3fa391ed499750ad68ad5b000b4e2e0a86978e (diff) | |
Merge "Fix instance type cleanup when doing a same-id migration"
| -rwxr-xr-x | nova/compute/manager.py | 40 | ||||
| -rw-r--r-- | nova/tests/compute/test_compute.py | 43 |
2 files changed, 76 insertions, 7 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py index e172e6ad8..7a9d4e6a7 100755 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1875,6 +1875,35 @@ class ComputeManager(manager.SchedulerDependentManager): locals(), instance=instance) self.driver.change_instance_metadata(context, instance, diff) + def _cleanup_stored_instance_types(self, migration, instance, + restore_old=False): + """Clean up "old" and "new" instance_type information stored in + instance's system_metadata. Optionally update the "current" + instance_type to the saved old one first. + + Returns the updated system_metadata as a dict, as well as the + post-cleanup current instance type. + """ + same_type = (migration['old_instance_type_id'] == + migration['new_instance_type_id']) + + sys_meta = utils.metadata_to_dict(instance['system_metadata']) + if restore_old and not same_type: + instance_type = instance_types.extract_instance_type(instance, + 'old_') + sys_meta = instance_types.save_instance_type_info(sys_meta, + instance_type) + else: + instance_type = instance_types.extract_instance_type(instance) + + if not same_type: + instance_types.delete_instance_type_info(sys_meta, 'old_') + + # NOTE(danms): new instance type is always stored in prep_resize + instance_types.delete_instance_type_info(sys_meta, 'new_') + + return sys_meta, instance_type + @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @wrap_instance_event @wrap_instance_fault @@ -1890,8 +1919,8 @@ class ComputeManager(manager.SchedulerDependentManager): with self._error_out_instance_on_exception(context, instance['uuid'], reservations): # NOTE(danms): delete stashed old/new instance_type information - sys_meta = utils.metadata_to_dict(instance['system_metadata']) - instance_types.delete_instance_type_info(sys_meta, 'old_', 'new_') + sys_meta, instance_type = self._cleanup_stored_instance_types( + migration, instance) self._instance_update(context, instance['uuid'], system_metadata=sys_meta) @@ -2002,11 +2031,8 @@ class ComputeManager(manager.SchedulerDependentManager): self._notify_about_instance_usage( context, instance, "resize.revert.start") - instance_type = instance_types.extract_instance_type(instance, - prefix='old_') - sys_meta = utils.metadata_to_dict(instance['system_metadata']) - instance_types.save_instance_type_info(sys_meta, instance_type) - instance_types.delete_instance_type_info(sys_meta, 'new_', 'old_') + sys_meta, instance_type = self._cleanup_stored_instance_types( + migration, instance, True) instance = self._instance_update(context, instance['uuid'], diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index e247b41c9..9ec527d12 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -2584,6 +2584,49 @@ class ComputeTestCase(BaseTestCase): self.compute.terminate_instance(self.context, instance=jsonutils.to_primitive(inst_ref)) + def _test_cleanup_stored_instance_types(self, old, new, revert=False): + migration = dict(old_instance_type_id=old, + new_instance_type_id=new) + instance = dict(system_metadata=list()) + instance['system_metadata'].append(dict(key='instance_type_id', + value=old)) + sys_meta = dict(instance_type_id=old) + self.mox.StubOutWithMock(instance_types, 'extract_instance_type') + self.mox.StubOutWithMock(instance_types, 'delete_instance_type_info') + self.mox.StubOutWithMock(instance_types, 'save_instance_type_info') + if revert and old != new: + instance_types.extract_instance_type(instance, 'old_').AndReturn( + {'instance_type_id': old}) + instance_types.save_instance_type_info( + sys_meta, {'instance_type_id': old}).AndReturn(sys_meta) + else: + instance_types.extract_instance_type(instance).AndReturn( + {'instance_type_id': new}) + if old != new: + instance_types.delete_instance_type_info( + sys_meta, 'old_').AndReturn(sys_meta) + instance_types.delete_instance_type_info( + sys_meta, 'new_').AndReturn(sys_meta) + + self.mox.ReplayAll() + res = self.compute._cleanup_stored_instance_types(migration, instance, + revert) + self.assertEqual(res, + (sys_meta, + {'instance_type_id': revert and old or new})) + + def test_cleanup_stored_instance_types_for_resize(self): + self._test_cleanup_stored_instance_types('1', '2') + + def test_cleanup_stored_instance_types_for_resize_with_update(self): + self._test_cleanup_stored_instance_types('1', '2', True) + + def test_cleanup_stored_instance_types_for_migration(self): + self._test_cleanup_stored_instance_types('1', '1') + + def test_cleanup_stored_instance_types_for_migration_with_update(self): + self._test_cleanup_stored_instance_types('1', '1', True) + def test_get_by_flavor_id(self): type = instance_types.get_instance_type_by_flavor_id(1) self.assertEqual(type['name'], 'm1.tiny') |
