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: