From f7cdc3eefe1d34bca2efb08d21c401cc9d9a457d Mon Sep 17 00:00:00 2001 From: Abhishek Talwar Date: Thu, 11 Dec 2014 14:54:03 +0530 Subject: [PATCH] Glance image delete output Deleting an already deleted image using admin user is throwing an error "404 Not Found" which is confusing. Deleting an image that does not exist throws "No image with a name or ID of 'image-id' exists." Updated the code so that trying to delete an already deleted image throws "No image with an ID of 'image-id' exists." error. Closes-Bug: #1333119 Change-Id: I8f9a6174663337a0f48aafa029a4339c32eb2134 Co-Authored-By: Abhishek Talwar Co-Authored-By: Kamil Rykowski --- glanceclient/v1/shell.py | 3 +++ glanceclient/v2/shell.py | 4 ++++ tests/v1/test_shell.py | 32 ++++++++++++++++++++++++++++++++ tests/v2/test_shell_v2.py | 12 ++++++++++++ 4 files changed, 51 insertions(+) diff --git a/glanceclient/v1/shell.py b/glanceclient/v1/shell.py index d4d117e3..3a1bc815 100644 --- a/glanceclient/v1/shell.py +++ b/glanceclient/v1/shell.py @@ -321,6 +321,9 @@ def do_image_delete(gc, args): """Delete specified image(s).""" for args_image in args.images: image = utils.find_resource(gc.images, args_image) + if image and image.status == "deleted": + msg = "No image with an ID of '%s' exists." % image.id + raise exc.CommandError(msg) try: if args.verbose: print('Requesting image delete for %s ...' % diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py index 4da2d990..81b48b94 100644 --- a/glanceclient/v2/shell.py +++ b/glanceclient/v2/shell.py @@ -261,6 +261,10 @@ def do_image_upload(gc, args): @utils.arg('id', metavar='', help='ID of image to delete.') def do_image_delete(gc, args): """Delete specified image.""" + image = gc.images.get(args.id) + if image and image.status == "deleted": + msg = "No image with an ID of '%s' exists." % image.id + utils.exit(msg) gc.images.delete(args.id) diff --git a/tests/v1/test_shell.py b/tests/v1/test_shell.py index fa2cd5fe..fb02c391 100644 --- a/tests/v1/test_shell.py +++ b/tests/v1/test_shell.py @@ -187,6 +187,28 @@ fixtures = { }, None ) + }, + '/v1/images/detail?limit=20&name=70aa106f-3750-4d7c-a5ce-0a535ac08d0a': { + 'GET': ( + {}, + {'images': [ + { + 'id': '70aa106f-3750-4d7c-a5ce-0a535ac08d0a', + 'name': 'imagedeleted', + 'deleted': True, + 'status': 'deleted', + }, + ]}, + ), + }, + '/v1/images/70aa106f-3750-4d7c-a5ce-0a535ac08d0a': { + 'HEAD': ( + { + 'x-image-meta-id': '70aa106f-3750-4d7c-a5ce-0a535ac08d0a', + 'x-image-meta-status': 'deleted' + }, + None + ) } } @@ -387,6 +409,16 @@ class ShellStdinHandlingTests(testtools.TestCase): ) ) + def test_image_delete_deleted(self): + self.assertRaises( + exc.CommandError, + v1shell.do_image_delete, + self.gc, + argparse.Namespace( + images=['70aa106f-3750-4d7c-a5ce-0a535ac08d0a'] + ) + ) + def test_image_update_closed_stdin(self): """Supply glanceclient with a closed stdin, and perform an image update to an active image. Glanceclient should not attempt to read diff --git a/tests/v2/test_shell_v2.py b/tests/v2/test_shell_v2.py index 23894eab..203771c0 100644 --- a/tests/v2/test_shell_v2.py +++ b/tests/v2/test_shell_v2.py @@ -350,6 +350,18 @@ class ShellV2Test(testtools.TestCase): mocked_delete.assert_called_once_with('pass') + def test_do_image_delete_deleted(self): + image_id = 'deleted-img' + args = self._make_args({'id': image_id}) + with mock.patch.object(self.gc.images, 'get') as mocked_get: + mocked_get.return_value = self._make_args({'id': image_id, + 'status': 'deleted'}) + + msg = "No image with an ID of '%s' exists." % image_id + self.assert_exits_with_msg(func=test_shell.do_image_delete, + func_args=args, + err_msg=msg) + def test_do_member_list(self): args = self._make_args({'image_id': 'IMG-01'}) with mock.patch.object(self.gc.image_members, 'list') as mocked_list: