From f200799848831a00f350c324bb77c00efa50da1c Mon Sep 17 00:00:00 2001 From: Yongli He Date: Mon, 9 Sep 2019 13:56:30 +0800 Subject: compute: Add 'server show --topology' option Add support for compute microversion 2.78 by adding a '--topology' option to 'openstack server show' command that retrieves server NUMA information. Change-Id: Ie22979df2ea9082ca64a4d43b571bd4025684825 --- openstackclient/compute/v2/server.py | 46 ++++++++++++++++---- .../tests/unit/compute/v2/test_server.py | 49 ++++++++++++++++++++++ 2 files changed, 86 insertions(+), 9 deletions(-) (limited to 'openstackclient') diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index ba0243ef..c1716e5b 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -3383,7 +3383,8 @@ class ShelveServer(command.Command): class ShowServer(command.ShowOne): _description = _( "Show server details. Specify ``--os-compute-api-version 2.47`` " - "or higher to see the embedded flavor information for the server.") + "or higher to see the embedded flavor information for the server." + ) def get_parser(self, prog_name): parser = super(ShowServer, self).get_parser(prog_name) @@ -3392,18 +3393,29 @@ class ShowServer(command.ShowOne): metavar='', help=_('Server (name or ID)'), ) - parser.add_argument( + # TODO(stephenfin): This should be a separate command, not a flag + diagnostics_group = parser.add_mutually_exclusive_group() + diagnostics_group.add_argument( '--diagnostics', action='store_true', default=False, help=_('Display server diagnostics information'), ) + diagnostics_group.add_argument( + '--topology', + action='store_true', + default=False, + help=_( + 'Include topology information in the output ' + '(supported by --os-compute-api-version 2.78 or above)' + ), + ) return parser def take_action(self, parsed_args): compute_client = self.app.client_manager.compute - server = utils.find_resource(compute_client.servers, - parsed_args.server) + server = utils.find_resource( + compute_client.servers, parsed_args.server) if parsed_args.diagnostics: (resp, data) = server.diagnostics() @@ -3412,10 +3424,26 @@ class ShowServer(command.ShowOne): "Error retrieving diagnostics data\n" )) return ({}, {}) - else: - data = _prep_server_detail(compute_client, - self.app.client_manager.image, server, - refresh=False) + return zip(*sorted(data.items())) + + topology = None + if parsed_args.topology: + if compute_client.api_version < api_versions.APIVersion('2.78'): + msg = _( + '--os-compute-api-version 2.78 or greater is required to ' + 'support the --topology option' + ) + raise exceptions.CommandError(msg) + + topology = server.topology() + + data = _prep_server_detail( + compute_client, self.app.client_manager.image, server, + refresh=False) + + if topology: + data['topology'] = format_columns.DictColumn(topology) + return zip(*sorted(data.items())) @@ -3731,7 +3759,7 @@ class UnsetServer(command.Command): help=_( 'Tag to remove from the server. ' 'Specify multiple times to remove multiple tags. ' - '(supported by --os-compute-api-version 2.26 or later' + '(supported by --os-compute-api-version 2.26 or above)' ), ) return parser diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py index efc105e5..8c3bf317 100644 --- a/openstackclient/tests/unit/compute/v2/test_server.py +++ b/openstackclient/tests/unit/compute/v2/test_server.py @@ -6285,6 +6285,10 @@ class TestServerShow(TestServer): self.image = image_fakes.FakeImage.create_one_image() self.flavor = compute_fakes.FakeFlavor.create_one_flavor() + self.topology = { + 'nodes': [{'vcpu_set': [0, 1]}, {'vcpu_set': [2, 3]}], + 'pagesize_kb': None, + } server_info = { 'image': {'id': self.image.id}, 'flavor': {'id': self.flavor.id}, @@ -6298,6 +6302,7 @@ class TestServerShow(TestServer): resp.status_code = 200 server_method = { 'diagnostics': (resp, {'test': 'test'}), + 'topology': self.topology, } self.server = compute_fakes.FakeServer.create_one_server( attrs=server_info, methods=server_method) @@ -6348,6 +6353,7 @@ class TestServerShow(TestServer): ] verifylist = [ ('diagnostics', False), + ('topology', False), ('server', self.server.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -6365,6 +6371,7 @@ class TestServerShow(TestServer): ] verifylist = [ ('diagnostics', False), + ('topology', False), ('server', self.server.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -6391,6 +6398,7 @@ class TestServerShow(TestServer): ] verifylist = [ ('diagnostics', True), + ('topology', False), ('server', self.server.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -6400,6 +6408,47 @@ class TestServerShow(TestServer): self.assertEqual(('test',), columns) self.assertEqual(('test',), data) + def test_show_topology(self): + self.app.client_manager.compute.api_version = \ + api_versions.APIVersion('2.78') + + arglist = [ + '--topology', + self.server.name, + ] + verifylist = [ + ('diagnostics', False), + ('topology', True), + ('server', self.server.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.columns += ('topology',) + self.data += (format_columns.DictColumn(self.topology),) + + columns, data = self.cmd.take_action(parsed_args) + + self.assertCountEqual(self.columns, columns) + self.assertCountEqual(self.data, data) + + def test_show_topology_pre_v278(self): + self.app.client_manager.compute.api_version = \ + api_versions.APIVersion('2.77') + + arglist = [ + '--topology', + self.server.name, + ] + verifylist = [ + ('diagnostics', False), + ('topology', True), + ('server', self.server.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args) + class TestServerStart(TestServer): -- cgit v1.2.1