leapp-repository/SOURCES/0060-ipuconfig-Map-source-to-target-distro-paths-when-con.patch
2025-12-01 09:14:24 +00:00

346 lines
13 KiB
Diff

From 37f6e616843a9441a6a79fecbffa94c238d987aa Mon Sep 17 00:00:00 2001
From: Matej Matuska <mmatuska@redhat.com>
Date: Thu, 18 Sep 2025 19:12:41 +0200
Subject: [PATCH 60/69] ipuconfig: Map source to target distro paths when
converting
Jira: RHEL-110563
---
.../libraries/ipuworkflowconfig.py | 112 +++++++++++-----
.../tests/test_ipuworkflowconfig.py | 123 ++++++++++++------
2 files changed, 167 insertions(+), 68 deletions(-)
diff --git a/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py b/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py
index afc139a1..0c05640a 100644
--- a/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py
+++ b/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py
@@ -93,31 +93,7 @@ def load_upgrade_paths_definitions(paths_definition_file):
return definitions
-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:
- api.current_logger().warning('No upgrade paths defined for distro \'{}\''.format(distro_id))
-
- raw_upgrade_paths_for_flavour = raw_upgrade_paths_for_distro.get(flavour, {})
-
- if not raw_upgrade_paths_for_flavour:
- api.current_logger().warning('Cannot discover any upgrade paths for flavour: {}/{}'.format(distro_id, flavour))
-
- return raw_upgrade_paths_for_flavour
-
-
-def construct_models_for_paths_matching_source_major(raw_paths, src_major_version):
- multipaths_matching_source = []
- for src_version, target_versions in raw_paths.items():
- if src_version.split('.')[0] == src_major_version:
- source_to_targets = IPUSourceToPossibleTargets(source_version=src_version,
- target_versions=target_versions)
- multipaths_matching_source.append(source_to_targets)
- return multipaths_matching_source
-
-
-def construct_virtual_version(all_upgrade_path_defs, distro, version):
+def get_virtual_version(all_upgrade_path_defs, distro, version):
if distro.lower() != 'centos':
return version
@@ -147,11 +123,78 @@ def construct_virtual_version(all_upgrade_path_defs, distro, version):
return virtual_version
+def extract_upgrade_paths_for_distro_and_flavour(all_definitions, distro, flavour):
+ distro_paths = all_definitions.get(distro, {})
+ if not distro_paths:
+ api.current_logger().warning(
+ "No upgrade paths defined for distro '{}'".format(distro)
+ )
+
+ distro_paths = distro_paths.get(flavour, {})
+ if not distro_paths:
+ api.current_logger().warning(
+ "Cannot discover any upgrade paths for flavour: {}/{}".format(
+ distro, flavour
+ )
+ )
+ return distro_paths
+
+
+def make_cross_distro_paths(all_paths, source_distro, target_distro, flavour):
+ """
+ Make paths for upgrade + conversion.
+
+ :param all_paths: The raw upgrade paths retrieved from upgrade_paths.json
+ :type all_paths: dict
+ :param source_distro: The source distro.
+ :type source_distro: str
+ :param target_distro: The target distro.
+ :type target_distro: str
+ :param flavour: The flavour to find paths for.
+ :type target_distro: str
+ :return: A dictionary with conversion paths for upgrade + conversion between
+ source and target distro.
+ :rtype: dict
+ """
+ # using source and target for both distro and version gets confusing, using
+ # a and b for distro instead
+ paths_a = extract_upgrade_paths_for_distro_and_flavour(
+ all_paths, source_distro, flavour
+ )
+ paths_b = extract_upgrade_paths_for_distro_and_flavour(
+ all_paths, target_distro, flavour
+ )
+
+ conversion_paths = {}
+ for source_ver_a, _ in paths_a.items():
+ virt_source_ver_a = get_virtual_version(all_paths, source_distro, source_ver_a)
+
+ for source_ver_b, target_ver_b in paths_b.items():
+ virt_source_ver_b = get_virtual_version(all_paths, target_distro, source_ver_b)
+ if virt_source_ver_a == virt_source_ver_b:
+ conversion_paths[source_ver_a] = target_ver_b
+
+ return conversion_paths
+
+
+def construct_models_for_paths_matching_source_major(
+ raw_paths, src_major_version
+):
+ multipaths_matching_source = []
+ for src_version, target_versions in raw_paths.items():
+ if src_version.split('.')[0] == src_major_version:
+ source_to_targets = IPUSourceToPossibleTargets(source_version=src_version,
+ target_versions=target_versions)
+ multipaths_matching_source.append(source_to_targets)
+ return multipaths_matching_source
+
+
def produce_ipu_config(actor):
flavour = os.environ.get('LEAPP_UPGRADE_PATH_FLAVOUR')
target_version = os.environ.get('LEAPP_UPGRADE_PATH_TARGET_RELEASE')
os_release = get_os_release('/etc/os-release')
source_version = os_release.version_id
+ target_distro = os.environ.get('LEAPP_TARGET_OS')
check_target_major_version(source_version, target_version)
@@ -159,13 +202,22 @@ def produce_ipu_config(actor):
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)
+ if os_release.release_id == target_distro:
+ raw_upgrade_paths = extract_upgrade_paths_for_distro_and_flavour(
+ all_upgrade_path_defs, os_release.release_id, flavour
+ )
+ else:
+ raw_upgrade_paths = make_cross_distro_paths(
+ all_upgrade_path_defs, os_release.release_id, target_distro, flavour
+ )
- target_distro = os.environ.get('LEAPP_TARGET_OS')
+ virtual_source_version = get_virtual_version(all_upgrade_path_defs, os_release.release_id, source_version)
+ virtual_target_version = get_virtual_version(all_upgrade_path_defs, target_distro, target_version)
- virtual_source_version = construct_virtual_version(all_upgrade_path_defs, os_release.release_id, source_version)
- virtual_target_version = construct_virtual_version(all_upgrade_path_defs, target_distro, target_version)
+ source_major_version = source_version.split('.')[0]
+ exposed_supported_paths = construct_models_for_paths_matching_source_major(
+ raw_upgrade_paths, source_major_version
+ )
actor.produce(IPUConfig(
leapp_env_vars=get_env_vars(),
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 96b63666..c0deaf0e 100644
--- a/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py
+++ b/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py
@@ -1,6 +1,4 @@
-import json
import os
-import tempfile
import pytest
@@ -42,6 +40,43 @@ def _get_os_release(version='7.9', codename='Maipo'):
return release
+TEST_UPGRADE_PATHS = {
+ 'rhel': {
+ 'default': {
+ '8.10': ['9.4', '9.6', '9.7'],
+ '8.4': ['9.2'],
+ '9.6': ['10.0'],
+ '9.7': ['10.1'],
+ '8': ['9.4', '9.6'],
+ '9': ['10.1'],
+ },
+ 'saphana': {
+ '8.10': ['9.6', '9.4'],
+ '8': ['9.6', '9.4'],
+ '9.6': ['10.0'],
+ '9': ['10.0'],
+ },
+ },
+ 'centos': {
+ 'default': {
+ '8': ['9'],
+ '9': ['10'],
+ },
+ '_virtual_versions': {
+ '8': '8.10',
+ '9': '9.7',
+ '10': '10.1',
+ },
+ },
+ 'almalinux': {
+ 'default': {
+ '8.10': ['9.0', '9.1', '9.2', '9.3', '9.4', '9.5', '9.6', '9.7'],
+ '9.7': ['10.0', '10.1'],
+ },
+ },
+}
+
+
def test_leapp_env_vars(monkeypatch):
_clean_leapp_envs(monkeypatch)
monkeypatch.setenv('LEAPP_WHATEVER', '0')
@@ -82,6 +117,7 @@ def test_get_booted_kernel(monkeypatch):
IPUSourceToPossibleTargets(source_version='8.10', target_versions=['9.4', '9.5', '9.6']),
IPUSourceToPossibleTargets(source_version='8.4', target_versions=['9.2']),
IPUSourceToPossibleTargets(source_version='8', target_versions=['9.4', '9.5', '9.6']),
+ IPUSourceToPossibleTargets(source_version='8.6', target_versions=['9']),
]
),
(
@@ -90,6 +126,13 @@ def test_get_booted_kernel(monkeypatch):
IPUSourceToPossibleTargets(source_version='80.0', target_versions=['81.0']),
]
),
+ (
+ '9',
+ [
+ IPUSourceToPossibleTargets(source_version='9', target_versions=['10']),
+ IPUSourceToPossibleTargets(source_version='9.6', target_versions=['10.0']),
+ ]
+ ),
)
)
def test_construct_models_for_paths_matching_source_major(source_major_version, expected_result):
@@ -98,7 +141,9 @@ def test_construct_models_for_paths_matching_source_major(source_major_version,
'8.4': ['9.2'],
'9.6': ['10.0'],
'8': ['9.4', '9.5', '9.6'],
- '80.0': ['81.0']
+ '80.0': ['81.0'],
+ '8.6': ['9'],
+ '9': ['10'],
}
result = ipuworkflowconfig.construct_models_for_paths_matching_source_major(RAW_PATHS, source_major_version)
@@ -106,6 +151,38 @@ def test_construct_models_for_paths_matching_source_major(source_major_version,
assert result == sorted(expected_result, key=lambda x: x.source_version)
+@pytest.mark.parametrize(
+ "src_distro,dst_distro,expected",
+ [
+ ("centos", "rhel", {"8": ["9.4", "9.6", "9.7"], "9": ["10.1"]}),
+ ("almalinux", "rhel", {"8.10": ["9.4", "9.6", "9.7"], "9.7": ["10.1"]}),
+ ("rhel", "centos", {"8.10": ["9"], "9.7": ["10"]}),
+ ("almalinux", "centos", {"8.10": ["9"], "9.7": ["10"]}),
+ (
+ "rhel",
+ "almalinux",
+ {
+ "8.10": ["9.0", "9.1", "9.2", "9.3", "9.4", "9.5", "9.6", "9.7"],
+ "9.7": ["10.0", "10.1"],
+ },
+ ),
+ (
+ "centos",
+ "almalinux",
+ {
+ "8": ["9.0", "9.1", "9.2", "9.3", "9.4", "9.5", "9.6", "9.7"],
+ "9": ["10.0", "10.1"],
+ },
+ ),
+ ],
+)
+def test_make_cross_distro_paths(src_distro, dst_distro, expected):
+ res = ipuworkflowconfig.make_cross_distro_paths(
+ TEST_UPGRADE_PATHS, src_distro, dst_distro, 'default'
+ )
+ assert res == expected
+
+
@pytest.mark.parametrize(
('distro', 'flavour', 'expected_result'),
(
@@ -163,8 +240,9 @@ def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flav
}
}
- result = ipuworkflowconfig.extract_upgrade_paths_for_distro_and_flavour(defined_upgrade_paths,
- distro, flavour)
+ result = ipuworkflowconfig.extract_upgrade_paths_for_distro_and_flavour(
+ defined_upgrade_paths, distro, flavour
+ )
assert result == expected_result
@@ -172,7 +250,7 @@ def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flav
('construction_params', 'expected_versions'),
[
(('centos', '8'), '8.10'),
- (('centos', '9'), '9.5'),
+ (('centos', '9'), '9.7'),
(('rhel', '8.10'), '8.10'),
(('rhel', '9.4'), '9.4'),
(('almalinux', '8.10'), '8.10'),
@@ -180,36 +258,5 @@ def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flav
]
)
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',
- }
- },
- 'almalinux': {
- 'default': {
- '8.10': ['9.0', '9.1', '9.2', '9.3', '9.4', '9.5', '9.6'],
- '9.6': ['10.0']
- }
- },
- }
-
- result = ipuworkflowconfig.construct_virtual_version(defined_upgrade_paths, *construction_params)
+ result = ipuworkflowconfig.get_virtual_version(TEST_UPGRADE_PATHS, *construction_params)
assert result == expected_versions
--
2.51.1