From 9a48ac590bf9594ea7e9eefdaa668af5f7c75976 Mon Sep 17 00:00:00 2001 From: Michal Hecko Date: Fri, 2 May 2025 17:12:55 +0200 Subject: [PATCH 33/37] libs(common, version): autocorrect centos versions into MAJOR.MINOR When executing version.matches_version on CentOS, autocorrect versions of the form MAJOR into MAJOR.MINOR using virtual versions available in IPU configuration. Autocorrection is implemented only if a used version matches source/target version. For example, if match_list contains '8' on a CentOS 8 system, the version will be autocorrected to '8.10'. However, if a version that does not match the source/target version is present, it will be left untouched. Jira-ref: RHEL-80334 --- .../libraries/config/tests/test_version.py | 15 ++++++++ .../common/libraries/config/version.py | 34 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/repos/system_upgrade/common/libraries/config/tests/test_version.py b/repos/system_upgrade/common/libraries/config/tests/test_version.py index a8a1023e..420571c0 100644 --- a/repos/system_upgrade/common/libraries/config/tests/test_version.py +++ b/repos/system_upgrade/common/libraries/config/tests/test_version.py @@ -61,6 +61,21 @@ def test_matches_version_pass(monkeypatch): assert version.matches_version(['> 7.6', '< 7.10'], '7.7') +def test_matches_version_centos_autocorrect(monkeypatch): + actor_mock = CurrentActorMocked(release_id='centos', + src_ver='8', dst_ver='9', + virtual_source_version='8.10', virtual_target_version='9.5') + monkeypatch.setattr(api, 'current_actor', actor_mock) + + assert version.matches_version(['8'], '8.10') + assert version.matches_version(['9'], '9.5') + assert not version.matches_version(['8'], '9.5') + + assert version.matches_version(['> 8', '<= 9'], '9.5') + + assert version.matches_version(['> 8.10', '<= 9.7'], '9') + + @pytest.mark.parametrize('result,version_list', [ (True, ['7.6', '7.7']), (True, ['7.6']), diff --git a/repos/system_upgrade/common/libraries/config/version.py b/repos/system_upgrade/common/libraries/config/version.py index 2e837a61..4b6e616c 100644 --- a/repos/system_upgrade/common/libraries/config/version.py +++ b/repos/system_upgrade/common/libraries/config/version.py @@ -164,6 +164,15 @@ def _cmp_versions(versions): return all(s[0] in OP_MAP for s in split) +def _autocorrect_centos_version(version_to_correct): + version_cfg = api.current_actor().configuration.version + if version_to_correct == version_cfg.source: + version_to_correct = version_cfg.virtual_source_version + elif version_to_correct == version_cfg.target: + version_to_correct = version_cfg.virtual_target_version + return version_to_correct + + def matches_version(match_list, detected): """ Check if the `detected` version meets the criteria specified in `match_list`. @@ -189,6 +198,31 @@ def matches_version(match_list, detected): if not isinstance(detected, six.string_types): raise TypeError("Detected version has to be a string " "but provided was {}: '{}'".format(type(detected), detected)) + + # If we are on CentOS, and we are provided with a version of the form MAJOR, try to correct + # the version into MAJOR.MINOR using virtual versions + if api.current_actor().configuration.os_release.release_id == 'centos': + new_detected = _autocorrect_centos_version(detected) + # We might have a matchlist ['> 8', '<= 9'] that, e.g., results from blindly using source/target versions + # to make a matchlist. Our `detected` version might be some fixed string, e.g., `9.1`. So we need to + # also autocorrect the matchlist. Due to how autocorrection works, no changes are done to matchlist + # parts that contain full versions. + new_matchlist = [] + for predicate in match_list: + if ' ' in predicate: + op, version = predicate.split(' ', 1) + version = _autocorrect_centos_version(version) + new_matchlist.append('{} {}'.format(op, version)) + else: + version = _autocorrect_centos_version(predicate) + new_matchlist.append(version) + + msg = 'Performed autocorrection from matches_version(%s, %s) to matches_version(%s, %s)' + api.current_logger().debug(msg, match_list, detected, new_matchlist, new_detected) + + match_list = new_matchlist + detected = new_detected + _validate_versions([detected]) if not _are_comparison_operators_used(match_list): -- 2.49.0