Fix image ID in libvirt metadata when unshelving
Nova adds the temporary shelved image ID to libvirt metadata when unshelving image-backed instances. This is corrected when the instance is cold restarted, resized or migrated but causes issues for other services such as Ceilometer which rely on this data being correct. This patch ensures the correct image ID is set in the libvirt domain metadata when image-backed instances are unshelved. Signed-off-by: Callum Dickinson <callum.dickinson@catalystcloud.nz> Co-Authored-By: Jeremy Lamb <jeremy.lamb@catalystcloud.nz> Closes-Bug: #2100588 Change-Id: Ifd9f092299912606931848b2b25b4be6b36effac
This commit is contained in:
@@ -691,6 +691,7 @@ def _create_test_instance():
|
||||
'root_gb': 10,
|
||||
'ephemeral_gb': 20,
|
||||
'system_metadata': {
|
||||
'image_base_image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
|
||||
'image_disk_format': 'raw'
|
||||
},
|
||||
'instance_type_id': flavor.id,
|
||||
@@ -2902,6 +2903,48 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
self.assertEqual(meta.ports.ports[1].ips[1].ip_type, 'fixed')
|
||||
self.assertEqual(meta.ports.ports[1].ips[1].ip_version, 6)
|
||||
|
||||
def test_get_guest_config_meta_building_image_id(self):
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
test_instance["vm_state"] = "building"
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
idm = drvr.get_instance_driver_metadata(
|
||||
objects.Instance(**test_instance),
|
||||
_fake_network_info(self))
|
||||
meta = drvr._get_guest_config_meta(idm)
|
||||
|
||||
self.assertEqual("image", meta.roottype)
|
||||
self.assertEqual("155d900f-4e14-4e4c-a73d-069cbf4541e6",
|
||||
meta.rootid)
|
||||
|
||||
def test_get_guest_config_meta_no_base_image_ref_image_id(self):
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
test_instance["system_metadata"] = {"image_disk_format": "raw"}
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
idm = drvr.get_instance_driver_metadata(
|
||||
objects.Instance(**test_instance),
|
||||
_fake_network_info(self))
|
||||
meta = drvr._get_guest_config_meta(idm)
|
||||
|
||||
self.assertEqual("image", meta.roottype)
|
||||
self.assertEqual("155d900f-4e14-4e4c-a73d-069cbf4541e6",
|
||||
meta.rootid)
|
||||
|
||||
def test_get_guest_config_meta_unshelve_image_id(self):
|
||||
test_instance = copy.deepcopy(self.test_instance)
|
||||
test_instance["vm_state"] = "shelved_offloaded"
|
||||
test_instance["system_metadata"]["image_base_image_ref"] = (
|
||||
"85daefce-4e20-4d2b-a4f3-11d3765f2a8f")
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
idm = drvr.get_instance_driver_metadata(
|
||||
objects.Instance(**test_instance),
|
||||
_fake_network_info(self))
|
||||
meta = drvr._get_guest_config_meta(idm)
|
||||
|
||||
self.assertEqual("image", meta.roottype)
|
||||
self.assertEqual(test_instance["system_metadata"][
|
||||
"image_base_image_ref"],
|
||||
meta.rootid)
|
||||
|
||||
@mock.patch.object(time, "time")
|
||||
def test_get_guest_config(self, time_mock):
|
||||
"""Generate a "standard" guest with minimal configuration.
|
||||
|
||||
+8
-1
@@ -394,7 +394,14 @@ class ComputeDriver(object):
|
||||
flavor=flavor,
|
||||
image=image,
|
||||
root_type = 'image' if instance.image_ref else 'volume',
|
||||
root_id = instance.image_ref,
|
||||
# NOTE(callumdickinson): Once an image-backed instance has
|
||||
# been shelved, instance.image_ref changes to the ID of the
|
||||
# temporary image storing the root volume while shelved.
|
||||
# Prefer base_image_ref from the system metadata, if available,
|
||||
# to ensure that the ID of the original image the instance was
|
||||
# booted from is used for the driver metadata.
|
||||
root_id=system_meta.get('image_base_image_ref',
|
||||
instance.image_ref),
|
||||
creation_time = time.time(),
|
||||
network_info=network_info
|
||||
)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
When an instance booted from local storage is unshelved,
|
||||
the image ID published to the libvirt domain metadata was
|
||||
the ID for the temporary Glance image generated to store
|
||||
the instance state, instead of the original image as intended.
|
||||
Since the temporary image is removed after the instance is
|
||||
unshelved, this results in an invalid image ID being stored
|
||||
in the libvirt domain metadata. This issue has now been fixed.
|
||||
Affected instances will need to be shutdown, restarted, cold
|
||||
migrated or shelved-and-unshelved to update the metadata.
|
||||
Reference in New Issue
Block a user