leapp-repository/SOURCES/0016-feat-upgrade_paths-include-information-about-distro-.patch
eabdullin b1bd6e77a6 Import from CS git
(cherry picked from commit 5bdc5cf293)
2025-05-15 11:55:21 +03:00

382 lines
15 KiB
Diff

From 6bfb0ae05f8ac05f34b5974a85ae5a703ada72b0 Mon Sep 17 00:00:00 2001
From: Michal Hecko <mhecko@redhat.com>
Date: Sat, 29 Mar 2025 21:56:07 +0100
Subject: [PATCH 16/37] feat(upgrade_paths): include information about distro
id
This patch tweaks upgrade_paths.json and the code reading it to contain
information about what for what distro are the upgrade paths defined.
This allows the upgrade tooling to possibly support also other distros,
such as CentOS Stream. However, this patch is only a small step towards
such a goal and further work is needed to support these systems.
Jira-ref: RHEL-80550
---
commands/command_utils.py | 28 ++++--
commands/tests/test_upgrade_paths.py | 15 ++--
.../libraries/ipuworkflowconfig.py | 35 +++++---
.../tests/test_ipuworkflowconfig.py | 85 ++++++++++++++++++-
.../tests/files/upgrade_paths.json | 29 ++++---
.../common/files/upgrade_paths.json | 36 +++++---
6 files changed, 177 insertions(+), 51 deletions(-)
diff --git a/commands/command_utils.py b/commands/command_utils.py
index 84b9de1b..a13ca59b 100644
--- a/commands/command_utils.py
+++ b/commands/command_utils.py
@@ -71,15 +71,24 @@ def get_upgrade_flavour():
return LEAPP_UPGRADE_FLAVOUR_DEFAULT
+def _retrieve_os_release_contents(_os_release_path='/etc/os-release'):
+ """
+ Retrieve the contents of /etc/os-release
+
+ :rtype: dict[str, str]
+ """
+ with open(_os_release_path) as os_release_handle:
+ lines = os_release_handle.readlines()
+ return dict(line.strip().split('=', 1) for line in lines if '=' in line)
+
+
def get_os_release_version_id(filepath):
"""
Retrieve data about System OS release from provided file.
:return: `str` version_id
"""
- with open(filepath) as f:
- data = dict(l.strip().split('=', 1) for l in f.readlines() if '=' in l)
- return data.get('VERSION_ID', '').strip('"')
+ return _retrieve_os_release_contents(_os_release_path=filepath).get('VERSION_ID', '').strip('"')
def get_upgrade_paths_config():
@@ -92,13 +101,13 @@ def get_upgrade_paths_config():
return upgrade_paths_map
-def get_target_versions_from_config(src_version_id, flavor):
+def get_target_versions_from_config(src_version_id, distro, flavor):
"""
Retrieve all possible target versions from upgrade_paths_map.
If no match is found returns empty list.
"""
upgrade_paths_map = get_upgrade_paths_config()
- return upgrade_paths_map.get(flavor, {}).get(src_version_id, [])
+ return upgrade_paths_map.get(distro, {}).get(flavor, {}).get(src_version_id, [])
def get_supported_target_versions(flavour=get_upgrade_flavour()):
@@ -107,14 +116,17 @@ def get_supported_target_versions(flavour=get_upgrade_flavour()):
The default value for `flavour` is `default`.
"""
- current_version_id = get_os_release_version_id('/etc/os-release')
- target_versions = get_target_versions_from_config(current_version_id, flavour)
+ os_release_contents = _retrieve_os_release_contents()
+ current_version_id = os_release_contents.get('VERSION_ID', '').strip('"')
+ distro_id = os_release_contents.get('ID', '').strip('"')
+
+ target_versions = get_target_versions_from_config(current_version_id, distro_id, flavour)
if not target_versions:
# If we cannot find a particular major.minor version in the map,
# we fallback to pick a target version just based on a major version.
# This can happen for example when testing not yet released versions
major_version = get_major_version(current_version_id)
- target_versions = get_target_versions_from_config(major_version, flavour)
+ target_versions = get_target_versions_from_config(major_version, distro_id, flavour)
return target_versions
diff --git a/commands/tests/test_upgrade_paths.py b/commands/tests/test_upgrade_paths.py
index f1312f66..c2cb09aa 100644
--- a/commands/tests/test_upgrade_paths.py
+++ b/commands/tests/test_upgrade_paths.py
@@ -8,19 +8,24 @@ from leapp.exceptions import CommandError
@mock.patch("leapp.cli.commands.command_utils.get_upgrade_paths_config",
- return_value={"default": {"7.9": ["8.4"], "8.6": ["9.0"], "7": ["8.4"], "8": ["9.0"]}})
+ return_value={'rhel': {"default": {"7.9": ["8.4"], "8.6": ["9.0"], "7": ["8.4"], "8": ["9.0"]}}})
def test_get_target_version(mock_open, monkeypatch):
-
- monkeypatch.setattr(command_utils, 'get_os_release_version_id', lambda x: '8.6')
+ etc_os_release_contents = {'ID': 'rhel', 'VERSION_ID': '8.6'}
+ monkeypatch.setattr(command_utils, '_retrieve_os_release_contents',
+ lambda *args, **kwargs: etc_os_release_contents)
assert command_utils.get_target_version('default') == '9.0'
monkeypatch.setenv('LEAPP_DEVEL_TARGET_RELEASE', '')
- monkeypatch.setattr(command_utils, 'get_os_release_version_id', lambda x: '8.6')
+ etc_os_release_contents = {'ID': 'rhel', 'VERSION_ID': '8.6'}
+ monkeypatch.setattr(command_utils, '_retrieve_os_release_contents',
+ lambda *args, **kwargs: etc_os_release_contents)
assert command_utils.get_target_version('default') == '9.0'
monkeypatch.delenv('LEAPP_DEVEL_TARGET_RELEASE', raising=True)
# unsupported path
- monkeypatch.setattr(command_utils, 'get_os_release_version_id', lambda x: '8.5')
+ etc_os_release_contents = {'ID': 'rhel', 'VERSION_ID': '8.5'}
+ monkeypatch.setattr(command_utils, '_retrieve_os_release_contents',
+ lambda *args, **kwargs: etc_os_release_contents)
assert command_utils.get_target_version('default') == '9.0'
diff --git a/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py b/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py
index 86df709e..35f61669 100644
--- a/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py
+++ b/repos/system_upgrade/common/actors/ipuworkflowconfig/libraries/ipuworkflowconfig.py
@@ -1,9 +1,10 @@
+import json
import os
import platform
from leapp.exceptions import StopActorExecutionError
-from leapp.libraries.stdlib import CalledProcessError, run
-from leapp.models import EnvVar, IPUConfig, OSRelease, Version
+from leapp.libraries.stdlib import api, CalledProcessError, run
+from leapp.models import EnvVar, IPUConfig, IPUSourceToPossibleTargets, OSRelease, Version
ENV_IGNORE = ('LEAPP_CURRENT_PHASE', 'LEAPP_CURRENT_ACTOR', 'LEAPP_VERBOSE',
'LEAPP_DEBUG')
@@ -85,24 +86,34 @@ def check_target_major_version(curr_version, target_version):
)
-def load_raw_upgrade_paths_for_flavour(flavour='default', paths_definition_file='upgrade_paths.json'):
+def load_upgrade_paths_definitions(paths_definition_file):
with open(api.get_common_file_path(paths_definition_file)) as fp:
- data = json.loads(fp.read())
+ definitions = json.loads(fp.read())
+ return definitions
- raw_upgrade_paths = data.get(flavour, {})
- if not raw_upgrade_paths:
- api.current_logger().warning('Cannot discover any upgrade paths for flavour: {}'.format(flavour))
+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)
+ raw_upgrade_paths_for_distro = all_definitions.get(distro_id, {})
- return raw_upgrade_paths
+ 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 ipu_paths.items():
+ 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 = IPUSourceToPossibleTargets(source_version=src_version,
+ target_versions=target_versions)
+ multipaths_matching_source.append(source_to_targets)
return multipaths_matching_source
@@ -114,7 +125,7 @@ def produce_ipu_config(actor):
check_target_major_version(source_version, target_version)
- raw_upgrade_paths = load_raw_upgrade_paths_for_flavour(flavour)
+ raw_upgrade_paths = load_raw_upgrade_paths_for_distro_and_flavour(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)
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 a5e4d03b..d88424ce 100644
--- a/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py
+++ b/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py
@@ -7,7 +7,7 @@ import pytest
from leapp.exceptions import StopActorExecutionError
from leapp.libraries.actor import ipuworkflowconfig
from leapp.libraries.stdlib import CalledProcessError
-from leapp.models import OSRelease
+from leapp.models import IPUSourceToPossibleTargets, OSRelease
CUR_DIR = os.path.dirname(os.path.abspath(__file__))
@@ -70,3 +70,86 @@ def test_get_booted_kernel(monkeypatch):
monkeypatch.setattr(ipuworkflowconfig, 'run', _raise_call_error)
with pytest.raises(StopActorExecutionError):
ipuworkflowconfig.get_booted_kernel()
+
+
+@pytest.mark.parametrize(
+ ('source_major_version', 'expected_result'),
+ (
+ ('7', []),
+ (
+ '8',
+ [
+ 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']),
+ ]
+ ),
+ (
+ '80',
+ [
+ IPUSourceToPossibleTargets(source_version='80.0', target_versions=['81.0']),
+ ]
+ ),
+ )
+)
+def test_construct_models_for_paths_matching_source_major(source_major_version, expected_result):
+ RAW_PATHS = {
+ '8.10': ['9.4', '9.5', '9.6'],
+ '8.4': ['9.2'],
+ '9.6': ['10.0'],
+ '8': ['9.4', '9.5', '9.6'],
+ '80.0': ['81.0']
+ }
+
+ result = ipuworkflowconfig.construct_models_for_paths_matching_source_major(RAW_PATHS, source_major_version)
+ result = sorted(result, key=lambda x: x.source_version)
+ assert result == sorted(expected_result, key=lambda x: x.source_version)
+
+
+@pytest.mark.parametrize(
+ ('distro', 'flavour', 'expected_result'),
+ (
+ ('fedora', 'default', {}),
+ (
+ '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']
+ }
+ ),
+ (
+ 'rhel', 'saphana',
+ {
+ '8.10': ['9.6', '9.4'],
+ '8': ['9.6', '9.4'],
+ '9.6': ['10.0'],
+ '9': ['10.0']
+ }
+ ),
+ )
+)
+def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flavour, expected_result):
+ 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']
+ }
+ }
+ }
+ monkeypatch.setattr(ipuworkflowconfig, 'load_upgrade_paths_definitions', lambda *args: defined_upgrade_paths)
+
+ result = ipuworkflowconfig.load_raw_upgrade_paths_for_distro_and_flavour(distro, flavour)
+ assert result == expected_result
diff --git a/repos/system_upgrade/common/actors/scandefinedipupaths/tests/files/upgrade_paths.json b/repos/system_upgrade/common/actors/scandefinedipupaths/tests/files/upgrade_paths.json
index edd32224..b6107376 100644
--- a/repos/system_upgrade/common/actors/scandefinedipupaths/tests/files/upgrade_paths.json
+++ b/repos/system_upgrade/common/actors/scandefinedipupaths/tests/files/upgrade_paths.json
@@ -1,15 +1,22 @@
{
- "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"]
+ "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"]
+ }
},
- "saphana": {
- "8.10": ["9.6", "9.4"],
- "8": ["9.6", "9.4"],
- "9.6": ["10.0"],
- "9": ["10.0"]
+ "centos": {
+ "default": {
+ "8": ["9"]
+ }
}
}
diff --git a/repos/system_upgrade/common/files/upgrade_paths.json b/repos/system_upgrade/common/files/upgrade_paths.json
index 1c54dae8..7ace7943 100644
--- a/repos/system_upgrade/common/files/upgrade_paths.json
+++ b/repos/system_upgrade/common/files/upgrade_paths.json
@@ -1,18 +1,26 @@
{
- "default": {
- "7.9": ["8.10"],
- "8.10": ["9.4", "9.6"],
- "9.6": ["10.0"],
- "7": ["8.10"],
- "8": ["9.4", "9.6"],
- "9": ["10.0"]
+ "rhel": {
+ "default": {
+ "7.9": ["8.10"],
+ "8.10": ["9.4", "9.6"],
+ "9.6": ["10.0"],
+ "7": ["8.10"],
+ "8": ["9.4", "9.6"],
+ "9": ["10.0"]
+ },
+ "saphana": {
+ "7.9": ["8.10"],
+ "7": ["8.10"],
+ "8.10": ["9.6", "9.4"],
+ "8": ["9.6", "9.4"],
+ "9.6": ["10.0"],
+ "9": ["10.0"]
+ }
},
- "saphana": {
- "7.9": ["8.10"],
- "7": ["8.10"],
- "8.10": ["9.6", "9.4"],
- "8": ["9.6", "9.4"],
- "9.6": ["10.0"],
- "9": ["10.0"]
+ "centos": {
+ "default": {
+ "8": ["9"],
+ "9": ["10"]
+ }
}
}
--
2.49.0