Add waiters to OSC share create/delete/resize
This patch adds a '--wait' argument to the following commands: openstack share create openstack share delete openstack share resize When passing that flag, the command will return only after the action has been performed. For share create and share reszise, the command will return after the share reaches 'available' state. For deleting a share, the command will return only after the share has been deleted. Change-Id: I8d6ddb1eeba97313fd58f1f6d205906b7611af3a Partially-implements: bp add-waiters
This commit is contained in:
parent
f98d4fa7d3
commit
78981e768c
|
@ -172,6 +172,12 @@ class CreateShare(command.ShowOne):
|
|||
help=_('Optional share group name or ID in which to create '
|
||||
'the share. (Default=None).')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--wait',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Wait for share creation')
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
@ -218,6 +224,17 @@ class CreateShare(command.ShowOne):
|
|||
|
||||
share = share_client.shares.create(**body)
|
||||
|
||||
if parsed_args.wait:
|
||||
if not oscutils.wait_for_status(
|
||||
status_f=share_client.shares.get,
|
||||
res_id=share.id,
|
||||
success_status=['available']
|
||||
):
|
||||
LOG.error(_("ERROR: Share is in error state."))
|
||||
|
||||
share = apiutils.find_resource(share_client.shares,
|
||||
share.id)
|
||||
|
||||
printable_share = share._info
|
||||
printable_share.pop('links', None)
|
||||
printable_share.pop('shares_type', None)
|
||||
|
@ -251,6 +268,12 @@ class DeleteShare(command.Command):
|
|||
help=_("Attempt forced removal of share(s), regardless of state "
|
||||
"(defaults to False)")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--wait",
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Wait for share deletion")
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
@ -269,6 +292,12 @@ class DeleteShare(command.Command):
|
|||
else:
|
||||
share_client.shares.delete(share_obj,
|
||||
share_group_id)
|
||||
if parsed_args.wait:
|
||||
if not oscutils.wait_for_delete(
|
||||
manager=share_client.shares,
|
||||
res_id=share_obj.id):
|
||||
result += 1
|
||||
|
||||
except Exception as exc:
|
||||
result += 1
|
||||
LOG.error(_("Failed to delete share with "
|
||||
|
@ -706,6 +735,12 @@ class ResizeShare(command.Command):
|
|||
type=int,
|
||||
help=_('New size of share, in GiBs')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--wait',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Wait for share resize')
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
@ -733,3 +768,11 @@ class ResizeShare(command.Command):
|
|||
raise exceptions.CommandError(_(
|
||||
"Share size is already at %s GiBs" % new_size
|
||||
))
|
||||
if parsed_args.wait:
|
||||
if not oscutils.wait_for_status(
|
||||
status_f=share_client.shares.get,
|
||||
res_id=share.id,
|
||||
success_status=['available']
|
||||
):
|
||||
raise exceptions.CommandError(_(
|
||||
"Share not available after resize attempt."))
|
||||
|
|
|
@ -55,9 +55,13 @@ class TestShareCreate(TestShare):
|
|||
def setUp(self):
|
||||
super(TestShareCreate, self).setUp()
|
||||
|
||||
self.new_share = manila_fakes.FakeShare.create_one_share()
|
||||
self.new_share = manila_fakes.FakeShare.create_one_share(
|
||||
attrs={'status': 'available'}
|
||||
)
|
||||
self.shares_mock.create.return_value = self.new_share
|
||||
|
||||
self.shares_mock.get.return_value = self.new_share
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = osc_shares.CreateShare(self.app, None)
|
||||
|
||||
|
@ -146,6 +150,81 @@ class TestShareCreate(TestShare):
|
|||
# we implement snapshot support in OSC
|
||||
# def test_share_create_with_snapshot(self):
|
||||
|
||||
def test_share_create_wait(self):
|
||||
|
||||
arglist = [
|
||||
self.new_share.share_proto,
|
||||
str(self.new_share.size),
|
||||
'--wait'
|
||||
]
|
||||
verifylist = [
|
||||
('share_proto', self.new_share.share_proto),
|
||||
('size', self.new_share.size),
|
||||
('wait', True)
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.shares_mock.create.assert_called_with(
|
||||
availability_zone=None,
|
||||
description=None,
|
||||
is_public=False,
|
||||
metadata={},
|
||||
name=None,
|
||||
share_group_id=None,
|
||||
share_network=None,
|
||||
share_proto=self.new_share.share_proto,
|
||||
share_type=None,
|
||||
size=self.new_share.size,
|
||||
snapshot_id=None
|
||||
)
|
||||
|
||||
self.shares_mock.get.assert_called_with(self.new_share.id)
|
||||
self.assertCountEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.datalist, data)
|
||||
|
||||
@mock.patch('manilaclient.osc.v2.share.LOG')
|
||||
def test_share_create_wait_error(self, mock_logger):
|
||||
|
||||
arglist = [
|
||||
self.new_share.share_proto,
|
||||
str(self.new_share.size),
|
||||
'--wait'
|
||||
]
|
||||
verifylist = [
|
||||
('share_proto', self.new_share.share_proto),
|
||||
('size', self.new_share.size),
|
||||
('wait', True)
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
with mock.patch('osc_lib.utils.wait_for_status', return_value=False):
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.shares_mock.create.assert_called_with(
|
||||
availability_zone=None,
|
||||
description=None,
|
||||
is_public=False,
|
||||
metadata={},
|
||||
name=None,
|
||||
share_group_id=None,
|
||||
share_network=None,
|
||||
share_proto=self.new_share.share_proto,
|
||||
share_type=None,
|
||||
size=self.new_share.size,
|
||||
snapshot_id=None
|
||||
)
|
||||
|
||||
mock_logger.error.assert_called_with(
|
||||
"ERROR: Share is in error state.")
|
||||
|
||||
self.shares_mock.get.assert_called_with(self.new_share.id)
|
||||
self.assertCountEqual(self.columns, columns)
|
||||
self.assertCountEqual(self.datalist, data)
|
||||
|
||||
|
||||
class TestShareDelete(TestShare):
|
||||
|
||||
|
@ -246,6 +325,51 @@ class TestShareDelete(TestShare):
|
|||
self.assertRaises(osc_utils.ParserException,
|
||||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
def test_share_delete_wait(self):
|
||||
shares = self.setup_shares_mock(count=1)
|
||||
|
||||
arglist = [
|
||||
shares[0].name,
|
||||
'--wait'
|
||||
]
|
||||
verifylist = [
|
||||
("force", False),
|
||||
("share_group", None),
|
||||
('shares', [shares[0].name]),
|
||||
('wait', True)
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
with mock.patch('osc_lib.utils.wait_for_delete', return_value=True):
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.shares_mock.delete.assert_called_with(shares[0], None)
|
||||
self.shares_mock.get.assert_called_with(shares[0].name)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_share_delete_wait_error(self):
|
||||
shares = self.setup_shares_mock(count=1)
|
||||
|
||||
arglist = [
|
||||
shares[0].name,
|
||||
'--wait'
|
||||
]
|
||||
verifylist = [
|
||||
("force", False),
|
||||
("share_group", None),
|
||||
('shares', [shares[0].name]),
|
||||
('wait', True)
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
with mock.patch('osc_lib.utils.wait_for_delete', return_value=False):
|
||||
self.assertRaises(
|
||||
osc_exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args
|
||||
)
|
||||
|
||||
|
||||
class TestShareList(TestShare):
|
||||
|
||||
|
@ -1103,7 +1227,8 @@ class TestResizeShare(TestShare):
|
|||
super(TestResizeShare, self).setUp()
|
||||
|
||||
self._share = manila_fakes.FakeShare.create_one_share(
|
||||
attrs={'size': 2})
|
||||
attrs={'size': 2,
|
||||
'status': 'available'})
|
||||
self.shares_mock.get.return_value = self._share
|
||||
|
||||
# Get the command objects to test
|
||||
|
@ -1205,3 +1330,44 @@ class TestResizeShare(TestShare):
|
|||
|
||||
self.assertRaises(osc_utils.ParserException,
|
||||
self.check_parser, self.cmd, arglist, verifylist)
|
||||
|
||||
def test_share_resize_wait(self):
|
||||
arglist = [
|
||||
self._share.id,
|
||||
'3',
|
||||
'--wait'
|
||||
]
|
||||
verifylist = [
|
||||
('share', self._share.id),
|
||||
('new_size', 3),
|
||||
('wait', True)
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.shares_mock.extend.assert_called_with(
|
||||
self._share,
|
||||
3
|
||||
)
|
||||
self.shares_mock.get.assert_called_with(self._share.id)
|
||||
|
||||
def test_share_resize_wait_error(self):
|
||||
arglist = [
|
||||
self._share.id,
|
||||
'3',
|
||||
'--wait'
|
||||
]
|
||||
verifylist = [
|
||||
('share', self._share.id),
|
||||
('new_size', 3),
|
||||
('wait', True)
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
with mock.patch('osc_lib.utils.wait_for_status', return_value=False):
|
||||
self.assertRaises(
|
||||
osc_exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue