Merge "Update nova's copy of image metadata on rebuild"

This commit is contained in:
Jenkins
2012-05-16 22:01:48 +00:00
committed by Gerrit Code Review
2 changed files with 48 additions and 2 deletions
+31
View File
@@ -1349,6 +1349,32 @@ class API(BaseAPI):
if instance_type['root_gb'] < int(image.get('min_disk') or 0):
raise exception.InstanceTypeDiskTooSmall()
def _reset_image_metadata():
"""
Remove old image properties that we're storing as instance
system metadata. These properties start with 'image_'.
Then add the properites for the new image.
"""
# FIXME(comstud): There's a race condition here in that
# if the system_metadata for this instance is updated
# after we do the get and before we update.. those other
# updates will be lost. Since this problem exists in a lot
# of other places, I think it should be addressed in a DB
# layer overhaul.
sys_metadata = self.db.instance_system_metadata_get(context,
instance['uuid'])
# Remove the old keys
for key in sys_metadata.keys():
if key.startswith('image_'):
del sys_metadata[key]
# Add the new ones
for key, value in image['properties'].iteritems():
new_value = str(value)[:255]
sys_metadata['image_%s' % key] = new_value
self.db.instance_system_metadata_update(context,
instance['uuid'], sys_metadata, True)
self.update(context,
instance,
vm_state=vm_states.REBUILDING,
@@ -1359,6 +1385,11 @@ class API(BaseAPI):
progress=0,
**kwargs)
# On a rebuild, since we're potentially changing images, we need to
# wipe out the old image properties that we're storing as instance
# system metadata... and copy in the properties for the new image.
_reset_image_metadata()
rebuild_params = {
"new_pass": admin_password,
"injected_files": files_to_inject,
+17 -2
View File
@@ -115,7 +115,7 @@ class BaseTestCase(test.TestCase):
test_notifier.NOTIFICATIONS = []
def fake_show(meh, context, id):
return {'id': 1, 'min_disk': None, 'min_ram': None,
return {'id': id, 'min_disk': None, 'min_ram': None,
'properties': {'kernel_id': 'fake_kernel_id',
'ramdisk_id': 'fake_ramdisk_id',
'something_else': 'meow'}}
@@ -2307,6 +2307,15 @@ class ComputeAPITestCase(BaseTestCase):
instance = db.instance_get_by_uuid(self.context, instance_uuid)
self.assertEqual(instance['task_state'], None)
# Set some image metadata that should get wiped out and reset
# as well as some other metadata that should be preserved.
db.instance_system_metadata_update(self.context, instance_uuid,
{'image_kernel_id': 'old-data',
'image_ramdisk_id': 'old_data',
'image_something_else': 'old-data',
'image_should_remove': 'bye-bye',
'preserved': 'preserve this!'},
True)
# Make sure Compute API updates the image_ref before casting to
# compute manager.
@@ -2327,7 +2336,13 @@ class ComputeAPITestCase(BaseTestCase):
instance = db.instance_get_by_uuid(self.context, instance_uuid)
self.assertEqual(instance['vm_state'], vm_states.REBUILDING)
sys_metadata = db.instance_system_metadata_get(self.context,
instance_uuid)
self.assertEqual(sys_metadata,
{'image_kernel_id': 'fake_kernel_id',
'image_ramdisk_id': 'fake_ramdisk_id',
'image_something_else': 'meow',
'preserved': 'preserve this!'})
db.instance_destroy(self.context, instance['id'])
def test_reboot_soft(self):