Do not always assume image_id in volume_image_metadata

volume_image_metadata can contain only fields other than image_id.
We should not assume volume_image_metadata always contain image_id
when volume_image_metadata exists.

Change-Id: I0db8a05e488eb6bf276760d5116d05633c882701
Closes-Bug: #1834747
This commit is contained in:
Akihiro Motoki 2019-07-02 14:05:19 +09:00 committed by Vishal Manchanda
parent 82a20c670a
commit 42f4ef334d
2 changed files with 33 additions and 8 deletions

View File

@ -392,7 +392,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
api.network: ('servers_update_addresses',),
api.cinder: ('volume_list',),
})
def test_index_with_instance_booted_from_volume(self):
def _test_index_with_instance_booted_from_volume(
self, volume_image_metadata, expected_image_name):
servers = self.servers.list()
volume_server = servers[0]
# Override the server is booted from a volume.
@ -410,10 +411,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
volumes = self.cinder_volumes.list()
# 3rd volume in the list is attached to server with ID 1.
volume = volumes[2]
base_image = self.images.get(name='private_image')
volume.volume_image_metadata = {
"image_id": base_image.id,
}
volume.volume_image_metadata = volume_image_metadata
self._mock_extension_supported({'AdminActions': True,
'Shelve': True})
@ -433,7 +431,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.assertTemplateUsed(res, INDEX_TEMPLATE)
instances = res.context['instances_table'].data
self.assertEqual(len(instances), len(servers))
self.assertContains(res, base_image.name)
if expected_image_name:
self.assertContains(res, expected_image_name)
self._check_extension_supported({'AdminActions': 16,
'Shelve': 4})
@ -461,6 +460,28 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
mock.call(helpers.IsHttpRequest()))
self.mock_volume_list.assert_called_once_with(helpers.IsHttpRequest())
return instances
def test_index_with_instance_booted_from_volume(self):
base_image = self.images.get(name='private_image')
image_metadata = {
"image_id": base_image.id
}
servers = self._test_index_with_instance_booted_from_volume(
image_metadata, expected_image_name=base_image.name)
self.assertEqual(base_image.name, servers[0].image.name)
def test_index_with_instance_booted_from_volume_no_image_info(self):
# Borrowed from bug #1834747
image_metadata = {
'hw_qemu_guest_agent': 'yes',
'hw_vif_multiqueue_enabled': 'true',
'os_require_quiesce': 'yes',
}
servers = self._test_index_with_instance_booted_from_volume(
image_metadata, expected_image_name=None)
self.assertEqual('', servers[0].image)
def test_index_with_console_link(self):
res = self._get_index()

View File

@ -210,8 +210,12 @@ class IndexView(tables.PagedTableMixin, tables.DataTableView):
# Getting volume object, which is as attached
# as the first device
boot_volume = volume_dict[instance_volumes[0]['id']]
if hasattr(boot_volume, "volume_image_metadata"):
image_id = boot_volume.volume_image_metadata['image_id']
# There is a case where volume_image_metadata contains
# only fields other than 'image_id' (See bug 1834747),
# so we try to populate image information only when it is found.
volume_metadata = getattr(boot_volume, "volume_image_metadata", {})
image_id = volume_metadata.get('image_id')
if image_id:
try:
instance.image = image_dict[image_id]
except KeyError: