From 7cf60168c72be429720ebd01bea735148f819ec1 Mon Sep 17 00:00:00 2001 From: Rajat Dhasmana Date: Wed, 14 Jul 2021 06:23:19 -0400 Subject: [PATCH] Cleanup glance image metadata during instance reschedule When we create an instance using volume, if the instance create fails the first time, it tries to reschedule it using the same volume. When rescheduling, we encounter an issue with improper cleanup of glance image metadata, hence it fails on cinder side. This patch addresses it by checking for glance image metadata incase of an exception and does the proper cleanup. Closes-Bug: #1936474 Change-Id: Ife4e330b11bfe278231aa93e354e12b13d7dd7fc --- .../volume/flows/test_create_volume_flow.py | 35 +++++++++++++++++++ cinder/volume/flows/manager/create_volume.py | 7 ++++ ...age-metadata-cleanup-e0dcc6a32331a04f.yaml | 7 ++++ 3 files changed, 49 insertions(+) create mode 100644 releasenotes/notes/glance-image-metadata-cleanup-e0dcc6a32331a04f.yaml 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 e3e1ae8b46e..7b42b119006 100644 --- a/cinder/tests/unit/volume/flows/test_create_volume_flow.py +++ b/cinder/tests/unit/volume/flows/test_create_volume_flow.py @@ -2210,3 +2210,38 @@ class CreateVolumeFlowManagerImageCacheTestCase(test.TestCase): image_meta, self.mock_image_service, update_cache=True) + + @ddt.data([], ['fake_entry']) + @mock.patch('cinder.image.image_utils.verify_glance_image_signature') + @mock.patch('cinder.image.image_utils.qemu_img_info') + def test__create_from_image_cache_or_download( + self, glance_metadata, mock_qemu_img, mock_verify, + mock_get_internal_context, mock_create_from_img_dl, + mock_create_from_src, mock_handle_bootable, mock_fetch_img): + fake_db = mock.MagicMock() + fake_driver = mock.MagicMock() + fake_volume_manager = mock.MagicMock() + fake_db.volume_glance_metadata_get.return_value = glance_metadata + fake_manager = create_volume_manager.CreateVolumeFromSpecTask( + fake_volume_manager, fake_db, fake_driver) + volume = fake_volume.fake_volume_obj(self.ctxt, + id=fakes.VOLUME_ID, + host='host@backend#pool') + image_location = 'someImageLocationStr' + image_id = fakes.IMAGE_ID + image_meta = {'virtual_size': '1073741824', 'size': 1073741824} + mock_verify.return_value = True + + mock_create_from_img_dl.side_effect = exception.CinderException + self.assertRaises( + exception.CinderException, + fake_manager._create_from_image_cache_or_download, + self.ctxt, volume, image_location, image_id, image_meta, + self.mock_image_service) + fake_db.volume_glance_metadata_bulk_create.assert_called_once_with( + self.ctxt, volume.id, {'signature_verified': True}) + fake_db.volume_glance_metadata_get.assert_called_once_with( + self.ctxt, volume.id) + if glance_metadata: + fake_db.volume_glance_metadata_delete_by_volume.\ + assert_called_once_with(self.ctxt, volume.id) diff --git a/cinder/volume/flows/manager/create_volume.py b/cinder/volume/flows/manager/create_volume.py index 7775e82b716..014709f5308 100644 --- a/cinder/volume/flows/manager/create_volume.py +++ b/cinder/volume/flows/manager/create_volume.py @@ -953,6 +953,13 @@ class CreateVolumeFromSpecTask(flow_utils.CinderTask): volume, image_id, image_meta) + except Exception: + with excutils.save_and_reraise_exception(): + vol_glance_metadata = self.db.volume_glance_metadata_get( + context, volume.id) + if vol_glance_metadata: + self.db.volume_glance_metadata_delete_by_volume( + context, volume.id) finally: # If we created the volume as the minimal size, extend it back to # what was originally requested. If an exception has occurred or diff --git a/releasenotes/notes/glance-image-metadata-cleanup-e0dcc6a32331a04f.yaml b/releasenotes/notes/glance-image-metadata-cleanup-e0dcc6a32331a04f.yaml new file mode 100644 index 00000000000..533fca0f44b --- /dev/null +++ b/releasenotes/notes/glance-image-metadata-cleanup-e0dcc6a32331a04f.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + `Bug 1936474 + `__ + Fixed improper cleanup of glance image metadata when + rescheduling instance.