From 98a82a5c99bef19f8d5a6a4b3712873c64229688 Mon Sep 17 00:00:00 2001 From: Shivam Shukla Date: Sun, 1 Feb 2026 18:23:33 +0000 Subject: [PATCH] Add python-glanceclient dependency, tox version constraint, and workaround for Nova scheduler_hints bug This patch adds python-glanceclient as a direct dependency. Previously it was installed indirectly via heat-translator, but starting from heat-translator 3.4.0 it was removed from its requirements. This caused Tacker CI failures with "ModuleNotFoundError: glanceclient". This patch also adds a version constraint for tox to avoid versions >= 4.48.0, which cause CI failures during the pre-devstack task with "AttributeError: 'Parsed' object has no attribute 'config_format'". Additionally, this patch adds a temporary workaround for a Nova bug in microversion 2.100 where scheduler_hints.group is returned as a list in GET server responses, but Nova expects it to be a string during rebuild. This mismatch causes Heat stack updates to fail. The workaround removes scheduler_hints from nested VDU templates during change_vnfpkg rolling update operations and disables VDU IDs validation. Workaround Impact: 1) Allows change_vnfpkg rolling updates to complete successfully. 2) Heat may replace servers instead of updating them in place. 3) VDU IDs may change after the change_vnfpkg operation. This workaround should be removed after the Nova bug is fixed. Related Nova bug: https://bugs.launchpad.net/nova/+bug/2139275 Closes-Bug: https://bugs.launchpad.net/tacker/+bug/2143398 Closes-Bug: https://bugs.launchpad.net/tacker/+bug/2143583 Closes-Bug: https://bugs.launchpad.net/tacker/+bug/2139268 Change-Id: I7e7122ededb9694c57fd37b0d8109efb9fefac08 Signed-off-by: Shivam Shukla --- requirements.txt | 1 + .../infra_drivers/openstack/openstack.py | 41 +++++++++++++++++++ .../st_userdata/basic_min/test_basic_min.py | 16 ++++++-- tox.ini | 1 + 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 7fe4001da..bc3697cf6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -37,6 +37,7 @@ oslo.versionedobjects>=1.33.3 # Apache-2.0 openstacksdk>=0.44.0 # Apache-2.0 python-barbicanclient>=4.5.2 # Apache-2.0 python-heatclient>=1.10.0 # Apache-2.0 +python-glanceclient>=4.8.0 # Apache-2.0 python-keystoneclient>=3.8.0 # Apache-2.0 python-neutronclient>=6.7.0 # Apache-2.0 python-novaclient>=9.1.0 # Apache-2.0 diff --git a/tacker/sol_refactored/infra_drivers/openstack/openstack.py b/tacker/sol_refactored/infra_drivers/openstack/openstack.py index 5f11fd8be..a0c89346b 100644 --- a/tacker/sol_refactored/infra_drivers/openstack/openstack.py +++ b/tacker/sol_refactored/infra_drivers/openstack/openstack.py @@ -554,6 +554,47 @@ class Openstack(object): base_files = heat_client.get_files(stack_name) base_files.update(fields['files']) + # TODO(shivam): Remove this workaround once Nova microversion + # 2.100 bug is fixed. This temporarily removes scheduler_hints + # from nested templates during rolling updates to avoid Nova's + # scheduler_hints.group type mismatch error (list vs string). + # The Nova bug causes scheduler_hints.group to be returned as a list + # in GET server responses but expected as a string in rebuild requests. + # Related Nova bug: https://bugs.launchpad.net/nova/+bug/2139275 + for file_name, file_content in base_files.items(): + if file_name.endswith(('.yaml', '.yml')): + try: + nested_template = yaml.safe_load(file_content) + modified = False + + if 'resources' in nested_template: + for res_name, res_value in ( + nested_template['resources'].items()): + if ( + res_value.get('type') == 'OS::Nova::Server' + and 'properties' in res_value + and 'scheduler_hints' + in res_value['properties'] + ): + del res_value['properties']['scheduler_hints'] + modified = True + LOG.info( + "Removed scheduler_hints from %s:%s " + "to workaround Nova microversion " + "2.100 bug", + file_name, + res_name + ) + + if modified: + base_files[file_name] = yaml.dump(nested_template) + except Exception as e: + LOG.warning( + "Could not process %s to remove scheduler_hints: %s", + file_name, + e + ) + base_parameters = heat_client.get_parameters(stack_name) # NOTE: Using json.loads because parameters['nfv'] is string base_nfv_dict = json.loads(base_parameters.get('nfv', '{}')) diff --git a/tacker/tests/functional/sol_v2/vnflcm/st_userdata/basic_min/test_basic_min.py b/tacker/tests/functional/sol_v2/vnflcm/st_userdata/basic_min/test_basic_min.py index 6eaf95047..fae8e113f 100644 --- a/tacker/tests/functional/sol_v2/vnflcm/st_userdata/basic_min/test_basic_min.py +++ b/tacker/tests/functional/sol_v2/vnflcm/st_userdata/basic_min/test_basic_min.py @@ -392,11 +392,19 @@ class IndividualVnfcMgmtBasicMinTest(base_v2.BaseSolV2Test): 'CHANGE_VNFPKG', expected_inst_attrs, inst_id) # check vnfdId self.assertEqual(self.upd_new_min_vnfd_id, inst_17['vnfdId']) + # TODO(shivam): Temporarily skip VNFC IDs check after change_vnfpkg + # due to Nova microversion 2.100 workaround. The workaround removes + # scheduler_hints from templates, which may cause Heat to replace + # servers instead of updating them in-place, resulting in new VDU IDs. + # Once the Nova bug is fixed and the workaround is removed, this + # assertion should be restored to check for VNFC ID equality. + # check ids of VDU are not changed - self.assertEqual(self._get_vnfc_id(inst_15, 'VDU1', 0), - self._get_vnfc_id(inst_17, 'VDU1', 0)) - self.assertEqual(self._get_vnfc_id(inst_15, 'VDU2', 0), - self._get_vnfc_id(inst_17, 'VDU2', 0)) + # self.assertEqual(self._get_vnfc_id(inst_15, 'VDU1', 0), + # self._get_vnfc_id(inst_17, 'VDU1', 0)) + # self.assertEqual(self._get_vnfc_id(inst_15, 'VDU2', 0), + # self._get_vnfc_id(inst_17, 'VDU2', 0)) + # check image of VDU1 is changed self.assertNotEqual(self._get_vnfc_image(inst_15, 'VDU1', 0), self._get_vnfc_image(inst_17, 'VDU1', 0)) diff --git a/tox.ini b/tox.ini index 389d99a38..6d034594e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,7 @@ [tox] envlist = py310,py39,py38,py36,pep8,docs minversion = 4.11.0 +requires = tox<4.48.0 ignore_basepython_conflict = True [testenv]