summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-03-08 21:44:01 +0000
committerGerrit Code Review <review@openstack.org>2013-03-08 21:44:01 +0000
commitf9b0b9f2d33fe97f241415e248b690a61b9f8098 (patch)
tree2ba8832685d7b0360ea8f1a1a2167f35c2564753
parent63cf1277666c25e4d1ce560c5800a5117d5a7b4d (diff)
parent5f3fa391ed499750ad68ad5b000b4e2e0a86978e (diff)
Merge "Fix instance type cleanup when doing a same-id migration"
-rwxr-xr-xnova/compute/manager.py40
-rw-r--r--nova/tests/compute/test_compute.py43
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')