Fix handling of 'cinder_encryption_key_id' image metadata

The Cinder code that processes Glance image metadata
is a bit confused about whether this particular field
is a Glance property or metadata.

Since it isn't a defined a Glance property and is stored
in image metadata, ensure that Cinder also tracks it
metadata and not as a property.

This mismatch prior to this fix causes Cinder to create
volumes with the wrong encryption key when creating a
volume from an encrypted image, which results in an
unreadable volume.

Closes-Bug: #1764125
Change-Id: Ie5af3703eaa82d23b50127f611235d86e4104369
This commit is contained in:
Eric Harney
2018-05-29 12:12:13 -04:00
parent 4b96310411
commit 2792be3ffc
4 changed files with 11 additions and 5 deletions

View File

@@ -420,6 +420,11 @@ class GlanceImageService(object):
if self._image_schema.is_base_property(key) is True and
key != 'schema'}
# Process 'cinder_encryption_key_id' as a metadata key
if 'cinder_encryption_key_id' in image.keys():
image_meta['cinder_encryption_key_id'] = \
image['cinder_encryption_key_id']
# NOTE(aarefiev): nova is expected that all image properties
# (custom or defined in schema-image.json) stores in
# 'properties' key.
@@ -535,7 +540,8 @@ def _extract_attributes(image):
'name', 'created_at', 'updated_at',
'deleted', 'deleted_at', 'checksum',
'min_disk', 'min_ram', 'protected',
'visibility']
'visibility',
'cinder_encryption_key_id']
output = {}

View File

@@ -808,6 +808,7 @@ class TestGlanceImageService(test.TestCase):
'properties': {},
'owner': None,
'visibility': None,
'cinder_encryption_key_id': None
}
self.assertEqual(expected, actual)

View File

@@ -1094,7 +1094,8 @@ class CreateVolumeFlowManagerTestCase(test.TestCase):
image_meta, fake_image_service)
fake_driver.create_volume.assert_called_once_with(volume)
fake_driver.copy_image_to_encrypted_volume.assert_called_once_with(
fake_driver.copy_image_to_encrypted_volume.assert_not_called()
fake_driver.copy_image_to_volume.assert_called_once_with(
self.ctxt, volume, fake_image_service, image_id)
mock_handle_bootable.assert_called_once_with(self.ctxt, volume,
image_id=image_id,

View File

@@ -510,9 +510,7 @@ class CreateVolumeFromSpecTask(flow_utils.CinderTask):
{'image_id': image_id, 'volume_id': volume.id,
'image_location': image_location})
try:
image_properties = image_meta.get('properties', {})
image_encryption_key = image_properties.get(
'cinder_encryption_key_id')
image_encryption_key = image_meta.get('cinder_encryption_key_id')
if volume.encryption_key_id and image_encryption_key:
# If the image provided an encryption key, we have