diff --git a/glanceclient/v1/shell.py b/glanceclient/v1/shell.py index c4e53dc0..4c6591ae 100644 --- a/glanceclient/v1/shell.py +++ b/glanceclient/v1/shell.py @@ -332,6 +332,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 fa69f1d7..b405bcf7 100644 --- a/glanceclient/v2/shell.py +++ b/glanceclient/v2/shell.py @@ -268,6 +268,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 fd781c0b..c1a0a2e9 100644 --- a/tests/v2/test_shell_v2.py +++ b/tests/v2/test_shell_v2.py @@ -365,6 +365,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: