From 371e0b667e33a32196585c2f684b214bc25b184a Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Thu, 16 Nov 2017 08:46:49 -0600 Subject: [PATCH] Cleanup objects that we create on behalf of images When the use performs create_image on a cloud that requires the image be uploaded to swift, we upload the image content to swift for them. Once the image is imported, the content in swift is no longer needed as glance copies the data into its own area. Clean the images up so that we're not just accumulating tons of content in swift. Change-Id: Iede6441c0cad1d99e92fdfacf96d81aad479a93e --- .../cleanup-objects-f99aeecf22ac13dd.yaml | 6 ++++++ shade/openstackcloud.py | 8 ++++++++ shade/tests/unit/test_image.py | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 releasenotes/notes/cleanup-objects-f99aeecf22ac13dd.yaml diff --git a/releasenotes/notes/cleanup-objects-f99aeecf22ac13dd.yaml b/releasenotes/notes/cleanup-objects-f99aeecf22ac13dd.yaml new file mode 100644 index 000000000..e1e0752fd --- /dev/null +++ b/releasenotes/notes/cleanup-objects-f99aeecf22ac13dd.yaml @@ -0,0 +1,6 @@ +--- +features: + - If shade has to create objects in swift to upload an + image, it will now delete those objects upon successful + image creation as they are no longer needed. They will + also be deleted on fatal import errors. diff --git a/shade/openstackcloud.py b/shade/openstackcloud.py index f56e029ba..db7b18827 100644 --- a/shade/openstackcloud.py +++ b/shade/openstackcloud.py @@ -4875,6 +4875,9 @@ class OpenStackCloud( self.log.debug( "Image Task %s imported %s in %s", glance_task.id, image_id, (time.time() - start)) + # Clean up after ourselves. The object we created is not + # needed after the import is done. + self.delete_object(container, name) return self.get_image(image_id) elif status['status'] == 'failure': if status['message'] == IMAGE_ERROR_396: @@ -4882,6 +4885,11 @@ class OpenStackCloud( '/tasks', data=task_args) self.list_images.invalidate(self) else: + # Clean up after ourselves. The image did not import + # and this isn't a 'just retry' error - glance didn't + # like the content. So we don't want to keep it for + # next time. + self.delete_object(container, name) raise OpenStackCloudException( "Image creation failed: {message}".format( message=status['message']), diff --git a/shade/tests/unit/test_image.py b/shade/tests/unit/test_image.py index 97cab614e..71d723437 100644 --- a/shade/tests/unit/test_image.py +++ b/shade/tests/unit/test_image.py @@ -360,6 +360,25 @@ class TestImage(BaseTestImage): 'Content-Type': 'application/openstack-images-v2.1-json-patch'}) ), + dict(method='HEAD', + uri='{endpoint}/{container}/{object}'.format( + endpoint=endpoint, container=container_name, + object=image_name), + headers={ + 'X-Timestamp': '1429036140.50253', + 'X-Trans-Id': 'txbbb825960a3243b49a36f-005a0dadaedfw1', + 'Content-Length': '1290170880', + 'Last-Modified': 'Tue, 14 Apr 2015 18:29:01 GMT', + 'X-Object-Meta-X-Shade-Sha256': fakes.NO_SHA256, + 'X-Object-Meta-X-Shade-Md5': fakes.NO_MD5, + 'Date': 'Thu, 16 Nov 2017 15:24:30 GMT', + 'Accept-Ranges': 'bytes', + 'Content-Type': 'application/octet-stream', + 'Etag': fakes.NO_MD5}), + dict(method='DELETE', + uri='{endpoint}/{container}/{object}'.format( + endpoint=endpoint, container=container_name, + object=image_name)), dict(method='GET', uri='https://image.example.com/v2/images', json=self.fake_search_return) ])