From 2792be3ffced9b7faeb69fa100b3c50b76d00dc3 Mon Sep 17 00:00:00 2001 From: Eric Harney Date: Tue, 29 May 2018 12:12:13 -0400 Subject: [PATCH] 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 --- cinder/image/glance.py | 8 +++++++- cinder/tests/unit/image/test_glance.py | 1 + cinder/tests/unit/volume/flows/test_create_volume_flow.py | 3 ++- cinder/volume/flows/manager/create_volume.py | 4 +--- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/cinder/image/glance.py b/cinder/image/glance.py index 6cc2aefb19a..7b678cc5d02 100644 --- a/cinder/image/glance.py +++ b/cinder/image/glance.py @@ -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 = {} diff --git a/cinder/tests/unit/image/test_glance.py b/cinder/tests/unit/image/test_glance.py index 3d257d59388..7809ee47d29 100644 --- a/cinder/tests/unit/image/test_glance.py +++ b/cinder/tests/unit/image/test_glance.py @@ -808,6 +808,7 @@ class TestGlanceImageService(test.TestCase): 'properties': {}, 'owner': None, 'visibility': None, + 'cinder_encryption_key_id': None } self.assertEqual(expected, actual) diff --git a/cinder/tests/unit/volume/flows/test_create_volume_flow.py b/cinder/tests/unit/volume/flows/test_create_volume_flow.py index 172d5f0e39d..caf5193b9ff 100644 --- a/cinder/tests/unit/volume/flows/test_create_volume_flow.py +++ b/cinder/tests/unit/volume/flows/test_create_volume_flow.py @@ -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, diff --git a/cinder/volume/flows/manager/create_volume.py b/cinder/volume/flows/manager/create_volume.py index 03068704227..5300462f455 100644 --- a/cinder/volume/flows/manager/create_volume.py +++ b/cinder/volume/flows/manager/create_volume.py @@ -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