e5599cfda4
- Add detection of possible usage of OpenSSL IBMCA engine on IBM Z machines - Add detection of modified /etc/pki/tls/openssl.cnf file - Update the leapp upgrade data files - Fix handling of symlinks under /etc/pki with relative paths specified - Report custom actors and modifications of the upgrade tooling - Requires xfsprogs and e2fsprogs to ensure that Ext4 and XFS tools are installed - Bump leapp-repository-dependencies to 10 - Resolves: RHEL-1774, RHEL-16729
256 lines
11 KiB
Diff
256 lines
11 KiB
Diff
From 118133a734987e4d2c01ab9775525b0152adc780 Mon Sep 17 00:00:00 2001
|
|
From: Inessa Vasilevskaya <ivasilev@redhat.com>
|
|
Date: Thu, 14 Dec 2023 14:03:25 +0100
|
|
Subject: [PATCH 51/60] Introduce two functions for listing which packages are
|
|
leapp packages.
|
|
|
|
* rpms.get_leapp_packages() library function returns the leapp packages which ship the leapp
|
|
components.
|
|
* rpms.get_leapp_deps_packages() library function returns the leapp deps meta packages which list
|
|
the requirements of the associated leapp packages.
|
|
|
|
This function can be used as leapp-installation-packages-getter.
|
|
Refactoring of other actors using it will be done later.
|
|
---
|
|
repos/system_upgrade/common/libraries/rpms.py | 139 ++++++++++++++++++
|
|
.../common/libraries/tests/test_rpms.py | 67 ++++++++-
|
|
2 files changed, 205 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/repos/system_upgrade/common/libraries/rpms.py b/repos/system_upgrade/common/libraries/rpms.py
|
|
index 6a5e8637..2890240f 100644
|
|
--- a/repos/system_upgrade/common/libraries/rpms.py
|
|
+++ b/repos/system_upgrade/common/libraries/rpms.py
|
|
@@ -1,7 +1,47 @@
|
|
from leapp.libraries import stdlib
|
|
+from leapp.libraries.common.config.version import get_source_major_version
|
|
from leapp.models import InstalledRPM
|
|
|
|
|
|
+class LeappComponents(object):
|
|
+ """
|
|
+ Supported component values to be used with get_packages_function:
|
|
+ * FRAMEWORK - the core of the leapp project: the leapp executable and
|
|
+ associated leapp libraries
|
|
+ * REPOSITORY - the leapp-repository project
|
|
+ * COCKPIT - the cockpit-leapp project
|
|
+ * TOOLS - miscellaneous tooling like snactor
|
|
+ """
|
|
+ FRAMEWORK = 'framework'
|
|
+ REPOSITORY = 'repository'
|
|
+ COCKPIT = 'cockpit'
|
|
+ TOOLS = 'tools'
|
|
+
|
|
+
|
|
+_LEAPP_PACKAGES_MAP = {
|
|
+ LeappComponents.FRAMEWORK: {'7': {'pkgs': ['leapp', 'python2-leapp'],
|
|
+ 'deps': ['leapp-deps']},
|
|
+ '8': {'pkgs': ['leapp', 'python3-leapp'],
|
|
+ 'deps': ['leapp-deps']}
|
|
+ },
|
|
+ LeappComponents.REPOSITORY: {'7': {'pkgs': ['leapp-upgrade-el7toel8'],
|
|
+ 'deps': ['leapp-upgrade-el7toel8-deps']},
|
|
+ '8': {'pkgs': ['leapp-upgrade-el8toel9'],
|
|
+ 'deps': ['leapp-upgrade-el8toel9-deps']}
|
|
+ },
|
|
+ LeappComponents.COCKPIT: {'7': {'pkgs': ['cockpit-leapp']},
|
|
+ '8': {'pkgs': ['cockpit-leapp']}
|
|
+ },
|
|
+ LeappComponents.TOOLS: {'7': {'pkgs': ['snactor']},
|
|
+ '8': {'pkgs': ['snactor']}
|
|
+ }
|
|
+ }
|
|
+
|
|
+GET_LEAPP_PACKAGES_DEFAULT_COMPONENTS = frozenset((LeappComponents.FRAMEWORK,
|
|
+ LeappComponents.REPOSITORY,
|
|
+ LeappComponents.TOOLS))
|
|
+
|
|
+
|
|
def get_installed_rpms():
|
|
rpm_cmd = [
|
|
'/bin/rpm',
|
|
@@ -114,3 +154,102 @@ def check_file_modification(config):
|
|
"""
|
|
output = _read_rpm_modifications(config)
|
|
return _parse_config_modification(output, config)
|
|
+
|
|
+
|
|
+def _get_leapp_packages_of_type(major_version, component, type_='pkgs'):
|
|
+ """
|
|
+ Private implementation of get_leapp_packages() and get_leapp_deps_packages().
|
|
+
|
|
+ :param major_version: Same as for :func:`get_leapp_packages` and
|
|
+ :func:`get_leapp_deps_packages`
|
|
+ :param component: Same as for :func:`get_leapp_packages` and :func:`get_leapp_deps_packages`
|
|
+ :param type_: Either "pkgs" or "deps". Determines which set of packages we're looking for.
|
|
+ Corresponds to the keys in the `_LEAPP_PACKAGES_MAP`.
|
|
+
|
|
+ Retrieving the set of leapp and leapp-deps packages only differs in which key is used to
|
|
+ retrieve the packages from _LEAPP_PACKAGES_MAP. This function abstracts that difference.
|
|
+ """
|
|
+ res = set()
|
|
+
|
|
+ major_versions = [major_version] if isinstance(major_version, str) else major_version
|
|
+ if not major_versions:
|
|
+ # No major_version of interest specified -> treat as if only current source system version
|
|
+ # requested
|
|
+ major_versions = [get_source_major_version()]
|
|
+
|
|
+ components = [component] if isinstance(component, str) else component
|
|
+ if not components:
|
|
+ error_msg = ("At least one component must be specified when calling this"
|
|
+ " function, available choices are {choices}".format(
|
|
+ choices=sorted(_LEAPP_PACKAGES_MAP.keys()))
|
|
+ )
|
|
+ raise ValueError(error_msg)
|
|
+
|
|
+ for comp in components:
|
|
+ for a_major_version in major_versions:
|
|
+ if comp not in _LEAPP_PACKAGES_MAP:
|
|
+ error_msg = "The requested component {comp} is unknown, available choices are {choices}".format(
|
|
+ comp=component, choices=sorted(_LEAPP_PACKAGES_MAP.keys()))
|
|
+ raise ValueError(error_msg)
|
|
+
|
|
+ if a_major_version not in _LEAPP_PACKAGES_MAP[comp]:
|
|
+ error_msg = "The requested major_version {ver} is unknown, available choices are {choices}".format(
|
|
+ ver=a_major_version, choices=sorted(_LEAPP_PACKAGES_MAP[comp].keys()))
|
|
+ raise ValueError(error_msg)
|
|
+
|
|
+ # All went well otherwise, get the data
|
|
+ res.update(_LEAPP_PACKAGES_MAP[comp][a_major_version].get(type_, []))
|
|
+
|
|
+ return sorted(res)
|
|
+
|
|
+
|
|
+def get_leapp_packages(major_version=None, component=GET_LEAPP_PACKAGES_DEFAULT_COMPONENTS):
|
|
+ """
|
|
+ Get list of leapp packages.
|
|
+
|
|
+ :param major_version: a list or string specifying major_versions. If not defined then current
|
|
+ system_version will be used.
|
|
+ :param component: a list or a single enum value specifying leapp components
|
|
+ (use enum :class: LeappComponents) If defined then only packages related to the specific
|
|
+ component(s) will be returned.
|
|
+ The default set of components is in `GET_LEAPP_PACKAGES_DEFAULT_COMPONENTS` and
|
|
+ simple modifications of the default can be achieved with code like:
|
|
+
|
|
+ .. code-block:: python
|
|
+ get_leapp_packages(
|
|
+ component=GET_LEAPP_PACKAGES_DEFAULT_COMPONENTS.difference(
|
|
+ [LeappComponents.TOOLS]
|
|
+ ))
|
|
+
|
|
+ :raises ValueError: if a requested component or major_version doesn't exist.
|
|
+
|
|
+ .. note::
|
|
+ Call :func:`get_leapp_dep_packages` as well if you also need the deps metapackages.
|
|
+ Those packages determine which RPMs need to be installed for leapp to function.
|
|
+ They aren't just Requires on the base leapp and leapp-repository RPMs because they
|
|
+ need to be switched from the old system_version's to the new ones at a different
|
|
+ point in the upgrade than the base RPMs.
|
|
+ """
|
|
+ return _get_leapp_packages_of_type(major_version, component, type_="pkgs")
|
|
+
|
|
+
|
|
+def get_leapp_dep_packages(major_version=None, component=GET_LEAPP_PACKAGES_DEFAULT_COMPONENTS):
|
|
+ """
|
|
+ Get list of leapp dep metapackages.
|
|
+
|
|
+ :param major_version: a list or string specifying major_versions. If not defined then current
|
|
+ system_version will be used.
|
|
+ :param component: a list or a single enum value specifying leapp components
|
|
+ (use enum :class: LeappComponents) If defined then only packages related to the specific
|
|
+ component(s) will be returned.
|
|
+ The default set of components is in `GET_LEAPP_PACKAGES_DEFAULT_COMPONENTS` and
|
|
+ simple modifications of the default can be achieved with code like:
|
|
+
|
|
+ .. code-block:: python
|
|
+ get_leapp_packages(
|
|
+ component=GET_LEAPP_PACKAGES_DEFAULT_COMPONENTS.difference(
|
|
+ [LeappComponents.TOOLS]
|
|
+ ))
|
|
+ :raises ValueError: if a requested component or major_version doesn't exist.
|
|
+ """
|
|
+ return _get_leapp_packages_of_type(major_version, component, type_="deps")
|
|
diff --git a/repos/system_upgrade/common/libraries/tests/test_rpms.py b/repos/system_upgrade/common/libraries/tests/test_rpms.py
|
|
index 39a32dcb..955ab05c 100644
|
|
--- a/repos/system_upgrade/common/libraries/tests/test_rpms.py
|
|
+++ b/repos/system_upgrade/common/libraries/tests/test_rpms.py
|
|
@@ -1,4 +1,8 @@
|
|
-from leapp.libraries.common.rpms import _parse_config_modification
|
|
+import pytest
|
|
+
|
|
+from leapp.libraries.common.rpms import _parse_config_modification, get_leapp_dep_packages, get_leapp_packages
|
|
+from leapp.libraries.common.testutils import CurrentActorMocked
|
|
+from leapp.libraries.stdlib import api
|
|
|
|
|
|
def test_parse_config_modification():
|
|
@@ -30,3 +34,64 @@ def test_parse_config_modification():
|
|
"S.5....T. c /etc/ssh/sshd_config",
|
|
]
|
|
assert _parse_config_modification(data, "/etc/ssh/sshd_config")
|
|
+
|
|
+
|
|
+@pytest.mark.parametrize('major_version,component,result', [
|
|
+ (None, None, ['leapp', 'python3-leapp', 'leapp-upgrade-el8toel9', 'snactor']),
|
|
+ ('7', None, ['leapp', 'python2-leapp', 'leapp-upgrade-el7toel8', 'snactor']),
|
|
+ (['7', '8'], None, ['leapp', 'python2-leapp', 'leapp-upgrade-el7toel8',
|
|
+ 'python3-leapp', 'leapp-upgrade-el8toel9', 'snactor']),
|
|
+ ('8', 'framework', ['leapp', 'python3-leapp']),
|
|
+ ])
|
|
+def test_get_leapp_packages(major_version, component, result, monkeypatch):
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch='x86_64', src_ver='8.9', dst_ver='9.3'))
|
|
+
|
|
+ kwargs = {}
|
|
+ if major_version:
|
|
+ kwargs["major_version"] = major_version
|
|
+ if component:
|
|
+ kwargs["component"] = component
|
|
+
|
|
+ assert set(get_leapp_packages(** kwargs)) == set(result)
|
|
+
|
|
+
|
|
+@pytest.mark.parametrize('major_version,component,result', [
|
|
+ ('8', 'nosuchcomponent',
|
|
+ (ValueError,
|
|
+ r"component nosuchcomponent is unknown, available choices are \['cockpit', 'framework', 'repository', 'tools']")
|
|
+ ),
|
|
+ ('nosuchversion', "framework",
|
|
+ (ValueError, r"major_version nosuchversion is unknown, available choices are \['7', '8']")),
|
|
+ ('nosuchversion', False,
|
|
+ (ValueError, r"At least one component must be specified when calling this function,"
|
|
+ r" available choices are \['cockpit', 'framework', 'repository', 'tools']")),
|
|
+])
|
|
+def test_get_leapp_packages_errors(major_version, component, result, monkeypatch):
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch='x86_64', src_ver='8.9', dst_ver='9.3'))
|
|
+
|
|
+ kwargs = {}
|
|
+ if major_version:
|
|
+ kwargs["major_version"] = major_version
|
|
+ if component is not None:
|
|
+ kwargs["component"] = component
|
|
+
|
|
+ exc_type, exc_msg = result
|
|
+ with pytest.raises(exc_type, match=exc_msg):
|
|
+ get_leapp_packages(**kwargs)
|
|
+
|
|
+
|
|
+@pytest.mark.parametrize('major_version,component,result', [
|
|
+ (None, None, ['leapp-deps', 'leapp-upgrade-el8toel9-deps']),
|
|
+ ('8', 'framework', ['leapp-deps']),
|
|
+ ('7', 'tools', []),
|
|
+])
|
|
+def test_get_leapp_dep_packages(major_version, component, result, monkeypatch):
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch='x86_64', src_ver='8.9', dst_ver='9.3'))
|
|
+
|
|
+ kwargs = {}
|
|
+ if major_version:
|
|
+ kwargs["major_version"] = major_version
|
|
+ if component:
|
|
+ kwargs["component"] = component
|
|
+
|
|
+ assert frozenset(get_leapp_dep_packages(**kwargs)) == frozenset(result)
|
|
--
|
|
2.43.0
|
|
|