Skip to content

Commit 5f62572

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Add support for deleting volumes with associated snapshots"
2 parents 97ccb65 + 954c28d commit 5f62572

4 files changed

Lines changed: 76 additions & 11 deletions

File tree

doc/source/command-objects/volume.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,19 @@ Delete volume(s)
8888
.. code:: bash
8989
9090
os volume delete
91-
[--force]
91+
[--force | --purge]
9292
<volume> [<volume> ...]
9393
9494
.. option:: --force
9595

9696
Attempt forced removal of volume(s), regardless of state (defaults to False)
9797

98+
.. option:: --purge
99+
100+
Remove any snapshots along with volume(s) (defaults to False)
101+
102+
*Volume version 2 only*
103+
98104
.. _volume_delete-volume:
99105
.. describe:: <volume>
100106

openstackclient/tests/volume/v2/test_volume.py

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -420,27 +420,32 @@ def test_volume_delete_one_volume(self):
420420
volumes[0].id
421421
]
422422
verifylist = [
423-
("volumes", [volumes[0].id])
423+
("force", False),
424+
("purge", False),
425+
("volumes", [volumes[0].id]),
424426
]
425427
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
426428

427429
result = self.cmd.take_action(parsed_args)
428430

429-
self.volumes_mock.delete.assert_called_with(volumes[0].id)
431+
self.volumes_mock.delete.assert_called_once_with(
432+
volumes[0].id, cascade=False)
430433
self.assertIsNone(result)
431434

432435
def test_volume_delete_multi_volumes(self):
433436
volumes = self.setup_volumes_mock(count=3)
434437

435438
arglist = [v.id for v in volumes]
436439
verifylist = [
440+
('force', False),
441+
('purge', False),
437442
('volumes', arglist),
438443
]
439444
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
440445

441446
result = self.cmd.take_action(parsed_args)
442447

443-
calls = [call(v.id) for v in volumes]
448+
calls = [call(v.id, cascade=False) for v in volumes]
444449
self.volumes_mock.delete.assert_has_calls(calls)
445450
self.assertIsNone(result)
446451

@@ -452,6 +457,8 @@ def test_volume_delete_multi_volumes_with_exception(self):
452457
'unexist_volume',
453458
]
454459
verifylist = [
460+
('force', False),
461+
('purge', False),
455462
('volumes', arglist),
456463
]
457464
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -471,8 +478,46 @@ def test_volume_delete_multi_volumes_with_exception(self):
471478

472479
self.assertEqual(2, find_mock.call_count)
473480
self.volumes_mock.delete.assert_called_once_with(
474-
volumes[0].id
475-
)
481+
volumes[0].id, cascade=False)
482+
483+
def test_volume_delete_with_purge(self):
484+
volumes = self.setup_volumes_mock(count=1)
485+
486+
arglist = [
487+
'--purge',
488+
volumes[0].id,
489+
]
490+
verifylist = [
491+
('force', False),
492+
('purge', True),
493+
('volumes', [volumes[0].id]),
494+
]
495+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
496+
497+
result = self.cmd.take_action(parsed_args)
498+
499+
self.volumes_mock.delete.assert_called_once_with(
500+
volumes[0].id, cascade=True)
501+
self.assertIsNone(result)
502+
503+
def test_volume_delete_with_force(self):
504+
volumes = self.setup_volumes_mock(count=1)
505+
506+
arglist = [
507+
'--force',
508+
volumes[0].id,
509+
]
510+
verifylist = [
511+
('force', True),
512+
('purge', False),
513+
('volumes', [volumes[0].id]),
514+
]
515+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
516+
517+
result = self.cmd.take_action(parsed_args)
518+
519+
self.volumes_mock.force_delete.assert_called_once_with(volumes[0].id)
520+
self.assertIsNone(result)
476521

477522

478523
class TestVolumeList(TestVolume):

openstackclient/volume/v2/volume.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,19 @@ def get_parser(self, prog_name):
166166
nargs="+",
167167
help=_("Volume(s) to delete (name or ID)")
168168
)
169-
parser.add_argument(
169+
group = parser.add_mutually_exclusive_group()
170+
group.add_argument(
170171
"--force",
171172
action="store_true",
172-
default=False,
173173
help=_("Attempt forced removal of volume(s), regardless of state "
174174
"(defaults to False)")
175175
)
176+
group.add_argument(
177+
"--purge",
178+
action="store_true",
179+
help=_("Remove any snapshots along with volume(s) "
180+
"(defaults to False)")
181+
)
176182
return parser
177183

178184
def take_action(self, parsed_args):
@@ -186,12 +192,13 @@ def take_action(self, parsed_args):
186192
if parsed_args.force:
187193
volume_client.volumes.force_delete(volume_obj.id)
188194
else:
189-
volume_client.volumes.delete(volume_obj.id)
195+
volume_client.volumes.delete(volume_obj.id,
196+
cascade=parsed_args.purge)
190197
except Exception as e:
191198
result += 1
192199
LOG.error(_("Failed to delete volume with "
193-
"name or ID '%(volume)s': %(e)s")
194-
% {'volume': i, 'e': e})
200+
"name or ID '%(volume)s': %(e)s"),
201+
{'volume': i, 'e': e})
195202

196203
if result > 0:
197204
total = len(parsed_args.volumes)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
features:
3+
- |
4+
Add ``--purge`` option to ``volume delete`` command (Volume v2 only) in
5+
order to removing any snapshots along with volume automatically when user
6+
delete the volume.
7+
[Bug `1589332 <https://bugs.launchpad.net/python-openstackclient/+bug/1589332>`_]

0 commit comments

Comments
 (0)