Skip to content

Commit 93578ef

Browse files
committed
Add 'Host Status' to 'server list --long' with >= v2.16
Currently, the 'Host Status' field is shown only for 'server show' but not for 'server list'. The host_status can be helpful for users who are having issues with servers that show a status of ACTIVE, as it can show a hint about the compute host status when nova policy is configured to allow it. Story: 2009689 Task: 44003 Change-Id: I6209cf52044218b7b32ab2fa5712574f12ba2f5f
1 parent 9fc9e8d commit 93578ef

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

openstackclient/compute/v2/server.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,6 +2569,21 @@ def take_action(self, parsed_args):
25692569
else:
25702570
s.security_groups_name = []
25712571

2572+
# The host_status field contains the status of the compute host the
2573+
# server is on. It is only returned by the API when the nova-api
2574+
# policy allows. Users can look at the host_status field when, for
2575+
# example, their server has status ACTIVE but is unresponsive. The
2576+
# host_status field can indicate a possible problem on the host
2577+
# it's on, providing useful information to a user in this
2578+
# situation.
2579+
if (
2580+
compute_client.api_version >= api_versions.APIVersion('2.16') and
2581+
parsed_args.long
2582+
):
2583+
if any([hasattr(s, 'host_status') for s in data]):
2584+
columns += ('Host Status',)
2585+
column_headers += ('Host Status',)
2586+
25722587
table = (
25732588
column_headers,
25742589
(

openstackclient/tests/unit/compute/v2/test_server.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4885,6 +4885,99 @@ def test_server_list_with_power_state(self):
48854885
self.assertEqual(self.columns, columns)
48864886
self.assertEqual(tuple(self.data), tuple(data))
48874887

4888+
def test_server_list_long_with_host_status_v216(self):
4889+
self.app.client_manager.compute.api_version = \
4890+
api_versions.APIVersion('2.16')
4891+
4892+
self.data1 = tuple(
4893+
(
4894+
s.id,
4895+
s.name,
4896+
s.status,
4897+
getattr(s, 'OS-EXT-STS:task_state'),
4898+
server.PowerStateColumn(
4899+
getattr(s, 'OS-EXT-STS:power_state')
4900+
),
4901+
format_columns.DictListColumn(s.networks),
4902+
# Image will be an empty string if boot-from-volume
4903+
self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
4904+
s.image['id'] if s.image else server.IMAGE_STRING_FOR_BFV,
4905+
self.flavor.name,
4906+
s.flavor['id'],
4907+
getattr(s, 'OS-EXT-AZ:availability_zone'),
4908+
getattr(s, 'OS-EXT-SRV-ATTR:host'),
4909+
s.Metadata,
4910+
) for s in self.servers)
4911+
4912+
arglist = [
4913+
'--long'
4914+
]
4915+
verifylist = [
4916+
('long', True),
4917+
]
4918+
4919+
# First test without host_status in the data -- the column should not
4920+
# be present in this case.
4921+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
4922+
columns, data = self.cmd.take_action(parsed_args)
4923+
4924+
self.servers_mock.list.assert_called_with(**self.kwargs)
4925+
4926+
self.assertEqual(self.columns_long, columns)
4927+
self.assertEqual(tuple(self.data1), tuple(data))
4928+
4929+
# Next test with host_status in the data -- the column should be
4930+
# present in this case.
4931+
self.servers_mock.reset_mock()
4932+
4933+
self.attrs['host_status'] = 'UP'
4934+
servers = self.setup_servers_mock(3)
4935+
self.servers_mock.list.return_value = servers
4936+
4937+
# Make sure the returned image and flavor IDs match the servers.
4938+
Image = collections.namedtuple('Image', 'id name')
4939+
self.images_mock.return_value = [
4940+
Image(id=s.image['id'], name=self.image.name)
4941+
# Image will be an empty string if boot-from-volume
4942+
for s in servers if s.image
4943+
]
4944+
4945+
Flavor = collections.namedtuple('Flavor', 'id name')
4946+
self.flavors_mock.list.return_value = [
4947+
Flavor(id=s.flavor['id'], name=self.flavor.name)
4948+
for s in servers
4949+
]
4950+
4951+
# Add the expected host_status column and data.
4952+
columns_long = self.columns_long + ('Host Status',)
4953+
self.data2 = tuple(
4954+
(
4955+
s.id,
4956+
s.name,
4957+
s.status,
4958+
getattr(s, 'OS-EXT-STS:task_state'),
4959+
server.PowerStateColumn(
4960+
getattr(s, 'OS-EXT-STS:power_state')
4961+
),
4962+
format_columns.DictListColumn(s.networks),
4963+
# Image will be an empty string if boot-from-volume
4964+
self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
4965+
s.image['id'] if s.image else server.IMAGE_STRING_FOR_BFV,
4966+
self.flavor.name,
4967+
s.flavor['id'],
4968+
getattr(s, 'OS-EXT-AZ:availability_zone'),
4969+
getattr(s, 'OS-EXT-SRV-ATTR:host'),
4970+
s.Metadata,
4971+
s.host_status,
4972+
) for s in servers)
4973+
4974+
columns, data = self.cmd.take_action(parsed_args)
4975+
4976+
self.servers_mock.list.assert_called_with(**self.kwargs)
4977+
4978+
self.assertEqual(columns_long, columns)
4979+
self.assertEqual(tuple(self.data2), tuple(data))
4980+
48884981

48894982
class TestServerListV273(_TestServerList):
48904983

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
The ``server list`` command will now display ``Host Status`` when the
5+
``--long`` option is specified and the compute API microversion is 2.16 or
6+
greater.

0 commit comments

Comments
 (0)