Skip to content

Commit e755460

Browse files
committed
Fix microversion 2.100
This change fixes missing conditional logic for microversion 2.100 which adds support for showing `scheduler_hints` field to `openstack server list --long` output. Change-Id: I2820e02a91deb73850f37dc737dbec79dea99e8d Signed-off-by: Rajesh Tailor <ratailor@redhat.com>
1 parent 5f1ffe7 commit e755460

2 files changed

Lines changed: 170 additions & 19 deletions

File tree

openstackclient/compute/v2/server.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,17 @@ def _prep_server_detail(compute_client, image_client, server, *, refresh=True):
183183
'updated_at': 'updated',
184184
'user_data': 'OS-EXT-SRV-ATTR:user_data',
185185
'vm_state': 'OS-EXT-STS:vm_state',
186-
'scheduler_hints': 'scheduler_hints',
187186
}
188187
# NOTE(ratailor): microversion 2.96 introduces
189188
# pinned_availability_zone support
190189
if sdk_utils.supports_microversion(compute_client, '2.96'):
191190
column_map['pinned_availability_zone'] = 'pinned_availability_zone'
192191

192+
# NOTE(ratailor): microversion 2.100 introduces
193+
# scheduler_hints support
194+
if sdk_utils.supports_microversion(compute_client, '2.100'):
195+
column_map['scheduler_hints'] = 'scheduler_hints'
196+
193197
# Some columns returned by openstacksdk should not be shown because they're
194198
# either irrelevant or duplicates
195199
ignored_columns = {
@@ -335,10 +339,11 @@ def _prep_server_detail(compute_client, image_client, server, *, refresh=True):
335339
info['OS-EXT-STS:power_state']
336340
)
337341

338-
if 'scheduler_hints' in info:
339-
info['scheduler_hints'] = format_columns.DictListColumn(
340-
info.pop('scheduler_hints', {}),
341-
)
342+
if sdk_utils.supports_microversion(compute_client, '2.100'):
343+
if 'scheduler_hints' in info:
344+
info['scheduler_hints'] = format_columns.DictListColumn(
345+
info.pop('scheduler_hints', {}),
346+
)
342347

343348
return info
344349

@@ -2849,18 +2854,20 @@ def take_action(self, parsed_args):
28492854
'availability_zone',
28502855
'hypervisor_hostname',
28512856
'metadata',
2852-
'scheduler_hints',
28532857
)
28542858
column_headers += (
28552859
'Availability Zone',
28562860
'Host',
28572861
'Properties',
2858-
'Scheduler Hints',
28592862
)
28602863
if sdk_utils.supports_microversion(compute_client, '2.96'):
28612864
columns += ('pinned_availability_zone',)
28622865
column_headers += ('Pinned Availability Zone',)
28632866

2867+
if sdk_utils.supports_microversion(compute_client, '2.100'):
2868+
columns += ('scheduler_hints',)
2869+
column_headers += ('Scheduler Hints',)
2870+
28642871
if parsed_args.all_projects:
28652872
columns += ('project_id',)
28662873
column_headers += ('Project ID',)
@@ -2912,8 +2919,11 @@ def take_action(self, parsed_args):
29122919
'scheduler_hints',
29132920
"Scheduler Hints",
29142921
):
2915-
columns += ('scheduler_hints',)
2916-
column_headers += ('Scheduler Hints',)
2922+
if sdk_utils.supports_microversion(
2923+
compute_client, '2.100'
2924+
):
2925+
columns += ('scheduler_hints',)
2926+
column_headers += ('Scheduler Hints',)
29172927

29182928
# remove duplicates
29192929
column_headers = tuple(dict.fromkeys(column_headers))

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

Lines changed: 151 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4584,7 +4584,6 @@ class _TestServerList(TestServer):
45844584
'Availability Zone',
45854585
'Host',
45864586
'Properties',
4587-
'Scheduler Hints',
45884587
)
45894588
columns_all_projects = (
45904589
'ID',
@@ -4734,7 +4733,6 @@ def test_server_list_long_option(self):
47344733
getattr(s, 'availability_zone'),
47354734
server.HostColumn(getattr(s, 'hypervisor_hostname')),
47364735
format_columns.DictColumn(s.metadata),
4737-
format_columns.DictListColumn(None),
47384736
)
47394737
for s in self.servers
47404738
)
@@ -4811,8 +4809,6 @@ def test_server_list_column_option(self):
48114809
'Host',
48124810
'-c',
48134811
'Properties',
4814-
'-c',
4815-
'Scheduler Hints',
48164812
'--long',
48174813
]
48184814
verifylist = [
@@ -4834,7 +4830,6 @@ def test_server_list_column_option(self):
48344830
self.assertIn('Availability Zone', columns)
48354831
self.assertIn('Host', columns)
48364832
self.assertIn('Properties', columns)
4837-
self.assertIn('Scheduler Hints', columns)
48384833
self.assertCountEqual(columns, set(columns))
48394834

48404835
def test_server_list_no_name_lookup_option(self):
@@ -5247,7 +5242,6 @@ def test_server_list_long_with_host_status_v216(self):
52475242
getattr(s, 'availability_zone'),
52485243
server.HostColumn(getattr(s, 'hypervisor_hostname')),
52495244
format_columns.DictColumn(s.metadata),
5250-
format_columns.DictListColumn(s.scheduler_hints),
52515245
)
52525246
for s in self.servers
52535247
)
@@ -5303,7 +5297,6 @@ def test_server_list_long_with_host_status_v216(self):
53035297
getattr(s, 'availability_zone'),
53045298
server.HostColumn(getattr(s, 'hypervisor_hostname')),
53055299
format_columns.DictColumn(s.metadata),
5306-
format_columns.DictListColumn(s.scheduler_hints),
53075300
s.host_status,
53085301
)
53095302
for s in servers
@@ -5558,7 +5551,6 @@ class TestServerListV296(_TestServerList):
55585551
'Availability Zone',
55595552
'Host',
55605553
'Properties',
5561-
'Scheduler Hints',
55625554
'Pinned Availability Zone',
55635555
)
55645556

@@ -5611,7 +5603,6 @@ def test_server_list_long_option(self):
56115603
getattr(s, 'availability_zone'),
56125604
server.HostColumn(getattr(s, 'hypervisor_hostname')),
56135605
format_columns.DictColumn(s.metadata),
5614-
format_columns.DictListColumn(None),
56155606
getattr(s, 'pinned_availability_zone', ''),
56165607
)
56175608
for s in self.servers
@@ -5660,9 +5651,159 @@ def test_server_list_column_option(self):
56605651
'-c',
56615652
'Properties',
56625653
'-c',
5663-
'Scheduler Hints',
5654+
'Pinned Availability Zone',
5655+
'--long',
5656+
]
5657+
verifylist = [
5658+
('long', True),
5659+
]
5660+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
5661+
5662+
columns, data = self.cmd.take_action(parsed_args)
5663+
5664+
self.compute_client.servers.assert_called_with(**self.kwargs)
5665+
self.assertIn('Project ID', columns)
5666+
self.assertIn('User ID', columns)
5667+
self.assertIn('Created At', columns)
5668+
self.assertIn('Security Groups', columns)
5669+
self.assertIn('Task State', columns)
5670+
self.assertIn('Power State', columns)
5671+
self.assertIn('Image ID', columns)
5672+
self.assertIn('Flavor ID', columns)
5673+
self.assertIn('Availability Zone', columns)
5674+
self.assertIn('Pinned Availability Zone', columns)
5675+
self.assertIn('Host', columns)
5676+
self.assertIn('Properties', columns)
5677+
self.assertCountEqual(columns, set(columns))
5678+
5679+
5680+
class TestServerListV2100(_TestServerList):
5681+
columns = (
5682+
'ID',
5683+
'Name',
5684+
'Status',
5685+
'Networks',
5686+
'Image',
5687+
'Flavor',
5688+
)
5689+
columns_long = (
5690+
'ID',
5691+
'Name',
5692+
'Status',
5693+
'Task State',
5694+
'Power State',
5695+
'Networks',
5696+
'Image Name',
5697+
'Image ID',
5698+
'Flavor',
5699+
'Availability Zone',
5700+
'Host',
5701+
'Properties',
5702+
'Pinned Availability Zone',
5703+
'Scheduler Hints',
5704+
)
5705+
5706+
def setUp(self):
5707+
super().setUp()
5708+
self.set_compute_api_version('2.100')
5709+
5710+
self.image_client.images.return_value = [
5711+
sdk_fakes.generate_fake_resource(
5712+
_image.Image, id=s.image['id'], name=self.image.name
5713+
)
5714+
# Image will be an empty string if boot-from-volume
5715+
for s in self.servers
5716+
if s.image
5717+
]
5718+
5719+
self.compute_client.flavors.return_value = [
5720+
sdk_fakes.generate_fake_resource(
5721+
_flavor.Flavor, id=s.flavor['id'], name=self.flavor.name
5722+
)
5723+
for s in self.servers
5724+
]
5725+
5726+
self.data = tuple(
5727+
(
5728+
s.id,
5729+
s.name,
5730+
s.status,
5731+
server.AddressesColumn(s.addresses),
5732+
# Image will be an empty string if boot-from-volume
5733+
self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
5734+
self.flavor.name,
5735+
)
5736+
for s in self.servers
5737+
)
5738+
5739+
def test_server_list_long_option(self):
5740+
self.data = tuple(
5741+
(
5742+
s.id,
5743+
s.name,
5744+
s.status,
5745+
getattr(s, 'task_state'),
5746+
server.PowerStateColumn(getattr(s, 'power_state')),
5747+
server.AddressesColumn(s.addresses),
5748+
# Image will be an empty string if boot-from-volume
5749+
self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
5750+
s.image['id'] if s.image else server.IMAGE_STRING_FOR_BFV,
5751+
self.flavor.name,
5752+
getattr(s, 'availability_zone'),
5753+
server.HostColumn(getattr(s, 'hypervisor_hostname')),
5754+
format_columns.DictColumn(s.metadata),
5755+
getattr(s, 'pinned_availability_zone', ''),
5756+
format_columns.DictListColumn(None),
5757+
)
5758+
for s in self.servers
5759+
)
5760+
arglist = [
5761+
'--long',
5762+
]
5763+
verifylist = [
5764+
('all_projects', False),
5765+
('long', True),
5766+
]
5767+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
5768+
5769+
columns, data = self.cmd.take_action(parsed_args)
5770+
self.compute_client.servers.assert_called_with(**self.kwargs)
5771+
image_ids = {s.image['id'] for s in self.servers if s.image}
5772+
self.image_client.images.assert_called_once_with(
5773+
id=f'in:{",".join(image_ids)}',
5774+
)
5775+
self.compute_client.flavors.assert_called_once_with(is_public=None)
5776+
self.assertEqual(self.columns_long, columns)
5777+
self.assertEqual(self.data, tuple(data))
5778+
5779+
def test_server_list_column_option(self):
5780+
arglist = [
5781+
'-c',
5782+
'Project ID',
5783+
'-c',
5784+
'User ID',
5785+
'-c',
5786+
'Created At',
5787+
'-c',
5788+
'Security Groups',
5789+
'-c',
5790+
'Task State',
5791+
'-c',
5792+
'Power State',
5793+
'-c',
5794+
'Image ID',
5795+
'-c',
5796+
'Flavor ID',
5797+
'-c',
5798+
'Availability Zone',
5799+
'-c',
5800+
'Host',
5801+
'-c',
5802+
'Properties',
56645803
'-c',
56655804
'Pinned Availability Zone',
5805+
'-c',
5806+
'Scheduler Hints',
56665807
'--long',
56675808
]
56685809
verifylist = [

0 commit comments

Comments
 (0)