From f9b67893acf94c06fd41be36b80b99788dc77e48 Mon Sep 17 00:00:00 2001 From: Lee Yarwood Date: Tue, 15 Sep 2020 18:17:04 +0100 Subject: [PATCH] compute: Skip cinder_encryption_key_id check when booting from volume Idf84ccff254d26fa13473fe9741ddac21cbcf321 added this check in order for Nova to avoid booting encrypted images created by Cinder as there is currently no support for using such images (rotating keys etc). The check however missed the slightly convoluted use case where this image property is found against a volume after the volume in question is created using an encrypted image created by cinder from an encrypted volume. In other words: - Cinder creates an encrypted volume A - Glance creates an encrypted image A from volume A - Cinder creates an encrypted volume B from image A - Nova attempts to boot an instance using volume B Note that Nova may request the creation of volume B or a user could also do this directly through Cinder. As such this change simply ensures that the instance isn't booting from a volume when preforming the check as it is only valid when booting from an image. Closes-Bug: #1895696 Change-Id: Ic92cab7362fa25050e5bbef5c3e360108365b5c7 --- nova/compute/api.py | 7 +++++- .../regressions/test_bug_1895696.py | 24 +++++-------------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 917b0796a0..59d2186c2c 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -627,7 +627,12 @@ class API(base.Base): return image_properties = image.get('properties', {}) - if image_properties.get('cinder_encryption_key_id'): + # NOTE(lyarwood) Skip this check when image_id is None indicating that + # the instance is booting from a volume that was itself initially + # created from an image. As such we don't care if + # cinder_encryption_key_id was against the original image as we are now + # booting from an encrypted volume. + if image_properties.get('cinder_encryption_key_id') and image_id: reason = _('Direct booting of an image uploaded from an ' 'encrypted volume is unsupported.') raise exception.ImageUnacceptable(image_id=image_id, diff --git a/nova/tests/functional/regressions/test_bug_1895696.py b/nova/tests/functional/regressions/test_bug_1895696.py index 909ca6a08d..8f16b7b56e 100644 --- a/nova/tests/functional/regressions/test_bug_1895696.py +++ b/nova/tests/functional/regressions/test_bug_1895696.py @@ -122,15 +122,9 @@ class TestNonBootableImageMeta(integrated_helpers._IntegratedTestBase): 'volume_size': 1, }] - # FIXME(lyarwood) n-api should ignore cinder_encryption_key_id in the - # original image in this case and accept the request. - ex = self.assertRaises( - client.OpenStackApiException, self.api.post_server, - {'server': server}) - self.assertEqual(400, ex.response.status_code) - self.assertIn( - "Direct booting of an image uploaded from an encrypted volume is " - "unsupported", str(ex)) + # Assert that this request is accepted and the server moves to ACTIVE + server = self.api.post_server({'server': server}) + self._wait_for_state_change(server, 'ACTIVE') def test_nonbootable_metadata_bfv_volume_image_metadata(self): """Assert behaviour when c-api has created volume using encrypted image @@ -147,12 +141,6 @@ class TestNonBootableImageMeta(integrated_helpers._IntegratedTestBase): 'uuid': uuids.cinder_encrypted_volume_uuid, }] - # FIXME(lyarwood) n-api should ignore cinder_encryption_key_id in the - # volume volume_image_metadata in this case and accept the request. - ex = self.assertRaises( - client.OpenStackApiException, self.api.post_server, - {'server': server}) - self.assertEqual(400, ex.response.status_code) - self.assertIn( - "Direct booting of an image uploaded from an encrypted volume is " - "unsupported", str(ex)) + # Assert that this request is accepted and the server moves to ACTIVE + server = self.api.post_server({'server': server}) + self._wait_for_state_change(server, 'ACTIVE')