Merge ""--wait" option added for snapshot create/revert/delete commands"
This commit is contained in:
commit
9e81815674
@ -1054,6 +1054,7 @@ class ShellTest(test_utils.TestCase):
|
|||||||
self.shell.cs, expected_snapshot, 'deleted',
|
self.shell.cs, expected_snapshot, 'deleted',
|
||||||
resource_type='snapshot')
|
resource_type='snapshot')
|
||||||
|
|
||||||
|
@mock.patch.object(shell_v2, '_wait_for_share_status', mock.Mock())
|
||||||
def test_revert_to_snapshot(self):
|
def test_revert_to_snapshot(self):
|
||||||
|
|
||||||
fake_share_snapshot = type(
|
fake_share_snapshot = type(
|
||||||
@ -1066,6 +1067,25 @@ class ShellTest(test_utils.TestCase):
|
|||||||
|
|
||||||
self.assert_called('POST', '/shares/1234/action',
|
self.assert_called('POST', '/shares/1234/action',
|
||||||
body={'revert': {'snapshot_id': '5678'}})
|
body={'revert': {'snapshot_id': '5678'}})
|
||||||
|
# _wait_for_share_status should not be trigerred
|
||||||
|
self.assertEqual(0, shell_v2._wait_for_share_status.call_count)
|
||||||
|
|
||||||
|
@mock.patch.object(shell_v2, '_wait_for_share_status', mock.Mock())
|
||||||
|
def test_revert_to_snapshot_with_wait(self):
|
||||||
|
|
||||||
|
fake_share_snapshot = type(
|
||||||
|
'FakeShareSnapshot', (object,), {'id': '5678', 'share_id': '1234'})
|
||||||
|
self.mock_object(
|
||||||
|
shell_v2, '_find_share_snapshot',
|
||||||
|
mock.Mock(return_value=fake_share_snapshot))
|
||||||
|
|
||||||
|
self.run_command('revert-to-snapshot 5678 --wait')
|
||||||
|
|
||||||
|
self.assert_called('POST', '/shares/1234/action',
|
||||||
|
body={'revert': {'snapshot_id': '5678'}})
|
||||||
|
# _wait_for_share_status should be trigerred once
|
||||||
|
shell_v2._wait_for_share_status.assert_called_once_with(
|
||||||
|
self.shell.cs, mock.ANY)
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
self.run_command('delete 1234')
|
self.run_command('delete 1234')
|
||||||
@ -3693,6 +3713,39 @@ class ShellTest(test_utils.TestCase):
|
|||||||
'DELETE', '/share-networks/%s' % sn.id,
|
'DELETE', '/share-networks/%s' % sn.id,
|
||||||
clear_callstack=False)
|
clear_callstack=False)
|
||||||
|
|
||||||
|
@mock.patch.object(shell_v2, '_find_share', mock.Mock())
|
||||||
|
@mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock())
|
||||||
|
def test_snapshot_create(self):
|
||||||
|
share_to_create_snapshot = shares.Share('fake_share', {'id': '1234'})
|
||||||
|
shell_v2._find_share.return_value = share_to_create_snapshot
|
||||||
|
|
||||||
|
self.run_command(
|
||||||
|
'snapshot-create fake_share --name testshare1snapshot')
|
||||||
|
|
||||||
|
shell_v2._find_share.assert_has_calls([
|
||||||
|
mock.call(self.shell.cs, 'fake_share')])
|
||||||
|
self.assert_called_anytime(
|
||||||
|
'POST', '/snapshots', clear_callstack=False)
|
||||||
|
# _wait_for_snapshot_status should not be trigerred
|
||||||
|
self.assertEqual(0, shell_v2._wait_for_snapshot_status.call_count)
|
||||||
|
|
||||||
|
@mock.patch.object(shell_v2, '_find_share', mock.Mock())
|
||||||
|
@mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock())
|
||||||
|
def test_snapshot_create_with_wait(self):
|
||||||
|
share_to_create_snapshot = shares.Share('fake_share', {'id': '1234'})
|
||||||
|
shell_v2._find_share.return_value = share_to_create_snapshot
|
||||||
|
|
||||||
|
self.run_command(
|
||||||
|
'snapshot-create fake_share --name testshare1snapshot --wait')
|
||||||
|
|
||||||
|
shell_v2._find_share.assert_has_calls([
|
||||||
|
mock.call(self.shell.cs, 'fake_share')])
|
||||||
|
self.assert_called_anytime(
|
||||||
|
'POST', '/snapshots', clear_callstack=False)
|
||||||
|
# _wait_for_snapshot_status should be trigerred once
|
||||||
|
shell_v2._wait_for_snapshot_status.assert_called_once_with(
|
||||||
|
self.shell.cs, mock.ANY, expected_status='available')
|
||||||
|
|
||||||
@ddt.data(('fake_snapshot1', ), ('fake_snapshot1', 'fake_snapshot2'))
|
@ddt.data(('fake_snapshot1', ), ('fake_snapshot1', 'fake_snapshot2'))
|
||||||
def test_snapshot_delete(self, snapshot_ids):
|
def test_snapshot_delete(self, snapshot_ids):
|
||||||
fake_snapshots = [
|
fake_snapshots = [
|
||||||
@ -3713,6 +3766,23 @@ class ShellTest(test_utils.TestCase):
|
|||||||
'DELETE', '/snapshots/%s' % snapshot.id,
|
'DELETE', '/snapshots/%s' % snapshot.id,
|
||||||
clear_callstack=False)
|
clear_callstack=False)
|
||||||
|
|
||||||
|
@mock.patch.object(shell_v2, '_find_share_snapshot', mock.Mock())
|
||||||
|
@mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock())
|
||||||
|
def test_snapshot_delete_with_wait(self):
|
||||||
|
fake_snapshot = share_snapshots.ShareSnapshot(
|
||||||
|
'fake', {'id': 'fake_snapshot1'}, True)
|
||||||
|
shell_v2._find_share_snapshot.return_value = fake_snapshot
|
||||||
|
|
||||||
|
self.run_command('snapshot-delete fake_snapshot1 --wait')
|
||||||
|
|
||||||
|
shell_v2._find_share_snapshot.assert_has_calls([
|
||||||
|
mock.call(self.shell.cs, 'fake_snapshot1')])
|
||||||
|
self.assert_called_anytime(
|
||||||
|
'DELETE', '/snapshots/fake_snapshot1', clear_callstack=False)
|
||||||
|
# _wait_for_resource_status should be trigerred once
|
||||||
|
shell_v2._wait_for_snapshot_status.assert_called_once_with(
|
||||||
|
self.shell.cs, 'fake_snapshot1', expected_status='deleted')
|
||||||
|
|
||||||
@ddt.data(('snapshot_xyz', ), ('snapshot_abc', 'snapshot_xyz'))
|
@ddt.data(('snapshot_xyz', ), ('snapshot_abc', 'snapshot_xyz'))
|
||||||
def test_snapshot_force_delete_wait(self, snapshots_to_delete):
|
def test_snapshot_force_delete_wait(self, snapshots_to_delete):
|
||||||
fake_manager = mock.Mock()
|
fake_manager = mock.Mock()
|
||||||
|
@ -1817,11 +1817,18 @@ def do_snapshot_unmanage(cs, args):
|
|||||||
metavar='<snapshot>',
|
metavar='<snapshot>',
|
||||||
help='Name or ID of the snapshot to restore. The snapshot must be the '
|
help='Name or ID of the snapshot to restore. The snapshot must be the '
|
||||||
'most recent one known to manila.')
|
'most recent one known to manila.')
|
||||||
|
@cliutils.arg(
|
||||||
|
'--wait',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='Wait for share to be reverted from snapshot.')
|
||||||
def do_revert_to_snapshot(cs, args):
|
def do_revert_to_snapshot(cs, args):
|
||||||
"""Revert a share to the specified snapshot."""
|
"""Revert a share to the specified snapshot."""
|
||||||
snapshot = _find_share_snapshot(cs, args.snapshot)
|
snapshot = _find_share_snapshot(cs, args.snapshot)
|
||||||
share = _find_share(cs, snapshot.share_id)
|
share = _find_share(cs, snapshot.share_id)
|
||||||
share.revert_to_snapshot(snapshot)
|
share.revert_to_snapshot(snapshot)
|
||||||
|
if args.wait:
|
||||||
|
_wait_for_share_status(cs, share)
|
||||||
|
|
||||||
|
|
||||||
@cliutils.arg(
|
@cliutils.arg(
|
||||||
@ -3061,6 +3068,11 @@ def do_snapshot_instance_export_location_show(cs, args):
|
|||||||
metavar='<description>',
|
metavar='<description>',
|
||||||
default=None,
|
default=None,
|
||||||
help='Optional snapshot description. (Default=None)')
|
help='Optional snapshot description. (Default=None)')
|
||||||
|
@cliutils.arg(
|
||||||
|
'--wait',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='Wait for snapshot to be created.')
|
||||||
def do_snapshot_create(cs, args):
|
def do_snapshot_create(cs, args):
|
||||||
"""Add a new snapshot."""
|
"""Add a new snapshot."""
|
||||||
share = _find_share(cs, args.share)
|
share = _find_share(cs, args.share)
|
||||||
@ -3068,6 +3080,12 @@ def do_snapshot_create(cs, args):
|
|||||||
args.force,
|
args.force,
|
||||||
args.name,
|
args.name,
|
||||||
args.description)
|
args.description)
|
||||||
|
if args.wait:
|
||||||
|
try:
|
||||||
|
_wait_for_snapshot_status(cs, snapshot,
|
||||||
|
expected_status='available')
|
||||||
|
except exceptions.CommandError as e:
|
||||||
|
print(e, file=sys.stderr)
|
||||||
_print_share_snapshot(cs, snapshot)
|
_print_share_snapshot(cs, snapshot)
|
||||||
|
|
||||||
|
|
||||||
@ -3143,6 +3161,11 @@ def do_snapshot_rename(cs, args):
|
|||||||
metavar='<snapshot>',
|
metavar='<snapshot>',
|
||||||
nargs='+',
|
nargs='+',
|
||||||
help='Name or ID of the snapshot(s) to delete.')
|
help='Name or ID of the snapshot(s) to delete.')
|
||||||
|
@cliutils.arg(
|
||||||
|
'--wait',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help='Wait for snapshot to be deleted')
|
||||||
def do_snapshot_delete(cs, args):
|
def do_snapshot_delete(cs, args):
|
||||||
"""Remove one or more snapshots."""
|
"""Remove one or more snapshots."""
|
||||||
failure_count = 0
|
failure_count = 0
|
||||||
@ -3152,6 +3175,9 @@ def do_snapshot_delete(cs, args):
|
|||||||
snapshot_ref = _find_share_snapshot(
|
snapshot_ref = _find_share_snapshot(
|
||||||
cs, snapshot)
|
cs, snapshot)
|
||||||
cs.share_snapshots.delete(snapshot_ref)
|
cs.share_snapshots.delete(snapshot_ref)
|
||||||
|
if args.wait:
|
||||||
|
_wait_for_snapshot_status(cs, snapshot,
|
||||||
|
expected_status='deleted')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
failure_count += 1
|
failure_count += 1
|
||||||
print("Delete for snapshot %s failed: %s" % (
|
print("Delete for snapshot %s failed: %s" % (
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The commands "snapshot-create", "snapshot-delete" and "revert-to-snapshot"
|
||||||
|
now accept an optional "--wait" option that allows users to let the
|
||||||
|
client poll for the completion of the operation.
|
Loading…
Reference in New Issue
Block a user