forked from rpms/leapp-repository
335 lines
16 KiB
Diff
335 lines
16 KiB
Diff
From 5f569408469d4e43ff559c5b90c3cc068d59d3a4 Mon Sep 17 00:00:00 2001
|
|
From: Michal Hecko <mhecko@redhat.com>
|
|
Date: Fri, 2 May 2025 16:35:18 +0200
|
|
Subject: [PATCH 32/37] models(ipuconfig): extend Version class to contain
|
|
virtual versions
|
|
|
|
Add virtual_{source,target}_version fields to the Version model. These
|
|
fields store a virtual MAJOR.MINOR CentOS version so that
|
|
version-specific checks originally written for RHEL can work as expected
|
|
also on CentOS. On non-CentOS system, the value of these fields should
|
|
be the same as source/target versions. The ipuworkflowconfig actor is
|
|
modified accordingly to populate the newly added fields.
|
|
|
|
Jira-ref: RHEL-80334
|
|
---
|
|
.../checksaphana/tests/test_checksaphana.py | 4 ++
|
|
.../libraries/ipuworkflowconfig.py | 51 +++++++++++++++++--
|
|
.../tests/test_ipuworkflowconfig.py | 41 ++++++++++++++-
|
|
.../common/libraries/config/mock_configs.py | 16 ++++--
|
|
.../libraries/config/tests/test_version.py | 12 +++--
|
|
.../common/libraries/testutils.py | 13 ++++-
|
|
.../system_upgrade/common/models/ipuconfig.py | 15 ++++++
|
|
7 files changed, 137 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/repos/system_upgrade/common/actors/checksaphana/tests/test_checksaphana.py b/repos/system_upgrade/common/actors/checksaphana/tests/test_checksaphana.py
|
|
index 1417b00a..1e43f403 100644
|
|
--- a/repos/system_upgrade/common/actors/checksaphana/tests/test_checksaphana.py
|
|
+++ b/repos/system_upgrade/common/actors/checksaphana/tests/test_checksaphana.py
|
|
@@ -181,6 +181,8 @@ class MockSAPHanaVersionInstance(object):
|
|
)
|
|
)
|
|
def test_checksaphana__fullfills_rhel86_hana_min_version(monkeypatch, major, rev, patchlevel, result):
|
|
+ monkeypatch.setattr(checksaphana.api, 'current_actor', testutils.CurrentActorMocked())
|
|
+
|
|
monkeypatch.setattr(version, 'get_target_major_version', lambda: '8')
|
|
monkeypatch.setattr(version, 'get_target_version', lambda: '8.6')
|
|
monkeypatch.setattr(checksaphana, 'SAP_HANA_RHEL86_REQUIRED_PATCH_LEVELS', ((4, 48, 2), (5, 52, 0)))
|
|
@@ -213,6 +215,8 @@ def test_checksaphana__fullfills_rhel86_hana_min_version(monkeypatch, major, rev
|
|
)
|
|
)
|
|
def test_checksaphana__fullfills_hana_rhel90_min_version(monkeypatch, major, rev, patchlevel, result):
|
|
+ monkeypatch.setattr(checksaphana.api, 'current_actor', testutils.CurrentActorMocked())
|
|
+
|
|
monkeypatch.setattr(version, 'get_target_major_version', lambda: '9')
|
|
monkeypatch.setattr(version, 'get_target_version', lambda: '9.0')
|
|
monkeypatch.setattr(checksaphana, 'SAP_HANA_RHEL90_REQUIRED_PATCH_LEVELS', ((5, 59, 4), (6, 63, 0)))
|
|
diff --git a/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py b/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py
|
|
index 35f61669..f76677fd 100644
|
|
--- a/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py
|
|
+++ b/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py
|
|
@@ -10,6 +10,7 @@ ENV_IGNORE = ('LEAPP_CURRENT_PHASE', 'LEAPP_CURRENT_ACTOR', 'LEAPP_VERBOSE',
|
|
'LEAPP_DEBUG')
|
|
|
|
ENV_MAPPING = {'LEAPP_DEVEL_DM_DISABLE_UDEV': 'DM_DISABLE_UDEV'}
|
|
+CENTOS_VIRTUAL_VERSIONS_KEY = '_virtual_versions'
|
|
|
|
|
|
def get_env_vars():
|
|
@@ -92,8 +93,7 @@ def load_upgrade_paths_definitions(paths_definition_file):
|
|
return definitions
|
|
|
|
|
|
-def load_raw_upgrade_paths_for_distro_and_flavour(distro_id, flavour, paths_definition_file='upgrade_paths.json'):
|
|
- all_definitions = load_upgrade_paths_definitions(paths_definition_file)
|
|
+def extract_upgrade_paths_for_distro_and_flavour(all_definitions, distro_id, flavour):
|
|
raw_upgrade_paths_for_distro = all_definitions.get(distro_id, {})
|
|
|
|
if not raw_upgrade_paths_for_distro:
|
|
@@ -117,6 +117,39 @@ def construct_models_for_paths_matching_source_major(raw_paths, src_major_versio
|
|
return multipaths_matching_source
|
|
|
|
|
|
+def construct_virtual_versions(all_upgrade_path_defs, distro_id, source_version, target_version):
|
|
+ if distro_id.lower() != 'centos':
|
|
+ return (source_version, target_version)
|
|
+
|
|
+ centos_upgrade_paths = all_upgrade_path_defs.get('centos', {})
|
|
+ if not centos_upgrade_paths:
|
|
+ raise StopActorExecutionError('There are no upgrade paths defined for CentOS.')
|
|
+
|
|
+ virtual_versions = centos_upgrade_paths.get(CENTOS_VIRTUAL_VERSIONS_KEY, {})
|
|
+ if not virtual_versions: # Unlikely, only if using old upgrade_paths.json, but the user should not touch the file
|
|
+ details = {'details': 'The file does not contain any information about virtual versions of CentOS'}
|
|
+ raise StopActorExecutionError('The internal upgrade_paths.json file is malformed.')
|
|
+
|
|
+ source_virtual_version = virtual_versions.get(source_version)
|
|
+ target_virtual_version = virtual_versions.get(target_version)
|
|
+
|
|
+ if not source_virtual_version or not target_virtual_version:
|
|
+ if not source_virtual_version and not target_virtual_version:
|
|
+ what_is_missing = 'CentOS {} (source) and CentOS {} (target)'.format(source_virtual_version,
|
|
+ target_virtual_version)
|
|
+ elif not source_virtual_version:
|
|
+ what_is_missing = 'CentOS {} (source)'.format(source_virtual_version)
|
|
+ else:
|
|
+ what_is_missing = 'CentOS {} (target)'.format(target_virtual_version)
|
|
+
|
|
+ details_msg = 'The {} field in upgrade path definitions does not provide any information for {}'
|
|
+ details = {'details': details_msg.format(CENTOS_VIRTUAL_VERSIONS_KEY, what_is_missing)}
|
|
+ raise StopActorExecutionError('Failed to identify virtual minor version number for the system.',
|
|
+ details=details)
|
|
+
|
|
+ return (source_virtual_version, target_virtual_version)
|
|
+
|
|
+
|
|
def produce_ipu_config(actor):
|
|
flavour = os.environ.get('LEAPP_UPGRADE_PATH_FLAVOUR')
|
|
target_version = os.environ.get('LEAPP_UPGRADE_PATH_TARGET_RELEASE')
|
|
@@ -125,17 +158,27 @@ def produce_ipu_config(actor):
|
|
|
|
check_target_major_version(source_version, target_version)
|
|
|
|
- raw_upgrade_paths = load_raw_upgrade_paths_for_distro_and_flavour(os_release.release_id, flavour)
|
|
+ all_upgrade_path_defs = load_upgrade_paths_definitions('upgrade_paths.json')
|
|
+ raw_upgrade_paths = extract_upgrade_paths_for_distro_and_flavour(all_upgrade_path_defs,
|
|
+ os_release.release_id,
|
|
+ flavour)
|
|
source_major_version = source_version.split('.')[0]
|
|
exposed_supported_paths = construct_models_for_paths_matching_source_major(raw_upgrade_paths, source_major_version)
|
|
|
|
+ virtual_source_version, virtual_target_version = construct_virtual_versions(all_upgrade_path_defs,
|
|
+ os_release.release_id,
|
|
+ source_version,
|
|
+ target_version)
|
|
+
|
|
actor.produce(IPUConfig(
|
|
leapp_env_vars=get_env_vars(),
|
|
os_release=os_release,
|
|
architecture=platform.machine(),
|
|
version=Version(
|
|
source=source_version,
|
|
- target=target_version
|
|
+ target=target_version,
|
|
+ virtual_source_version=virtual_source_version,
|
|
+ virtual_target_version=virtual_target_version,
|
|
),
|
|
kernel=get_booted_kernel(),
|
|
flavour=flavour,
|
|
diff --git a/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py b/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py
|
|
index d88424ce..6184121b 100644
|
|
--- a/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py
|
|
+++ b/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py
|
|
@@ -149,7 +149,44 @@ def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flav
|
|
}
|
|
}
|
|
}
|
|
- monkeypatch.setattr(ipuworkflowconfig, 'load_upgrade_paths_definitions', lambda *args: defined_upgrade_paths)
|
|
|
|
- result = ipuworkflowconfig.load_raw_upgrade_paths_for_distro_and_flavour(distro, flavour)
|
|
+ result = ipuworkflowconfig.extract_upgrade_paths_for_distro_and_flavour(defined_upgrade_paths,
|
|
+ distro, flavour)
|
|
assert result == expected_result
|
|
+
|
|
+
|
|
+@pytest.mark.parametrize(
|
|
+ ('construction_params', 'expected_versions'),
|
|
+ [
|
|
+ (('centos', '8', '9'), ('8.10', '9.5')),
|
|
+ (('rhel', '8.10', '9.4'), ('8.10', '9.4')),
|
|
+ ]
|
|
+)
|
|
+def test_virtual_version_construction(construction_params, expected_versions):
|
|
+ defined_upgrade_paths = {
|
|
+ 'rhel': {
|
|
+ 'default': {
|
|
+ '8.10': ['9.4', '9.5', '9.6'],
|
|
+ '8.4': ['9.2'],
|
|
+ '9.6': ['10.0'],
|
|
+ '8': ['9.4', '9.5', '9.6'],
|
|
+ '9': ['10.0']
|
|
+ },
|
|
+ 'saphana': {
|
|
+ '8.10': ['9.6', '9.4'],
|
|
+ '8': ['9.6', '9.4'],
|
|
+ '9.6': ['10.0'],
|
|
+ '9': ['10.0']
|
|
+ }
|
|
+ },
|
|
+ 'centos': {
|
|
+ '8': ['9'],
|
|
+ '_virtual_versions': {
|
|
+ '8': '8.10',
|
|
+ '9': '9.5',
|
|
+ }
|
|
+ },
|
|
+ }
|
|
+
|
|
+ result = ipuworkflowconfig.construct_virtual_versions(defined_upgrade_paths, *construction_params)
|
|
+ assert result == expected_versions
|
|
diff --git a/repos/system_upgrade/common/libraries/config/mock_configs.py b/repos/system_upgrade/common/libraries/config/mock_configs.py
|
|
index a1c9c0fd..a7ee0000 100644
|
|
--- a/repos/system_upgrade/common/libraries/config/mock_configs.py
|
|
+++ b/repos/system_upgrade/common/libraries/config/mock_configs.py
|
|
@@ -19,7 +19,9 @@ CONFIG = IPUConfig(
|
|
),
|
|
version=Version(
|
|
source='7.6',
|
|
- target='8.0'
|
|
+ target='8.0',
|
|
+ virtual_source_version='7.6',
|
|
+ virtual_target_version='8.0'
|
|
),
|
|
architecture='x86_64',
|
|
kernel='3.10.0-957.43.1.el7.x86_64',
|
|
@@ -39,7 +41,9 @@ CONFIG_NO_NETWORK_RENAMING = IPUConfig(
|
|
),
|
|
version=Version(
|
|
source='7.6',
|
|
- target='8.0'
|
|
+ target='8.0',
|
|
+ virtual_source_version='7.6',
|
|
+ virtual_target_version='8.0'
|
|
),
|
|
architecture='x86_64',
|
|
kernel='3.10.0-957.43.1.el7.x86_64',
|
|
@@ -59,7 +63,9 @@ CONFIG_ALL_SIGNED = IPUConfig(
|
|
),
|
|
version=Version(
|
|
source='7.6',
|
|
- target='8.0'
|
|
+ target='8.0',
|
|
+ virtual_source_version='7.6',
|
|
+ virtual_target_version='8.0'
|
|
),
|
|
architecture='x86_64',
|
|
kernel='3.10.0-957.43.1.el7.x86_64',
|
|
@@ -78,7 +84,9 @@ CONFIG_S390X = IPUConfig(
|
|
),
|
|
version=Version(
|
|
source='7.6',
|
|
- target='8.0'
|
|
+ target='8.0',
|
|
+ virtual_source_version='7.6',
|
|
+ virtual_target_version='8.0'
|
|
),
|
|
architecture='s390x',
|
|
kernel='3.10.0-957.43.1.el7.x86_64',
|
|
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 3cb6479c..a8a1023e 100644
|
|
--- a/repos/system_upgrade/common/libraries/config/tests/test_version.py
|
|
+++ b/repos/system_upgrade/common/libraries/config/tests/test_version.py
|
|
@@ -27,7 +27,9 @@ def test_cmp_versions():
|
|
assert not version._cmp_versions(['>= 7.6', '& 7.7'])
|
|
|
|
|
|
-def test_matches_version_wrong_args():
|
|
+def test_matches_version_wrong_args(monkeypatch):
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked())
|
|
+
|
|
with pytest.raises(TypeError):
|
|
version.matches_version('>= 7.6', '7.7')
|
|
with pytest.raises(TypeError):
|
|
@@ -42,7 +44,9 @@ def test_matches_version_wrong_args():
|
|
version.matches_version(['>= 7.6', '& 7.7'], '7.7')
|
|
|
|
|
|
-def test_matches_version_fail():
|
|
+def test_matches_version_fail(monkeypatch):
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked())
|
|
+
|
|
assert not version.matches_version(['> 7.6', '< 7.7'], '7.6')
|
|
assert not version.matches_version(['> 7.6', '< 7.7'], '7.7')
|
|
assert not version.matches_version(['> 7.6', '< 7.10'], '7.6')
|
|
@@ -50,7 +54,9 @@ def test_matches_version_fail():
|
|
assert not version.matches_version(['7.6', '7.7', '7.10'], '7.8')
|
|
|
|
|
|
-def test_matches_version_pass():
|
|
+def test_matches_version_pass(monkeypatch):
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked())
|
|
+
|
|
assert version.matches_version(['7.6', '7.7', '7.10'], '7.7')
|
|
assert version.matches_version(['> 7.6', '< 7.10'], '7.7')
|
|
|
|
diff --git a/repos/system_upgrade/common/libraries/testutils.py b/repos/system_upgrade/common/libraries/testutils.py
|
|
index 1b3c3683..3e145d91 100644
|
|
--- a/repos/system_upgrade/common/libraries/testutils.py
|
|
+++ b/repos/system_upgrade/common/libraries/testutils.py
|
|
@@ -74,15 +74,24 @@ def _make_default_config(actor_config_schema):
|
|
return _normalize_config({}, merged_schema) # Will fill default values during normalization
|
|
|
|
|
|
+# Note: The constructor of the following class takes in too many arguments (R0913). A builder-like
|
|
+# pattern would be nice here. Ideally, the builder should actively prevent the developer from setting fields
|
|
+# that do not affect actor's behavior in __setattr__.
|
|
class CurrentActorMocked(object): # pylint:disable=R0904
|
|
- def __init__(self, arch=architecture.ARCH_X86_64, envars=None, kernel='3.10.0-957.43.1.el7.x86_64',
|
|
+ def __init__(self, arch=architecture.ARCH_X86_64, envars=None, # pylint:disable=R0913
|
|
+ kernel='3.10.0-957.43.1.el7.x86_64',
|
|
release_id='rhel', src_ver='7.8', dst_ver='8.1', msgs=None, flavour='default', config=None,
|
|
+ virtual_source_version=None, virtual_target_version=None,
|
|
supported_upgrade_paths=None):
|
|
"""
|
|
:param List[IPUSourceToPossibleTargets] supported_upgrade_paths: List of supported upgrade paths.
|
|
"""
|
|
envarsList = [EnvVar(name=k, value=v) for k, v in envars.items()] if envars else []
|
|
- version = namedtuple('Version', ['source', 'target'])(src_ver, dst_ver)
|
|
+
|
|
+ version_fields = ['source', 'target', 'virtual_source_version', 'virtual_target_version']
|
|
+ version_values = [src_ver, dst_ver, virtual_source_version or src_ver, virtual_target_version or dst_ver]
|
|
+ version = namedtuple('Version', version_fields)(*version_values)
|
|
+
|
|
release = namedtuple('OS_release', ['release_id', 'version_id'])(release_id, src_ver)
|
|
|
|
self._common_folder = '../../files'
|
|
diff --git a/repos/system_upgrade/common/models/ipuconfig.py b/repos/system_upgrade/common/models/ipuconfig.py
|
|
index 0a16b603..379ac13f 100644
|
|
--- a/repos/system_upgrade/common/models/ipuconfig.py
|
|
+++ b/repos/system_upgrade/common/models/ipuconfig.py
|
|
@@ -33,6 +33,21 @@ class Version(Model):
|
|
target = fields.String()
|
|
"""Version of the target system. E.g. '8.2.'."""
|
|
|
|
+ virtual_source_version = fields.String()
|
|
+ """
|
|
+ Source OS version used when checking whether to execute version-dependent code.
|
|
+
|
|
+ On RHEL and other systems that have version of the form MINOR.MAJOR, `virtual_source_version`
|
|
+ matches `source_version`.
|
|
+
|
|
+ CentOS has version of the form MAJOR, lacking the minor version number. The
|
|
+ `virtual_source_version` value is obtained by combining CentOS major
|
|
+ version number with a minor version number stored internally in the upgrade_paths.json file.
|
|
+ """
|
|
+
|
|
+ virtual_target_version = fields.String()
|
|
+ """ See :py:attr:`virtual_source_version` """
|
|
+
|
|
|
|
class IPUSourceToPossibleTargets(Model):
|
|
"""
|
|
--
|
|
2.49.0
|
|
|