- Detect XFS file systems with problematic parameters - Raise an inhibitor if unsupported target version supplied instead of error - Prevent a possible crash with LiveMode when adding the upgrade boot entry on systems with LVM - Resolves: RHEL-57043, RHEL-52309, RHEL-60034
304 lines
11 KiB
Diff
304 lines
11 KiB
Diff
From a6438828415c094c600de80e2e05409a4ccd5822 Mon Sep 17 00:00:00 2001
|
|
From: Petr Stodulka <pstodulk@redhat.com>
|
|
Date: Wed, 29 Jan 2025 04:43:33 +0100
|
|
Subject: [PATCH 61/63] Introduce deprecated IPUPaths msg (temporary solution)
|
|
|
|
This is hackish precursor to move checking of the specified
|
|
target system versions into actors to be able to create report
|
|
when unsupported target version is specified.
|
|
|
|
The problem is that currently there is no information about the
|
|
supported upgrade paths in messages. Also, the information about
|
|
supported source and target versions are stored in two different
|
|
places (in system upgrade common repo):
|
|
* shared configs.version library
|
|
* files/upgrade_paths.json
|
|
|
|
As a temporary solution let's introduce IPUPaths message which
|
|
will contain filtered data from the json file based on:
|
|
* the upgrade flavour (default, saphana)
|
|
* and source major version
|
|
|
|
There is no value to print information to users about different
|
|
upgrade paths for other flavours and OS major versions. The model
|
|
is marked as deprecated so we can remove it in the next release when
|
|
we redesign this solution to unify how actors get this data
|
|
(and define them just in one place).
|
|
|
|
jira: RHEL-51072
|
|
---
|
|
.../actors/scandefinedipupaths/actor.py | 31 ++++++
|
|
.../libraries/scandefinedipupaths.py | 43 ++++++++
|
|
.../tests/files/upgrade_paths.json | 15 +++
|
|
.../tests/test_scandefinedipupaths.py | 97 +++++++++++++++++++
|
|
.../system_upgrade/common/models/ipupaths.py | 43 ++++++++
|
|
5 files changed, 229 insertions(+)
|
|
create mode 100644 repos/system_upgrade/common/actors/scandefinedipupaths/actor.py
|
|
create mode 100644 repos/system_upgrade/common/actors/scandefinedipupaths/libraries/scandefinedipupaths.py
|
|
create mode 100644 repos/system_upgrade/common/actors/scandefinedipupaths/tests/files/upgrade_paths.json
|
|
create mode 100644 repos/system_upgrade/common/actors/scandefinedipupaths/tests/test_scandefinedipupaths.py
|
|
create mode 100644 repos/system_upgrade/common/models/ipupaths.py
|
|
|
|
diff --git a/repos/system_upgrade/common/actors/scandefinedipupaths/actor.py b/repos/system_upgrade/common/actors/scandefinedipupaths/actor.py
|
|
new file mode 100644
|
|
index 00000000..a84c85f2
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/common/actors/scandefinedipupaths/actor.py
|
|
@@ -0,0 +1,31 @@
|
|
+from leapp.actors import Actor
|
|
+from leapp.libraries.actor import scandefinedipupaths
|
|
+from leapp.models import IPUPaths
|
|
+from leapp.tags import FactsPhaseTag, IPUWorkflowTag
|
|
+
|
|
+
|
|
+class ScanDefinedIPUPaths(Actor):
|
|
+ """
|
|
+ Load defined IPU paths for the current major source system version
|
|
+ and defined upgrade flavour.
|
|
+
|
|
+ The upgrade paths are defined inside `files/upgrade_paths.json`.
|
|
+ Based on the defined upgrade flavour (default, saphana, ..) loads particular
|
|
+ definitions and filter out all upgrade paths from other system major versions.
|
|
+ I.e. for RHEL 8.10 system with the default upgrade flavour, load all upgrade
|
|
+ paths from any RHEL 8 system defined under the 'default' flavour.
|
|
+
|
|
+ The code is mostly taken from the CLI command_utils. The duplicate solution
|
|
+ is not so problematic now as it will be unified next time.
|
|
+
|
|
+ Note the deprecation suppression is expected here as this is considered as
|
|
+ temporary solution now.
|
|
+ """
|
|
+
|
|
+ name = 'scan_defined_ipu_paths'
|
|
+ consumes = ()
|
|
+ produces = (IPUPaths,)
|
|
+ tags = (IPUWorkflowTag, FactsPhaseTag)
|
|
+
|
|
+ def process(self):
|
|
+ scandefinedipupaths.process()
|
|
diff --git a/repos/system_upgrade/common/actors/scandefinedipupaths/libraries/scandefinedipupaths.py b/repos/system_upgrade/common/actors/scandefinedipupaths/libraries/scandefinedipupaths.py
|
|
new file mode 100644
|
|
index 00000000..1e39f2c8
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/common/actors/scandefinedipupaths/libraries/scandefinedipupaths.py
|
|
@@ -0,0 +1,43 @@
|
|
+import json
|
|
+
|
|
+from leapp.libraries.common.config.version import get_source_major_version
|
|
+from leapp.libraries.stdlib import api
|
|
+from leapp.models import IPUPath, IPUPaths
|
|
+from leapp.utils.deprecation import suppress_deprecation
|
|
+
|
|
+
|
|
+def load_ipu_paths_for_flavour(flavour, _filename='upgrade_paths.json'):
|
|
+ """
|
|
+ Load defined IPU paths from the upgrade_paths.json file for the specified
|
|
+ flavour.
|
|
+
|
|
+ Note the file is required to be always present, so skipping any test
|
|
+ for the missing file. Crash hard and terribly if the file is missing
|
|
+ or the content is invalid.
|
|
+
|
|
+ We expect the flavour to be always good as it is under our control
|
|
+ (already sanitized in IPUConfig), but return empty dict and log it if missing.
|
|
+ """
|
|
+ with open(api.get_common_file_path(_filename)) as fp:
|
|
+ data = json.loads(fp.read())
|
|
+ if flavour not in data:
|
|
+ api.current_logger().warning(
|
|
+ 'Cannot discover any upgrade paths for flavour: {}'
|
|
+ .format(flavour)
|
|
+ )
|
|
+ return data.get(flavour, {})
|
|
+
|
|
+
|
|
+def get_filtered_ipu_paths(ipu_paths, src_major_version):
|
|
+ result = []
|
|
+ for src_version, tgt_versions in ipu_paths.items():
|
|
+ if src_version.split('.')[0] == src_major_version:
|
|
+ result.append(IPUPath(source_version=src_version, target_versions=tgt_versions))
|
|
+ return result
|
|
+
|
|
+
|
|
+@suppress_deprecation(IPUPaths)
|
|
+def process():
|
|
+ flavour = api.current_actor().configuration.flavour
|
|
+ ipu_paths = load_ipu_paths_for_flavour(flavour)
|
|
+ api.produce(IPUPaths(data=get_filtered_ipu_paths(ipu_paths, get_source_major_version())))
|
|
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
|
|
new file mode 100644
|
|
index 00000000..edd32224
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/common/actors/scandefinedipupaths/tests/files/upgrade_paths.json
|
|
@@ -0,0 +1,15 @@
|
|
+{
|
|
+ "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"]
|
|
+ }
|
|
+}
|
|
diff --git a/repos/system_upgrade/common/actors/scandefinedipupaths/tests/test_scandefinedipupaths.py b/repos/system_upgrade/common/actors/scandefinedipupaths/tests/test_scandefinedipupaths.py
|
|
new file mode 100644
|
|
index 00000000..9ffc9829
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/common/actors/scandefinedipupaths/tests/test_scandefinedipupaths.py
|
|
@@ -0,0 +1,97 @@
|
|
+import json
|
|
+import os
|
|
+
|
|
+import pytest
|
|
+
|
|
+from leapp.libraries.actor import scandefinedipupaths
|
|
+from leapp.libraries.common.testutils import CurrentActorMocked, produce_mocked
|
|
+from leapp.models import IPUPath, IPUPaths
|
|
+from leapp.utils.deprecation import suppress_deprecation
|
|
+
|
|
+CUR_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
+
|
|
+
|
|
+class CurrentActorMockedModified(CurrentActorMocked):
|
|
+ def get_common_file_path(self, fname):
|
|
+ fpath = os.path.join(CUR_DIR, 'files', fname)
|
|
+ assert os.path.exists(fpath)
|
|
+ if os.path.exists(fpath):
|
|
+ return fpath
|
|
+ return None
|
|
+
|
|
+
|
|
+@pytest.mark.parametrize(('flavour', 'expected_result'), (
|
|
+ ('nonsense', {}),
|
|
+ (
|
|
+ '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']
|
|
+ }
|
|
+ ),
|
|
+))
|
|
+def test_load_ipu_paths_for_flavour(monkeypatch, flavour, expected_result):
|
|
+ monkeypatch.setattr(scandefinedipupaths.api, 'current_actor', CurrentActorMockedModified())
|
|
+
|
|
+ result = scandefinedipupaths.load_ipu_paths_for_flavour(flavour=flavour)
|
|
+ assert result == expected_result
|
|
+
|
|
+
|
|
+_DATA_IPU_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']
|
|
+}
|
|
+
|
|
+
|
|
+@suppress_deprecation(IPUPaths)
|
|
+@pytest.mark.parametrize(('maj_version', 'expected_result'), (
|
|
+ ('7', []),
|
|
+ (
|
|
+ '8',
|
|
+ [
|
|
+ IPUPath(source_version='8.10', target_versions=['9.4', '9.5', '9.6']),
|
|
+ IPUPath(source_version='8.4', target_versions=['9.2']),
|
|
+ IPUPath(source_version='8', target_versions=['9.4', '9.5', '9.6']),
|
|
+ ]
|
|
+ ),
|
|
+ (
|
|
+ '80',
|
|
+ [
|
|
+ IPUPath(source_version='80.0', target_versions=['81.0']),
|
|
+ ]
|
|
+ ),
|
|
+
|
|
+
|
|
+))
|
|
+def test_get_filtered_ipu_paths(monkeypatch, maj_version, expected_result):
|
|
+ result = scandefinedipupaths.get_filtered_ipu_paths(_DATA_IPU_PATHS, maj_version)
|
|
+ result = sorted(result, key=lambda x: x.source_version)
|
|
+ assert result == sorted(expected_result, key=lambda x: x.source_version)
|
|
+
|
|
+
|
|
+def test_scan_defined_ipu_paths(monkeypatch):
|
|
+ # let's try one 'full' happy run
|
|
+ monkeypatch.setattr(scandefinedipupaths.api, 'current_actor', CurrentActorMockedModified(src_ver='9.6'))
|
|
+ monkeypatch.setattr(scandefinedipupaths.api, 'produce', produce_mocked())
|
|
+ scandefinedipupaths.process()
|
|
+
|
|
+ assert scandefinedipupaths.api.produce.called == 1
|
|
+ msg = scandefinedipupaths.api.produce.model_instances[0]
|
|
+ assert isinstance(msg, IPUPaths)
|
|
+ assert len(msg.data) == 2
|
|
+ assert {i.source_version for i in msg.data} == {'9', '9.6'}
|
|
diff --git a/repos/system_upgrade/common/models/ipupaths.py b/repos/system_upgrade/common/models/ipupaths.py
|
|
new file mode 100644
|
|
index 00000000..5469f25e
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/common/models/ipupaths.py
|
|
@@ -0,0 +1,43 @@
|
|
+from leapp.models import fields, Model
|
|
+from leapp.topics import SystemInfoTopic
|
|
+from leapp.utils.deprecation import deprecated
|
|
+
|
|
+
|
|
+class IPUPath(Model):
|
|
+ """
|
|
+ Represent upgrade paths from a source system version.
|
|
+
|
|
+ This model is not supposed to be produced nor consumed directly by any actor.
|
|
+ See `IPUPaths` instead.
|
|
+ """
|
|
+ topic = SystemInfoTopic
|
|
+
|
|
+ source_version = fields.String()
|
|
+ """Version of a particular source system."""
|
|
+
|
|
+ target_versions = fields.List(fields.String())
|
|
+ """List of defined target system versions for the `source_version` system."""
|
|
+
|
|
+
|
|
+@deprecated(
|
|
+ since="2025-02-01",
|
|
+ message="This model is temporary and not assumed to be used in any actors."
|
|
+)
|
|
+class IPUPaths(Model):
|
|
+ """
|
|
+ Defined Upgrade paths from the source system major version and used upgrade flavour.
|
|
+
|
|
+ In example for the RHEL 8.10 system with the 'default' upgrade flavour it will
|
|
+ contain information about all defined upgrade paths from any RHEL 8 system
|
|
+ for the 'default' flavour (other flavour can be e.g. 'saphana' for systems
|
|
+ with SAP HANA installed.
|
|
+
|
|
+ Note this model is marked as deprecated now as it is considered as a temporary
|
|
+ solution. It can be removed in any future release!
|
|
+ """
|
|
+ topic = SystemInfoTopic
|
|
+
|
|
+ data = fields.List(fields.Model(IPUPath))
|
|
+ """
|
|
+ List of defined (filtered) upgrade paths.
|
|
+ """
|
|
--
|
|
2.48.1
|
|
|