From 4ce8e800c408583fe58b429fb249b2c202a65f0a Mon Sep 17 00:00:00 2001 From: Jay Lau Date: Fri, 25 Oct 2013 22:57:03 -0400 Subject: [PATCH] Enable "cinder delete" can delete multiple volumes in one request "nova delete" can delete multiple servers in one request but "cinder delete" can only delete one volume in one request, it is better to enhance cinder client to support remove multiple volumes in one request. Change-Id: I6a63aa3d7e4c152ae5e45bf2b36d862bdcd6df33 Closes-Bug: #1241941 --- cinderclient/tests/v1/fakes.py | 11 +++++++-- cinderclient/tests/v1/test_shell.py | 4 ++++ cinderclient/tests/v2/fakes.py | 11 +++++++-- cinderclient/tests/v2/test_shell.py | 4 ++++ cinderclient/v1/shell.py | 36 +++++++++++++++++++++-------- cinderclient/v2/shell.py | 36 +++++++++++++++++++++-------- 6 files changed, 78 insertions(+), 24 deletions(-) diff --git a/cinderclient/tests/v1/fakes.py b/cinderclient/tests/v1/fakes.py index 260bcaa57..b1d482117 100644 --- a/cinderclient/tests/v1/fakes.py +++ b/cinderclient/tests/v1/fakes.py @@ -297,13 +297,17 @@ class FakeHTTPClient(base_client.HTTPClient): # at the very least it's not complete def get_volumes_detail(self, **kw): return (200, {}, {"volumes": [ - {'id': 1234, + {'id': kw.get('id', 1234), 'name': 'sample-volume', 'attachments': [{'server_id': 1234}]}, ]}) def get_volumes_1234(self, **kw): - r = {'volume': self.get_volumes_detail()[2]['volumes'][0]} + r = {'volume': self.get_volumes_detail(id=1234)[2]['volumes'][0]} + return (200, {}, r) + + def get_volumes_5678(self, **kw): + r = {'volume': self.get_volumes_detail(id=5678)[2]['volumes'][0]} return (200, {}, r) def get_volumes_1234_encryption(self, **kw): @@ -350,6 +354,9 @@ class FakeHTTPClient(base_client.HTTPClient): def delete_volumes_1234(self, **kw): return (202, {}, None) + def delete_volumes_5678(self, **kw): + return (202, {}, None) + # # Quotas # diff --git a/cinderclient/tests/v1/test_shell.py b/cinderclient/tests/v1/test_shell.py index 26571da1b..740342d9c 100644 --- a/cinderclient/tests/v1/test_shell.py +++ b/cinderclient/tests/v1/test_shell.py @@ -117,6 +117,10 @@ class ShellTest(utils.TestCase): self.run_command('delete 1234') self.assert_called('DELETE', '/volumes/1234') + def test_delete_multiple(self): + self.run_command('delete 1234 5678') + self.assert_called('DELETE', '/volumes/5678') + def test_backup(self): self.run_command('backup-create 1234') self.assert_called('POST', '/backups') diff --git a/cinderclient/tests/v2/fakes.py b/cinderclient/tests/v2/fakes.py index 35351b2ce..174369d0a 100644 --- a/cinderclient/tests/v2/fakes.py +++ b/cinderclient/tests/v2/fakes.py @@ -304,13 +304,17 @@ class FakeHTTPClient(base_client.HTTPClient): # at the very least it's not complete def get_volumes_detail(self, **kw): return (200, {}, {"volumes": [ - {'id': 1234, + {'id': kw.get('id', 1234), 'name': 'sample-volume', 'attachments': [{'server_id': 1234}]}, ]}) def get_volumes_1234(self, **kw): - r = {'volume': self.get_volumes_detail()[2]['volumes'][0]} + r = {'volume': self.get_volumes_detail(id=1234)[2]['volumes'][0]} + return (200, {}, r) + + def get_volumes_5678(self, **kw): + r = {'volume': self.get_volumes_detail(id=5678)[2]['volumes'][0]} return (200, {}, r) def get_volumes_1234_encryption(self, **kw): @@ -357,6 +361,9 @@ class FakeHTTPClient(base_client.HTTPClient): def delete_volumes_1234(self, **kw): return (202, {}, None) + def delete_volumes_5678(self, **kw): + return (202, {}, None) + # # Quotas # diff --git a/cinderclient/tests/v2/test_shell.py b/cinderclient/tests/v2/test_shell.py index 566f620c7..26a389c8e 100644 --- a/cinderclient/tests/v2/test_shell.py +++ b/cinderclient/tests/v2/test_shell.py @@ -95,6 +95,10 @@ class ShellTest(utils.TestCase): self.run_command('delete 1234') self.assert_called('DELETE', '/volumes/1234') + def test_delete_multiple(self): + self.run_command('delete 1234 5678') + self.assert_called('DELETE', '/volumes/5678') + def test_backup(self): self.run_command('backup-create 1234') self.assert_called('POST', '/backups') diff --git a/cinderclient/v1/shell.py b/cinderclient/v1/shell.py index 2e90d5bf7..820dc87e0 100644 --- a/cinderclient/v1/shell.py +++ b/cinderclient/v1/shell.py @@ -277,22 +277,38 @@ def do_create(cs, args): _print_volume(volume) -@utils.arg('volume', metavar='', - help='Name or ID of the volume to delete.') +@utils.arg('volume', metavar='', nargs='+', + help='Name or ID of the volume(s) to delete.') @utils.service_type('volume') def do_delete(cs, args): - """Remove a volume.""" - volume = utils.find_volume(cs, args.volume) - volume.delete() + """Remove volume(s).""" + failure_count = 0 + for volume in args.volume: + try: + utils.find_volume(cs, volume).delete() + except Exception as e: + failure_count += 1 + print("Delete for volume %s failed: %s" % (volume, e)) + if failure_count == len(args.volume): + raise exceptions.CommandError("Unable to delete any of the specified " + "volumes.") -@utils.arg('volume', metavar='', - help='Name or ID of the volume to delete.') +@utils.arg('volume', metavar='', nargs='+', + help='Name or ID of the volume(s) to delete.') @utils.service_type('volume') def do_force_delete(cs, args): - """Attempt forced removal of a volume, regardless of its state.""" - volume = utils.find_volume(cs, args.volume) - volume.force_delete() + """Attempt forced removal of volume(s), regardless of the state(s).""" + failure_count = 0 + for volume in args.volume: + try: + utils.find_volume(cs, volume).force_delete() + except Exception as e: + failure_count += 1 + print("Delete for volume %s failed: %s" % (volume, e)) + if failure_count == len(args.volume): + raise exceptions.CommandError("Unable to force delete any of the " + "specified volumes.") @utils.arg('volume', metavar='', diff --git a/cinderclient/v2/shell.py b/cinderclient/v2/shell.py index d23360441..cd23ab44d 100644 --- a/cinderclient/v2/shell.py +++ b/cinderclient/v2/shell.py @@ -304,23 +304,39 @@ def do_create(cs, args): @utils.arg('volume', - metavar='', - help='Name or ID of the volume to delete.') + metavar='', nargs='+', + help='Name or ID of the volume(s) to delete.') @utils.service_type('volumev2') def do_delete(cs, args): - """Remove a volume.""" - volume = utils.find_volume(cs, args.volume) - volume.delete() + """Remove a volume(s).""" + failure_count = 0 + for volume in args.volume: + try: + utils.find_volume(cs, volume).delete() + except Exception as e: + failure_count += 1 + print("Delete for volume %s failed: %s" % (volume, e)) + if failure_count == len(args.volume): + raise exceptions.CommandError("Unable to delete any of the specified " + "volumes.") @utils.arg('volume', - metavar='', - help='Name or ID of the volume to delete.') + metavar='', nargs='+', + help='Name or ID of the volume(s) to delete.') @utils.service_type('volumev2') def do_force_delete(cs, args): - """Attempt forced removal of a volume, regardless of its state.""" - volume = utils.find_volume(cs, args.volume) - volume.force_delete() + """Attempt forced removal of volume(s), regardless of the state(s).""" + failure_count = 0 + for volume in args.volume: + try: + utils.find_volume(cs, volume).force_delete() + except Exception as e: + failure_count += 1 + print("Delete for volume %s failed: %s" % (volume, e)) + if failure_count == len(args.volume): + raise exceptions.CommandError("Unable to force delete any of the " + "specified volumes.") @utils.arg('volume', metavar='',