Add 'server unshelve --wait' option

This was recently added to the 'server shelve' command. Add it now for
the 'unshelve' command.

Change-Id: I633dd85b60cf70b4f8610f414d82669dd6a53111
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
Stephen Finucane 2020-11-18 11:27:30 +00:00
parent 64c2a1a453
commit 2b073c2034
3 changed files with 101 additions and 48 deletions

View File

@ -4131,25 +4131,54 @@ class UnshelveServer(command.Command):
'SHELVED_OFFLOADED server (supported by ' 'SHELVED_OFFLOADED server (supported by '
'--os-compute-api-version 2.77 or above)'), '--os-compute-api-version 2.77 or above)'),
) )
parser.add_argument(
'--wait',
action='store_true',
default=False,
help=_('Wait for unshelve operation to complete'),
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
def _show_progress(progress):
if progress:
self.app.stdout.write('\rProgress: %s' % progress)
self.app.stdout.flush()
compute_client = self.app.client_manager.compute compute_client = self.app.client_manager.compute
support_az = compute_client.api_version >= api_versions.APIVersion( kwargs = {}
'2.77')
if not support_az and parsed_args.availability_zone: if parsed_args.availability_zone:
msg = _("--os-compute-api-version 2.77 or greater is required " if compute_client.api_version < api_versions.APIVersion('2.77'):
"to support the '--availability-zone' option.") msg = _(
raise exceptions.CommandError(msg) '--os-compute-api-version 2.77 or greater is required '
'to support the --availability-zone option'
)
raise exceptions.CommandError(msg)
kwargs['availability_zone'] = parsed_args.availability_zone
for server in parsed_args.server: for server in parsed_args.server:
if support_az: server_obj = utils.find_resource(
utils.find_resource( compute_client.servers,
compute_client.servers, server,
server )
).unshelve(availability_zone=parsed_args.availability_zone)
else: if server_obj.status.lower() not in (
utils.find_resource( 'shelved', 'shelved_offloaded',
compute_client.servers, ):
server, continue
).unshelve()
server_obj.unshelve(**kwargs)
if parsed_args.wait:
if not utils.wait_for_status(
compute_client.servers.get, server_obj.id,
success_status=('active', 'shutoff'),
callback=_show_progress,
):
LOG.error(_('Error unshelving server %s'), server_obj.id)
self.app.stdout.write(
_('Error unshelving server: %s\n') % server_obj.id)
raise SystemExit

View File

@ -6969,6 +6969,9 @@ class TestServerUnshelve(TestServer):
self.methods = { self.methods = {
'unshelve': None, 'unshelve': None,
} }
self.attrs = {
'status': 'SHELVED',
}
def test_unshelve_one_server(self): def test_unshelve_one_server(self):
self.run_method_with_servers('unshelve', 1) self.run_method_with_servers('unshelve', 1)
@ -6976,8 +6979,34 @@ class TestServerUnshelve(TestServer):
def test_unshelve_multi_servers(self): def test_unshelve_multi_servers(self):
self.run_method_with_servers('unshelve', 3) self.run_method_with_servers('unshelve', 3)
def test_unshelve_server_with_specified_az(self): def test_unshelve_with_specified_az(self):
server = compute_fakes.FakeServer.create_one_server() self.app.client_manager.compute.api_version = \
api_versions.APIVersion('2.77')
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = [
'--availability-zone', "foo-az",
server.id,
]
verifylist = [
('availability_zone', "foo-az"),
('server', [server.id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(server.id)
server.unshelve.assert_called_with(availability_zone="foo-az")
def test_unshelve_with_specified_az_pre_v277(self):
self.app.client_manager.compute.api_version = \
api_versions.APIVersion('2.76')
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
arglist = [ arglist = [
server.id, server.id,
'--availability-zone', "foo-az", '--availability-zone', "foo-az",
@ -6987,44 +7016,37 @@ class TestServerUnshelve(TestServer):
('server', [server.id]) ('server', [server.id])
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
ex = self.assertRaises(exceptions.CommandError, ex = self.assertRaises(
self.cmd.take_action, exceptions.CommandError,
parsed_args) self.cmd.take_action,
parsed_args)
self.assertIn( self.assertIn(
'--os-compute-api-version 2.77 or greater is required', str(ex)) '--os-compute-api-version 2.77 or greater is required', str(ex))
@mock.patch.object(common_utils, 'wait_for_status', return_value=True)
def test_unshelve_with_wait(self, mock_wait_for_status):
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
class TestServerUnshelveV277(TestServerUnshelve): arglist = ['--wait', server.name]
def setUp(self):
super(TestServerUnshelveV277, self).setUp()
self.server = compute_fakes.FakeServer.create_one_server(
methods=self.methods)
# This is the return value for utils.find_resource()
self.servers_mock.get.return_value = self.server
# Get the command object to test
self.cmd = server.UnshelveServer(self.app, None)
def test_specified_az_to_unshelve_with_v277(self):
self.app.client_manager.compute.api_version = api_versions.APIVersion(
'2.77')
arglist = [
'--availability-zone', "foo-az",
self.server.id,
]
verifylist = [ verifylist = [
('availability_zone', "foo-az"), ('server', [server.name]),
('server', [self.server.id]) ('wait', True),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id) self.assertIsNone(result)
self.server.unshelve.assert_called_with(availability_zone="foo-az")
self.servers_mock.get.assert_called_once_with(server.name)
server.unshelve.assert_called_once_with()
mock_wait_for_status.assert_called_once_with(
self.servers_mock.get,
server.id,
callback=mock.ANY,
success_status=('active', 'shutoff'),
)
class TestServerGeneral(TestServer): class TestServerGeneral(TestServer):

View File

@ -6,3 +6,5 @@ features:
server in environments where automatic offloading is not configured, while server in environments where automatic offloading is not configured, while
``--wait`` allows users to wait for the shelve and/or shelve offload ``--wait`` allows users to wait for the shelve and/or shelve offload
operations to complete. operations to complete.
- |
Add support ``--wait`` option for ``server shelve``.