Compare commits
No commits in common. "c8" and "a8-elevate-0210" have entirely different histories.
c8
...
a8-elevate
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
SOURCES/deps-pkgs-13.tar.gz
|
||||
SOURCES/leapp-repository-0.24.0.tar.gz
|
||||
SOURCES/deps-pkgs-11.tar.gz
|
||||
SOURCES/leapp-repository-0.21.0.tar.gz
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
3590b33b4a79ebe62f5cfa0eeca7efb41d526498 SOURCES/deps-pkgs-13.tar.gz
|
||||
2271b92541564ebd07a038a8b45e5a33d5f8b9c9 SOURCES/leapp-repository-0.24.0.tar.gz
|
||||
8b3fe3a7b52d2e144d374623aa5b0b0add7ab0c7 SOURCES/deps-pkgs-11.tar.gz
|
||||
9327be3720ccb3f7b285d2199463d7df0c38dfae SOURCES/leapp-repository-0.21.0.tar.gz
|
||||
|
||||
@ -1,112 +0,0 @@
|
||||
From 34aeae1e023e61345a1bb020b42231a79a0be4a8 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Thu, 26 Feb 2026 17:52:23 +0100
|
||||
Subject: [PATCH 01/44] Remove legacy overlay solution leftovers
|
||||
|
||||
The solution was removed in 93429, however there are some leftovers.
|
||||
---
|
||||
.../libraries/userspacegen.py | 19 -------------------
|
||||
.../common/libraries/dnfplugin.py | 15 ++++-----------
|
||||
.../common/libraries/overlaygen.py | 6 ------
|
||||
3 files changed, 4 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
index 66843645..7dbadae2 100644
|
||||
--- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
+++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
@@ -178,26 +178,7 @@ def _import_gpg_keys(context, install_root_dir, target_major_version):
|
||||
)
|
||||
|
||||
|
||||
-def _handle_transaction_err_msg_size_old(err):
|
||||
- # NOTE(pstodulk): This is going to be removed in future!
|
||||
-
|
||||
- article_section = 'Generic case'
|
||||
- xfs_info = next(api.consume(XFSPresence), XFSPresence())
|
||||
- if xfs_info.present and xfs_info.without_ftype:
|
||||
- article_section = 'XFS ftype=0 case'
|
||||
-
|
||||
- message = ('There is not enough space on the file system hosting /var/lib/leapp directory '
|
||||
- 'to extract the packages.')
|
||||
- details = {'hint': "Please follow the instructions in the '{}' section of the article at: "
|
||||
- "link: https://access.redhat.com/solutions/5057391".format(article_section)}
|
||||
-
|
||||
- raise StopActorExecutionError(message=message, details=details)
|
||||
-
|
||||
-
|
||||
def _handle_transaction_err_msg_size(err):
|
||||
- if get_env('LEAPP_OVL_LEGACY', '0') == '1':
|
||||
- _handle_transaction_err_msg_size_old(err)
|
||||
- return # not needed actually as the above function raises error, but for visibility
|
||||
NO_SPACE_STR = 'more space needed on the'
|
||||
|
||||
# Disk Requirements:
|
||||
diff --git a/repos/system_upgrade/common/libraries/dnfplugin.py b/repos/system_upgrade/common/libraries/dnfplugin.py
|
||||
index d50dbbce..b91bcbe7 100644
|
||||
--- a/repos/system_upgrade/common/libraries/dnfplugin.py
|
||||
+++ b/repos/system_upgrade/common/libraries/dnfplugin.py
|
||||
@@ -7,7 +7,6 @@ import shutil
|
||||
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries.common import dnfconfig, guards, mounting, overlaygen, rhsm, utils
|
||||
-from leapp.libraries.common.config import get_env
|
||||
from leapp.libraries.common.config.version import get_target_major_version, get_target_version
|
||||
from leapp.libraries.common.gpg import is_nogpgcheck_set
|
||||
from leapp.libraries.stdlib import api, CalledProcessError, config
|
||||
@@ -166,16 +165,10 @@ def _handle_transaction_err_msg_old(stage, xfs_info, err):
|
||||
raise StopActorExecutionError(message=message, details=details)
|
||||
|
||||
|
||||
-def _handle_transaction_err_msg(stage, xfs_info, err, is_container=False):
|
||||
- # ignore the fallback when the error is related to the container issue
|
||||
- # e.g. installation of packages inside the container; so it's unrelated
|
||||
- # to the upgrade transactions.
|
||||
- if get_env('LEAPP_OVL_LEGACY', '0') == '1' and not is_container:
|
||||
- _handle_transaction_err_msg_old(stage, xfs_info, err)
|
||||
- return # not needed actually as the above function raises error, but for visibility
|
||||
+def _handle_transaction_err_msg(err, is_container=False):
|
||||
NO_SPACE_STR = 'more space needed on the'
|
||||
- message = 'DNF execution failed with non zero exit code.'
|
||||
if NO_SPACE_STR not in err.stderr:
|
||||
+ message = 'DNF execution failed with non zero exit code.'
|
||||
# if there was a problem reaching repos and proxy is configured in DNF/YUM configs, the
|
||||
# proxy is likely the problem.
|
||||
# NOTE(mmatuska): We can't consistently detect there was a problem reaching some repos,
|
||||
@@ -308,7 +301,7 @@ def _transaction(context, stage, target_repoids, tasks, plugin_info, xfs_info,
|
||||
)
|
||||
except CalledProcessError as e:
|
||||
api.current_logger().error('Cannot calculate, check, test, or perform the upgrade transaction.')
|
||||
- _handle_transaction_err_msg(stage, xfs_info, e, is_container=False)
|
||||
+ _handle_transaction_err_msg(e, is_container=False)
|
||||
finally:
|
||||
if stage == 'check':
|
||||
backup_debug_data(context=context)
|
||||
@@ -384,7 +377,7 @@ def install_initramdisk_requirements(packages, target_userspace_info, used_repos
|
||||
api.current_logger().error(
|
||||
'Cannot install packages in the target container required to build the upgrade initramfs.'
|
||||
)
|
||||
- _handle_transaction_err_msg('', None, e, is_container=True)
|
||||
+ _handle_transaction_err_msg(e, is_container=True)
|
||||
|
||||
|
||||
def perform_transaction_install(target_userspace_info, storage_info, used_repos, tasks, plugin_info, xfs_info):
|
||||
diff --git a/repos/system_upgrade/common/libraries/overlaygen.py b/repos/system_upgrade/common/libraries/overlaygen.py
|
||||
index f0d0ba1d..3091ab5b 100644
|
||||
--- a/repos/system_upgrade/common/libraries/overlaygen.py
|
||||
+++ b/repos/system_upgrade/common/libraries/overlaygen.py
|
||||
@@ -594,12 +594,6 @@ def create_source_overlay(
|
||||
in the OVERLAY_DO_NOT_MOUNT set. Such prepared OVL images are then composed
|
||||
together to reflect the real host filesystem. In the end everything is cleaned.
|
||||
|
||||
- The new solution can be now problematic for system with too many partitions
|
||||
- and loop devices. For such systems we keep for now the possibility of the
|
||||
- fallback to an old solution, which has however number of issues that are
|
||||
- fixed by the new design. To fallback to the old solution, set envar:
|
||||
- LEAPP_OVL_LEGACY=1
|
||||
-
|
||||
Disk images created for OVL are formatted with XFS by default. In case of
|
||||
problems, it's possible to switch to Ext4 FS using:
|
||||
LEAPP_OVL_IMG_FS_EXT4=1
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
From fbc38d4ad1d828e0553579e3719c0e4ed4a2a6bd Mon Sep 17 00:00:00 2001
|
||||
From: jinkangkang <1547182170@qq.com>
|
||||
Date: Mon, 19 Aug 2024 18:46:08 +0800
|
||||
Subject: [PATCH 01/40] rhui(alibaba): add ARM RHEL8 and RHEL9 setup entries
|
||||
(#1277)
|
||||
|
||||
Since leapp's RHUI mechanism filters setups based on the architecture of the source system,
|
||||
it was not possible to upgrade of ARM-based RHEL systems on Alibaba cloud as there
|
||||
were no ARM entries in RHUI_SETUPS. This patch adds these entries, making it possible
|
||||
for EL 8 -> 9 upgrades of ARM systems on Alibaba cloud.
|
||||
---
|
||||
repos/system_upgrade/common/libraries/rhui.py | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/libraries/rhui.py b/repos/system_upgrade/common/libraries/rhui.py
|
||||
index 51694ac2..30de0275 100644
|
||||
--- a/repos/system_upgrade/common/libraries/rhui.py
|
||||
+++ b/repos/system_upgrade/common/libraries/rhui.py
|
||||
@@ -348,6 +348,22 @@ RHUI_SETUPS = {
|
||||
('content.crt', RHUI_PKI_PRODUCT_DIR)
|
||||
],
|
||||
os_version='9'),
|
||||
+ ],
|
||||
+ RHUIFamily(RHUIProvider.ALIBABA, arch=arch.ARCH_ARM64, client_files_folder='alibaba'): [
|
||||
+ mk_rhui_setup(clients={'aliyun_rhui_rhel8'}, leapp_pkg='leapp-rhui-alibaba',
|
||||
+ mandatory_files=[('leapp-alibaba.repo', YUM_REPOS_PATH)],
|
||||
+ optional_files=[
|
||||
+ ('key.pem', RHUI_PKI_DIR),
|
||||
+ ('content.crt', RHUI_PKI_PRODUCT_DIR)
|
||||
+ ],
|
||||
+ os_version='8'),
|
||||
+ mk_rhui_setup(clients={'aliyun_rhui_rhel9'}, leapp_pkg='leapp-rhui-alibaba',
|
||||
+ mandatory_files=[('leapp-alibaba.repo', YUM_REPOS_PATH)],
|
||||
+ optional_files=[
|
||||
+ ('key.pem', RHUI_PKI_DIR),
|
||||
+ ('content.crt', RHUI_PKI_PRODUCT_DIR)
|
||||
+ ],
|
||||
+ os_version='9'),
|
||||
]
|
||||
}
|
||||
|
||||
--
|
||||
2.47.0
|
||||
@ -0,0 +1,41 @@
|
||||
From 7e0fb44bb673893d0409903f6a441d0eb2829d22 Mon Sep 17 00:00:00 2001
|
||||
From: Evgeni Golov <evgeni@golov.de>
|
||||
Date: Tue, 20 Aug 2024 15:11:02 +0200
|
||||
Subject: [PATCH 02/40] don't require all versions to be defined for obsoleted
|
||||
keys
|
||||
|
||||
in releases where we do not have any obsoleted keys, we still had to
|
||||
define an entry (with an empty list), as otherwise the code would fail
|
||||
|
||||
instead, we can catch the KeyError and carry on as nothing happened
|
||||
---
|
||||
.../libraries/removeobsoleterpmgpgkeys.py | 13 ++++++++-----
|
||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/removeobsoletegpgkeys/libraries/removeobsoleterpmgpgkeys.py b/repos/system_upgrade/common/actors/removeobsoletegpgkeys/libraries/removeobsoleterpmgpgkeys.py
|
||||
index 6e84c2e9..bda7efa3 100644
|
||||
--- a/repos/system_upgrade/common/actors/removeobsoletegpgkeys/libraries/removeobsoleterpmgpgkeys.py
|
||||
+++ b/repos/system_upgrade/common/actors/removeobsoletegpgkeys/libraries/removeobsoleterpmgpgkeys.py
|
||||
@@ -12,11 +12,14 @@ def _get_obsolete_keys():
|
||||
distribution = api.current_actor().configuration.os_release.release_id
|
||||
obsoleted_keys_map = get_distribution_data(distribution).get('obsoleted-keys', {})
|
||||
keys = []
|
||||
- for version in range(7, int(get_target_major_version()) + 1):
|
||||
- for key in obsoleted_keys_map[str(version)]:
|
||||
- name, version, release = key.rsplit("-", 2)
|
||||
- if has_package(InstalledRPM, name, version=version, release=release):
|
||||
- keys.append(key)
|
||||
+ try:
|
||||
+ for version in range(7, int(get_target_major_version()) + 1):
|
||||
+ for key in obsoleted_keys_map[str(version)]:
|
||||
+ name, version, release = key.rsplit("-", 2)
|
||||
+ if has_package(InstalledRPM, name, version=version, release=release):
|
||||
+ keys.append(key)
|
||||
+ except KeyError:
|
||||
+ pass
|
||||
|
||||
return keys
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
226
SOURCES/0003-Add-RHEL-10.0-prod-certs.patch
Normal file
226
SOURCES/0003-Add-RHEL-10.0-prod-certs.patch
Normal file
@ -0,0 +1,226 @@
|
||||
From 9f2f1726d8a5bdd12309a3a3111984f1666b903f Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Thu, 22 Aug 2024 15:52:19 +0200
|
||||
Subject: [PATCH 03/40] Add RHEL 10.0 prod-certs
|
||||
|
||||
Previously we temporarily used the RHEL 9 x86_64 prod cert for others
|
||||
archs it was missing completely.
|
||||
|
||||
Jira: OAMG-11138
|
||||
---
|
||||
.../common/files/prod-certs/10.0/279.pem | 37 ++++++++++
|
||||
.../common/files/prod-certs/10.0/419.pem | 37 ++++++++++
|
||||
.../common/files/prod-certs/10.0/479.pem | 68 ++++++++++---------
|
||||
.../common/files/prod-certs/10.0/72.pem | 37 ++++++++++
|
||||
4 files changed, 146 insertions(+), 33 deletions(-)
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/10.0/279.pem
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/10.0/419.pem
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/10.0/72.pem
|
||||
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/10.0/279.pem b/repos/system_upgrade/common/files/prod-certs/10.0/279.pem
|
||||
new file mode 100644
|
||||
index 00000000..f62340fc
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/10.0/279.pem
|
||||
@@ -0,0 +1,37 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGczCCBFugAwIBAgIUfZodBQY+YRSlyRRiFX1dx4vQ5y4wDQYJKoZIhvcNAQEL
|
||||
+BQAwga4xCzAJBgNVBAYTAlVTMRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEWMBQG
|
||||
+A1UECgwNUmVkIEhhdCwgSW5jLjEYMBYGA1UECwwPUmVkIEhhdCBOZXR3b3JrMS4w
|
||||
+LAYDVQQDDCVSZWQgSGF0IEVudGl0bGVtZW50IFByb2R1Y3QgQXV0aG9yaXR5MSQw
|
||||
+IgYJKoZIhvcNAQkBFhVjYS1zdXBwb3J0QHJlZGhhdC5jb20wHhcNMjQwODE1MDYx
|
||||
+NjQ5WhcNNDQwODE1MDYxNjQ5WjBEMUIwQAYDVQQDDDlSZWQgSGF0IFByb2R1Y3Qg
|
||||
+SUQgWzA0YTU4NDFkLTVlNmUtNDU1Yy1hZWYwLTdhOTQ0NTBiNjg3Nl0wggIiMA0G
|
||||
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGP0nTjP4TN3LHVTfeQV+0u/Se01LU
|
||||
+FJ66GhksOGzXzKSx6kbuFde0eHYIwV8tmZOMDIv2LVezHKRClVB1dMalQXfcLaoF
|
||||
+AcHmCViz353vzXHynybzMXFs9xbzZMglduBbcStWHy+TmoJsbVwIAAdv4NYyrQQD
|
||||
+LLVuX8mACCFg0YFG8ok5tN0Kt2liHTYpSoEuRI9ke+joNQkU3fsxcOlV5Cr1W2pG
|
||||
+OkosvC4R9dvRjsjnEQ6tHeRhs5oEBZW3eZhnW3Qv8p9jaNU51TlYXLIH0+Fsx0uL
|
||||
+XETzTWP4YmvBwtrGaq+PhRogJHNw8BM/zrNUzUEFBr6WKWRFB6zkfKNnNkOIZi52
|
||||
+deFuqYuj+fRy5ehAFVWOHNFMzHvUSKJqGaLD5TW8aqQeFA3FvXce03WVwCFQIOvH
|
||||
+F4y+sCNh1aliWkjJbc2yw9a3VhQeJ0wFIAngpy0h/3V3IT3dpK2XHAL9CfIWxk6Z
|
||||
+wSwHNUKfP0aZYyXX/pfMFLXINSoHKSXHRMsf7P+wr0D47atkDLWYHIJjBXG9s5mG
|
||||
+eobEC5OghL4DzW/mEKOwKI5JxUH5yKXfRgG7RwfzlFnQgs2Qd0p2sstZbjCOmEra
|
||||
+cGfaDaLf7O1/6dAQPalCpn+uG5bv2NzIJmX2Rep7XA50XQLBqHg3r/cvMhcQQrIQ
|
||||
+nE2pDC01zYhUTwIDAQABo4HxMIHuMAkGA1UdEwQCMAAwQwYMKwYBBAGSCAkBghcB
|
||||
+BDMMMVJlZCBIYXQgRW50ZXJwcmlzZSBMaW51eCBmb3IgUG93ZXIsIGxpdHRsZSBl
|
||||
+bmRpYW4wFgYMKwYBBAGSCAkBghcCBAYMBDEwLjAwGQYMKwYBBAGSCAkBghcDBAkM
|
||||
+B3BwYzY0bGUwKQYMKwYBBAGSCAkBghcEBBkMF3JoZWwtMTAscmhlbC0xMC1wcGM2
|
||||
+NGxlMB0GA1UdDgQWBBRh6iC1NXyvZ2Q6/2sI5hB40M0flTAfBgNVHSMEGDAWgBSW
|
||||
+/bscQED/QIStsh8LJsHDam/WfDANBgkqhkiG9w0BAQsFAAOCAgEAv6ySsgygc2z2
|
||||
+kQJeu9sdvBNFKe+gEtXbPu6+rZKPPosW3cggMJCnsZgki3nUogovz0Z3MPkbmRz+
|
||||
+GJwVjiVBnfUQLoORSDYwqYZB4WRoqszW/dytd7/64IehvD/JZo3Oa8BNYRSG/Ukh
|
||||
+7iUIT8ryFIH1DTUIersVObINN2gk3hC2JJXoTfNqIYG+4OAEUE7/F4CptRAGbgH/
|
||||
+4/9vfe2KNXvPMoWvILpXpD5w8t9Xh0Wl97N1W7+FLVRwQHAQ2/yBTu/sY27FvVSl
|
||||
+0o+SBSvjTKIi+9QslRpi0QCVza5WxHTiO8nzYgzFjfMkt6lzK74puf3VJavpqkQ9
|
||||
+dVfyp36A3Fh6vDsiNxhsfKrp8z2JnKA3vdslsH7cOHCIFYHXiqeaP654t4oGeESD
|
||||
+EPfS6PpXSyi47Kd/qjA2srgpXNQl2yMd0ih6NoHaoSYXFfb4LX6cWFGcT/AWZsaC
|
||||
+xv2pN9J0KhF2loLp8SK19FESc0rJShkAacTcxeYjuDYbvLtJi4Z5aWWVU421rMSs
|
||||
+X9IdiWa4WL70ZaDK5cP54S4zZNsVDKniUzNXwPltDCpqefy8ka4o5QlWNreBrXXW
|
||||
+6cy8I6L2om7xZ5hAZ3CB7nUZe9QE/LXnHqK3cQetvd5Q2LMnp6gVtgQ4a+7vD9xz
|
||||
+ExLtbBZjvGJFudimMmOxvn/J5+GMmm4=
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/10.0/419.pem b/repos/system_upgrade/common/files/prod-certs/10.0/419.pem
|
||||
new file mode 100644
|
||||
index 00000000..08cb5b02
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/10.0/419.pem
|
||||
@@ -0,0 +1,37 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGZTCCBE2gAwIBAgIUWARL99TkK+hxtTJkE5icdHXLfY0wDQYJKoZIhvcNAQEL
|
||||
+BQAwga4xCzAJBgNVBAYTAlVTMRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEWMBQG
|
||||
+A1UECgwNUmVkIEhhdCwgSW5jLjEYMBYGA1UECwwPUmVkIEhhdCBOZXR3b3JrMS4w
|
||||
+LAYDVQQDDCVSZWQgSGF0IEVudGl0bGVtZW50IFByb2R1Y3QgQXV0aG9yaXR5MSQw
|
||||
+IgYJKoZIhvcNAQkBFhVjYS1zdXBwb3J0QHJlZGhhdC5jb20wHhcNMjQwODE1MDYx
|
||||
+NjQ5WhcNNDQwODE1MDYxNjQ5WjBEMUIwQAYDVQQDDDlSZWQgSGF0IFByb2R1Y3Qg
|
||||
+SUQgW2Y3ZWFmNGU2LTYwZGYtNDMyNC04N2I0LTdhNGUzZGVkZmViNV0wggIiMA0G
|
||||
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGP0nTjP4TN3LHVTfeQV+0u/Se01LU
|
||||
+FJ66GhksOGzXzKSx6kbuFde0eHYIwV8tmZOMDIv2LVezHKRClVB1dMalQXfcLaoF
|
||||
+AcHmCViz353vzXHynybzMXFs9xbzZMglduBbcStWHy+TmoJsbVwIAAdv4NYyrQQD
|
||||
+LLVuX8mACCFg0YFG8ok5tN0Kt2liHTYpSoEuRI9ke+joNQkU3fsxcOlV5Cr1W2pG
|
||||
+OkosvC4R9dvRjsjnEQ6tHeRhs5oEBZW3eZhnW3Qv8p9jaNU51TlYXLIH0+Fsx0uL
|
||||
+XETzTWP4YmvBwtrGaq+PhRogJHNw8BM/zrNUzUEFBr6WKWRFB6zkfKNnNkOIZi52
|
||||
+deFuqYuj+fRy5ehAFVWOHNFMzHvUSKJqGaLD5TW8aqQeFA3FvXce03WVwCFQIOvH
|
||||
+F4y+sCNh1aliWkjJbc2yw9a3VhQeJ0wFIAngpy0h/3V3IT3dpK2XHAL9CfIWxk6Z
|
||||
+wSwHNUKfP0aZYyXX/pfMFLXINSoHKSXHRMsf7P+wr0D47atkDLWYHIJjBXG9s5mG
|
||||
+eobEC5OghL4DzW/mEKOwKI5JxUH5yKXfRgG7RwfzlFnQgs2Qd0p2sstZbjCOmEra
|
||||
+cGfaDaLf7O1/6dAQPalCpn+uG5bv2NzIJmX2Rep7XA50XQLBqHg3r/cvMhcQQrIQ
|
||||
+nE2pDC01zYhUTwIDAQABo4HjMIHgMAkGA1UdEwQCMAAwNQYMKwYBBAGSCAkBgyMB
|
||||
+BCUMI1JlZCBIYXQgRW50ZXJwcmlzZSBMaW51eCBmb3IgQVJNIDY0MBYGDCsGAQQB
|
||||
+kggJAYMjAgQGDAQxMC4wMBkGDCsGAQQBkggJAYMjAwQJDAdhYXJjaDY0MCkGDCsG
|
||||
+AQQBkggJAYMjBAQZDBdyaGVsLTEwLHJoZWwtMTAtYWFyY2g2NDAdBgNVHQ4EFgQU
|
||||
+YeogtTV8r2dkOv9rCOYQeNDNH5UwHwYDVR0jBBgwFoAUlv27HEBA/0CErbIfCybB
|
||||
+w2pv1nwwDQYJKoZIhvcNAQELBQADggIBAIpdcHN7RN18pg5ELfc55Sj58ivL5N25
|
||||
+19KprqbM7aVum32abw7/Qksfs6maGQpU6Hh/UqhJlGQ2bN48jZ/kdMKor4agSQ/T
|
||||
+iwr3b8RBJFPVCuqQJXIe4g3iRbHfnIjGxgoMgv36j58PENoEnpPtR7ZtHMyqQ2SO
|
||||
+m1WRQhY5tJ4Fk/Zkx/trxlNvmsTAjNRa530kqG4TfiMVvWNaVdxHsjMv0lXLJRXx
|
||||
+KT6+iHt2QBs2No5O8cjlXr/CzfGrB5TlBNrsHqhO0Llmw28KpcWGYGdexKdIHrDG
|
||||
+A/K0Pr21yRstUWN39jz/tdEqt1q8T7/it3oM976keQmFAxBa/CpyEG5Y6FKw9+F0
|
||||
+LtkAyI3XGHK7LbCOE67s7u0/BfgQvww1FqztVnVZ4sXlagj/IuYPJBhfGDe/6tik
|
||||
+laqP8FtR6xJdSra2YQMBc0kZb0Sv1uy7pGofNSvLM5L76XqiwKoDVo/eAcl60OWY
|
||||
+rF86pEDLGDmdJBLJKX2/77pzpQpZ9Yvc4vWwoZrP4gRKBuWF28aLH0OsWzdsfdMG
|
||||
+9+DrcO/58slMbWng1ZzOQyEjp7x1kto5sa5m2q8LMo06ETYT8ps5A0hyltBz1yAt
|
||||
+JEBS4Y14YlF6Px67aTak07MNo7AaaphuD47D2Sy3pwHa+vOx4nv/G33+G0iOm3Lr
|
||||
+zVAjwlfLIUB9
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/10.0/479.pem b/repos/system_upgrade/common/files/prod-certs/10.0/479.pem
|
||||
index 1ea1cd3d..d89f6188 100644
|
||||
--- a/repos/system_upgrade/common/files/prod-certs/10.0/479.pem
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/10.0/479.pem
|
||||
@@ -1,35 +1,37 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
-MIIGFTCCA/2gAwIBAgIJALDxRLt/tVDQMA0GCSqGSIb3DQEBCwUAMIGuMQswCQYD
|
||||
-VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFjAUBgNVBAoMDVJlZCBI
|
||||
-YXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0d29yazEuMCwGA1UEAwwlUmVk
|
||||
-IEhhdCBFbnRpdGxlbWVudCBQcm9kdWN0IEF1dGhvcml0eTEkMCIGCSqGSIb3DQEJ
|
||||
-ARYVY2Etc3VwcG9ydEByZWRoYXQuY29tMB4XDTIzMDcxOTE2MzQwOFoXDTQzMDcx
|
||||
-OTE2MzQwOFowRDFCMEAGA1UEAww5UmVkIEhhdCBQcm9kdWN0IElEIFsxZDg0ZDQ5
|
||||
-Ny1jZmNmLTQxNjEtOTM0YS0zNzk2MDU4M2ZmZGZdMIICIjANBgkqhkiG9w0BAQEF
|
||||
-AAOCAg8AMIICCgKCAgEAxj9J04z+Ezdyx1U33kFftLv0ntNS1BSeuhoZLDhs18yk
|
||||
-sepG7hXXtHh2CMFfLZmTjAyL9i1XsxykQpVQdXTGpUF33C2qBQHB5glYs9+d781x
|
||||
-8p8m8zFxbPcW82TIJXbgW3ErVh8vk5qCbG1cCAAHb+DWMq0EAyy1bl/JgAghYNGB
|
||||
-RvKJObTdCrdpYh02KUqBLkSPZHvo6DUJFN37MXDpVeQq9VtqRjpKLLwuEfXb0Y7I
|
||||
-5xEOrR3kYbOaBAWVt3mYZ1t0L/KfY2jVOdU5WFyyB9PhbMdLi1xE801j+GJrwcLa
|
||||
-xmqvj4UaICRzcPATP86zVM1BBQa+lilkRQes5HyjZzZDiGYudnXhbqmLo/n0cuXo
|
||||
-QBVVjhzRTMx71Eiiahmiw+U1vGqkHhQNxb13HtN1lcAhUCDrxxeMvrAjYdWpYlpI
|
||||
-yW3NssPWt1YUHidMBSAJ4KctIf91dyE93aStlxwC/QnyFsZOmcEsBzVCnz9GmWMl
|
||||
-1/6XzBS1yDUqByklx0TLH+z/sK9A+O2rZAy1mByCYwVxvbOZhnqGxAuToIS+A81v
|
||||
-5hCjsCiOScVB+cil30YBu0cH85RZ0ILNkHdKdrLLWW4wjphK2nBn2g2i3+ztf+nQ
|
||||
-ED2pQqZ/rhuW79jcyCZl9kXqe1wOdF0Cwah4N6/3LzIXEEKyEJxNqQwtNc2IVE8C
|
||||
-AwEAAaOBnjCBmzAJBgNVHRMEAjAAMDUGDCsGAQQBkggJAYNfAQQlDCNSZWQgSGF0
|
||||
-IEVudGVycHJpc2UgTGludXggZm9yIHg4Nl82NDAVBgwrBgEEAZIICQGDXwIEBQwD
|
||||
-OS40MBgGDCsGAQQBkggJAYNfAwQIDAZ4ODZfNjQwJgYMKwYBBAGSCAkBg18EBBYM
|
||||
-FHJoZWwtOSxyaGVsLTkteDg2XzY0MA0GCSqGSIb3DQEBCwUAA4ICAQCGUDPFBrLs
|
||||
-sK/RITJothRhKhKNX3zu9TWRG0WKxszCx/y7c4yEfH1TV/yd7BNB2RubaoayWz8E
|
||||
-TQjcRW8BnVu9JrlbdpWJm4eN+dOOpcESPilLnkz4Tr0WYDsT1/jk/uiorK4h21S0
|
||||
-EwMicuSuEmm0OUEX0zj2X/IyveFRtpJpH/JktznCkvexysc1JRzqMCbal8GipRX9
|
||||
-Xf7Oko6QiaUpu5GDLN2OXhizYHdR2f3l+Sn2cScsbi3fSVv+DLsnaz6J0kZ4U8q3
|
||||
-lYk/ZYifJjG+/7cv3e+usixpmK/qYlpOvunUDnqOkDfUs4/4bZjH8e8CdqJk4YvU
|
||||
-RRtLr7muXEJsaqF7lxAViXnKxT/z/+1kOgN/+Oyzjs4QDsk2HQpWHFgNYSSG9Mmz
|
||||
-PUS8tk2T0j5sN55X7QRRl5c0oqrBU5XaWyL26QcfONYcR8dBaKawjxg8CI9KzsYY
|
||||
-sb2jjS+fBkB1OI2c6z4OZRd+0N6FQ6gq++KiXOLFvi/QSFNi9Veb56c5tR2l6fBk
|
||||
-0pSH06Gg2s0aQg20NdMIr+HaYsVdJRsE1FgQ2tlfFx9rGkcqhgwV3Za/abgtRb2o
|
||||
-YVwps28DLm41DXf5DnXK+BXFHrtR/3YAZtga+R7OL/RvcF0kc2kudlxqd/8Y33uL
|
||||
-nqnoATy31FTW4J4rEfanJTQgTpatZmbaLQ==
|
||||
+MIIGYzCCBEugAwIBAgIUL5D34AcwqLAbqlUcxntHUCtEVxQwDQYJKoZIhvcNAQEL
|
||||
+BQAwga4xCzAJBgNVBAYTAlVTMRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEWMBQG
|
||||
+A1UECgwNUmVkIEhhdCwgSW5jLjEYMBYGA1UECwwPUmVkIEhhdCBOZXR3b3JrMS4w
|
||||
+LAYDVQQDDCVSZWQgSGF0IEVudGl0bGVtZW50IFByb2R1Y3QgQXV0aG9yaXR5MSQw
|
||||
+IgYJKoZIhvcNAQkBFhVjYS1zdXBwb3J0QHJlZGhhdC5jb20wHhcNMjQwODE1MDYx
|
||||
+NjQ5WhcNNDQwODE1MDYxNjQ5WjBEMUIwQAYDVQQDDDlSZWQgSGF0IFByb2R1Y3Qg
|
||||
+SUQgWzk5NDZhMmY5LTI4NDMtNDJhOS1iNzhlLTIzM2E5ODIwYjVhZV0wggIiMA0G
|
||||
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGP0nTjP4TN3LHVTfeQV+0u/Se01LU
|
||||
+FJ66GhksOGzXzKSx6kbuFde0eHYIwV8tmZOMDIv2LVezHKRClVB1dMalQXfcLaoF
|
||||
+AcHmCViz353vzXHynybzMXFs9xbzZMglduBbcStWHy+TmoJsbVwIAAdv4NYyrQQD
|
||||
+LLVuX8mACCFg0YFG8ok5tN0Kt2liHTYpSoEuRI9ke+joNQkU3fsxcOlV5Cr1W2pG
|
||||
+OkosvC4R9dvRjsjnEQ6tHeRhs5oEBZW3eZhnW3Qv8p9jaNU51TlYXLIH0+Fsx0uL
|
||||
+XETzTWP4YmvBwtrGaq+PhRogJHNw8BM/zrNUzUEFBr6WKWRFB6zkfKNnNkOIZi52
|
||||
+deFuqYuj+fRy5ehAFVWOHNFMzHvUSKJqGaLD5TW8aqQeFA3FvXce03WVwCFQIOvH
|
||||
+F4y+sCNh1aliWkjJbc2yw9a3VhQeJ0wFIAngpy0h/3V3IT3dpK2XHAL9CfIWxk6Z
|
||||
+wSwHNUKfP0aZYyXX/pfMFLXINSoHKSXHRMsf7P+wr0D47atkDLWYHIJjBXG9s5mG
|
||||
+eobEC5OghL4DzW/mEKOwKI5JxUH5yKXfRgG7RwfzlFnQgs2Qd0p2sstZbjCOmEra
|
||||
+cGfaDaLf7O1/6dAQPalCpn+uG5bv2NzIJmX2Rep7XA50XQLBqHg3r/cvMhcQQrIQ
|
||||
+nE2pDC01zYhUTwIDAQABo4HhMIHeMAkGA1UdEwQCMAAwNQYMKwYBBAGSCAkBg18B
|
||||
+BCUMI1JlZCBIYXQgRW50ZXJwcmlzZSBMaW51eCBmb3IgeDg2XzY0MBYGDCsGAQQB
|
||||
+kggJAYNfAgQGDAQxMC4wMBgGDCsGAQQBkggJAYNfAwQIDAZ4ODZfNjQwKAYMKwYB
|
||||
+BAGSCAkBg18EBBgMFnJoZWwtMTAscmhlbC0xMC14ODZfNjQwHQYDVR0OBBYEFGHq
|
||||
+ILU1fK9nZDr/awjmEHjQzR+VMB8GA1UdIwQYMBaAFJb9uxxAQP9AhK2yHwsmwcNq
|
||||
+b9Z8MA0GCSqGSIb3DQEBCwUAA4ICAQAa+c2/Usg6JToULhYTdLhf15Hk6xxdlwT7
|
||||
+zZlnZLbuAKtaDqP1NiSiX0Z/lMJzFfW0B/zyWLy8uiXLYmF5V28f8yWK0Nksx2v7
|
||||
+I7u6ZZN2dKDQZKsEoP0g3ptvVRWn9h5otS7yPkOK4Dzj04yJqOSGP9bp6OHEhm1S
|
||||
+x4ErITkN/3MXOf9vT+I6wydVKsw4fdlWgVjmBd90bzVTnv4dWtJio+le+9ad9RSf
|
||||
+M3aD5ufiELeRKMp6ExnC/cnoWtuH+b4BJ37TQ3Kpn3fDtbrzVvQH/dpqZ7P33yqg
|
||||
+PnBEXOiLimDnnmDJ9ImQ1pVTrKJMxaj1Mk6onERe36n/iAsj+BwZvBiv7UaLPMnW
|
||||
+nJGg+LQ4iUZrGWYD4N9Ou++nvsR8dCWRhXSuXensfli3lL/W0P62yzfYCyqOYeL1
|
||||
+msDcCmBEWJUtAaeAbASUIVx02JWPPmMSUqWs8xOecQjzoGuCQg4JM/UfsZzxepw0
|
||||
+bs9YSUVw8J9R2d4kuze65qDTMRg+cK2LX1xg1KkR/UWZOGxHHJAfwGWdPwSkiOPQ
|
||||
+MVJ7LJjvozebHWSuiSxk+GWWr+NdxIJrFRGbivXyAkmqMRrPe1VLVxWwCdyud9o8
|
||||
+b2WbFgrNS2jOnHwldtM2ZAhrF5W4ckvVL7hLp2JoQnJfCcWson9NK6Y2M4bNwQnC
|
||||
+ihxphLzOAw==
|
||||
-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/10.0/72.pem b/repos/system_upgrade/common/files/prod-certs/10.0/72.pem
|
||||
new file mode 100644
|
||||
index 00000000..e0274f9c
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/10.0/72.pem
|
||||
@@ -0,0 +1,37 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGZDCCBEygAwIBAgIUSTvcD4Wsduixh8PFmwk6aI0KTEcwDQYJKoZIhvcNAQEL
|
||||
+BQAwga4xCzAJBgNVBAYTAlVTMRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEWMBQG
|
||||
+A1UECgwNUmVkIEhhdCwgSW5jLjEYMBYGA1UECwwPUmVkIEhhdCBOZXR3b3JrMS4w
|
||||
+LAYDVQQDDCVSZWQgSGF0IEVudGl0bGVtZW50IFByb2R1Y3QgQXV0aG9yaXR5MSQw
|
||||
+IgYJKoZIhvcNAQkBFhVjYS1zdXBwb3J0QHJlZGhhdC5jb20wHhcNMjQwODE1MDYx
|
||||
+NjQ5WhcNNDQwODE1MDYxNjQ5WjBEMUIwQAYDVQQDDDlSZWQgSGF0IFByb2R1Y3Qg
|
||||
+SUQgW2VjN2EwZDQyLTgzNjItNDg2YS04ZjcyLTc3YThiOWU2MjM0YV0wggIiMA0G
|
||||
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGP0nTjP4TN3LHVTfeQV+0u/Se01LU
|
||||
+FJ66GhksOGzXzKSx6kbuFde0eHYIwV8tmZOMDIv2LVezHKRClVB1dMalQXfcLaoF
|
||||
+AcHmCViz353vzXHynybzMXFs9xbzZMglduBbcStWHy+TmoJsbVwIAAdv4NYyrQQD
|
||||
+LLVuX8mACCFg0YFG8ok5tN0Kt2liHTYpSoEuRI9ke+joNQkU3fsxcOlV5Cr1W2pG
|
||||
+OkosvC4R9dvRjsjnEQ6tHeRhs5oEBZW3eZhnW3Qv8p9jaNU51TlYXLIH0+Fsx0uL
|
||||
+XETzTWP4YmvBwtrGaq+PhRogJHNw8BM/zrNUzUEFBr6WKWRFB6zkfKNnNkOIZi52
|
||||
+deFuqYuj+fRy5ehAFVWOHNFMzHvUSKJqGaLD5TW8aqQeFA3FvXce03WVwCFQIOvH
|
||||
+F4y+sCNh1aliWkjJbc2yw9a3VhQeJ0wFIAngpy0h/3V3IT3dpK2XHAL9CfIWxk6Z
|
||||
+wSwHNUKfP0aZYyXX/pfMFLXINSoHKSXHRMsf7P+wr0D47atkDLWYHIJjBXG9s5mG
|
||||
+eobEC5OghL4DzW/mEKOwKI5JxUH5yKXfRgG7RwfzlFnQgs2Qd0p2sstZbjCOmEra
|
||||
+cGfaDaLf7O1/6dAQPalCpn+uG5bv2NzIJmX2Rep7XA50XQLBqHg3r/cvMhcQQrIQ
|
||||
+nE2pDC01zYhUTwIDAQABo4HiMIHfMAkGA1UdEwQCMAAwOwYLKwYBBAGSCAkBSAEE
|
||||
+LAwqUmVkIEhhdCBFbnRlcnByaXNlIExpbnV4IGZvciBJQk0geiBTeXN0ZW1zMBUG
|
||||
+CysGAQQBkggJAUgCBAYMBDEwLjAwFgYLKwYBBAGSCAkBSAMEBwwFczM5MHgwJgYL
|
||||
+KwYBBAGSCAkBSAQEFwwVcmhlbC0xMCxyaGVsLTEwLXMzOTB4MB0GA1UdDgQWBBRh
|
||||
+6iC1NXyvZ2Q6/2sI5hB40M0flTAfBgNVHSMEGDAWgBSW/bscQED/QIStsh8LJsHD
|
||||
+am/WfDANBgkqhkiG9w0BAQsFAAOCAgEAsj4qPVsDkFrfuVDn8JCJ7tIH5WhaOzL6
|
||||
+3GBsQIKGd8a1WscPfSpr/phNSBPWFyvV2b+0HzblYzBZbx6ExykTDLh5L01nPM0s
|
||||
++hqPxZgF/kcTbLWmAanl32R9+Gs2P2JN1CaCclXgM4USEagBWYeMhJSmQR3bOnSe
|
||||
+Jjm3tjvhnbIQd6xgPpTjrqZ35z1BW0P0qQFdBbB0k+MfPkhYKEr+Vfn0rU8vk4UP
|
||||
+F9sY9HkZLqIBxlXeTUerNZvHSuOy2KgoS4l25/QwUutHnnSGZZpARiU1XYNcynVL
|
||||
+r5COHlb6TYkeRhSAm6RVM4XPYoFgN6cbhY1orwFC2/0i30EnsTMB6ctnLKCf7qgM
|
||||
+GDG2W7ct0m6koA7s2TGmgp33DPw9adX7qgIV0OjLzBYJ1fyVv3sYlOKRuyDz0l+N
|
||||
+u6Rnv1ecNUspWn+5ogBbdgwU6yah6oo/fJIWm62U38UGH5ic+/7sBnga8q5sDI90
|
||||
++h+nlTIAnD0ICzjEDASiLlYft+hQ9pOt/rgEIrPeKTe+fbefUIXJ5h343E51POnY
|
||||
+uZRXcirc33QL/PgBRce1taIXjsRD+FSJM0tx/vf8H9j0rzSAxDoXJNsdq4/32scy
|
||||
+6Zk2fgtm80xxIzju84jXVUrSBRMpWD9I+FZId4IE7tQhwKNi1b7DdNeaQLfaoq8U
|
||||
+1PEea/tQDSA=
|
||||
+-----END CERTIFICATE-----
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,106 +0,0 @@
|
||||
From b96c610bb27ab5f7ef1ad65a1a763ed2d31b6816 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Tue, 17 Feb 2026 10:23:18 +0100
|
||||
Subject: [PATCH 03/44] Enable logrotate.timer during 8to9 IPU
|
||||
|
||||
On el8 logrotate uses cron, on el9 a systemd timer is used. This is not
|
||||
automatically migrated during an IPU, this patch adds a actor that
|
||||
does so.
|
||||
|
||||
Jira: RHEL-17361
|
||||
---
|
||||
.../actors/enablelogrotatetimer/actor.py | 22 +++++++++++++
|
||||
.../libraries/enablelogrotatetimer.py | 13 ++++++++
|
||||
.../tests/test_enablelogrotatetimer.py | 31 +++++++++++++++++++
|
||||
3 files changed, 66 insertions(+)
|
||||
create mode 100644 repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/actor.py
|
||||
create mode 100644 repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/libraries/enablelogrotatetimer.py
|
||||
create mode 100644 repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/tests/test_enablelogrotatetimer.py
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/actor.py b/repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..bc3c7ec3
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/actor.py
|
||||
@@ -0,0 +1,22 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.libraries.actor import enablelogrotatetimer
|
||||
+from leapp.models import SystemdServicesInfoTarget, SystemdServicesTasks
|
||||
+from leapp.tags import FinalizationPhaseTag, IPUWorkflowTag
|
||||
+
|
||||
+
|
||||
+class EnableLogrotateTimer(Actor):
|
||||
+ """
|
||||
+ Enable logrotate.timer on the target system after upgrade
|
||||
+
|
||||
+ The logrotate.timer systemd timer unit replaces the traditional cron-based
|
||||
+ logrotate execution used in RHEL 8. This actor ensures the timer is enabled
|
||||
+ after the in-place upgrade is complete.
|
||||
+ """
|
||||
+
|
||||
+ name = 'enable_logrotate_timer'
|
||||
+ consumes = (SystemdServicesInfoTarget,)
|
||||
+ produces = (SystemdServicesTasks,)
|
||||
+ tags = (FinalizationPhaseTag, IPUWorkflowTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ enablelogrotatetimer.process()
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/libraries/enablelogrotatetimer.py b/repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/libraries/enablelogrotatetimer.py
|
||||
new file mode 100644
|
||||
index 00000000..c9783ae9
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/libraries/enablelogrotatetimer.py
|
||||
@@ -0,0 +1,13 @@
|
||||
+from leapp.libraries.common.systemd import enable_unit
|
||||
+from leapp.libraries.stdlib import api, CalledProcessError
|
||||
+
|
||||
+LOGROTATE_TIMER = 'logrotate.timer'
|
||||
+
|
||||
+
|
||||
+def process():
|
||||
+ try:
|
||||
+ enable_unit(LOGROTATE_TIMER)
|
||||
+ except CalledProcessError as e:
|
||||
+ api.current_logger().error(
|
||||
+ "Failed to enable {}: {}".format(LOGROTATE_TIMER, e)
|
||||
+ )
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/tests/test_enablelogrotatetimer.py b/repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/tests/test_enablelogrotatetimer.py
|
||||
new file mode 100644
|
||||
index 00000000..f366bd6a
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/enablelogrotatetimer/tests/test_enablelogrotatetimer.py
|
||||
@@ -0,0 +1,31 @@
|
||||
+from leapp.libraries.actor import enablelogrotatetimer
|
||||
+from leapp.libraries.common.testutils import logger_mocked
|
||||
+from leapp.libraries.stdlib import api, CalledProcessError
|
||||
+
|
||||
+
|
||||
+def test_success(monkeypatch):
|
||||
+
|
||||
+ def mock_enable_unit(unit):
|
||||
+ assert unit == 'logrotate.timer'
|
||||
+
|
||||
+ monkeypatch.setattr(enablelogrotatetimer, "enable_unit", mock_enable_unit)
|
||||
+ enablelogrotatetimer.process()
|
||||
+
|
||||
+
|
||||
+def test_failed_to_enable(monkeypatch):
|
||||
+
|
||||
+ def mock_enable_unit(unit):
|
||||
+ assert unit == 'logrotate.timer'
|
||||
+ raise CalledProcessError(
|
||||
+ "Failed to enable logrotate.titmer",
|
||||
+ ["systemctl", "enable", "logrotate.timer"],
|
||||
+ {
|
||||
+ "exit_code": 1,
|
||||
+ "stderr": "err",
|
||||
+ },
|
||||
+ )
|
||||
+
|
||||
+ monkeypatch.setattr(enablelogrotatetimer, "enable_unit", mock_enable_unit)
|
||||
+ monkeypatch.setattr(api, "current_logger", logger_mocked())
|
||||
+ enablelogrotatetimer.process()
|
||||
+ assert "Failed to enable logrotate.timer" in api.current_logger.errmsg[0]
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -1,63 +0,0 @@
|
||||
From 0e0db2860587d57193a52135ae88df8917d70538 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Wed, 11 Feb 2026 16:51:41 +0100
|
||||
Subject: [PATCH 04/44] feat(net-naming-scheme): enable by default on CS 9to10
|
||||
|
||||
This was done for RHEL 9to10 in
|
||||
91f37a3913c1608b24c9aa583ac3b13a08aace71.
|
||||
|
||||
Jira: RHEL-148291
|
||||
---
|
||||
.../libraries/emit_net_naming.py | 10 ++++------
|
||||
.../tests/test_emit_net_naming_scheme.py | 9 ++-------
|
||||
2 files changed, 6 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/emit_net_naming_scheme/libraries/emit_net_naming.py b/repos/system_upgrade/common/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
index 7b112ff0..ef2c0b79 100644
|
||||
--- a/repos/system_upgrade/common/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
+++ b/repos/system_upgrade/common/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
@@ -1,5 +1,5 @@
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
-from leapp.libraries.common.config import get_env, get_target_distro_id, version
|
||||
+from leapp.libraries.common.config import get_env, version
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import (
|
||||
KernelCmdline,
|
||||
@@ -49,11 +49,9 @@ def is_net_scheme_compatible_with_current_cmdline():
|
||||
def emit_msgs_to_use_net_naming_schemes():
|
||||
is_feature_enabled = get_env('LEAPP_DISABLE_NET_NAMING_SCHEMES', '0') != '1'
|
||||
|
||||
- is_net_naming_available = version.get_target_major_version() == "9" or (
|
||||
- version.matches_target_version(">= 10.2")
|
||||
- # TODO the net-naming-sysattrs pkg is not yet available on CS10, remove
|
||||
- # this when it becomes
|
||||
- and not get_target_distro_id() == "centos"
|
||||
+ is_net_naming_available = (
|
||||
+ version.get_target_major_version() == "9"
|
||||
+ or version.matches_target_version(">= 10.2")
|
||||
)
|
||||
|
||||
if not (is_feature_enabled and is_net_naming_available):
|
||||
diff --git a/repos/system_upgrade/common/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py b/repos/system_upgrade/common/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py
|
||||
index 9c1f91bb..d8eef404 100644
|
||||
--- a/repos/system_upgrade/common/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py
|
||||
+++ b/repos/system_upgrade/common/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py
|
||||
@@ -95,13 +95,8 @@ def test_emit_msgs_to_use_net_naming_schemes(
|
||||
pkg_name = emit_net_naming_lib.NET_NAMING_SYSATTRS_RPM_NAME[target_major]
|
||||
produced_messages = api.produce.model_instances
|
||||
|
||||
- if (
|
||||
- is_net_scheme_enabled
|
||||
- # the package is available since 10.2
|
||||
- and target_ver != "10.0"
|
||||
- # TODO not yet available in CS 10, remove this when it is
|
||||
- and not (target_distro == "centos" and target_major == "10")
|
||||
- ):
|
||||
+ # the package is available since 10.2
|
||||
+ if is_net_scheme_enabled and target_ver != "10.0":
|
||||
userspace_tasks = ensure_one_msg_of_type_produced(produced_messages, TargetUserSpaceUpgradeTasks)
|
||||
assert userspace_tasks.install_rpms == [pkg_name]
|
||||
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,100 @@
|
||||
From bf302fc794957a88bc4785f4dd2505b8d71012e0 Mon Sep 17 00:00:00 2001
|
||||
From: Evgeni Golov <evgeni@golov.de>
|
||||
Date: Wed, 21 Aug 2024 07:52:02 +0200
|
||||
Subject: [PATCH 04/40] properly scope try/except when loading obsoleted keys
|
||||
|
||||
We want to load all possible keys, even *after* a KeyError happenend
|
||||
|
||||
Fixes: 7e0fb44bb673893d0409903f6a441d0eb2829d22
|
||||
---
|
||||
.../libraries/removeobsoleterpmgpgkeys.py | 8 +--
|
||||
.../tests/test_removeobsoleterpmgpgkeys.py | 50 +++++++++++++++++++
|
||||
2 files changed, 54 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/removeobsoletegpgkeys/libraries/removeobsoleterpmgpgkeys.py b/repos/system_upgrade/common/actors/removeobsoletegpgkeys/libraries/removeobsoleterpmgpgkeys.py
|
||||
index bda7efa3..198c4368 100644
|
||||
--- a/repos/system_upgrade/common/actors/removeobsoletegpgkeys/libraries/removeobsoleterpmgpgkeys.py
|
||||
+++ b/repos/system_upgrade/common/actors/removeobsoletegpgkeys/libraries/removeobsoleterpmgpgkeys.py
|
||||
@@ -12,14 +12,14 @@ def _get_obsolete_keys():
|
||||
distribution = api.current_actor().configuration.os_release.release_id
|
||||
obsoleted_keys_map = get_distribution_data(distribution).get('obsoleted-keys', {})
|
||||
keys = []
|
||||
- try:
|
||||
- for version in range(7, int(get_target_major_version()) + 1):
|
||||
+ for version in range(7, int(get_target_major_version()) + 1):
|
||||
+ try:
|
||||
for key in obsoleted_keys_map[str(version)]:
|
||||
name, version, release = key.rsplit("-", 2)
|
||||
if has_package(InstalledRPM, name, version=version, release=release):
|
||||
keys.append(key)
|
||||
- except KeyError:
|
||||
- pass
|
||||
+ except KeyError:
|
||||
+ pass
|
||||
|
||||
return keys
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/removeobsoletegpgkeys/tests/test_removeobsoleterpmgpgkeys.py b/repos/system_upgrade/common/actors/removeobsoletegpgkeys/tests/test_removeobsoleterpmgpgkeys.py
|
||||
index 4d9a0e84..b78174cc 100644
|
||||
--- a/repos/system_upgrade/common/actors/removeobsoletegpgkeys/tests/test_removeobsoleterpmgpgkeys.py
|
||||
+++ b/repos/system_upgrade/common/actors/removeobsoletegpgkeys/tests/test_removeobsoleterpmgpgkeys.py
|
||||
@@ -76,6 +76,56 @@ def test_get_obsolete_keys(monkeypatch, version, expected):
|
||||
assert set(keys) == set(expected)
|
||||
|
||||
|
||||
+@pytest.mark.parametrize(
|
||||
+ "version, obsoleted_keys, expected",
|
||||
+ [
|
||||
+ (10, None, []),
|
||||
+ (10, {}, []),
|
||||
+ (10, {"8": ["gpg-pubkey-888-abc"], "10": ["gpg-pubkey-10-10"]}, ["gpg-pubkey-888-abc", "gpg-pubkey-10-10"]),
|
||||
+ (9, {"8": ["gpg-pubkey-888-abc"], "9": ["gpg-pubkey-999-def"]}, ["gpg-pubkey-999-def", "gpg-pubkey-888-abc"]),
|
||||
+ (8, {"8": ["gpg-pubkey-888-abc"], "9": ["gpg-pubkey-999-def"]}, ["gpg-pubkey-888-abc"])
|
||||
+ ]
|
||||
+)
|
||||
+def test_get_obsolete_keys_incomplete_data(monkeypatch, version, obsoleted_keys, expected):
|
||||
+ def get_target_major_version_mocked():
|
||||
+ return version
|
||||
+
|
||||
+ def get_distribution_data_mocked(_distro):
|
||||
+ if obsoleted_keys is None:
|
||||
+ return {}
|
||||
+ return {'obsoleted-keys': obsoleted_keys}
|
||||
+
|
||||
+ def has_package_mocked(*args, **kwargs):
|
||||
+ return True
|
||||
+
|
||||
+ monkeypatch.setattr(
|
||||
+ removeobsoleterpmgpgkeys,
|
||||
+ "get_target_major_version",
|
||||
+ get_target_major_version_mocked,
|
||||
+ )
|
||||
+
|
||||
+ monkeypatch.setattr(
|
||||
+ removeobsoleterpmgpgkeys,
|
||||
+ "get_distribution_data",
|
||||
+ get_distribution_data_mocked,
|
||||
+ )
|
||||
+
|
||||
+ monkeypatch.setattr(
|
||||
+ removeobsoleterpmgpgkeys,
|
||||
+ "has_package",
|
||||
+ has_package_mocked,
|
||||
+ )
|
||||
+
|
||||
+ monkeypatch.setattr(
|
||||
+ api,
|
||||
+ "current_actor",
|
||||
+ CurrentActorMocked(),
|
||||
+ )
|
||||
+
|
||||
+ keys = removeobsoleterpmgpgkeys._get_obsolete_keys()
|
||||
+ assert set(keys) == set(expected)
|
||||
+
|
||||
+
|
||||
@pytest.mark.parametrize(
|
||||
"keys, should_register",
|
||||
[
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
From 26e4ca841b23907eda2de78288183285e6b54b1f Mon Sep 17 00:00:00 2001
|
||||
From: karolinku <kkula@redhat.com>
|
||||
Date: Tue, 3 Mar 2026 13:56:26 +0100
|
||||
Subject: [PATCH 05/44] Leapp_resume.service: Silence AVC SELinux warnings
|
||||
|
||||
Wrap the ExecStart command in `/bin/sh -c` to avoid SELinux AVC denials.
|
||||
|
||||
The leapp_resume.service unit is inherently "malformed" from SELinux's
|
||||
perspective: it directly executes /root/tmp_leapp_py3/leapp3, which is
|
||||
labeled admin_home_t. When the system boots in Permissive mode (as it
|
||||
does during the upgrade), SELinux logs AVC denials for this access
|
||||
rather than blocking it. These AVCs are expected but noisy and
|
||||
confusing.
|
||||
|
||||
By invoking the command through /bin/sh -c, the execution context is
|
||||
evaluated against /bin/sh (which carries a proper shell_exec_t label),
|
||||
avoiding the admin_home_t AVC altogether.
|
||||
|
||||
It is also confirmed with SELinux team that this issue could be
|
||||
solved with also following solution (in case of any future issues):
|
||||
```
|
||||
ExecStartPre=chcon -t bin_t /root/tmp_leapp_py3/leapp3
|
||||
ExecStart=/root/tmp_leapp_py3/leapp3 upgrade --resume
|
||||
````
|
||||
|
||||
Jira: RHEL-149141
|
||||
---
|
||||
.../actors/createresumeservice/files/leapp_resume.service | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/createresumeservice/files/leapp_resume.service b/repos/system_upgrade/common/actors/createresumeservice/files/leapp_resume.service
|
||||
index 39ac6112..859237a1 100644
|
||||
--- a/repos/system_upgrade/common/actors/createresumeservice/files/leapp_resume.service
|
||||
+++ b/repos/system_upgrade/common/actors/createresumeservice/files/leapp_resume.service
|
||||
@@ -9,7 +9,7 @@ Wants=network-online.target
|
||||
[Service]
|
||||
Type=oneshot
|
||||
# FIXME: this is temporary workaround for Python3
|
||||
-ExecStart=/root/tmp_leapp_py3/leapp3 upgrade --resume
|
||||
+ExecStart=/bin/sh -c "/root/tmp_leapp_py3/leapp3 upgrade --resume"
|
||||
StandardOutput=journal+console
|
||||
# FIXME: this shouldn't be needed, but Satellite upgrade runs installer, and that's slow
|
||||
TimeoutStartSec=infinity
|
||||
--
|
||||
2.53.0
|
||||
|
||||
283
SOURCES/0005-Update-references-from-master-branch-to-main.patch
Normal file
283
SOURCES/0005-Update-references-from-master-branch-to-main.patch
Normal file
@ -0,0 +1,283 @@
|
||||
From 9d49f4675c2b7b18ba7b344bb0032a5538782560 Mon Sep 17 00:00:00 2001
|
||||
From: Vojtech Sokol <vsokol@redhat.com>
|
||||
Date: Mon, 2 Sep 2024 17:21:36 +0200
|
||||
Subject: [PATCH 05/40] Update references from master branch to main
|
||||
|
||||
Focus was on making the CI and GitHub actions work after the default
|
||||
branch was switched from master to main.
|
||||
|
||||
See: OAMG-4907
|
||||
---
|
||||
.github/workflows/codespell.yml | 4 ++--
|
||||
.github/workflows/differential-shellcheck.yml | 4 ++--
|
||||
.github/workflows/pr-welcome-msg.yml | 2 +-
|
||||
.github/workflows/tmt-tests.yml | 16 ++++++++--------
|
||||
.github/workflows/unit-tests.yml | 12 ++++++------
|
||||
.packit.yaml | 10 +++++-----
|
||||
Makefile | 14 +++++++-------
|
||||
7 files changed, 31 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
|
||||
index 673cef17..1195d8d1 100644
|
||||
--- a/.github/workflows/codespell.yml
|
||||
+++ b/.github/workflows/codespell.yml
|
||||
@@ -3,10 +3,10 @@ name: Codespell
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- - master
|
||||
+ - main
|
||||
pull_request:
|
||||
branches:
|
||||
- - master
|
||||
+ - main
|
||||
|
||||
jobs:
|
||||
codespell:
|
||||
diff --git a/.github/workflows/differential-shellcheck.yml b/.github/workflows/differential-shellcheck.yml
|
||||
index f1ed5f6a..e1bafb93 100644
|
||||
--- a/.github/workflows/differential-shellcheck.yml
|
||||
+++ b/.github/workflows/differential-shellcheck.yml
|
||||
@@ -4,7 +4,7 @@
|
||||
name: Differential ShellCheck
|
||||
on:
|
||||
pull_request:
|
||||
- branches: [master]
|
||||
+ branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
security-events: write
|
||||
pull-requests: write
|
||||
|
||||
- steps:
|
||||
+ steps:
|
||||
- name: Repository checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
diff --git a/.github/workflows/pr-welcome-msg.yml b/.github/workflows/pr-welcome-msg.yml
|
||||
index ff9414d2..0102c41f 100644
|
||||
--- a/.github/workflows/pr-welcome-msg.yml
|
||||
+++ b/.github/workflows/pr-welcome-msg.yml
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
However, here are additional useful commands for packit:
|
||||
- **`/packit test`** to re-run manually the default tests
|
||||
- **`/packit retest-failed`** to re-run failed tests manually
|
||||
- - **`/packit test oamg/leapp#42`** to run tests with leapp builds for the leapp PR#42 (default is latest upstream - master - build)
|
||||
+ - **`/packit test oamg/leapp#42`** to run tests with leapp builds for the leapp PR#42 (default is latest upstream - main - build)
|
||||
|
||||
Note that first time contributors cannot run tests automatically - they need to be started by a reviewer.
|
||||
|
||||
diff --git a/.github/workflows/tmt-tests.yml b/.github/workflows/tmt-tests.yml
|
||||
index 7e9fd706..1fa00e60 100644
|
||||
--- a/.github/workflows/tmt-tests.yml
|
||||
+++ b/.github/workflows/tmt-tests.yml
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
|
||||
call_workflow_tests_79to88_integration:
|
||||
needs: call_workflow_copr_build
|
||||
- uses: oamg/leapp/.github/workflows/reuse-tests-7to8.yml@master
|
||||
+ uses: oamg/leapp/.github/workflows/reuse-tests-7to8.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
copr_artifacts: ${{ needs.call_workflow_copr_build.outputs.artifacts }}
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
|
||||
call_workflow_tests_79to86_integration:
|
||||
needs: call_workflow_copr_build
|
||||
- uses: oamg/leapp/.github/workflows/reuse-tests-7to8.yml@master
|
||||
+ uses: oamg/leapp/.github/workflows/reuse-tests-7to8.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
copr_artifacts: ${{ needs.call_workflow_copr_build.outputs.artifacts }}
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
|
||||
call_workflow_tests_79to88_sst:
|
||||
needs: call_workflow_copr_build
|
||||
- uses: oamg/leapp/.github/workflows/reuse-tests-7to8.yml@master
|
||||
+ uses: oamg/leapp/.github/workflows/reuse-tests-7to8.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
copr_artifacts: ${{ needs.call_workflow_copr_build.outputs.artifacts }}
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
|
||||
call_workflow_tests_7to8_aws:
|
||||
needs: call_workflow_copr_build
|
||||
- uses: oamg/leapp/.github/workflows/reuse-tests-7to8.yml@master
|
||||
+ uses: oamg/leapp/.github/workflows/reuse-tests-7to8.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
copr_artifacts: ${{ needs.call_workflow_copr_build.outputs.artifacts }}
|
||||
@@ -71,7 +71,7 @@ jobs:
|
||||
|
||||
call_workflow_tests_86to90_integration:
|
||||
needs: call_workflow_copr_build
|
||||
- uses: oamg/leapp/.github/workflows/reuse-tests-8to9.yml@master
|
||||
+ uses: oamg/leapp/.github/workflows/reuse-tests-8to9.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
copr_artifacts: ${{ needs.call_workflow_copr_build.outputs.artifacts }}
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
|
||||
call_workflow_tests_88to92_integration:
|
||||
needs: call_workflow_copr_build
|
||||
- uses: oamg/leapp/.github/workflows/reuse-tests-8to9.yml@master
|
||||
+ uses: oamg/leapp/.github/workflows/reuse-tests-8to9.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
copr_artifacts: ${{ needs.call_workflow_copr_build.outputs.artifacts }}
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
|
||||
call_workflow_tests_86to90_sst:
|
||||
needs: call_workflow_copr_build
|
||||
- uses: oamg/leapp/.github/workflows/reuse-tests-8to9.yml@master
|
||||
+ uses: oamg/leapp/.github/workflows/reuse-tests-8to9.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
copr_artifacts: ${{ needs.call_workflow_copr_build.outputs.artifacts }}
|
||||
@@ -116,7 +116,7 @@ jobs:
|
||||
|
||||
call_workflow_tests_86to90_aws:
|
||||
needs: call_workflow_copr_build
|
||||
- uses: oamg/leapp/.github/workflows/reuse-tests-8to9.yml@master
|
||||
+ uses: oamg/leapp/.github/workflows/reuse-tests-8to9.yml@main
|
||||
secrets: inherit
|
||||
with:
|
||||
copr_artifacts: ${{ needs.call_workflow_copr_build.outputs.artifacts }}
|
||||
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
|
||||
index 2a05106e..42b72b8d 100644
|
||||
--- a/.github/workflows/unit-tests.yml
|
||||
+++ b/.github/workflows/unit-tests.yml
|
||||
@@ -2,10 +2,10 @@ name: Unit Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- - master
|
||||
+ - main
|
||||
pull_request:
|
||||
branches:
|
||||
- - master
|
||||
+ - main
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@@ -74,10 +74,10 @@ jobs:
|
||||
# NOTE(ivasilev) fetch-depth 0 is critical here as leapp deps discovery depends on specific substring in
|
||||
# commit message and default 1 option will get us just merge commit which has an unrelevant message.
|
||||
fetch-depth: '0'
|
||||
- # NOTE(ivasilev) master -> origin/master is used for leapp deps discovery in Makefile via git log master..HEAD
|
||||
- - name: Set master to origin/master
|
||||
- if: github.ref != 'refs/heads/master'
|
||||
+ # NOTE(ivasilev) main -> origin/main is used for leapp deps discovery in Makefile via git log main..HEAD
|
||||
+ - name: Set main to origin/main
|
||||
+ if: github.ref != 'refs/heads/main'
|
||||
run: |
|
||||
- git branch -f master origin/master
|
||||
+ git branch -f main origin/main
|
||||
- name: ${{matrix.scenarios.name}}
|
||||
run: script -e -c /bin/bash -c 'TERM=xterm podman build --security-opt=seccomp=unconfined -t leapp-tests -f utils/container-tests/Containerfile.${{matrix.scenarios.container}} utils/container-tests && PYTHON_VENV=${{matrix.scenarios.python}} REPOSITORIES=${{matrix.scenarios.repos}} podman run --security-opt=seccomp=unconfined --rm -ti -v ${PWD}:/payload --env=PYTHON_VENV --env=REPOSITORIES leapp-tests'
|
||||
diff --git a/.packit.yaml b/.packit.yaml
|
||||
index d91a47e5..fbfd0eea 100644
|
||||
--- a/.packit.yaml
|
||||
+++ b/.packit.yaml
|
||||
@@ -22,7 +22,7 @@ actions:
|
||||
fix-spec-file:
|
||||
- bash -c "sed -i -r \"0,/Release:/ s/Release:(\s*)\S*/Release:\1${PACKIT_RPMSPEC_RELEASE}%{?dist}/\" packaging/leapp-repository.spec"
|
||||
post-upstream-clone:
|
||||
- # builds from PRs should have lower NVR than those from master branch
|
||||
+ # builds from PRs should have lower NVR than those from main branch
|
||||
- bash -c "sed -i \"s/1%{?dist}/0%{?dist}/g\" packaging/leapp-repository.spec"
|
||||
|
||||
jobs:
|
||||
@@ -44,12 +44,12 @@ jobs:
|
||||
fix-spec-file:
|
||||
- bash -c "sed -i -r \"0,/Release:/ s/Release:(\s*)\S*/Release:\1${PACKIT_RPMSPEC_RELEASE}%{?dist}/\" packaging/leapp-repository.spec"
|
||||
post-upstream-clone:
|
||||
- # builds from PRs should have lower NVR than those from master branch
|
||||
+ # builds from PRs should have lower NVR than those from main branch
|
||||
- bash -c "sed -i \"s/1%{?dist}/0%{?dist}/g\" packaging/leapp-repository.spec"
|
||||
- job: copr_build
|
||||
trigger: commit
|
||||
metadata:
|
||||
- branch: master
|
||||
+ branch: main
|
||||
owner: "@oamg"
|
||||
project: leapp
|
||||
targets:
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
fix-spec-file:
|
||||
- bash -c "sed -i -r \"0,/Release:/ s/Release:(\s*)\S*/Release:\1${PACKIT_RPMSPEC_RELEASE}%{?dist}/\" packaging/leapp-repository.spec"
|
||||
post-upstream-clone:
|
||||
- # builds from master branch should start with 100 release, to have high priority
|
||||
+ # builds from main branch should start with 100 release, to have high priority
|
||||
- bash -c "sed -i \"s/1%{?dist}/100%{?dist}/g\" packaging/leapp-repository.spec"
|
||||
- job: copr_build
|
||||
trigger: release
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
fix-spec-file:
|
||||
- bash -c "sed -i -r \"0,/Release:/ s/Release:(\s*)\S*/Release:\1${PACKIT_RPMSPEC_RELEASE}%{?dist}/\" packaging/leapp-repository.spec"
|
||||
post-upstream-clone:
|
||||
- # builds from master branch should start with 100 release, to have high priority
|
||||
+ # builds from main branch should start with 100 release, to have high priority
|
||||
- bash -c "sed -i \"s/1%{?dist}/100%{?dist}/g\" packaging/leapp-repository.spec"
|
||||
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 5b2bc4d2..8aeef77d 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -64,7 +64,7 @@ endif
|
||||
|
||||
# just to reduce number of unwanted builds mark as the upstream one when
|
||||
# someone will call copr_build without additional parameters
|
||||
-MASTER_BRANCH=master
|
||||
+MASTER_BRANCH=main
|
||||
|
||||
# In case the PR or MR is defined or in case build is not coming from the
|
||||
# MATER_BRANCH branch, N_REL=0; (so build is not update of the approved
|
||||
@@ -76,10 +76,10 @@ SHORT_SHA=`git rev-parse --short HEAD`
|
||||
BRANCH=`git rev-parse --abbrev-ref HEAD | tr -- '-/' '_'`
|
||||
|
||||
# The dependent framework PR connection will be taken from the top commit's depends-on message.
|
||||
-REQ_LEAPP_PR=$(shell git log master..HEAD | grep -m1 -iE '^[[:space:]]*Depends-On:[[:space:]]*.*[[:digit:]]+[[:space:]]*$$' | grep -Eo '*[[:digit:]]*')
|
||||
+REQ_LEAPP_PR=$(shell git log main..HEAD | grep -m1 -iE '^[[:space:]]*Depends-On:[[:space:]]*.*[[:digit:]]+[[:space:]]*$$' | grep -Eo '*[[:digit:]]*')
|
||||
# NOTE(ivasilev) In case of travis relying on top commit is a no go as a top commit will be a merge commit.
|
||||
ifdef CI
|
||||
- REQ_LEAPP_PR=$(shell git log master..HEAD | grep -m1 -iE '^[[:space:]]*Depends-On:[[:space:]]*.*[[:digit:]]+[[:space:]]*$$' | grep -Eo '[[:digit:]]*')
|
||||
+ REQ_LEAPP_PR=$(shell git log main..HEAD | grep -m1 -iE '^[[:space:]]*Depends-On:[[:space:]]*.*[[:digit:]]+[[:space:]]*$$' | grep -Eo '[[:digit:]]*')
|
||||
endif
|
||||
|
||||
# In case anyone would like to add any other suffix, just make it possible
|
||||
@@ -92,8 +92,8 @@ REQUEST=`if test -n "$$PR"; then echo ".PR$${PR}"; elif test -n "$$MR"; then ech
|
||||
# Examples:
|
||||
# 0.201810080027Z.4078402.packaging.PR2
|
||||
# 0.201810080027Z.4078402.packaging
|
||||
-# 0.201810080027Z.4078402.master.MR2
|
||||
-# 1.201810080027Z.4078402.master
|
||||
+# 0.201810080027Z.4078402.main.MR2
|
||||
+# 1.201810080027Z.4078402.main
|
||||
RELEASE="$(N_REL).$(TIMESTAMP).$(SHORT_SHA).$(BRANCH)$(REQUEST)$(_SUFFIX)"
|
||||
|
||||
all: help
|
||||
@@ -302,7 +302,7 @@ install-deps:
|
||||
pip install --upgrade setuptools; \
|
||||
pip install --upgrade -r requirements.txt; \
|
||||
./utils/install_commands.sh $(_PYTHON_VENV); \
|
||||
- # In case the top commit Depends-On some yet unmerged framework patch - override master leapp with the proper version
|
||||
+ # In case the top commit Depends-On some yet unmerged framework patch - override main leapp with the proper version
|
||||
if [[ ! -z "$(REQ_LEAPP_PR)" ]] ; then \
|
||||
echo "Leapp-repository depends on the yet unmerged pr of the framework #$(REQ_LEAPP_PR), installing it.." && \
|
||||
$(VENVNAME)/bin/pip install -I "git+https://github.com/oamg/leapp.git@refs/pull/$(REQ_LEAPP_PR)/head"; \
|
||||
@@ -332,7 +332,7 @@ install-deps-fedora:
|
||||
pip install --upgrade setuptools; \
|
||||
pip install --upgrade -r requirements.txt; \
|
||||
./utils/install_commands.sh $(_PYTHON_VENV); \
|
||||
- # In case the top commit Depends-On some yet unmerged framework patch - override master leapp with the proper version
|
||||
+ # In case the top commit Depends-On some yet unmerged framework patch - override main leapp with the proper version
|
||||
if [[ ! -z "$(REQ_LEAPP_PR)" ]] ; then \
|
||||
echo "Leapp-repository depends on the yet unmerged pr of the framework #$(REQ_LEAPP_PR), installing it.." && \
|
||||
$(VENVNAME)/bin/pip install -I "git+https://github.com/oamg/leapp.git@refs/pull/$(REQ_LEAPP_PR)/head"; \
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,138 +0,0 @@
|
||||
From 9827568a1e8caeb3e96c0c40a3d7a741997391c6 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Tue, 17 Feb 2026 16:56:43 +0100
|
||||
Subject: [PATCH 06/44] Add API to get a distro "report" name
|
||||
|
||||
Add a global variable DISTRO_REPORT_NAMES which can be directly be used
|
||||
in format_map() or unpacked into format() calls.
|
||||
There are also source and target fields which can be used in e.g.
|
||||
fstrings.
|
||||
|
||||
Jira: RHEL-130948
|
||||
---
|
||||
.../system_upgrade/common/libraries/distro.py | 72 ++++++++++++++++++-
|
||||
.../common/libraries/tests/test_distro.py | 19 +++++
|
||||
2 files changed, 90 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/libraries/distro.py b/repos/system_upgrade/common/libraries/distro.py
|
||||
index 34c48a57..1a5e3923 100644
|
||||
--- a/repos/system_upgrade/common/libraries/distro.py
|
||||
+++ b/repos/system_upgrade/common/libraries/distro.py
|
||||
@@ -1,9 +1,10 @@
|
||||
import json
|
||||
import os
|
||||
+from collections.abc import Mapping
|
||||
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries.common import efi, repofileutils, rhsm
|
||||
-from leapp.libraries.common.config import get_target_distro_id
|
||||
+from leapp.libraries.common.config import get_source_distro_id, get_target_distro_id
|
||||
from leapp.libraries.common.config.architecture import ARCH_ACCEPTED, ARCH_X86_64
|
||||
from leapp.libraries.common.config.version import get_target_major_version
|
||||
from leapp.libraries.stdlib import api
|
||||
@@ -234,6 +235,75 @@ def distro_id_to_pretty_name(distro_id):
|
||||
}[distro_id]
|
||||
|
||||
|
||||
+def _distro_id_to_report_name(distro_id):
|
||||
+ """
|
||||
+ Get the display name for the given distro id.
|
||||
+
|
||||
+ The display name should be used for user facing text, such as in reports.
|
||||
+ For a real/full name see the :func:`distro_id_to_pretty_name` function.
|
||||
+ """
|
||||
+ return {
|
||||
+ "rhel": "RHEL",
|
||||
+ "centos": "CentOS Stream",
|
||||
+ "almalinux": "AlmaLinux"
|
||||
+ }[distro_id]
|
||||
+
|
||||
+
|
||||
+class _DistroReportNames(Mapping):
|
||||
+ """
|
||||
+ A mapping of distro names to be used in reports.
|
||||
+
|
||||
+ In addition to the properties :attr:`source` and :attr:`target`, this class
|
||||
+ can be used in :func:`format_map()` or unpacked to :func:`format` where it
|
||||
+ exposes them as 'source_distro' and 'target_distro'.
|
||||
+ """
|
||||
+
|
||||
+ @property
|
||||
+ def source(self) -> str:
|
||||
+ """
|
||||
+ The source distro report name.
|
||||
+
|
||||
+ :type: str
|
||||
+ """
|
||||
+ return _distro_id_to_report_name(get_source_distro_id())
|
||||
+
|
||||
+ @property
|
||||
+ def target(self) -> str:
|
||||
+ """
|
||||
+ The target distro report name.
|
||||
+
|
||||
+ :type: str
|
||||
+ """
|
||||
+ return _distro_id_to_report_name(get_target_distro_id())
|
||||
+
|
||||
+ def __getitem__(self, key):
|
||||
+ if key == 'source_distro':
|
||||
+ return self.source
|
||||
+
|
||||
+ if key == 'target_distro':
|
||||
+ return self.target
|
||||
+
|
||||
+ raise KeyError(f"Key '{key}' not found in {self.__class__.__name__}")
|
||||
+
|
||||
+ def __len__(self):
|
||||
+ return 2
|
||||
+
|
||||
+ def __iter__(self):
|
||||
+ yield from ['source_distro', 'target_distro']
|
||||
+
|
||||
+
|
||||
+DISTRO_REPORT_NAMES = _DistroReportNames()
|
||||
+"""
|
||||
+A mapping of distro "display" names for use in reports.
|
||||
+
|
||||
+Can be used as argument for format_map() or unpacked in format() calls.
|
||||
+The format string placeholders 'source_distro' and 'target_distro' are then
|
||||
+replaced by the respective distro names or abbreviations of them.
|
||||
+
|
||||
+See :class:`_DistroReportNames`.
|
||||
+"""
|
||||
+
|
||||
+
|
||||
def get_distro_efidir_canon_path(distro_id):
|
||||
"""
|
||||
Get canonical path to the distro EFI directory in the EFI mountpoint.
|
||||
diff --git a/repos/system_upgrade/common/libraries/tests/test_distro.py b/repos/system_upgrade/common/libraries/tests/test_distro.py
|
||||
index ec7d8f77..d266a9c6 100644
|
||||
--- a/repos/system_upgrade/common/libraries/tests/test_distro.py
|
||||
+++ b/repos/system_upgrade/common/libraries/tests/test_distro.py
|
||||
@@ -235,3 +235,22 @@ def test_get_distro_repoids_invalid_repo(monkeypatch):
|
||||
)
|
||||
def test__get_distro_efidir_canon_path(distro, expect):
|
||||
assert expect == distrolib.get_distro_efidir_canon_path(distro)
|
||||
+
|
||||
+
|
||||
+def test_distro_report_names(monkeypatch):
|
||||
+ current_actor = CurrentActorMocked(src_distro="centos", dst_distro="rhel")
|
||||
+ monkeypatch.setattr(api, "current_actor", current_actor)
|
||||
+
|
||||
+ assert distrolib.DISTRO_REPORT_NAMES.source == "CentOS Stream"
|
||||
+ assert distrolib.DISTRO_REPORT_NAMES.target == "RHEL"
|
||||
+
|
||||
+ expect = "CentOS Stream is upstream for RHEL"
|
||||
+ template = "{source_distro} is upstream for {target_distro}"
|
||||
+ assert expect == template.format_map(distrolib.DISTRO_REPORT_NAMES)
|
||||
+ assert expect == template.format(**distrolib.DISTRO_REPORT_NAMES)
|
||||
+
|
||||
+ template = "{source_distro} is {what} for {target_distro}"
|
||||
+ assert expect == template.format(what='upstream', **distrolib.DISTRO_REPORT_NAMES)
|
||||
+
|
||||
+ template = "{source_distro} is {what} for RHEL"
|
||||
+ assert expect == template.format(what='upstream', **distrolib.DISTRO_REPORT_NAMES)
|
||||
--
|
||||
2.53.0
|
||||
|
||||
43
SOURCES/0006-ReadOfKernelArgsError-fix-the-error.patch
Normal file
43
SOURCES/0006-ReadOfKernelArgsError-fix-the-error.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 41e32e3aa6394b8397bef9b797892d9fa119d608 Mon Sep 17 00:00:00 2001
|
||||
From: Yuriy Kohut <yura.kohut@gmail.com>
|
||||
Date: Thu, 29 Aug 2024 12:36:23 +0300
|
||||
Subject: [PATCH 06/40] ReadOfKernelArgsError: fix the error: - AttributeError:
|
||||
module 'leapp.reporting' has no attribute 'Hints'
|
||||
|
||||
---
|
||||
.../kernelcmdlineconfig/libraries/kernelcmdlineconfig.py | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py b/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py
|
||||
index 238a8aa6..6b261c3b 100644
|
||||
--- a/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py
|
||||
@@ -175,14 +175,14 @@ def entrypoint(configs=None):
|
||||
api.current_logger().error(str(e))
|
||||
|
||||
if use_cmdline_file():
|
||||
- report_hint = reporting.Hints(
|
||||
+ report_hint = (
|
||||
'After the system has been rebooted into the new version of RHEL, you'
|
||||
' should take the kernel cmdline arguments from /proc/cmdline (Everything'
|
||||
' except the BOOT_IMAGE entry and initrd entries) and copy them into'
|
||||
' /etc/kernel/cmdline before installing any new kernels.'
|
||||
)
|
||||
else:
|
||||
- report_hint = reporting.Hints(
|
||||
+ report_hint = (
|
||||
'After the system has been rebooted into the new version of RHEL, you'
|
||||
' should take the kernel cmdline arguments from /proc/cmdline (Everything'
|
||||
' except the BOOT_IMAGE entry and initrd entries) and then use the'
|
||||
@@ -204,7 +204,7 @@ def entrypoint(configs=None):
|
||||
' not able to set the arguments as the default for kernels installed in'
|
||||
' the future.'
|
||||
),
|
||||
- report_hint,
|
||||
+ reporting.Remediation(hint=report_hint),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups([
|
||||
reporting.Groups.BOOT,
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,190 +0,0 @@
|
||||
From d6e4afe5c51ac8809649ca395e2ffafc5ab76922 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Wed, 4 Mar 2026 22:45:18 +0100
|
||||
Subject: [PATCH 07/44] livemode: copy upgrade kernel's hmac into /boot
|
||||
|
||||
Copying kernel's HMAC is necessary in order to boot with FIPS mode
|
||||
enabled. Standard (old) upgrade process copies the kernel HMAC file
|
||||
already, livemode did not in order to keep the initial implementation
|
||||
simple. This change adds copying of kernel HMAC also for livemode.
|
||||
|
||||
Jira-ref: RHEL-129571
|
||||
---
|
||||
.../libraries/upgradeinitramfsgenerator.py | 50 +++++++----
|
||||
.../unit_test_upgradeinitramfsgenerator.py | 84 ++++++++++++++++++-
|
||||
2 files changed, 118 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py
|
||||
index 03447b7c..1a0dccd8 100644
|
||||
--- a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py
|
||||
+++ b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py
|
||||
@@ -480,6 +480,16 @@ def prepare_boot_files_for_livemode(context):
|
||||
|
||||
copy_target_kernel_from_userspace_into_boot(context, target_kernel_ver, kernel_artifact_name)
|
||||
|
||||
+ uspace_kernel_hmac_path = context.full_path('/lib/modules/{}/.vmlinuz.hmac'.format(target_kernel_ver))
|
||||
+ upgrade_kernel_hmac_dest = '/boot/.{}.hmac'.format(kernel_artifact_name)
|
||||
+ create_upgrade_hmac_from_target_hmac(uspace_kernel_hmac_path, upgrade_kernel_hmac_dest, kernel_artifact_name)
|
||||
+ api.current_logger().info(
|
||||
+ 'Written hmac ({0}) for the upgrade kernel (based on {1})'.format(
|
||||
+ upgrade_kernel_hmac_dest,
|
||||
+ uspace_kernel_hmac_path
|
||||
+ )
|
||||
+ )
|
||||
+
|
||||
USERSPACE_ARTIFACTS_PATH = '/artifacts'
|
||||
context.makedirs(USERSPACE_ARTIFACTS_PATH, exists_ok=True)
|
||||
userspace_initramfs_dest = os.path.join(USERSPACE_ARTIFACTS_PATH, initramfs_artifact_name)
|
||||
@@ -493,25 +503,35 @@ def prepare_boot_files_for_livemode(context):
|
||||
|
||||
return BootContent(kernel_path=host_kernel_dest,
|
||||
initram_path=host_initramfs_dest,
|
||||
- kernel_hmac_path='')
|
||||
+ kernel_hmac_path=upgrade_kernel_hmac_dest)
|
||||
+
|
||||
+
|
||||
+def _read_file(path):
|
||||
+ with open(path) as in_file:
|
||||
+ return in_file.read()
|
||||
+
|
||||
+
|
||||
+def _write_file(path, data):
|
||||
+ with open(path, 'w') as out_file:
|
||||
+ out_file.write(data)
|
||||
|
||||
|
||||
-def create_upgrade_hmac_from_target_hmac(original_hmac_path, upgrade_hmac_path, upgrade_kernel):
|
||||
+def create_upgrade_hmac_from_target_hmac(original_hmac_path: str, upgrade_hmac_path: str, upgrade_kernel: str):
|
||||
# Rename the kernel name stored in the HMAC file as the upgrade kernel is named differently and the HMAC file
|
||||
# refers to the real target kernel
|
||||
- with open(original_hmac_path) as original_hmac_file:
|
||||
- hmac_file_lines = [line for line in original_hmac_file.read().split('\n') if line]
|
||||
- if len(hmac_file_lines) > 1:
|
||||
- details = ('Expected the target kernel HMAC file to containing only one HMAC line, '
|
||||
- 'found {0}'.format(len(hmac_file_lines)))
|
||||
- raise StopActorExecutionError('Failed to prepare HMAC file for upgrade kernel.',
|
||||
- details={'details': details})
|
||||
-
|
||||
- # Keep only non-empty strings after splitting on space
|
||||
- hmac, dummy_target_kernel_name = [fragment for fragment in hmac_file_lines[0].split(' ') if fragment]
|
||||
-
|
||||
- with open(upgrade_hmac_path, 'w') as upgrade_kernel_hmac_file:
|
||||
- upgrade_kernel_hmac_file.write('{hmac} {kernel}\n'.format(hmac=hmac, kernel=upgrade_kernel))
|
||||
+ original_hmac_file_content = _read_file(original_hmac_path)
|
||||
+ hmac_file_lines = [line for line in original_hmac_file_content.split('\n') if line]
|
||||
+ if len(hmac_file_lines) > 1:
|
||||
+ details = ('Expected the target kernel HMAC file to containing only one HMAC line, '
|
||||
+ 'found {0}'.format(len(hmac_file_lines)))
|
||||
+ raise StopActorExecutionError('Failed to prepare HMAC file for upgrade kernel.',
|
||||
+ details={'details': details})
|
||||
+
|
||||
+ # Keep only non-empty strings after splitting on space
|
||||
+ hmac, dummy_target_kernel_name = [fragment for fragment in hmac_file_lines[0].split(' ') if fragment]
|
||||
+
|
||||
+ upgrade_hmac_content = '{hmac} {kernel}\n'.format(hmac=hmac, kernel=upgrade_kernel)
|
||||
+ _write_file(upgrade_hmac_path, upgrade_hmac_content)
|
||||
|
||||
|
||||
def copy_boot_files(context):
|
||||
diff --git a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py
|
||||
index b96bf79f..165a4df0 100644
|
||||
--- a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py
|
||||
+++ b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py
|
||||
@@ -116,7 +116,7 @@ class MockedContext:
|
||||
self.called_copy_to.append((src, dst))
|
||||
self.content.add(dst)
|
||||
|
||||
- def makedirs(self, path):
|
||||
+ def makedirs(self, path, exists_ok=True):
|
||||
self.called_makedirs.append(path)
|
||||
|
||||
def remove_tree(self, path):
|
||||
@@ -402,3 +402,85 @@ def test_copy_modules_duplicate_skip(monkeypatch, kind):
|
||||
assert context.content
|
||||
assert len(context.called_copy_to) == 1
|
||||
assert debugmsg in upgradeinitramfsgenerator.api.current_logger.dbgmsg
|
||||
+
|
||||
+
|
||||
+def test_create_upgrade_hmac_from_target_hmac(monkeypatch):
|
||||
+ upgrade_hmac_written = False
|
||||
+
|
||||
+ def _read_file_mock(path):
|
||||
+ assert path == '/original-hmac'
|
||||
+ return ('ff00a9674033eea61bec48d21a1d2c27eaac9bd6ed4997e31dd0d9307c7a4770eb81df7116c'
|
||||
+ '4ace25d354a06dfdcd75e38f504f2ea7c1c4bdc95ea7083b701c0 vmlinuz-6.12.0-55.9.1.el10_0.x86_64')
|
||||
+
|
||||
+ def _write_file_mock(path, content):
|
||||
+ assert path == '/boot/.vmlinuz-upgrade.x86_64.hmac'
|
||||
+ expected_content = ('ff00a9674033eea61bec48d21a1d2c27eaac9bd6ed4997e31dd0d9307c7a4770eb81df7116c'
|
||||
+ '4ace25d354a06dfdcd75e38f504f2ea7c1c4bdc95ea7083b701c0 '
|
||||
+ 'vmlinuz-upgrade.x86_64\n')
|
||||
+ assert content == expected_content
|
||||
+ nonlocal upgrade_hmac_written
|
||||
+ upgrade_hmac_written = True
|
||||
+
|
||||
+ monkeypatch.setattr(upgradeinitramfsgenerator, '_read_file', _read_file_mock)
|
||||
+ monkeypatch.setattr(upgradeinitramfsgenerator, '_write_file', _write_file_mock)
|
||||
+ upgradeinitramfsgenerator.create_upgrade_hmac_from_target_hmac(
|
||||
+ '/original-hmac', '/boot/.vmlinuz-upgrade.x86_64.hmac', 'vmlinuz-upgrade.x86_64')
|
||||
+
|
||||
+ assert upgrade_hmac_written
|
||||
+
|
||||
+
|
||||
+def test_prepare_boot_files_for_livemode(monkeypatch):
|
||||
+ context_mock = MockedContext()
|
||||
+
|
||||
+ monkeypatch.setattr(upgradeinitramfsgenerator,
|
||||
+ '_get_target_kernel_version',
|
||||
+ lambda ctx: '6.18.3-100.fc42.x86_64')
|
||||
+
|
||||
+ monkeypatch.setattr(upgradeinitramfsgenerator,
|
||||
+ 'get_boot_artifact_names',
|
||||
+ lambda: ('vmlinuz-upgrade.x86_64', 'initramfs-upgrade.x86_64.img'))
|
||||
+
|
||||
+ upgrade_kernel_present = False
|
||||
+ initramfs_generated = False
|
||||
+ upgrade_initramfs_present = False
|
||||
+ upgrade_kernel_hmac_present = False
|
||||
+
|
||||
+ def copy_target_kernel_mock(context, target_kernel_ver, kernel_artifact_name):
|
||||
+ nonlocal upgrade_kernel_present
|
||||
+ upgrade_kernel_present = True
|
||||
+
|
||||
+ def _generate_initramfs_mock(context, userspace_initramfs_dest, target_kernel_ver):
|
||||
+ nonlocal initramfs_generated
|
||||
+ initramfs_generated = True
|
||||
+
|
||||
+ def create_upgrade_hmac_from_target_hmac_mock(uspace_kernel_hmac_path,
|
||||
+ upgrade_kernel_hmac_dest,
|
||||
+ kernel_artifact_name):
|
||||
+ assert upgrade_kernel_hmac_dest == '/boot/.vmlinuz-upgrade.x86_64.hmac'
|
||||
+ nonlocal upgrade_kernel_hmac_present
|
||||
+ upgrade_kernel_hmac_present = True
|
||||
+
|
||||
+ monkeypatch.setattr(upgradeinitramfsgenerator,
|
||||
+ 'copy_target_kernel_from_userspace_into_boot',
|
||||
+ copy_target_kernel_mock)
|
||||
+
|
||||
+ monkeypatch.setattr(upgradeinitramfsgenerator,
|
||||
+ 'create_upgrade_hmac_from_target_hmac',
|
||||
+ create_upgrade_hmac_from_target_hmac_mock)
|
||||
+
|
||||
+ monkeypatch.setattr(upgradeinitramfsgenerator,
|
||||
+ '_generate_livemode_initramfs',
|
||||
+ _generate_initramfs_mock)
|
||||
+
|
||||
+ boot_content = upgradeinitramfsgenerator.prepare_boot_files_for_livemode(context_mock)
|
||||
+
|
||||
+ upgrade_initramfs_present = context_mock.called_copy_from[0][1] == '/boot/initramfs-upgrade.x86_64.img'
|
||||
+
|
||||
+ assert upgrade_kernel_present
|
||||
+ assert initramfs_generated
|
||||
+ assert upgrade_initramfs_present
|
||||
+ assert upgrade_kernel_hmac_present
|
||||
+
|
||||
+ assert boot_content.kernel_path == '/boot/vmlinuz-upgrade.x86_64'
|
||||
+ assert boot_content.initram_path == '/boot/initramfs-upgrade.x86_64.img'
|
||||
+ assert boot_content.kernel_hmac_path == '/boot/.vmlinuz-upgrade.x86_64.hmac'
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
From 88e13fb0545e0d42df2777538a0c6921bab91e33 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Fri, 27 Sep 2024 14:53:01 +0200
|
||||
Subject: [PATCH 07/40] pylint: exclude rule: too-many-positional-arguments
|
||||
(code: R0917)
|
||||
|
||||
New version of Pylint have the rule for checking of positional
|
||||
arguments - complaining when more than 4 positional arguments exists.
|
||||
We do not want to refactor the code to make it happy and the default
|
||||
value cannot be set right now - that's planned for future Pylint
|
||||
versions at this moment. So excluding this rule.
|
||||
|
||||
For more info:
|
||||
* https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/too-many-positional-arguments.html
|
||||
---
|
||||
.pylintrc | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/.pylintrc b/.pylintrc
|
||||
index f78c1c3f..5d75df40 100644
|
||||
--- a/.pylintrc
|
||||
+++ b/.pylintrc
|
||||
@@ -41,6 +41,8 @@ disable=
|
||||
consider-using-from-import,
|
||||
use-list-literal,
|
||||
use-dict-literal,
|
||||
+ too-many-lines, # we do not want to take care about that one
|
||||
+ too-many-positional-arguments, # we cannot set yet max-possitional-arguments unfortunately
|
||||
# new for python3 version of pylint
|
||||
useless-object-inheritance,
|
||||
consider-using-set-comprehension, # pylint3 force to use comprehension in place we don't want (py2 doesnt have these options, for inline skip)
|
||||
@@ -57,8 +59,7 @@ disable=
|
||||
redundant-u-string-prefix, # still have py2 to support
|
||||
logging-format-interpolation,
|
||||
logging-not-lazy,
|
||||
- use-yield-from, # yield from cannot be used until we require python 3.3 or greater
|
||||
- too-many-lines # we do not want to take care about that one
|
||||
+ use-yield-from # yield from cannot be used until we require python 3.3 or greater
|
||||
|
||||
[FORMAT]
|
||||
# Maximum number of characters on a single line.
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,131 +0,0 @@
|
||||
From 0fc2075683ffe30b77e83c7d793815e9301fa41d Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Fri, 13 Mar 2026 10:03:19 +0100
|
||||
Subject: [PATCH 08/44] fix(livemode): make live.dir is relative to device root
|
||||
|
||||
Booting from an squashfs image (from a local block dev) requires to
|
||||
parameters:
|
||||
- identifier of the device where the squashfs image resides
|
||||
- path to the squashfs image on the given device (aka live.dir)
|
||||
Therefore, live.dir needs to be set up with a path that is relative to
|
||||
the device where the image resides. This patch fixes the current
|
||||
behavior where the path is being taken as it is, i.e., relative to the
|
||||
root of the source system.
|
||||
|
||||
Jira-ref: RHEL-104379
|
||||
---
|
||||
.../libraries/addupgradebootentry.py | 29 ++++++++++-----
|
||||
.../tests/unit_test_addupgradebootentry.py | 36 +++++++++++--------
|
||||
2 files changed, 43 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py b/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py
|
||||
index b28ec57c..5b635a83 100644
|
||||
--- a/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py
|
||||
+++ b/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py
|
||||
@@ -270,14 +270,26 @@ def local_os_stat(path):
|
||||
return os.stat(path)
|
||||
|
||||
|
||||
-def _get_device_uuid(path):
|
||||
+def _split_path_on_mount_point(path):
|
||||
+ """ Split a given path into a prefix where a device is mounted and suffix relative to the device root. """
|
||||
+ mount_point = path
|
||||
+ while not os.path.ismount(mount_point):
|
||||
+ mount_point = os.path.dirname(mount_point)
|
||||
+
|
||||
+ relative_suffix = path[len(mount_point):]
|
||||
+ if len(relative_suffix) == 0 or relative_suffix[0] != '/':
|
||||
+ # relative_suffix is '' if the squashfs dir is set to root (/)
|
||||
+ # relative_suffix does not start with '/' if the dir is located in /, i.e., /mydir
|
||||
+ relative_suffix = '/{}'.format(relative_suffix)
|
||||
+
|
||||
+ return (mount_point, relative_suffix)
|
||||
+
|
||||
+
|
||||
+def _get_device_uuid(mount_point):
|
||||
"""
|
||||
- Find the UUID of a device in which the given path is located.
|
||||
+ Find the UUID of a device mounted at a given mount point.
|
||||
"""
|
||||
- while not os.path.ismount(path):
|
||||
- path = os.path.dirname(path)
|
||||
-
|
||||
- needle_dev_id = local_os_stat(path).st_dev
|
||||
+ needle_dev_id = local_os_stat(mount_point).st_dev
|
||||
|
||||
for uuid in os.listdir('/dev/disk/by-uuid'):
|
||||
uuid_fullpath = os.path.join('/dev/disk/by-uuid/', uuid)
|
||||
@@ -333,8 +345,9 @@ def construct_cmdline_args_for_livemode():
|
||||
if livemode_config.url_to_load_squashfs_from:
|
||||
args['root'] = 'live:{}'.format(livemode_config.url_to_load_squashfs_from)
|
||||
else:
|
||||
- args['root'] = 'live:UUID={}'.format(_get_device_uuid(dir_path_containing_liveimg))
|
||||
- args['rd.live.dir'] = dir_path_containing_liveimg
|
||||
+ dev_mount_point, dir_location_on_dev = _split_path_on_mount_point(dir_path_containing_liveimg)
|
||||
+ args['root'] = 'live:UUID={}'.format(_get_device_uuid(dev_mount_point))
|
||||
+ args['rd.live.dir'] = dir_location_on_dev
|
||||
args['rd.live.squashimg'] = liveimg_filename
|
||||
|
||||
if livemode_config.dracut_network:
|
||||
diff --git a/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py b/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py
|
||||
index 7341602b..79c05a5d 100644
|
||||
--- a/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py
|
||||
+++ b/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py
|
||||
@@ -279,23 +279,31 @@ def test_get_rdlvm_arg_values(monkeypatch):
|
||||
assert args == ('A', 'B')
|
||||
|
||||
|
||||
+@pytest.mark.parametrize(
|
||||
+ ('path', 'mount_point', 'suffix'),
|
||||
+ [
|
||||
+ ('/', '/', '/'),
|
||||
+ ('/dir', '/', '/dir'),
|
||||
+ ('/dir/squashfs', '/', '/dir/squashfs'),
|
||||
+ ('/dir/squashfs', '/dir', '/squashfs'),
|
||||
+ ]
|
||||
+)
|
||||
+def test_split_path_on_mount_point(monkeypatch, path, mount_point, suffix):
|
||||
+ def is_mount_mock(_path):
|
||||
+ return _path == mount_point
|
||||
+
|
||||
+ monkeypatch.setattr(os.path, 'ismount', is_mount_mock)
|
||||
+
|
||||
+ ret_mount_point, ret_suffix = addupgradebootentry._split_path_on_mount_point(path)
|
||||
+ assert ret_mount_point == mount_point
|
||||
+ assert ret_suffix == suffix
|
||||
+
|
||||
+
|
||||
def test_get_device_uuid(monkeypatch):
|
||||
"""
|
||||
The file in question is /var/lib/file
|
||||
Underlying partition /var is a device /dev/sda1 (dev_id=10) linked to from /dev/disk/by-uuid/MY_UUID1
|
||||
"""
|
||||
-
|
||||
- execution_stats = {
|
||||
- 'is_mount_call_count': 0
|
||||
- }
|
||||
-
|
||||
- def is_mount_mock(path):
|
||||
- execution_stats['is_mount_call_count'] += 1
|
||||
- assert execution_stats['is_mount_call_count'] <= 3
|
||||
- return path == '/var'
|
||||
-
|
||||
- monkeypatch.setattr(os.path, 'ismount', is_mount_mock)
|
||||
-
|
||||
StatResult = namedtuple('StatResult', ('st_dev', 'st_rdev'))
|
||||
|
||||
def stat_mock(path):
|
||||
@@ -325,8 +333,8 @@ def test_get_device_uuid(monkeypatch):
|
||||
|
||||
monkeypatch.setattr(os, 'readlink', readlink_mock)
|
||||
|
||||
- path = '/var/lib/file'
|
||||
- uuid = addupgradebootentry._get_device_uuid(path)
|
||||
+ mount_point = '/var'
|
||||
+ uuid = addupgradebootentry._get_device_uuid(mount_point)
|
||||
|
||||
assert uuid == 'MY_UUID1'
|
||||
|
||||
--
|
||||
2.53.0
|
||||
|
||||
534
SOURCES/0008-pam_userdb-migrate-backend-database.patch
Normal file
534
SOURCES/0008-pam_userdb-migrate-backend-database.patch
Normal file
@ -0,0 +1,534 @@
|
||||
From 658700d6424e852917b62c190dd23cbb3026b67d Mon Sep 17 00:00:00 2001
|
||||
From: Iker Pedrosa <ipedrosa@redhat.com>
|
||||
Date: Mon, 5 Aug 2024 15:15:44 +0200
|
||||
Subject: [PATCH 08/40] pam_userdb: migrate backend database
|
||||
|
||||
pam_userdb module changed its backend database technology from lidb to
|
||||
gdbm for RHEL10. This requires a set of leapp actors to perform the
|
||||
database migration automatically when upgrading to RHEL10:
|
||||
|
||||
* ScanPamUserDB takes care of scanning the PAM service folder to detect
|
||||
whether pam_userdb is used and the location of the database in use.
|
||||
This information is stored in a model.
|
||||
|
||||
* CheckPamUserDB checks the databases reported by ScanPamUserDB and
|
||||
prints a report about them.
|
||||
|
||||
* ConvertPamUserDB checks the databases reported by ScanPamUserDB and
|
||||
converts them to GDBM format.
|
||||
|
||||
* RemoveOldPamUserDB checks the databases reported by ScanPamUserDB and
|
||||
removes them.
|
||||
|
||||
All these actors include unit-tests.
|
||||
|
||||
Finally, there's also a spec file change to add `libdb-utils` dependency
|
||||
as it is required to convert pam_userdb databases from BerkeleyDB to
|
||||
GDBM.
|
||||
|
||||
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
|
||||
---
|
||||
packaging/leapp-repository.spec | 6 +++
|
||||
.../actors/pamuserdb/checkpamuserdb/actor.py | 18 ++++++++
|
||||
.../libraries/checkpamuserdb.py | 28 ++++++++++++
|
||||
.../tests/test_checkpamuserdb.py | 43 +++++++++++++++++++
|
||||
.../pamuserdb/convertpamuserdb/actor.py | 18 ++++++++
|
||||
.../libraries/convertpamuserdb.py | 27 ++++++++++++
|
||||
.../tests/test_convertpamuserdb.py | 39 +++++++++++++++++
|
||||
.../pamuserdb/removeoldpamuserdb/actor.py | 18 ++++++++
|
||||
.../libraries/removeoldpamuserdb.py | 25 +++++++++++
|
||||
.../tests/test_removeoldpamuserdb.py | 38 ++++++++++++++++
|
||||
.../actors/pamuserdb/scanpamuserdb/actor.py | 18 ++++++++
|
||||
.../scanpamuserdb/libraries/scanpamuserdb.py | 29 +++++++++++++
|
||||
.../tests/files/pam_userdb_basic | 1 +
|
||||
.../tests/files/pam_userdb_complete | 9 ++++
|
||||
.../tests/files/pam_userdb_missing | 1 +
|
||||
.../scanpamuserdb/tests/test_scanpamuserdb.py | 27 ++++++++++++
|
||||
.../el9toel10/models/pamuserdblocation.py | 14 ++++++
|
||||
17 files changed, 359 insertions(+)
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/actor.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/libraries/checkpamuserdb.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/tests/test_checkpamuserdb.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/actor.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/libraries/convertpamuserdb.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/tests/test_convertpamuserdb.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/actor.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/libraries/removeoldpamuserdb.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/tests/test_removeoldpamuserdb.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/actor.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/libraries/scanpamuserdb.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_basic
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_complete
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_missing
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/test_scanpamuserdb.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/models/pamuserdblocation.py
|
||||
|
||||
diff --git a/packaging/leapp-repository.spec b/packaging/leapp-repository.spec
|
||||
index 146afc45..0d63ba02 100644
|
||||
--- a/packaging/leapp-repository.spec
|
||||
+++ b/packaging/leapp-repository.spec
|
||||
@@ -211,6 +211,12 @@ Requires: dracut
|
||||
Requires: NetworkManager-libnm
|
||||
Requires: python3-gobject-base
|
||||
|
||||
+%endif
|
||||
+
|
||||
+%if 0%{?rhel} && 0%{?rhel} == 9
|
||||
+############# RHEL 9 dependencies (when the source system is RHEL 9) ##########
|
||||
+# Required to convert pam_userdb database from BerkeleyDB to GDBM
|
||||
+Requires: libdb-utils
|
||||
%endif
|
||||
##################################################
|
||||
# end requirement
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/actor.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..8fada645
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/actor.py
|
||||
@@ -0,0 +1,18 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.libraries.actor import checkpamuserdb
|
||||
+from leapp.models import PamUserDbLocation, Report
|
||||
+from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
+
|
||||
+
|
||||
+class CheckPamUserDb(Actor):
|
||||
+ """
|
||||
+ Create report with the location of pam_userdb databases
|
||||
+ """
|
||||
+
|
||||
+ name = 'check_pam_user_db'
|
||||
+ consumes = (PamUserDbLocation,)
|
||||
+ produces = (Report,)
|
||||
+ tags = (ChecksPhaseTag, IPUWorkflowTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ checkpamuserdb.process()
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/libraries/checkpamuserdb.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/libraries/checkpamuserdb.py
|
||||
new file mode 100644
|
||||
index 00000000..05cc71a9
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/libraries/checkpamuserdb.py
|
||||
@@ -0,0 +1,28 @@
|
||||
+from leapp import reporting
|
||||
+from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import PamUserDbLocation
|
||||
+
|
||||
+FMT_LIST_SEPARATOR = "\n - "
|
||||
+
|
||||
+
|
||||
+def process():
|
||||
+ msg = next(api.consume(PamUserDbLocation), None)
|
||||
+ if not msg:
|
||||
+ raise StopActorExecutionError('Expected PamUserDbLocation, but got None')
|
||||
+
|
||||
+ if msg.locations:
|
||||
+ reporting.create_report([
|
||||
+ reporting.Title('pam_userdb databases will be converted to GDBM'),
|
||||
+ reporting.Summary(
|
||||
+ 'On RHEL 10, GDMB is used by pam_userdb as it\'s backend database,'
|
||||
+ ' replacing BerkeleyDB. Existing pam_userdb databases will be'
|
||||
+ ' converted to GDBM. The following databases will be converted:'
|
||||
+ '{sep}{locations}'.format(sep=FMT_LIST_SEPARATOR, locations=FMT_LIST_SEPARATOR.join(msg.locations))),
|
||||
+ reporting.Severity(reporting.Severity.INFO),
|
||||
+ reporting.Groups([reporting.Groups.SECURITY, reporting.Groups.AUTHENTICATION])
|
||||
+ ])
|
||||
+ else:
|
||||
+ api.current_logger().debug(
|
||||
+ 'No pam_userdb databases were located, thus nothing will be converted'
|
||||
+ )
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/tests/test_checkpamuserdb.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/tests/test_checkpamuserdb.py
|
||||
new file mode 100644
|
||||
index 00000000..2e11106b
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/checkpamuserdb/tests/test_checkpamuserdb.py
|
||||
@@ -0,0 +1,43 @@
|
||||
+import pytest
|
||||
+
|
||||
+from leapp import reporting
|
||||
+from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.actor import checkpamuserdb
|
||||
+from leapp.libraries.common.testutils import create_report_mocked, logger_mocked
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import PamUserDbLocation
|
||||
+
|
||||
+
|
||||
+def test_process_no_msg(monkeypatch):
|
||||
+ def consume_mocked(*args, **kwargs):
|
||||
+ yield None
|
||||
+
|
||||
+ monkeypatch.setattr(api, 'consume', consume_mocked)
|
||||
+
|
||||
+ with pytest.raises(StopActorExecutionError):
|
||||
+ checkpamuserdb.process()
|
||||
+
|
||||
+
|
||||
+def test_process_no_location(monkeypatch):
|
||||
+ def consume_mocked(*args, **kwargs):
|
||||
+ yield PamUserDbLocation(locations=[])
|
||||
+
|
||||
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
||||
+ monkeypatch.setattr(api, 'consume', consume_mocked)
|
||||
+
|
||||
+ checkpamuserdb.process()
|
||||
+ assert (
|
||||
+ 'No pam_userdb databases were located, thus nothing will be converted'
|
||||
+ in api.current_logger.dbgmsg
|
||||
+ )
|
||||
+
|
||||
+
|
||||
+def test_process_locations(monkeypatch):
|
||||
+ def consume_mocked(*args, **kwargs):
|
||||
+ yield PamUserDbLocation(locations=['/tmp/db1', '/tmp/db2'])
|
||||
+
|
||||
+ monkeypatch.setattr(reporting, "create_report", create_report_mocked())
|
||||
+ monkeypatch.setattr(api, 'consume', consume_mocked)
|
||||
+
|
||||
+ checkpamuserdb.process()
|
||||
+ assert reporting.create_report.called == 1
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/actor.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..5f8525b6
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/actor.py
|
||||
@@ -0,0 +1,18 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.libraries.actor import convertpamuserdb
|
||||
+from leapp.models import PamUserDbLocation
|
||||
+from leapp.tags import IPUWorkflowTag, PreparationPhaseTag
|
||||
+
|
||||
+
|
||||
+class ConvertPamUserDb(Actor):
|
||||
+ """
|
||||
+ Convert the pam_userdb databases to GDBM
|
||||
+ """
|
||||
+
|
||||
+ name = 'convert_pam_user_db'
|
||||
+ consumes = (PamUserDbLocation,)
|
||||
+ produces = ()
|
||||
+ tags = (PreparationPhaseTag, IPUWorkflowTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ convertpamuserdb.process()
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/libraries/convertpamuserdb.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/libraries/convertpamuserdb.py
|
||||
new file mode 100644
|
||||
index 00000000..e55b4102
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/libraries/convertpamuserdb.py
|
||||
@@ -0,0 +1,27 @@
|
||||
+from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.stdlib import api, CalledProcessError, run
|
||||
+from leapp.models import PamUserDbLocation
|
||||
+
|
||||
+
|
||||
+def _convert_db(db_path):
|
||||
+ cmd = ['db_converter', '--src', f'{db_path}.db', '--dest', f'{db_path}.gdbm']
|
||||
+ try:
|
||||
+ run(cmd)
|
||||
+ except (CalledProcessError, OSError) as e:
|
||||
+ # As the db_converter does not remove the original DB after conversion or upon failure,
|
||||
+ # interrupt the upgrade, keeping the original DBs.
|
||||
+ # If all DBs are successfully converted, the leftover DBs are removed in the removeoldpamuserdb actor.
|
||||
+ raise StopActorExecutionError(
|
||||
+ 'Cannot convert pam_userdb database.',
|
||||
+ details={'details': '{}: {}'.format(str(e), e.stderr)}
|
||||
+ )
|
||||
+
|
||||
+
|
||||
+def process():
|
||||
+ msg = next(api.consume(PamUserDbLocation), None)
|
||||
+ if not msg:
|
||||
+ raise StopActorExecutionError('Expected PamUserDbLocation, but got None')
|
||||
+
|
||||
+ if msg.locations:
|
||||
+ for location in msg.locations:
|
||||
+ _convert_db(location)
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/tests/test_convertpamuserdb.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/tests/test_convertpamuserdb.py
|
||||
new file mode 100644
|
||||
index 00000000..46505492
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/convertpamuserdb/tests/test_convertpamuserdb.py
|
||||
@@ -0,0 +1,39 @@
|
||||
+import os
|
||||
+
|
||||
+import pytest
|
||||
+
|
||||
+from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.actor import convertpamuserdb
|
||||
+from leapp.libraries.common.testutils import logger_mocked
|
||||
+from leapp.libraries.stdlib import api, CalledProcessError
|
||||
+
|
||||
+CUR_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
+
|
||||
+
|
||||
+def test_convert_db_success(monkeypatch):
|
||||
+ location = os.path.join(CUR_DIR, '/files/db1')
|
||||
+
|
||||
+ def run_mocked(cmd, **kwargs):
|
||||
+ assert cmd == ['db_converter', '--src', f'{location}.db', '--dest', f'{location}.gdbm']
|
||||
+
|
||||
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
||||
+ monkeypatch.setattr(convertpamuserdb, 'run', run_mocked)
|
||||
+ convertpamuserdb._convert_db(location)
|
||||
+ assert len(api.current_logger.errmsg) == 0
|
||||
+
|
||||
+
|
||||
+def test_convert_db_failure(monkeypatch):
|
||||
+ location = os.path.join(CUR_DIR, '/files/db1')
|
||||
+
|
||||
+ def run_mocked(cmd, **kwargs):
|
||||
+ raise CalledProcessError(
|
||||
+ message='A Leapp Command Error occurred.',
|
||||
+ command=cmd,
|
||||
+ result={'exit_code': 1}
|
||||
+ )
|
||||
+
|
||||
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
||||
+ monkeypatch.setattr(convertpamuserdb, 'run', run_mocked)
|
||||
+ with pytest.raises(StopActorExecutionError) as err:
|
||||
+ convertpamuserdb._convert_db(location)
|
||||
+ assert str(err.value) == 'Cannot convert pam_userdb database.'
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/actor.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..39a00855
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/actor.py
|
||||
@@ -0,0 +1,18 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.libraries.actor import removeoldpamuserdb
|
||||
+from leapp.models import PamUserDbLocation
|
||||
+from leapp.tags import ApplicationsPhaseTag, IPUWorkflowTag
|
||||
+
|
||||
+
|
||||
+class RemoveOldPamUserDb(Actor):
|
||||
+ """
|
||||
+ Remove old pam_userdb databases
|
||||
+ """
|
||||
+
|
||||
+ name = 'remove_old_pam_user_db'
|
||||
+ consumes = (PamUserDbLocation,)
|
||||
+ produces = ()
|
||||
+ tags = (ApplicationsPhaseTag, IPUWorkflowTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ removeoldpamuserdb.process()
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/libraries/removeoldpamuserdb.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/libraries/removeoldpamuserdb.py
|
||||
new file mode 100644
|
||||
index 00000000..5fc4cb4d
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/libraries/removeoldpamuserdb.py
|
||||
@@ -0,0 +1,25 @@
|
||||
+from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.stdlib import api, CalledProcessError, run
|
||||
+from leapp.models import PamUserDbLocation
|
||||
+
|
||||
+
|
||||
+def _remove_db(db_path):
|
||||
+ cmd = ['rm', '-f', f'{db_path}.db']
|
||||
+ try:
|
||||
+ run(cmd)
|
||||
+ except (CalledProcessError, OSError) as e:
|
||||
+ api.current_logger().error(
|
||||
+ 'Failed to remove {}.db: {}'.format(
|
||||
+ db_path, e
|
||||
+ )
|
||||
+ )
|
||||
+
|
||||
+
|
||||
+def process():
|
||||
+ msg = next(api.consume(PamUserDbLocation), None)
|
||||
+ if not msg:
|
||||
+ raise StopActorExecutionError('Expected PamUserDbLocation, but got None')
|
||||
+
|
||||
+ if msg.locations:
|
||||
+ for location in msg.locations:
|
||||
+ _remove_db(location)
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/tests/test_removeoldpamuserdb.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/tests/test_removeoldpamuserdb.py
|
||||
new file mode 100644
|
||||
index 00000000..2c1d5c75
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/removeoldpamuserdb/tests/test_removeoldpamuserdb.py
|
||||
@@ -0,0 +1,38 @@
|
||||
+import os
|
||||
+
|
||||
+from leapp.libraries.actor import removeoldpamuserdb
|
||||
+from leapp.libraries.common.testutils import logger_mocked
|
||||
+from leapp.libraries.stdlib import api, CalledProcessError
|
||||
+
|
||||
+CUR_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
+
|
||||
+
|
||||
+def test_remove_db_success(monkeypatch):
|
||||
+ location = os.path.join(CUR_DIR, '/files/db1')
|
||||
+
|
||||
+ def run_mocked(cmd, **kwargs):
|
||||
+ assert cmd == ['rm', '-f', f'{location}.db']
|
||||
+
|
||||
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
||||
+ monkeypatch.setattr(removeoldpamuserdb, 'run', run_mocked)
|
||||
+ removeoldpamuserdb._remove_db(location)
|
||||
+ assert len(api.current_logger.errmsg) == 0
|
||||
+
|
||||
+
|
||||
+def test_remove_db_failure(monkeypatch):
|
||||
+ location = os.path.join(CUR_DIR, '/files/db1')
|
||||
+
|
||||
+ def run_mocked(cmd, **kwargs):
|
||||
+ raise CalledProcessError(
|
||||
+ message='A Leapp Command Error occurred.',
|
||||
+ command=cmd,
|
||||
+ result={'exit_code': 1}
|
||||
+ )
|
||||
+
|
||||
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
||||
+ monkeypatch.setattr(removeoldpamuserdb, 'run', run_mocked)
|
||||
+ removeoldpamuserdb._remove_db(location)
|
||||
+ assert (
|
||||
+ 'Failed to remove /files/db1.db'
|
||||
+ not in api.current_logger.errmsg
|
||||
+ )
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/actor.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..b6b35f1a
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/actor.py
|
||||
@@ -0,0 +1,18 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.libraries.actor import scanpamuserdb
|
||||
+from leapp.models import PamUserDbLocation
|
||||
+from leapp.tags import FactsPhaseTag, IPUWorkflowTag
|
||||
+
|
||||
+
|
||||
+class ScanPamUserDb(Actor):
|
||||
+ """
|
||||
+ Scan the PAM service folder for the location of pam_userdb databases
|
||||
+ """
|
||||
+
|
||||
+ name = 'scan_pam_user_db'
|
||||
+ consumes = ()
|
||||
+ produces = (PamUserDbLocation,)
|
||||
+ tags = (FactsPhaseTag, IPUWorkflowTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ self.produce(scanpamuserdb.parse_pam_config_folder('/etc/pam.d/'))
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/libraries/scanpamuserdb.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/libraries/scanpamuserdb.py
|
||||
new file mode 100644
|
||||
index 00000000..0f668c02
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/libraries/scanpamuserdb.py
|
||||
@@ -0,0 +1,29 @@
|
||||
+import os
|
||||
+import re
|
||||
+
|
||||
+from leapp.models import PamUserDbLocation
|
||||
+
|
||||
+
|
||||
+def _parse_pam_config_file(conf_file):
|
||||
+ with open(conf_file, 'r') as file:
|
||||
+ for line in file:
|
||||
+ if 'pam_userdb' in line:
|
||||
+ match = re.search(r'db=(\S+)', line)
|
||||
+ if match:
|
||||
+ return match.group(1)
|
||||
+
|
||||
+ return None
|
||||
+
|
||||
+
|
||||
+def parse_pam_config_folder(conf_folder):
|
||||
+ locations = set()
|
||||
+
|
||||
+ for file_name in os.listdir(conf_folder):
|
||||
+ file_path = os.path.join(conf_folder, file_name)
|
||||
+
|
||||
+ if os.path.isfile(file_path):
|
||||
+ location = _parse_pam_config_file(file_path)
|
||||
+ if location is not None:
|
||||
+ locations.add(location)
|
||||
+
|
||||
+ return PamUserDbLocation(locations=list(locations))
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_basic b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_basic
|
||||
new file mode 100644
|
||||
index 00000000..f115147b
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_basic
|
||||
@@ -0,0 +1 @@
|
||||
+auth required pam_userdb.so db=/tmp/db1
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_complete b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_complete
|
||||
new file mode 100644
|
||||
index 00000000..84e40b48
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_complete
|
||||
@@ -0,0 +1,9 @@
|
||||
+auth required pam_env.so
|
||||
+auth required pam_faildelay.so delay=2000000
|
||||
+auth sufficient pam_fprintd.so
|
||||
+auth [default=1 ignore=ignore success=ok] pam_usertype.so isregular
|
||||
+auth [default=1 ignore=ignore success=ok] pam_localuser.so
|
||||
+auth required pam_userdb.so db=/tmp/db2
|
||||
+auth [default=1 ignore=ignore success=ok] pam_usertype.so isregular
|
||||
+auth sufficient pam_sss.so forward_pass
|
||||
+auth required pam_deny.so
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_missing b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_missing
|
||||
new file mode 100644
|
||||
index 00000000..764947fc
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/files/pam_userdb_missing
|
||||
@@ -0,0 +1 @@
|
||||
+auth sufficient pam_unix.so nullok
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/test_scanpamuserdb.py b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/test_scanpamuserdb.py
|
||||
new file mode 100644
|
||||
index 00000000..3b752d87
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pamuserdb/scanpamuserdb/tests/test_scanpamuserdb.py
|
||||
@@ -0,0 +1,27 @@
|
||||
+import os
|
||||
+
|
||||
+import pytest
|
||||
+
|
||||
+from leapp.libraries.actor import scanpamuserdb
|
||||
+
|
||||
+CUR_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(
|
||||
+ "inp,exp_out",
|
||||
+ [
|
||||
+ ("files/pam_userdb_missing", None),
|
||||
+ ("files/pam_userdb_basic", "/tmp/db1"),
|
||||
+ ("files/pam_userdb_complete", "/tmp/db2"),
|
||||
+ ],
|
||||
+)
|
||||
+def test_parse_pam_config_file(inp, exp_out):
|
||||
+ file = scanpamuserdb._parse_pam_config_file(os.path.join(CUR_DIR, inp))
|
||||
+ assert file == exp_out
|
||||
+
|
||||
+
|
||||
+def test_parse_pam_config_folder():
|
||||
+ msg = scanpamuserdb.parse_pam_config_folder(os.path.join(CUR_DIR, "files/"))
|
||||
+ assert len(msg.locations) == 2
|
||||
+ assert "/tmp/db1" in msg.locations
|
||||
+ assert "/tmp/db2" in msg.locations
|
||||
diff --git a/repos/system_upgrade/el9toel10/models/pamuserdblocation.py b/repos/system_upgrade/el9toel10/models/pamuserdblocation.py
|
||||
new file mode 100644
|
||||
index 00000000..d15b2041
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/models/pamuserdblocation.py
|
||||
@@ -0,0 +1,14 @@
|
||||
+from leapp.models import fields, Model
|
||||
+from leapp.topics import SystemInfoTopic
|
||||
+
|
||||
+
|
||||
+class PamUserDbLocation(Model):
|
||||
+ """
|
||||
+ Provides a list of all database files for pam_userdb
|
||||
+ """
|
||||
+ topic = SystemInfoTopic
|
||||
+
|
||||
+ locations = fields.List(fields.String(), default=[])
|
||||
+ """
|
||||
+ The list with the full path to the database files.
|
||||
+ """
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
From d6e57eec3ded2887008055442ba906a92c572a01 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Thu, 10 Oct 2024 14:03:36 +0200
|
||||
Subject: [PATCH 09/40] Replace mirror.centos.org with vault.centos.org Centos
|
||||
7 Containerfile
|
||||
|
||||
As mirror.centos.org is dead, replace mirrorlist with baseurl pointing
|
||||
to vault.centos.org in utils/container-builds/Containerfile.centos7.
|
||||
---
|
||||
utils/container-builds/Containerfile.centos7 | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/utils/container-builds/Containerfile.centos7 b/utils/container-builds/Containerfile.centos7
|
||||
index 70ac3df1..af00eddb 100644
|
||||
--- a/utils/container-builds/Containerfile.centos7
|
||||
+++ b/utils/container-builds/Containerfile.centos7
|
||||
@@ -2,6 +2,11 @@ FROM centos:7
|
||||
|
||||
VOLUME /repo
|
||||
|
||||
+# mirror.centos.org is dead, comment out mirrorlist and set baseurl to vault.centos.org
|
||||
+RUN sed -i s/mirror.centos.org/vault.centos.org/ /etc/yum.repos.d/CentOS-*.repo
|
||||
+RUN sed -i s/^#\s*baseurl=http/baseurl=http/ /etc/yum.repos.d/CentOS-*.repo
|
||||
+RUN sed -i s/^mirrorlist=http/#mirrorlist=http/ /etc/yum.repos.d/CentOS-*.repo
|
||||
+
|
||||
RUN yum update -y && \
|
||||
yum install -y rpm-build python-devel make git
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
From 3a9cb366b7487bb5cc57e7650447af327c343b0d Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Wed, 18 Mar 2026 09:58:13 +0100
|
||||
Subject: [PATCH 09/44] fix(livemode): change location of source system tree
|
||||
|
||||
Before this patch, the generated squashfs image mounts the source system
|
||||
tree at /run/initramfs/live, which is the location used by dmsquash-live
|
||||
to mount the block device that holds the squashfs image. This device,
|
||||
however, might be arbitrary, e.g., it could be hosting /var of the
|
||||
source system. Therefore, the squashfs system would attempt to mount
|
||||
multiple things at /run/initramfs/live (/ and /var of the source
|
||||
system), creating problems. This patch changes the location of the
|
||||
source system tree to '/run/upgrade'.
|
||||
|
||||
Jira-ref: RHEL-104379
|
||||
---
|
||||
.../files/do-upgrade.sh | 4 ++--
|
||||
.../libraries/prepareliveimage.py | 12 ++++++++++--
|
||||
2 files changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/livemode/modify_userspace_for_livemode/files/do-upgrade.sh b/repos/system_upgrade/common/actors/livemode/modify_userspace_for_livemode/files/do-upgrade.sh
|
||||
index 4b2f9a1f..51ebddb5 100755
|
||||
--- a/repos/system_upgrade/common/actors/livemode/modify_userspace_for_livemode/files/do-upgrade.sh
|
||||
+++ b/repos/system_upgrade/common/actors/livemode/modify_userspace_for_livemode/files/do-upgrade.sh
|
||||
@@ -28,8 +28,8 @@ export LEAPPHOME=/root/tmp_leapp_py3
|
||||
export LEAPP3_BIN=$LEAPPHOME/leapp3
|
||||
|
||||
# this was initially a dracut script, hence $NEWROOT.
|
||||
-# the rootfs is mounted on /run/initramfs/live when booted with dmsquash-live
|
||||
-export NEWROOT=/run/initramfs/live
|
||||
+# the rootfs is mounted on /run/upgrade when booted with dmsquash-live
|
||||
+export NEWROOT=/run/upgrade
|
||||
|
||||
NSPAWN_OPTS="--capability=all --bind=/dev --bind=/dev/pts --bind=/proc --bind=/run/udev --bind=/run/lock"
|
||||
[ -d /dev/mapper ] && NSPAWN_OPTS="$NSPAWN_OPTS --bind=/dev/mapper"
|
||||
diff --git a/repos/system_upgrade/common/actors/livemode/modify_userspace_for_livemode/libraries/prepareliveimage.py b/repos/system_upgrade/common/actors/livemode/modify_userspace_for_livemode/libraries/prepareliveimage.py
|
||||
index 2587bf89..96dadadf 100644
|
||||
--- a/repos/system_upgrade/common/actors/livemode/modify_userspace_for_livemode/libraries/prepareliveimage.py
|
||||
+++ b/repos/system_upgrade/common/actors/livemode/modify_userspace_for_livemode/libraries/prepareliveimage.py
|
||||
@@ -18,8 +18,16 @@ LEAPP_CONSOLE_SERVICE_FILE = 'console.service'
|
||||
LEAPP_STRACE_SERVICE_FILE = 'upgrade-strace.service'
|
||||
""" Service that executes the upgrade while strace-ing the corresponding Leapp's process tree. """
|
||||
|
||||
-SOURCE_ROOT_MOUNT_LOCATION = '/run/initramfs/live'
|
||||
-""" Controls where the source system's root will be mounted inside the upgrade image. """
|
||||
+SOURCE_ROOT_MOUNT_LOCATION = '/run/upgrade'
|
||||
+"""
|
||||
+Controls where the source system's root will be mounted inside the upgrade image.
|
||||
+
|
||||
+Note: This cannot be set to /run/initramfs/live as the path is used by
|
||||
+ dmsquash-live by default to mount the block device that holds the squashfs
|
||||
+ image. As this device can be arbitrary (e.g., it can be mounted as /var on the
|
||||
+ source system), using /run/initramfs/live would cause mounting problems - we
|
||||
+ would attempt to mount / and also (for example) /var on the same location.
|
||||
+"""
|
||||
|
||||
|
||||
def create_fstab_mounting_current_root_elsewhere(context, host_fstab):
|
||||
--
|
||||
2.53.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,35 @@
|
||||
From b997e4eeb835809d1fbfd1a0b9a6114c133bf0b4 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Thu, 10 Oct 2024 15:28:48 +0200
|
||||
Subject: [PATCH 10/40] kernelcmdlineconfig: Add Report to produces tuple
|
||||
|
||||
The missing `leapp.reporting.Report` class is added to
|
||||
kernelcmdlineconfig actor `produces` tuple.
|
||||
---
|
||||
.../system_upgrade/common/actors/kernelcmdlineconfig/actor.py | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/kernelcmdlineconfig/actor.py b/repos/system_upgrade/common/actors/kernelcmdlineconfig/actor.py
|
||||
index b44fd835..3585a14e 100644
|
||||
--- a/repos/system_upgrade/common/actors/kernelcmdlineconfig/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/kernelcmdlineconfig/actor.py
|
||||
@@ -4,6 +4,7 @@ from leapp.actors import Actor
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries.actor import kernelcmdlineconfig
|
||||
from leapp.models import FirmwareFacts, InstalledTargetKernelInfo, KernelCmdlineArg, TargetKernelCmdlineArgTasks
|
||||
+from leapp.reporting import Report
|
||||
from leapp.tags import FinalizationPhaseTag, IPUWorkflowTag
|
||||
|
||||
|
||||
@@ -14,7 +15,7 @@ class KernelCmdlineConfig(Actor):
|
||||
|
||||
name = 'kernelcmdlineconfig'
|
||||
consumes = (KernelCmdlineArg, InstalledTargetKernelInfo, FirmwareFacts, TargetKernelCmdlineArgTasks)
|
||||
- produces = ()
|
||||
+ produces = (Report,)
|
||||
tags = (FinalizationPhaseTag, IPUWorkflowTag)
|
||||
|
||||
def process(self):
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,86 +0,0 @@
|
||||
From f6838df00e3be7d8beec99bd9448ed47c7720853 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 18:25:09 +0100
|
||||
Subject: [PATCH 11/44] checkblacklistca: Respect distro name in reports
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../libraries/checkblacklistca.py | 28 +++++++++++++------
|
||||
.../tests/component_test_checkblacklistca.py | 9 ++++++
|
||||
2 files changed, 29 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/checkblacklistca/libraries/checkblacklistca.py b/repos/system_upgrade/el8toel9/actors/checkblacklistca/libraries/checkblacklistca.py
|
||||
index 53b912b8..635b3640 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/checkblacklistca/libraries/checkblacklistca.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/checkblacklistca/libraries/checkblacklistca.py
|
||||
@@ -1,4 +1,5 @@
|
||||
from leapp import reporting
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import BlackListCA, BlackListError
|
||||
|
||||
@@ -50,9 +51,14 @@ def process():
|
||||
reporting.Title('Distrusted CA certificates will be moved from blacklist to blocklist'),
|
||||
reporting.Summary(
|
||||
'The directories which store user and administrator supplied '
|
||||
- 'distrusted certificates have change names from blacklist in '
|
||||
- 'RHEL8 to blocklist in RHEL9. As a result {} and '
|
||||
- '{} will be deleted.'.format(reportString, deleteString)),
|
||||
+ 'distrusted certificates were renamed from blacklist in '
|
||||
+ '{source_distro} 8 to blocklist in {target_distro} 9. '
|
||||
+ 'As a result {report_string} and {delete_string} will be deleted.'.format(
|
||||
+ report_string=reportString,
|
||||
+ delete_string=deleteString,
|
||||
+ **DISTRO_REPORT_NAMES,
|
||||
+ )
|
||||
+ ),
|
||||
reporting.Severity(reporting.Severity.INFO),
|
||||
reporting.Groups([reporting.Groups.SECURITY]),
|
||||
reporting.Groups([reporting.Groups.AUTHENTICATION])
|
||||
@@ -63,11 +69,17 @@ def process():
|
||||
reporting.Summary(
|
||||
'The directories which stores user and administrator supplied '
|
||||
'distrusted certificates has change names from blacklist in '
|
||||
- 'RHEL8 to blocklist in RHEL9. But we are unable to access the '
|
||||
- 'RHEL8 directory {} because {}. You can clear this error by '
|
||||
- 'correcting the condition, or by moving the contents to {} '
|
||||
- 'and removing {} completely'
|
||||
- '. '.format(ble.sourceDir, ble.error, ble.targetDir, ble.sourceDir)),
|
||||
+ '{source_distro} 8 to blocklist in {target_distro} 9. '
|
||||
+ 'But we are unable to access the {source_distro} 8 directory '
|
||||
+ '{source_dir} because {error}. You can clear this error by '
|
||||
+ 'correcting the condition, or by moving the contents to '
|
||||
+ '{target_dir} and removing {source_dir} completely'.format(
|
||||
+ source_dir=ble.sourceDir,
|
||||
+ error=ble.error,
|
||||
+ target_dir=ble.targetDir,
|
||||
+ **DISTRO_REPORT_NAMES,
|
||||
+ )
|
||||
+ ),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups([reporting.Groups.SECURITY]),
|
||||
reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/checkblacklistca/tests/component_test_checkblacklistca.py b/repos/system_upgrade/el8toel9/actors/checkblacklistca/tests/component_test_checkblacklistca.py
|
||||
index 2fc27501..af7e6305 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/checkblacklistca/tests/component_test_checkblacklistca.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/checkblacklistca/tests/component_test_checkblacklistca.py
|
||||
@@ -1,7 +1,16 @@
|
||||
+import pytest
|
||||
+
|
||||
+from leapp.libraries.common import distro
|
||||
from leapp.models import BlackListCA, BlackListError, Report
|
||||
from leapp.utils.report import is_inhibitor
|
||||
|
||||
|
||||
+@pytest.fixture(autouse=True)
|
||||
+def common_mocks(monkeypatch):
|
||||
+ monkeypatch.setattr(distro, 'get_source_distro_id', lambda: 'rhel')
|
||||
+ monkeypatch.setattr(distro, 'get_target_distro_id', lambda: 'rhel')
|
||||
+
|
||||
+
|
||||
def test_actor_execution_empty(current_actor_context):
|
||||
current_actor_context.feed()
|
||||
current_actor_context.run()
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,204 @@
|
||||
From c2c96affa7b20c82969419ce49b65cbf646a0c32 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Fri, 18 Oct 2024 12:43:19 +0200
|
||||
Subject: [PATCH 11/40] kernelcmdlineconfig: Use args from first entry when
|
||||
multiple entries are listed
|
||||
|
||||
Instead of erroring out when grubby lists multiple entries for the
|
||||
default kernel, always use the `args=` and `root=` from the first one and create
|
||||
a post-upgrade report. The report instruct user to ensure those are the
|
||||
correct ones or to correct them.
|
||||
|
||||
This can happen, for example, if MAKEDEBUG=yes is set in
|
||||
/etc/sysconfing/kernel.
|
||||
|
||||
Jira: RHEL-46911
|
||||
---
|
||||
.../libraries/kernelcmdlineconfig.py | 79 ++++++++++++++++---
|
||||
.../tests/test_kernelcmdlineconfig.py | 48 ++++++++++-
|
||||
2 files changed, 116 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py b/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py
|
||||
index 6b261c3b..19c50f3c 100644
|
||||
--- a/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py
|
||||
@@ -109,10 +109,55 @@ def _extract_grubby_value(record):
|
||||
return matches.group(2)
|
||||
|
||||
|
||||
+def report_multple_entries_for_default_kernel():
|
||||
+ if use_cmdline_file():
|
||||
+ report_hint = (
|
||||
+ 'After the system has been rebooted into the new version of RHEL,'
|
||||
+ ' check that configured default kernel cmdline arguments in /etc/kernel/cmdline '
|
||||
+ ' are correct. In case that different arguments are expected, update the file as needed.'
|
||||
+ )
|
||||
+ else:
|
||||
+ report_hint = (
|
||||
+ 'After the system has been rebooted into the new version of RHEL,'
|
||||
+ ' check that configured default kernel cmdline arguments are set as expected, using'
|
||||
+ ' the `grub2-editenv list` command. '
|
||||
+ ' If different default arguments are expected, update them using grub2-editenv.\n'
|
||||
+ ' For example, consider that current booted kernel has correct kernel cmdline'
|
||||
+ ' arguments and /proc/cmdline contains:\n\n'
|
||||
+ ' BOOT_IMAGE=(hd0,msdos1)/vmlinuz-4.18.0-425.3.1.el8.x86_64'
|
||||
+ ' root=/dev/mapper/rhel_ibm--root ro console=tty0'
|
||||
+ ' console=ttyS0,115200 rd_NO_PLYMOUTH\n\n'
|
||||
+ ' then run the following grub2-editenv command:\n\n'
|
||||
+ ' # grub2-editenv - set "kernelopts=root=/dev/mapper/rhel_ibm--root'
|
||||
+ ' ro console=tty0 console=ttyS0,115200 rd_NO_PLYMOUTH"'
|
||||
+ )
|
||||
+
|
||||
+ reporting.create_report([
|
||||
+ reporting.Title('Ensure that expected default kernel cmdline arguments are set'),
|
||||
+ reporting.Summary(
|
||||
+ 'During the upgrade we needed to modify the kernel command line arguments.'
|
||||
+ ' However, multiple bootloader entries with different arguments were found for the default'
|
||||
+ ' kernel (perhaps MAKEDEBUG=yes is set in /etc/sysconfig/kernel).'
|
||||
+ ' Leapp used the arguments from the first found entry of the target kernel'
|
||||
+ ' and set it as the new default kernel cmdline arguments for kernels installed in the future.'
|
||||
+ ),
|
||||
+ reporting.Remediation(hint=report_hint),
|
||||
+ reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Groups([
|
||||
+ reporting.Groups.BOOT,
|
||||
+ reporting.Groups.KERNEL,
|
||||
+ reporting.Groups.POST,
|
||||
+ ]),
|
||||
+ reporting.RelatedResource('file', '/etc/kernel/cmdline'),
|
||||
+ ])
|
||||
+
|
||||
+
|
||||
def retrieve_args_for_default_kernel(kernel_info):
|
||||
# Copy the args for the default kernel to all kernels.
|
||||
kernel_args = None
|
||||
kernel_root = None
|
||||
+ detected_multiple_entries = False
|
||||
+
|
||||
cmd = ['grubby', '--info', kernel_info.kernel_img_path]
|
||||
output = stdlib.run(cmd, split=False)
|
||||
for record in output['stdout'].splitlines():
|
||||
@@ -122,19 +167,30 @@ def retrieve_args_for_default_kernel(kernel_info):
|
||||
temp_kernel_args = _extract_grubby_value(record)
|
||||
|
||||
if kernel_args:
|
||||
- api.current_logger().warning('Grubby output is malformed:'
|
||||
- ' `args=` is listed more than once.')
|
||||
if kernel_args != temp_kernel_args:
|
||||
- raise ReadOfKernelArgsError('Grubby listed `args=` multiple'
|
||||
- ' times with different values.')
|
||||
- kernel_args = _extract_grubby_value(record)
|
||||
+ api.current_logger().warning(
|
||||
+ 'Grubby output listed `args=` multiple times with different values,'
|
||||
+ ' continuing with the first result'
|
||||
+ )
|
||||
+ detected_multiple_entries = True
|
||||
+ else:
|
||||
+ api.current_logger().warning('Grubby output listed `args=` more than once')
|
||||
+ else:
|
||||
+ kernel_args = temp_kernel_args
|
||||
elif record.startswith('root='):
|
||||
- api.current_logger().warning('Grubby output is malformed:'
|
||||
- ' `root=` is listed more than once.')
|
||||
+ temp_kernel_root = _extract_grubby_value(record)
|
||||
+
|
||||
if kernel_root:
|
||||
- raise ReadOfKernelArgsError('Grubby listed `root=` multiple'
|
||||
- ' times with different values')
|
||||
- kernel_root = _extract_grubby_value(record)
|
||||
+ if kernel_root != temp_kernel_root:
|
||||
+ api.current_logger().warning(
|
||||
+ 'Grubby output listed `root=` multiple times with different values,'
|
||||
+ ' continuing with the first result'
|
||||
+ )
|
||||
+ detected_multiple_entries = True
|
||||
+ else:
|
||||
+ api.current_logger().warning('Grubby output listed `root=` more than once')
|
||||
+ else:
|
||||
+ kernel_root = temp_kernel_root
|
||||
|
||||
if not kernel_args or not kernel_root:
|
||||
raise ReadOfKernelArgsError(
|
||||
@@ -142,6 +198,9 @@ def retrieve_args_for_default_kernel(kernel_info):
|
||||
' kernels: root={}, args={}'.format(kernel_root, kernel_args)
|
||||
)
|
||||
|
||||
+ if detected_multiple_entries:
|
||||
+ report_multple_entries_for_default_kernel()
|
||||
+
|
||||
return kernel_root, kernel_args
|
||||
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/kernelcmdlineconfig/tests/test_kernelcmdlineconfig.py b/repos/system_upgrade/common/actors/kernelcmdlineconfig/tests/test_kernelcmdlineconfig.py
|
||||
index ffe4b046..e5759a7b 100644
|
||||
--- a/repos/system_upgrade/common/actors/kernelcmdlineconfig/tests/test_kernelcmdlineconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/kernelcmdlineconfig/tests/test_kernelcmdlineconfig.py
|
||||
@@ -4,11 +4,12 @@ from collections import namedtuple
|
||||
|
||||
import pytest
|
||||
|
||||
+from leapp import reporting
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries import stdlib
|
||||
from leapp.libraries.actor import kernelcmdlineconfig
|
||||
from leapp.libraries.common.config import architecture
|
||||
-from leapp.libraries.common.testutils import CurrentActorMocked
|
||||
+from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import InstalledTargetKernelInfo, KernelCmdlineArg, TargetKernelCmdlineArgTasks
|
||||
|
||||
@@ -183,6 +184,51 @@ def test_kernelcmdline_config_no_version(monkeypatch):
|
||||
assert not mocked_run.commands
|
||||
|
||||
|
||||
+SECOND_KERNEL_ARGS = (
|
||||
+ 'ro rootflags=subvol=root'
|
||||
+ ' resume=/dev/mapper/luks-2c0df999-81ec-4a35-a1f9-b93afee8c6ad'
|
||||
+ ' rd.luks.uuid=luks-90a6412f-c588-46ca-9118-5aca35943d25'
|
||||
+ ' rd.luks.uuid=luks-2c0df999-81ec-4a35-a1f9-b93afee8c6ad'
|
||||
+)
|
||||
+SECOND_KERNEL_ROOT = 'UUID=1aa15850-2685-418d-95a6-f7266a2de83b'
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(
|
||||
+ 'second_grubby_output',
|
||||
+ (
|
||||
+ TEMPLATE_GRUBBY_INFO_OUTPUT.format(SECOND_KERNEL_ARGS, SECOND_KERNEL_ROOT),
|
||||
+ TEMPLATE_GRUBBY_INFO_OUTPUT.format(SAMPLE_KERNEL_ARGS, SECOND_KERNEL_ROOT),
|
||||
+ TEMPLATE_GRUBBY_INFO_OUTPUT.format(SECOND_KERNEL_ARGS, SAMPLE_KERNEL_ROOT),
|
||||
+ )
|
||||
+)
|
||||
+def test_kernelcmdline_config_mutiple_args(monkeypatch, second_grubby_output):
|
||||
+ kernel_img_path = '/boot/vmlinuz-X'
|
||||
+ kernel_info = InstalledTargetKernelInfo(pkg_nevra=TARGET_KERNEL_NEVRA,
|
||||
+ uname_r='',
|
||||
+ kernel_img_path=kernel_img_path,
|
||||
+ initramfs_path='/boot/initramfs-X')
|
||||
+
|
||||
+ # For this test, we need to check we get the proper report if grubby --info
|
||||
+ # outputs multiple different `root=` or `args=`
|
||||
+ # and that the first ones are used
|
||||
+ grubby_info_output = "\n".join((SAMPLE_GRUBBY_INFO_OUTPUT, second_grubby_output))
|
||||
+
|
||||
+ mocked_run = MockedRun(
|
||||
+ outputs={" ".join(("grubby", "--info", kernel_img_path)): grubby_info_output,
|
||||
+ }
|
||||
+ )
|
||||
+ monkeypatch.setattr(stdlib, 'run', mocked_run)
|
||||
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked())
|
||||
+ monkeypatch.setattr(reporting, "create_report", create_report_mocked())
|
||||
+
|
||||
+ root, args = kernelcmdlineconfig.retrieve_args_for_default_kernel(kernel_info)
|
||||
+ assert root == SAMPLE_KERNEL_ROOT
|
||||
+ assert args == SAMPLE_KERNEL_ARGS
|
||||
+ assert reporting.create_report.called == 1
|
||||
+ expected_title = 'Ensure that expected default kernel cmdline arguments are set'
|
||||
+ assert expected_title in reporting.create_report.report_fields['title']
|
||||
+
|
||||
+
|
||||
def test_kernelcmdline_config_malformed_args(monkeypatch):
|
||||
kernel_img_path = '/boot/vmlinuz-X'
|
||||
kernel_info = InstalledTargetKernelInfo(pkg_nevra=TARGET_KERNEL_NEVRA,
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
From a2a3dfb9b14f9582b4c895bda28a3ecb604ea737 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 18:34:34 +0100
|
||||
Subject: [PATCH 12/44] blsgrubcfgonppc64: Respect distro name in reports
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../libraries/blsgrubcfgonppc64.py | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/checkblsgrubcfgonppc64/libraries/blsgrubcfgonppc64.py b/repos/system_upgrade/el8toel9/actors/checkblsgrubcfgonppc64/libraries/blsgrubcfgonppc64.py
|
||||
index d723df65..58d15e25 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/checkblsgrubcfgonppc64/libraries/blsgrubcfgonppc64.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/checkblsgrubcfgonppc64/libraries/blsgrubcfgonppc64.py
|
||||
@@ -1,6 +1,7 @@
|
||||
from leapp import reporting
|
||||
from leapp.libraries.common import grub
|
||||
from leapp.libraries.common.config import architecture
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import DefaultGrubInfo, FirmwareFacts, GrubCfgBios
|
||||
|
||||
@@ -31,8 +32,9 @@ def process():
|
||||
'Leapp cannot continue with upgrade on "ppc64le" bare metal systems'
|
||||
),
|
||||
reporting.Summary(
|
||||
- 'In-place upgrade to RHEL 9 is not supported on POWER8 and POWER9 bare metal systems. '
|
||||
- 'For more information, refer to the following article: {}'.format(URL)
|
||||
+ f'In-place upgrade to {DISTRO_REPORT_NAMES.target} 9 is not'
|
||||
+ ' supported on POWER8 and POWER9 bare metal systems. For more'
|
||||
+ ' information, refer to the attached article.'
|
||||
),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups(['inhibitor']),
|
||||
@@ -54,8 +56,9 @@ def process():
|
||||
'On "ppc64le" systems with BLS enabled, the GRUB configuration is not '
|
||||
'properly converted after the upgrade and Leapp has to run "grub2-mkconfig" '
|
||||
'-o /boot/grub2/grub.cfg command in order to fix an issue with booting into '
|
||||
- 'the RHEL 8 kernel instead of RHEL 9.'
|
||||
-
|
||||
+ 'the {source_distro} 8 kernel instead of {target_distro} 9.'.format_map(
|
||||
+ DISTRO_REPORT_NAMES
|
||||
+ )
|
||||
),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups([reporting.Groups.BOOT]),
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,216 @@
|
||||
From 053137c50d1b060f9e6e6e45d82196b1045391b7 Mon Sep 17 00:00:00 2001
|
||||
From: mhecko <mhecko@redhat.com>
|
||||
Date: Thu, 4 Apr 2024 14:22:48 +0200
|
||||
Subject: [PATCH 12/40] check_microarch: refactor to handle possible future
|
||||
reqs
|
||||
|
||||
---
|
||||
.../actors/checkmicroarchitecture/actor.py | 0
|
||||
.../libraries/checkmicroarchitecture.py | 73 +++++++++++++++++++
|
||||
.../tests/test_checkmicroarchitecture.py | 21 ++++--
|
||||
.../libraries/checkmicroarchitecture.py | 46 ------------
|
||||
4 files changed, 87 insertions(+), 53 deletions(-)
|
||||
rename repos/system_upgrade/{el8toel9 => common}/actors/checkmicroarchitecture/actor.py (100%)
|
||||
create mode 100644 repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
rename repos/system_upgrade/{el8toel9 => common}/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py (79%)
|
||||
delete mode 100644 repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/actor.py b/repos/system_upgrade/common/actors/checkmicroarchitecture/actor.py
|
||||
similarity index 100%
|
||||
rename from repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/actor.py
|
||||
rename to repos/system_upgrade/common/actors/checkmicroarchitecture/actor.py
|
||||
diff --git a/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py b/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
new file mode 100644
|
||||
index 00000000..cc617203
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
@@ -0,0 +1,73 @@
|
||||
+from collections import namedtuple
|
||||
+
|
||||
+from leapp import reporting
|
||||
+from leapp.libraries.common.config.architecture import ARCH_X86_64, matches_architecture
|
||||
+from leapp.libraries.common.config.version import get_target_major_version
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import CPUInfo
|
||||
+
|
||||
+X86_64_BASELINE_FLAGS = ['cmov', 'cx8', 'fpu', 'fxsr', 'mmx', 'syscall', 'sse', 'sse2']
|
||||
+X86_64_V2_FLAGS = ['cx16', 'lahf_lm', 'popcnt', 'pni', 'sse4_1', 'sse4_2', 'ssse3']
|
||||
+
|
||||
+MicroarchInfo = namedtuple('MicroarchInfo', ('required_flags', 'extra_report_fields', 'microarch_ver'))
|
||||
+
|
||||
+
|
||||
+def _inhibit_upgrade(missing_flags, target_rhel, microarch_ver, extra_report_fields=None):
|
||||
+ title = 'Current x86-64 microarchitecture is unsupported in {0}'.format(target_rhel)
|
||||
+ summary = ('{0} has a higher CPU requirement than older versions, it now requires a CPU '
|
||||
+ 'compatible with {1} instruction set or higher.\n\n'
|
||||
+ 'Missings flags detected are: {2}\n'.format(target_rhel, microarch_ver, ', '.join(missing_flags)))
|
||||
+
|
||||
+ report_fields = [
|
||||
+ reporting.Title(title),
|
||||
+ reporting.Summary(summary),
|
||||
+ reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
+ reporting.Groups([reporting.Groups.SANITY]),
|
||||
+ reporting.Remediation(hint=('If case of using virtualization, virtualization platforms often allow '
|
||||
+ 'configuring a minimum denominator CPU model for compatibility when migrating '
|
||||
+ 'between different CPU models. Ensure that minimum requirements are not below '
|
||||
+ 'that of {0}\n').format(target_rhel)),
|
||||
+ ]
|
||||
+
|
||||
+ if extra_report_fields:
|
||||
+ report_fields += extra_report_fields
|
||||
+
|
||||
+ reporting.create_report(report_fields)
|
||||
+
|
||||
+
|
||||
+def process():
|
||||
+ """
|
||||
+ Check whether the processor matches the required microarchitecture.
|
||||
+ """
|
||||
+
|
||||
+ if not matches_architecture(ARCH_X86_64):
|
||||
+ api.current_logger().info('Architecture not x86-64. Skipping microarchitecture test.')
|
||||
+ return
|
||||
+
|
||||
+ cpuinfo = next(api.consume(CPUInfo))
|
||||
+
|
||||
+ rhel9_microarch_article = reporting.ExternalLink(
|
||||
+ title='Building Red Hat Enterprise Linux 9 for the x86-64-v2 microarchitecture level',
|
||||
+ url='https://red.ht/rhel-9-intel-microarchitectures'
|
||||
+ )
|
||||
+
|
||||
+ rhel_major_to_microarch_reqs = {
|
||||
+ '9': MicroarchInfo(microarch_ver='x86-64-v2',
|
||||
+ required_flags=(X86_64_BASELINE_FLAGS + X86_64_V2_FLAGS),
|
||||
+ extra_report_fields=[rhel9_microarch_article]),
|
||||
+ }
|
||||
+
|
||||
+ microarch_info = rhel_major_to_microarch_reqs.get(get_target_major_version())
|
||||
+ if not microarch_info:
|
||||
+ api.current_logger().info('No known microarchitecture requirements are known for target RHEL%s.',
|
||||
+ get_target_major_version())
|
||||
+ return
|
||||
+
|
||||
+ missing_flags = [flag for flag in microarch_info.required_flags if flag not in cpuinfo.flags]
|
||||
+ api.current_logger().debug('Required flags missing: %s', missing_flags)
|
||||
+ if missing_flags:
|
||||
+ _inhibit_upgrade(missing_flags,
|
||||
+ 'RHEL{0}'.format(get_target_major_version()),
|
||||
+ microarch_info.microarch_ver,
|
||||
+ extra_report_fields=microarch_info.extra_report_fields)
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py b/repos/system_upgrade/common/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
|
||||
similarity index 79%
|
||||
rename from repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
|
||||
rename to repos/system_upgrade/common/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
|
||||
index b7c850d9..b0624f2b 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
|
||||
@@ -25,7 +25,13 @@ def test_not_x86_64_passes(monkeypatch, arch):
|
||||
assert not reporting.create_report.called
|
||||
|
||||
|
||||
-def test_valid_microarchitecture(monkeypatch):
|
||||
+@pytest.mark.parametrize(
|
||||
+ ('target_ver', 'cpu_flags'),
|
||||
+ [
|
||||
+ ('9.0', checkmicroarchitecture.X86_64_BASELINE_FLAGS + checkmicroarchitecture.X86_64_V2_FLAGS)
|
||||
+ ]
|
||||
+)
|
||||
+def test_valid_microarchitecture(monkeypatch, target_ver, cpu_flags):
|
||||
"""
|
||||
Test no report is generated on a valid microarchitecture
|
||||
"""
|
||||
@@ -33,9 +39,8 @@ def test_valid_microarchitecture(monkeypatch):
|
||||
monkeypatch.setattr(reporting, "create_report", create_report_mocked())
|
||||
monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
||||
|
||||
- required_flags = checkmicroarchitecture.X86_64_BASELINE_FLAGS + checkmicroarchitecture.X86_64_V2_FLAGS
|
||||
- monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_X86_64,
|
||||
- msgs=[CPUInfo(flags=required_flags)]))
|
||||
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_X86_64, dst_ver=target_ver,
|
||||
+ msgs=[CPUInfo(flags=cpu_flags)]))
|
||||
|
||||
checkmicroarchitecture.process()
|
||||
|
||||
@@ -43,14 +48,16 @@ def test_valid_microarchitecture(monkeypatch):
|
||||
assert not reporting.create_report.called
|
||||
|
||||
|
||||
-def test_invalid_microarchitecture(monkeypatch):
|
||||
+@pytest.mark.parametrize('target_ver', ['9.0'])
|
||||
+def test_invalid_microarchitecture(monkeypatch, target_ver):
|
||||
"""
|
||||
Test report is generated on x86-64 architecture with invalid microarchitecture and the upgrade is inhibited
|
||||
"""
|
||||
|
||||
monkeypatch.setattr(reporting, "create_report", create_report_mocked())
|
||||
monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
||||
- monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_X86_64, msgs=[CPUInfo()]))
|
||||
+ monkeypatch.setattr(api, 'current_actor',
|
||||
+ CurrentActorMocked(arch=ARCH_X86_64, msgs=[CPUInfo()], dst_ver=target_ver))
|
||||
|
||||
checkmicroarchitecture.process()
|
||||
|
||||
@@ -60,6 +67,6 @@ def test_invalid_microarchitecture(monkeypatch):
|
||||
assert 'Architecture not x86-64. Skipping microarchitecture test.' not in api.current_logger().infomsg
|
||||
assert reporting.create_report.called == 1
|
||||
assert 'microarchitecture is unsupported' in produced_title
|
||||
- assert 'RHEL9 has a higher CPU requirement' in produced_summary
|
||||
+ assert 'has a higher CPU requirement' in produced_summary
|
||||
assert reporting.create_report.report_fields['severity'] == reporting.Severity.HIGH
|
||||
assert is_inhibitor(reporting.create_report.report_fields)
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py b/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
deleted file mode 100644
|
||||
index 9c083d7e..00000000
|
||||
--- a/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
+++ /dev/null
|
||||
@@ -1,46 +0,0 @@
|
||||
-from leapp import reporting
|
||||
-from leapp.libraries.common.config.architecture import ARCH_X86_64, matches_architecture
|
||||
-from leapp.libraries.stdlib import api
|
||||
-from leapp.models import CPUInfo
|
||||
-
|
||||
-X86_64_BASELINE_FLAGS = ['cmov', 'cx8', 'fpu', 'fxsr', 'mmx', 'syscall', 'sse', 'sse2']
|
||||
-X86_64_V2_FLAGS = ['cx16', 'lahf_lm', 'popcnt', 'pni', 'sse4_1', 'sse4_2', 'ssse3']
|
||||
-
|
||||
-
|
||||
-def _inhibit_upgrade(missing_flags):
|
||||
- title = 'Current x86-64 microarchitecture is unsupported in RHEL9'
|
||||
- summary = ('RHEL9 has a higher CPU requirement than older versions, it now requires a CPU '
|
||||
- 'compatible with x86-64-v2 instruction set or higher.\n\n'
|
||||
- 'Missings flags detected are: {}\n'.format(', '.join(missing_flags)))
|
||||
-
|
||||
- reporting.create_report([
|
||||
- reporting.Title(title),
|
||||
- reporting.Summary(summary),
|
||||
- reporting.ExternalLink(title='Building Red Hat Enterprise Linux 9 for the x86-64-v2 microarchitecture level',
|
||||
- url='https://red.ht/rhel-9-intel-microarchitectures'),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
- reporting.Groups([reporting.Groups.SANITY]),
|
||||
- reporting.Remediation(hint=('If case of using virtualization, virtualization platforms often allow '
|
||||
- 'configuring a minimum denominator CPU model for compatibility when migrating '
|
||||
- 'between different CPU models. Ensure that minimum requirements are not below '
|
||||
- 'that of RHEL9\n')),
|
||||
- ])
|
||||
-
|
||||
-
|
||||
-def process():
|
||||
- """
|
||||
- Check whether the processor matches the required microarchitecture.
|
||||
- """
|
||||
-
|
||||
- if not matches_architecture(ARCH_X86_64):
|
||||
- api.current_logger().info('Architecture not x86-64. Skipping microarchitecture test.')
|
||||
- return
|
||||
-
|
||||
- cpuinfo = next(api.consume(CPUInfo))
|
||||
-
|
||||
- required_flags = X86_64_BASELINE_FLAGS + X86_64_V2_FLAGS
|
||||
- missing_flags = [flag for flag in required_flags if flag not in cpuinfo.flags]
|
||||
- api.current_logger().debug('Required flags missing: %s', missing_flags)
|
||||
- if missing_flags:
|
||||
- _inhibit_upgrade(missing_flags)
|
||||
--
|
||||
2.47.0
|
||||
|
||||
133
SOURCES/0013-check_microarch-add-rhel10-requirements.patch
Normal file
133
SOURCES/0013-check_microarch-add-rhel10-requirements.patch
Normal file
@ -0,0 +1,133 @@
|
||||
From d3ebc990ba65801fbed2aaf1dce8329698667d1c Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Wed, 28 Aug 2024 12:18:40 +0200
|
||||
Subject: [PATCH 13/40] check_microarch: add rhel10 requirements
|
||||
|
||||
---
|
||||
.../actors/checkmicroarchitecture/actor.py | 13 ++++++++++--
|
||||
.../libraries/checkmicroarchitecture.py | 8 +++++--
|
||||
.../tests/test_checkmicroarchitecture.py | 21 ++++++++++++++-----
|
||||
3 files changed, 33 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/checkmicroarchitecture/actor.py b/repos/system_upgrade/common/actors/checkmicroarchitecture/actor.py
|
||||
index 98ffea80..bb342f2f 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkmicroarchitecture/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkmicroarchitecture/actor.py
|
||||
@@ -17,7 +17,8 @@ class CheckMicroarchitecture(Actor):
|
||||
levels.
|
||||
|
||||
RHEL9 has a higher CPU requirement than older versions, it now requires a
|
||||
- CPU compatible with ``x86-64-v2`` instruction set or higher.
|
||||
+ CPU compatible with ``x86-64-v2`` instruction set or higher. Similarly,
|
||||
+ RHEL10 requires at least ``x86-64-v3`` instruction set.
|
||||
|
||||
.. table:: Required CPU features by microarchitecure level with a
|
||||
corresponding flag as shown by ``lscpu``.
|
||||
@@ -43,7 +44,15 @@ class CheckMicroarchitecture(Actor):
|
||||
| | SSE4_2 | sse4_2 |
|
||||
| | SSSE3 | ssse3 |
|
||||
+------------+-------------+--------------------+
|
||||
- | ... | | |
|
||||
+ | x86-64-v3 | AVX | avx |
|
||||
+ | | AVX2 | avx2 |
|
||||
+ | | BMI1 | bmi1 |
|
||||
+ | | BMI2 | bmi2 |
|
||||
+ | | F16C | f16c |
|
||||
+ | | FMA | fma |
|
||||
+ | | LZCNT | abm |
|
||||
+ | | MOVBE | movbe |
|
||||
+ | | OSXSAVE | xsave |
|
||||
+------------+-------------+--------------------+
|
||||
|
||||
Note: To get the corresponding flag for the CPU feature consult the file
|
||||
diff --git a/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py b/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
index cc617203..94e85e3e 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
@@ -8,6 +8,7 @@ from leapp.models import CPUInfo
|
||||
|
||||
X86_64_BASELINE_FLAGS = ['cmov', 'cx8', 'fpu', 'fxsr', 'mmx', 'syscall', 'sse', 'sse2']
|
||||
X86_64_V2_FLAGS = ['cx16', 'lahf_lm', 'popcnt', 'pni', 'sse4_1', 'sse4_2', 'ssse3']
|
||||
+X86_64_V3_FLAGS = ['avx2', 'bmi1', 'bmi2', 'f16c', 'fma', 'abm', 'movbe', 'xsave']
|
||||
|
||||
MicroarchInfo = namedtuple('MicroarchInfo', ('required_flags', 'extra_report_fields', 'microarch_ver'))
|
||||
|
||||
@@ -16,7 +17,7 @@ def _inhibit_upgrade(missing_flags, target_rhel, microarch_ver, extra_report_fie
|
||||
title = 'Current x86-64 microarchitecture is unsupported in {0}'.format(target_rhel)
|
||||
summary = ('{0} has a higher CPU requirement than older versions, it now requires a CPU '
|
||||
'compatible with {1} instruction set or higher.\n\n'
|
||||
- 'Missings flags detected are: {2}\n'.format(target_rhel, microarch_ver, ', '.join(missing_flags)))
|
||||
+ 'Missings flags detected are: {2}\n').format(target_rhel, microarch_ver, ', '.join(missing_flags))
|
||||
|
||||
report_fields = [
|
||||
reporting.Title(title),
|
||||
@@ -24,7 +25,7 @@ def _inhibit_upgrade(missing_flags, target_rhel, microarch_ver, extra_report_fie
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
reporting.Groups([reporting.Groups.SANITY]),
|
||||
- reporting.Remediation(hint=('If case of using virtualization, virtualization platforms often allow '
|
||||
+ reporting.Remediation(hint=('If a case of using virtualization, virtualization platforms often allow '
|
||||
'configuring a minimum denominator CPU model for compatibility when migrating '
|
||||
'between different CPU models. Ensure that minimum requirements are not below '
|
||||
'that of {0}\n').format(target_rhel)),
|
||||
@@ -56,6 +57,9 @@ def process():
|
||||
'9': MicroarchInfo(microarch_ver='x86-64-v2',
|
||||
required_flags=(X86_64_BASELINE_FLAGS + X86_64_V2_FLAGS),
|
||||
extra_report_fields=[rhel9_microarch_article]),
|
||||
+ '10': MicroarchInfo(microarch_ver='x86-64-v3',
|
||||
+ required_flags=(X86_64_BASELINE_FLAGS + X86_64_V2_FLAGS + X86_64_V3_FLAGS),
|
||||
+ extra_report_fields=[]),
|
||||
}
|
||||
|
||||
microarch_info = rhel_major_to_microarch_reqs.get(get_target_major_version())
|
||||
diff --git a/repos/system_upgrade/common/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py b/repos/system_upgrade/common/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
|
||||
index b0624f2b..eeca8be0 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
|
||||
@@ -25,10 +25,15 @@ def test_not_x86_64_passes(monkeypatch, arch):
|
||||
assert not reporting.create_report.called
|
||||
|
||||
|
||||
+ENTIRE_V2_FLAG_SET = checkmicroarchitecture.X86_64_BASELINE_FLAGS + checkmicroarchitecture.X86_64_V2_FLAGS
|
||||
+ENTIRE_V3_FLAG_SET = ENTIRE_V2_FLAG_SET + checkmicroarchitecture.X86_64_V3_FLAGS
|
||||
+
|
||||
+
|
||||
@pytest.mark.parametrize(
|
||||
('target_ver', 'cpu_flags'),
|
||||
[
|
||||
- ('9.0', checkmicroarchitecture.X86_64_BASELINE_FLAGS + checkmicroarchitecture.X86_64_V2_FLAGS)
|
||||
+ ('9.0', ENTIRE_V2_FLAG_SET),
|
||||
+ ('10.0', ENTIRE_V3_FLAG_SET)
|
||||
]
|
||||
)
|
||||
def test_valid_microarchitecture(monkeypatch, target_ver, cpu_flags):
|
||||
@@ -48,16 +53,22 @@ def test_valid_microarchitecture(monkeypatch, target_ver, cpu_flags):
|
||||
assert not reporting.create_report.called
|
||||
|
||||
|
||||
-@pytest.mark.parametrize('target_ver', ['9.0'])
|
||||
-def test_invalid_microarchitecture(monkeypatch, target_ver):
|
||||
+@pytest.mark.parametrize(
|
||||
+ ('target_ver', 'cpu_flags'),
|
||||
+ (
|
||||
+ ('9.0', checkmicroarchitecture.X86_64_BASELINE_FLAGS),
|
||||
+ ('10.0', ENTIRE_V2_FLAG_SET),
|
||||
+ )
|
||||
+)
|
||||
+def test_invalid_microarchitecture(monkeypatch, target_ver, cpu_flags):
|
||||
"""
|
||||
Test report is generated on x86-64 architecture with invalid microarchitecture and the upgrade is inhibited
|
||||
"""
|
||||
-
|
||||
+ cpu_info = CPUInfo(flags=cpu_flags)
|
||||
monkeypatch.setattr(reporting, "create_report", create_report_mocked())
|
||||
monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
||||
monkeypatch.setattr(api, 'current_actor',
|
||||
- CurrentActorMocked(arch=ARCH_X86_64, msgs=[CPUInfo()], dst_ver=target_ver))
|
||||
+ CurrentActorMocked(arch=ARCH_X86_64, msgs=[cpu_info], dst_ver=target_ver))
|
||||
|
||||
checkmicroarchitecture.process()
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
From b43ed18a6e4cea273def17c83c0c8d1742ba5145 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 16:16:17 +0100
|
||||
Subject: [PATCH 13/44] checkselinux: Respect distro name in report
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../common/actors/checkselinux/libraries/checkselinux.py | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/checkselinux/libraries/checkselinux.py b/repos/system_upgrade/common/actors/checkselinux/libraries/checkselinux.py
|
||||
index 2ef914ac..dbd79adf 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkselinux/libraries/checkselinux.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkselinux/libraries/checkselinux.py
|
||||
@@ -1,5 +1,6 @@
|
||||
from leapp import reporting
|
||||
from leapp.libraries.common.config.version import get_target_major_version
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import KernelCmdlineArg, SELinuxFacts, SelinuxPermissiveDecision, SelinuxRelabelDecision
|
||||
|
||||
@@ -20,10 +21,10 @@ def process():
|
||||
reporting.create_report([
|
||||
reporting.Title('LEAPP detected SELinux disabled in "/etc/selinux/config"'),
|
||||
reporting.Summary(
|
||||
- 'On RHEL 9, disabling SELinux in "/etc/selinux/config" is no longer possible. '
|
||||
- 'This way, the system starts with SELinux enabled but with no policy loaded. LEAPP '
|
||||
+ 'On {target_distro} 9, disabling SELinux in "/etc/selinux/config" is no longer possible. '
|
||||
+ 'This way, the system starts with SELinux enabled but with no policy loaded. Leapp '
|
||||
'will automatically disable SELinux using "SELINUX=0" kernel command line parameter. '
|
||||
- 'However, Red Hat strongly recommends to have SELinux enabled'
|
||||
+ 'However, it is strongly recommended to have SELinux enabled'.format_map(DISTRO_REPORT_NAMES)
|
||||
),
|
||||
reporting.Severity(reporting.Severity.INFO),
|
||||
reporting.Groups([reporting.Groups.SELINUX]),
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
From a14793892bafaad0802844cbb56be3be3220eb47 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Wed, 25 Sep 2024 17:29:02 +0200
|
||||
Subject: [PATCH 14/40] Skip checking files under .../directory-hash/ dir
|
||||
|
||||
* The main reason for this change is to improve performance and
|
||||
reduce flood of logs for the content that does not seem to be important
|
||||
to check for the upgrade process.
|
||||
|
||||
The directory has been relatively recently added to ca-certificates
|
||||
rpm on EL 9+ systems mostly to improve performance of OpenSSL and
|
||||
the content does not seem to be important for the IPU process.
|
||||
The high number of files takes too much time to evaluate and causes
|
||||
flood of logs that are not important.
|
||||
|
||||
This is updated solution that we drop originally: 60f500e59bb92
|
||||
---
|
||||
.../targetuserspacecreator/libraries/userspacegen.py | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
index cd2d7d6e..d7698056 100644
|
||||
--- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
+++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
@@ -311,6 +311,16 @@ def _get_files_owned_by_rpms(context, dirpath, pkgs=None, recursive=False):
|
||||
searchdir = context.full_path(dirpath)
|
||||
if recursive:
|
||||
for root, _, files in os.walk(searchdir):
|
||||
+ if '/directory-hash/' in root:
|
||||
+ # tl;dr; for the performance improvement
|
||||
+ # The directory has been relatively recently added to ca-certificates
|
||||
+ # rpm on EL 9+ systems and the content does not seem to be important
|
||||
+ # for the IPU process. Also, it contains high number of files and
|
||||
+ # their processing floods the output and slows down IPU.
|
||||
+ # So skipping it entirely.
|
||||
+ # This is updated solution that we drop originally: 60f500e59bb92
|
||||
+ api.current_logger().debug('SKIP files in the {} directory: Not important for the IPU.'.format(root))
|
||||
+ continue
|
||||
for filename in files:
|
||||
relpath = os.path.relpath(os.path.join(root, filename), searchdir)
|
||||
file_list.append(relpath)
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
From 60e54a82da37bb0d2f1bee1a35d1d7fa01cf3df7 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 16:44:04 +0100
|
||||
Subject: [PATCH 14/44] checkosrelease: Respect distro name in report
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../common/actors/checkosrelease/actor.py | 2 +-
|
||||
.../actors/checkosrelease/libraries/checkosrelease.py | 10 +++++++---
|
||||
.../actors/checkosrelease/tests/test_checkosrelease.py | 4 +++-
|
||||
3 files changed, 11 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/checkosrelease/actor.py b/repos/system_upgrade/common/actors/checkosrelease/actor.py
|
||||
index 7747eb9b..8c60d968 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkosrelease/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkosrelease/actor.py
|
||||
@@ -6,7 +6,7 @@ from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
|
||||
class CheckOSRelease(Actor):
|
||||
"""
|
||||
- Check if the current RHEL minor version is supported. If not, inhibit the upgrade process.
|
||||
+ Check if the current distro version is supported. If not, inhibit the upgrade process.
|
||||
|
||||
This check can be skipped by using the LEAPP_DEVEL_SKIP_CHECK_OS_RELEASE environment variable.
|
||||
"""
|
||||
diff --git a/repos/system_upgrade/common/actors/checkosrelease/libraries/checkosrelease.py b/repos/system_upgrade/common/actors/checkosrelease/libraries/checkosrelease.py
|
||||
index 1ee6e6ab..1ab89a8d 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkosrelease/libraries/checkosrelease.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkosrelease/libraries/checkosrelease.py
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
|
||||
from leapp import reporting
|
||||
from leapp.libraries.common.config import version
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
|
||||
COMMON_REPORT_TAGS = [reporting.Groups.SANITY]
|
||||
FMT_LIST_SEPARATOR = '\n - '
|
||||
@@ -14,7 +15,9 @@ def skip_check():
|
||||
if os.getenv('LEAPP_DEVEL_SKIP_CHECK_OS_RELEASE'):
|
||||
reporting.create_report([
|
||||
reporting.Title('Skipped OS release check'),
|
||||
- reporting.Summary('Source RHEL release check skipped via LEAPP_DEVEL_SKIP_CHECK_OS_RELEASE env var.'),
|
||||
+ reporting.Summary(
|
||||
+ 'Source system release check skipped via LEAPP_DEVEL_SKIP_CHECK_OS_RELEASE env variable.'
|
||||
+ ),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups(COMMON_REPORT_TAGS)
|
||||
] + related)
|
||||
@@ -24,7 +27,7 @@ def skip_check():
|
||||
|
||||
|
||||
def check_os_version():
|
||||
- """ Check the RHEL minor version and inhibit the upgrade if it does not match the supported ones """
|
||||
+ """ Check the distro version and inhibit the upgrade if it does not match the supported ones """
|
||||
if not version.is_supported_version():
|
||||
supported_releases = []
|
||||
for rel in version.SUPPORTED_VERSIONS:
|
||||
@@ -33,7 +36,8 @@ def check_os_version():
|
||||
current_release = ' '.join(version.current_version()).upper()
|
||||
reporting.create_report([
|
||||
reporting.Title(
|
||||
- 'The installed OS version is not supported for the in-place upgrade to the target RHEL version'
|
||||
+ 'The installed OS version is not supported for the in-place upgrade'
|
||||
+ ' to the target {target_distro} version'.format_map(DISTRO_REPORT_NAMES)
|
||||
),
|
||||
reporting.Summary(
|
||||
'The supported OS releases for the upgrade process:'
|
||||
diff --git a/repos/system_upgrade/common/actors/checkosrelease/tests/test_checkosrelease.py b/repos/system_upgrade/common/actors/checkosrelease/tests/test_checkosrelease.py
|
||||
index 1ca8a1d7..c1c43065 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkosrelease/tests/test_checkosrelease.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkosrelease/tests/test_checkosrelease.py
|
||||
@@ -3,7 +3,8 @@ import os
|
||||
from leapp import reporting
|
||||
from leapp.libraries.actor import checkosrelease
|
||||
from leapp.libraries.common.config import version
|
||||
-from leapp.libraries.common.testutils import create_report_mocked, produce_mocked
|
||||
+from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked, produce_mocked
|
||||
+from leapp.libraries.stdlib import api
|
||||
from leapp.utils.report import is_inhibitor
|
||||
|
||||
|
||||
@@ -26,6 +27,7 @@ def test_no_skip_check(monkeypatch):
|
||||
|
||||
|
||||
def test_not_supported_release(monkeypatch):
|
||||
+ monkeypatch.setattr(api, "current_actor", CurrentActorMocked())
|
||||
monkeypatch.setattr(version, "is_supported_version", lambda: False)
|
||||
monkeypatch.setattr(version, "get_source_major_version", lambda: '8')
|
||||
monkeypatch.setattr(version, "current_version", lambda: ('bad', '8'))
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
From cef2825778eb63f95e13cf48b1683bc98c32c21b Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Fri, 25 Oct 2024 16:33:38 +0200
|
||||
Subject: [PATCH 15/40] lib(overlay): cap the max size of disk images
|
||||
|
||||
On systems with large disks (e.g. 16TB) with lots of free space, leapp
|
||||
might attemt to create files larger than the max file size of the
|
||||
underlying FS. Attempting to create such large files causes leapp
|
||||
to crash. This patch caps the max image size to 1TB, based on empirical
|
||||
evidence that more free space is not needed for the upgrade RPM
|
||||
transaction.
|
||||
|
||||
Jira-ref: RHEL-57064
|
||||
---
|
||||
.../common/libraries/overlaygen.py | 28 +++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/libraries/overlaygen.py b/repos/system_upgrade/common/libraries/overlaygen.py
|
||||
index c1ac9ad3..867e3559 100644
|
||||
--- a/repos/system_upgrade/common/libraries/overlaygen.py
|
||||
+++ b/repos/system_upgrade/common/libraries/overlaygen.py
|
||||
@@ -68,6 +68,27 @@ or close to that size, stay always with this minimal protected size defined by
|
||||
this constant.
|
||||
"""
|
||||
|
||||
+_MAX_DISK_IMAGE_SIZE_MB = 2**20 # 1*TB
|
||||
+"""
|
||||
+Maximum size of the created (sparse) images.
|
||||
+
|
||||
+Defaults to 1TB. If a disk with capacity larger than _MAX_DISK_IMAGE_SIZE_MB
|
||||
+is mounted on the system, the corresponding image used to store overlay
|
||||
+modifications will be capped to _MAX_DISK_IMAGE_SIZE_MB.
|
||||
+
|
||||
+Engineering rationale:
|
||||
+ This constant was introduced to prevent leapp from creating files that are
|
||||
+ virtually larger than the maximum file size supported by the file system.
|
||||
+ E.g. if the source system hosts /var/lib/leapp on EXT4, then we cannot
|
||||
+ create a file larger than 16TB.
|
||||
+ We create these "disk images" to be able to verify the system has enough
|
||||
+ disk space to perform the RPM upgrade transaction. From our experience,
|
||||
+ we are not aware of any system which could have installed so much content
|
||||
+ by RPMs that we would need 1TB of the free space on a single FS. Therefore,
|
||||
+ we consider this value as safe while preventing us from exceeding FS
|
||||
+ limits.
|
||||
+"""
|
||||
+
|
||||
|
||||
MountPoints = namedtuple('MountPoints', ['fs_file', 'fs_vfstype'])
|
||||
|
||||
@@ -287,6 +308,13 @@ def _prepare_required_mounts(scratch_dir, mounts_dir, storage_info, scratch_rese
|
||||
disk_size = _get_fspace(mountpoint, convert_to_mibs=True, coefficient=0.95)
|
||||
if mountpoint == scratch_mp:
|
||||
disk_size = scratch_disk_size
|
||||
+
|
||||
+ if disk_size > _MAX_DISK_IMAGE_SIZE_MB:
|
||||
+ msg = ('Image for overlayfs corresponding to the disk mounted at %s would ideally have %d MB, '
|
||||
+ 'but we truncate it to %d MB to avoid bumping to max file limits.')
|
||||
+ api.current_logger().info(msg, mountpoint, disk_size, _MAX_DISK_IMAGE_SIZE_MB)
|
||||
+ disk_size = _MAX_DISK_IMAGE_SIZE_MB
|
||||
+
|
||||
image = _create_mount_disk_image(disk_images_directory, mountpoint, disk_size)
|
||||
result[mountpoint] = mounting.LoopMount(
|
||||
source=image,
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,113 +0,0 @@
|
||||
From ce379f96f128b60d93e02f95351e2f718940d2f2 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Mon, 23 Feb 2026 12:45:59 +0100
|
||||
Subject: [PATCH 15/44] rocecheck: Remove outadated check for source version
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../actors/rocecheck/libraries/rocecheck.py | 35 ++-----------------
|
||||
.../rocecheck/tests/unit_test_rocecheck.py | 22 ------------
|
||||
2 files changed, 3 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/rocecheck/libraries/rocecheck.py b/repos/system_upgrade/el8toel9/actors/rocecheck/libraries/rocecheck.py
|
||||
index 7549feb8..0ed2046a 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/rocecheck/libraries/rocecheck.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/rocecheck/libraries/rocecheck.py
|
||||
@@ -1,6 +1,6 @@
|
||||
from leapp import reporting
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
-from leapp.libraries.common.config import architecture, version
|
||||
+from leapp.libraries.common.config import architecture
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import KernelCmdline, RoceDetected
|
||||
|
||||
@@ -37,36 +37,8 @@ def _fmt_list(items):
|
||||
return ''.join([FMT_LIST_SEPARATOR.format(i) for i in items])
|
||||
|
||||
|
||||
-def _report_old_version(roce):
|
||||
+def _report_wrong_setup(roce):
|
||||
roce_nics = roce.roce_nics_connected + roce.roce_nics_connecting
|
||||
- reporting.create_report([
|
||||
- reporting.Title('A newer version of RHEL 8 is required for the upgrade with RoCE.'),
|
||||
- reporting.Summary(
|
||||
- 'The RHEL 9 system uses different network schemes for NIC names'
|
||||
- ' than RHEL 8.'
|
||||
- ' RHEL {version} does not provide functionality to be able'
|
||||
- ' to set the system configuration in a way the network interface'
|
||||
- ' names used by RoCE are persistent on both (RHEL 8 and RHEL 9)'
|
||||
- ' systems.'
|
||||
- ' The in-place upgrade from the current version of RHEL to RHEL 9'
|
||||
- ' will break the RoCE network configuration.'
|
||||
- '\n\nRoCE detected on following NICs:{nics}'
|
||||
- .format(
|
||||
- version=version.get_source_version(),
|
||||
- nics=_fmt_list(roce_nics)
|
||||
- )
|
||||
- ),
|
||||
- reporting.Remediation(hint=(
|
||||
- 'Update the system to RHEL 8.8 or newer using DNF and then reboot'
|
||||
- ' the system prior the in-place upgrade to RHEL 9.'
|
||||
- )),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([
|
||||
- reporting.Groups.INHIBITOR,
|
||||
- reporting.Groups.ACCESSIBILITY,
|
||||
- reporting.Groups.SANITY,
|
||||
- ]),
|
||||
- ])
|
||||
|
||||
|
||||
def _report_wrong_setup(roce):
|
||||
@@ -128,7 +100,6 @@ def process():
|
||||
# No used RoCE detected - nothing to do
|
||||
api.current_logger().debug('Skipping RoCE checks: No RoCE card detected.')
|
||||
return
|
||||
- if version.matches_source_version('<= 8.6'):
|
||||
- _report_old_version(roce)
|
||||
+
|
||||
if not is_kernel_arg_set():
|
||||
_report_wrong_setup(roce)
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/rocecheck/tests/unit_test_rocecheck.py b/repos/system_upgrade/el8toel9/actors/rocecheck/tests/unit_test_rocecheck.py
|
||||
index b5511d17..70e4a7b3 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/rocecheck/tests/unit_test_rocecheck.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/rocecheck/tests/unit_test_rocecheck.py
|
||||
@@ -52,7 +52,6 @@ def test_roce_noibmz(monkeypatch, arch):
|
||||
|
||||
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=arch))
|
||||
monkeypatch.setattr(reporting, "create_report", create_report_mocked())
|
||||
- monkeypatch.setattr(rocecheck, '_report_old_version', mocked_do_not_call_me)
|
||||
monkeypatch.setattr(rocecheck, '_report_wrong_setup', mocked_do_not_call_me)
|
||||
monkeypatch.setattr(rocecheck, 'is_kernel_arg_set', mocked_do_not_call_me)
|
||||
monkeypatch.setattr(rocecheck.api, 'consume', mocked_do_not_call_me)
|
||||
@@ -76,27 +75,6 @@ def test_roce_ok(monkeypatch, msgs, version):
|
||||
assert not reporting.create_report.called
|
||||
|
||||
|
||||
-@pytest.mark.parametrize('msgs', (
|
||||
- [_kernel_cmdline(['net.naming-scheme=rhel-8.7']), _roce(['eno'], [])],
|
||||
- [_kernel_cmdline(['net.naming-scheme=rhel-8.7']), _roce([], ['eno'])],
|
||||
- [_kernel_cmdline(['net.naming-scheme=rhel-8.6']), _roce(['eno'], [])],
|
||||
- [_kernel_cmdline(['net.naming-scheme=rhel-8.6']), _roce(['eno', 'eno1'], ['enp'])],
|
||||
- [_kernel_cmdline(['foo=bar']), _roce(['eno'], [])],
|
||||
- [_kernel_cmdline(), _roce(['eno'], [])],
|
||||
-))
|
||||
-@pytest.mark.parametrize('version', ['8.0', '8.3', '8.6'])
|
||||
-def test_roce_old_rhel(monkeypatch, msgs, version):
|
||||
- curr_actor_mocked = CurrentActorMocked(arch=architecture.ARCH_S390X, src_ver=version, msgs=msgs)
|
||||
- monkeypatch.setattr(api, 'current_actor', curr_actor_mocked)
|
||||
- monkeypatch.setattr(reporting, "create_report", create_report_mocked())
|
||||
- rocecheck.process()
|
||||
- assert reporting.create_report.called
|
||||
- assert any(
|
||||
- 'version of RHEL' in report['title']
|
||||
- for report in reporting.create_report.reports
|
||||
- )
|
||||
-
|
||||
-
|
||||
# NOTE: what about the situation when net.naming-scheme is configured multiple times???
|
||||
@pytest.mark.parametrize('msgs', (
|
||||
[_kernel_cmdline(['net.naming-scheme=rhel-8.6']), _roce(['eno'], [])],
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,168 @@
|
||||
From ec078243771f8ef43853bd242175a612fe84f95b Mon Sep 17 00:00:00 2001
|
||||
From: tomasfratrik <tomasfratrik8@gmail.com>
|
||||
Date: Wed, 17 Jul 2024 12:12:50 +0200
|
||||
Subject: [PATCH 16/40] Raise proper error when ModelViolationError occurs
|
||||
|
||||
This error occurs when repo file has invalid definition, specifically
|
||||
when the 'name' entry of the config files is invalid. Also add tests.
|
||||
|
||||
Jira: RHEL-19249
|
||||
---
|
||||
.../systemfacts/libraries/systemfacts.py | 13 ++++++++-
|
||||
.../systemfacts/tests/test_systemfacts.py | 24 ++++++++++++++++-
|
||||
.../common/libraries/repofileutils.py | 17 +++++++++++-
|
||||
.../libraries/tests/test_repofileutils.py | 27 +++++++++++++++++++
|
||||
4 files changed, 78 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/systemfacts/libraries/systemfacts.py b/repos/system_upgrade/common/actors/systemfacts/libraries/systemfacts.py
|
||||
index d1eeb28c..f16cea1d 100644
|
||||
--- a/repos/system_upgrade/common/actors/systemfacts/libraries/systemfacts.py
|
||||
+++ b/repos/system_upgrade/common/actors/systemfacts/libraries/systemfacts.py
|
||||
@@ -217,7 +217,18 @@ def get_sysctls_status():
|
||||
|
||||
def get_repositories_status():
|
||||
""" Get a basic information about YUM repositories installed in the system """
|
||||
- return RepositoriesFacts(repositories=repofileutils.get_parsed_repofiles())
|
||||
+ try:
|
||||
+ return RepositoriesFacts(repositories=repofileutils.get_parsed_repofiles())
|
||||
+ except repofileutils.InvalidRepoDefinition as e:
|
||||
+ raise StopActorExecutionError(
|
||||
+ message=str(e),
|
||||
+ details={
|
||||
+ 'hint': 'For more directions on how to resolve the issue, see: {url}.'
|
||||
+ .format(
|
||||
+ url='https://access.redhat.com/solutions/6969001'
|
||||
+ )
|
||||
+ }
|
||||
+ )
|
||||
|
||||
|
||||
def get_selinux_status():
|
||||
diff --git a/repos/system_upgrade/common/actors/systemfacts/tests/test_systemfacts.py b/repos/system_upgrade/common/actors/systemfacts/tests/test_systemfacts.py
|
||||
index badf174c..5831b979 100644
|
||||
--- a/repos/system_upgrade/common/actors/systemfacts/tests/test_systemfacts.py
|
||||
+++ b/repos/system_upgrade/common/actors/systemfacts/tests/test_systemfacts.py
|
||||
@@ -3,7 +3,16 @@ import pwd
|
||||
|
||||
import pytest
|
||||
|
||||
-from leapp.libraries.actor.systemfacts import _get_system_groups, _get_system_users, anyendswith, anyhasprefix, aslist
|
||||
+from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.actor.systemfacts import (
|
||||
+ _get_system_groups,
|
||||
+ _get_system_users,
|
||||
+ anyendswith,
|
||||
+ anyhasprefix,
|
||||
+ aslist,
|
||||
+ get_repositories_status
|
||||
+)
|
||||
+from leapp.libraries.common import repofileutils
|
||||
from leapp.libraries.common.testutils import logger_mocked
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.snactor.fixture import current_actor_libraries
|
||||
@@ -116,3 +125,16 @@ def test_get_system_groups(monkeypatch, etc_group_names, skipped_group_names):
|
||||
assert group_name not in api.current_logger().dbgmsg[0]
|
||||
else:
|
||||
assert not api.current_logger().dbgmsg
|
||||
+
|
||||
+
|
||||
+def test_failed_parsed_repofiles(monkeypatch):
|
||||
+ def _raise_invalidrepo_error():
|
||||
+ raise repofileutils.InvalidRepoDefinition(msg='mocked error',
|
||||
+ repofile='/etc/yum.repos.d/mock.repo',
|
||||
+ repoid='mocked repoid')
|
||||
+
|
||||
+ monkeypatch.setattr(repofileutils, 'get_parsed_repofiles', _raise_invalidrepo_error)
|
||||
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
||||
+
|
||||
+ with pytest.raises(StopActorExecutionError):
|
||||
+ get_repositories_status()
|
||||
diff --git a/repos/system_upgrade/common/libraries/repofileutils.py b/repos/system_upgrade/common/libraries/repofileutils.py
|
||||
index a563be52..cab3c42b 100644
|
||||
--- a/repos/system_upgrade/common/libraries/repofileutils.py
|
||||
+++ b/repos/system_upgrade/common/libraries/repofileutils.py
|
||||
@@ -11,6 +11,16 @@ except ImportError:
|
||||
api.current_logger().warning('repofileutils.py: failed to import dnf')
|
||||
|
||||
|
||||
+class InvalidRepoDefinition(Exception):
|
||||
+ """Raised when a repository definition is invalid."""
|
||||
+ def __init__(self, msg, repofile, repoid):
|
||||
+ message = 'Invalid repository definition: {repoid} in: {repofile}: {msg}'.format(
|
||||
+ repoid=repoid, repofile=repofile, msg=msg)
|
||||
+ super(InvalidRepoDefinition, self).__init__(message)
|
||||
+ self.repofile = repofile
|
||||
+ self.repoid = repoid
|
||||
+
|
||||
+
|
||||
def _parse_repository(repoid, repo_data):
|
||||
def asbool(x):
|
||||
return x == '1'
|
||||
@@ -33,12 +43,17 @@ def parse_repofile(repofile):
|
||||
:param repofile: Path to the repo file
|
||||
:type repofile: str
|
||||
:rtype: RepositoryFile
|
||||
+ :raises InvalidRepoDefinition: If the repository definition is invalid,
|
||||
+ this can for example occur if 'name' field in repository is missing or it is invalid.
|
||||
"""
|
||||
data = []
|
||||
with open(repofile, mode='r') as fp:
|
||||
cp = utils.parse_config(fp, strict=False)
|
||||
for repoid in cp.sections():
|
||||
- data.append(_parse_repository(repoid, dict(cp.items(repoid))))
|
||||
+ try:
|
||||
+ data.append(_parse_repository(repoid, dict(cp.items(repoid))))
|
||||
+ except fields.ModelViolationError as e:
|
||||
+ raise InvalidRepoDefinition(e, repofile=repofile, repoid=repoid)
|
||||
return RepositoryFile(file=repofile, data=data)
|
||||
|
||||
|
||||
diff --git a/repos/system_upgrade/common/libraries/tests/test_repofileutils.py b/repos/system_upgrade/common/libraries/tests/test_repofileutils.py
|
||||
index 51cc1c11..42c7e49e 100644
|
||||
--- a/repos/system_upgrade/common/libraries/tests/test_repofileutils.py
|
||||
+++ b/repos/system_upgrade/common/libraries/tests/test_repofileutils.py
|
||||
@@ -1,7 +1,10 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
+import pytest
|
||||
+
|
||||
from leapp.libraries.common import repofileutils
|
||||
+from leapp.models.fields import ModelViolationError
|
||||
|
||||
CUR_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
@@ -12,6 +15,30 @@ def test_invert_dict():
|
||||
assert inv_dict == {'a': [1], 'b': [1, 2]}
|
||||
|
||||
|
||||
+@pytest.mark.parametrize(
|
||||
+ ('repoid', 'data'),
|
||||
+ (
|
||||
+ ('missing-name', {'baseurl': 'http://example.com', 'enabled': '1', 'gpgcheck': '1'}),
|
||||
+ (None, {'name': 'name', 'baseurl': 'http://example.com', 'enabled': '1', 'gpgcheck': '1'}),
|
||||
+ ('name-none', {'name': None, 'baseurl': 'http://example.com', 'enabled': '1', 'gpgcheck': '1'}),
|
||||
+ ('baseurl-true', {'name': 'valid', 'baseurl': True, 'enabled': '1', 'gpgcheck': '1'}),
|
||||
+ )
|
||||
+)
|
||||
+def test__parse_repository_missing_name(repoid, data):
|
||||
+ with pytest.raises(ModelViolationError):
|
||||
+ repofileutils._parse_repository(repoid, data)
|
||||
+
|
||||
+
|
||||
+def test_parse_repofile_error(monkeypatch):
|
||||
+ def _parse_repository_mocked(*args, **kwargs):
|
||||
+ raise ModelViolationError('')
|
||||
+
|
||||
+ monkeypatch.setattr(repofileutils, '_parse_repository', _parse_repository_mocked)
|
||||
+
|
||||
+ with pytest.raises(repofileutils.InvalidRepoDefinition):
|
||||
+ repofileutils.parse_repofile(os.path.join(CUR_DIR, 'sample_repos.txt'))
|
||||
+
|
||||
+
|
||||
def test_parse_repofile():
|
||||
repofile = repofileutils.parse_repofile(os.path.join(CUR_DIR, 'sample_repos.txt'))
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,114 +0,0 @@
|
||||
From 18fa991962cb1198173f0ad08a34de27467c32fe Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Mon, 23 Feb 2026 13:59:35 +0100
|
||||
Subject: [PATCH 16/44] rocecheck: Respect distro name in report
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../actors/rocecheck/libraries/rocecheck.py | 81 ++++++++++---------
|
||||
1 file changed, 44 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/rocecheck/libraries/rocecheck.py b/repos/system_upgrade/el8toel9/actors/rocecheck/libraries/rocecheck.py
|
||||
index 0ed2046a..5014a8db 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/rocecheck/libraries/rocecheck.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/rocecheck/libraries/rocecheck.py
|
||||
@@ -1,6 +1,7 @@
|
||||
from leapp import reporting
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
-from leapp.libraries.common.config import architecture
|
||||
+from leapp.libraries.common.config import architecture, get_target_distro_id
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import KernelCmdline, RoceDetected
|
||||
|
||||
@@ -40,45 +41,51 @@ def _fmt_list(items):
|
||||
def _report_wrong_setup(roce):
|
||||
roce_nics = roce.roce_nics_connected + roce.roce_nics_connecting
|
||||
|
||||
+ summary = (
|
||||
+ 'The {target_distro} 9 system uses different network schemes for NIC names'
|
||||
+ ' than {source_distro} 8.'
|
||||
+ ' The below listed RoCE NICs need to be reconfigured to the new'
|
||||
+ ' interface naming scheme in order to prevent loss of network'
|
||||
+ ' access to your system via these interfaces after the upgrade.'
|
||||
+ ' For more information, see: {url}'
|
||||
+ '\n\nRoCE detected on the following NICs:{nics}'
|
||||
+ ).format(
|
||||
+ nics=_fmt_list(roce_nics),
|
||||
+ url=DOC_URL,
|
||||
+ **DISTRO_REPORT_NAMES,
|
||||
+ )
|
||||
+ remmediation_hint = (
|
||||
+ 'Prerequisite for upgrading to {target_distro} {target_version}:'
|
||||
+ 'In {source_distro} 8, all RoCE cards must be configured with the interface'
|
||||
+ ' names they should have in {target_distro} {target_version}.\n'
|
||||
+ 'For more information, see chapter 1.4 of the RHEL 8 Product'
|
||||
+ ' Documentation (see the attached link) and follow these steps:\n'
|
||||
+ '1.) determine the current interface device names of the RoCE'
|
||||
+ ' cards that are in "connected to" or in "connecting" state\n'
|
||||
+ '2.) determine if UID uniqueness is set for these cards\n'
|
||||
+ '3.) compute new interface device names from the UID or the'
|
||||
+ ' function ID, respectively\n'
|
||||
+ '4.) change the network interface device names in ifcfg'
|
||||
+ ' files\n'
|
||||
+ '5.) set the kernel parameter net.naming-scheme=rhel-8.7 in the'
|
||||
+ ' effective .conf file in /boot/loader/entries\n'
|
||||
+ '6.) adjust other settings that rely on the interface device names'
|
||||
+ ' (e.g. firewall) by changing the interface device names'
|
||||
+ ' accordingly\n'
|
||||
+ '7.) run `zipl -V` and reboot the system\n'
|
||||
+ '8.) check your network connectivity\n'
|
||||
+ '\n'
|
||||
+ 'Caution: Creating an incorrect configuration might cause the loss'
|
||||
+ ' of your network connection after reboot!'
|
||||
+ ).format(
|
||||
+ target_version="9" if get_target_distro_id() == "centos" else "9.x",
|
||||
+ **DISTRO_REPORT_NAMES,
|
||||
+ )
|
||||
|
||||
-def _report_wrong_setup(roce):
|
||||
- roce_nics = roce.roce_nics_connected + roce.roce_nics_connecting
|
||||
reporting.create_report([
|
||||
reporting.Title('Invalid RoCE configuration for the in-place upgrade'),
|
||||
- reporting.Summary(
|
||||
- 'The RHEL 9 system uses different network schemes for NIC names'
|
||||
- ' than RHEL 8.'
|
||||
- ' The below listed RoCE NICs need to be reconfigured to the new'
|
||||
- ' interface naming scheme in order to prevent loss of network'
|
||||
- ' access to your system via these interfaces after the upgrade.'
|
||||
- ' For more information, see: {url}'
|
||||
- '\n\nRoCE detected on the following NICs:{nics}'
|
||||
- .format(nics=_fmt_list(roce_nics), url=DOC_URL)
|
||||
- ),
|
||||
- reporting.Remediation(hint=(
|
||||
- 'Prerequisite for upgrading to RHEL9.x:'
|
||||
- 'In RHEL 8, all RoCE cards must be configured with the interface'
|
||||
- ' names they should have in RHEL9.x.\n'
|
||||
- 'For more information, see chapter 1.4 of the RHEL8 Product'
|
||||
- ' Documentation (see the attached link) and follow these steps:\n'
|
||||
- '1.) determine the current interface device names of the RoCE'
|
||||
- ' cards that are in "connected to" or in "connecting" state\n'
|
||||
- '2.) determine if UID uniqueness is set for these cards\n'
|
||||
- '3.) compute new interface device names from the UID or the'
|
||||
- ' function ID, respectively\n'
|
||||
- '4.) change the network interface device names in ifcfg'
|
||||
- ' files\n'
|
||||
- '5.) set the kernel parameter net.naming-scheme=rhel-8.7 in the'
|
||||
- ' effective .conf file in /boot/loader/entries\n'
|
||||
- '6.) adjust other settings that rely on the interface device names'
|
||||
- ' (e.g. firewall) by changing the interface device names'
|
||||
- ' accordingly\n'
|
||||
- '7.) run `zipl -V` and reboot the system\n'
|
||||
- '8.) check your network connectivity\n'
|
||||
- '\n'
|
||||
- 'Caution: Creating an incorrect configuration might cause the loss'
|
||||
- ' of your network connection after reboot!'
|
||||
- )),
|
||||
+ reporting.Summary(summary),
|
||||
+ reporting.Remediation(hint=remmediation_hint),
|
||||
reporting.ExternalLink(
|
||||
title='Predictable network interface device names on the System z platform',
|
||||
url=DOC_URL),
|
||||
--
|
||||
2.53.0
|
||||
|
||||
56
SOURCES/0017-InhibitWhenLuks-simplify-the-logic.patch
Normal file
56
SOURCES/0017-InhibitWhenLuks-simplify-the-logic.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From f84c6f808a821d3ccd09a4a8278cef9c09984a28 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Zatovic <daniel.zatovic@gmail.com>
|
||||
Date: Wed, 3 Apr 2024 23:25:06 +0200
|
||||
Subject: [PATCH 17/40] InhibitWhenLuks: simplify the logic
|
||||
|
||||
---
|
||||
.../common/actors/inhibitwhenluks/actor.py | 35 +++++++------------
|
||||
1 file changed, 13 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py b/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py
|
||||
index d3ff2d2e..40b845b0 100644
|
||||
--- a/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py
|
||||
@@ -24,26 +24,17 @@ class InhibitWhenLuks(Actor):
|
||||
ceph_info = next(self.consume(CephInfo))
|
||||
if ceph_info:
|
||||
ceph_vol = ceph_info.encrypted_volumes[:]
|
||||
- for storage_info in self.consume(StorageInfo):
|
||||
- for blk in storage_info.lsblk:
|
||||
- if blk.tp == 'crypt' and blk.name not in ceph_vol:
|
||||
- create_report([
|
||||
- reporting.Title('LUKS encrypted partition detected'),
|
||||
- reporting.Summary('Upgrading system with encrypted partitions is not supported'),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.BOOT, reporting.Groups.ENCRYPTION]),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
- ])
|
||||
- break
|
||||
except StopIteration:
|
||||
- for storage_info in self.consume(StorageInfo):
|
||||
- for blk in storage_info.lsblk:
|
||||
- if blk.tp == 'crypt':
|
||||
- create_report([
|
||||
- reporting.Title('LUKS encrypted partition detected'),
|
||||
- reporting.Summary('Upgrading system with encrypted partitions is not supported'),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.BOOT, reporting.Groups.ENCRYPTION]),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
- ])
|
||||
- break
|
||||
+ pass
|
||||
+
|
||||
+ for storage_info in self.consume(StorageInfo):
|
||||
+ for blk in storage_info.lsblk:
|
||||
+ if blk.tp == 'crypt' and blk.name not in ceph_vol:
|
||||
+ create_report([
|
||||
+ reporting.Title('LUKS encrypted partition detected'),
|
||||
+ reporting.Summary('Upgrading system with encrypted partitions is not supported'),
|
||||
+ reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Groups([reporting.Groups.BOOT, reporting.Groups.ENCRYPTION]),
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
+ ])
|
||||
+ break
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,101 +0,0 @@
|
||||
From 71aa340ff3c2b5b9cd25e0aa731ace1b87e46d7f Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Mon, 23 Feb 2026 14:15:18 +0100
|
||||
Subject: [PATCH 17/44] opensshpermitrootlogincheck: Remove 7to8 related code
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../opensshpermitrootlogincheck/actor.py | 64 +------------------
|
||||
1 file changed, 2 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/opensshpermitrootlogincheck/actor.py b/repos/system_upgrade/common/actors/opensshpermitrootlogincheck/actor.py
|
||||
index 98d329ab..3aedfd5e 100644
|
||||
--- a/repos/system_upgrade/common/actors/opensshpermitrootlogincheck/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/opensshpermitrootlogincheck/actor.py
|
||||
@@ -1,7 +1,7 @@
|
||||
from leapp import reporting
|
||||
from leapp.actors import Actor
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
-from leapp.libraries.actor.opensshpermitrootlogincheck import global_value, semantics_changes
|
||||
+from leapp.libraries.actor.opensshpermitrootlogincheck import global_value
|
||||
from leapp.libraries.common.config.version import get_source_major_version
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import OpenSshConfig, Report
|
||||
@@ -46,73 +46,13 @@ class OpenSshPermitRootLoginCheck(Actor):
|
||||
'Could not check openssh configuration', details={'details': 'No OpenSshConfig facts found.'}
|
||||
)
|
||||
|
||||
- if get_source_major_version() == '7':
|
||||
- self.process7to8(config)
|
||||
- elif get_source_major_version() == '8':
|
||||
+ if get_source_major_version() == '8':
|
||||
self.process8to9(config)
|
||||
elif int(get_source_major_version()) >= 9:
|
||||
pass
|
||||
else:
|
||||
api.current_logger().warning('Unknown source major version: {}'.format(get_source_major_version()))
|
||||
|
||||
- @staticmethod
|
||||
- def process7to8(config):
|
||||
- # when the config was not modified, we can pass this check and let the
|
||||
- # rpm handle the configuration file update
|
||||
- if not config.modified:
|
||||
- return
|
||||
-
|
||||
- # When the configuration does not contain *any* PermitRootLogin directive and
|
||||
- # the configuration file was locally modified, it will not get updated by
|
||||
- # RPM and the user might be locked away from the server with new default
|
||||
- if not config.permit_root_login:
|
||||
- create_report([
|
||||
- reporting.Title('Possible problems with remote login using root account'),
|
||||
- reporting.Summary(
|
||||
- 'OpenSSH configuration file does not explicitly state '
|
||||
- 'the option PermitRootLogin in sshd_config file, '
|
||||
- 'which will default in RHEL8 to "prohibit-password".'
|
||||
- ),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups(COMMON_REPORT_TAGS),
|
||||
- reporting.Remediation(
|
||||
- hint='If you depend on remote root logins using passwords, consider '
|
||||
- 'setting up a different user for remote administration or adding '
|
||||
- '"PermitRootLogin yes" to sshd_config. '
|
||||
- 'If this change is ok for you, add explicit '
|
||||
- '"PermitRootLogin prohibit-password" to your sshd_config '
|
||||
- 'to ignore this inhibitor'
|
||||
- ),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR])
|
||||
- ] + COMMON_RESOURCES)
|
||||
- return
|
||||
-
|
||||
- # Check if there is at least one PermitRootLogin other than "no"
|
||||
- # in match blocks (other than Match All).
|
||||
- # This usually means some more complicated setup depending on the
|
||||
- # default value being globally "yes" and being overwritten by this
|
||||
- # match block
|
||||
- if semantics_changes(config):
|
||||
- create_report([
|
||||
- reporting.Title('OpenSSH configured to allow root login'),
|
||||
- reporting.Summary(
|
||||
- 'OpenSSH is configured to deny root logins in match '
|
||||
- 'blocks, but not explicitly enabled in global or '
|
||||
- '"Match all" context. This update changes the '
|
||||
- 'default to disable root logins using passwords '
|
||||
- 'so your server might get inaccessible.'
|
||||
- ),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups(COMMON_REPORT_TAGS),
|
||||
- reporting.Remediation(
|
||||
- hint='Consider using different user for administrative '
|
||||
- 'logins or make sure your configuration file '
|
||||
- 'contains the line "PermitRootLogin yes" '
|
||||
- 'in global context if desired.'
|
||||
- ),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR])
|
||||
- ] + COMMON_RESOURCES)
|
||||
-
|
||||
@staticmethod
|
||||
def process8to9(config):
|
||||
# RHEL8 default sshd configuration file is not modified: It will get replaced by rpm and
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,271 @@
|
||||
From 03fc6743b8916f23f6a213e3f0fc3020ee141b96 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Zatovic <daniel.zatovic@gmail.com>
|
||||
Date: Wed, 3 Apr 2024 23:42:45 +0200
|
||||
Subject: [PATCH 18/40] StorageScanner: Add parent device name to lsblk
|
||||
|
||||
Modify the StorageInfo model to include path and name of the parent
|
||||
device. Use StorageScanner to collect this information.
|
||||
|
||||
Morover fix lsblk test, there should be a full device path in "lsblk
|
||||
-pbnr" output (just names were used in the original test).
|
||||
---
|
||||
.../tests/test_inhibitwhenluks.py | 12 +--
|
||||
.../libraries/storagescanner.py | 29 +++++--
|
||||
.../tests/unit_test_storagescanner.py | 78 +++++++++++++++----
|
||||
.../common/models/storageinfo.py | 2 +
|
||||
.../tests/unit_test_vdoconversionscanner.py | 4 +-
|
||||
5 files changed, 95 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py b/repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py
|
||||
index fee50f9d..405a3429 100644
|
||||
--- a/repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py
|
||||
+++ b/repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py
|
||||
@@ -5,8 +5,8 @@ from leapp.utils.report import is_inhibitor
|
||||
|
||||
|
||||
def test_actor_with_luks(current_actor_context):
|
||||
- with_luks = [LsblkEntry(name='luks-132', kname='kname1', maj_min='253:0', rm='0',
|
||||
- size='10G', bsize=10*(1 << 39), ro='0', tp='crypt', mountpoint='')]
|
||||
+ with_luks = [LsblkEntry(name='luks-132', kname='kname1', maj_min='253:0', rm='0', size='10G', bsize=10*(1 << 39),
|
||||
+ ro='0', tp='crypt', mountpoint='', parent_name='', parent_path='')]
|
||||
|
||||
current_actor_context.feed(StorageInfo(lsblk=with_luks))
|
||||
current_actor_context.run()
|
||||
@@ -16,8 +16,8 @@ def test_actor_with_luks(current_actor_context):
|
||||
|
||||
|
||||
def test_actor_with_luks_ceph_only(current_actor_context):
|
||||
- with_luks = [LsblkEntry(name='luks-132', kname='kname1', maj_min='253:0', rm='0',
|
||||
- size='10G', bsize=10*(1 << 39), ro='0', tp='crypt', mountpoint='')]
|
||||
+ with_luks = [LsblkEntry(name='luks-132', kname='kname1', maj_min='253:0', rm='0', size='10G', bsize=10*(1 << 39),
|
||||
+ ro='0', tp='crypt', mountpoint='', parent_name='', parent_path='')]
|
||||
ceph_volume = ['luks-132']
|
||||
current_actor_context.feed(StorageInfo(lsblk=with_luks))
|
||||
current_actor_context.feed(CephInfo(encrypted_volumes=ceph_volume))
|
||||
@@ -26,8 +26,8 @@ def test_actor_with_luks_ceph_only(current_actor_context):
|
||||
|
||||
|
||||
def test_actor_without_luks(current_actor_context):
|
||||
- without_luks = [LsblkEntry(name='sda1', kname='sda1', maj_min='8:0', rm='0',
|
||||
- size='10G', bsize=10*(1 << 39), ro='0', tp='part', mountpoint='/boot')]
|
||||
+ without_luks = [LsblkEntry(name='sda1', kname='sda1', maj_min='8:0', rm='0', size='10G', bsize=10*(1 << 39),
|
||||
+ ro='0', tp='part', mountpoint='/boot', parent_name='', parent_path='')]
|
||||
|
||||
current_actor_context.feed(StorageInfo(lsblk=without_luks))
|
||||
current_actor_context.run()
|
||||
diff --git a/repos/system_upgrade/common/actors/storagescanner/libraries/storagescanner.py b/repos/system_upgrade/common/actors/storagescanner/libraries/storagescanner.py
|
||||
index f15f0d87..cad6bd32 100644
|
||||
--- a/repos/system_upgrade/common/actors/storagescanner/libraries/storagescanner.py
|
||||
+++ b/repos/system_upgrade/common/actors/storagescanner/libraries/storagescanner.py
|
||||
@@ -164,18 +164,31 @@ def _get_mount_info(path):
|
||||
)
|
||||
|
||||
|
||||
+def _get_lsblk_info_for_devpath(dev_path):
|
||||
+ lsblk_cmd = ['lsblk', '-nr', '--output', 'NAME,KNAME,SIZE', dev_path]
|
||||
+ lsblk_info_for_devpath = next(_get_cmd_output(lsblk_cmd, ' ', 3), None)
|
||||
+
|
||||
+ return lsblk_info_for_devpath
|
||||
+
|
||||
+
|
||||
@aslist
|
||||
def _get_lsblk_info():
|
||||
""" Collect storage info from lsblk command """
|
||||
- cmd = ['lsblk', '-pbnr', '--output', 'NAME,MAJ:MIN,RM,SIZE,RO,TYPE,MOUNTPOINT']
|
||||
- for entry in _get_cmd_output(cmd, ' ', 7):
|
||||
- dev_path, maj_min, rm, bsize, ro, tp, mountpoint = entry
|
||||
- lsblk_cmd = ['lsblk', '-nr', '--output', 'NAME,KNAME,SIZE', dev_path]
|
||||
- lsblk_info_for_devpath = next(_get_cmd_output(lsblk_cmd, ' ', 3), None)
|
||||
+ cmd = ['lsblk', '-pbnr', '--output', 'NAME,MAJ:MIN,RM,SIZE,RO,TYPE,MOUNTPOINT,PKNAME']
|
||||
+ for entry in _get_cmd_output(cmd, ' ', 8):
|
||||
+ dev_path, maj_min, rm, bsize, ro, tp, mountpoint, parent_path = entry
|
||||
+
|
||||
+ lsblk_info_for_devpath = _get_lsblk_info_for_devpath(dev_path)
|
||||
if not lsblk_info_for_devpath:
|
||||
return
|
||||
-
|
||||
name, kname, size = lsblk_info_for_devpath
|
||||
+
|
||||
+ parent_name = ""
|
||||
+ if parent_path:
|
||||
+ parent_info = _get_lsblk_info_for_devpath(parent_path)
|
||||
+ if parent_info:
|
||||
+ parent_name, _, _ = parent_info
|
||||
+
|
||||
yield LsblkEntry(
|
||||
name=name,
|
||||
kname=kname,
|
||||
@@ -185,7 +198,9 @@ def _get_lsblk_info():
|
||||
bsize=int(bsize),
|
||||
ro=ro,
|
||||
tp=tp,
|
||||
- mountpoint=mountpoint)
|
||||
+ mountpoint=mountpoint,
|
||||
+ parent_name=parent_name,
|
||||
+ parent_path=parent_path)
|
||||
|
||||
|
||||
@aslist
|
||||
diff --git a/repos/system_upgrade/common/actors/storagescanner/tests/unit_test_storagescanner.py b/repos/system_upgrade/common/actors/storagescanner/tests/unit_test_storagescanner.py
|
||||
index 4dc11ea4..456e40ec 100644
|
||||
--- a/repos/system_upgrade/common/actors/storagescanner/tests/unit_test_storagescanner.py
|
||||
+++ b/repos/system_upgrade/common/actors/storagescanner/tests/unit_test_storagescanner.py
|
||||
@@ -255,13 +255,18 @@ def test_get_lsblk_info(monkeypatch):
|
||||
bytes_per_gb = 1 << 30
|
||||
|
||||
def get_cmd_output_mocked(cmd, delim, expected_len):
|
||||
- if cmd == ['lsblk', '-pbnr', '--output', 'NAME,MAJ:MIN,RM,SIZE,RO,TYPE,MOUNTPOINT']:
|
||||
+ if cmd == ['lsblk', '-pbnr', '--output', 'NAME,MAJ:MIN,RM,SIZE,RO,TYPE,MOUNTPOINT,PKNAME']:
|
||||
output_lines_split_on_whitespace = [
|
||||
- ['vda', '252:0', '0', str(40 * bytes_per_gb), '0', 'disk', ''],
|
||||
- ['vda1', '252:1', '0', str(1 * bytes_per_gb), '0', 'part', '/boot'],
|
||||
- ['vda2', '252:2', '0', str(39 * bytes_per_gb), '0', 'part', ''],
|
||||
- ['rhel_ibm--p8--kvm--03--guest--02-root', '253:0', '0', str(38 * bytes_per_gb), '0', 'lvm', '/'],
|
||||
- ['rhel_ibm--p8--kvm--03--guest--02-swap', '253:1', '0', str(1 * bytes_per_gb), '0', 'lvm', '[SWAP]']
|
||||
+ ['/dev/vda', '252:0', '0', str(40 * bytes_per_gb), '0', 'disk', '', ''],
|
||||
+ ['/dev/vda1', '252:1', '0', str(1 * bytes_per_gb), '0', 'part', '/boot', ''],
|
||||
+ ['/dev/vda2', '252:2', '0', str(39 * bytes_per_gb), '0', 'part', '', ''],
|
||||
+ ['/dev/mapper/rhel_ibm--p8--kvm--03--guest--02-root', '253:0', '0', str(38 * bytes_per_gb), '0', 'lvm',
|
||||
+ '/', ''],
|
||||
+ ['/dev/mapper/rhel_ibm--p8--kvm--03--guest--02-swap', '253:1', '0', str(1 * bytes_per_gb), '0', 'lvm',
|
||||
+ '[SWAP]', ''],
|
||||
+ ['/dev/mapper/luks-01b60fff-a2a8-4c03-893f-056bfc3f06f6', '254:0', '0', str(38 * bytes_per_gb), '0',
|
||||
+ 'crypt', '', '/dev/nvme0n1p1'],
|
||||
+ ['/dev/nvme0n1p1', '259:1', '0', str(39 * bytes_per_gb), '0', 'part', '', '/dev/nvme0n1'],
|
||||
]
|
||||
for output_line_parts in output_lines_split_on_whitespace:
|
||||
yield output_line_parts
|
||||
@@ -269,11 +274,17 @@ def test_get_lsblk_info(monkeypatch):
|
||||
# We cannot have the output in a list, since the command is called per device. Therefore, we have to map
|
||||
# each device path to its output.
|
||||
output_lines_split_on_whitespace_per_device = {
|
||||
- 'vda': ['vda', 'vda', '40G'],
|
||||
- 'vda1': ['vda1', 'vda1', '1G'],
|
||||
- 'vda2': ['vda2', 'vda2', '39G'],
|
||||
- 'rhel_ibm--p8--kvm--03--guest--02-root': ['rhel_ibm--p8--kvm--03--guest--02-root', 'kname1', '38G'],
|
||||
- 'rhel_ibm--p8--kvm--03--guest--02-swap': ['rhel_ibm--p8--kvm--03--guest--02-swap', 'kname2', '1G']
|
||||
+ '/dev/vda': ['vda', 'vda', '40G'],
|
||||
+ '/dev/vda1': ['vda1', 'vda1', '1G'],
|
||||
+ '/dev/vda2': ['vda2', 'vda2', '39G'],
|
||||
+ '/dev/mapper/rhel_ibm--p8--kvm--03--guest--02-root':
|
||||
+ ['rhel_ibm--p8--kvm--03--guest--02-root', 'kname1', '38G'],
|
||||
+ '/dev/mapper/rhel_ibm--p8--kvm--03--guest--02-swap':
|
||||
+ ['rhel_ibm--p8--kvm--03--guest--02-swap', 'kname2', '1G'],
|
||||
+ '/dev/mapper/luks-01b60fff-a2a8-4c03-893f-056bfc3f06f6':
|
||||
+ ['luks-01b60fff-a2a8-4c03-893f-056bfc3f06f6', 'dm-0', '38G'],
|
||||
+ '/dev/nvme0n1p1': ['nvme0n1p1', 'nvme0n1p1', '39G'],
|
||||
+ '/dev/nvme0n1': ['nvme0n1', 'nvme0n1', '40G'],
|
||||
}
|
||||
dev_path = cmd[4]
|
||||
if dev_path not in output_lines_split_on_whitespace_per_device:
|
||||
@@ -294,7 +305,9 @@ def test_get_lsblk_info(monkeypatch):
|
||||
bsize=40 * bytes_per_gb,
|
||||
ro='0',
|
||||
tp='disk',
|
||||
- mountpoint=''),
|
||||
+ mountpoint='',
|
||||
+ parent_name='',
|
||||
+ parent_path=''),
|
||||
LsblkEntry(
|
||||
name='vda1',
|
||||
kname='vda1',
|
||||
@@ -304,7 +317,9 @@ def test_get_lsblk_info(monkeypatch):
|
||||
bsize=1 * bytes_per_gb,
|
||||
ro='0',
|
||||
tp='part',
|
||||
- mountpoint='/boot'),
|
||||
+ mountpoint='/boot',
|
||||
+ parent_name='',
|
||||
+ parent_path=''),
|
||||
LsblkEntry(
|
||||
name='vda2',
|
||||
kname='vda2',
|
||||
@@ -314,7 +329,9 @@ def test_get_lsblk_info(monkeypatch):
|
||||
bsize=39 * bytes_per_gb,
|
||||
ro='0',
|
||||
tp='part',
|
||||
- mountpoint=''),
|
||||
+ mountpoint='',
|
||||
+ parent_name='',
|
||||
+ parent_path=''),
|
||||
LsblkEntry(
|
||||
name='rhel_ibm--p8--kvm--03--guest--02-root',
|
||||
kname='kname1',
|
||||
@@ -324,7 +341,9 @@ def test_get_lsblk_info(monkeypatch):
|
||||
bsize=38 * bytes_per_gb,
|
||||
ro='0',
|
||||
tp='lvm',
|
||||
- mountpoint='/'),
|
||||
+ mountpoint='/',
|
||||
+ parent_name='',
|
||||
+ parent_path=''),
|
||||
LsblkEntry(
|
||||
name='rhel_ibm--p8--kvm--03--guest--02-swap',
|
||||
kname='kname2',
|
||||
@@ -334,7 +353,34 @@ def test_get_lsblk_info(monkeypatch):
|
||||
bsize=1 * bytes_per_gb,
|
||||
ro='0',
|
||||
tp='lvm',
|
||||
- mountpoint='[SWAP]')]
|
||||
+ mountpoint='[SWAP]',
|
||||
+ parent_name='',
|
||||
+ parent_path=''),
|
||||
+ LsblkEntry(
|
||||
+ name='luks-01b60fff-a2a8-4c03-893f-056bfc3f06f6',
|
||||
+ kname='dm-0',
|
||||
+ maj_min='254:0',
|
||||
+ rm='0',
|
||||
+ size='38G',
|
||||
+ bsize=38 * bytes_per_gb,
|
||||
+ ro='0',
|
||||
+ tp='crypt',
|
||||
+ mountpoint='',
|
||||
+ parent_name='nvme0n1p1',
|
||||
+ parent_path='/dev/nvme0n1p1'),
|
||||
+ LsblkEntry(
|
||||
+ name='nvme0n1p1',
|
||||
+ kname='nvme0n1p1',
|
||||
+ maj_min='259:1',
|
||||
+ rm='0',
|
||||
+ size='39G',
|
||||
+ bsize=39 * bytes_per_gb,
|
||||
+ ro='0',
|
||||
+ tp='part',
|
||||
+ mountpoint='',
|
||||
+ parent_name='nvme0n1',
|
||||
+ parent_path='/dev/nvme0n1'),
|
||||
+ ]
|
||||
|
||||
actual = storagescanner._get_lsblk_info()
|
||||
assert expected == actual
|
||||
diff --git a/repos/system_upgrade/common/models/storageinfo.py b/repos/system_upgrade/common/models/storageinfo.py
|
||||
index 5bb9caac..71e7459d 100644
|
||||
--- a/repos/system_upgrade/common/models/storageinfo.py
|
||||
+++ b/repos/system_upgrade/common/models/storageinfo.py
|
||||
@@ -43,6 +43,8 @@ class LsblkEntry(Model):
|
||||
ro = fields.String()
|
||||
tp = fields.String()
|
||||
mountpoint = fields.String()
|
||||
+ parent_name = fields.String()
|
||||
+ parent_path = fields.String()
|
||||
|
||||
|
||||
class PvsEntry(Model):
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/vdoconversionscanner/tests/unit_test_vdoconversionscanner.py b/repos/system_upgrade/el8toel9/actors/vdoconversionscanner/tests/unit_test_vdoconversionscanner.py
|
||||
index 0745c91d..4d6ef0dc 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/vdoconversionscanner/tests/unit_test_vdoconversionscanner.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/vdoconversionscanner/tests/unit_test_vdoconversionscanner.py
|
||||
@@ -26,7 +26,9 @@ def _lsblk_entry(prefix, number, types, size='128G', bsize=2 ** 37):
|
||||
bsize=bsize,
|
||||
ro='0',
|
||||
tp=types[random.randint(0, len(types) - 1)],
|
||||
- mountpoint='')
|
||||
+ mountpoint='',
|
||||
+ parent_name='',
|
||||
+ parent_path='')
|
||||
|
||||
|
||||
@aslist
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
From d5edd261a729f0a83aa9642bf3655acf63f8808e Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Mon, 23 Feb 2026 14:15:38 +0100
|
||||
Subject: [PATCH 18/44] opensshpermitrootlogincheck: Respect target distro name
|
||||
in report
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../actors/opensshpermitrootlogincheck/actor.py | 17 ++++++++++-------
|
||||
1 file changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/opensshpermitrootlogincheck/actor.py b/repos/system_upgrade/common/actors/opensshpermitrootlogincheck/actor.py
|
||||
index 3aedfd5e..93ee5021 100644
|
||||
--- a/repos/system_upgrade/common/actors/opensshpermitrootlogincheck/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/opensshpermitrootlogincheck/actor.py
|
||||
@@ -3,6 +3,7 @@ from leapp.actors import Actor
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries.actor.opensshpermitrootlogincheck import global_value
|
||||
from leapp.libraries.common.config.version import get_source_major_version
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import OpenSshConfig, Report
|
||||
from leapp.reporting import create_report
|
||||
@@ -62,12 +63,12 @@ class OpenSshPermitRootLoginCheck(Actor):
|
||||
create_report([
|
||||
reporting.Title('Possible problems with remote login using root account'),
|
||||
reporting.Summary(
|
||||
- 'OpenSSH configuration file will get updated to RHEL9 '
|
||||
+ 'OpenSSH configuration file will get updated to {target_distro} 9 '
|
||||
'version, no longer allowing root login with password. '
|
||||
'It is a good practice to use non-root administrative '
|
||||
'user and non-password authentications, but if you rely '
|
||||
'on the remote root login, this change can lock you out '
|
||||
- 'of this system.'
|
||||
+ 'of this system.'.format_map(DISTRO_REPORT_NAMES)
|
||||
),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups(COMMON_REPORT_TAGS),
|
||||
@@ -93,11 +94,13 @@ class OpenSshPermitRootLoginCheck(Actor):
|
||||
create_report([
|
||||
reporting.Title('Remote root logins globally allowed using password'),
|
||||
reporting.Summary(
|
||||
- 'RHEL9 no longer allows remote root logins, but the '
|
||||
- 'server configuration explicitly overrides this default. '
|
||||
- 'The configuration file will not be updated and root is '
|
||||
- 'still going to be allowed to login with password. '
|
||||
- 'This is not recommended and considered as a security risk.'
|
||||
+ '{target_distro} 9 no longer allows remote root logins, but '
|
||||
+ 'the server configuration explicitly overrides this default. '
|
||||
+ 'The configuration file will not be updated and root is still'
|
||||
+ 'going to be allowed to login with password. This is not '
|
||||
+ 'recommended and considered as a security risk. '.format_map(
|
||||
+ DISTRO_REPORT_NAMES
|
||||
+ )
|
||||
),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups(COMMON_REPORT_TAGS),
|
||||
--
|
||||
2.53.0
|
||||
|
||||
1030
SOURCES/0019-LuksScanner-Add-LUKS-dump-scanner-and-models.patch
Normal file
1030
SOURCES/0019-LuksScanner-Add-LUKS-dump-scanner-and-models.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,120 +0,0 @@
|
||||
From 61dc43540b15c71a8a2c2d5705c5952de059b6d8 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 18:05:37 +0100
|
||||
Subject: [PATCH 19/44] checkifcfg_ifcfg: Respect distro name in report
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../checkifcfg/libraries/checkifcfg_ifcfg.py | 37 +++++++++++++------
|
||||
.../checkifcfg/tests/unit_test_ifcfg.py | 9 ++++-
|
||||
2 files changed, 32 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/checkifcfg/libraries/checkifcfg_ifcfg.py b/repos/system_upgrade/el8toel9/actors/checkifcfg/libraries/checkifcfg_ifcfg.py
|
||||
index ed666350..79ede81e 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/checkifcfg/libraries/checkifcfg_ifcfg.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/checkifcfg/libraries/checkifcfg_ifcfg.py
|
||||
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
|
||||
from leapp import reporting
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.common.rpms import has_package
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import IfCfg, InstalledRPM, RpmTransactionTasks
|
||||
@@ -8,6 +9,12 @@ from leapp.models import IfCfg, InstalledRPM, RpmTransactionTasks
|
||||
FMT_LIST_SEPARATOR = '\n - '
|
||||
|
||||
|
||||
+def _format_files_list(files):
|
||||
+ return "".join(
|
||||
+ ["{}{}".format(FMT_LIST_SEPARATOR, f) for f in files]
|
||||
+ )
|
||||
+
|
||||
+
|
||||
def process():
|
||||
TRUE_VALUES = ['yes', 'true', '1']
|
||||
TYPE_MAP = {
|
||||
@@ -74,12 +81,15 @@ def process():
|
||||
|
||||
if bad_type_files:
|
||||
title = 'Network configuration for unsupported device types detected'
|
||||
- summary = ('RHEL 9 does not support the legacy network-scripts'
|
||||
- ' package that was deprecated in RHEL 8 in favor of'
|
||||
- ' NetworkManager. Files for device types that are not'
|
||||
- ' supported by NetworkManager are present in the system.'
|
||||
- ' Files with the problematic configuration:{}').format(
|
||||
- ''.join(['{}{}'.format(FMT_LIST_SEPARATOR, bfile) for bfile in bad_type_files])
|
||||
+ summary = (
|
||||
+ "{target_distro} 9 does not support the legacy network-scripts"
|
||||
+ " package that was deprecated in {source_distro} 8 in favor of"
|
||||
+ " NetworkManager. Files for device types that are not"
|
||||
+ " supported by NetworkManager are present in the system."
|
||||
+ " Files with the problematic configuration:{bad_files}".format(
|
||||
+ bad_files=_format_files_list(bad_type_files),
|
||||
+ **DISTRO_REPORT_NAMES,
|
||||
+ )
|
||||
)
|
||||
remediation = ('Consult the nm-settings-ifcfg-rh(5) manual for'
|
||||
' valid types of ifcfg files. Remove configuration'
|
||||
@@ -104,12 +114,15 @@ def process():
|
||||
|
||||
if not_controlled_files:
|
||||
title = 'Network configuration with disabled NetworkManager support detected'
|
||||
- summary = ('RHEL 9 does not support the legacy network-scripts'
|
||||
- ' package that was deprecated in RHEL 8 in favor of'
|
||||
- ' NetworkManager. Configuration present in the system'
|
||||
- ' prohibit NetworkManager from loading it.'
|
||||
- ' Files with the problematic configuration:{}').format(
|
||||
- ''.join(['{}{}'.format(FMT_LIST_SEPARATOR, bfile) for bfile in not_controlled_files])
|
||||
+ summary = (
|
||||
+ '{target_distro} 9 does not support the legacy network-scripts'
|
||||
+ ' package that was deprecated in {source_distro} 8 in favor of'
|
||||
+ ' NetworkManager. Configuration present in the system'
|
||||
+ ' prohibit NetworkManager from loading it.'
|
||||
+ ' Files with the problematic configuration:{bad_files}'
|
||||
+ ).format(
|
||||
+ bad_files=_format_files_list(not_controlled_files),
|
||||
+ **DISTRO_REPORT_NAMES,
|
||||
)
|
||||
remediation = ('Ensure the ifcfg files comply with format described in'
|
||||
' nm-settings-ifcfg-rh(5) manual and remove the'
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/checkifcfg/tests/unit_test_ifcfg.py b/repos/system_upgrade/el8toel9/actors/checkifcfg/tests/unit_test_ifcfg.py
|
||||
index ddabedf2..02ffc65c 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/checkifcfg/tests/unit_test_ifcfg.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/checkifcfg/tests/unit_test_ifcfg.py
|
||||
@@ -1,3 +1,4 @@
|
||||
+from leapp.libraries.common import distro
|
||||
from leapp.models import IfCfg, IfCfgProperty, InstalledRPM, RPM, RpmTransactionTasks
|
||||
from leapp.reporting import Report
|
||||
from leapp.utils.report import is_inhibitor
|
||||
@@ -85,10 +86,12 @@ def test_ifcfg_good_type(current_actor_context):
|
||||
assert rpm_transaction.to_install == ["NetworkManager"]
|
||||
|
||||
|
||||
-def test_ifcfg_not_controlled(current_actor_context):
|
||||
+def test_ifcfg_not_controlled(monkeypatch, current_actor_context):
|
||||
"""
|
||||
Report if there's a NM_CONTROLLED=no file.
|
||||
"""
|
||||
+ monkeypatch.setattr(distro, 'get_source_distro_id', lambda: 'rhel')
|
||||
+ monkeypatch.setattr(distro, 'get_target_distro_id', lambda: 'rhel')
|
||||
|
||||
current_actor_context.feed(IfCfg(
|
||||
filename="/NM/ifcfg-eth0",
|
||||
@@ -105,10 +108,12 @@ def test_ifcfg_not_controlled(current_actor_context):
|
||||
assert "disabled NetworkManager" in report_fields['title']
|
||||
|
||||
|
||||
-def test_ifcfg_unknown_type(current_actor_context):
|
||||
+def test_ifcfg_unknown_type(monkeypatch, current_actor_context):
|
||||
"""
|
||||
Report if there's configuration for a type we don't recognize.
|
||||
"""
|
||||
+ monkeypatch.setattr(distro, 'get_source_distro_id', lambda: 'rhel')
|
||||
+ monkeypatch.setattr(distro, 'get_target_distro_id', lambda: 'rhel')
|
||||
|
||||
current_actor_context.feed(IfCfg(
|
||||
filename="/NM/ifcfg-pigeon0",
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,455 @@
|
||||
From ad241f701b39a81d132105f1a301f2f5546f498a Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Zatovic <daniel.zatovic@gmail.com>
|
||||
Date: Tue, 6 Aug 2024 17:26:58 +0200
|
||||
Subject: [PATCH 20/40] InhibitWhenLuks: allow upgrades for LUKS2 bound to
|
||||
Clevis TPM2 token
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
So far, upgrades with encrypted drives were not supported. Encrypted
|
||||
drives require interactively typing unlock passphrases, which is not
|
||||
suitable for automatic upgrades using Leapp. We add a feature, where
|
||||
systems with all drives configured with automatic unlock method can be
|
||||
upgraded.
|
||||
|
||||
Currently, we only support drives configured with Clevis/TPM2 token,
|
||||
because networking is not configured during Leapp upgrade (excluding
|
||||
NBDE).
|
||||
|
||||
We consume LuksDumps message to decide whether the upgrade process
|
||||
should be inhibited. If there is at least one LUKS2 device without
|
||||
Clevis TPM2 binding, we inhibit the upgrade because we cannot tell if
|
||||
the device is not a part of a more complex storage stack and the failure
|
||||
to unlock the device migt cause boot problem.
|
||||
|
||||
Co-authored-by: Petr Stodůlka <pstodulk@redhat.com>
|
||||
---
|
||||
.../common/actors/inhibitwhenluks/actor.py | 38 ++--
|
||||
.../libraries/inhibitwhenluks.py | 164 +++++++++++++++++
|
||||
.../tests/test_inhibitwhenluks.py | 169 ++++++++++++++++--
|
||||
3 files changed, 329 insertions(+), 42 deletions(-)
|
||||
create mode 100644 repos/system_upgrade/common/actors/inhibitwhenluks/libraries/inhibitwhenluks.py
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py b/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py
|
||||
index 40b845b0..65607167 100644
|
||||
--- a/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py
|
||||
@@ -1,40 +1,24 @@
|
||||
-from leapp import reporting
|
||||
from leapp.actors import Actor
|
||||
-from leapp.models import CephInfo, StorageInfo
|
||||
-from leapp.reporting import create_report, Report
|
||||
+from leapp.libraries.actor.inhibitwhenluks import check_invalid_luks_devices
|
||||
+from leapp.models import CephInfo, LuksDumps, StorageInfo, TargetUserSpaceUpgradeTasks, UpgradeInitramfsTasks
|
||||
+from leapp.reporting import Report
|
||||
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
|
||||
|
||||
class InhibitWhenLuks(Actor):
|
||||
"""
|
||||
- Check if any encrypted partitions is in use. If yes, inhibit the upgrade process.
|
||||
+ Check if any encrypted partitions are in use and whether they are supported for the upgrade.
|
||||
|
||||
- Upgrading system with encrypted partition is not supported.
|
||||
+ Upgrading EL7 system with encrypted partition is not supported (but ceph OSDs).
|
||||
+ For EL8+ it's ok if the discovered used encrypted storage has LUKS2 format
|
||||
+ and it's bounded to clevis-tpm2 token (so it can be automatically unlocked
|
||||
+ during the process).
|
||||
"""
|
||||
|
||||
name = 'check_luks_and_inhibit'
|
||||
- consumes = (StorageInfo, CephInfo)
|
||||
- produces = (Report,)
|
||||
+ consumes = (CephInfo, LuksDumps, StorageInfo)
|
||||
+ produces = (Report, TargetUserSpaceUpgradeTasks, UpgradeInitramfsTasks)
|
||||
tags = (ChecksPhaseTag, IPUWorkflowTag)
|
||||
|
||||
def process(self):
|
||||
- # If encrypted Ceph volumes present, check if there are more encrypted disk in lsblk than Ceph vol
|
||||
- ceph_vol = []
|
||||
- try:
|
||||
- ceph_info = next(self.consume(CephInfo))
|
||||
- if ceph_info:
|
||||
- ceph_vol = ceph_info.encrypted_volumes[:]
|
||||
- except StopIteration:
|
||||
- pass
|
||||
-
|
||||
- for storage_info in self.consume(StorageInfo):
|
||||
- for blk in storage_info.lsblk:
|
||||
- if blk.tp == 'crypt' and blk.name not in ceph_vol:
|
||||
- create_report([
|
||||
- reporting.Title('LUKS encrypted partition detected'),
|
||||
- reporting.Summary('Upgrading system with encrypted partitions is not supported'),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.BOOT, reporting.Groups.ENCRYPTION]),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
- ])
|
||||
- break
|
||||
+ check_invalid_luks_devices()
|
||||
diff --git a/repos/system_upgrade/common/actors/inhibitwhenluks/libraries/inhibitwhenluks.py b/repos/system_upgrade/common/actors/inhibitwhenluks/libraries/inhibitwhenluks.py
|
||||
new file mode 100644
|
||||
index 00000000..57a94e9d
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/actors/inhibitwhenluks/libraries/inhibitwhenluks.py
|
||||
@@ -0,0 +1,164 @@
|
||||
+from leapp import reporting
|
||||
+from leapp.libraries.common.config.version import get_source_major_version
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import (
|
||||
+ CephInfo,
|
||||
+ DracutModule,
|
||||
+ LuksDumps,
|
||||
+ StorageInfo,
|
||||
+ TargetUserSpaceUpgradeTasks,
|
||||
+ UpgradeInitramfsTasks
|
||||
+)
|
||||
+from leapp.reporting import create_report
|
||||
+
|
||||
+# https://red.ht/clevis-tpm2-luks-auto-unlock-rhel8
|
||||
+# https://red.ht/clevis-tpm2-luks-auto-unlock-rhel9
|
||||
+# https://red.ht/convert-to-luks2-rhel8
|
||||
+# https://red.ht/convert-to-luks2-rhel9
|
||||
+CLEVIS_DOC_URL_FMT = 'https://red.ht/clevis-tpm2-luks-auto-unlock-rhel{}'
|
||||
+LUKS2_CONVERT_DOC_URL_FMT = 'https://red.ht/convert-to-luks2-rhel{}'
|
||||
+
|
||||
+FMT_LIST_SEPARATOR = '\n - '
|
||||
+
|
||||
+
|
||||
+def _formatted_list_output(input_list, sep=FMT_LIST_SEPARATOR):
|
||||
+ return ['{}{}'.format(sep, item) for item in input_list]
|
||||
+
|
||||
+
|
||||
+def _at_least_one_tpm_token(luks_dump):
|
||||
+ return any([token.token_type == "clevis-tpm2" for token in luks_dump.tokens])
|
||||
+
|
||||
+
|
||||
+def _get_ceph_volumes():
|
||||
+ ceph_info = next(api.consume(CephInfo), None)
|
||||
+ return ceph_info.encrypted_volumes[:] if ceph_info else []
|
||||
+
|
||||
+
|
||||
+def apply_obsoleted_check_ipu_7_8():
|
||||
+ ceph_vol = _get_ceph_volumes()
|
||||
+ for storage_info in api.consume(StorageInfo):
|
||||
+ for blk in storage_info.lsblk:
|
||||
+ if blk.tp == 'crypt' and blk.name not in ceph_vol:
|
||||
+ create_report([
|
||||
+ reporting.Title('LUKS encrypted partition detected'),
|
||||
+ reporting.Summary('Upgrading system with encrypted partitions is not supported'),
|
||||
+ reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Groups([reporting.Groups.BOOT, reporting.Groups.ENCRYPTION]),
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
+ ])
|
||||
+ break
|
||||
+
|
||||
+
|
||||
+def report_inhibitor(luks1_partitions, no_tpm2_partitions):
|
||||
+ source_major_version = get_source_major_version()
|
||||
+ clevis_doc_url = CLEVIS_DOC_URL_FMT.format(source_major_version)
|
||||
+ luks2_convert_doc_url = LUKS2_CONVERT_DOC_URL_FMT.format(source_major_version)
|
||||
+ summary = (
|
||||
+ 'We have detected LUKS encrypted volumes that do not meet current'
|
||||
+ ' criteria to be able to proceed the in-place upgrade process.'
|
||||
+ ' Right now the upgrade process requires for encrypted storage to be'
|
||||
+ ' in LUKS2 format configured with Clevis TPM 2.0.'
|
||||
+ )
|
||||
+
|
||||
+ report_hints = []
|
||||
+
|
||||
+ if luks1_partitions:
|
||||
+
|
||||
+ summary += (
|
||||
+ '\n\nSince RHEL 8 the default format for LUKS encryption is LUKS2.'
|
||||
+ ' Despite the old LUKS1 format is still supported on RHEL systems'
|
||||
+ ' it has some limitations in comparison to LUKS2.'
|
||||
+ ' Only the LUKS2 format is supported for upgrades.'
|
||||
+ ' The following LUKS1 partitions have been discovered on your system:{}'
|
||||
+ .format(''.join(_formatted_list_output(luks1_partitions)))
|
||||
+ )
|
||||
+ report_hints.append(reporting.Remediation(
|
||||
+ hint=(
|
||||
+ 'Convert your LUKS1 encrypted devices to LUKS2 and bind it to TPM2 using clevis.'
|
||||
+ ' If this is not possible in your case consider clean installation'
|
||||
+ ' of the target RHEL system instead.'
|
||||
+ )
|
||||
+ ))
|
||||
+ report_hints.append(reporting.ExternalLink(
|
||||
+ url=luks2_convert_doc_url,
|
||||
+ title='LUKS versions in RHEL: Conversion'
|
||||
+ ))
|
||||
+
|
||||
+ if no_tpm2_partitions:
|
||||
+ summary += (
|
||||
+ '\n\nCurrently we require the process to be non-interactive and'
|
||||
+ ' offline. For this reason we require automatic unlock of'
|
||||
+ ' encrypted devices during the upgrade process.'
|
||||
+ ' Currently we support automatic unlocking during the upgrade only'
|
||||
+ ' for volumes bound to Clevis TPM2 token.'
|
||||
+ ' The following LUKS2 devices without Clevis TPM2 token '
|
||||
+ ' have been discovered on your system: {}'
|
||||
+ .format(''.join(_formatted_list_output(no_tpm2_partitions)))
|
||||
+ )
|
||||
+
|
||||
+ report_hints.append(reporting.Remediation(
|
||||
+ hint=(
|
||||
+ 'Add Clevis TPM2 binding to LUKS devices.'
|
||||
+ ' If some LUKS devices use still the old LUKS1 format, convert'
|
||||
+ ' them to LUKS2 prior to binding.'
|
||||
+ )
|
||||
+ ))
|
||||
+ report_hints.append(reporting.ExternalLink(
|
||||
+ url=clevis_doc_url,
|
||||
+ title='Configuring manual enrollment of LUKS-encrypted volumes by using a TPM 2.0 policy'
|
||||
+ )
|
||||
+ )
|
||||
+ create_report([
|
||||
+ reporting.Title('Detected LUKS devices unsuitable for in-place upgrade.'),
|
||||
+ reporting.Summary(summary),
|
||||
+ reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Groups([reporting.Groups.BOOT, reporting.Groups.ENCRYPTION]),
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
+ ] + report_hints)
|
||||
+
|
||||
+
|
||||
+def check_invalid_luks_devices():
|
||||
+ if get_source_major_version() == '7':
|
||||
+ # NOTE: keeping unchanged behaviour for IPU 7 -> 8
|
||||
+ apply_obsoleted_check_ipu_7_8()
|
||||
+ return
|
||||
+
|
||||
+ luks_dumps = next(api.consume(LuksDumps), None)
|
||||
+ if not luks_dumps:
|
||||
+ api.current_logger().debug('No LUKS volumes detected. Skipping.')
|
||||
+ return
|
||||
+
|
||||
+ luks1_partitions = []
|
||||
+ no_tpm2_partitions = []
|
||||
+ ceph_vol = _get_ceph_volumes()
|
||||
+ for luks_dump in luks_dumps.dumps:
|
||||
+ # if the device is managed by ceph, don't inhibit
|
||||
+ if luks_dump.device_name in ceph_vol:
|
||||
+ api.current_logger().debug('Skipping LUKS CEPH volume: {}'.format(luks_dump.device_name))
|
||||
+ continue
|
||||
+
|
||||
+ if luks_dump.version == 1:
|
||||
+ luks1_partitions.append(luks_dump.device_name)
|
||||
+ elif luks_dump.version == 2 and not _at_least_one_tpm_token(luks_dump):
|
||||
+ no_tpm2_partitions.append(luks_dump.device_name)
|
||||
+
|
||||
+ if luks1_partitions or no_tpm2_partitions:
|
||||
+ report_inhibitor(luks1_partitions, no_tpm2_partitions)
|
||||
+ else:
|
||||
+ required_crypt_rpms = [
|
||||
+ 'clevis',
|
||||
+ 'clevis-dracut',
|
||||
+ 'clevis-systemd',
|
||||
+ 'clevis-udisks2',
|
||||
+ 'clevis-luks',
|
||||
+ 'cryptsetup',
|
||||
+ 'tpm2-tss',
|
||||
+ 'tpm2-tools',
|
||||
+ 'tpm2-abrmd'
|
||||
+ ]
|
||||
+ api.produce(TargetUserSpaceUpgradeTasks(install_rpms=required_crypt_rpms))
|
||||
+ api.produce(UpgradeInitramfsTasks(include_dracut_modules=[
|
||||
+ DracutModule(name='clevis'),
|
||||
+ DracutModule(name='clevis-pin-tpm2')
|
||||
+ ])
|
||||
+ )
|
||||
diff --git a/repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py b/repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py
|
||||
index 405a3429..d559b54c 100644
|
||||
--- a/repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py
|
||||
+++ b/repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py
|
||||
@@ -1,34 +1,173 @@
|
||||
-from leapp.models import CephInfo, LsblkEntry, StorageInfo
|
||||
+"""
|
||||
+Unit tests for inhibitwhenluks actor
|
||||
+
|
||||
+Skip isort as it's kind of broken when mixing grid import and one line imports
|
||||
+
|
||||
+isort:skip_file
|
||||
+"""
|
||||
+
|
||||
+from leapp.libraries.common.config import version
|
||||
+from leapp.models import (
|
||||
+ CephInfo,
|
||||
+ LsblkEntry,
|
||||
+ LuksDump,
|
||||
+ LuksDumps,
|
||||
+ LuksToken,
|
||||
+ StorageInfo,
|
||||
+ TargetUserSpaceUpgradeTasks,
|
||||
+ UpgradeInitramfsTasks
|
||||
+)
|
||||
from leapp.reporting import Report
|
||||
from leapp.snactor.fixture import current_actor_context
|
||||
from leapp.utils.report import is_inhibitor
|
||||
|
||||
+_REPORT_TITLE_UNSUITABLE = 'Detected LUKS devices unsuitable for in-place upgrade.'
|
||||
|
||||
-def test_actor_with_luks(current_actor_context):
|
||||
- with_luks = [LsblkEntry(name='luks-132', kname='kname1', maj_min='253:0', rm='0', size='10G', bsize=10*(1 << 39),
|
||||
- ro='0', tp='crypt', mountpoint='', parent_name='', parent_path='')]
|
||||
|
||||
- current_actor_context.feed(StorageInfo(lsblk=with_luks))
|
||||
+def test_actor_with_luks1_notpm(monkeypatch, current_actor_context):
|
||||
+ monkeypatch.setattr(version, 'get_source_major_version', lambda: '8')
|
||||
+ luks_dump = LuksDump(
|
||||
+ version=1,
|
||||
+ uuid='dd09e6d4-b595-4f1c-80b8-fd47540e6464',
|
||||
+ device_path='/dev/sda',
|
||||
+ device_name='sda')
|
||||
+ current_actor_context.feed(LuksDumps(dumps=[luks_dump]))
|
||||
+ current_actor_context.feed(CephInfo(encrypted_volumes=[]))
|
||||
current_actor_context.run()
|
||||
assert current_actor_context.consume(Report)
|
||||
report_fields = current_actor_context.consume(Report)[0].report
|
||||
assert is_inhibitor(report_fields)
|
||||
+ assert not current_actor_context.consume(TargetUserSpaceUpgradeTasks)
|
||||
+ assert not current_actor_context.consume(UpgradeInitramfsTasks)
|
||||
|
||||
+ assert report_fields['title'] == _REPORT_TITLE_UNSUITABLE
|
||||
+ assert 'LUKS1 partitions have been discovered' in report_fields['summary']
|
||||
+ assert luks_dump.device_name in report_fields['summary']
|
||||
|
||||
-def test_actor_with_luks_ceph_only(current_actor_context):
|
||||
- with_luks = [LsblkEntry(name='luks-132', kname='kname1', maj_min='253:0', rm='0', size='10G', bsize=10*(1 << 39),
|
||||
- ro='0', tp='crypt', mountpoint='', parent_name='', parent_path='')]
|
||||
- ceph_volume = ['luks-132']
|
||||
- current_actor_context.feed(StorageInfo(lsblk=with_luks))
|
||||
- current_actor_context.feed(CephInfo(encrypted_volumes=ceph_volume))
|
||||
+
|
||||
+def test_actor_with_luks2_notpm(monkeypatch, current_actor_context):
|
||||
+ monkeypatch.setattr(version, 'get_source_major_version', lambda: '8')
|
||||
+ luks_dump = LuksDump(
|
||||
+ version=2,
|
||||
+ uuid='27b57c75-9adf-4744-ab04-9eb99726a301',
|
||||
+ device_path='/dev/sda',
|
||||
+ device_name='sda')
|
||||
+ current_actor_context.feed(LuksDumps(dumps=[luks_dump]))
|
||||
+ current_actor_context.feed(CephInfo(encrypted_volumes=[]))
|
||||
+ current_actor_context.run()
|
||||
+ assert current_actor_context.consume(Report)
|
||||
+ report_fields = current_actor_context.consume(Report)[0].report
|
||||
+ assert is_inhibitor(report_fields)
|
||||
+ assert not current_actor_context.consume(TargetUserSpaceUpgradeTasks)
|
||||
+ assert not current_actor_context.consume(UpgradeInitramfsTasks)
|
||||
+
|
||||
+ assert report_fields['title'] == _REPORT_TITLE_UNSUITABLE
|
||||
+ assert 'LUKS2 devices without Clevis TPM2 token' in report_fields['summary']
|
||||
+ assert luks_dump.device_name in report_fields['summary']
|
||||
+
|
||||
+
|
||||
+def test_actor_with_luks2_invalid_token(monkeypatch, current_actor_context):
|
||||
+ monkeypatch.setattr(version, 'get_source_major_version', lambda: '8')
|
||||
+ luks_dump = LuksDump(
|
||||
+ version=2,
|
||||
+ uuid='dc1dbe37-6644-4094-9839-8fc5dcbec0c6',
|
||||
+ device_path='/dev/sda',
|
||||
+ device_name='sda',
|
||||
+ tokens=[LuksToken(token_id=0, keyslot=1, token_type='clevis')])
|
||||
+ current_actor_context.feed(LuksDumps(dumps=[luks_dump]))
|
||||
+ current_actor_context.feed(CephInfo(encrypted_volumes=[]))
|
||||
+ current_actor_context.run()
|
||||
+ assert current_actor_context.consume(Report)
|
||||
+ report_fields = current_actor_context.consume(Report)[0].report
|
||||
+ assert is_inhibitor(report_fields)
|
||||
+
|
||||
+ assert report_fields['title'] == _REPORT_TITLE_UNSUITABLE
|
||||
+ assert 'LUKS2 devices without Clevis TPM2 token' in report_fields['summary']
|
||||
+ assert luks_dump.device_name in report_fields['summary']
|
||||
+ assert not current_actor_context.consume(TargetUserSpaceUpgradeTasks)
|
||||
+ assert not current_actor_context.consume(UpgradeInitramfsTasks)
|
||||
+
|
||||
+
|
||||
+def test_actor_with_luks2_clevis_tpm_token(monkeypatch, current_actor_context):
|
||||
+ monkeypatch.setattr(version, 'get_source_major_version', lambda: '8')
|
||||
+ luks_dump = LuksDump(
|
||||
+ version=2,
|
||||
+ uuid='83050bd9-61c6-4ff0-846f-bfd3ac9bfc67',
|
||||
+ device_path='/dev/sda',
|
||||
+ device_name='sda',
|
||||
+ tokens=[LuksToken(token_id=0, keyslot=1, token_type='clevis-tpm2')])
|
||||
+ current_actor_context.feed(LuksDumps(dumps=[luks_dump]))
|
||||
+ current_actor_context.feed(CephInfo(encrypted_volumes=[]))
|
||||
current_actor_context.run()
|
||||
assert not current_actor_context.consume(Report)
|
||||
|
||||
+ upgrade_tasks = current_actor_context.consume(TargetUserSpaceUpgradeTasks)
|
||||
+ assert len(upgrade_tasks) == 1
|
||||
+ assert set(upgrade_tasks[0].install_rpms) == set([
|
||||
+ 'clevis',
|
||||
+ 'clevis-dracut',
|
||||
+ 'clevis-systemd',
|
||||
+ 'clevis-udisks2',
|
||||
+ 'clevis-luks',
|
||||
+ 'cryptsetup',
|
||||
+ 'tpm2-tss',
|
||||
+ 'tpm2-tools',
|
||||
+ 'tpm2-abrmd'
|
||||
+ ])
|
||||
+ assert current_actor_context.consume(UpgradeInitramfsTasks)
|
||||
|
||||
-def test_actor_without_luks(current_actor_context):
|
||||
- without_luks = [LsblkEntry(name='sda1', kname='sda1', maj_min='8:0', rm='0', size='10G', bsize=10*(1 << 39),
|
||||
- ro='0', tp='part', mountpoint='/boot', parent_name='', parent_path='')]
|
||||
|
||||
- current_actor_context.feed(StorageInfo(lsblk=without_luks))
|
||||
+def test_actor_with_luks2_ceph(monkeypatch, current_actor_context):
|
||||
+ monkeypatch.setattr(version, 'get_source_major_version', lambda: '8')
|
||||
+ ceph_volume = ['sda']
|
||||
+ current_actor_context.feed(CephInfo(encrypted_volumes=ceph_volume))
|
||||
+ luks_dump = LuksDump(
|
||||
+ version=2,
|
||||
+ uuid='0edb8c11-1a04-4abd-a12d-93433ee7b8d8',
|
||||
+ device_path='/dev/sda',
|
||||
+ device_name='sda',
|
||||
+ tokens=[LuksToken(token_id=0, keyslot=1, token_type='clevis')])
|
||||
+ current_actor_context.feed(LuksDumps(dumps=[luks_dump]))
|
||||
current_actor_context.run()
|
||||
assert not current_actor_context.consume(Report)
|
||||
+
|
||||
+ # make sure we don't needlessly include clevis packages, when there is no clevis token
|
||||
+ assert not current_actor_context.consume(TargetUserSpaceUpgradeTasks)
|
||||
+
|
||||
+
|
||||
+LSBLK_ENTRY = LsblkEntry(
|
||||
+ name="luks-whatever",
|
||||
+ kname="dm-0",
|
||||
+ maj_min="252:1",
|
||||
+ rm="0",
|
||||
+ size="1G",
|
||||
+ bsize=1073741824,
|
||||
+ ro="0",
|
||||
+ tp="crypt",
|
||||
+ mountpoint="/",
|
||||
+ parent_name="",
|
||||
+ parent_path=""
|
||||
+)
|
||||
+
|
||||
+
|
||||
+def test_inhibitor_on_el7(monkeypatch, current_actor_context):
|
||||
+ # NOTE(pstodulk): consider it good enough as el7 stuff is going to be removed
|
||||
+ # soon.
|
||||
+ monkeypatch.setattr(version, 'get_source_major_version', lambda: '7')
|
||||
+
|
||||
+ luks_dump = LuksDump(
|
||||
+ version=2,
|
||||
+ uuid='83050bd9-61c6-4ff0-846f-bfd3ac9bfc67',
|
||||
+ device_path='/dev/sda',
|
||||
+ device_name='sda',
|
||||
+ tokens=[LuksToken(token_id=0, keyslot=1, token_type='clevis-tpm2')])
|
||||
+ current_actor_context.feed(LuksDumps(dumps=[luks_dump]))
|
||||
+ current_actor_context.feed(CephInfo(encrypted_volumes=[]))
|
||||
+
|
||||
+ current_actor_context.feed(StorageInfo(lsblk=[LSBLK_ENTRY]))
|
||||
+ current_actor_context.run()
|
||||
+ assert current_actor_context.consume(Report)
|
||||
+
|
||||
+ report_fields = current_actor_context.consume(Report)[0].report
|
||||
+ assert is_inhibitor(report_fields)
|
||||
+ assert report_fields['title'] == 'LUKS encrypted partition detected'
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,155 +0,0 @@
|
||||
From 747e4467aafe7c97b2a02b67527af70083a89e91 Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 18:11:02 +0100
|
||||
Subject: [PATCH 20/44] opensslproviders: Use distro name in the leapp comment
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../libraries/add_provider.py | 13 ++--
|
||||
.../tests/test_add_provider.py | 66 ++++++++++++-------
|
||||
2 files changed, 53 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/opensslproviders/libraries/add_provider.py b/repos/system_upgrade/el8toel9/actors/opensslproviders/libraries/add_provider.py
|
||||
index 91462f18..3bf4cbf8 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/opensslproviders/libraries/add_provider.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/opensslproviders/libraries/add_provider.py
|
||||
@@ -2,13 +2,13 @@ import re
|
||||
|
||||
from leapp import reporting
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.stdlib import api
|
||||
|
||||
# The openssl configuration file
|
||||
# TODO copied from opensslconfigscanner/libraries/readconf.py
|
||||
CONFIG = '/etc/pki/tls/openssl.cnf'
|
||||
|
||||
-LEAPP_COMMENT = '# Modified by leapp during upgrade to RHEL 9\n'
|
||||
APPEND_STRING = (
|
||||
'[provider_sect]\n'
|
||||
'default = default_sect\n'
|
||||
@@ -22,6 +22,11 @@ APPEND_STRING = (
|
||||
)
|
||||
|
||||
|
||||
+def _get_leapp_comment():
|
||||
+ # cannot access DISTRO_REPORT_NAMES at top level
|
||||
+ return f"# Modified by leapp during upgrade to {DISTRO_REPORT_NAMES.target} 9\n"
|
||||
+
|
||||
+
|
||||
def _add_lines(lines, add):
|
||||
"""
|
||||
Add lines to the list of lines. Breaking possible newlines onto separate items
|
||||
@@ -76,12 +81,12 @@ def _modify_file(f, fail_on_error=True):
|
||||
lines = f.readlines()
|
||||
lines = _replace(lines, r"openssl_conf\s*=\s*default_modules",
|
||||
"openssl_conf = openssl_init",
|
||||
- LEAPP_COMMENT, True, fail_on_error)
|
||||
+ _get_leapp_comment(), True, fail_on_error)
|
||||
lines = _replace(lines, r"\[\s*default_modules\s*\]",
|
||||
"[openssl_init]\n"
|
||||
"providers = provider_sect",
|
||||
- LEAPP_COMMENT, True, fail_on_error)
|
||||
- lines = _append(lines, APPEND_STRING, LEAPP_COMMENT)
|
||||
+ _get_leapp_comment(), True, fail_on_error)
|
||||
+ lines = _append(lines, APPEND_STRING, _get_leapp_comment())
|
||||
f.seek(0)
|
||||
f.write(''.join(lines))
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/opensslproviders/tests/test_add_provider.py b/repos/system_upgrade/el8toel9/actors/opensslproviders/tests/test_add_provider.py
|
||||
index 78f2e9c6..c6e31c29 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/opensslproviders/tests/test_add_provider.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/opensslproviders/tests/test_add_provider.py
|
||||
@@ -3,12 +3,14 @@ import pytest
|
||||
from leapp.libraries.actor.add_provider import (
|
||||
_add_lines,
|
||||
_append,
|
||||
+ _get_leapp_comment,
|
||||
_modify_file,
|
||||
_replace,
|
||||
APPEND_STRING,
|
||||
- LEAPP_COMMENT,
|
||||
NotFoundException
|
||||
)
|
||||
+from leapp.libraries.common.testutils import CurrentActorMocked
|
||||
+from leapp.libraries.stdlib import api
|
||||
|
||||
testdata = (
|
||||
([], 'one', ['one\n']),
|
||||
@@ -80,32 +82,52 @@ class MockFile:
|
||||
|
||||
|
||||
testdata = (
|
||||
- ('', ''),
|
||||
- ('openssl_conf=default_modules\n',
|
||||
- '{}# openssl_conf=default_modules\nopenssl_conf = openssl_init\n'.format(LEAPP_COMMENT)),
|
||||
- ('openssl_conf = default_modules\n',
|
||||
- '{}# openssl_conf = default_modules\nopenssl_conf = openssl_init\n'.format(LEAPP_COMMENT)),
|
||||
- ('openssl_conf = default_modules\n',
|
||||
- '{}# openssl_conf = default_modules\nopenssl_conf = openssl_init\n'.format(LEAPP_COMMENT)),
|
||||
- (' openssl_conf = default_modules \n',
|
||||
- '{}# openssl_conf = default_modules \nopenssl_conf = openssl_init\n'.format(LEAPP_COMMENT)),
|
||||
- ('[default_modules]\n',
|
||||
- '{}# [default_modules]\n[openssl_init]\nproviders = provider_sect\n'.format(LEAPP_COMMENT)),
|
||||
- ('[ default_modules ]\n',
|
||||
- '{}# [ default_modules ]\n[openssl_init]\nproviders = provider_sect\n'.format(LEAPP_COMMENT)),
|
||||
- (' [ default_modules ] \n',
|
||||
- '{}# [ default_modules ] \n[openssl_init]\nproviders = provider_sect\n'.format(LEAPP_COMMENT)),
|
||||
- ('openssl_conf=default_modules\n[default_modules]\n',
|
||||
- '{c}# openssl_conf=default_modules\nopenssl_conf = openssl_init\n'
|
||||
- '{c}# [default_modules]\n[openssl_init]\nproviders = provider_sect\n'.format(c=LEAPP_COMMENT)),
|
||||
+ ("", ""),
|
||||
+ (
|
||||
+ "openssl_conf=default_modules\n",
|
||||
+ "{c}# openssl_conf=default_modules\nopenssl_conf = openssl_init\n",
|
||||
+ ),
|
||||
+ (
|
||||
+ "openssl_conf = default_modules\n",
|
||||
+ "{c}# openssl_conf = default_modules\nopenssl_conf = openssl_init\n",
|
||||
+ ),
|
||||
+ (
|
||||
+ "openssl_conf = default_modules\n",
|
||||
+ "{c}# openssl_conf = default_modules\nopenssl_conf = openssl_init\n",
|
||||
+ ),
|
||||
+ (
|
||||
+ " openssl_conf = default_modules \n",
|
||||
+ "{c}# openssl_conf = default_modules \nopenssl_conf = openssl_init\n",
|
||||
+ ),
|
||||
+ (
|
||||
+ "[default_modules]\n",
|
||||
+ "{c}# [default_modules]\n[openssl_init]\nproviders = provider_sect\n",
|
||||
+ ),
|
||||
+ (
|
||||
+ "[ default_modules ]\n",
|
||||
+ "{c}# [ default_modules ]\n[openssl_init]\nproviders = provider_sect\n",
|
||||
+ ),
|
||||
+ (
|
||||
+ " [ default_modules ] \n",
|
||||
+ "{c}# [ default_modules ] \n[openssl_init]\nproviders = provider_sect\n",
|
||||
+ ),
|
||||
+ (
|
||||
+ "openssl_conf=default_modules\n[default_modules]\n",
|
||||
+ "{c}# openssl_conf=default_modules\nopenssl_conf = openssl_init\n"
|
||||
+ "{c}# [default_modules]\n[openssl_init]\nproviders = provider_sect\n",
|
||||
+ ),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('file_content,expected', testdata)
|
||||
-def test_modify_file(file_content, expected):
|
||||
- f = MockFile(file_content)
|
||||
+def test_modify_file(monkeypatch, file_content, expected):
|
||||
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked())
|
||||
+
|
||||
+ f = MockFile(file_content.format(c=_get_leapp_comment()))
|
||||
|
||||
# Test separate replaces and do not fail if pattern is not found
|
||||
_modify_file(f, False)
|
||||
|
||||
- assert f.content == "{}{}{}\n".format(expected, LEAPP_COMMENT, APPEND_STRING)
|
||||
+ assert f.content == "{}{}{}\n".format(
|
||||
+ expected.format(c=_get_leapp_comment()), _get_leapp_comment(), APPEND_STRING
|
||||
+ )
|
||||
--
|
||||
2.53.0
|
||||
|
||||
57
SOURCES/0021-Rename-inhibitwhenluks-actor-to-checkluks.patch
Normal file
57
SOURCES/0021-Rename-inhibitwhenluks-actor-to-checkluks.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 8e5fe75e4ee76eb62eb51001c28f1f1443f0a563 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Fri, 18 Oct 2024 07:13:42 +0200
|
||||
Subject: [PATCH 21/40] Rename inhibitwhenluks actor to checkluks
|
||||
|
||||
The actor nowadays does more then just inhibiting the upgrade when
|
||||
LUKS is detected. Let's rename it to respect current behaviour.
|
||||
---
|
||||
.../common/actors/{inhibitwhenluks => checkluks}/actor.py | 6 +++---
|
||||
.../inhibitwhenluks.py => checkluks/libraries/checkluks.py} | 0
|
||||
.../tests/test_checkluks.py} | 0
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
rename repos/system_upgrade/common/actors/{inhibitwhenluks => checkluks}/actor.py (85%)
|
||||
rename repos/system_upgrade/common/actors/{inhibitwhenluks/libraries/inhibitwhenluks.py => checkluks/libraries/checkluks.py} (100%)
|
||||
rename repos/system_upgrade/common/actors/{inhibitwhenluks/tests/test_inhibitwhenluks.py => checkluks/tests/test_checkluks.py} (100%)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py b/repos/system_upgrade/common/actors/checkluks/actor.py
|
||||
similarity index 85%
|
||||
rename from repos/system_upgrade/common/actors/inhibitwhenluks/actor.py
|
||||
rename to repos/system_upgrade/common/actors/checkluks/actor.py
|
||||
index 65607167..607fd040 100644
|
||||
--- a/repos/system_upgrade/common/actors/inhibitwhenluks/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkluks/actor.py
|
||||
@@ -1,11 +1,11 @@
|
||||
from leapp.actors import Actor
|
||||
-from leapp.libraries.actor.inhibitwhenluks import check_invalid_luks_devices
|
||||
+from leapp.libraries.actor.checkluks import check_invalid_luks_devices
|
||||
from leapp.models import CephInfo, LuksDumps, StorageInfo, TargetUserSpaceUpgradeTasks, UpgradeInitramfsTasks
|
||||
from leapp.reporting import Report
|
||||
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
|
||||
|
||||
-class InhibitWhenLuks(Actor):
|
||||
+class CheckLuks(Actor):
|
||||
"""
|
||||
Check if any encrypted partitions are in use and whether they are supported for the upgrade.
|
||||
|
||||
@@ -15,7 +15,7 @@ class InhibitWhenLuks(Actor):
|
||||
during the process).
|
||||
"""
|
||||
|
||||
- name = 'check_luks_and_inhibit'
|
||||
+ name = 'check_luks'
|
||||
consumes = (CephInfo, LuksDumps, StorageInfo)
|
||||
produces = (Report, TargetUserSpaceUpgradeTasks, UpgradeInitramfsTasks)
|
||||
tags = (ChecksPhaseTag, IPUWorkflowTag)
|
||||
diff --git a/repos/system_upgrade/common/actors/inhibitwhenluks/libraries/inhibitwhenluks.py b/repos/system_upgrade/common/actors/checkluks/libraries/checkluks.py
|
||||
similarity index 100%
|
||||
rename from repos/system_upgrade/common/actors/inhibitwhenluks/libraries/inhibitwhenluks.py
|
||||
rename to repos/system_upgrade/common/actors/checkluks/libraries/checkluks.py
|
||||
diff --git a/repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py b/repos/system_upgrade/common/actors/checkluks/tests/test_checkluks.py
|
||||
similarity index 100%
|
||||
rename from repos/system_upgrade/common/actors/inhibitwhenluks/tests/test_inhibitwhenluks.py
|
||||
rename to repos/system_upgrade/common/actors/checkluks/tests/test_checkluks.py
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
From 35ea535848223e32bd01d726a838abd2ae84fa3e Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 18:30:51 +0100
|
||||
Subject: [PATCH 21/44] opensslconfigcheck: Dont make the recommendation as
|
||||
redhat if not rhel target
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../opensslconfigcheck/libraries/opensslconfigcheck.py | 9 +++++++--
|
||||
.../tests/component_test_opensslconfigcheck.py | 7 +++++--
|
||||
2 files changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/opensslconfigcheck/libraries/opensslconfigcheck.py b/repos/system_upgrade/el8toel9/actors/opensslconfigcheck/libraries/opensslconfigcheck.py
|
||||
index 07c1b22f..a686a7f2 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/opensslconfigcheck/libraries/opensslconfigcheck.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/opensslconfigcheck/libraries/opensslconfigcheck.py
|
||||
@@ -1,4 +1,5 @@
|
||||
from leapp import reporting
|
||||
+from leapp.libraries.common.config import get_target_distro_id
|
||||
from leapp.libraries.stdlib import api
|
||||
|
||||
|
||||
@@ -228,14 +229,18 @@ def check_crypto_policies(config):
|
||||
path=("default_modules", "ssl_conf", "ssl_module",
|
||||
"system_default", "crypto_policy", ".include"),
|
||||
value="/etc/crypto-policies/back-ends/opensslcnf.config"):
|
||||
+
|
||||
reporting.create_report([
|
||||
reporting.Title('The OpenSSL configuration is missing the crypto policies integration'),
|
||||
+
|
||||
reporting.Summary(
|
||||
'The OpenSSL configuration file `/etc/pki/tls/openssl.cnf` does not contain the '
|
||||
'directive to include the system-wide crypto policies. This is not recommended '
|
||||
- 'by Red Hat and can lead to decreasing overall system security and inconsistent '
|
||||
+ '{} can lead to decreasing overall system security and inconsistent '
|
||||
'behavior between applications. If you need to adjust the crypto policies to your '
|
||||
- 'needs, it is recommended to use custom crypto policies.'
|
||||
+ 'needs, it is recommended to use custom crypto policies.'.format(
|
||||
+ "by Red Hat and" if get_target_distro_id() == "rhel" else "as it"
|
||||
+ )
|
||||
),
|
||||
reporting.Severity(reporting.Severity.MEDIUM),
|
||||
reporting.Groups([
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/opensslconfigcheck/tests/component_test_opensslconfigcheck.py b/repos/system_upgrade/el8toel9/actors/opensslconfigcheck/tests/component_test_opensslconfigcheck.py
|
||||
index d3363def..892cb7f1 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/opensslconfigcheck/tests/component_test_opensslconfigcheck.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/opensslconfigcheck/tests/component_test_opensslconfigcheck.py
|
||||
@@ -1,3 +1,4 @@
|
||||
+from leapp.libraries.actor import opensslconfigcheck
|
||||
from leapp.models import OpenSslConfig, OpenSslConfigBlock, OpenSslConfigPair, Report
|
||||
|
||||
|
||||
@@ -12,7 +13,8 @@ def test_actor_execution_empty(current_actor_context):
|
||||
assert not current_actor_context.consume(Report)
|
||||
|
||||
|
||||
-def test_actor_execution_empty_modified(current_actor_context):
|
||||
+def test_actor_execution_empty_modified(current_actor_context, monkeypatch):
|
||||
+ monkeypatch.setattr(opensslconfigcheck, 'get_target_distro_id', lambda: 'rhel')
|
||||
current_actor_context.feed(
|
||||
OpenSslConfig(
|
||||
blocks=[],
|
||||
@@ -25,7 +27,8 @@ def test_actor_execution_empty_modified(current_actor_context):
|
||||
assert 'missing the crypto policies integration' in r[0].report['title']
|
||||
|
||||
|
||||
-def test_actor_execution_default_modified(current_actor_context):
|
||||
+def test_actor_execution_default_modified(current_actor_context, monkeypatch):
|
||||
+ monkeypatch.setattr(opensslconfigcheck, 'get_target_distro_id', lambda: 'rhel')
|
||||
current_actor_context.feed(
|
||||
OpenSslConfig(
|
||||
openssl_conf='default_modules',
|
||||
--
|
||||
2.53.0
|
||||
|
||||
172
SOURCES/0022-Fix-IPU-being-blocked-by-resource-limitations.patch
Normal file
172
SOURCES/0022-Fix-IPU-being-blocked-by-resource-limitations.patch
Normal file
@ -0,0 +1,172 @@
|
||||
From 5e6d176ab685f2e85ac1aea9533b04d46f25e9b7 Mon Sep 17 00:00:00 2001
|
||||
From: tomasfratrik <tomasfratrik8@gmail.com>
|
||||
Date: Tue, 18 Jun 2024 10:22:35 +0200
|
||||
Subject: [PATCH 22/40] Fix IPU being blocked by resource limitations
|
||||
|
||||
First resource limit is maximum number of open file descriptors limit,
|
||||
second one being limit for maximum writable file size. Plus add unit
|
||||
tests.
|
||||
|
||||
Resolves: RHEL-26459 and RHEL-16881
|
||||
---
|
||||
commands/command_utils.py | 38 ++++++++++++++++++
|
||||
commands/preupgrade/__init__.py | 2 +
|
||||
commands/tests/test_upgrade_paths.py | 60 ++++++++++++++++++++++++++++
|
||||
commands/upgrade/__init__.py | 3 ++
|
||||
4 files changed, 103 insertions(+)
|
||||
|
||||
diff --git a/commands/command_utils.py b/commands/command_utils.py
|
||||
index 4f6f99eb..2810a542 100644
|
||||
--- a/commands/command_utils.py
|
||||
+++ b/commands/command_utils.py
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
+import resource
|
||||
|
||||
from leapp.exceptions import CommandError
|
||||
from leapp.utils import path
|
||||
@@ -140,3 +141,40 @@ def vet_upgrade_path(args):
|
||||
flavor=flavor,
|
||||
choices=','.join(supported_target_versions)))
|
||||
return (target_release, flavor)
|
||||
+
|
||||
+
|
||||
+def set_resource_limits():
|
||||
+ """
|
||||
+ Set resource limits for the maximum number of open file descriptors and the maximum writable file size.
|
||||
+
|
||||
+ :raises: `CommandError` if the resource limits cannot be set
|
||||
+ """
|
||||
+
|
||||
+ def set_resource_limit(resource_type, soft, hard):
|
||||
+ rtype_string = (
|
||||
+ 'open file descriptors' if resource_type == resource.RLIMIT_NOFILE
|
||||
+ else 'writable file size' if resource_type == resource.RLIMIT_FSIZE
|
||||
+ else 'unknown resource'
|
||||
+ )
|
||||
+ try:
|
||||
+ resource.setrlimit(resource_type, (soft, hard))
|
||||
+ except ValueError as err:
|
||||
+ raise CommandError(
|
||||
+ 'Failure occurred while attempting to set soft limit higher than the hard limit. '
|
||||
+ 'Resource type: {}, error: {}'.format(rtype_string, err)
|
||||
+ )
|
||||
+ except OSError as err:
|
||||
+ raise CommandError(
|
||||
+ 'Failed to set resource limit. Resource type: {}, error: {}'.format(rtype_string, err)
|
||||
+ )
|
||||
+
|
||||
+ soft_nofile, _ = resource.getrlimit(resource.RLIMIT_NOFILE)
|
||||
+ soft_fsize, _ = resource.getrlimit(resource.RLIMIT_FSIZE)
|
||||
+ nofile_limit = 1024*16
|
||||
+ fsize_limit = resource.RLIM_INFINITY
|
||||
+
|
||||
+ if soft_nofile < nofile_limit:
|
||||
+ set_resource_limit(resource.RLIMIT_NOFILE, nofile_limit, nofile_limit)
|
||||
+
|
||||
+ if soft_fsize != fsize_limit:
|
||||
+ set_resource_limit(resource.RLIMIT_FSIZE, fsize_limit, fsize_limit)
|
||||
diff --git a/commands/preupgrade/__init__.py b/commands/preupgrade/__init__.py
|
||||
index 5a89069f..a9fa40e0 100644
|
||||
--- a/commands/preupgrade/__init__.py
|
||||
+++ b/commands/preupgrade/__init__.py
|
||||
@@ -59,6 +59,8 @@ def preupgrade(args, breadcrumbs):
|
||||
except LeappError as exc:
|
||||
raise CommandError(exc.message)
|
||||
|
||||
+ command_utils.set_resource_limits()
|
||||
+
|
||||
workflow = repositories.lookup_workflow('IPUWorkflow')()
|
||||
util.warn_if_unsupported(configuration)
|
||||
util.process_whitelist_experimental(repositories, workflow, configuration, logger)
|
||||
diff --git a/commands/tests/test_upgrade_paths.py b/commands/tests/test_upgrade_paths.py
|
||||
index 53f081a5..f1312f66 100644
|
||||
--- a/commands/tests/test_upgrade_paths.py
|
||||
+++ b/commands/tests/test_upgrade_paths.py
|
||||
@@ -1,3 +1,5 @@
|
||||
+import resource
|
||||
+
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
@@ -50,3 +52,61 @@ def test_vet_upgrade_path(mock_open, monkeypatch):
|
||||
monkeypatch.setenv('LEAPP_DEVEL_TARGET_RELEASE', '9.0')
|
||||
args = mock.Mock(target='1.2')
|
||||
assert command_utils.vet_upgrade_path(args) == ('9.0', 'default')
|
||||
+
|
||||
+
|
||||
+def _mock_getrlimit_factory(nofile_limits=(1024, 4096), fsize_limits=(1024, 4096)):
|
||||
+ """
|
||||
+ Factory function to create a mock `getrlimit` function with configurable return values.
|
||||
+ The default param values are lower than the expected values.
|
||||
+
|
||||
+ :param nofile_limits: Tuple representing (soft, hard) limits for `RLIMIT_NOFILE`
|
||||
+ :param fsize_limits: Tuple representing (soft, hard) limits for `RLIMIT_FSIZE`
|
||||
+ :return: A mock `getrlimit` function
|
||||
+ """
|
||||
+ def mock_getrlimit(resource_type):
|
||||
+ if resource_type == resource.RLIMIT_NOFILE:
|
||||
+ return nofile_limits
|
||||
+ if resource_type == resource.RLIMIT_FSIZE:
|
||||
+ return fsize_limits
|
||||
+ return (0, 0)
|
||||
+
|
||||
+ return mock_getrlimit
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize("nofile_limits, fsize_limits, expected_calls", [
|
||||
+ # Case where both limits need to be increased
|
||||
+ ((1024, 4096), (1024, 4096), [
|
||||
+ (resource.RLIMIT_NOFILE, (1024*16, 1024*16)),
|
||||
+ (resource.RLIMIT_FSIZE, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
|
||||
+ ]),
|
||||
+ # Case where neither limit needs to be changed
|
||||
+ ((1024*16, 1024*16), (resource.RLIM_INFINITY, resource.RLIM_INFINITY), [])
|
||||
+])
|
||||
+def test_set_resource_limits_increase(monkeypatch, nofile_limits, fsize_limits, expected_calls):
|
||||
+ setrlimit_called = []
|
||||
+
|
||||
+ def mock_setrlimit(resource_type, limits):
|
||||
+ setrlimit_called.append((resource_type, limits))
|
||||
+
|
||||
+ monkeypatch.setattr(resource, "getrlimit", _mock_getrlimit_factory(nofile_limits, fsize_limits))
|
||||
+ monkeypatch.setattr(resource, "setrlimit", mock_setrlimit)
|
||||
+
|
||||
+ command_utils.set_resource_limits()
|
||||
+
|
||||
+ assert setrlimit_called == expected_calls
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize("errortype, expected_message", [
|
||||
+ (OSError, "Failed to set resource limit"),
|
||||
+ (ValueError, "Failure occurred while attempting to set soft limit higher than the hard limit")
|
||||
+])
|
||||
+def test_set_resource_limits_exceptions(monkeypatch, errortype, expected_message):
|
||||
+ monkeypatch.setattr(resource, "getrlimit", _mock_getrlimit_factory())
|
||||
+
|
||||
+ def mock_setrlimit(*args, **kwargs):
|
||||
+ raise errortype("mocked error")
|
||||
+
|
||||
+ monkeypatch.setattr(resource, "setrlimit", mock_setrlimit)
|
||||
+
|
||||
+ with pytest.raises(CommandError, match=expected_message):
|
||||
+ command_utils.set_resource_limits()
|
||||
diff --git a/commands/upgrade/__init__.py b/commands/upgrade/__init__.py
|
||||
index 1e15b59c..c7487fde 100644
|
||||
--- a/commands/upgrade/__init__.py
|
||||
+++ b/commands/upgrade/__init__.py
|
||||
@@ -89,6 +89,9 @@ def upgrade(args, breadcrumbs):
|
||||
repositories = util.load_repositories()
|
||||
except LeappError as exc:
|
||||
raise CommandError(exc.message)
|
||||
+
|
||||
+ command_utils.set_resource_limits()
|
||||
+
|
||||
workflow = repositories.lookup_workflow('IPUWorkflow')(auto_reboot=args.reboot)
|
||||
util.process_whitelist_experimental(repositories, workflow, configuration, logger)
|
||||
util.warn_if_unsupported(configuration)
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,73 +0,0 @@
|
||||
From 367654a5eeaa1a13d857ff04acdc1e7890550fc1 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 17:35:53 +0100
|
||||
Subject: [PATCH 22/44] checkmicroarchitecture: Respect distro name in report
|
||||
|
||||
Also add stable report key, the title used for key computation was using
|
||||
target major ver == 8:
|
||||
'Current x86-64 microarchitecture is unsupported in RHEL8'
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../libraries/checkmicroarchitecture.py | 17 ++++++++++-------
|
||||
1 file changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py b/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
index a063b534..3011f906 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
|
||||
@@ -3,6 +3,7 @@ from collections import namedtuple
|
||||
from leapp import reporting
|
||||
from leapp.libraries.common.config.architecture import ARCH_X86_64, matches_architecture
|
||||
from leapp.libraries.common.config.version import get_target_major_version
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import CPUInfo
|
||||
|
||||
@@ -13,11 +14,11 @@ X86_64_V3_FLAGS = ['avx2', 'bmi1', 'bmi2', 'f16c', 'fma', 'abm', 'movbe', 'xsave
|
||||
MicroarchInfo = namedtuple('MicroarchInfo', ('required_flags', 'extra_report_fields', 'microarch_ver'))
|
||||
|
||||
|
||||
-def _inhibit_upgrade(missing_flags, target_rhel, microarch_ver, extra_report_fields=None):
|
||||
- title = 'Current x86-64 microarchitecture is unsupported in {0}'.format(target_rhel)
|
||||
+def _inhibit_upgrade(missing_flags, target_distro, microarch_ver, extra_report_fields=None):
|
||||
+ title = 'Current x86-64 microarchitecture is unsupported in the target OS'
|
||||
summary = ('{0} has a higher CPU requirement than older versions, it now requires a CPU '
|
||||
'compatible with {1} instruction set or higher.\n\n'
|
||||
- 'Missings flags detected are: {2}\n').format(target_rhel, microarch_ver, ', '.join(missing_flags))
|
||||
+ 'Missings flags detected are: {2}\n').format(target_distro, microarch_ver, ', '.join(missing_flags))
|
||||
|
||||
report_fields = [
|
||||
reporting.Title(title),
|
||||
@@ -28,7 +29,8 @@ def _inhibit_upgrade(missing_flags, target_rhel, microarch_ver, extra_report_fie
|
||||
reporting.Remediation(hint=('If a case of using virtualization, virtualization platforms often allow '
|
||||
'configuring a minimum denominator CPU model for compatibility when migrating '
|
||||
'between different CPU models. Ensure that minimum requirements are not below '
|
||||
- 'that of {0}\n').format(target_rhel)),
|
||||
+ 'that of {0}\n').format(target_distro)),
|
||||
+ reporting.Key('0f48cdbe5aa2584e2ca7f4eb470b9b79da9e515d')
|
||||
]
|
||||
|
||||
if extra_report_fields:
|
||||
@@ -69,14 +71,15 @@ def process():
|
||||
|
||||
microarch_info = rhel_major_to_microarch_reqs.get(get_target_major_version())
|
||||
if not microarch_info:
|
||||
- api.current_logger().info('No known microarchitecture requirements are known for target RHEL%s.',
|
||||
- get_target_major_version())
|
||||
+ api.current_logger().info(
|
||||
+ 'No known microarchitecture requirements are known'
|
||||
+ ' for target {target_distro} {version}.'.format(**DISTRO_REPORT_NAMES, version=get_target_major_version()))
|
||||
return
|
||||
|
||||
missing_flags = [flag for flag in microarch_info.required_flags if flag not in cpuinfo.flags]
|
||||
api.current_logger().debug('Required flags missing: %s', missing_flags)
|
||||
if missing_flags:
|
||||
_inhibit_upgrade(missing_flags,
|
||||
- 'RHEL{0}'.format(get_target_major_version()),
|
||||
+ '{target_distro} {version}'.format(**DISTRO_REPORT_NAMES, version=get_target_major_version()),
|
||||
microarch_info.microarch_ver,
|
||||
extra_report_fields=microarch_info.extra_report_fields)
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
From 0e250cdc4672263d753209c420c15a33f9ae90eb Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 17:45:16 +0100
|
||||
Subject: [PATCH 23/44] checkmemory: Respect distro name in reports
|
||||
|
||||
Also add stable key to the report, the distro key was computed as if for
|
||||
7->8 upgrade, the title:
|
||||
'Minimum memory requirements for RHEL 8 are not met'
|
||||
|
||||
as the reports for 8->9 and 9->10 are unified with the above report, the
|
||||
following keys are no longer used:
|
||||
Minimum memory requirements for RHEL 9 are not met -> e3066f6fae135718b3158597145554c4f22b9372
|
||||
Minimum memory requirements for RHEL 10 are not met -> ccf14c3ac899f3cdc3123dadac399cafe28ce2ef
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../checkmemory/libraries/checkmemory.py | 33 ++++++++++---------
|
||||
.../checkmemory/tests/test_checkmemory.py | 2 +-
|
||||
2 files changed, 18 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/checkmemory/libraries/checkmemory.py b/repos/system_upgrade/common/actors/checkmemory/libraries/checkmemory.py
|
||||
index 040b404b..cdf8faa6 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkmemory/libraries/checkmemory.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkmemory/libraries/checkmemory.py
|
||||
@@ -1,6 +1,6 @@
|
||||
from leapp import reporting
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
-from leapp.libraries.common.config import architecture, version
|
||||
+from leapp.libraries.common.config import architecture
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import MemoryInfo
|
||||
|
||||
@@ -32,23 +32,24 @@ def process():
|
||||
minimum_req_error = _check_memory(memoryinfo)
|
||||
|
||||
if minimum_req_error:
|
||||
- title = 'Minimum memory requirements for RHEL {} are not met'.format(version.get_target_major_version())
|
||||
+ title = "Minimum memory requirements for the target OS are not met"
|
||||
summary = 'Memory detected: {} MiB, required: {} MiB'.format(
|
||||
int(minimum_req_error['detected'] / 1024),
|
||||
int(minimum_req_error['minimal_req'] / 1024),
|
||||
)
|
||||
reporting.create_report([
|
||||
- reporting.Title(title),
|
||||
- reporting.Summary(summary),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.SANITY, reporting.Groups.INHIBITOR]),
|
||||
- reporting.ExternalLink(
|
||||
- url='https://access.redhat.com/solutions/7014179',
|
||||
- title='Leapp upgrade fail with error"Minimum memory requirements '
|
||||
- 'for RHEL 8 are not met"Upgrade cannot proceed'
|
||||
- ),
|
||||
- reporting.ExternalLink(
|
||||
- url='https://access.redhat.com/articles/rhel-limits',
|
||||
- title='Red Hat Enterprise Linux Technology Capabilities and Limits'
|
||||
- ),
|
||||
- ])
|
||||
+ reporting.Title(title),
|
||||
+ reporting.Summary(summary),
|
||||
+ reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Groups([reporting.Groups.SANITY, reporting.Groups.INHIBITOR]),
|
||||
+ reporting.ExternalLink(
|
||||
+ url='https://access.redhat.com/solutions/7014179',
|
||||
+ title='Leapp upgrade fail with error "Minimum memory requirements '
|
||||
+ 'for RHEL 8 are not met"Upgrade cannot proceed'
|
||||
+ ),
|
||||
+ reporting.ExternalLink(
|
||||
+ url='https://access.redhat.com/articles/rhel-limits',
|
||||
+ title='Red Hat Enterprise Linux Technology Capabilities and Limits'
|
||||
+ ),
|
||||
+ reporting.Key('be50646b45beb8304c13daf5380d836a4be8e1cc'),
|
||||
+ ])
|
||||
diff --git a/repos/system_upgrade/common/actors/checkmemory/tests/test_checkmemory.py b/repos/system_upgrade/common/actors/checkmemory/tests/test_checkmemory.py
|
||||
index 79158dc6..38ddfa33 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkmemory/tests/test_checkmemory.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkmemory/tests/test_checkmemory.py
|
||||
@@ -21,7 +21,7 @@ def test_check_memory_high(monkeypatch):
|
||||
|
||||
|
||||
def test_report(monkeypatch):
|
||||
- title_msg = 'Minimum memory requirements for RHEL 9 are not met'
|
||||
+ title_msg = 'Minimum memory requirements for the target OS are not met'
|
||||
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked())
|
||||
monkeypatch.setattr(api, 'consume', lambda x: iter([MemoryInfo(mem_total=129)]))
|
||||
monkeypatch.setattr(reporting, "create_report", create_report_mocked())
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,675 @@
|
||||
From e1bdf2c02dd193cdd7a2da95e2a3cfa5e6e1e8b3 Mon Sep 17 00:00:00 2001
|
||||
From: mhecko <mhecko@redhat.com>
|
||||
Date: Mon, 29 Apr 2024 11:16:46 +0200
|
||||
Subject: [PATCH 23/40] feature: add possibility to use net.naming-scheme
|
||||
|
||||
Leapp writes .link files to prevent interfaces being renamed
|
||||
after booting to post-upgrade system. This patch adds a less
|
||||
error-prone approach that uses net.naming-scheme kernel param.
|
||||
The naming-scheme tells udev what hardware properties to use
|
||||
when composing a device name. Moreover, possible values of this
|
||||
parameter are coarse-grained "profiles", that tell udev to
|
||||
behave as if it did on RHEL8.0.
|
||||
|
||||
The functionality is enabled by setting LEAPP_USE_NET_NAMING_SCHEME
|
||||
environmental variable to 1. If the feature is enabled, the .link
|
||||
file generation is disabled. A kernel parameter `net.naming-scheme=`
|
||||
is added to the upgrade boot entry and the post-upgrade entry.
|
||||
The value of the parameter will be `rhel-<source_major>.0`. Note
|
||||
that the minor source version is *not used*. Using also source major
|
||||
version instead of 0 causes the device names to change slightly,
|
||||
so we use 0. Moreover, an extra RPM named `rhel-net-naming-sysattrs`
|
||||
is installed to the target system and target userspace container.
|
||||
The RPM provides definitions of the "profiles" for net.naming-scheme.
|
||||
|
||||
The feature is available only for 8>9 and higher. Attempting to
|
||||
upgrade 7>8 with LEAPP_USE_NET_NAMING_SCHEME=1 will ignore
|
||||
the value of LEAPP_USE_NET_NAMING_SCHEME.
|
||||
|
||||
Add a possibility to use the net.naming-scheme cmdline argument
|
||||
to make immutable network interface names during the upgrade.
|
||||
The feature can be used only for 8>9 upgrades and higher.
|
||||
To enable the feature, use LEAPP_USE_NET_NAMING_SCHEME=1.
|
||||
|
||||
Jira-ref: RHEL-23473
|
||||
---
|
||||
.../actors/addupgradebootentry/actor.py | 10 +-
|
||||
.../libraries/addupgradebootentry.py | 78 ++++++++++-----
|
||||
.../tests/unit_test_addupgradebootentry.py | 47 ++++-----
|
||||
.../actors/kernelcmdlineconfig/actor.py | 16 +++-
|
||||
.../libraries/kernelcmdlineconfig.py | 12 ++-
|
||||
.../libraries/persistentnetnamesconfig.py | 5 +-
|
||||
.../common/models/kernelcmdlineargs.py | 21 ++++
|
||||
.../actors/emit_net_naming_scheme/actor.py | 28 ++++++
|
||||
.../libraries/emit_net_naming.py | 63 ++++++++++++
|
||||
.../tests/test_emit_net_naming_scheme.py | 95 +++++++++++++++++++
|
||||
10 files changed, 318 insertions(+), 57 deletions(-)
|
||||
create mode 100644 repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/actor.py
|
||||
create mode 100644 repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
create mode 100644 repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/addupgradebootentry/actor.py b/repos/system_upgrade/common/actors/addupgradebootentry/actor.py
|
||||
index f400ebf8..e4ecf39e 100644
|
||||
--- a/repos/system_upgrade/common/actors/addupgradebootentry/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/addupgradebootentry/actor.py
|
||||
@@ -8,11 +8,13 @@ from leapp.models import (
|
||||
FirmwareFacts,
|
||||
GrubConfigError,
|
||||
KernelCmdline,
|
||||
+ LateTargetKernelCmdlineArgTasks,
|
||||
LiveImagePreparationInfo,
|
||||
LiveModeArtifacts,
|
||||
LiveModeConfig,
|
||||
TargetKernelCmdlineArgTasks,
|
||||
- TransactionDryRun
|
||||
+ TransactionDryRun,
|
||||
+ UpgradeKernelCmdlineArgTasks
|
||||
)
|
||||
from leapp.tags import InterimPreparationPhaseTag, IPUWorkflowTag
|
||||
|
||||
@@ -33,9 +35,11 @@ class AddUpgradeBootEntry(Actor):
|
||||
LiveModeArtifacts,
|
||||
LiveModeConfig,
|
||||
KernelCmdline,
|
||||
- TransactionDryRun
|
||||
+ TransactionDryRun,
|
||||
+ TargetKernelCmdlineArgTasks,
|
||||
+ UpgradeKernelCmdlineArgTasks
|
||||
)
|
||||
- produces = (TargetKernelCmdlineArgTasks,)
|
||||
+ produces = (LateTargetKernelCmdlineArgTasks,)
|
||||
tags = (IPUWorkflowTag, InterimPreparationPhaseTag)
|
||||
|
||||
def process(self):
|
||||
diff --git a/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py b/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py
|
||||
index 553ffc35..b236e39b 100644
|
||||
--- a/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py
|
||||
+++ b/repos/system_upgrade/common/actors/addupgradebootentry/libraries/addupgradebootentry.py
|
||||
@@ -9,14 +9,16 @@ from leapp.models import (
|
||||
BootContent,
|
||||
KernelCmdline,
|
||||
KernelCmdlineArg,
|
||||
+ LateTargetKernelCmdlineArgTasks,
|
||||
LiveImagePreparationInfo,
|
||||
LiveModeArtifacts,
|
||||
LiveModeConfig,
|
||||
- TargetKernelCmdlineArgTasks
|
||||
+ TargetKernelCmdlineArgTasks,
|
||||
+ UpgradeKernelCmdlineArgTasks
|
||||
)
|
||||
|
||||
|
||||
-def collect_boot_args(livemode_enabled):
|
||||
+def collect_upgrade_kernel_args(livemode_enabled):
|
||||
args = {
|
||||
'enforcing': '0',
|
||||
'rd.plymouth': '0',
|
||||
@@ -34,7 +36,10 @@ def collect_boot_args(livemode_enabled):
|
||||
livemode_args = construct_cmdline_args_for_livemode()
|
||||
args.update(livemode_args)
|
||||
|
||||
- return args
|
||||
+ upgrade_kernel_args = collect_set_of_kernel_args_from_msgs(UpgradeKernelCmdlineArgTasks, 'to_add')
|
||||
+ args.update(upgrade_kernel_args)
|
||||
+
|
||||
+ return set(args.items())
|
||||
|
||||
|
||||
def collect_undesired_args(livemode_enabled):
|
||||
@@ -43,11 +48,11 @@ def collect_undesired_args(livemode_enabled):
|
||||
args = dict(zip(('ro', 'rhgb', 'quiet'), itertools.repeat(None)))
|
||||
args['rd.lvm.lv'] = _get_rdlvm_arg_values()
|
||||
|
||||
- return args
|
||||
+ return set(args.items())
|
||||
|
||||
|
||||
-def format_grubby_args_from_args_dict(args_dict):
|
||||
- """ Format the given args dictionary in a form required by grubby's --args. """
|
||||
+def format_grubby_args_from_args_set(args_dict):
|
||||
+ """ Format the given args set in a form required by grubby's --args. """
|
||||
|
||||
def fmt_single_arg(arg_pair):
|
||||
key, value = arg_pair
|
||||
@@ -65,7 +70,7 @@ def format_grubby_args_from_args_dict(args_dict):
|
||||
else:
|
||||
yield (key, value) # Just a single (key, value) pair
|
||||
|
||||
- arg_sequence = itertools.chain(*(flatten_arguments(arg_pair) for arg_pair in args_dict.items()))
|
||||
+ arg_sequence = itertools.chain(*(flatten_arguments(arg_pair) for arg_pair in args_dict))
|
||||
|
||||
# Sorting should be fine as only values can be None, but we cannot have a (key, None) and (key, value) in
|
||||
# the dictionary at the same time.
|
||||
@@ -78,7 +83,7 @@ def format_grubby_args_from_args_dict(args_dict):
|
||||
def figure_out_commands_needed_to_add_entry(kernel_path, initramfs_path, args_to_add, args_to_remove):
|
||||
boot_entry_modification_commands = []
|
||||
|
||||
- args_to_add_str = format_grubby_args_from_args_dict(args_to_add)
|
||||
+ args_to_add_str = format_grubby_args_from_args_set(args_to_add)
|
||||
|
||||
create_entry_cmd = [
|
||||
'/usr/sbin/grubby',
|
||||
@@ -93,7 +98,7 @@ def figure_out_commands_needed_to_add_entry(kernel_path, initramfs_path, args_to
|
||||
|
||||
# We need to update root= param separately, since we cannot do it during --add-kernel with --copy-default.
|
||||
# This is likely a bug in grubby.
|
||||
- root_param_value = args_to_add.get('root', None)
|
||||
+ root_param_value = dict(args_to_add).get('root', None)
|
||||
if root_param_value:
|
||||
enforce_root_param_for_the_entry_cmd = [
|
||||
'/usr/sbin/grubby',
|
||||
@@ -103,7 +108,7 @@ def figure_out_commands_needed_to_add_entry(kernel_path, initramfs_path, args_to
|
||||
boot_entry_modification_commands.append(enforce_root_param_for_the_entry_cmd)
|
||||
|
||||
if args_to_remove:
|
||||
- args_to_remove_str = format_grubby_args_from_args_dict(args_to_remove)
|
||||
+ args_to_remove_str = format_grubby_args_from_args_set(args_to_remove)
|
||||
remove_undesired_args_cmd = [
|
||||
'/usr/sbin/grubby',
|
||||
'--update-kernel', kernel_path,
|
||||
@@ -113,18 +118,55 @@ def figure_out_commands_needed_to_add_entry(kernel_path, initramfs_path, args_to
|
||||
return boot_entry_modification_commands
|
||||
|
||||
|
||||
+def collect_set_of_kernel_args_from_msgs(msg_type, arg_list_field_name):
|
||||
+ cmdline_modification_msgs = api.consume(msg_type)
|
||||
+ lists_of_args_to_add = (getattr(msg, arg_list_field_name, []) for msg in cmdline_modification_msgs)
|
||||
+ args = itertools.chain(*lists_of_args_to_add)
|
||||
+ return set((arg.key, arg.value) for arg in args)
|
||||
+
|
||||
+
|
||||
+def emit_removal_of_args_meant_only_for_upgrade_kernel(added_upgrade_kernel_args):
|
||||
+ """
|
||||
+ Emit message requesting removal of upgrade kernel args that should not be on the target kernel.
|
||||
+
|
||||
+ Target kernel args are created by copying the args of the booted (upgrade) kernel. Therefore,
|
||||
+ we need to explicitly modify the target kernel cmdline, removing what should not have been copied.
|
||||
+ """
|
||||
+ target_args_to_add = collect_set_of_kernel_args_from_msgs(TargetKernelCmdlineArgTasks, 'to_add')
|
||||
+ actual_kernel_args = collect_set_of_kernel_args_from_msgs(KernelCmdline, 'parameters')
|
||||
+
|
||||
+ # actual_kernel_args should not be changed during upgrade, unless explicitly removed by
|
||||
+ # TargetKernelCmdlineArgTasks.to_remove, but that is handled by some other upgrade component. We just want
|
||||
+ # to make sure we remove what was not on the source system and that we don't overwrite args to be added to target.
|
||||
+ args_not_present_on_target_kernel = added_upgrade_kernel_args - actual_kernel_args - target_args_to_add
|
||||
+
|
||||
+ # We remove only what we've added and what will not be already removed by someone else.
|
||||
+ args_to_remove = [KernelCmdlineArg(key=arg[0], value=arg[1]) for arg in args_not_present_on_target_kernel]
|
||||
+
|
||||
+ if args_to_remove:
|
||||
+ msg = ('Following upgrade kernel args were added, but they should not be present '
|
||||
+ 'on target cmdline: `%s`, requesting removal.')
|
||||
+ api.current_logger().info(msg, args_not_present_on_target_kernel)
|
||||
+ args_sorted = sorted(args_to_remove, key=lambda arg: arg.key)
|
||||
+ api.produce(LateTargetKernelCmdlineArgTasks(to_remove=args_sorted))
|
||||
+
|
||||
+
|
||||
def add_boot_entry(configs=None):
|
||||
kernel_dst_path, initram_dst_path = get_boot_file_paths()
|
||||
+
|
||||
_remove_old_upgrade_boot_entry(kernel_dst_path, configs=configs)
|
||||
|
||||
livemode_enabled = next(api.consume(LiveImagePreparationInfo), None) is not None
|
||||
|
||||
- cmdline_args = collect_boot_args(livemode_enabled)
|
||||
+ # We have to keep the desired and unwanted args separate and modify cmline in two separate grubby calls. Merging
|
||||
+ # these sets and trying to execute only a single command would leave the unwanted cmdline args present if they
|
||||
+ # are present on the original system.
|
||||
+ added_cmdline_args = collect_upgrade_kernel_args(livemode_enabled)
|
||||
undesired_cmdline_args = collect_undesired_args(livemode_enabled)
|
||||
|
||||
commands_to_run = figure_out_commands_needed_to_add_entry(kernel_dst_path,
|
||||
initram_dst_path,
|
||||
- args_to_add=cmdline_args,
|
||||
+ args_to_add=added_cmdline_args,
|
||||
args_to_remove=undesired_cmdline_args)
|
||||
|
||||
def run_commands_adding_entry(extra_command_suffix=None):
|
||||
@@ -146,16 +188,8 @@ def add_boot_entry(configs=None):
|
||||
# See https://bugzilla.redhat.com/show_bug.cgi?id=1764306
|
||||
run(['/usr/sbin/zipl'])
|
||||
|
||||
- if 'debug' in cmdline_args:
|
||||
- # The kernelopts for target kernel are generated based on the cmdline used in the upgrade initramfs,
|
||||
- # therefore, if we enabled debug above, and the original system did not have the debug kernelopt, we
|
||||
- # need to explicitly remove it from the target os boot entry.
|
||||
- # NOTE(mhecko): This will also unconditionally remove debug kernelopt if the source system used it.
|
||||
- api.produce(TargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='debug')]))
|
||||
-
|
||||
- # NOTE(mmatuska): This will remove the option even if the source system had it set.
|
||||
- # However enforcing=0 shouldn't be set persistently anyway.
|
||||
- api.produce(TargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='enforcing', value='0')]))
|
||||
+ effective_upgrade_kernel_args = added_cmdline_args - undesired_cmdline_args
|
||||
+ emit_removal_of_args_meant_only_for_upgrade_kernel(effective_upgrade_kernel_args)
|
||||
|
||||
except CalledProcessError as e:
|
||||
raise StopActorExecutionError(
|
||||
diff --git a/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py b/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py
|
||||
index c4f5232b..2f58ba9e 100644
|
||||
--- a/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py
|
||||
+++ b/repos/system_upgrade/common/actors/addupgradebootentry/tests/unit_test_addupgradebootentry.py
|
||||
@@ -12,6 +12,7 @@ from leapp.models import (
|
||||
BootContent,
|
||||
KernelCmdline,
|
||||
KernelCmdlineArg,
|
||||
+ LateTargetKernelCmdlineArgTasks,
|
||||
LiveModeArtifacts,
|
||||
LiveModeConfig,
|
||||
TargetKernelCmdlineArgTasks
|
||||
@@ -82,8 +83,10 @@ def test_add_boot_entry(monkeypatch, run_args, arch):
|
||||
assert addupgradebootentry.run.args[0] == run_args.args_remove
|
||||
assert addupgradebootentry.run.args[1] == run_args.args_add
|
||||
assert api.produce.model_instances == [
|
||||
- TargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='debug')]),
|
||||
- TargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='enforcing', value='0')])
|
||||
+ LateTargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='debug'),
|
||||
+ KernelCmdlineArg(key='enforcing', value='0'),
|
||||
+ KernelCmdlineArg(key='plymouth.enable', value='0'),
|
||||
+ KernelCmdlineArg(key='rd.plymouth', value='0')])
|
||||
]
|
||||
|
||||
if run_args.args_zipl:
|
||||
@@ -103,16 +106,16 @@ def test_debug_kernelopt_removal_task_production(monkeypatch, is_leapp_invoked_w
|
||||
CurrentActorMocked(envars={'LEAPP_DEBUG': str(int(is_leapp_invoked_with_debug))}))
|
||||
|
||||
addupgradebootentry.add_boot_entry()
|
||||
+ assert len(api.produce.model_instances) == 1
|
||||
|
||||
- expected_produced_messages = []
|
||||
- if is_leapp_invoked_with_debug:
|
||||
- expected_produced_messages = [TargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='debug')])]
|
||||
-
|
||||
- expected_produced_messages.append(
|
||||
- TargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='enforcing', value='0')])
|
||||
- )
|
||||
+ produced_msg = api.produce.model_instances[0]
|
||||
+ assert isinstance(produced_msg, LateTargetKernelCmdlineArgTasks)
|
||||
|
||||
- assert api.produce.model_instances == expected_produced_messages
|
||||
+ debug_kernel_cmline_arg = KernelCmdlineArg(key='debug')
|
||||
+ if is_leapp_invoked_with_debug:
|
||||
+ assert debug_kernel_cmline_arg in produced_msg.to_remove
|
||||
+ else:
|
||||
+ assert debug_kernel_cmline_arg not in produced_msg.to_remove
|
||||
|
||||
|
||||
def test_add_boot_entry_configs(monkeypatch):
|
||||
@@ -132,8 +135,10 @@ def test_add_boot_entry_configs(monkeypatch):
|
||||
assert addupgradebootentry.run.args[2] == run_args_add + ['-c', CONFIGS[0]]
|
||||
assert addupgradebootentry.run.args[3] == run_args_add + ['-c', CONFIGS[1]]
|
||||
assert api.produce.model_instances == [
|
||||
- TargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='debug')]),
|
||||
- TargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='enforcing', value='0')]),
|
||||
+ LateTargetKernelCmdlineArgTasks(to_remove=[KernelCmdlineArg(key='debug'),
|
||||
+ KernelCmdlineArg(key='enforcing', value='0'),
|
||||
+ KernelCmdlineArg(key='plymouth.enable', value='0'),
|
||||
+ KernelCmdlineArg(key='rd.plymouth', value='0')])
|
||||
]
|
||||
|
||||
|
||||
@@ -183,7 +188,7 @@ def test_fix_grub_config_error(monkeypatch, error_type, test_file_name):
|
||||
(False, False),
|
||||
)
|
||||
)
|
||||
-def test_collect_boot_args(monkeypatch, is_debug_enabled, network_enablement_type):
|
||||
+def test_collect_upgrade_kernel_args(monkeypatch, is_debug_enabled, network_enablement_type):
|
||||
env_vars = {'LEAPP_DEBUG': str(int(is_debug_enabled))}
|
||||
if network_enablement_type:
|
||||
env_vars['LEAPP_DEVEL_INITRAM_NETWORK'] = network_enablement_type
|
||||
@@ -192,7 +197,8 @@ def test_collect_boot_args(monkeypatch, is_debug_enabled, network_enablement_typ
|
||||
monkeypatch.setattr(addupgradebootentry, 'construct_cmdline_args_for_livemode',
|
||||
lambda *args: {'livemodearg': 'value'})
|
||||
|
||||
- args = addupgradebootentry.collect_boot_args(livemode_enabled=True)
|
||||
+ arg_set = addupgradebootentry.collect_upgrade_kernel_args(livemode_enabled=True)
|
||||
+ args = dict(arg_set)
|
||||
|
||||
assert args['enforcing'] == '0'
|
||||
assert args['rd.plymouth'] == '0'
|
||||
@@ -320,16 +326,3 @@ def test_get_device_uuid(monkeypatch):
|
||||
uuid = addupgradebootentry._get_device_uuid(path)
|
||||
|
||||
assert uuid == 'MY_UUID1'
|
||||
-
|
||||
-
|
||||
-@pytest.mark.parametrize(
|
||||
- ('args', 'expected_result'),
|
||||
- (
|
||||
- ([('argA', 'val'), ('argB', 'valB'), ('argC', None), ], 'argA=val argB=valB argC'),
|
||||
- ([('argA', ('val1', 'val2'))], 'argA=val1 argA=val2')
|
||||
- )
|
||||
-)
|
||||
-def test_format_grubby_args_from_args_dict(args, expected_result):
|
||||
- actual_result = addupgradebootentry.format_grubby_args_from_args_dict(dict(args))
|
||||
-
|
||||
- assert actual_result == expected_result
|
||||
diff --git a/repos/system_upgrade/common/actors/kernelcmdlineconfig/actor.py b/repos/system_upgrade/common/actors/kernelcmdlineconfig/actor.py
|
||||
index 3585a14e..6d5f39dd 100644
|
||||
--- a/repos/system_upgrade/common/actors/kernelcmdlineconfig/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/kernelcmdlineconfig/actor.py
|
||||
@@ -3,7 +3,13 @@ import os
|
||||
from leapp.actors import Actor
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries.actor import kernelcmdlineconfig
|
||||
-from leapp.models import FirmwareFacts, InstalledTargetKernelInfo, KernelCmdlineArg, TargetKernelCmdlineArgTasks
|
||||
+from leapp.models import (
|
||||
+ FirmwareFacts,
|
||||
+ InstalledTargetKernelInfo,
|
||||
+ KernelCmdlineArg,
|
||||
+ LateTargetKernelCmdlineArgTasks,
|
||||
+ TargetKernelCmdlineArgTasks
|
||||
+)
|
||||
from leapp.reporting import Report
|
||||
from leapp.tags import FinalizationPhaseTag, IPUWorkflowTag
|
||||
|
||||
@@ -14,7 +20,13 @@ class KernelCmdlineConfig(Actor):
|
||||
"""
|
||||
|
||||
name = 'kernelcmdlineconfig'
|
||||
- consumes = (KernelCmdlineArg, InstalledTargetKernelInfo, FirmwareFacts, TargetKernelCmdlineArgTasks)
|
||||
+ consumes = (
|
||||
+ KernelCmdlineArg,
|
||||
+ InstalledTargetKernelInfo,
|
||||
+ FirmwareFacts,
|
||||
+ LateTargetKernelCmdlineArgTasks,
|
||||
+ TargetKernelCmdlineArgTasks
|
||||
+ )
|
||||
produces = (Report,)
|
||||
tags = (FinalizationPhaseTag, IPUWorkflowTag)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py b/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py
|
||||
index 19c50f3c..98b8b95b 100644
|
||||
--- a/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/kernelcmdlineconfig/libraries/kernelcmdlineconfig.py
|
||||
@@ -1,3 +1,4 @@
|
||||
+import itertools
|
||||
import re
|
||||
|
||||
from leapp import reporting
|
||||
@@ -5,7 +6,12 @@ from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries import stdlib
|
||||
from leapp.libraries.common.config import architecture, version
|
||||
from leapp.libraries.stdlib import api
|
||||
-from leapp.models import InstalledTargetKernelInfo, KernelCmdlineArg, TargetKernelCmdlineArgTasks
|
||||
+from leapp.models import (
|
||||
+ InstalledTargetKernelInfo,
|
||||
+ KernelCmdlineArg,
|
||||
+ LateTargetKernelCmdlineArgTasks,
|
||||
+ TargetKernelCmdlineArgTasks
|
||||
+)
|
||||
|
||||
KERNEL_CMDLINE_FILE = "/etc/kernel/cmdline"
|
||||
|
||||
@@ -71,7 +77,9 @@ def retrieve_arguments_to_modify():
|
||||
kernelargs_msgs_to_add = list(api.consume(KernelCmdlineArg))
|
||||
kernelargs_msgs_to_remove = []
|
||||
|
||||
- for target_kernel_arg_task in api.consume(TargetKernelCmdlineArgTasks):
|
||||
+ modification_msgs = itertools.chain(api.consume(TargetKernelCmdlineArgTasks),
|
||||
+ api.consume(LateTargetKernelCmdlineArgTasks))
|
||||
+ for target_kernel_arg_task in modification_msgs:
|
||||
kernelargs_msgs_to_add.extend(target_kernel_arg_task.to_add)
|
||||
kernelargs_msgs_to_remove.extend(target_kernel_arg_task.to_remove)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py b/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
index dc5196ea..2f12742a 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
@@ -2,7 +2,7 @@ import errno
|
||||
import os
|
||||
import re
|
||||
|
||||
-from leapp.libraries.common.config import get_env
|
||||
+from leapp.libraries.common.config import get_env, version
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import (
|
||||
InitrdIncludes,
|
||||
@@ -39,6 +39,9 @@ def generate_link_file(interface):
|
||||
|
||||
@suppress_deprecation(InitrdIncludes)
|
||||
def process():
|
||||
+ if get_env('LEAPP_USE_NET_NAMING_SCHEMES', '0') == '1' and version.get_target_major_version() != '8':
|
||||
+ api.current_logger().info('Skipping generation of .link files renaming NICs as LEAPP_USE_NET_NAMING_SCHEMES=1')
|
||||
+ return
|
||||
|
||||
if get_env('LEAPP_NO_NETWORK_RENAMING', '0') == '1':
|
||||
api.current_logger().info(
|
||||
diff --git a/repos/system_upgrade/common/models/kernelcmdlineargs.py b/repos/system_upgrade/common/models/kernelcmdlineargs.py
|
||||
index e3568a0a..fafd2853 100644
|
||||
--- a/repos/system_upgrade/common/models/kernelcmdlineargs.py
|
||||
+++ b/repos/system_upgrade/common/models/kernelcmdlineargs.py
|
||||
@@ -24,6 +24,27 @@ class TargetKernelCmdlineArgTasks(Model):
|
||||
to_remove = fields.List(fields.Model(KernelCmdlineArg), default=[])
|
||||
|
||||
|
||||
+class LateTargetKernelCmdlineArgTasks(Model):
|
||||
+ """
|
||||
+ Desired modifications of the target kernel args produced later in the upgrade process.
|
||||
+
|
||||
+ Defined to prevent loops in the actor dependency graph.
|
||||
+ """
|
||||
+ topic = SystemInfoTopic
|
||||
+
|
||||
+ to_add = fields.List(fields.Model(KernelCmdlineArg), default=[])
|
||||
+ to_remove = fields.List(fields.Model(KernelCmdlineArg), default=[])
|
||||
+
|
||||
+
|
||||
+class UpgradeKernelCmdlineArgTasks(Model):
|
||||
+ """
|
||||
+ Modifications of the upgrade kernel cmdline.
|
||||
+ """
|
||||
+ topic = SystemInfoTopic
|
||||
+
|
||||
+ to_add = fields.List(fields.Model(KernelCmdlineArg), default=[])
|
||||
+
|
||||
+
|
||||
class KernelCmdline(Model):
|
||||
"""
|
||||
Kernel command line parameters the system was booted with
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/actor.py b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..769fe20b
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/actor.py
|
||||
@@ -0,0 +1,28 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.libraries.actor import emit_net_naming as emit_net_naming_lib
|
||||
+from leapp.models import (
|
||||
+ KernelCmdline,
|
||||
+ RpmTransactionTasks,
|
||||
+ TargetKernelCmdlineArgTasks,
|
||||
+ TargetUserSpaceUpgradeTasks,
|
||||
+ UpgradeKernelCmdlineArgTasks
|
||||
+)
|
||||
+from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
+
|
||||
+
|
||||
+class EmitNetNamingScheme(Actor):
|
||||
+ """
|
||||
+ Emit necessary modifications of the upgrade environment and target command line to use net.naming-scheme.
|
||||
+ """
|
||||
+ name = 'emit_net_naming_scheme'
|
||||
+ consumes = (KernelCmdline,)
|
||||
+ produces = (
|
||||
+ RpmTransactionTasks,
|
||||
+ TargetKernelCmdlineArgTasks,
|
||||
+ TargetUserSpaceUpgradeTasks,
|
||||
+ UpgradeKernelCmdlineArgTasks,
|
||||
+ )
|
||||
+ tags = (ChecksPhaseTag, IPUWorkflowTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ emit_net_naming_lib.emit_msgs_to_use_net_naming_schemes()
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
new file mode 100644
|
||||
index 00000000..65abdd4d
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
@@ -0,0 +1,63 @@
|
||||
+from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.common.config import get_env, version
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import (
|
||||
+ KernelCmdline,
|
||||
+ KernelCmdlineArg,
|
||||
+ RpmTransactionTasks,
|
||||
+ TargetKernelCmdlineArgTasks,
|
||||
+ TargetUserSpaceUpgradeTasks,
|
||||
+ UpgradeKernelCmdlineArgTasks
|
||||
+)
|
||||
+
|
||||
+NET_NAMING_SYSATTRS_RPM_NAME = 'rhel-net-naming-sysattrs'
|
||||
+
|
||||
+
|
||||
+def is_net_scheme_compatible_with_current_cmdline():
|
||||
+ kernel_cmdline = next(api.consume(KernelCmdline), None)
|
||||
+ if not kernel_cmdline:
|
||||
+ # Super unlikely
|
||||
+ raise StopActorExecutionError('Did not receive any KernelCmdline messages.')
|
||||
+
|
||||
+ allows_predictable_names = True
|
||||
+ already_has_a_net_naming_scheme = False
|
||||
+ for param in kernel_cmdline.parameters:
|
||||
+ if param.key == 'net.ifnames':
|
||||
+ if param.value == '0':
|
||||
+ allows_predictable_names = False
|
||||
+ elif param.value == '1':
|
||||
+ allows_predictable_names = True
|
||||
+ if param.key == 'net.naming-scheme':
|
||||
+ # We assume that the kernel cmdline does not contain invalid entries, namely,
|
||||
+ # that the net.naming-scheme refers to a valid scheme.
|
||||
+ already_has_a_net_naming_scheme = True
|
||||
+
|
||||
+ is_compatible = allows_predictable_names and not already_has_a_net_naming_scheme
|
||||
+
|
||||
+ msg = ('Should net.naming-scheme be added to kernel cmdline: %s. '
|
||||
+ 'Reason: allows_predictable_names=%s, already_has_a_net_naming_scheme=%s')
|
||||
+ api.current_logger().info(msg, 'yes' if is_compatible else 'no',
|
||||
+ allows_predictable_names,
|
||||
+ already_has_a_net_naming_scheme)
|
||||
+
|
||||
+ return is_compatible
|
||||
+
|
||||
+
|
||||
+def emit_msgs_to_use_net_naming_schemes():
|
||||
+ if get_env('LEAPP_USE_NET_NAMING_SCHEMES', '0') != '1' and version.get_target_major_version() != '8':
|
||||
+ return
|
||||
+
|
||||
+ # The package should be installed regardless of whether we will modify the cmdline -
|
||||
+ # if the cmdline already contains net.naming-scheme, then the package will be useful
|
||||
+ # in both, the upgrade environment and on the target system.
|
||||
+ pkgs_to_install = [NET_NAMING_SYSATTRS_RPM_NAME]
|
||||
+ api.produce(TargetUserSpaceUpgradeTasks(install_rpms=pkgs_to_install))
|
||||
+ api.produce(RpmTransactionTasks(to_install=pkgs_to_install))
|
||||
+
|
||||
+ if not is_net_scheme_compatible_with_current_cmdline():
|
||||
+ return
|
||||
+
|
||||
+ naming_scheme = 'rhel-{0}.0'.format(version.get_source_major_version())
|
||||
+ cmdline_args = [KernelCmdlineArg(key='net.naming-scheme', value=naming_scheme)]
|
||||
+ api.produce(UpgradeKernelCmdlineArgTasks(to_add=cmdline_args))
|
||||
+ api.produce(TargetKernelCmdlineArgTasks(to_add=cmdline_args))
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py
|
||||
new file mode 100644
|
||||
index 00000000..7a5eeba5
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py
|
||||
@@ -0,0 +1,95 @@
|
||||
+import pytest
|
||||
+
|
||||
+from leapp.libraries.actor import emit_net_naming as emit_net_naming_lib
|
||||
+from leapp.libraries.common.testutils import CurrentActorMocked, produce_mocked
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import (
|
||||
+ KernelCmdline,
|
||||
+ KernelCmdlineArg,
|
||||
+ RpmTransactionTasks,
|
||||
+ TargetKernelCmdlineArgTasks,
|
||||
+ TargetUserSpaceUpgradeTasks,
|
||||
+ UpgradeKernelCmdlineArgTasks
|
||||
+)
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(
|
||||
+ ('kernel_args', 'should_be_compatible'),
|
||||
+ [
|
||||
+ ([KernelCmdlineArg(key='net.naming-scheme', value='rhel-8.10')], False),
|
||||
+ ([KernelCmdlineArg(key='net.ifnames', value='1')], True),
|
||||
+ ([KernelCmdlineArg(key='net.ifnames', value='0')], False),
|
||||
+ (
|
||||
+ [
|
||||
+ KernelCmdlineArg(key='net.naming-scheme', value='rhel-8.10'),
|
||||
+ KernelCmdlineArg(key='net.ifname', value='0'),
|
||||
+ KernelCmdlineArg(key='root', value='/dev/vda1')
|
||||
+ ],
|
||||
+ False
|
||||
+ ),
|
||||
+ ([KernelCmdlineArg(key='root', value='/dev/vda1')], True),
|
||||
+ ]
|
||||
+)
|
||||
+def test_is_net_scheme_compatible_with_current_cmdline(monkeypatch, kernel_args, should_be_compatible):
|
||||
+ kernel_cmdline = KernelCmdline(parameters=kernel_args)
|
||||
+
|
||||
+ def mocked_consume(msg_type):
|
||||
+ yield {KernelCmdline: kernel_cmdline}[msg_type]
|
||||
+
|
||||
+ monkeypatch.setattr(api, 'consume', mocked_consume)
|
||||
+
|
||||
+ assert emit_net_naming_lib.is_net_scheme_compatible_with_current_cmdline() == should_be_compatible, \
|
||||
+ [(arg.key, arg.value) for arg in kernel_cmdline.parameters]
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(
|
||||
+ ('is_net_scheme_enabled', 'is_current_cmdline_compatible'),
|
||||
+ [
|
||||
+ (True, True),
|
||||
+ (True, False),
|
||||
+ (False, True)
|
||||
+ ]
|
||||
+)
|
||||
+def test_emit_msgs_to_use_net_naming_schemes(monkeypatch, is_net_scheme_enabled, is_current_cmdline_compatible):
|
||||
+ envvar_value = '1' if is_net_scheme_enabled else '0'
|
||||
+
|
||||
+ mocked_actor = CurrentActorMocked(src_ver='8.10',
|
||||
+ dst_ver='9.5',
|
||||
+ envars={'LEAPP_USE_NET_NAMING_SCHEMES': envvar_value})
|
||||
+ monkeypatch.setattr(api, 'current_actor', mocked_actor)
|
||||
+
|
||||
+ monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
+ monkeypatch.setattr(emit_net_naming_lib,
|
||||
+ 'is_net_scheme_compatible_with_current_cmdline',
|
||||
+ lambda: is_current_cmdline_compatible)
|
||||
+
|
||||
+ emit_net_naming_lib.emit_msgs_to_use_net_naming_schemes()
|
||||
+
|
||||
+ def ensure_one_msg_of_type_produced(produced_messages, msg_type):
|
||||
+ msgs = (msg for msg in produced_messages if isinstance(msg, msg_type))
|
||||
+ msg = next(msgs)
|
||||
+ assert not next(msgs, None), 'More than one message of type {type} produced'.format(type=type)
|
||||
+ return msg
|
||||
+
|
||||
+ produced_messages = api.produce.model_instances
|
||||
+ if is_net_scheme_enabled:
|
||||
+ userspace_tasks = ensure_one_msg_of_type_produced(produced_messages, TargetUserSpaceUpgradeTasks)
|
||||
+ assert userspace_tasks.install_rpms == [emit_net_naming_lib.NET_NAMING_SYSATTRS_RPM_NAME]
|
||||
+
|
||||
+ rpm_tasks = ensure_one_msg_of_type_produced(produced_messages, RpmTransactionTasks)
|
||||
+ assert rpm_tasks.to_install == [emit_net_naming_lib.NET_NAMING_SYSATTRS_RPM_NAME]
|
||||
+ else:
|
||||
+ assert not api.produce.called
|
||||
+ return
|
||||
+
|
||||
+ upgrade_cmdline_mods = (msg for msg in produced_messages if isinstance(msg, UpgradeKernelCmdlineArgTasks))
|
||||
+ target_cmdline_mods = (msg for msg in produced_messages if isinstance(msg, TargetKernelCmdlineArgTasks))
|
||||
+
|
||||
+ if is_current_cmdline_compatible:
|
||||
+ # We should emit cmdline modifications - both UpgradeKernelCmdlineArgTasks and TargetKernelCmdlineArgTasks
|
||||
+ # should be produced
|
||||
+ assert next(upgrade_cmdline_mods, None)
|
||||
+ assert next(target_cmdline_mods, None)
|
||||
+ else:
|
||||
+ assert not next(upgrade_cmdline_mods, None)
|
||||
+ assert not next(target_cmdline_mods, None)
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
From b4b535454b74c05682ecf0d3059decbd2c9530e0 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Wed, 6 Nov 2024 22:23:37 +0100
|
||||
Subject: [PATCH 24/40] prevent the feature for being used outside 8>9
|
||||
|
||||
---
|
||||
.../libraries/persistentnetnamesconfig.py | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py b/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
index 2f12742a..b2c7f5ff 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
@@ -39,7 +39,8 @@ def generate_link_file(interface):
|
||||
|
||||
@suppress_deprecation(InitrdIncludes)
|
||||
def process():
|
||||
- if get_env('LEAPP_USE_NET_NAMING_SCHEMES', '0') == '1' and version.get_target_major_version() != '8':
|
||||
+ if get_env('LEAPP_USE_NET_NAMING_SCHEMES', '0') == '1' and version.get_target_major_version() == '9':
|
||||
+ # We can use this only for 8>9, for now
|
||||
api.current_logger().info('Skipping generation of .link files renaming NICs as LEAPP_USE_NET_NAMING_SCHEMES=1')
|
||||
return
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,126 +0,0 @@
|
||||
From 73b2a3f76e6f808c381a29253ef7e1cd5bfd4f69 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 18:11:43 +0100
|
||||
Subject: [PATCH 24/44] targetuserspacecreator: Respect distro name in report
|
||||
|
||||
Also add stable report key for no base repos inhibitor. The key was
|
||||
computed with 'Cannot find required basic RHEL target repositories.' as
|
||||
the title.
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../libraries/userspacegen.py | 34 ++++++++++---------
|
||||
.../tests/unit_test_targetuserspacecreator.py | 10 +++---
|
||||
2 files changed, 23 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
index 7dbadae2..2475aad4 100644
|
||||
--- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
+++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
@@ -844,9 +844,8 @@ def _inhibit_if_no_base_repos(distro_repoids):
|
||||
no_baseos = all("baseos" not in ri for ri in distro_repoids)
|
||||
no_appstream = all("appstream" not in ri for ri in distro_repoids)
|
||||
if no_baseos or no_appstream:
|
||||
- reporting.create_report([
|
||||
- # TODO: Make the report distro agnostic
|
||||
- reporting.Title('Cannot find required basic RHEL target repositories.'),
|
||||
+ report = [
|
||||
+ reporting.Title('Cannot find required basic target OS repositories.'),
|
||||
reporting.Summary(
|
||||
'This can happen when a repository ID was entered incorrectly either while using the --enablerepo'
|
||||
' option of leapp or in a third party actor that produces a CustomTargetRepositoryMessage.'
|
||||
@@ -854,17 +853,6 @@ def _inhibit_if_no_base_repos(distro_repoids):
|
||||
reporting.Groups([reporting.Groups.REPOSITORY]),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
- reporting.Remediation(hint=(
|
||||
- 'It is required to have RHEL repositories on the system'
|
||||
- ' provided by the subscription-manager unless the --no-rhsm'
|
||||
- ' option is specified. You might be missing a valid SKU for'
|
||||
- ' the target system or have a failed network connection.'
|
||||
- ' Check whether your system is attached to a valid SKU that is'
|
||||
- ' providing RHEL {} repositories.'
|
||||
- ' If you are using Red Hat Satellite, read the upgrade documentation'
|
||||
- ' to set up Satellite and the system properly.'
|
||||
-
|
||||
- ).format(target_major_version)),
|
||||
reporting.ExternalLink(
|
||||
url='https://access.redhat.com/solutions/5392811',
|
||||
title='RHEL 7 to RHEL 8 LEAPP Upgrade Failing When Using Red Hat Satellite'
|
||||
@@ -874,8 +862,22 @@ def _inhibit_if_no_base_repos(distro_repoids):
|
||||
# https://red.ht/preparing-for-upgrade-to-rhel9
|
||||
# https://red.ht/preparing-for-upgrade-to-rhel10
|
||||
url='https://red.ht/preparing-for-upgrade-to-rhel{}'.format(target_major_version),
|
||||
- title='Preparing for the upgrade')
|
||||
- ])
|
||||
+ title='Preparing for the upgrade'),
|
||||
+ reporting.Key('f5770a56e540f27d370da7b697cb4a2e81e2c30d'),
|
||||
+ ]
|
||||
+ if get_target_distro_id() == 'rhel':
|
||||
+ report.append(reporting.Remediation(hint=(
|
||||
+ 'It is required to have RHEL repositories on the system'
|
||||
+ ' provided by the subscription-manager unless the --no-rhsm'
|
||||
+ ' option is specified. You might be missing a valid SKU for'
|
||||
+ ' the target system or have a failed network connection.'
|
||||
+ ' Check whether your system is attached to a valid SKU that is'
|
||||
+ ' providing RHEL {} repositories.'
|
||||
+ ' If you are using Red Hat Satellite, read the upgrade documentation'
|
||||
+ ' to set up Satellite and the system properly.'
|
||||
+ .format(target_major_version)))
|
||||
+ )
|
||||
+ reporting.create_report(report)
|
||||
raise StopActorExecution()
|
||||
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py b/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py
|
||||
index e8853979..b49eff56 100644
|
||||
--- a/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py
|
||||
+++ b/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py
|
||||
@@ -1103,7 +1103,7 @@ def test_gather_target_repositories_none_available(monkeypatch):
|
||||
reports = [m.report for m in mocked_produce.model_instances if isinstance(m, reporting.Report)]
|
||||
inhibitors = [m for m in reports if 'INHIBITOR' in m.get('flags', ())]
|
||||
assert len(inhibitors) == 1
|
||||
- assert inhibitors[0].get('title', '') == 'Cannot find required basic RHEL target repositories.'
|
||||
+ assert inhibitors[0].get('title', '') == 'Cannot find required basic target OS repositories.'
|
||||
|
||||
|
||||
@suppress_deprecation(models.RHELTargetRepository)
|
||||
@@ -1166,7 +1166,7 @@ def test_gather_target_repositories_baseos_appstream_not_available(monkeypatch):
|
||||
reports = [m.report for m in mocked_produce.model_instances if isinstance(m, reporting.Report)]
|
||||
inhibitors = [m for m in reports if 'inhibitor' in m.get('groups', ())]
|
||||
assert len(inhibitors) == 1
|
||||
- assert inhibitors[0].get('title', '') == 'Cannot find required basic RHEL target repositories.'
|
||||
+ assert inhibitors[0].get('title', '') == 'Cannot find required basic target OS repositories.'
|
||||
# Now test the case when either of AppStream and BaseOs is not available, upgrade should be inhibited
|
||||
mocked_produce = produce_mocked()
|
||||
monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked())
|
||||
@@ -1181,7 +1181,7 @@ def test_gather_target_repositories_baseos_appstream_not_available(monkeypatch):
|
||||
reports = [m.report for m in mocked_produce.model_instances if isinstance(m, reporting.Report)]
|
||||
inhibitors = [m for m in reports if 'inhibitor' in m.get('groups', ())]
|
||||
assert len(inhibitors) == 1
|
||||
- assert inhibitors[0].get('title', '') == 'Cannot find required basic RHEL target repositories.'
|
||||
+ assert inhibitors[0].get('title', '') == 'Cannot find required basic target OS repositories.'
|
||||
mocked_produce = produce_mocked()
|
||||
monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked())
|
||||
monkeypatch.setattr(userspacegen.api.current_actor(), 'produce', mocked_produce)
|
||||
@@ -1195,7 +1195,7 @@ def test_gather_target_repositories_baseos_appstream_not_available(monkeypatch):
|
||||
reports = [m.report for m in mocked_produce.model_instances if isinstance(m, reporting.Report)]
|
||||
inhibitors = [m for m in reports if 'inhibitor' in m.get('groups', ())]
|
||||
assert len(inhibitors) == 1
|
||||
- assert inhibitors[0].get('title', '') == 'Cannot find required basic RHEL target repositories.'
|
||||
+ assert inhibitors[0].get('title', '') == 'Cannot find required basic target OS repositories.'
|
||||
|
||||
|
||||
def test__get_distro_available_repoids_norhsm_norhui(monkeypatch):
|
||||
@@ -1254,7 +1254,7 @@ def test__get_distro_available_repoids_nobaserepos_inhibit(
|
||||
# TODO adjust the asserts when the report is made distro agnostic
|
||||
assert reporting.create_report.called == 1
|
||||
report = reporting.create_report.reports[0]
|
||||
- assert "Cannot find required basic RHEL target repositories" in report["title"]
|
||||
+ assert "Cannot find required basic target OS repositories" in report["title"]
|
||||
assert reporting.Groups.INHIBITOR in report["groups"]
|
||||
|
||||
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -1,241 +0,0 @@
|
||||
From 8e0aad41201e080482fbc279fd2d58bc11c20e91 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 18:46:16 +0100
|
||||
Subject: [PATCH 25/44] checkdetecteddevicesanddirvers: Respect distro name in
|
||||
reports
|
||||
|
||||
Also add stable keys to all reports, the keys were generated as if on
|
||||
7->8 upgrade (target major version == 8), the exact titles used for
|
||||
computation:
|
||||
- 'Leapp detected loaded kernel drivers which have been removed in RHEL 8. Upgrade cannot proceed.'
|
||||
- 'Leapp detected devices which are no longer supported in RHEL 8. Upgrade cannot proceed.'
|
||||
- 'Leapp detected a processor which is no longer supported in RHEL 8. Upgrade cannot proceed.'
|
||||
- 'Leapp detected loaded kernel drivers which are no longer maintained in RHEL 8.'
|
||||
- 'Leapp detected devices which are no longer maintained in RHEL 8'
|
||||
- 'Leapp detected a processor which is no longer maintained in RHEL 8.'
|
||||
|
||||
The following report titles and keys are no longer used as they've been
|
||||
unified with the reports above and now also use the respective keys:
|
||||
|
||||
Leapp detected loaded kernel drivers which have been removed in RHEL 9. Upgrade cannot proceed.
|
||||
- 7ae2961239eec9905e2580fa6309a589b1dca953
|
||||
Leapp detected devices which are no longer supported in RHEL 9. Upgrade cannot proceed.
|
||||
- 0e042eba4d14bd1f1ae691db6389621f778f21ad
|
||||
Leapp detected a processor which is no longer supported in RHEL 9. Upgrade cannot proceed.
|
||||
- f79672290945c09de12a14b28906b98d5c8ed68a
|
||||
Leapp detected loaded kernel drivers which are no longer maintained in RHEL 9.
|
||||
- b03c306f274b33b4cf3c7cd3764366c599681481
|
||||
Leapp detected devices which are no longer maintained in RHEL 9
|
||||
- 65ac6710649c928288162900e8df8316ac8e1bda
|
||||
Leapp detected a processor which is no longer maintained in RHEL 9.
|
||||
- 93f6cf039f01095a59ebaf581ced33316e034ef8
|
||||
Leapp detected loaded kernel drivers which have been removed in RHEL 10. Upgrade cannot proceed.
|
||||
- 48e04852631245aa4afee9adcdc7c2375b8cffb8
|
||||
Leapp detected devices which are no longer supported in RHEL 10. Upgrade cannot proceed.
|
||||
- fa9da5bf370c8477eb4f8366b68ffac2aaae6374
|
||||
Leapp detected a processor which is no longer supported in RHEL 10. Upgrade cannot proceed.
|
||||
- f6199d8526ee41c3e89b4ed11b3f8ee90cfc6f9f
|
||||
Leapp detected loaded kernel drivers which are no longer maintained in RHEL 10.
|
||||
- fbb11ae5828d624c4e4c91e73d766c8e27b066d9
|
||||
Leapp detected devices which are no longer maintained in RHEL 10
|
||||
- 93f67baabd93c00625fce5ad47edbf19972e41a0
|
||||
Leapp detected a processor which is no longer maintained in RHEL 10.
|
||||
- 9dde4bcd8b458bd6803462216785df3a1476c1f8
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../libraries/checkdddd.py | 70 +++++++++++--------
|
||||
1 file changed, 41 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/checkdetecteddevicesanddrivers/libraries/checkdddd.py b/repos/system_upgrade/common/actors/checkdetecteddevicesanddrivers/libraries/checkdddd.py
|
||||
index 1f01adde..22a39c29 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkdetecteddevicesanddrivers/libraries/checkdddd.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkdetecteddevicesanddrivers/libraries/checkdddd.py
|
||||
@@ -3,6 +3,7 @@ from enum import IntEnum
|
||||
|
||||
from leapp import reporting
|
||||
from leapp.libraries.common.config.version import get_source_major_version, get_target_major_version
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import DetectedDeviceOrDriver
|
||||
|
||||
@@ -22,17 +23,19 @@ def create_inhibitors(inhibiting_entries):
|
||||
if drivers:
|
||||
reporting.create_report([
|
||||
reporting.Title(
|
||||
- 'Leapp detected loaded kernel drivers which have been removed '
|
||||
- 'in RHEL {}. Upgrade cannot proceed.'.format(get_target_major_version())
|
||||
+ 'Leapp detected loaded kernel drivers that have been removed in'
|
||||
+ ' the target OS. Upgrade cannot proceed.'
|
||||
),
|
||||
reporting.Summary(
|
||||
(
|
||||
- 'Support for the following RHEL {source} device drivers has been removed in RHEL {target}:\n'
|
||||
+ 'Support for the following {source_distro} {source_version} device drivers has'
|
||||
+ ' been removed in {target_distro} {target_version}:\n'
|
||||
' - {drivers}\n'
|
||||
).format(
|
||||
drivers='\n - '.join([entry.driver_name for entry in drivers]),
|
||||
- target=get_target_major_version(),
|
||||
- source=get_source_major_version(),
|
||||
+ target_version=get_target_major_version(),
|
||||
+ source_version=get_source_major_version(),
|
||||
+ **DISTRO_REPORT_NAMES
|
||||
)
|
||||
),
|
||||
reporting.ExternalLink(
|
||||
@@ -52,52 +55,57 @@ def create_inhibitors(inhibiting_entries):
|
||||
reporting.Audience('sysadmin'),
|
||||
reporting.Groups([reporting.Groups.KERNEL, reporting.Groups.DRIVERS]),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR])
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
+ reporting.Key('f08a07da902958defa4f5c2699fae9ec2eb67c5b'),
|
||||
])
|
||||
|
||||
devices = inhibiting_entries.get(MessagingClass.DEVICES)
|
||||
if devices:
|
||||
reporting.create_report([
|
||||
reporting.Title(
|
||||
- 'Leapp detected devices which are no longer supported in RHEL {}. Upgrade cannot proceed.'.format(
|
||||
- get_target_major_version())
|
||||
+ 'Leapp detected devices no longer supported by the target OS.'
|
||||
+ ' Upgrade cannot proceed.'
|
||||
),
|
||||
reporting.Summary(
|
||||
(
|
||||
- 'Support for the following devices has been removed in RHEL {target}:\n'
|
||||
+ 'Support for the following devices has been removed in {target_distro} {version}:\n'
|
||||
' - {devices}\n'
|
||||
).format(
|
||||
devices='\n - '.join(['{name} ({pci})'.format(name=entry.device_name,
|
||||
pci=entry.device_id) for entry in devices]),
|
||||
- target=get_target_major_version(),
|
||||
+ version=get_target_major_version(),
|
||||
+ **DISTRO_REPORT_NAMES
|
||||
)
|
||||
),
|
||||
reporting.Audience('sysadmin'),
|
||||
reporting.Groups([reporting.Groups.KERNEL]),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR])
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
+ reporting.Key('ccfc28592c82123649fc824c6c1c89cabfceae7c'),
|
||||
])
|
||||
|
||||
cpus = inhibiting_entries.get(MessagingClass.CPUS)
|
||||
if cpus:
|
||||
reporting.create_report([
|
||||
reporting.Title(
|
||||
- 'Leapp detected a processor which is no longer supported in RHEL {}. Upgrade cannot proceed.'.format(
|
||||
- get_target_major_version())
|
||||
+ 'Leapp detected a processor no longer supported by the target OS.'
|
||||
+ ' Upgrade cannot proceed.'
|
||||
),
|
||||
reporting.Summary(
|
||||
(
|
||||
- 'Support for the following processors has been removed in RHEL {target}:\n'
|
||||
+ 'Support for the following processors has been removed in {target_distro} {version}:\n'
|
||||
' - {processors}\n'
|
||||
).format(
|
||||
processors='\n - '.join([entry.device_name for entry in cpus]),
|
||||
- target=get_target_major_version(),
|
||||
+ version=get_target_major_version(),
|
||||
+ **DISTRO_REPORT_NAMES
|
||||
)
|
||||
),
|
||||
reporting.Audience('sysadmin'),
|
||||
reporting.Groups([reporting.Groups.KERNEL, reporting.Groups.BOOT]),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR])
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
+ reporting.Key('e3e9e4d2566733e2f843db9823c8568b9b6922f9'),
|
||||
])
|
||||
|
||||
|
||||
@@ -109,65 +117,69 @@ def create_warnings(unmaintained_entries):
|
||||
if drivers:
|
||||
reporting.create_report([
|
||||
reporting.Title(
|
||||
- 'Leapp detected loaded kernel drivers which are no longer maintained in RHEL {}.'.format(
|
||||
- get_target_major_version())
|
||||
+ 'Leapp detected loaded kernel drivers no longer maintained in the target OS'
|
||||
),
|
||||
reporting.Summary(
|
||||
(
|
||||
- 'The following RHEL {source} device drivers are no longer maintained RHEL {target}:\n'
|
||||
+ 'The following {source_distro} {source_version} device drivers are no longer'
|
||||
+ ' maintained {target_distro} {target_version}:\n'
|
||||
' - {drivers}\n'
|
||||
).format(
|
||||
drivers='\n - '.join([entry.driver_name for entry in drivers]),
|
||||
- target=get_target_major_version(),
|
||||
- source=get_source_major_version(),
|
||||
+ target_version=get_target_major_version(),
|
||||
+ source_version=get_source_major_version(),
|
||||
+ **DISTRO_REPORT_NAMES
|
||||
)
|
||||
),
|
||||
reporting.Audience('sysadmin'),
|
||||
reporting.Groups([reporting.Groups.KERNEL, reporting.Groups.DRIVERS]),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Key('0ff2413fd3cb0358736bf9be597f4dbdf58f2c4d'),
|
||||
])
|
||||
|
||||
devices = unmaintained_entries.get(MessagingClass.DEVICES)
|
||||
if devices:
|
||||
reporting.create_report([
|
||||
reporting.Title(
|
||||
- 'Leapp detected devices which are no longer maintained in RHEL {}'.format(
|
||||
- get_target_major_version())
|
||||
+ 'Leapp detected devices no longer maintained in the target OS'
|
||||
),
|
||||
reporting.Summary(
|
||||
(
|
||||
- 'The support for the following devices has been removed in RHEL {target} and '
|
||||
+ 'The support for the following devices has been removed in {target_distro} {version} and '
|
||||
'are no longer maintained:\n - {devices}\n'
|
||||
).format(
|
||||
devices='\n - '.join(['{name} ({pci})'.format(name=entry.device_name,
|
||||
pci=entry.device_id) for entry in devices]),
|
||||
- target=get_target_major_version(),
|
||||
+ version=get_target_major_version(),
|
||||
+ **DISTRO_REPORT_NAMES
|
||||
)
|
||||
),
|
||||
reporting.Audience('sysadmin'),
|
||||
reporting.Groups([reporting.Groups.KERNEL]),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Key('261e3e55a3a80346f2fcc2a1e59c64f7a4caa263'),
|
||||
])
|
||||
|
||||
cpus = unmaintained_entries.get(MessagingClass.CPUS)
|
||||
if cpus:
|
||||
reporting.create_report([
|
||||
reporting.Title(
|
||||
- 'Leapp detected a processor which is no longer maintained in RHEL {}.'.format(
|
||||
- get_target_major_version())
|
||||
+ 'Leapp detected a processor no longer maintained in the target OS'
|
||||
),
|
||||
reporting.Summary(
|
||||
(
|
||||
- 'The following processors are no longer maintained in RHEL {target}:\n'
|
||||
+ 'The following processors are no longer maintained in {target_distro} {version}:\n'
|
||||
' - {processors}\n'
|
||||
).format(
|
||||
processors='\n - '.join([entry.device_name for entry in cpus]),
|
||||
- target=get_target_major_version(),
|
||||
+ version=get_target_major_version(),
|
||||
+ **DISTRO_REPORT_NAMES
|
||||
)
|
||||
),
|
||||
reporting.Audience('sysadmin'),
|
||||
reporting.Groups([reporting.Groups.KERNEL, reporting.Groups.BOOT]),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Key('61eb181bbc56328fbe03b5229d25a8ea5ebdc7a2'),
|
||||
])
|
||||
|
||||
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
From e43a8922e06d72212e8e2a8b51747c668147182c Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Wed, 6 Nov 2024 22:26:01 +0100
|
||||
Subject: [PATCH 25/40] fix condition on when net naming is emitted
|
||||
|
||||
---
|
||||
.../emit_net_naming_scheme/libraries/emit_net_naming.py | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
index 65abdd4d..726bb459 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
@@ -44,7 +44,10 @@ def is_net_scheme_compatible_with_current_cmdline():
|
||||
|
||||
|
||||
def emit_msgs_to_use_net_naming_schemes():
|
||||
- if get_env('LEAPP_USE_NET_NAMING_SCHEMES', '0') != '1' and version.get_target_major_version() != '8':
|
||||
+ is_env_var_set = get_env('LEAPP_USE_NET_NAMING_SCHEMES', '0') == '1'
|
||||
+ is_upgrade_8to9 = version.get_target_major_version() == '9'
|
||||
+ is_net_naming_enabled_and_permitted = is_env_var_set and is_upgrade_8to9
|
||||
+ if not is_net_naming_enabled_and_permitted:
|
||||
return
|
||||
|
||||
# The package should be installed regardless of whether we will modify the cmdline -
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,140 +0,0 @@
|
||||
From e9fa8aac4b32baaaf171c1cd6cd25f88a78d36a0 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Mon, 2 Mar 2026 19:01:02 +0100
|
||||
Subject: [PATCH 26/44] reportleftoverpackages: Respect distro name in reports
|
||||
|
||||
The actors is also moved from the reportleftoverpackages actor
|
||||
subdirectory to the root actor directory.
|
||||
|
||||
Also add stable report keys to the reports. The keys were computed using
|
||||
titles:
|
||||
- 'Leftover RHEL packages have been removed'
|
||||
- 'Some RHEL packages have not been upgraded'
|
||||
|
||||
Jira: RHEL-130950
|
||||
---
|
||||
.../{reportleftoverpackages => }/actor.py | 8 ++++----
|
||||
.../libraries/reportleftoverpackages.py | 17 +++++++++++------
|
||||
.../tests/test_reportleftoverpackages.py | 9 ++++++---
|
||||
3 files changed, 21 insertions(+), 13 deletions(-)
|
||||
rename repos/system_upgrade/common/actors/reportleftoverpackages/{reportleftoverpackages => }/actor.py (61%)
|
||||
rename repos/system_upgrade/common/actors/reportleftoverpackages/{reportleftoverpackages => }/libraries/reportleftoverpackages.py (73%)
|
||||
rename repos/system_upgrade/common/actors/reportleftoverpackages/{reportleftoverpackages => }/tests/test_reportleftoverpackages.py (86%)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/reportleftoverpackages/reportleftoverpackages/actor.py b/repos/system_upgrade/common/actors/reportleftoverpackages/actor.py
|
||||
similarity index 61%
|
||||
rename from repos/system_upgrade/common/actors/reportleftoverpackages/reportleftoverpackages/actor.py
|
||||
rename to repos/system_upgrade/common/actors/reportleftoverpackages/actor.py
|
||||
index 58573451..d0640774 100644
|
||||
--- a/repos/system_upgrade/common/actors/reportleftoverpackages/reportleftoverpackages/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/reportleftoverpackages/actor.py
|
||||
@@ -7,11 +7,11 @@ from leapp.tags import IPUWorkflowTag, RPMUpgradePhaseTag
|
||||
|
||||
class ReportLeftoverPackages(Actor):
|
||||
"""
|
||||
- Collect messages about leftover RHEL packages from older major versions and generate a report.
|
||||
+ Generate a report about leftover distribution packages from older major versions.
|
||||
|
||||
- Depending on execution of previous actors,
|
||||
- generated report contains information that there are still old RHEL packages
|
||||
- present on the system, which makes it unsupported or lists packages that have been removed.
|
||||
+ Generated report informs about old distribution packages present on the system,
|
||||
+ which makes it unsupported, and lists packages that have been removed if there
|
||||
+ were any.
|
||||
"""
|
||||
|
||||
name = 'report_leftover_packages'
|
||||
diff --git a/repos/system_upgrade/common/actors/reportleftoverpackages/reportleftoverpackages/libraries/reportleftoverpackages.py b/repos/system_upgrade/common/actors/reportleftoverpackages/libraries/reportleftoverpackages.py
|
||||
similarity index 73%
|
||||
rename from repos/system_upgrade/common/actors/reportleftoverpackages/reportleftoverpackages/libraries/reportleftoverpackages.py
|
||||
rename to repos/system_upgrade/common/actors/reportleftoverpackages/libraries/reportleftoverpackages.py
|
||||
index 51bda931..cd45ac87 100644
|
||||
--- a/repos/system_upgrade/common/actors/reportleftoverpackages/reportleftoverpackages/libraries/reportleftoverpackages.py
|
||||
+++ b/repos/system_upgrade/common/actors/reportleftoverpackages/libraries/reportleftoverpackages.py
|
||||
@@ -1,4 +1,5 @@
|
||||
from leapp import reporting
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import LeftoverPackages, RemovedPackages
|
||||
|
||||
@@ -11,15 +12,16 @@ def process():
|
||||
leftover_pkgs_to_remove = ['-'.join([pkg.name, pkg.version, pkg.release]) for pkg in leftover_packages.items]
|
||||
|
||||
if removed_packages and removed_packages.items:
|
||||
- title = 'Leftover RHEL packages have been removed'
|
||||
+ title = 'Leftover packages from the original OS have been removed'
|
||||
removed = ['-'.join([pkg.name, pkg.version, pkg.release]) for pkg in removed_packages.items]
|
||||
summary = (
|
||||
- 'Following packages have been removed:{sep}{list}\n'
|
||||
+ 'Following {source_distro} packages have been removed:{sep}{list}\n'
|
||||
'Dependent packages may have been removed as well, please check that you are not missing '
|
||||
'any packages.'
|
||||
.format(
|
||||
sep=FMT_LIST_SEPARATOR,
|
||||
- list=FMT_LIST_SEPARATOR.join(removed)
|
||||
+ list=FMT_LIST_SEPARATOR.join(removed),
|
||||
+ **DISTRO_REPORT_NAMES
|
||||
)
|
||||
)
|
||||
reporting.create_report([
|
||||
@@ -27,23 +29,26 @@ def process():
|
||||
reporting.Summary(summary),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups([reporting.Groups.SANITY]),
|
||||
+ reporting.Key('5afbad560709afa4e40a160e40dfd44788ba9c3b'),
|
||||
] + [reporting.RelatedResource('package', pkg.name) for pkg in removed_packages.items])
|
||||
return
|
||||
|
||||
if leftover_packages and leftover_packages.items:
|
||||
summary = (
|
||||
- 'Following RHEL packages have not been upgraded:{sep}{list}\n'
|
||||
+ 'Following {source_distro} packages have not been upgraded:{sep}{list}\n'
|
||||
'Please remove these packages to keep your system in supported state.'
|
||||
.format(
|
||||
sep=FMT_LIST_SEPARATOR,
|
||||
- list=FMT_LIST_SEPARATOR.join(leftover_pkgs_to_remove)
|
||||
+ list=FMT_LIST_SEPARATOR.join(leftover_pkgs_to_remove),
|
||||
+ **DISTRO_REPORT_NAMES
|
||||
)
|
||||
)
|
||||
reporting.create_report([
|
||||
- reporting.Title('Some RHEL packages have not been upgraded'),
|
||||
+ reporting.Title('Some packages from the original OS have not been upgraded'),
|
||||
reporting.Summary(summary),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups([reporting.Groups.SANITY]),
|
||||
+ reporting.Key('d424c3132ed78a8632b5c73d919909e453107c06'),
|
||||
] + [reporting.RelatedResource('package', pkg.name) for pkg in leftover_packages.items])
|
||||
else:
|
||||
api.current_logger().info('No leftover packages, skipping...')
|
||||
diff --git a/repos/system_upgrade/common/actors/reportleftoverpackages/reportleftoverpackages/tests/test_reportleftoverpackages.py b/repos/system_upgrade/common/actors/reportleftoverpackages/tests/test_reportleftoverpackages.py
|
||||
similarity index 86%
|
||||
rename from repos/system_upgrade/common/actors/reportleftoverpackages/reportleftoverpackages/tests/test_reportleftoverpackages.py
|
||||
rename to repos/system_upgrade/common/actors/reportleftoverpackages/tests/test_reportleftoverpackages.py
|
||||
index ff493c57..9502bfd2 100644
|
||||
--- a/repos/system_upgrade/common/actors/reportleftoverpackages/reportleftoverpackages/tests/test_reportleftoverpackages.py
|
||||
+++ b/repos/system_upgrade/common/actors/reportleftoverpackages/tests/test_reportleftoverpackages.py
|
||||
@@ -27,7 +27,10 @@ def test_no_removed_packages_leftover_present(monkeypatch):
|
||||
reportleftoverpackages.process()
|
||||
|
||||
assert reporting.create_report.called == 1
|
||||
- assert 'Some RHEL packages have not been upgraded' in reporting.create_report.report_fields['title']
|
||||
+ assert (
|
||||
+ 'Some packages from the original OS have not been upgraded'
|
||||
+ in reporting.create_report.report_fields['title']
|
||||
+ )
|
||||
assert 'Following RHEL packages have not been upgraded' in reporting.create_report.report_fields['summary']
|
||||
summary = 'Please remove these packages to keep your system in supported state.'
|
||||
assert summary in reporting.create_report.report_fields['summary']
|
||||
@@ -44,6 +47,6 @@ def test_removed_packages(monkeypatch):
|
||||
reportleftoverpackages.process()
|
||||
|
||||
assert reporting.create_report.called == 1
|
||||
- assert 'Leftover RHEL packages have been removed' in reporting.create_report.report_fields['title']
|
||||
- assert 'Following packages have been removed' in reporting.create_report.report_fields['summary']
|
||||
+ assert 'Leftover packages from the original OS have been removed' in reporting.create_report.report_fields['title']
|
||||
+ assert 'Following RHEL packages have been removed' in reporting.create_report.report_fields['summary']
|
||||
assert 'rpm-1.0-1.el7' in reporting.create_report.report_fields['summary']
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
From 0bf07d1546ccdc6d4a9e6f4936a98b4d6ca27789 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Tue, 12 Nov 2024 09:10:50 +0100
|
||||
Subject: [PATCH 26/40] scangrubdevpartitionlayout: Skip warning msgs
|
||||
|
||||
The fdisk output can contain warning msgs when a partition is not
|
||||
aligned on physical sector boundary, like:
|
||||
Partition 4 does not start on physical sector boundary.
|
||||
We know that in case of MBR the line we expect to parse always
|
||||
starts with canonical path. So let's skip all lines which does
|
||||
not start with '/'.
|
||||
|
||||
jira: https://issues.redhat.com/browse/RHEL-50947
|
||||
---
|
||||
.../libraries/scan_layout.py | 10 ++++++++++
|
||||
.../tests/test_scan_partition_layout.py | 3 +++
|
||||
2 files changed, 13 insertions(+)
|
||||
|
||||
diff --git a/repos/system_upgrade/el7toel8/actors/scangrubdevpartitionlayout/libraries/scan_layout.py b/repos/system_upgrade/el7toel8/actors/scangrubdevpartitionlayout/libraries/scan_layout.py
|
||||
index 83d02656..7f4a2a59 100644
|
||||
--- a/repos/system_upgrade/el7toel8/actors/scangrubdevpartitionlayout/libraries/scan_layout.py
|
||||
+++ b/repos/system_upgrade/el7toel8/actors/scangrubdevpartitionlayout/libraries/scan_layout.py
|
||||
@@ -68,6 +68,16 @@ def get_partition_layout(device):
|
||||
|
||||
partitions = []
|
||||
for partition_line in table_iter:
|
||||
+ if not partition_line.startswith('/'):
|
||||
+ # the output can contain warning msg when a partition is not aligned
|
||||
+ # on physical sector boundary, like:
|
||||
+ # ~~~
|
||||
+ # Partition 4 does not start on physical sector boundary.
|
||||
+ # ~~~
|
||||
+ # We know that in case of MBR the line we expect to parse always
|
||||
+ # starts with canonical path. So let's use this condition.
|
||||
+ # See https://issues.redhat.com/browse/RHEL-50947
|
||||
+ continue
|
||||
# Fields: Device Boot Start End Sectors Size Id Type
|
||||
# The line looks like: `/dev/vda1 * 2048 2099199 2097152 1G 83 Linux`
|
||||
part_info = split_on_space_segments(partition_line)
|
||||
diff --git a/repos/system_upgrade/el7toel8/actors/scangrubdevpartitionlayout/tests/test_scan_partition_layout.py b/repos/system_upgrade/el7toel8/actors/scangrubdevpartitionlayout/tests/test_scan_partition_layout.py
|
||||
index 743ca71f..9c32e16f 100644
|
||||
--- a/repos/system_upgrade/el7toel8/actors/scangrubdevpartitionlayout/tests/test_scan_partition_layout.py
|
||||
+++ b/repos/system_upgrade/el7toel8/actors/scangrubdevpartitionlayout/tests/test_scan_partition_layout.py
|
||||
@@ -49,6 +49,9 @@ def test_get_partition_layout(monkeypatch, devices, fs):
|
||||
part_line = '{0} * {1} 2099199 1048576 83 {2}'.format(part.name, part.start_offset, fs)
|
||||
fdisk_output.append(part_line)
|
||||
|
||||
+ # add a problematic warning msg to test:
|
||||
+ # https://issues.redhat.com/browse/RHEL-50947
|
||||
+ fdisk_output.append('Partition 3 does not start on physical sector boundary.')
|
||||
device_to_fdisk_output[device.name] = fdisk_output
|
||||
|
||||
def mocked_run(cmd, *args, **kwargs):
|
||||
--
|
||||
2.47.0
|
||||
|
||||
1756
SOURCES/0027-Workaround-for-ARM-Upgrades-from-RHEL8-to-RHEL9.5.patch
Normal file
1756
SOURCES/0027-Workaround-for-ARM-Upgrades-from-RHEL8-to-RHEL9.5.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,32 +0,0 @@
|
||||
From 9f0cbbcb5a75f77b226cf385b6179f93fbdf9bc0 Mon Sep 17 00:00:00 2001
|
||||
From: Sergii Golovatiuk <sgolovat@redhat.com>
|
||||
Date: Wed, 18 Mar 2026 17:19:38 +0100
|
||||
Subject: [PATCH 27/44] fix(overlaygen): exclude hugetlbfs from overlay mounts
|
||||
|
||||
hugetlbfs should not be mounted in the overlay environment during the
|
||||
upgrade. It's not a regular mount point. This patch adds it to the
|
||||
OVERLAY_DO_NOT_MOUNT exclusion list.
|
||||
|
||||
Resolves: RHEL-156902
|
||||
|
||||
Signed-off-by: Sergii Golovatiuk <sgolovat@redhat.com>
|
||||
---
|
||||
repos/system_upgrade/common/libraries/overlaygen.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/libraries/overlaygen.py b/repos/system_upgrade/common/libraries/overlaygen.py
|
||||
index 3091ab5b..9fdaadf9 100644
|
||||
--- a/repos/system_upgrade/common/libraries/overlaygen.py
|
||||
+++ b/repos/system_upgrade/common/libraries/overlaygen.py
|
||||
@@ -10,7 +10,7 @@ from leapp.libraries.common.config import get_env
|
||||
from leapp.libraries.common.config.version import get_target_major_version
|
||||
from leapp.libraries.stdlib import api, CalledProcessError, run
|
||||
|
||||
-OVERLAY_DO_NOT_MOUNT = ('tmpfs', 'devtmpfs', 'devpts', 'sysfs', 'proc', 'cramfs', 'sysv', 'vfat')
|
||||
+OVERLAY_DO_NOT_MOUNT = ('tmpfs', 'devtmpfs', 'devpts', 'sysfs', 'proc', 'cramfs', 'sysv', 'vfat', 'hugetlbfs')
|
||||
|
||||
# NOTE(pstodulk): what about using more closer values and than just multiply
|
||||
# the final result by magical constant?... this number is most likely going to
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,115 @@
|
||||
From 866a4b9f163c3aec31736ac0ce25f564fe016cb4 Mon Sep 17 00:00:00 2001
|
||||
From: Jarek Prokop <jprokop@redhat.com>
|
||||
Date: Tue, 5 Nov 2024 10:15:28 +0100
|
||||
Subject: [PATCH 28/40] Add el9toel10 actor to handle symlink -> directory with
|
||||
ruby IRB.
|
||||
|
||||
The `/usr/share/ruby/irb` path is a symlink in RHEL 9,
|
||||
but a regular directory in RHEL 10.
|
||||
This puts us back in line with RHEL 8 and Fedora in terms of the
|
||||
path's file type regarding the rubygem-irb package.
|
||||
|
||||
Since this was not handled on RPM level, handle it as actor again.
|
||||
This was copied and adjusted from same-named el8->el9 actor.
|
||||
|
||||
We do not care about the validity or target of the symlink, we just
|
||||
remove it to allow DNF create the correct directory on upgrade.
|
||||
|
||||
Without this workaround, the upgrade will fail in transaction test with
|
||||
reports of file conflicts on the directory path.
|
||||
|
||||
Users should not expect to ever retain anything in this directory.
|
||||
---
|
||||
.../actors/registerrubyirbadjustment/actor.py | 31 +++++++++++++++++++
|
||||
.../test_register_ruby_irb_adjustments.py | 11 +++++++
|
||||
.../el9toel10/tools/handlerubyirbsymlink | 22 +++++++++++++
|
||||
3 files changed, 64 insertions(+)
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/registerrubyirbadjustment/actor.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/registerrubyirbadjustment/tests/test_register_ruby_irb_adjustments.py
|
||||
create mode 100755 repos/system_upgrade/el9toel10/tools/handlerubyirbsymlink
|
||||
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/registerrubyirbadjustment/actor.py b/repos/system_upgrade/el9toel10/actors/registerrubyirbadjustment/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..4fbec7ff
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/registerrubyirbadjustment/actor.py
|
||||
@@ -0,0 +1,31 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.models import DNFWorkaround
|
||||
+from leapp.tags import FactsPhaseTag, IPUWorkflowTag
|
||||
+
|
||||
+
|
||||
+class RegisterRubyIRBAdjustment(Actor):
|
||||
+ """
|
||||
+ Register a workaround to allow rubygem-irb's symlink -> directory conversion.
|
||||
+
|
||||
+ The /usr/share/ruby/irb has been moved from a symlink to a directory
|
||||
+ in RHEL 10 and this conversion was not handled on the RPM level.
|
||||
+ This leads to DNF reporting package file conflicts when a major upgrade
|
||||
+ is attempted and rubygem-irb is installed.
|
||||
+
|
||||
+ Register "handlerubyirbsymlink" script that removes the symlink prior
|
||||
+ to DNF upgrade and allows it to create the expected directory in place of
|
||||
+ the removed symlink.
|
||||
+ """
|
||||
+
|
||||
+ name = 'register_ruby_irb_adjustment'
|
||||
+ consumes = ()
|
||||
+ produces = (DNFWorkaround,)
|
||||
+ tags = (IPUWorkflowTag, FactsPhaseTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ self.produce(
|
||||
+ DNFWorkaround(
|
||||
+ display_name='IRB directory fix',
|
||||
+ script_path=self.get_tool_path('handlerubyirbsymlink'),
|
||||
+ )
|
||||
+ )
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/registerrubyirbadjustment/tests/test_register_ruby_irb_adjustments.py b/repos/system_upgrade/el9toel10/actors/registerrubyirbadjustment/tests/test_register_ruby_irb_adjustments.py
|
||||
new file mode 100644
|
||||
index 00000000..fc341646
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/registerrubyirbadjustment/tests/test_register_ruby_irb_adjustments.py
|
||||
@@ -0,0 +1,11 @@
|
||||
+import os.path
|
||||
+
|
||||
+from leapp.models import DNFWorkaround
|
||||
+
|
||||
+
|
||||
+def test_register_ruby_irb_adjustments(current_actor_context):
|
||||
+ current_actor_context.run()
|
||||
+ assert len(current_actor_context.consume(DNFWorkaround)) == 1
|
||||
+ assert current_actor_context.consume(DNFWorkaround)[0].display_name == 'IRB directory fix'
|
||||
+ assert os.path.basename(current_actor_context.consume(DNFWorkaround)[0].script_path) == 'handlerubyirbsymlink'
|
||||
+ assert os.path.exists(current_actor_context.consume(DNFWorkaround)[0].script_path)
|
||||
diff --git a/repos/system_upgrade/el9toel10/tools/handlerubyirbsymlink b/repos/system_upgrade/el9toel10/tools/handlerubyirbsymlink
|
||||
new file mode 100755
|
||||
index 00000000..e9ac40fe
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/tools/handlerubyirbsymlink
|
||||
@@ -0,0 +1,22 @@
|
||||
+#!/usr/bin/bash -e
|
||||
+
|
||||
+# just in case of hidden files.. not sure why would someone do that, it's more
|
||||
+# like forgotten cache file possibility, but rather do that..
|
||||
+shopt -s dotglob
|
||||
+
|
||||
+handle_dir() {
|
||||
+ # Check that $1 is a symlink then unlink it so that RPM
|
||||
+ # can freely create the directory.
|
||||
+ if [ ! -L "$1" ]; then
|
||||
+ return
|
||||
+ fi
|
||||
+
|
||||
+ # There is no configuration or anything that the user should ever customize
|
||||
+ # and expect to retain.
|
||||
+ unlink "$1"
|
||||
+
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+
|
||||
+handle_dir /usr/share/ruby/irb
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,121 +0,0 @@
|
||||
From 4c303cb3d30f891aa5d5d3ff4b3675deb41c6385 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Mon, 16 Mar 2026 23:10:49 +0100
|
||||
Subject: [PATCH 28/44] biosdevname: Fix check of naming scheme and tests
|
||||
|
||||
The original check matched also NIC names with suffixes that do not
|
||||
correspond to biosdevname naming scheme (e.g. "em0net"). Make the
|
||||
check strict for the whole ^string$ and update tests to cover the
|
||||
scenario.
|
||||
|
||||
Also I made small refactorings in tests
|
||||
* so in case of failure it's visible what input data caused the
|
||||
failure
|
||||
* minimize changes needed to do with planned update of Interface model
|
||||
---
|
||||
.../biosdevname/libraries/biosdevname.py | 4 +-
|
||||
.../biosdevname/tests/test_biosdevname.py | 73 ++++++++-----------
|
||||
2 files changed, 31 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/biosdevname/libraries/biosdevname.py b/repos/system_upgrade/common/actors/biosdevname/libraries/biosdevname.py
|
||||
index a6b4a242..e2f4b1d1 100644
|
||||
--- a/repos/system_upgrade/common/actors/biosdevname/libraries/biosdevname.py
|
||||
+++ b/repos/system_upgrade/common/actors/biosdevname/libraries/biosdevname.py
|
||||
@@ -27,8 +27,8 @@ def is_vendor_dell():
|
||||
|
||||
def all_interfaces_biosdevname(interfaces):
|
||||
# Biosdevname supports two naming schemes
|
||||
- emx = re.compile('em[0-9]+')
|
||||
- pxpy = re.compile('p[0-9]+p[0-9]+')
|
||||
+ emx = re.compile('^em[0-9]+$')
|
||||
+ pxpy = re.compile('^p[0-9]+p[0-9]+$')
|
||||
|
||||
for i in interfaces:
|
||||
if emx.match(i.name) is None and pxpy.match(i.name) is None:
|
||||
diff --git a/repos/system_upgrade/common/actors/biosdevname/tests/test_biosdevname.py b/repos/system_upgrade/common/actors/biosdevname/tests/test_biosdevname.py
|
||||
index 427eea54..3aa8c614 100644
|
||||
--- a/repos/system_upgrade/common/actors/biosdevname/tests/test_biosdevname.py
|
||||
+++ b/repos/system_upgrade/common/actors/biosdevname/tests/test_biosdevname.py
|
||||
@@ -59,50 +59,35 @@ def test_is_vendor_is_not_dell(monkeypatch):
|
||||
assert not biosdevname.is_vendor_dell()
|
||||
|
||||
|
||||
-def test_all_interfaces_biosdevname(monkeypatch):
|
||||
- pci_info = PCIAddress(domain="domain", function="function", bus="bus", device="device")
|
||||
-
|
||||
- interfaces = [
|
||||
- Interface(
|
||||
- name="eth0", mac="mac", vendor="dell", pci_info=pci_info, devpath="path", driver="drv"
|
||||
- )
|
||||
- ]
|
||||
- assert not biosdevname.all_interfaces_biosdevname(interfaces)
|
||||
- interfaces = [
|
||||
- Interface(
|
||||
- name="em0", mac="mac", vendor="dell", pci_info=pci_info, devpath="path", driver="drv"
|
||||
- )
|
||||
- ]
|
||||
- assert biosdevname.all_interfaces_biosdevname(interfaces)
|
||||
- interfaces = [
|
||||
- Interface(
|
||||
- name="p0p22", mac="mac", vendor="dell", pci_info=pci_info, devpath="path", driver="drv"
|
||||
- )
|
||||
- ]
|
||||
- assert biosdevname.all_interfaces_biosdevname(interfaces)
|
||||
-
|
||||
- interfaces = [
|
||||
- Interface(
|
||||
- name="p1p2", mac="mac", vendor="dell", pci_info=pci_info, devpath="path", driver="drv"
|
||||
- ),
|
||||
- Interface(
|
||||
- name="em2", mac="mac", vendor="dell", pci_info=pci_info, devpath="path", driver="drv"
|
||||
- ),
|
||||
- ]
|
||||
- assert biosdevname.all_interfaces_biosdevname(interfaces)
|
||||
-
|
||||
- interfaces = [
|
||||
- Interface(
|
||||
- name="p1p2", mac="mac", vendor="dell", pci_info=pci_info, devpath="path", driver="drv"
|
||||
- ),
|
||||
- Interface(
|
||||
- name="em2", mac="mac", vendor="dell", pci_info=pci_info, devpath="path", driver="drv"
|
||||
- ),
|
||||
- Interface(
|
||||
- name="eth0", mac="mac", vendor="dell", pci_info=pci_info, devpath="path", driver="drv"
|
||||
- ),
|
||||
- ]
|
||||
- assert not biosdevname.all_interfaces_biosdevname(interfaces)
|
||||
+def _gen_ifaces_by_names(names):
|
||||
+ pci = PCIAddress(domain="0000", bus="3e", function="00", device="PCI bridge")
|
||||
+ interfaces = []
|
||||
+ for nic_name in names:
|
||||
+ interfaces.append(Interface(
|
||||
+ name=nic_name,
|
||||
+ devpath="path",
|
||||
+ driver="drv",
|
||||
+ mac="52:54:00:0b:4a:6d",
|
||||
+ pci_info=pci,
|
||||
+ vendor="dell",
|
||||
+ ))
|
||||
+ return interfaces
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(("interface_names", "expected_result"), (
|
||||
+ (["eth0"], False),
|
||||
+ (["preem0"], False),
|
||||
+ (["em0post"], False),
|
||||
+ (["prep0p22"], False),
|
||||
+ (["p0p22post"], False),
|
||||
+ (["em0"], True),
|
||||
+ (["p0p22"], True),
|
||||
+ (["em2", "p1p22"], True),
|
||||
+ (["p1p2", "em2", "eth0"], False)
|
||||
+))
|
||||
+def test_all_interfaces_biosdevname(interface_names, expected_result):
|
||||
+ interfaces = _gen_ifaces_by_names(interface_names)
|
||||
+ assert biosdevname.all_interfaces_biosdevname(interfaces) == expected_result
|
||||
|
||||
|
||||
def test_enable_biosdevname(monkeypatch):
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From 81a3297516fbbd120b0fb870de36f1a1b290dd21 Mon Sep 17 00:00:00 2001
|
||||
From: Jarek Prokop <jprokop@redhat.com>
|
||||
Date: Wed, 6 Nov 2024 15:21:14 +0100
|
||||
Subject: [PATCH 29/40] Expand on the actor docstring for the el8->el9
|
||||
rubygem-irb symlink fix.
|
||||
|
||||
In RHEL 10, the directory is a regular directory again.
|
||||
|
||||
The 2 actors are separate over creating a common solution for both.
|
||||
Expand in the docstring on the reason for the el8->el9 actor to
|
||||
differentiate them apart.
|
||||
---
|
||||
.../actors/registerrubyirbadjustment/actor.py | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/actor.py b/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/actor.py
|
||||
index ac4d1e6f..a33d8831 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/actor.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/registerrubyirbadjustment/actor.py
|
||||
@@ -5,7 +5,16 @@ from leapp.tags import FactsPhaseTag, IPUWorkflowTag
|
||||
|
||||
class RegisterRubyIRBAdjustment(Actor):
|
||||
"""
|
||||
- Registers a workaround which will adjust the Ruby IRB directories during the upgrade.
|
||||
+ Register a workaround to allow rubygem-irb's directory -> symlink conversion.
|
||||
+
|
||||
+ The /usr/share/ruby/irb has been moved from a directory to a symlink
|
||||
+ in RHEL 9 and this conversion was not handled on RPM level.
|
||||
+ This leads to DNF reporting package file conflicts when a major upgrade
|
||||
+ is attempted and rubygem-irb (or ruby-irb) is installed.
|
||||
+
|
||||
+ Register "handlerubyirbsymlink" script that removes the directory prior
|
||||
+ to DNF upgrade and allows it to create the expected symlink in place of
|
||||
+ the removed directory.
|
||||
"""
|
||||
|
||||
name = 'register_ruby_irb_adjustment'
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,340 +0,0 @@
|
||||
From 8d8774c34518a6269d56f100c2fc312ec0bbbde1 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Fri, 13 Mar 2026 16:15:20 +0100
|
||||
Subject: [PATCH 29/44] persistentnetnamesdisable: refactoring + fix ethX
|
||||
detection
|
||||
|
||||
The original check of ethX interfaces was buggy as it detected all
|
||||
interfaces with the eth[0-9] substring:
|
||||
* eth0
|
||||
* preeth0
|
||||
* eth0post
|
||||
...
|
||||
The check has been corrected to search just for ethX kernel names,
|
||||
skipping NIC names with additional prefixes or suffixes. Added test
|
||||
for the ethX_count function. Tests have been slightly refactored to
|
||||
minimize planned changes in the Interface model.
|
||||
|
||||
Also the actor has been originally executed in incorrect phase.
|
||||
Moving the actor to CheckPhase where it should be. Also I refactorred
|
||||
the actor a little bit, moving the code to the private library to
|
||||
follow current best practices.
|
||||
|
||||
Jira: RHEL-3370
|
||||
---
|
||||
.../actors/persistentnetnamesdisable/actor.py | 63 +----------
|
||||
.../libraries/persistentnetnamesdisable.py | 75 +++++++++++++
|
||||
.../tests/test_persistentnetnamesdisable.py | 104 ++++++++++++++----
|
||||
3 files changed, 163 insertions(+), 79 deletions(-)
|
||||
create mode 100644 repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py b/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py
|
||||
index b0182982..15c43141 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py
|
||||
@@ -1,11 +1,8 @@
|
||||
-import re
|
||||
-
|
||||
-from leapp import reporting
|
||||
from leapp.actors import Actor
|
||||
-from leapp.libraries.common.config.version import get_target_major_version
|
||||
+from leapp.libraries.actor import persistentnetnamesdisable
|
||||
from leapp.models import KernelCmdlineArg, PersistentNetNamesFacts
|
||||
-from leapp.reporting import create_report, Report
|
||||
-from leapp.tags import FactsPhaseTag, IPUWorkflowTag
|
||||
+from leapp.reporting import Report
|
||||
+from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
|
||||
|
||||
class PersistentNetNamesDisable(Actor):
|
||||
@@ -16,57 +13,7 @@ class PersistentNetNamesDisable(Actor):
|
||||
name = 'persistentnetnamesdisable'
|
||||
consumes = (PersistentNetNamesFacts,)
|
||||
produces = (KernelCmdlineArg, Report)
|
||||
- tags = (FactsPhaseTag, IPUWorkflowTag)
|
||||
-
|
||||
- @staticmethod
|
||||
- def ethX_count(interfaces):
|
||||
- ethX = re.compile('eth[0-9]+')
|
||||
- count = 0
|
||||
-
|
||||
- for i in interfaces:
|
||||
- if ethX.match(i.name):
|
||||
- count = count + 1
|
||||
- return count
|
||||
-
|
||||
- @staticmethod
|
||||
- def single_eth0(interfaces):
|
||||
- return len(interfaces) == 1 and interfaces[0].name == 'eth0'
|
||||
-
|
||||
- def disable_persistent_naming(self):
|
||||
- self.log.info("Single eth0 network interface detected. Appending 'net.ifnames=0' to RHEL-8 kernel commandline")
|
||||
- self.produce(KernelCmdlineArg(**{'key': 'net.ifnames', 'value': '0'}))
|
||||
+ tags = (ChecksPhaseTag, IPUWorkflowTag)
|
||||
|
||||
def process(self):
|
||||
- interfaces = next(self.consume(PersistentNetNamesFacts)).interfaces
|
||||
-
|
||||
- if self.single_eth0(interfaces):
|
||||
- self.disable_persistent_naming()
|
||||
- elif len(interfaces) > 1 and self.ethX_count(interfaces) > 0:
|
||||
- report_entries = [
|
||||
- reporting.Title('Unsupported network configuration'),
|
||||
- reporting.Summary(
|
||||
- 'Detected multiple physical network interfaces where one or more use kernel naming (e.g. eth0). '
|
||||
- 'Upgrade process can not continue because stability of names can not be guaranteed. '
|
||||
- ),
|
||||
- reporting.ExternalLink(
|
||||
- title='How to Perform an In-Place Upgrade when Using Kernel-Assigned NIC Names',
|
||||
- url='https://access.redhat.com/solutions/4067471'
|
||||
- ),
|
||||
- reporting.Remediation(
|
||||
- hint='Rename all ethX network interfaces following the attached KB solution article.'
|
||||
- ),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.NETWORK]),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR])
|
||||
- ]
|
||||
-
|
||||
- if get_target_major_version() == '9':
|
||||
- report_entries.append(
|
||||
- reporting.ExternalLink(
|
||||
- title='RHEL 8 to RHEL 9: inplace upgrade fails at '
|
||||
- '"Network configuration for unsupported device types detected"',
|
||||
- url='https://access.redhat.com/solutions/7009239'
|
||||
- )
|
||||
- )
|
||||
-
|
||||
- create_report(report_entries)
|
||||
+ persistentnetnamesdisable.process()
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py b/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py
|
||||
new file mode 100644
|
||||
index 00000000..0d1a90e2
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py
|
||||
@@ -0,0 +1,75 @@
|
||||
+import re
|
||||
+
|
||||
+from leapp import reporting
|
||||
+from leapp.libraries.common.config.version import get_target_major_version
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import KernelCmdlineArg, PersistentNetNamesFacts
|
||||
+from leapp.reporting import create_report
|
||||
+
|
||||
+
|
||||
+def ethX_count(interfaces):
|
||||
+ """
|
||||
+ Count how many network interfaces with ethX naming is present.
|
||||
+ """
|
||||
+ ethX = re.compile('^eth[0-9]+$')
|
||||
+ count = 0
|
||||
+
|
||||
+ for i in interfaces:
|
||||
+ if ethX.match(i.name):
|
||||
+ count = count + 1
|
||||
+ return count
|
||||
+
|
||||
+
|
||||
+def single_eth0(interfaces):
|
||||
+ return len(interfaces) == 1 and interfaces[0].name == 'eth0'
|
||||
+
|
||||
+
|
||||
+def disable_persistent_naming():
|
||||
+ api.current_logger().info(
|
||||
+ "Single eth0 network interface detected."
|
||||
+ " Appending 'net.ifnames=0' for the target system kernel commandline"
|
||||
+ )
|
||||
+ api.produce(KernelCmdlineArg(**{'key': 'net.ifnames', 'value': '0'}))
|
||||
+
|
||||
+
|
||||
+def report_ethX_ifaces():
|
||||
+ report_entries = [
|
||||
+ reporting.Title('Unsupported network configuration'),
|
||||
+ reporting.Summary(
|
||||
+ 'Detected multiple physical network interfaces where one or more'
|
||||
+ ' use kernel naming (e.g. eth0). Upgrade process cannot continue'
|
||||
+ ' because stability of names can not be guaranteed.'
|
||||
+ ),
|
||||
+ reporting.ExternalLink(
|
||||
+ title='How to Perform an In-Place Upgrade when Using Kernel-Assigned NIC Names',
|
||||
+ url='https://access.redhat.com/solutions/4067471'
|
||||
+ ),
|
||||
+ reporting.Remediation(
|
||||
+ hint='Rename all ethX network interfaces following the attached KB solution article.'
|
||||
+ ),
|
||||
+ reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Groups([reporting.Groups.NETWORK]),
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR])
|
||||
+ ]
|
||||
+
|
||||
+ if get_target_major_version() == '9':
|
||||
+ report_entries.append(
|
||||
+ reporting.ExternalLink(
|
||||
+ title='RHEL 8 to RHEL 9: inplace upgrade fails at '
|
||||
+ '"Network configuration for unsupported device types detected"',
|
||||
+ url='https://access.redhat.com/solutions/7009239'
|
||||
+ )
|
||||
+ )
|
||||
+
|
||||
+ create_report(report_entries)
|
||||
+
|
||||
+
|
||||
+def process():
|
||||
+ interfaces = next(api.consume(PersistentNetNamesFacts)).interfaces
|
||||
+
|
||||
+ if single_eth0(interfaces):
|
||||
+ disable_persistent_naming()
|
||||
+ return
|
||||
+
|
||||
+ if len(interfaces) > 1 and ethX_count(interfaces):
|
||||
+ report_ethX_ifaces()
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py b/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py
|
||||
index 95b695c0..2369e80f 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py
|
||||
@@ -1,17 +1,53 @@
|
||||
import pytest
|
||||
|
||||
-from leapp.libraries.common.config import version
|
||||
+from leapp.libraries.actor import persistentnetnamesdisable
|
||||
from leapp.models import Interface, KernelCmdlineArg, PCIAddress, PersistentNetNamesFacts
|
||||
from leapp.reporting import Report
|
||||
from leapp.snactor.fixture import current_actor_context
|
||||
from leapp.utils.report import is_inhibitor
|
||||
|
||||
|
||||
+def _gen_ifaces_by_names(names):
|
||||
+ pci = PCIAddress(domain="0000", bus="3e", function="00", device="PCI bridge")
|
||||
+ interfaces = []
|
||||
+ for nic_name in names:
|
||||
+ interfaces.append(Interface(
|
||||
+ name=nic_name,
|
||||
+ devpath="/devices/platform/usb/cdc-wdm0",
|
||||
+ driver="pcieport",
|
||||
+ mac="52:54:00:0b:4a:6d",
|
||||
+ pci_info=pci,
|
||||
+ vendor="redhat",
|
||||
+ ))
|
||||
+ return interfaces
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(('interfaces', 'exp_result'), (
|
||||
+ (_gen_ifaces_by_names(['eno1', 'eno2', 'myfoo00', 'nicname']), 0),
|
||||
+ (_gen_ifaces_by_names(['preeth0', 'eth2post', 'preeth0post']), 0),
|
||||
+ (_gen_ifaces_by_names(['eth0']), 1),
|
||||
+ (_gen_ifaces_by_names(['eth0', 'eth1', 'eth01', 'eth4980']), 4),
|
||||
+ (_gen_ifaces_by_names(['myeth0', 'eth0', 'something']), 1),
|
||||
+))
|
||||
+def test_ethX_count(interfaces, exp_result):
|
||||
+ """
|
||||
+ Test the correct detection of ethX interfaces.
|
||||
+
|
||||
+ It tests the bug causing https://issues.redhat.com/browse/RHEL-3370
|
||||
+ """
|
||||
+ assert persistentnetnamesdisable.ethX_count(interfaces) == exp_result
|
||||
+
|
||||
+
|
||||
def test_actor_single_eth0(current_actor_context):
|
||||
pci = PCIAddress(domain="0000", bus="3e", function="00", device="PCI bridge")
|
||||
- interface = [Interface(name="eth0", mac="52:54:00:0b:4a:6d", vendor="redhat",
|
||||
- driver="pcieport", pci_info=pci,
|
||||
- devpath="/devices/platform/usb/cdc-wdm0")]
|
||||
+ interface = [Interface(
|
||||
+ name="eth0",
|
||||
+ mac="52:54:00:0b:4a:6d",
|
||||
+ vendor="redhat",
|
||||
+ driver="pcieport",
|
||||
+ pci_info=pci,
|
||||
+ devpath="/devices/platform/usb/cdc-wdm0"
|
||||
+ )]
|
||||
current_actor_context.feed(PersistentNetNamesFacts(interfaces=interface))
|
||||
current_actor_context.run()
|
||||
assert not current_actor_context.consume(Report)
|
||||
@@ -21,15 +57,25 @@ def test_actor_single_eth0(current_actor_context):
|
||||
'target_version', ['9', '10']
|
||||
)
|
||||
def test_actor_more_ethX(monkeypatch, current_actor_context, target_version):
|
||||
- monkeypatch.setattr(version, 'get_target_major_version', lambda: target_version)
|
||||
+ monkeypatch.setattr(persistentnetnamesdisable, 'get_target_major_version', lambda: target_version)
|
||||
pci1 = PCIAddress(domain="0000", bus="3e", function="00", device="PCI bridge")
|
||||
pci2 = PCIAddress(domain="0000", bus="3d", function="00", device="Serial controller")
|
||||
- interface = [Interface(name="eth0", mac="52:54:00:0b:4a:6d", vendor="redhat",
|
||||
- driver="pcieport", pci_info=pci1,
|
||||
- devpath="/devices/platform/usb/cdc-wdm0"),
|
||||
- Interface(name="eth1", mac="52:54:00:0b:4a:6a", vendor="redhat",
|
||||
- driver="serial", pci_info=pci2,
|
||||
- devpath="/devices/hidraw/hidraw0")]
|
||||
+ interface = [
|
||||
+ Interface(
|
||||
+ name="eth0",
|
||||
+ mac="52:54:00:0b:4a:6d",
|
||||
+ vendor="redhat",
|
||||
+ driver="pcieport",
|
||||
+ pci_info=pci1,
|
||||
+ devpath="/devices/platform/usb/cdc-wdm0"),
|
||||
+ Interface(
|
||||
+ name="eth1",
|
||||
+ mac="52:54:00:0b:4a:6a",
|
||||
+ vendor="redhat",
|
||||
+ driver="serial",
|
||||
+ pci_info=pci2,
|
||||
+ devpath="/devices/hidraw/hidraw0")
|
||||
+ ]
|
||||
current_actor_context.feed(PersistentNetNamesFacts(interfaces=interface))
|
||||
current_actor_context.run()
|
||||
|
||||
@@ -50,9 +96,15 @@ def test_actor_more_ethX(monkeypatch, current_actor_context, target_version):
|
||||
|
||||
def test_actor_single_int_not_ethX(current_actor_context):
|
||||
pci = PCIAddress(domain="0000", bus="3e", function="00", device="PCI bridge")
|
||||
- interface = [Interface(name="tap0", mac="52:54:00:0b:4a:60", vendor="redhat",
|
||||
- driver="pcieport", pci_info=pci,
|
||||
- devpath="/devices/platform/usb/cdc-wdm0")]
|
||||
+ interface = [
|
||||
+ Interface(
|
||||
+ name="tap0",
|
||||
+ mac="52:54:00:0b:4a:60",
|
||||
+ vendor="redhat",
|
||||
+ driver="pcieport",
|
||||
+ pci_info=pci,
|
||||
+ devpath="/devices/platform/usb/cdc-wdm0")
|
||||
+ ]
|
||||
current_actor_context.feed(PersistentNetNamesFacts(interfaces=interface))
|
||||
current_actor_context.run()
|
||||
assert not current_actor_context.consume(Report)
|
||||
@@ -62,15 +114,25 @@ def test_actor_single_int_not_ethX(current_actor_context):
|
||||
'target_version', ['9', '10']
|
||||
)
|
||||
def test_actor_ethX_and_not_ethX(monkeypatch, current_actor_context, target_version):
|
||||
- monkeypatch.setattr(version, 'get_target_major_version', lambda: target_version)
|
||||
+ monkeypatch.setattr(persistentnetnamesdisable, 'get_target_major_version', lambda: target_version)
|
||||
pci1 = PCIAddress(domain="0000", bus="3e", function="00", device="PCI bridge")
|
||||
pci2 = PCIAddress(domain="0000", bus="3d", function="00", device="Serial controller")
|
||||
- interface = [Interface(name="virbr0", mac="52:54:00:0b:4a:6d", vendor="redhat",
|
||||
- driver="pcieport", pci_info=pci1,
|
||||
- devpath="/devices/platform/usb/cdc-wdm0"),
|
||||
- Interface(name="eth0", mac="52:54:00:0b:4a:6a", vendor="redhat",
|
||||
- driver="serial", pci_info=pci2,
|
||||
- devpath="/devices/hidraw/hidraw0")]
|
||||
+ interface = [
|
||||
+ Interface(
|
||||
+ name="virbr0",
|
||||
+ mac="52:54:00:0b:4a:6d",
|
||||
+ vendor="redhat",
|
||||
+ driver="pcieport",
|
||||
+ pci_info=pci1,
|
||||
+ devpath="/devices/platform/usb/cdc-wdm0"),
|
||||
+ Interface(
|
||||
+ name="eth0",
|
||||
+ mac="52:54:00:0b:4a:6a",
|
||||
+ vendor="redhat",
|
||||
+ driver="serial",
|
||||
+ pci_info=pci2,
|
||||
+ devpath="/devices/hidraw/hidraw0")
|
||||
+ ]
|
||||
current_actor_context.feed(PersistentNetNamesFacts(interfaces=interface))
|
||||
current_actor_context.run()
|
||||
assert current_actor_context.consume(Report)
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -1,518 +0,0 @@
|
||||
From cdbb91156d1b87883523eed476c9a5d16b4b4e20 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Wed, 21 Feb 2024 20:55:54 +0100
|
||||
Subject: [PATCH 30/44] Fix scan of net interfaces: non-PCI, conflicting,
|
||||
broken
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Non-PCI network devices (present usually on IBM Z architecture)
|
||||
does not have ID_VENDOR_ID attribute and also there is nothing
|
||||
we could put into Interface.pci_info about them.
|
||||
For such devices:
|
||||
* set empty string for Interface.vendor field
|
||||
* and None value for pci_info.
|
||||
The Interface model has been updated, allowing None value for
|
||||
pci_info field.
|
||||
|
||||
Also some interfaces do not have to be "managed" by udev or can
|
||||
provide incomplete data. This can happen e.g. in situations when
|
||||
udev want to assign a NIC name that is already used by another
|
||||
network interface. Such an interface stays with kernel name (ethX)
|
||||
and udev DB contains only elementary information about it. This
|
||||
led originally to a skip of the interface during system scanning
|
||||
by leapp actors and such systems bypassed checks for presence of
|
||||
ethX NIC names later. Usually such interfaces have been renamed after
|
||||
the upgrade (either to a new non-ethX name, or they had a different
|
||||
ethX value) which led to another issues.
|
||||
|
||||
The new solution requires just bare-minimum details to be always
|
||||
present (like NIC name and device path; if missing, the skip is used
|
||||
again). For other values we set an empty strings if missing.
|
||||
|
||||
Tests have been updated and extended to cover new changes, using
|
||||
mainly real input data collected from affected systems.
|
||||
|
||||
Jira: RHEL-22371, RHEL-72140
|
||||
|
||||
Co-authored-by: Michal Hečko <michal.sk.com@gmail.com>
|
||||
---
|
||||
.../tests/test_persistentnetnames.py | 5 +
|
||||
.../tests/test_persistentnetnamesinitramfs.py | 6 +
|
||||
.../common/libraries/persistentnetnames.py | 35 ++-
|
||||
.../tests/test_persistentnetnames_library.py | 243 ++++++++++++++++--
|
||||
.../common/models/persistentnetnamesfacts.py | 57 +++-
|
||||
5 files changed, 314 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnames/tests/test_persistentnetnames.py b/repos/system_upgrade/common/actors/persistentnetnames/tests/test_persistentnetnames.py
|
||||
index ffea5983..a47eeabe 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnames/tests/test_persistentnetnames.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnames/tests/test_persistentnetnames.py
|
||||
@@ -32,6 +32,11 @@ class interfaces_mocked:
|
||||
|
||||
@pytest.mark.parametrize('count', [0, 1, 8, 256])
|
||||
def test_run(monkeypatch, current_actor_context, count):
|
||||
+ """
|
||||
+ Basic test of interface scanner actor
|
||||
+
|
||||
+ Full testing of underlying function is covered in tests of common library.
|
||||
+ """
|
||||
monkeypatch.setattr(persistentnetnames, 'interfaces', interfaces_mocked(count))
|
||||
current_actor_context.run()
|
||||
assert len(current_actor_context.consume(PersistentNetNamesFacts)[0].interfaces) == count
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesinitramfs/tests/test_persistentnetnamesinitramfs.py b/repos/system_upgrade/common/actors/persistentnetnamesinitramfs/tests/test_persistentnetnamesinitramfs.py
|
||||
index f149502b..5605af4b 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesinitramfs/tests/test_persistentnetnamesinitramfs.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesinitramfs/tests/test_persistentnetnamesinitramfs.py
|
||||
@@ -32,6 +32,12 @@ class interfaces_mocked:
|
||||
|
||||
@pytest.mark.parametrize('count', [0, 1, 8, 256])
|
||||
def test_run(monkeypatch, current_actor_context, count):
|
||||
+ """
|
||||
+ Basic functionality test.
|
||||
+
|
||||
+ The full testing of the underlying scanner function is covered by the common
|
||||
+ library.
|
||||
+ """
|
||||
monkeypatch.setattr(persistentnetnames, 'interfaces', interfaces_mocked(count))
|
||||
current_actor_context.run()
|
||||
assert len(current_actor_context.consume(PersistentNetNamesFactsInitramfs)[0].interfaces) == count
|
||||
diff --git a/repos/system_upgrade/common/libraries/persistentnetnames.py b/repos/system_upgrade/common/libraries/persistentnetnames.py
|
||||
index 7fdf7eaa..48dee5f8 100644
|
||||
--- a/repos/system_upgrade/common/libraries/persistentnetnames.py
|
||||
+++ b/repos/system_upgrade/common/libraries/persistentnetnames.py
|
||||
@@ -41,16 +41,41 @@ def interfaces():
|
||||
try:
|
||||
attrs['name'] = dev.sys_name
|
||||
attrs['devpath'] = dev.device_path
|
||||
- attrs['driver'] = dev['ID_NET_DRIVER']
|
||||
- attrs['vendor'] = dev['ID_VENDOR_ID']
|
||||
- attrs['pci_info'] = PCIAddress(**pci_info(dev['ID_PATH']))
|
||||
- attrs['mac'] = dev.attributes.get('address')
|
||||
+
|
||||
+ # can be missing when the interface is not "managed" by udev
|
||||
+ # TODO(pstodulk): check the MAC, I think that that one should be
|
||||
+ # actually always in DB.
|
||||
+ attrs['driver'] = dev.get('ID_NET_DRIVER', '')
|
||||
+ attrs['mac'] = dev.attributes.get('address', '')
|
||||
if isinstance(attrs['mac'], bytes):
|
||||
attrs['mac'] = attrs['mac'].decode()
|
||||
+
|
||||
+ # pci info is not provided for cards that do not use PCI bus,
|
||||
+ # also it can be missing if the interface is not "managed" by udev.
|
||||
+ # Also vendor can be provided only for cards on PCI bus.
|
||||
+ attrs['vendor'] = dev.get('ID_VENDOR_ID', '')
|
||||
+ attrs['pci_info'] = None # default for non-PCI card
|
||||
+ if dev.get('ID_PATH', '').startswith('pci-'):
|
||||
+ attrs['pci_info'] = PCIAddress(**pci_info(dev['ID_PATH']))
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
# FIXME(msekleta): We should probably handle errors more granularly
|
||||
# Maybe we should inhibit upgrade process at this point
|
||||
- api.current_logger().warning('Failed to gather information about network interface: %s', e)
|
||||
+ net_name = attrs.get('name', 'unknown-interface')
|
||||
+ api.current_logger().warning(
|
||||
+ 'Failed to gather information about network interface %s: "%s"',
|
||||
+ net_name, str(e)
|
||||
+ )
|
||||
+ # NOTE(pstodulk): skipping the interface as it's really broken
|
||||
+ # or unknown from the code in leapp-repository pov and another
|
||||
+ # processing would lead now to a broken upgrades.
|
||||
+ # Other values that are usually expected but can be missing
|
||||
+ # in some situations are covered and do not raise this exception.
|
||||
continue
|
||||
|
||||
+ if not all([attrs['driver'], attrs['mac']]):
|
||||
+ api.current_logger().warning(
|
||||
+ 'Information in udev about %s network interface is incomplete.',
|
||||
+ attrs['name']
|
||||
+ )
|
||||
+
|
||||
yield Interface(**attrs)
|
||||
diff --git a/repos/system_upgrade/common/libraries/tests/test_persistentnetnames_library.py b/repos/system_upgrade/common/libraries/tests/test_persistentnetnames_library.py
|
||||
index 74aa08fa..b45863d9 100644
|
||||
--- a/repos/system_upgrade/common/libraries/tests/test_persistentnetnames_library.py
|
||||
+++ b/repos/system_upgrade/common/libraries/tests/test_persistentnetnames_library.py
|
||||
@@ -1,57 +1,252 @@
|
||||
+import pytest
|
||||
+
|
||||
from leapp.libraries.common import persistentnetnames
|
||||
from leapp.libraries.common.testutils import produce_mocked
|
||||
from leapp.libraries.stdlib import api
|
||||
+from leapp.models import PCIAddress
|
||||
|
||||
|
||||
-class AttributesTest:
|
||||
- def __init__(self):
|
||||
- self.attributes = {
|
||||
- 'address': b'fa:16:3e:cd:26:5a'
|
||||
- }
|
||||
+class AttributesMocked:
|
||||
+ def __init__(self, attributes):
|
||||
+ self._attributes = attributes
|
||||
|
||||
- def get(self, attribute):
|
||||
- if attribute in self.attributes:
|
||||
- return self.attributes[attribute]
|
||||
- raise KeyError
|
||||
+ def get(self, key, default=None):
|
||||
+ return self._attributes.get(key, default)
|
||||
|
||||
|
||||
-class DeviceTest:
|
||||
- def __init__(self):
|
||||
- self.dict_data = {
|
||||
- 'ID_NET_DRIVER': 'virtio_net',
|
||||
- 'ID_VENDOR_ID': '0x1af4',
|
||||
- 'ID_PATH': 'pci-0000:00:03.0',
|
||||
- }
|
||||
+class DeviceMocked:
|
||||
+ def __init__(self, properties, attributes):
|
||||
+ self.dict_data = properties
|
||||
+ self._attributes = attributes
|
||||
|
||||
def __getitem__(self, key):
|
||||
+ return self.dict_data[key]
|
||||
+
|
||||
+ def get(self, key, default=None):
|
||||
if key in self.dict_data:
|
||||
return self.dict_data[key]
|
||||
- raise KeyError
|
||||
+ return default
|
||||
|
||||
@property
|
||||
def sys_name(self):
|
||||
- return 'eth'
|
||||
+ return self.dict_data['INTERFACE']
|
||||
|
||||
@property
|
||||
def device_path(self):
|
||||
- return '/devices/pci0000:00/0000:00:03.0/virtio0/net/eth0'
|
||||
+ return self.dict_data['DEVPATH']
|
||||
|
||||
@property
|
||||
def attributes(self):
|
||||
- return AttributesTest()
|
||||
+ return AttributesMocked(self._attributes)
|
||||
+
|
||||
|
||||
+@pytest.mark.parametrize('input_mac', ('fa:16:3e:cd:26:5a', b'fa:16:3e:cd:26:5a'))
|
||||
+def test_getting_interfaces_complete_good(monkeypatch, input_mac):
|
||||
+ """
|
||||
+ Detailed parsing of physical net interface with complete data
|
||||
+ """
|
||||
+ def mocked_physical_interfaces():
|
||||
+ properties = {
|
||||
+ 'CURRENT_TAGS': ':systemd:',
|
||||
+ 'DEVPATH': '/devices/pci0000:17/0000:17:02.0/0000:19:00.0/net/eno3',
|
||||
+ 'ID_BUS': 'pci',
|
||||
+ 'ID_MM_CANDIDATE': '1',
|
||||
+ 'ID_MODEL_FROM_DATABASE': 'NetXtreme BCM5720 Gigabit Ethernet PCIe',
|
||||
+ 'ID_MODEL_ID': '0x165f',
|
||||
+ 'ID_NET_DRIVER': 'tg3',
|
||||
+ 'ID_NET_LABEL_ONBOARD': 'NIC3',
|
||||
+ 'ID_NET_LINK_FILE': '/usr/lib/systemd/network/99-default.link',
|
||||
+ 'ID_NET_NAME': 'eno3',
|
||||
+ 'ID_NET_NAME_MAC': 'enx34735a9920fe',
|
||||
+ 'ID_NET_NAME_ONBOARD': 'eno3',
|
||||
+ 'ID_NET_NAME_PATH': 'enp25s0f0',
|
||||
+ 'ID_NET_NAMING_SCHEME': 'rhel-9.0',
|
||||
+ 'ID_OUI_FROM_DATABASE': 'Dell Inc.',
|
||||
+ 'ID_PATH': 'pci-0000:19:00.0',
|
||||
+ 'ID_PATH_TAG': 'pci-0000_19_00_0',
|
||||
+ 'ID_PCI_CLASS_FROM_DATABASE': 'Network controller',
|
||||
+ 'ID_PCI_SUBCLASS_FROM_DATABASE': 'Ethernet controller',
|
||||
+ 'ID_VENDOR_FROM_DATABASE': 'Broadcom Inc. and subsidiaries',
|
||||
+ 'ID_VENDOR_ID': '0x14e4',
|
||||
+ 'IFINDEX': '4',
|
||||
+ 'INTERFACE': 'eno3',
|
||||
+ 'SUBSYSTEM': 'net',
|
||||
+ 'SYSTEMD_ALIAS': '/sys/subsystem/net/devices/eno3',
|
||||
+ 'TAGS': ':systemd:',
|
||||
+ 'USEC_INITIALIZED': '16690226'
|
||||
+ }
|
||||
+ attributes = {
|
||||
+ 'address': input_mac
|
||||
+ }
|
||||
+ return [DeviceMocked(properties, attributes)]
|
||||
+
|
||||
+ monkeypatch.setattr(persistentnetnames, 'physical_interfaces', mocked_physical_interfaces)
|
||||
+ monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
+
|
||||
+ interface = next(persistentnetnames.interfaces())
|
||||
|
||||
-def provide_test_interfaces():
|
||||
- return [DeviceTest()]
|
||||
+ assert interface.name == 'eno3'
|
||||
+ assert interface.devpath == '/devices/pci0000:17/0000:17:02.0/0000:19:00.0/net/eno3'
|
||||
+ assert interface.driver == 'tg3'
|
||||
+ assert interface.vendor == '0x14e4'
|
||||
+ assert interface.mac == 'fa:16:3e:cd:26:5a'
|
||||
+ assert interface.pci_info == PCIAddress(
|
||||
+ domain='0000',
|
||||
+ bus='19',
|
||||
+ device='00',
|
||||
+ function='0'
|
||||
+ )
|
||||
|
||||
|
||||
-def test_getting_interfaces(monkeypatch):
|
||||
- monkeypatch.setattr(persistentnetnames, 'physical_interfaces', provide_test_interfaces)
|
||||
+def test_getting_interfaces_complete_good_roce(monkeypatch):
|
||||
+ """
|
||||
+ ROCE net interface parsing
|
||||
+ """
|
||||
+ def mocked_physical_interfaces():
|
||||
+ properties = {
|
||||
+ 'CURRENT_TAGS': ':systemd:',
|
||||
+ 'DEVPATH': '/devices/pci0201:00/0201:00:00.0/net/eno513',
|
||||
+ 'ID_BUS': 'pci',
|
||||
+ 'ID_MODEL_FROM_DATABASE': 'ConnectX Family mlx5Gen Virtual Function',
|
||||
+ 'ID_MODEL_ID': '0x101e',
|
||||
+ 'ID_NET_DRIVER': 'mlx5_core',
|
||||
+ 'ID_NET_LINK_FILE': '/etc/systemd/network/10-anaconda-ifname-eno513.link',
|
||||
+ 'ID_NET_NAME': 'eno513',
|
||||
+ 'ID_NET_NAME_MAC': 'enx2219aef66069',
|
||||
+ 'ID_NET_NAME_ONBOARD': 'eno513',
|
||||
+ 'ID_NET_NAME_PATH': 'enP513p0s0',
|
||||
+ 'ID_NET_NAME_SLOT': 'ens5912',
|
||||
+ 'ID_NET_NAMING_SCHEME': 'rhel-9.0',
|
||||
+ 'ID_PATH': 'pci-0201:00:00.0',
|
||||
+ 'ID_PATH_TAG': 'pci-0201_00_00_0',
|
||||
+ 'ID_PCI_CLASS_FROM_DATABASE': 'Network controller',
|
||||
+ 'ID_PCI_SUBCLASS_FROM_DATABASE': 'Ethernet controller',
|
||||
+ 'ID_VENDOR_FROM_DATABASE': 'Mellanox Technologies',
|
||||
+ 'ID_VENDOR_ID': '0x15b3',
|
||||
+ 'IFINDEX': '2',
|
||||
+ 'INTERFACE': 'eno513',
|
||||
+ 'SUBSYSTEM': 'net',
|
||||
+ 'SYSTEMD_ALIAS': '/sys/subsystem/net/devices/eno513',
|
||||
+ 'TAGS': ':systemd:',
|
||||
+ 'USEC_INITIALIZED': '26747014'
|
||||
+ }
|
||||
+ attributes = {
|
||||
+ 'address': b'22:19:ae:f6:60:69'
|
||||
+ }
|
||||
+
|
||||
+ return [DeviceMocked(properties, attributes)]
|
||||
+
|
||||
+ monkeypatch.setattr(persistentnetnames, 'physical_interfaces', mocked_physical_interfaces)
|
||||
monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
+
|
||||
interface = next(persistentnetnames.interfaces())
|
||||
+
|
||||
assert interface.name
|
||||
assert interface.devpath
|
||||
assert interface.driver
|
||||
assert interface.vendor
|
||||
+ assert interface.mac
|
||||
assert interface.pci_info
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(('properties', 'attributes'), (
|
||||
+ (
|
||||
+ {
|
||||
+ # artificial data
|
||||
+ 'CURRENT_TAGS': ':systemd:',
|
||||
+ 'DEVPATH': '/devices/whatever/net/eno3',
|
||||
+ 'ID_MM_CANDIDATE': '1',
|
||||
+ 'ID_MODEL_FROM_DATABASE': 'Foo',
|
||||
+ 'ID_MODEL_ID': '0x0000',
|
||||
+ 'ID_NET_DRIVER': 'tg3',
|
||||
+ 'ID_NET_LABEL_ONBOARD': 'NIC3',
|
||||
+ 'ID_NET_LINK_FILE': '/usr/lib/systemd/network/99-default.link',
|
||||
+ 'ID_NET_NAME': 'eno3',
|
||||
+ 'ID_NET_NAME_MAC': 'enx34735a9920fe',
|
||||
+ 'ID_NET_NAME_ONBOARD': 'eno3',
|
||||
+ 'ID_NET_NAME_PATH': 'enp25s0f0',
|
||||
+ 'ID_NET_NAMING_SCHEME': 'rhel-9.0',
|
||||
+ 'ID_OUI_FROM_DATABASE': 'Dell Inc.',
|
||||
+ 'IFINDEX': '4',
|
||||
+ 'INTERFACE': 'eno3',
|
||||
+ 'SUBSYSTEM': 'net',
|
||||
+ 'SYSTEMD_ALIAS': '/sys/subsystem/net/devices/eno3',
|
||||
+ 'TAGS': ':systemd:',
|
||||
+ 'USEC_INITIALIZED': '16690226'
|
||||
+ }, {
|
||||
+ 'address': b'fa:16:3e:cd:26:5a'
|
||||
+ }
|
||||
+ ), (
|
||||
+ {
|
||||
+ 'CURRENT_TAGS': ':systemd:',
|
||||
+ 'DEVPATH': '/devices/css0/0.0.0001/0.0.0001/virtio1/net/enc1',
|
||||
+ 'ID_NET_DRIVER': 'virtio_net',
|
||||
+ 'ID_NET_LINK_FILE': '/usr/lib/systemd/network/99-default.link',
|
||||
+ 'ID_NET_NAME': 'enc1',
|
||||
+ 'ID_NET_NAME_MAC': 'enx001738010124',
|
||||
+ 'ID_NET_NAME_PATH': 'enc1',
|
||||
+ 'ID_NET_NAMING_SCHEME': 'rhel-9.0',
|
||||
+ 'ID_OUI_FROM_DATABASE': 'International Business Machines',
|
||||
+ 'ID_PATH': 'ccw-0.0.0001',
|
||||
+ 'ID_PATH_TAG': 'ccw-0_0_0001',
|
||||
+ 'IFINDEX': '2',
|
||||
+ 'INTERFACE': 'enc1',
|
||||
+ 'SUBSYSTEM': 'net',
|
||||
+ 'SYSTEMD_ALIAS': '/sys/subsystem/net/devices/enc1',
|
||||
+ 'TAGS': ':systemd:',
|
||||
+ 'USEC_INITIALIZED': '3423981'
|
||||
+ }, {
|
||||
+ 'address': b'00:17:38:01:01:24'
|
||||
+ }
|
||||
+ )
|
||||
+))
|
||||
+def test_getting_interfaces_nonpci_good(monkeypatch, properties, attributes):
|
||||
+ """
|
||||
+ Processing of net interface with incomplete data
|
||||
+ """
|
||||
+ def mocked_physical_interfaces():
|
||||
+ return [DeviceMocked(properties, attributes)]
|
||||
+
|
||||
+ monkeypatch.setattr(persistentnetnames, 'physical_interfaces', mocked_physical_interfaces)
|
||||
+ monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
+
|
||||
+ interface = next(persistentnetnames.interfaces())
|
||||
+
|
||||
+ assert interface.name
|
||||
+ assert interface.devpath
|
||||
+ assert interface.driver
|
||||
+ assert not interface.vendor
|
||||
+ assert interface.mac
|
||||
+ assert not interface.pci_info
|
||||
+
|
||||
+
|
||||
+def test_getting_interfaces_incomplete_udev_conflict(monkeypatch):
|
||||
+ """
|
||||
+ Test parsing of conflicting interface.
|
||||
+
|
||||
+ Such interface is not managed by udev and the information we could get
|
||||
+ about it is limited.
|
||||
+ """
|
||||
+ def mocked_physical_interfaces():
|
||||
+ properties = {
|
||||
+ 'DEVPATH': '/devices/pci0000:ae/0000:ae:00.0/0000:af:00.0/0000:b0:04.0/0000:b2:00.1/net/eth3',
|
||||
+ 'IFINDEX': '9',
|
||||
+ 'INTERFACE': 'eth3',
|
||||
+ 'SUBSYSTEM': 'net'
|
||||
+ }
|
||||
+ attributes = {
|
||||
+ 'address': b'fa:16:3e:cd:26:5a'
|
||||
+ }
|
||||
+ return [DeviceMocked(properties, attributes)]
|
||||
+
|
||||
+ monkeypatch.setattr(persistentnetnames, 'physical_interfaces', mocked_physical_interfaces)
|
||||
+ monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
+
|
||||
+ interface = next(persistentnetnames.interfaces())
|
||||
+
|
||||
+ assert interface.name
|
||||
+ assert interface.devpath
|
||||
+ assert not interface.driver
|
||||
+ assert not interface.vendor
|
||||
assert interface.mac
|
||||
+ assert not interface.pci_info
|
||||
diff --git a/repos/system_upgrade/common/models/persistentnetnamesfacts.py b/repos/system_upgrade/common/models/persistentnetnamesfacts.py
|
||||
index 395b26f0..3c71cdcd 100644
|
||||
--- a/repos/system_upgrade/common/models/persistentnetnamesfacts.py
|
||||
+++ b/repos/system_upgrade/common/models/persistentnetnamesfacts.py
|
||||
@@ -4,7 +4,10 @@ from leapp.topics import SystemInfoTopic
|
||||
|
||||
class PCIAddress(Model):
|
||||
"""
|
||||
- TODO: tbd
|
||||
+ Network Interface PCI address.
|
||||
+
|
||||
+ This model should not be produced nor consumed by actors directly.
|
||||
+ It's part of the Interface model.
|
||||
"""
|
||||
topic = SystemInfoTopic
|
||||
|
||||
@@ -16,16 +19,49 @@ class PCIAddress(Model):
|
||||
|
||||
class Interface(Model):
|
||||
"""
|
||||
- TODO: tbd - Interface or NetworkInterface?
|
||||
+ Physical network interface
|
||||
+
|
||||
+ Contains information about a network interface collected from udev.
|
||||
+ Data can be incomplete in case of issues or when the interface is not
|
||||
+ managed by udev.
|
||||
+
|
||||
+ This model should not be produced or consumed by actors directly.
|
||||
+ See PersistentNetNamesFacts or PersistentNetNamesFactsInitramfs.
|
||||
"""
|
||||
topic = SystemInfoTopic
|
||||
|
||||
name = fields.String()
|
||||
+ """
|
||||
+ Name of the interface.
|
||||
+ """
|
||||
+
|
||||
devpath = fields.String()
|
||||
+ """
|
||||
+ Path to the device.
|
||||
+ """
|
||||
+
|
||||
driver = fields.String()
|
||||
+ """
|
||||
+ Network interface driver identifier.
|
||||
+ """
|
||||
+
|
||||
vendor = fields.String()
|
||||
- pci_info = fields.Model(PCIAddress)
|
||||
+ """
|
||||
+ Numeric identifier of the hardware vendor on PCI bus.
|
||||
+ """
|
||||
+
|
||||
+ pci_info = fields.Nullable(fields.Model(PCIAddress))
|
||||
+ """
|
||||
+ Parsed PCI address of the network interface.
|
||||
+
|
||||
+ The value is None if the network interface is not connected via PCI or it is not managed
|
||||
+ by udev.
|
||||
+ """
|
||||
+
|
||||
mac = fields.String()
|
||||
+ """
|
||||
+ MAC address of the network interface.
|
||||
+ """
|
||||
|
||||
|
||||
class PersistentNetNamesFacts(Model):
|
||||
@@ -34,6 +70,9 @@ class PersistentNetNamesFacts(Model):
|
||||
"""
|
||||
topic = SystemInfoTopic
|
||||
interfaces = fields.List(fields.Model(Interface))
|
||||
+ """
|
||||
+ List of network interfaces with information collected from udev.
|
||||
+ """
|
||||
|
||||
|
||||
class PersistentNetNamesFactsInitramfs(PersistentNetNamesFacts):
|
||||
@@ -49,8 +88,17 @@ class RenamedInterface(Model):
|
||||
"""
|
||||
topic = SystemInfoTopic
|
||||
|
||||
+ # TODO(pstodulk) deprecate these fields and replace them by new ones
|
||||
+ # or deprecate the model completely.
|
||||
rhel7_name = fields.String()
|
||||
+ """
|
||||
+ Original interface name.
|
||||
+ """
|
||||
+
|
||||
rhel8_name = fields.String()
|
||||
+ """
|
||||
+ New interface name.
|
||||
+ """
|
||||
|
||||
|
||||
class RenamedInterfaces(Model):
|
||||
@@ -63,3 +111,6 @@ class RenamedInterfaces(Model):
|
||||
topic = SystemInfoTopic
|
||||
|
||||
renamed = fields.List(fields.Model(RenamedInterface))
|
||||
+ """
|
||||
+ The list of renamed interfaces.
|
||||
+ """
|
||||
--
|
||||
2.53.0
|
||||
|
||||
37814
SOURCES/0030-data-update-data-files.patch
Normal file
37814
SOURCES/0030-data-update-data-files.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,56 @@
|
||||
From 89afbe8cb41f874f32acddc1e1696132f3531677 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Fri, 8 Nov 2024 17:40:01 +0100
|
||||
Subject: [PATCH 31/40] Packaging: Require leapp-framework 6.x + update leapp
|
||||
deps
|
||||
|
||||
The leapp actors configuration feature is present since
|
||||
leapp-framework 6.0. Update the dependencies to ensure the correct
|
||||
version of the framework is installed on the system.
|
||||
|
||||
Also, leapp requirements have been updated - requiring python3-PyYAML
|
||||
as it requires YAML parser, bumping leapp-framework-dependencies to 6.
|
||||
Address the change in leapp-deps metapackage to satisfy leapp
|
||||
dependencies during the upgrade process.
|
||||
---
|
||||
packaging/leapp-repository.spec | 2 +-
|
||||
packaging/other_specs/leapp-el7toel8-deps.spec | 3 ++-
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/packaging/leapp-repository.spec b/packaging/leapp-repository.spec
|
||||
index 0d63ba02..570d0df2 100644
|
||||
--- a/packaging/leapp-repository.spec
|
||||
+++ b/packaging/leapp-repository.spec
|
||||
@@ -120,7 +120,7 @@ Requires: leapp-repository-dependencies = %{leapp_repo_deps}
|
||||
|
||||
# IMPORTANT: this is capability provided by the leapp framework rpm.
|
||||
# Check that 'version' instead of the real framework rpm version.
|
||||
-Requires: leapp-framework >= 5.0, leapp-framework < 6
|
||||
+Requires: leapp-framework >= 6.0, leapp-framework < 7
|
||||
|
||||
# Since we provide sub-commands for the leapp utility, we expect the leapp
|
||||
# tool to be installed as well.
|
||||
diff --git a/packaging/other_specs/leapp-el7toel8-deps.spec b/packaging/other_specs/leapp-el7toel8-deps.spec
|
||||
index d9e94faa..2c662a37 100644
|
||||
--- a/packaging/other_specs/leapp-el7toel8-deps.spec
|
||||
+++ b/packaging/other_specs/leapp-el7toel8-deps.spec
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
%define leapp_repo_deps 10
|
||||
-%define leapp_framework_deps 5
|
||||
+%define leapp_framework_deps 6
|
||||
|
||||
# NOTE: the Version contains the %{rhel} macro just for the convenience to
|
||||
# have always upgrade path between newer and older deps packages. So for
|
||||
@@ -112,6 +112,7 @@ Requires: python3
|
||||
Requires: python3-six
|
||||
Requires: python3-setuptools
|
||||
Requires: python3-requests
|
||||
+Requires: python3-PyYAML
|
||||
|
||||
|
||||
%description -n %{ldname}
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,398 +0,0 @@
|
||||
From c60f657713f130d3accee7ceb303d7286b6180d5 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Wed, 18 Mar 2026 17:57:56 +0100
|
||||
Subject: [PATCH 31/44] persistentnetnamesconfig: Deprecate legacy
|
||||
functionality
|
||||
|
||||
The legacy solution to make NIC names persistent during the upgrade
|
||||
is buggy and usually it's not used nowadays. Creation of link files
|
||||
in the legacy solution breaks bonding configuration and also does not
|
||||
handle interfaces in case of InfiniBand and RDMA.
|
||||
|
||||
At this point, we plan to use of net naming scheme mandatory during
|
||||
the upgrade (or at least the only solution for persistent NIC names).
|
||||
Mark following symbols as deprecated:
|
||||
* LEAPP_DISABLE_NET_NAMING_SCHEMES (envar)
|
||||
* LEAPP_NO_NETWORK_RENAMING (envar)
|
||||
* RenamedInterfaces (model)
|
||||
* RenamedInterface (model)
|
||||
|
||||
Also the RenamedInterface model had fields `rhel7_name` & `rhel8_name`,
|
||||
which has not actually correspond to the real state. So the fields
|
||||
have been renamed instantly to `original_name` & `new_name`.
|
||||
|
||||
Also dropping the produce of InitrdInclude message in the actor as
|
||||
the model is deprecated for a long time.
|
||||
|
||||
We could possibly still think about reporting changed interface names,
|
||||
but such a report should happen in the last (FirstBoot) phase when
|
||||
the networking should be already fully initialized. Such a report
|
||||
would be just a check whether net naming scheme works as expected.
|
||||
But it's not considered at this very moment.
|
||||
---
|
||||
docs/source/configuring-ipu/envars.md | 20 +++++++-
|
||||
.../libraries-and-api/deprecations-list.md | 6 ++-
|
||||
.../actors/persistentnetnamesconfig/actor.py | 19 ++++---
|
||||
.../libraries/persistentnetnamesconfig.py | 27 +++++-----
|
||||
.../tests/test_persistentnetnamesconfig.py | 50 ++++++++++---------
|
||||
.../common/models/persistentnetnamesfacts.py | 21 ++++++--
|
||||
6 files changed, 93 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/docs/source/configuring-ipu/envars.md b/docs/source/configuring-ipu/envars.md
|
||||
index 72d00634..9fa37f4f 100644
|
||||
--- a/docs/source/configuring-ipu/envars.md
|
||||
+++ b/docs/source/configuring-ipu/envars.md
|
||||
@@ -6,11 +6,21 @@ Below is a list of the general and development variables available.
|
||||
### General variables
|
||||
|
||||
#### LEAPP_DISABLE_NET_NAMING_SCHEMES
|
||||
-On RHEL 8 to 9 upgrades, by default, net.naming-scheme is used to make network interface names immutable during the upgrade. In this case an extra RPM named `rhel-net-naming-sysattrs` is installed to the target system and target userspace container, providing the definitions of the "profiles" for net.naming-scheme.
|
||||
+The `net.naming-scheme` kernel command line option is used by default to make
|
||||
+network interface names immutable during the upgrade.
|
||||
+In this case an extra RPM named `rhel-net-naming-sysattrs` (or `net-naming-sysattrs`)
|
||||
+is installed to the target system and target userspace container, providing
|
||||
+the definitions of the "profiles" for `net.naming-scheme`.
|
||||
|
||||
-If set to `0`, the "legacy" mechanism is used where leapp writes .link files to prevent interfaces being renamed
|
||||
+If set to `0`, the legacy mechanism is used where leapp writes .link files to prevent interfaces being renamed
|
||||
after booting to post-upgrade system.
|
||||
|
||||
+```{warning}
|
||||
+The variable is deprecated as it is a part of the legacy solution for handling
|
||||
+NIC names during the upgrade. Current supported solution allows only using
|
||||
+the `net.naming-scheme`.
|
||||
+```
|
||||
+
|
||||
#### LEAPP_ENABLE_REPOS
|
||||
Specify repositories (repoids) split by comma, that should be used during the in-place upgrade to the target system. It‘s overwritten automatically in case the --enablerepo option is used. It‘s recommended to use the --enablerepo option instead of the envar.
|
||||
|
||||
@@ -26,6 +36,12 @@ If set to `1`, Leapp does not register the system into Red Hat Lightspeed automa
|
||||
#### LEAPP_NO_NETWORK_RENAMING
|
||||
If set to `1`, the actor responsible to handle NICs names ends without doing anything. The actor usually creates UDEV rules to preserve original NICs in case they are changed. However, in some cases it‘s not wanted and it leads in malfunction network configuration (e.g. in case the bonding is configured on the system). It‘s expected that NICs have to be handled manually if needed.
|
||||
|
||||
+```{warning}
|
||||
+The variable is deprecated as it is a part of the legacy solution for
|
||||
+handling NIC names during the upgrade. Current supported solution allows only
|
||||
+using of the `net.naming-scheme`.
|
||||
+```
|
||||
+
|
||||
##### LEAPP_NO_RHSM
|
||||
If set to `1`, Leapp does not use Red Hat Subscription Management for the upgrade. It‘s equivalent to the --no-rhsm leapp option.
|
||||
|
||||
diff --git a/docs/source/libraries-and-api/deprecations-list.md b/docs/source/libraries-and-api/deprecations-list.md
|
||||
index 679bf489..a074ebc1 100644
|
||||
--- a/docs/source/libraries-and-api/deprecations-list.md
|
||||
+++ b/docs/source/libraries-and-api/deprecations-list.md
|
||||
@@ -13,7 +13,11 @@ framework, see {ref}`deprecation:list of the deprecated functionality in leapp`.
|
||||
Only the versions in which a deprecation has been made are listed.
|
||||
|
||||
## Next release <span style="font-size:0.5em; font-weight:normal">(till TODO date)</span>
|
||||
-- Note: nothing new deprecated yet
|
||||
+- Environment variables
|
||||
+ - **`LEAPP_DISABLE_NET_NAMING_SCHEMES`** - The `net.naming-scheme` kernel argument provides much better alternative to the legacy solution enabled using this variable. Hence the legacy solution is deprecated together with this environment variable.
|
||||
+ - **`LEAPP_NO_NETWORK_RENAMING`** - It becomes obsoleted by the solution based on `net.naming-scheme` which replaces the legacy solution based on created udev link files correcting NIC names during the upgrade.
|
||||
+- Models:
|
||||
+ - **`RenamedInterfaces`** - Information provided in this message is not always complete and it's not used since the `net.naming-scheme` kernel command line argument is set during the upgrade.
|
||||
|
||||
## v0.24.0 <span style="font-size:0.5em; font-weight:normal">(till September 2026)</span>
|
||||
- Shared libraries
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesconfig/actor.py b/repos/system_upgrade/common/actors/persistentnetnamesconfig/actor.py
|
||||
index 2689d837..7a21b43a 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesconfig/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesconfig/actor.py
|
||||
@@ -1,7 +1,6 @@
|
||||
from leapp.actors import Actor
|
||||
from leapp.libraries.actor import persistentnetnamesconfig
|
||||
from leapp.models import (
|
||||
- InitrdIncludes,
|
||||
PersistentNetNamesFacts,
|
||||
PersistentNetNamesFactsInitramfs,
|
||||
RenamedInterfaces,
|
||||
@@ -11,21 +10,27 @@ from leapp.tags import ApplicationsPhaseTag, IPUWorkflowTag
|
||||
from leapp.utils.deprecation import suppress_deprecation
|
||||
|
||||
|
||||
-@suppress_deprecation(InitrdIncludes)
|
||||
+@suppress_deprecation(RenamedInterfaces)
|
||||
class PersistentNetNamesConfig(Actor):
|
||||
"""
|
||||
Generate udev persistent network naming configuration
|
||||
|
||||
- This actor generates systemd-udevd link files for each physical ethernet interface present on RHEL-7
|
||||
- in case we notice that interface name differs on RHEL-8. Link file configuration will assign RHEL-7 version of
|
||||
- a name. Actors produces list of interfaces which changed name between RHEL-7 and RHEL-8.
|
||||
+ NOTE: This actor is deprecated and currently performs described actions
|
||||
+ only if LEAPP_NO_NETWORK_RENAMING != 1 and LEAPP_DISABLE_NET_NAMING_SCHEMES == 1.
|
||||
+
|
||||
+ This actor generates systemd-udevd link files for each physical network
|
||||
+ interface present on the original system if the interface name differs
|
||||
+ on the target OS. Link file configuration will assign original name that has
|
||||
+ been detected on the source OS.
|
||||
+
|
||||
+ Also produce list of interfaces which changed names during the upgrade
|
||||
+ process.
|
||||
"""
|
||||
|
||||
name = 'persistentnetnamesconfig'
|
||||
consumes = (PersistentNetNamesFacts, PersistentNetNamesFactsInitramfs)
|
||||
- produces = (RenamedInterfaces, InitrdIncludes, TargetInitramfsTasks)
|
||||
+ produces = (RenamedInterfaces, TargetInitramfsTasks)
|
||||
tags = (ApplicationsPhaseTag, IPUWorkflowTag)
|
||||
- initrd_files = []
|
||||
|
||||
def process(self):
|
||||
persistentnetnamesconfig.process()
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py b/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
index 189cd4d0..0618f090 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
@@ -2,10 +2,9 @@ import errno
|
||||
import os
|
||||
import re
|
||||
|
||||
-from leapp.libraries.common.config import get_env, version
|
||||
+from leapp.libraries.common.config import get_env
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import (
|
||||
- InitrdIncludes,
|
||||
PersistentNetNamesFacts,
|
||||
PersistentNetNamesFactsInitramfs,
|
||||
RenamedInterface,
|
||||
@@ -37,18 +36,21 @@ def generate_link_file(interface):
|
||||
return link_file
|
||||
|
||||
|
||||
-@suppress_deprecation(InitrdIncludes)
|
||||
+@suppress_deprecation(RenamedInterfaces, RenamedInterface)
|
||||
def process():
|
||||
are_net_schemes_enabled = get_env('LEAPP_DISABLE_NET_NAMING_SCHEMES', '0') != '1'
|
||||
- is_upgrade_8to9 = version.get_target_major_version() == '9'
|
||||
|
||||
- if are_net_schemes_enabled and is_upgrade_8to9:
|
||||
- # For 8>9 we are using net.naming_scheme kernel arg by default - do not generate link files
|
||||
+ if are_net_schemes_enabled:
|
||||
msg = ('Skipping generation of .link files renaming NICs as net.naming-scheme '
|
||||
- '{LEAPP_DISABLE_NET_NAMING_SCHEMES != 1} is enabled and upgrade is 8>9')
|
||||
- api.current_logger().info(msg)
|
||||
+ '{LEAPP_DISABLE_NET_NAMING_SCHEMES != 1} is enabled.')
|
||||
+ api.current_logger().debug(msg)
|
||||
return
|
||||
|
||||
+ api.current_logger().warning(
|
||||
+ 'LEAPP_DISABLE_NET_NAMING_SCHEMES=1 - Using deprecated handling'
|
||||
+ ' of network interface names by creating link files.'
|
||||
+ )
|
||||
+
|
||||
if get_env('LEAPP_NO_NETWORK_RENAMING', '0') == '1':
|
||||
api.current_logger().info(
|
||||
'Skipping handling of possibly renamed network interfaces: leapp executed with LEAPP_NO_NETWORK_RENAMING=1'
|
||||
@@ -80,13 +82,13 @@ def process():
|
||||
)
|
||||
continue
|
||||
|
||||
- if source_name != target_name and get_env('LEAPP_NO_NETWORK_RENAMING', '0') != '1':
|
||||
+ if source_name != target_name:
|
||||
api.current_logger().warning('Detected interface rename {} -> {}.'.format(source_name, target_name))
|
||||
|
||||
- if re.search('eth[0-9]+', iface.name) is not None:
|
||||
+ if re.search('^eth[0-9]+$', iface.name) is not None:
|
||||
api.current_logger().warning('Interface named using eth prefix, refusing to generate link file')
|
||||
- renamed_interfaces.append(RenamedInterface(**{'rhel7_name': source_name,
|
||||
- 'rhel8_name': target_name}))
|
||||
+ renamed_interfaces.append(RenamedInterface(**{'original_name': source_name,
|
||||
+ 'new_name': target_name}))
|
||||
continue
|
||||
|
||||
initrd_files.append(generate_link_file(iface))
|
||||
@@ -108,7 +110,6 @@ def process():
|
||||
api.current_logger().warning(msg)
|
||||
|
||||
api.produce(RenamedInterfaces(renamed=renamed_interfaces))
|
||||
- api.produce(InitrdIncludes(files=initrd_files))
|
||||
# TODO: cover actor by tests in future. I am skipping writing of tests
|
||||
# now as some refactoring and bugfixing related to this actor
|
||||
# is planned already.
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesconfig/tests/test_persistentnetnamesconfig.py b/repos/system_upgrade/common/actors/persistentnetnamesconfig/tests/test_persistentnetnamesconfig.py
|
||||
index c584c7ea..b107612b 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesconfig/tests/test_persistentnetnamesconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesconfig/tests/test_persistentnetnamesconfig.py
|
||||
@@ -7,7 +7,8 @@ from leapp.libraries.actor import persistentnetnamesconfig
|
||||
from leapp.libraries.common.config import mock_configs
|
||||
from leapp.libraries.common.testutils import CurrentActorMocked, logger_mocked, produce_mocked
|
||||
from leapp.models import (
|
||||
- InitrdIncludes,
|
||||
+ EnvVar,
|
||||
+ IPUConfig,
|
||||
Interface,
|
||||
PCIAddress,
|
||||
PersistentNetNamesFacts,
|
||||
@@ -19,6 +20,19 @@ from leapp.models import (
|
||||
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
CUR_DIR = ""
|
||||
|
||||
+CONFIG_DISABLED_NAMING_SCHEMES = IPUConfig(
|
||||
+ leapp_env_vars=[
|
||||
+ EnvVar(name='LEAPP_DEVEL', value='0'),
|
||||
+ EnvVar(name='LEAPP_DISABLE_NET_NAMING_SCHEMES', value='1'),
|
||||
+ ],
|
||||
+ os_release=mock_configs.CONFIG.os_release,
|
||||
+ version=mock_configs.CONFIG.version,
|
||||
+ architecture=mock_configs.CONFIG.architecture,
|
||||
+ kernel=mock_configs.CONFIG.kernel,
|
||||
+ supported_upgrade_paths=mock_configs.CONFIG.supported_upgrade_paths,
|
||||
+ distro=mock_configs.CONFIG.distro
|
||||
+)
|
||||
+
|
||||
|
||||
@pytest.fixture
|
||||
def adjust_cwd():
|
||||
@@ -56,12 +70,10 @@ def test_identical(current_actor_context):
|
||||
interfaces = generate_interfaces(4)
|
||||
current_actor_context.feed(PersistentNetNamesFacts(interfaces=interfaces))
|
||||
current_actor_context.feed(PersistentNetNamesFactsInitramfs(interfaces=interfaces))
|
||||
- current_actor_context.run(config_model=mock_configs.CONFIG)
|
||||
+ current_actor_context.run(config_model=CONFIG_DISABLED_NAMING_SCHEMES)
|
||||
|
||||
renamed_interfaces = current_actor_context.consume(RenamedInterfaces)[0]
|
||||
- initrd_files = current_actor_context.consume(InitrdIncludes)[0]
|
||||
t_initrafms_tasks = current_actor_context.consume(TargetInitramfsTasks)[0]
|
||||
- assert initrd_files.files == t_initrafms_tasks.include_files
|
||||
assert not renamed_interfaces.renamed
|
||||
assert not t_initrafms_tasks.include_files
|
||||
|
||||
@@ -73,12 +85,10 @@ def test_renamed_single_noneth(monkeypatch, current_actor_context):
|
||||
current_actor_context.feed(PersistentNetNamesFacts(interfaces=interfaces))
|
||||
interfaces[0].name = 'n4'
|
||||
current_actor_context.feed(PersistentNetNamesFactsInitramfs(interfaces=interfaces))
|
||||
- current_actor_context.run(config_model=mock_configs.CONFIG)
|
||||
+ current_actor_context.run(config_model=CONFIG_DISABLED_NAMING_SCHEMES)
|
||||
|
||||
renamed_interfaces = current_actor_context.consume(RenamedInterfaces)[0]
|
||||
- initrd_files = current_actor_context.consume(InitrdIncludes)[0]
|
||||
t_initrafms_tasks = current_actor_context.consume(TargetInitramfsTasks)[0]
|
||||
- assert initrd_files.files == t_initrafms_tasks.include_files
|
||||
assert not renamed_interfaces.renamed
|
||||
assert len(t_initrafms_tasks.include_files) == 1
|
||||
assert '/etc/systemd/network/10-leapp-n0.link' in t_initrafms_tasks.include_files
|
||||
@@ -92,12 +102,10 @@ def test_renamed_swap_noneth(monkeypatch, current_actor_context):
|
||||
interfaces[0].name = 'n3'
|
||||
interfaces[3].name = 'n0'
|
||||
current_actor_context.feed(PersistentNetNamesFactsInitramfs(interfaces=interfaces))
|
||||
- current_actor_context.run(config_model=mock_configs.CONFIG)
|
||||
+ current_actor_context.run(config_model=CONFIG_DISABLED_NAMING_SCHEMES)
|
||||
|
||||
renamed_interfaces = current_actor_context.consume(RenamedInterfaces)[0]
|
||||
- initrd_files = current_actor_context.consume(InitrdIncludes)[0]
|
||||
t_initrafms_tasks = current_actor_context.consume(TargetInitramfsTasks)[0]
|
||||
- assert initrd_files.files == t_initrafms_tasks.include_files
|
||||
assert not renamed_interfaces.renamed
|
||||
assert len(t_initrafms_tasks.include_files) == 2
|
||||
assert '/etc/systemd/network/10-leapp-n0.link' in t_initrafms_tasks.include_files
|
||||
@@ -113,15 +121,13 @@ def test_renamed_single_eth(monkeypatch, current_actor_context):
|
||||
current_actor_context.feed(PersistentNetNamesFacts(interfaces=interfaces))
|
||||
interfaces[0].name = 'eth4'
|
||||
current_actor_context.feed(PersistentNetNamesFactsInitramfs(interfaces=interfaces))
|
||||
- current_actor_context.run(config_model=mock_configs.CONFIG)
|
||||
+ current_actor_context.run(config_model=CONFIG_DISABLED_NAMING_SCHEMES)
|
||||
|
||||
renamed_interfaces = current_actor_context.consume(RenamedInterfaces)[0]
|
||||
- initrd_files = current_actor_context.consume(InitrdIncludes)[0]
|
||||
t_initrafms_tasks = current_actor_context.consume(TargetInitramfsTasks)[0]
|
||||
- assert initrd_files.files == t_initrafms_tasks.include_files
|
||||
assert len(renamed_interfaces.renamed) == 1
|
||||
- assert renamed_interfaces.renamed[0].rhel7_name == 'eth0'
|
||||
- assert renamed_interfaces.renamed[0].rhel8_name == 'eth4'
|
||||
+ assert renamed_interfaces.renamed[0].original_name == 'eth0'
|
||||
+ assert renamed_interfaces.renamed[0].new_name == 'eth4'
|
||||
assert not t_initrafms_tasks.include_files
|
||||
|
||||
|
||||
@@ -135,18 +141,16 @@ def test_renamed_swap_eth(monkeypatch, current_actor_context):
|
||||
interfaces[0].name = 'eth3'
|
||||
interfaces[3].name = 'eth0'
|
||||
current_actor_context.feed(PersistentNetNamesFactsInitramfs(interfaces=interfaces))
|
||||
- current_actor_context.run(config_model=mock_configs.CONFIG)
|
||||
+ current_actor_context.run(config_model=CONFIG_DISABLED_NAMING_SCHEMES)
|
||||
|
||||
renamed_interfaces = current_actor_context.consume(RenamedInterfaces)[0]
|
||||
- initrd_files = current_actor_context.consume(InitrdIncludes)[0]
|
||||
t_initrafms_tasks = current_actor_context.consume(TargetInitramfsTasks)[0]
|
||||
- assert initrd_files.files == t_initrafms_tasks.include_files
|
||||
assert len(renamed_interfaces.renamed) == 2
|
||||
for interface in renamed_interfaces.renamed:
|
||||
- if interface.rhel7_name == 'eth0':
|
||||
- assert interface.rhel8_name == 'eth3'
|
||||
- elif interface.rhel7_name == 'eth3':
|
||||
- assert interface.rhel8_name == 'eth0'
|
||||
+ if interface.original_name == 'eth0':
|
||||
+ assert interface.new_name == 'eth3'
|
||||
+ elif interface.original_name == 'eth3':
|
||||
+ assert interface.new_name == 'eth0'
|
||||
assert not t_initrafms_tasks.include_files
|
||||
|
||||
|
||||
@@ -179,7 +183,7 @@ def test_bz_1899455_crash_iface(monkeypatch, adjust_cwd):
|
||||
monkeypatch.setattr(persistentnetnamesconfig.api, 'produce', produce_mocked())
|
||||
persistentnetnamesconfig.process()
|
||||
|
||||
- for prod_models in [RenamedInterfaces, InitrdIncludes, TargetInitramfsTasks]:
|
||||
+ for prod_models in [RenamedInterfaces, TargetInitramfsTasks]:
|
||||
any(isinstance(i, prod_models) for i in persistentnetnamesconfig.api.produce.model_instances)
|
||||
assert any('Some network devices' in x for x in persistentnetnamesconfig.api.current_logger.warnmsg)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/models/persistentnetnamesfacts.py b/repos/system_upgrade/common/models/persistentnetnamesfacts.py
|
||||
index 3c71cdcd..e5cf979b 100644
|
||||
--- a/repos/system_upgrade/common/models/persistentnetnamesfacts.py
|
||||
+++ b/repos/system_upgrade/common/models/persistentnetnamesfacts.py
|
||||
@@ -1,5 +1,6 @@
|
||||
from leapp.models import fields, Model
|
||||
from leapp.topics import SystemInfoTopic
|
||||
+from leapp.utils.deprecation import deprecated
|
||||
|
||||
|
||||
class PCIAddress(Model):
|
||||
@@ -82,25 +83,37 @@ class PersistentNetNamesFactsInitramfs(PersistentNetNamesFacts):
|
||||
pass
|
||||
|
||||
|
||||
+@deprecated(
|
||||
+ since="2026-03-18",
|
||||
+ message=(
|
||||
+ "Information provided in this message is not always complete and it's"
|
||||
+ " not used nowadays when net naming scheme is set during the upgrade."
|
||||
+ )
|
||||
+)
|
||||
class RenamedInterface(Model):
|
||||
"""
|
||||
Provide original and new name of the network interface when renamed
|
||||
"""
|
||||
topic = SystemInfoTopic
|
||||
|
||||
- # TODO(pstodulk) deprecate these fields and replace them by new ones
|
||||
- # or deprecate the model completely.
|
||||
- rhel7_name = fields.String()
|
||||
+ original_name = fields.String()
|
||||
"""
|
||||
Original interface name.
|
||||
"""
|
||||
|
||||
- rhel8_name = fields.String()
|
||||
+ new_name = fields.String()
|
||||
"""
|
||||
New interface name.
|
||||
"""
|
||||
|
||||
|
||||
+@deprecated(
|
||||
+ since="2026-03-18",
|
||||
+ message=(
|
||||
+ "Information provided in this message is not always complete and it's"
|
||||
+ " not used nowadays when net naming scheme is set during the upgrade."
|
||||
+ )
|
||||
+)
|
||||
class RenamedInterfaces(Model):
|
||||
"""
|
||||
Provide list of renamed network interfaces
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
From 0872576049715c7a909379d5de5cc53bab3a408a Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Fri, 20 Mar 2026 17:19:20 +0100
|
||||
Subject: [PATCH 32/44] persistentnetnamesdisable: Disable net.ifnames
|
||||
correctly for single eth
|
||||
|
||||
Original solution disabled net.ifnames only for the target kernel
|
||||
bootloader entry. But the upgrade initramfs stayed unhandled.
|
||||
So it could happen that a "false positive" detection of changed
|
||||
network interface names could been detected during the upgrade process
|
||||
even when the target system booted again with "eth0" net interface
|
||||
(because of net.ifnames=0). Set the parameter also for the upgrade
|
||||
environment to behave same as on the target system.
|
||||
|
||||
Also, actor originally produced just the KernelCmdlineArg msg,
|
||||
which is nowadays considered kind of obsoleted for this purpose
|
||||
- still valid, but obsoleted. So produce UpgradeKernelCmdlineArgTasks
|
||||
and TargetKernelCmdlineArgTasks msgs instead.
|
||||
---
|
||||
.../tests/test_persistentnetnamesconfig.py | 2 +-
|
||||
.../common/actors/persistentnetnamesdisable/actor.py | 8 ++++++--
|
||||
.../libraries/persistentnetnamesdisable.py | 11 +++++++++--
|
||||
.../tests/test_persistentnetnamesdisable.py | 10 +++++++++-
|
||||
4 files changed, 25 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesconfig/tests/test_persistentnetnamesconfig.py b/repos/system_upgrade/common/actors/persistentnetnamesconfig/tests/test_persistentnetnamesconfig.py
|
||||
index b107612b..f2519d77 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesconfig/tests/test_persistentnetnamesconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesconfig/tests/test_persistentnetnamesconfig.py
|
||||
@@ -8,8 +8,8 @@ from leapp.libraries.common.config import mock_configs
|
||||
from leapp.libraries.common.testutils import CurrentActorMocked, logger_mocked, produce_mocked
|
||||
from leapp.models import (
|
||||
EnvVar,
|
||||
- IPUConfig,
|
||||
Interface,
|
||||
+ IPUConfig,
|
||||
PCIAddress,
|
||||
PersistentNetNamesFacts,
|
||||
PersistentNetNamesFactsInitramfs,
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py b/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py
|
||||
index 15c43141..741e2c86 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py
|
||||
@@ -1,6 +1,10 @@
|
||||
from leapp.actors import Actor
|
||||
from leapp.libraries.actor import persistentnetnamesdisable
|
||||
-from leapp.models import KernelCmdlineArg, PersistentNetNamesFacts
|
||||
+from leapp.models import (
|
||||
+ PersistentNetNamesFacts,
|
||||
+ TargetKernelCmdlineArgTasks,
|
||||
+ UpgradeKernelCmdlineArgTasks
|
||||
+)
|
||||
from leapp.reporting import Report
|
||||
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
|
||||
@@ -12,7 +16,7 @@ class PersistentNetNamesDisable(Actor):
|
||||
|
||||
name = 'persistentnetnamesdisable'
|
||||
consumes = (PersistentNetNamesFacts,)
|
||||
- produces = (KernelCmdlineArg, Report)
|
||||
+ produces = (Report, TargetKernelCmdlineArgTasks, UpgradeKernelCmdlineArgTasks)
|
||||
tags = (ChecksPhaseTag, IPUWorkflowTag)
|
||||
|
||||
def process(self):
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py b/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py
|
||||
index 0d1a90e2..38eef133 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py
|
||||
@@ -3,7 +3,12 @@ import re
|
||||
from leapp import reporting
|
||||
from leapp.libraries.common.config.version import get_target_major_version
|
||||
from leapp.libraries.stdlib import api
|
||||
-from leapp.models import KernelCmdlineArg, PersistentNetNamesFacts
|
||||
+from leapp.models import (
|
||||
+ KernelCmdlineArg,
|
||||
+ PersistentNetNamesFacts,
|
||||
+ TargetKernelCmdlineArgTasks,
|
||||
+ UpgradeKernelCmdlineArgTasks
|
||||
+)
|
||||
from leapp.reporting import create_report
|
||||
|
||||
|
||||
@@ -29,7 +34,9 @@ def disable_persistent_naming():
|
||||
"Single eth0 network interface detected."
|
||||
" Appending 'net.ifnames=0' for the target system kernel commandline"
|
||||
)
|
||||
- api.produce(KernelCmdlineArg(**{'key': 'net.ifnames', 'value': '0'}))
|
||||
+ k_arg = KernelCmdlineArg(key='net.ifnames', value='0')
|
||||
+ api.produce(UpgradeKernelCmdlineArgTasks(to_add=[k_arg]))
|
||||
+ api.produce(TargetKernelCmdlineArgTasks(to_add=[k_arg]))
|
||||
|
||||
|
||||
def report_ethX_ifaces():
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py b/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py
|
||||
index 2369e80f..81b5a28c 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py
|
||||
@@ -1,7 +1,13 @@
|
||||
import pytest
|
||||
|
||||
from leapp.libraries.actor import persistentnetnamesdisable
|
||||
-from leapp.models import Interface, KernelCmdlineArg, PCIAddress, PersistentNetNamesFacts
|
||||
+from leapp.models import (
|
||||
+ Interface,
|
||||
+ PCIAddress,
|
||||
+ PersistentNetNamesFacts,
|
||||
+ TargetKernelCmdlineArgTasks,
|
||||
+ UpgradeKernelCmdlineArgTasks
|
||||
+)
|
||||
from leapp.reporting import Report
|
||||
from leapp.snactor.fixture import current_actor_context
|
||||
from leapp.utils.report import is_inhibitor
|
||||
@@ -51,6 +57,8 @@ def test_actor_single_eth0(current_actor_context):
|
||||
current_actor_context.feed(PersistentNetNamesFacts(interfaces=interface))
|
||||
current_actor_context.run()
|
||||
assert not current_actor_context.consume(Report)
|
||||
+ assert current_actor_context.consume(UpgradeKernelCmdlineArgTasks)
|
||||
+ assert current_actor_context.consume(TargetKernelCmdlineArgTasks)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
--
|
||||
2.53.0
|
||||
|
||||
48
SOURCES/0032-spec-create-etc-leapp-actor_conf.d.patch
Normal file
48
SOURCES/0032-spec-create-etc-leapp-actor_conf.d.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 36b93e4a2504f72e5a371a75a23e7cd2c695b84b Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Sun, 6 Oct 2024 21:01:13 +0200
|
||||
Subject: [PATCH 32/40] spec: create /etc/leapp/actor_conf.d
|
||||
|
||||
Add additional build steps to the specfile that create the actor
|
||||
configuration directory. The directory is owned by the package, so
|
||||
it gets removed when the user uninstalls leapp.
|
||||
|
||||
Also prepared some comment lines for future when we will want to
|
||||
include some configuration files as part of the rpm.
|
||||
---
|
||||
etc/leapp/actor_conf.d/.gitkeep | 0
|
||||
packaging/leapp-repository.spec | 7 +++++++
|
||||
2 files changed, 7 insertions(+)
|
||||
create mode 100644 etc/leapp/actor_conf.d/.gitkeep
|
||||
|
||||
diff --git a/etc/leapp/actor_conf.d/.gitkeep b/etc/leapp/actor_conf.d/.gitkeep
|
||||
new file mode 100644
|
||||
index 00000000..e69de29b
|
||||
diff --git a/packaging/leapp-repository.spec b/packaging/leapp-repository.spec
|
||||
index 570d0df2..828355bf 100644
|
||||
--- a/packaging/leapp-repository.spec
|
||||
+++ b/packaging/leapp-repository.spec
|
||||
@@ -250,6 +250,11 @@ install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/files/
|
||||
install -m 0644 etc/leapp/transaction/* %{buildroot}%{_sysconfdir}/leapp/transaction
|
||||
install -m 0644 etc/leapp/files/* %{buildroot}%{_sysconfdir}/leapp/files
|
||||
|
||||
+# Actor configuration dir
|
||||
+install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/actor_conf.d/
|
||||
+# uncomment to install existing configs
|
||||
+#install -m 0644 etc/leapp/actor_conf.d/* %%{buildroot}%%{_sysconfdir}/leapp/actor_conf.d
|
||||
+
|
||||
# install CLI commands for the leapp utility on the expected path
|
||||
install -m 0755 -d %{buildroot}%{leapp_python_sitelib}/leapp/cli/
|
||||
cp -r commands %{buildroot}%{leapp_python_sitelib}/leapp/cli/
|
||||
@@ -295,6 +300,8 @@ done;
|
||||
%dir %{custom_repositorydir}
|
||||
%dir %{leapp_python_sitelib}/leapp/cli/commands
|
||||
%config %{_sysconfdir}/leapp/files/*
|
||||
+# uncomment to package installed configs
|
||||
+#%%config %%{_sysconfdir}/leapp/actor_conf.d/*
|
||||
%{_sysconfdir}/leapp/repos.d/*
|
||||
%{_sysconfdir}/leapp/transaction/*
|
||||
%{repositorydir}/*
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,303 +0,0 @@
|
||||
From 806e65d67cac9e16c0341f366133ae3c14844fcd Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Wed, 25 Mar 2026 15:57:37 +0100
|
||||
Subject: [PATCH 33/44] persistentnetnamesdisable: Mention net.naming-scheme in
|
||||
report
|
||||
|
||||
Since RHEL 8 it's possible to specifcy net.naming-scheme to have
|
||||
a consistent NIC names across RHEL major releases. When a specific
|
||||
net.naming-scheme is not specified in kernel cmdline, suggest people
|
||||
this option as well.
|
||||
---
|
||||
.../actors/persistentnetnamesdisable/actor.py | 15 +++-
|
||||
.../libraries/persistentnetnamesdisable.py | 86 +++++++++++++++----
|
||||
.../tests/test_persistentnetnamesdisable.py | 78 ++++++++++++++++-
|
||||
3 files changed, 158 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py b/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py
|
||||
index 741e2c86..0bcc3827 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesdisable/actor.py
|
||||
@@ -1,6 +1,7 @@
|
||||
from leapp.actors import Actor
|
||||
from leapp.libraries.actor import persistentnetnamesdisable
|
||||
from leapp.models import (
|
||||
+ KernelCmdline,
|
||||
PersistentNetNamesFacts,
|
||||
TargetKernelCmdlineArgTasks,
|
||||
UpgradeKernelCmdlineArgTasks
|
||||
@@ -11,11 +12,21 @@ from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
|
||||
class PersistentNetNamesDisable(Actor):
|
||||
"""
|
||||
- Disable systemd-udevd persistent network naming on machine with single eth0 NIC
|
||||
+ Check whether the system has any (physical) NICs with kernel naming (ethX)
|
||||
+
|
||||
+ The kernel naming is in general unstable - there is no guarantee of persistent
|
||||
+ NIC names between reboots, so eth0 can becaome eth3 and vice versa. If the
|
||||
+ system has more than one physical network interface, the kernel naming must
|
||||
+ not be used otherwise the upgrade is inhibited. The report contains remediation
|
||||
+ hints for user to resolve the problem before the upgrade.
|
||||
+
|
||||
+ On systems with only one physical network interface with eth0 NIC, register
|
||||
+ task to disable systemd-udevd persistent network naming (set `net.ifnames=0`
|
||||
+ on kernel cmdline for the upgrade environment and the upgraded system.
|
||||
"""
|
||||
|
||||
name = 'persistentnetnamesdisable'
|
||||
- consumes = (PersistentNetNamesFacts,)
|
||||
+ consumes = (PersistentNetNamesFacts, KernelCmdline)
|
||||
produces = (Report, TargetKernelCmdlineArgTasks, UpgradeKernelCmdlineArgTasks)
|
||||
tags = (ChecksPhaseTag, IPUWorkflowTag)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py b/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py
|
||||
index 38eef133..0a4209b8 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesdisable/libraries/persistentnetnamesdisable.py
|
||||
@@ -1,9 +1,11 @@
|
||||
import re
|
||||
|
||||
from leapp import reporting
|
||||
-from leapp.libraries.common.config.version import get_target_major_version
|
||||
+from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.common.config.version import get_source_major_version, get_target_major_version
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import (
|
||||
+ KernelCmdline,
|
||||
KernelCmdlineArg,
|
||||
PersistentNetNamesFacts,
|
||||
TargetKernelCmdlineArgTasks,
|
||||
@@ -29,6 +31,40 @@ def single_eth0(interfaces):
|
||||
return len(interfaces) == 1 and interfaces[0].name == 'eth0'
|
||||
|
||||
|
||||
+def is_kernel_arg_present(key, value=None):
|
||||
+ """
|
||||
+ Return True if requested argument is set in kernel cmdline. Return False otherwise.
|
||||
+
|
||||
+ If the `value` is specified, check also whether the specific value is set.
|
||||
+ The function consumes :class:`KernelCmdline`.
|
||||
+
|
||||
+ :param key: The kernel argument to search for
|
||||
+ :type key: str
|
||||
+ :param value: If string is specified, check for a specific string as well.
|
||||
+ :type value: str|None
|
||||
+ :rtype: bool
|
||||
+ """
|
||||
+ # NOTE(pstodulk): with small update a possible candidate to move into the
|
||||
+ # kernel shared library. For now, keeping it just in this actor.
|
||||
+ k_cmdline = next(api.consume(KernelCmdline), None)
|
||||
+ if not k_cmdline:
|
||||
+ # NOTE(pstodulk): this hypothetical situation, skipping coverage by
|
||||
+ # unit tests
|
||||
+ raise StopActorExecutionError(
|
||||
+ message='Missing information about current kernel command line.',
|
||||
+ details={
|
||||
+ 'details': 'Missing the KernelCmdline message.'
|
||||
+ }
|
||||
+ )
|
||||
+
|
||||
+ for k_arg in k_cmdline.parameters:
|
||||
+ if k_arg.key != key:
|
||||
+ continue
|
||||
+ if value is None or k_arg.value == value:
|
||||
+ return True
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
def disable_persistent_naming():
|
||||
api.current_logger().info(
|
||||
"Single eth0 network interface detected."
|
||||
@@ -40,27 +76,30 @@ def disable_persistent_naming():
|
||||
|
||||
|
||||
def report_ethX_ifaces():
|
||||
- report_entries = [
|
||||
- reporting.Title('Unsupported network configuration'),
|
||||
- reporting.Summary(
|
||||
- 'Detected multiple physical network interfaces where one or more'
|
||||
- ' use kernel naming (e.g. eth0). Upgrade process cannot continue'
|
||||
- ' because stability of names can not be guaranteed.'
|
||||
- ),
|
||||
+ url_title_kb = 'How to Perform an In-Place Upgrade when Using Kernel-Assigned NIC Names'
|
||||
+ hint_text = f'Rename all ethX network interfaces following the "{url_title_kb}" solution article.'
|
||||
+ report_external_links = [
|
||||
reporting.ExternalLink(
|
||||
- title='How to Perform an In-Place Upgrade when Using Kernel-Assigned NIC Names',
|
||||
+ title=url_title_kb,
|
||||
url='https://access.redhat.com/solutions/4067471'
|
||||
- ),
|
||||
- reporting.Remediation(
|
||||
- hint='Rename all ethX network interfaces following the attached KB solution article.'
|
||||
- ),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.NETWORK]),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR])
|
||||
+ )
|
||||
]
|
||||
+ if not is_kernel_arg_present('net.naming-scheme') and not is_kernel_arg_present('net.ifnames', '0'):
|
||||
+ hint_text += (
|
||||
+ ' If the detected ethX interfaces are not manually configured, it is'
|
||||
+ ' possible that new names were not assigned due to a naming conflict'
|
||||
+ ' in the current `net.naming-scheme`. This can be resolved by'
|
||||
+ ' configuring a newer naming scheme via the kernel argument.'
|
||||
+ ' For more information, see "Implementing consistent network interface naming".'
|
||||
+ )
|
||||
|
||||
+ # NOTE(pstodulk): the link is covered for RHEL 8, 9, 10
|
||||
+ report_external_links.append(reporting.ExternalLink(
|
||||
+ title='Implementing consistent network interface naming',
|
||||
+ url='https://red.ht/rhel-{}-consistent-nic-naming'.format(get_source_major_version())
|
||||
+ ))
|
||||
if get_target_major_version() == '9':
|
||||
- report_entries.append(
|
||||
+ report_external_links.append(
|
||||
reporting.ExternalLink(
|
||||
title='RHEL 8 to RHEL 9: inplace upgrade fails at '
|
||||
'"Network configuration for unsupported device types detected"',
|
||||
@@ -68,6 +107,19 @@ def report_ethX_ifaces():
|
||||
)
|
||||
)
|
||||
|
||||
+ report_entries = [
|
||||
+ reporting.Title('Unsupported network configuration'),
|
||||
+ reporting.Summary(
|
||||
+ 'Detected multiple physical network interfaces where one or more'
|
||||
+ ' use kernel naming (e.g. eth0). Upgrade process cannot continue'
|
||||
+ ' because stability of names can not be guaranteed.'
|
||||
+ ),
|
||||
+ reporting.Remediation(hint=hint_text),
|
||||
+ reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Groups([reporting.Groups.NETWORK]),
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR])
|
||||
+ ] + report_external_links
|
||||
+
|
||||
create_report(report_entries)
|
||||
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py b/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py
|
||||
index 81b5a28c..4b8669bb 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesdisable/tests/test_persistentnetnamesdisable.py
|
||||
@@ -1,8 +1,11 @@
|
||||
import pytest
|
||||
|
||||
from leapp.libraries.actor import persistentnetnamesdisable
|
||||
+from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked
|
||||
from leapp.models import (
|
||||
Interface,
|
||||
+ KernelCmdline,
|
||||
+ KernelCmdlineArg,
|
||||
PCIAddress,
|
||||
PersistentNetNamesFacts,
|
||||
TargetKernelCmdlineArgTasks,
|
||||
@@ -65,6 +68,7 @@ def test_actor_single_eth0(current_actor_context):
|
||||
'target_version', ['9', '10']
|
||||
)
|
||||
def test_actor_more_ethX(monkeypatch, current_actor_context, target_version):
|
||||
+ monkeypatch.setattr(persistentnetnamesdisable, 'get_source_major_version', lambda: str(int(target_version) - 1))
|
||||
monkeypatch.setattr(persistentnetnamesdisable, 'get_target_major_version', lambda: target_version)
|
||||
pci1 = PCIAddress(domain="0000", bus="3e", function="00", device="PCI bridge")
|
||||
pci2 = PCIAddress(domain="0000", bus="3d", function="00", device="Serial controller")
|
||||
@@ -84,7 +88,10 @@ def test_actor_more_ethX(monkeypatch, current_actor_context, target_version):
|
||||
pci_info=pci2,
|
||||
devpath="/devices/hidraw/hidraw0")
|
||||
]
|
||||
- current_actor_context.feed(PersistentNetNamesFacts(interfaces=interface))
|
||||
+ current_actor_context.feed(
|
||||
+ PersistentNetNamesFacts(interfaces=interface),
|
||||
+ KernelCmdline(parameters=[KernelCmdlineArg(key='what', value='ever')])
|
||||
+ )
|
||||
current_actor_context.run()
|
||||
|
||||
report_fields = current_actor_context.consume(Report)[0].report
|
||||
@@ -122,6 +129,7 @@ def test_actor_single_int_not_ethX(current_actor_context):
|
||||
'target_version', ['9', '10']
|
||||
)
|
||||
def test_actor_ethX_and_not_ethX(monkeypatch, current_actor_context, target_version):
|
||||
+ monkeypatch.setattr(persistentnetnamesdisable, 'get_source_major_version', lambda: str(int(target_version) - 1))
|
||||
monkeypatch.setattr(persistentnetnamesdisable, 'get_target_major_version', lambda: target_version)
|
||||
pci1 = PCIAddress(domain="0000", bus="3e", function="00", device="PCI bridge")
|
||||
pci2 = PCIAddress(domain="0000", bus="3d", function="00", device="Serial controller")
|
||||
@@ -141,7 +149,10 @@ def test_actor_ethX_and_not_ethX(monkeypatch, current_actor_context, target_vers
|
||||
pci_info=pci2,
|
||||
devpath="/devices/hidraw/hidraw0")
|
||||
]
|
||||
- current_actor_context.feed(PersistentNetNamesFacts(interfaces=interface))
|
||||
+ current_actor_context.feed(
|
||||
+ PersistentNetNamesFacts(interfaces=interface),
|
||||
+ KernelCmdline(parameters=[KernelCmdlineArg(key='what', value='ever')])
|
||||
+ )
|
||||
current_actor_context.run()
|
||||
assert current_actor_context.consume(Report)
|
||||
|
||||
@@ -158,3 +169,66 @@ def test_actor_ethX_and_not_ethX(monkeypatch, current_actor_context, target_vers
|
||||
assert rhel8to9_present
|
||||
else:
|
||||
assert not rhel8to9_present
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(('result_expected', 'key', 'value'), (
|
||||
+ (True, 'net.ifnames', None),
|
||||
+ (True, 'net.ifnames', '0'),
|
||||
+ (False, 'net.ifname', None),
|
||||
+ (False, 'inet.ifnames', None),
|
||||
+ (False, 'missing', None),
|
||||
+ (False, 'missing', 'whatever'),
|
||||
+ (False, 'net.ifnames', '1'),
|
||||
+))
|
||||
+def test_is_kernel_arg_present(monkeypatch, result_expected, key, value):
|
||||
+ k_args = [
|
||||
+ KernelCmdlineArg(key='Foo', value='0'),
|
||||
+ KernelCmdlineArg(key='net.ifnames', value='0'),
|
||||
+ KernelCmdlineArg(key='Something', value='None'),
|
||||
+ ]
|
||||
+ curr_actor_mocked = CurrentActorMocked(
|
||||
+ msgs=[KernelCmdline(parameters=k_args)]
|
||||
+ )
|
||||
+ monkeypatch.setattr(persistentnetnamesdisable.api, 'current_actor', curr_actor_mocked)
|
||||
+ assert result_expected is persistentnetnamesdisable.is_kernel_arg_present(key, value)
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(('naming_expected', 'k_args'), (
|
||||
+ (False, [KernelCmdlineArg(key='net.ifnames', value='0')]),
|
||||
+ (True, [KernelCmdlineArg(key='net.ifnames', value='1')]),
|
||||
+ (True, [KernelCmdlineArg(key='net.naming-scheme-foo', value='rhel-8.10')]),
|
||||
+ (
|
||||
+ # NOTE(pstodulk): this is kind of nonsense, but let's test it
|
||||
+ False,
|
||||
+ [
|
||||
+ KernelCmdlineArg(key='net.naming-scheme', value='rhel-8.10'),
|
||||
+ KernelCmdlineArg(key='net.ifnames', value='0'),
|
||||
+ ]
|
||||
+ ),
|
||||
+ (False, [KernelCmdlineArg(key='net.naming-scheme', value='rhel-8.10')]),
|
||||
+ (False, [KernelCmdlineArg(key='net.naming-scheme', value='rhel-9.10')]),
|
||||
+))
|
||||
+@pytest.mark.parametrize('src_ver', ('8.10', '9.8', '10.6'))
|
||||
+def test_report_ethx_ifaces_scheme(monkeypatch, naming_expected, src_ver, k_args):
|
||||
+ _v_split = src_ver.split('.')
|
||||
+ dst_ver = '{}.{}'.format(int(_v_split[0]) + 1, _v_split[1])
|
||||
+ curr_actor_mocked = CurrentActorMocked(
|
||||
+ msgs=[KernelCmdline(parameters=k_args)],
|
||||
+ src_ver=src_ver,
|
||||
+ dst_ver=dst_ver
|
||||
+ )
|
||||
+ monkeypatch.setattr(persistentnetnamesdisable, 'create_report', create_report_mocked())
|
||||
+ monkeypatch.setattr(persistentnetnamesdisable.api, 'current_actor', curr_actor_mocked)
|
||||
+
|
||||
+ persistentnetnamesdisable.report_ethX_ifaces()
|
||||
+ assert persistentnetnamesdisable.create_report.called
|
||||
+ report = persistentnetnamesdisable.create_report.reports[0]
|
||||
+
|
||||
+ if naming_expected:
|
||||
+ url = 'https://red.ht/rhel-{}-consistent-nic-naming'.format(_v_split[0])
|
||||
+ assert any(url == link['url'] for link in report['detail']['external'])
|
||||
+ assert 'net.naming-scheme' in report['detail']['remediations'][0]['context']
|
||||
+ else:
|
||||
+ url_str = 'consistent-nic-naming'
|
||||
+ assert not any(url_str in link['url'] for link in report['detail']['external'])
|
||||
+ assert 'net.naming-scheme' not in report['detail']['remediations'][0]['context']
|
||||
--
|
||||
2.53.0
|
||||
|
||||
31
SOURCES/0033-spec-drop-.gitkeep-files-from-the-RPM.patch
Normal file
31
SOURCES/0033-spec-drop-.gitkeep-files-from-the-RPM.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 87db66c863104fea824a4406732cbe233ffee412 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Wed, 13 Nov 2024 15:05:50 +0100
|
||||
Subject: [PATCH 33/40] spec: drop .gitkeep files from the RPM
|
||||
|
||||
We have several .gitkeep files in the repo as we want to have some
|
||||
directories present in git however these directories are empty
|
||||
otherwise. This is common hack to achieve this, but we do not want
|
||||
to have these files really in the resulting RPMs. So we just remove
|
||||
them.
|
||||
---
|
||||
packaging/leapp-repository.spec | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/packaging/leapp-repository.spec b/packaging/leapp-repository.spec
|
||||
index 828355bf..2bb52505 100644
|
||||
--- a/packaging/leapp-repository.spec
|
||||
+++ b/packaging/leapp-repository.spec
|
||||
@@ -272,6 +272,9 @@ rm -rf %{buildroot}%{repositorydir}/common/actors/testactor
|
||||
find %{buildroot}%{repositorydir}/common -name "test.py" -delete
|
||||
rm -rf `find %{buildroot}%{repositorydir} -name "tests" -type d`
|
||||
find %{buildroot}%{repositorydir} -name "Makefile" -delete
|
||||
+# .gitkeep file is used to have a directory in the repo. but we do not want these
|
||||
+# files in the resulting RPM
|
||||
+find %{buildroot} -name .gitkeep -delete
|
||||
|
||||
for DIRECTORY in $(find %{buildroot}%{repositorydir}/ -mindepth 1 -maxdepth 1 -type d);
|
||||
do
|
||||
--
|
||||
2.47.0
|
||||
|
||||
95
SOURCES/0034-cli-load-actor-configuration.patch
Normal file
95
SOURCES/0034-cli-load-actor-configuration.patch
Normal file
@ -0,0 +1,95 @@
|
||||
From 140a0bbb689814041fa6a03ee2b703e70a20f2f2 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Sun, 10 Nov 2024 13:54:20 +0100
|
||||
Subject: [PATCH 34/40] cli: load actor configuration
|
||||
|
||||
Load actor configuration when running `leapp upgrade` or `leapp
|
||||
preupgrade`. The configuration is loaded, saved to leapp's DB,
|
||||
and remains available to all actors via framework's global variable.
|
||||
---
|
||||
commands/command_utils.py | 32 +++++++++++++++++++++++++++++++-
|
||||
commands/preupgrade/__init__.py | 3 +++
|
||||
commands/upgrade/__init__.py | 3 +++
|
||||
3 files changed, 37 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/commands/command_utils.py b/commands/command_utils.py
|
||||
index 2810a542..190f5f03 100644
|
||||
--- a/commands/command_utils.py
|
||||
+++ b/commands/command_utils.py
|
||||
@@ -1,10 +1,12 @@
|
||||
+import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import resource
|
||||
|
||||
+from leapp.actors import config as actor_config
|
||||
from leapp.exceptions import CommandError
|
||||
-from leapp.utils import path
|
||||
+from leapp.utils import audit, path
|
||||
|
||||
HANA_BASE_PATH = '/hana/shared'
|
||||
HANA_SAPCONTROL_PATH_X86_64 = 'exe/linuxx86_64/hdb/sapcontrol'
|
||||
@@ -178,3 +180,31 @@ def set_resource_limits():
|
||||
|
||||
if soft_fsize != fsize_limit:
|
||||
set_resource_limit(resource.RLIMIT_FSIZE, fsize_limit, fsize_limit)
|
||||
+
|
||||
+
|
||||
+def load_actor_configs_and_store_it_in_db(context, repositories, framework_cfg):
|
||||
+ """
|
||||
+ Load actor configuration so that actor's can access it and store it into leapp db.
|
||||
+
|
||||
+ :param context: Current execution context
|
||||
+ :param repositories: Discovered repositories
|
||||
+ :param framework_cfg: Leapp's configuration
|
||||
+ """
|
||||
+ # Read the Actor Config and validate it against the schemas saved in the
|
||||
+ # configuration.
|
||||
+
|
||||
+ actor_config_schemas = tuple(actor.config_schemas for actor in repositories.actors)
|
||||
+ actor_config_schemas = actor_config.normalize_schemas(actor_config_schemas)
|
||||
+ actor_config_path = framework_cfg.get('actor_config', 'path')
|
||||
+
|
||||
+ # Note: actor_config.load() stores the loaded actor config into a global
|
||||
+ # variable which can then be accessed by functions in that file. Is this
|
||||
+ # the right way to store that information?
|
||||
+ actor_cfg = actor_config.load(actor_config_path, actor_config_schemas)
|
||||
+
|
||||
+ # Dump the collected configuration, checksum it and store it inside the DB
|
||||
+ config_text = json.dumps(actor_cfg)
|
||||
+ config_text_hash = hashlib.sha256(config_text.encode('utf-8')).hexdigest()
|
||||
+ config_data = audit.ActorConfigData(config=config_text, hash_id=config_text_hash)
|
||||
+ db_config = audit.ActorConfig(config=config_data, context=context)
|
||||
+ db_config.store()
|
||||
diff --git a/commands/preupgrade/__init__.py b/commands/preupgrade/__init__.py
|
||||
index a9fa40e0..631eca6b 100644
|
||||
--- a/commands/preupgrade/__init__.py
|
||||
+++ b/commands/preupgrade/__init__.py
|
||||
@@ -62,6 +62,9 @@ def preupgrade(args, breadcrumbs):
|
||||
command_utils.set_resource_limits()
|
||||
|
||||
workflow = repositories.lookup_workflow('IPUWorkflow')()
|
||||
+
|
||||
+ command_utils.load_actor_configs_and_store_it_in_db(context, repositories, cfg)
|
||||
+
|
||||
util.warn_if_unsupported(configuration)
|
||||
util.process_whitelist_experimental(repositories, workflow, configuration, logger)
|
||||
with beautify_actor_exception():
|
||||
diff --git a/commands/upgrade/__init__.py b/commands/upgrade/__init__.py
|
||||
index c7487fde..3dedd438 100644
|
||||
--- a/commands/upgrade/__init__.py
|
||||
+++ b/commands/upgrade/__init__.py
|
||||
@@ -93,6 +93,9 @@ def upgrade(args, breadcrumbs):
|
||||
command_utils.set_resource_limits()
|
||||
|
||||
workflow = repositories.lookup_workflow('IPUWorkflow')(auto_reboot=args.reboot)
|
||||
+
|
||||
+ command_utils.load_actor_configs_and_store_it_in_db(context, repositories, cfg)
|
||||
+
|
||||
util.process_whitelist_experimental(repositories, workflow, configuration, logger)
|
||||
util.warn_if_unsupported(configuration)
|
||||
with beautify_actor_exception():
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
From 0706cb54f4d1ba953de5e348cb03f9553b952669 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Tue, 17 Mar 2026 13:01:17 +0100
|
||||
Subject: [PATCH 34/44] fix quoting in list representation of commands
|
||||
|
||||
Removed redundant quotes included due to incorrect handling of command
|
||||
conversion to string representation in leapp framework's reporting
|
||||
module. The reporting module is fixed by RHEL-156521 and this patch is a
|
||||
followup that fixes usage of the module so that the commands are
|
||||
propagated to the leapp-report.txt correctly.
|
||||
|
||||
Jira: RHEL-155517, RHEL-155515
|
||||
---
|
||||
.../actors/checkdnfpluginpath/libraries/checkdnfpluginpath.py | 2 +-
|
||||
repos/system_upgrade/common/actors/checkrootsymlinks/actor.py | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/checkdnfpluginpath/libraries/checkdnfpluginpath.py b/repos/system_upgrade/common/actors/checkdnfpluginpath/libraries/checkdnfpluginpath.py
|
||||
index ce705361..be169e7e 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkdnfpluginpath/libraries/checkdnfpluginpath.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkdnfpluginpath/libraries/checkdnfpluginpath.py
|
||||
@@ -21,7 +21,7 @@ def check_dnf_pluginpath(dnf_pluginpath_detected):
|
||||
reporting.Remediation(
|
||||
hint='Remove or comment out the pluginpath option in the DNF '
|
||||
'configuration file to be able to upgrade the system',
|
||||
- commands=[['sed', '-i', '\'s/^pluginpath[[:space:]]*=/#pluginpath=/\'', DNF_CONFIG_PATH]],
|
||||
+ commands=[['sed', '-i', 's/^pluginpath[[:space:]]*=/#pluginpath=/', DNF_CONFIG_PATH]],
|
||||
),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Groups([reporting.Groups.INHIBITOR]),
|
||||
diff --git a/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py b/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py
|
||||
index 7b89bf7a..bee672bf 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py
|
||||
@@ -55,7 +55,7 @@ class CheckRootSymlinks(Actor):
|
||||
os.path.relpath(item.target, '/'),
|
||||
os.path.join('/', item.name)])
|
||||
commands.append(command)
|
||||
- rem_commands = [['sh', '-c', '"{}"'.format(' && '.join(commands))]]
|
||||
+ rem_commands = [['sh', '-c', '{}'.format(' && '.join(commands))]]
|
||||
# Generate reports about non-utf8 absolute links presence
|
||||
nonutf_count = len(absolute_links_nonutf)
|
||||
if nonutf_count > 0:
|
||||
--
|
||||
2.53.0
|
||||
|
||||
157
SOURCES/0035-configs-common-introduce-RHUI-configuration.patch
Normal file
157
SOURCES/0035-configs-common-introduce-RHUI-configuration.patch
Normal file
@ -0,0 +1,157 @@
|
||||
From f3d38325fb525bca427a2b00e2bfb73b9297c36a Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Sun, 10 Nov 2024 14:35:26 +0100
|
||||
Subject: [PATCH 35/40] configs(common): introduce RHUI configuration
|
||||
|
||||
Introduce a common configuration definition for RHUI related decisions.
|
||||
The configuration has an atomic nature - if the user wants to overwrite
|
||||
leapp's decisions, he/she must overwrite all of them. Essentially, all
|
||||
fields of the RHUI_SETUPS cloud map entry can be configured. Almost no
|
||||
non-empty defaults are provided, as no reasonable defaults can be given.
|
||||
This is due to all setup parameters are different from provider to
|
||||
provider. Therefore, default values are empty values, so that it can
|
||||
later be detected by an actor whether all fields of the RHUI config
|
||||
has been filled.
|
||||
|
||||
Jira ref: RHEL-56251
|
||||
---
|
||||
repos/system_upgrade/common/configs/rhui.py | 127 ++++++++++++++++++++
|
||||
1 file changed, 127 insertions(+)
|
||||
create mode 100644 repos/system_upgrade/common/configs/rhui.py
|
||||
|
||||
diff --git a/repos/system_upgrade/common/configs/rhui.py b/repos/system_upgrade/common/configs/rhui.py
|
||||
new file mode 100644
|
||||
index 00000000..ade9bab9
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/configs/rhui.py
|
||||
@@ -0,0 +1,127 @@
|
||||
+"""
|
||||
+Configuration keys for RHUI.
|
||||
+
|
||||
+In case of RHUI in private regions it usual that publicly known RHUI data
|
||||
+is not valid. In such cases it's possible to provide the correct expected
|
||||
+RHUI data to correct the in-place upgrade process.
|
||||
+"""
|
||||
+
|
||||
+from leapp.actors.config import Config
|
||||
+from leapp.models import fields
|
||||
+
|
||||
+RHUI_CONFIG_SECTION = 'rhui'
|
||||
+
|
||||
+
|
||||
+# @Note(mhecko): We use to distinguish config instantiated from default values that we should ignore
|
||||
+# # Maybe we could make all config values None and detect it that way, but then we cannot
|
||||
+# # give the user an example how the config should look like.
|
||||
+class RhuiUseConfig(Config):
|
||||
+ section = RHUI_CONFIG_SECTION
|
||||
+ name = "use_config"
|
||||
+ type_ = fields.Boolean()
|
||||
+ default = False
|
||||
+ description = """
|
||||
+ Use values provided in the configuration file to override leapp's decisions.
|
||||
+ """
|
||||
+
|
||||
+
|
||||
+class RhuiSourcePkgs(Config):
|
||||
+ section = RHUI_CONFIG_SECTION
|
||||
+ name = "source_clients"
|
||||
+ type_ = fields.List(fields.String())
|
||||
+ default = []
|
||||
+ description = """
|
||||
+ The name of the source RHUI client RPMs (to be removed from the system).
|
||||
+ """
|
||||
+
|
||||
+
|
||||
+class RhuiTargetPkgs(Config):
|
||||
+ section = RHUI_CONFIG_SECTION
|
||||
+ name = "target_clients"
|
||||
+ type_ = fields.List(fields.String())
|
||||
+ default = []
|
||||
+ description = """
|
||||
+ The name of the target RHUI client RPM (to be installed on the system).
|
||||
+ """
|
||||
+
|
||||
+
|
||||
+class RhuiCloudProvider(Config):
|
||||
+ section = RHUI_CONFIG_SECTION
|
||||
+ name = "cloud_provider"
|
||||
+ type_ = fields.String()
|
||||
+ default = ""
|
||||
+ description = """
|
||||
+ Cloud provider name that should be used internally by leapp.
|
||||
+
|
||||
+ Leapp recognizes the following cloud providers:
|
||||
+ - azure
|
||||
+ - aws
|
||||
+ - google
|
||||
+
|
||||
+ Cloud provider information is used for triggering some provider-specific modifications. The value also
|
||||
+ influences how leapp determines target repositories to enable.
|
||||
+ """
|
||||
+
|
||||
+
|
||||
+# @Note(mhecko): We likely don't need this. We need the variant primarily to grab files from a correct directory
|
||||
+# in leapp-rhui-<provider> folders.
|
||||
+class RhuiCloudVariant(Config):
|
||||
+ section = RHUI_CONFIG_SECTION
|
||||
+ name = "image_variant"
|
||||
+ type_ = fields.String()
|
||||
+ default = "ordinary"
|
||||
+ description = """
|
||||
+ RHEL variant of the source system - is the source system SAP-specific image?
|
||||
+
|
||||
+ Leapp recognizes the following cloud providers:
|
||||
+ - ordinary # The source system has not been deployed from a RHEL with SAP image
|
||||
+ - sap # RHEL SAP images
|
||||
+ - sap-apps # RHEL SAP Apps images (Azure only)
|
||||
+ - sap-ha # RHEL HA Apps images (HA only)
|
||||
+
|
||||
+ Cloud provider information is used for triggering some provider-specific modifications. The value also
|
||||
+ influences how leapp determines target repositories to enable.
|
||||
+
|
||||
+ Default:
|
||||
+ "ordinary"
|
||||
+ """
|
||||
+
|
||||
+
|
||||
+class RhuiUpgradeFiles(Config):
|
||||
+ section = RHUI_CONFIG_SECTION
|
||||
+ name = "upgrade_files"
|
||||
+ type_ = fields.StringMap(fields.String())
|
||||
+ default = dict()
|
||||
+ description = """
|
||||
+ A mapping from source file paths to the destination where should they be
|
||||
+ placed in the upgrade container.
|
||||
+
|
||||
+ Typically, these files should be provided by leapp-rhui-<PROVIDER> packages.
|
||||
+
|
||||
+ These files are needed to facilitate access to target repositories. Typical examples are: repofile(s),
|
||||
+ certificates and keys.
|
||||
+ """
|
||||
+
|
||||
+
|
||||
+class RhuiTargetRepositoriesToUse(Config):
|
||||
+ section = RHUI_CONFIG_SECTION
|
||||
+ name = "rhui_target_repositories_to_use"
|
||||
+ type_ = fields.List(fields.String())
|
||||
+ description = """
|
||||
+ List of target repositories enabled during the upgrade. Similar to executing leapp with --enablerepo.
|
||||
+
|
||||
+ The repositories to be enabled need to be either in the repofiles listed in the `upgrade_files` field,
|
||||
+ or in repofiles present on the source system.
|
||||
+ """
|
||||
+ default = list()
|
||||
+
|
||||
+
|
||||
+all_rhui_cfg = (
|
||||
+ RhuiTargetPkgs,
|
||||
+ RhuiUpgradeFiles,
|
||||
+ RhuiTargetRepositoriesToUse,
|
||||
+ RhuiCloudProvider,
|
||||
+ RhuiCloudVariant,
|
||||
+ RhuiSourcePkgs,
|
||||
+ RhuiUseConfig
|
||||
+)
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,116 +0,0 @@
|
||||
From a71fb36ca529b323a904adc2e9048a93074bf723 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Wed, 25 Mar 2026 18:01:42 +0100
|
||||
Subject: [PATCH 35/44] fixup! fix quoting in list representation of commands
|
||||
|
||||
---
|
||||
packaging/leapp-repository.spec | 2 +-
|
||||
.../common/actors/checkrootsymlinks/actor.py | 6 +++---
|
||||
.../libraries/checkyumpluginsenabled.py | 2 +-
|
||||
.../common/actors/verifydialogs/libraries/verifydialogs.py | 7 ++++---
|
||||
.../actors/inhibitcgroupsv1/libraries/inhibitcgroupsv1.py | 6 +++---
|
||||
.../actors/inhibitcgroupsv1/tests/test_inhibitcgroupsv1.py | 4 ++--
|
||||
6 files changed, 14 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/packaging/leapp-repository.spec b/packaging/leapp-repository.spec
|
||||
index 97bc261a..3ffafafa 100644
|
||||
--- a/packaging/leapp-repository.spec
|
||||
+++ b/packaging/leapp-repository.spec
|
||||
@@ -120,7 +120,7 @@ Requires: leapp-repository-dependencies = %{leapp_repo_deps}
|
||||
|
||||
# IMPORTANT: this is capability provided by the leapp framework rpm.
|
||||
# Check that 'version' instead of the real framework rpm version.
|
||||
-Requires: leapp-framework >= 6.2, leapp-framework < 7
|
||||
+Requires: leapp-framework >= 6.4, leapp-framework < 7
|
||||
|
||||
# Since we provide sub-commands for the leapp utility, we expect the leapp
|
||||
# tool to be installed as well.
|
||||
diff --git a/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py b/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py
|
||||
index bee672bf..2e805542 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py
|
||||
@@ -52,10 +52,10 @@ class CheckRootSymlinks(Actor):
|
||||
for item in absolute_links:
|
||||
command = ' '.join(['ln',
|
||||
'-snf',
|
||||
- os.path.relpath(item.target, '/'),
|
||||
- os.path.join('/', item.name)])
|
||||
+ f"'{os.path.relpath(item.target, '/')}'",
|
||||
+ f"'{os.path.join('/', item.name)}'"])
|
||||
commands.append(command)
|
||||
- rem_commands = [['sh', '-c', '{}'.format(' && '.join(commands))]]
|
||||
+ rem_commands = [['bash', '-c', '{}'.format(' && '.join(commands))]]
|
||||
# Generate reports about non-utf8 absolute links presence
|
||||
nonutf_count = len(absolute_links_nonutf)
|
||||
if nonutf_count > 0:
|
||||
diff --git a/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py b/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py
|
||||
index 87ff6511..9afa51ac 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py
|
||||
@@ -53,7 +53,7 @@ def check_required_dnf_plugins_enabled(pkg_manager_info):
|
||||
.format(dnf_conf_path, plugin_configs_dir)
|
||||
),
|
||||
# Provide all commands as one due to problems with satellites
|
||||
- commands=[['bash', '-c', '"{0}"'.format('; '.join(remediation_commands))]]
|
||||
+ commands=[['bash', '-c', '{0}'.format('; '.join(remediation_commands))]]
|
||||
),
|
||||
reporting.ExternalLink(
|
||||
url='https://access.redhat.com/solutions/7028063',
|
||||
diff --git a/repos/system_upgrade/common/actors/verifydialogs/libraries/verifydialogs.py b/repos/system_upgrade/common/actors/verifydialogs/libraries/verifydialogs.py
|
||||
index a79079b1..84b745ca 100644
|
||||
--- a/repos/system_upgrade/common/actors/verifydialogs/libraries/verifydialogs.py
|
||||
+++ b/repos/system_upgrade/common/actors/verifydialogs/libraries/verifydialogs.py
|
||||
@@ -13,13 +13,14 @@ def check_dialogs(inhibit_if_no_userchoice=True):
|
||||
dialogs_remediation = ('Please register user choices with leapp answer cli command or by manually editing '
|
||||
'the answerfile.')
|
||||
# FIXME: Enable more choices once we can do multi-command remediations
|
||||
- cmd_remediation = [['leapp', 'answer', '--section', "{}={}".format(s, choice)]
|
||||
- for s, choices in dialog.answerfile_sections.items() for choice in choices[:1]]
|
||||
+ cmd_remediations = [['leapp', 'answer', '--section', '{}={}'.format(s, choice)]
|
||||
+ for s, choices in dialog.answerfile_sections.items()
|
||||
+ for choice in choices[:1]]
|
||||
report_data = [reporting.Title('Missing required answers in the answer file'),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
reporting.Summary(summary.format('\n'.join(sections))),
|
||||
reporting.Groups([reporting.Groups.INHIBITOR] if inhibit_if_no_userchoice else []),
|
||||
- reporting.Remediation(hint=dialogs_remediation, commands=cmd_remediation),
|
||||
+ reporting.Remediation(hint=dialogs_remediation, commands=cmd_remediations),
|
||||
reporting.ExternalLink(
|
||||
url='https://access.redhat.com/solutions/7035321',
|
||||
title='Leapp upgrade fail with error "Inhibitor: Missing required answers '
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/inhibitcgroupsv1/libraries/inhibitcgroupsv1.py b/repos/system_upgrade/el9toel10/actors/inhibitcgroupsv1/libraries/inhibitcgroupsv1.py
|
||||
index 6ae41be2..a54883b2 100644
|
||||
--- a/repos/system_upgrade/el9toel10/actors/inhibitcgroupsv1/libraries/inhibitcgroupsv1.py
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/inhibitcgroupsv1/libraries/inhibitcgroupsv1.py
|
||||
@@ -49,9 +49,9 @@ def process():
|
||||
# remove the args from commandline, the defaults are the desired values
|
||||
commands=[
|
||||
[
|
||||
- "grubby",
|
||||
- "--update-kernel=ALL",
|
||||
- '--remove-args="{}"'.format(" ".join(remediation_cmd_args)),
|
||||
+ 'grubby',
|
||||
+ '--update-kernel', 'ALL',
|
||||
+ '--remove-args', '{}'.format(' '.join(remediation_cmd_args))
|
||||
],
|
||||
],
|
||||
),
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/inhibitcgroupsv1/tests/test_inhibitcgroupsv1.py b/repos/system_upgrade/el9toel10/actors/inhibitcgroupsv1/tests/test_inhibitcgroupsv1.py
|
||||
index 9b3ec96f..629e8798 100644
|
||||
--- a/repos/system_upgrade/el9toel10/actors/inhibitcgroupsv1/tests/test_inhibitcgroupsv1.py
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/inhibitcgroupsv1/tests/test_inhibitcgroupsv1.py
|
||||
@@ -39,9 +39,9 @@ def test_inhibit_should_inhibit(monkeypatch, cmdline_params):
|
||||
assert reporting.Groups.INHIBITOR in report["groups"]
|
||||
|
||||
command = [r for r in report["detail"]["remediations"] if r["type"] == "command"][0]
|
||||
- assert "systemd.unified_cgroup_hierarchy" in command['context'][2]
|
||||
+ assert "systemd.unified_cgroup_hierarchy" in command['context'][4]
|
||||
if len(cmdline_params) == 2:
|
||||
- assert "systemd.legacy_systemd_cgroup_controller" in command['context'][2]
|
||||
+ assert "systemd.legacy_systemd_cgroup_controller" in command['context'][4]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
--
|
||||
2.53.0
|
||||
|
||||
457
SOURCES/0036-check_rhui-read-RHUI-configuration.patch
Normal file
457
SOURCES/0036-check_rhui-read-RHUI-configuration.patch
Normal file
@ -0,0 +1,457 @@
|
||||
From a03e8e5d10c1d6f3cdae216fafa0d7f0d0896494 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Sun, 10 Nov 2024 14:36:07 +0100
|
||||
Subject: [PATCH 36/40] check_rhui: read RHUI configuration
|
||||
|
||||
Extend the check_rhui actor to read user-provided RHUI configuration.
|
||||
If the provided configuration values say that the user wants to
|
||||
overrwrite leapp's decisions, then the patch checks whether all values
|
||||
are provided. If so, corresponding RHUIInfo message is produced. The
|
||||
only implemented safe-guards are those that prevent the user from
|
||||
accidentaly specifying a non-existing file to be copied into the
|
||||
scrach container during us preparing to download target userspace
|
||||
content. If the user provides only some of the configuration values
|
||||
the upgrade is terminated early with an error, providing quick feedback
|
||||
about misconfiguration. The patch has been designed to allow development
|
||||
of upgrades on previously unknown clouds (clouds without an entry in
|
||||
RHUI_SETUPS).
|
||||
|
||||
Jira ref: RHEL-56251
|
||||
---
|
||||
.../common/actors/cloud/checkrhui/actor.py | 4 +
|
||||
.../cloud/checkrhui/libraries/checkrhui.py | 102 +++++++++-
|
||||
.../tests/component_test_checkrhui.py | 178 ++++++++++++++++--
|
||||
3 files changed, 265 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/cloud/checkrhui/actor.py b/repos/system_upgrade/common/actors/cloud/checkrhui/actor.py
|
||||
index 593e73e5..933ffcb3 100644
|
||||
--- a/repos/system_upgrade/common/actors/cloud/checkrhui/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/cloud/checkrhui/actor.py
|
||||
@@ -1,4 +1,5 @@
|
||||
from leapp.actors import Actor
|
||||
+from leapp.configs.common.rhui import all_rhui_cfg
|
||||
from leapp.libraries.actor import checkrhui as checkrhui_lib
|
||||
from leapp.models import (
|
||||
CopyFile,
|
||||
@@ -8,6 +9,7 @@ from leapp.models import (
|
||||
RequiredTargetUserspacePackages,
|
||||
RHUIInfo,
|
||||
RpmTransactionTasks,
|
||||
+ TargetRepositories,
|
||||
TargetUserSpacePreupgradeTasks
|
||||
)
|
||||
from leapp.reporting import Report
|
||||
@@ -21,6 +23,7 @@ class CheckRHUI(Actor):
|
||||
"""
|
||||
|
||||
name = 'checkrhui'
|
||||
+ config_schemas = all_rhui_cfg
|
||||
consumes = (InstalledRPM,)
|
||||
produces = (
|
||||
KernelCmdlineArg,
|
||||
@@ -28,6 +31,7 @@ class CheckRHUI(Actor):
|
||||
RequiredTargetUserspacePackages,
|
||||
Report, DNFPluginTask,
|
||||
RpmTransactionTasks,
|
||||
+ TargetRepositories,
|
||||
TargetUserSpacePreupgradeTasks,
|
||||
CopyFile,
|
||||
)
|
||||
diff --git a/repos/system_upgrade/common/actors/cloud/checkrhui/libraries/checkrhui.py b/repos/system_upgrade/common/actors/cloud/checkrhui/libraries/checkrhui.py
|
||||
index 3b217917..64e36e08 100644
|
||||
--- a/repos/system_upgrade/common/actors/cloud/checkrhui/libraries/checkrhui.py
|
||||
+++ b/repos/system_upgrade/common/actors/cloud/checkrhui/libraries/checkrhui.py
|
||||
@@ -2,17 +2,29 @@ import itertools
|
||||
import os
|
||||
from collections import namedtuple
|
||||
|
||||
+import leapp.configs.common.rhui as rhui_config_lib
|
||||
from leapp import reporting
|
||||
+from leapp.configs.common.rhui import ( # Import all config fields so we are not using their name attributes directly
|
||||
+ RhuiCloudProvider,
|
||||
+ RhuiCloudVariant,
|
||||
+ RhuiSourcePkgs,
|
||||
+ RhuiTargetPkgs,
|
||||
+ RhuiTargetRepositoriesToUse,
|
||||
+ RhuiUpgradeFiles,
|
||||
+ RhuiUseConfig
|
||||
+)
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries.common import rhsm, rhui
|
||||
from leapp.libraries.common.config import version
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import (
|
||||
CopyFile,
|
||||
+ CustomTargetRepository,
|
||||
DNFPluginTask,
|
||||
InstalledRPM,
|
||||
RHUIInfo,
|
||||
RpmTransactionTasks,
|
||||
+ TargetRepositories,
|
||||
TargetRHUIPostInstallTasks,
|
||||
TargetRHUIPreInstallTasks,
|
||||
TargetRHUISetupInfo,
|
||||
@@ -291,11 +303,11 @@ def produce_rhui_info_to_setup_target(rhui_family, source_setup_desc, target_set
|
||||
api.produce(rhui_info)
|
||||
|
||||
|
||||
-def produce_rpms_to_install_into_target(source_setup, target_setup):
|
||||
- to_install = sorted(target_setup.clients - source_setup.clients)
|
||||
- to_remove = sorted(source_setup.clients - target_setup.clients)
|
||||
+def produce_rpms_to_install_into_target(source_clients, target_clients):
|
||||
+ to_install = sorted(target_clients - source_clients)
|
||||
+ to_remove = sorted(source_clients - target_clients)
|
||||
|
||||
- api.produce(TargetUserSpacePreupgradeTasks(install_rpms=sorted(target_setup.clients)))
|
||||
+ api.produce(TargetUserSpacePreupgradeTasks(install_rpms=sorted(target_clients)))
|
||||
if to_install or to_remove:
|
||||
api.produce(RpmTransactionTasks(to_install=to_install, to_remove=to_remove))
|
||||
|
||||
@@ -316,7 +328,85 @@ def inform_about_upgrade_with_rhui_without_no_rhsm():
|
||||
return False
|
||||
|
||||
|
||||
+def emit_rhui_setup_tasks_based_on_config(rhui_config_dict):
|
||||
+ config_upgrade_files = rhui_config_dict[RhuiUpgradeFiles.name]
|
||||
+
|
||||
+ nonexisting_files_to_copy = []
|
||||
+ for source_path in config_upgrade_files:
|
||||
+ if not os.path.exists(source_path):
|
||||
+ nonexisting_files_to_copy.append(source_path)
|
||||
+
|
||||
+ if nonexisting_files_to_copy:
|
||||
+ details_lines = ['The following files were not found:']
|
||||
+ # Use .format and put backticks around paths so that weird unicode spaces will be easily seen
|
||||
+ details_lines.extend(' - `{0}`'.format(path) for path in nonexisting_files_to_copy)
|
||||
+ details = '\n'.join(details_lines)
|
||||
+
|
||||
+ reason = 'RHUI config lists nonexisting files in its `{0}` field.'.format(RhuiUpgradeFiles.name)
|
||||
+ raise StopActorExecutionError(reason, details={'details': details})
|
||||
+
|
||||
+ files_to_copy_into_overlay = [CopyFile(src=key, dst=value) for key, value in config_upgrade_files.items()]
|
||||
+ preinstall_tasks = TargetRHUIPreInstallTasks(files_to_copy_into_overlay=files_to_copy_into_overlay)
|
||||
+
|
||||
+ target_client_setup_info = TargetRHUISetupInfo(
|
||||
+ preinstall_tasks=preinstall_tasks,
|
||||
+ postinstall_tasks=TargetRHUIPostInstallTasks(),
|
||||
+ bootstrap_target_client=False, # We don't need to install the client into overlay - user provided all files
|
||||
+ )
|
||||
+
|
||||
+ rhui_info = RHUIInfo(
|
||||
+ provider=rhui_config_dict[RhuiCloudProvider.name],
|
||||
+ variant=rhui_config_dict[RhuiCloudVariant.name],
|
||||
+ src_client_pkg_names=rhui_config_dict[RhuiSourcePkgs.name],
|
||||
+ target_client_pkg_names=rhui_config_dict[RhuiTargetPkgs.name],
|
||||
+ target_client_setup_info=target_client_setup_info
|
||||
+ )
|
||||
+ api.produce(rhui_info)
|
||||
+
|
||||
+
|
||||
+def request_configured_repos_to_be_enabled(rhui_config):
|
||||
+ config_repos_to_enable = rhui_config[RhuiTargetRepositoriesToUse.name]
|
||||
+ custom_repos = [CustomTargetRepository(repoid=repoid) for repoid in config_repos_to_enable]
|
||||
+ if custom_repos:
|
||||
+ target_repos = TargetRepositories(custom_repos=custom_repos, rhel_repos=[])
|
||||
+ api.produce(target_repos)
|
||||
+
|
||||
+
|
||||
+def stop_with_err_if_config_missing_fields(config):
|
||||
+ required_fields = [
|
||||
+ RhuiTargetRepositoriesToUse,
|
||||
+ RhuiCloudProvider,
|
||||
+ # RhuiCloudVariant, <- this is not required
|
||||
+ RhuiSourcePkgs,
|
||||
+ RhuiTargetPkgs,
|
||||
+ RhuiUpgradeFiles,
|
||||
+ ]
|
||||
+
|
||||
+ missing_fields = tuple(field for field in required_fields if not config[field.name])
|
||||
+ if missing_fields:
|
||||
+ field_names = (field.name for field in missing_fields)
|
||||
+ missing_fields_str = ', '.join(field_names)
|
||||
+ details = 'The following required RHUI config fields are missing or they are set to an empty value: {}'
|
||||
+ details = details.format(missing_fields_str)
|
||||
+ raise StopActorExecutionError('Provided RHUI config is missing values for required fields.',
|
||||
+ details={'details': details})
|
||||
+
|
||||
+
|
||||
def process():
|
||||
+ rhui_config = api.current_actor().config[rhui_config_lib.RHUI_CONFIG_SECTION]
|
||||
+
|
||||
+ if rhui_config[RhuiUseConfig.name]:
|
||||
+ api.current_logger().info('Skipping RHUI upgrade auto-configuration - using provided config instead.')
|
||||
+ stop_with_err_if_config_missing_fields(rhui_config)
|
||||
+ emit_rhui_setup_tasks_based_on_config(rhui_config)
|
||||
+
|
||||
+ src_clients = set(rhui_config[RhuiSourcePkgs.name])
|
||||
+ target_clients = set(rhui_config[RhuiTargetPkgs.name])
|
||||
+ produce_rpms_to_install_into_target(src_clients, target_clients)
|
||||
+
|
||||
+ request_configured_repos_to_be_enabled(rhui_config)
|
||||
+ return
|
||||
+
|
||||
installed_rpm = itertools.chain(*[installed_rpm_msg.items for installed_rpm_msg in api.consume(InstalledRPM)])
|
||||
installed_pkgs = {rpm.name for rpm in installed_rpm}
|
||||
|
||||
@@ -342,7 +432,9 @@ def process():
|
||||
# Instruction on how to access the target content
|
||||
produce_rhui_info_to_setup_target(src_rhui_setup.family, src_rhui_setup.description, target_setup_desc)
|
||||
|
||||
- produce_rpms_to_install_into_target(src_rhui_setup.description, target_setup_desc)
|
||||
+ source_clients = src_rhui_setup.description.clients
|
||||
+ target_clients = target_setup_desc.clients
|
||||
+ produce_rpms_to_install_into_target(source_clients, target_clients)
|
||||
|
||||
if src_rhui_setup.family.provider == rhui.RHUIProvider.AWS:
|
||||
# We have to disable Amazon-id plugin in the initramdisk phase as there is no network
|
||||
diff --git a/repos/system_upgrade/common/actors/cloud/checkrhui/tests/component_test_checkrhui.py b/repos/system_upgrade/common/actors/cloud/checkrhui/tests/component_test_checkrhui.py
|
||||
index 27e70eea..3ac9c1b8 100644
|
||||
--- a/repos/system_upgrade/common/actors/cloud/checkrhui/tests/component_test_checkrhui.py
|
||||
+++ b/repos/system_upgrade/common/actors/cloud/checkrhui/tests/component_test_checkrhui.py
|
||||
@@ -1,30 +1,43 @@
|
||||
-from collections import namedtuple
|
||||
+import itertools
|
||||
+import os
|
||||
+from collections import defaultdict
|
||||
from enum import Enum
|
||||
|
||||
import pytest
|
||||
|
||||
from leapp import reporting
|
||||
+from leapp.configs.common.rhui import (
|
||||
+ all_rhui_cfg,
|
||||
+ RhuiCloudProvider,
|
||||
+ RhuiCloudVariant,
|
||||
+ RhuiSourcePkgs,
|
||||
+ RhuiTargetPkgs,
|
||||
+ RhuiTargetRepositoriesToUse,
|
||||
+ RhuiUpgradeFiles,
|
||||
+ RhuiUseConfig
|
||||
+)
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries.actor import checkrhui as checkrhui_lib
|
||||
from leapp.libraries.common import rhsm, rhui
|
||||
-from leapp.libraries.common.config import mock_configs, version
|
||||
from leapp.libraries.common.rhui import mk_rhui_setup, RHUIFamily
|
||||
-from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked, produce_mocked
|
||||
+from leapp.libraries.common.testutils import (
|
||||
+ _make_default_config,
|
||||
+ create_report_mocked,
|
||||
+ CurrentActorMocked,
|
||||
+ produce_mocked
|
||||
+)
|
||||
from leapp.libraries.stdlib import api
|
||||
from leapp.models import (
|
||||
- CopyFile,
|
||||
InstalledRPM,
|
||||
- RequiredTargetUserspacePackages,
|
||||
RHUIInfo,
|
||||
RPM,
|
||||
RpmTransactionTasks,
|
||||
+ TargetRepositories,
|
||||
TargetRHUIPostInstallTasks,
|
||||
TargetRHUIPreInstallTasks,
|
||||
TargetRHUISetupInfo,
|
||||
TargetUserSpacePreupgradeTasks
|
||||
)
|
||||
-from leapp.reporting import Report
|
||||
-from leapp.snactor.fixture import current_actor_context
|
||||
|
||||
RH_PACKAGER = 'Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>'
|
||||
|
||||
@@ -95,7 +108,8 @@ def mk_cloud_map(variants):
|
||||
]
|
||||
)
|
||||
def test_determine_rhui_src_variant(monkeypatch, extra_pkgs, rhui_setups, expected_result):
|
||||
- monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(src_ver='7.9'))
|
||||
+ actor = CurrentActorMocked(src_ver='7.9', config=_make_default_config(all_rhui_cfg))
|
||||
+ monkeypatch.setattr(api, 'current_actor', actor)
|
||||
installed_pkgs = {'zip', 'zsh', 'bash', 'grubby'}.union(set(extra_pkgs))
|
||||
|
||||
if expected_result and not isinstance(expected_result, RHUIFamily): # An exception
|
||||
@@ -167,7 +181,8 @@ def test_google_specific_customization(provider, should_mutate):
|
||||
)
|
||||
def test_aws_specific_customization(monkeypatch, rhui_family, target_major, should_mutate):
|
||||
dst_ver = '{major}.0'.format(major=target_major)
|
||||
- monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(dst_ver=dst_ver))
|
||||
+ actor = CurrentActorMocked(dst_ver=dst_ver, config=_make_default_config(all_rhui_cfg))
|
||||
+ monkeypatch.setattr(api, 'current_actor', actor)
|
||||
|
||||
setup_info = mk_setup_info()
|
||||
checkrhui_lib.customize_rhui_setup_for_aws(rhui_family, setup_info)
|
||||
@@ -215,12 +230,12 @@ def produce_rhui_info_to_setup_target(monkeypatch):
|
||||
|
||||
|
||||
def test_produce_rpms_to_install_into_target(monkeypatch):
|
||||
- source_rhui_setup = mk_rhui_setup(clients={'src_pkg'}, leapp_pkg='leapp_pkg')
|
||||
- target_rhui_setup = mk_rhui_setup(clients={'target_pkg'}, leapp_pkg='leapp_pkg')
|
||||
+ source_clients = {'src_pkg'}
|
||||
+ target_clients = {'target_pkg'}
|
||||
|
||||
monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
|
||||
- checkrhui_lib.produce_rpms_to_install_into_target(source_rhui_setup, target_rhui_setup)
|
||||
+ checkrhui_lib.produce_rpms_to_install_into_target(source_clients, target_clients)
|
||||
|
||||
assert len(api.produce.model_instances) == 2
|
||||
userspace_tasks, target_rpm_tasks = api.produce.model_instances[0], api.produce.model_instances[1]
|
||||
@@ -276,7 +291,8 @@ def test_process(monkeypatch, extra_installed_pkgs, skip_rhsm, expected_action):
|
||||
installed_rpms = InstalledRPM(items=installed_pkgs)
|
||||
|
||||
monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
- monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(src_ver='7.9', msgs=[installed_rpms]))
|
||||
+ actor = CurrentActorMocked(src_ver='7.9', msgs=[installed_rpms], config=_make_default_config(all_rhui_cfg))
|
||||
+ monkeypatch.setattr(api, 'current_actor', actor)
|
||||
monkeypatch.setattr(reporting, 'create_report', create_report_mocked())
|
||||
monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: skip_rhsm)
|
||||
monkeypatch.setattr(rhui, 'RHUI_SETUPS', known_setups)
|
||||
@@ -315,7 +331,8 @@ def test_unknown_target_rhui_setup(monkeypatch, is_target_setup_known):
|
||||
installed_rpms = InstalledRPM(items=installed_pkgs)
|
||||
|
||||
monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
- monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(src_ver='7.9', msgs=[installed_rpms]))
|
||||
+ actor = CurrentActorMocked(src_ver='7.9', msgs=[installed_rpms], config=_make_default_config(all_rhui_cfg))
|
||||
+ monkeypatch.setattr(api, 'current_actor', actor)
|
||||
monkeypatch.setattr(reporting, 'create_report', create_report_mocked())
|
||||
monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: True)
|
||||
monkeypatch.setattr(rhui, 'RHUI_SETUPS', known_setups)
|
||||
@@ -374,3 +391,136 @@ def test_select_chronologically_closest(monkeypatch, setups, desired_minor, expe
|
||||
setup = setups[0]
|
||||
|
||||
assert setup == expected_setup
|
||||
+
|
||||
+
|
||||
+def test_config_overwrites_everything(monkeypatch):
|
||||
+ rhui_config = {
|
||||
+ RhuiUseConfig.name: True,
|
||||
+ RhuiSourcePkgs.name: ['client_source'],
|
||||
+ RhuiTargetPkgs.name: ['client_target'],
|
||||
+ RhuiCloudProvider.name: 'aws',
|
||||
+ RhuiUpgradeFiles.name: {
|
||||
+ '/root/file.repo': '/etc/yum.repos.d/'
|
||||
+ },
|
||||
+ RhuiTargetRepositoriesToUse.name: [
|
||||
+ 'repoid_to_use'
|
||||
+ ]
|
||||
+ }
|
||||
+ all_config = {'rhui': rhui_config}
|
||||
+
|
||||
+ actor = CurrentActorMocked(config=all_config)
|
||||
+ monkeypatch.setattr(api, 'current_actor', actor)
|
||||
+
|
||||
+ function_calls = defaultdict(int)
|
||||
+
|
||||
+ def mk_function_probe(fn_name):
|
||||
+ def probe(*args, **kwargs):
|
||||
+ function_calls[fn_name] += 1
|
||||
+ return probe
|
||||
+
|
||||
+ monkeypatch.setattr(checkrhui_lib,
|
||||
+ 'emit_rhui_setup_tasks_based_on_config',
|
||||
+ mk_function_probe('emit_rhui_setup_tasks_based_on_config'))
|
||||
+ monkeypatch.setattr(checkrhui_lib,
|
||||
+ 'stop_with_err_if_config_missing_fields',
|
||||
+ mk_function_probe('stop_with_err_if_config_missing_fields'))
|
||||
+ monkeypatch.setattr(checkrhui_lib,
|
||||
+ 'produce_rpms_to_install_into_target',
|
||||
+ mk_function_probe('produce_rpms_to_install_into_target'))
|
||||
+ monkeypatch.setattr(checkrhui_lib,
|
||||
+ 'request_configured_repos_to_be_enabled',
|
||||
+ mk_function_probe('request_configured_repos_to_be_enabled'))
|
||||
+
|
||||
+ checkrhui_lib.process()
|
||||
+
|
||||
+ expected_function_calls = {
|
||||
+ 'emit_rhui_setup_tasks_based_on_config': 1,
|
||||
+ 'stop_with_err_if_config_missing_fields': 1,
|
||||
+ 'produce_rpms_to_install_into_target': 1,
|
||||
+ 'request_configured_repos_to_be_enabled': 1,
|
||||
+ }
|
||||
+
|
||||
+ assert function_calls == expected_function_calls
|
||||
+
|
||||
+
|
||||
+def test_request_configured_repos_to_be_enabled(monkeypatch):
|
||||
+ monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
+
|
||||
+ rhui_config = {
|
||||
+ RhuiUseConfig.name: True,
|
||||
+ RhuiSourcePkgs.name: ['client_source'],
|
||||
+ RhuiTargetPkgs.name: ['client_target'],
|
||||
+ RhuiCloudProvider.name: 'aws',
|
||||
+ RhuiUpgradeFiles.name: {
|
||||
+ '/root/file.repo': '/etc/yum.repos.d/'
|
||||
+ },
|
||||
+ RhuiTargetRepositoriesToUse.name: [
|
||||
+ 'repoid1',
|
||||
+ 'repoid2',
|
||||
+ 'repoid3',
|
||||
+ ]
|
||||
+ }
|
||||
+
|
||||
+ checkrhui_lib.request_configured_repos_to_be_enabled(rhui_config)
|
||||
+
|
||||
+ assert api.produce.called
|
||||
+ assert len(api.produce.model_instances) == 1
|
||||
+
|
||||
+ target_repos = api.produce.model_instances[0]
|
||||
+ assert isinstance(target_repos, TargetRepositories)
|
||||
+ assert not target_repos.rhel_repos
|
||||
+
|
||||
+ custom_repoids = sorted(custom_repo_model.repoid for custom_repo_model in target_repos.custom_repos)
|
||||
+ assert custom_repoids == ['repoid1', 'repoid2', 'repoid3']
|
||||
+
|
||||
+
|
||||
+@pytest.mark.parametrize(
|
||||
+ ('upgrade_files', 'existing_files'),
|
||||
+ (
|
||||
+ (['/root/a', '/root/b'], ['/root/a', '/root/b']),
|
||||
+ (['/root/a', '/root/b'], ['/root/b']),
|
||||
+ (['/root/a', '/root/b'], []),
|
||||
+ )
|
||||
+)
|
||||
+def test_missing_files_in_config(monkeypatch, upgrade_files, existing_files):
|
||||
+ upgrade_files_map = dict((source_path, '/tmp/dummy') for source_path in upgrade_files)
|
||||
+
|
||||
+ rhui_config = {
|
||||
+ RhuiUseConfig.name: True,
|
||||
+ RhuiSourcePkgs.name: ['client_source'],
|
||||
+ RhuiTargetPkgs.name: ['client_target'],
|
||||
+ RhuiCloudProvider.name: 'aws',
|
||||
+ RhuiCloudVariant.name: 'ordinary',
|
||||
+ RhuiUpgradeFiles.name: upgrade_files_map,
|
||||
+ RhuiTargetRepositoriesToUse.name: [
|
||||
+ 'repoid_to_use'
|
||||
+ ]
|
||||
+ }
|
||||
+
|
||||
+ monkeypatch.setattr(os.path, 'exists', lambda path: path in existing_files)
|
||||
+ monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
+
|
||||
+ should_error = (len(upgrade_files) != len(existing_files))
|
||||
+ if should_error:
|
||||
+ with pytest.raises(StopActorExecutionError):
|
||||
+ checkrhui_lib.emit_rhui_setup_tasks_based_on_config(rhui_config)
|
||||
+ else:
|
||||
+ checkrhui_lib.emit_rhui_setup_tasks_based_on_config(rhui_config)
|
||||
+ assert api.produce.called
|
||||
+ assert len(api.produce.model_instances) == 1
|
||||
+
|
||||
+ rhui_info = api.produce.model_instances[0]
|
||||
+ assert isinstance(rhui_info, RHUIInfo)
|
||||
+ assert rhui_info.provider == 'aws'
|
||||
+ assert rhui_info.variant == 'ordinary'
|
||||
+ assert rhui_info.src_client_pkg_names == ['client_source']
|
||||
+ assert rhui_info.target_client_pkg_names == ['client_target']
|
||||
+
|
||||
+ setup_info = rhui_info.target_client_setup_info
|
||||
+ assert not setup_info.bootstrap_target_client
|
||||
+
|
||||
+ _copies_to_perform = setup_info.preinstall_tasks.files_to_copy_into_overlay
|
||||
+ copies_to_perform = sorted((copy.src, copy.dst) for copy in _copies_to_perform)
|
||||
+ expected_copies = sorted(zip(upgrade_files, itertools.repeat('/tmp/dummy')))
|
||||
+
|
||||
+ assert copies_to_perform == expected_copies
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,533 +0,0 @@
|
||||
From 7d29232bdc45e15401d24a86f5508c3b3de826d1 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Pelka <tpelka@redhat.com>
|
||||
Date: Thu, 2 Apr 2026 09:24:33 +0200
|
||||
Subject: [PATCH 36/44] pulseaudiocheck: Add PulseAudio config check for RHEL 9
|
||||
to 10 upgrade
|
||||
|
||||
PulseAudio is replaced by PipeWire in RHEL 10. Add a scanner/checker
|
||||
actor pair that detects custom PulseAudio configuration which won't
|
||||
carry over after the upgrade.
|
||||
|
||||
The scanner (FactsCollectionPhase) checks for:
|
||||
- Modified default config files via RPM verification
|
||||
- Drop-in fragments in /etc/pulse/default.pa.d/ and system.pa.d/
|
||||
- Per-user configuration in ~/.config/pulse/
|
||||
|
||||
The checker (ChecksPhase) consumes the scan results and produces
|
||||
a report with a link to the PipeWire migration guide.
|
||||
|
||||
Resolves: DESKTOP-1151
|
||||
---
|
||||
.../pulseaudiocheck/checkpulseaudio/actor.py | 20 +++
|
||||
.../libraries/checkpulseaudio.py | 86 ++++++++++++
|
||||
.../tests/test_checkpulseaudio.py | 127 ++++++++++++++++++
|
||||
.../pulseaudiocheck/scanpulseaudio/actor.py | 20 +++
|
||||
.../libraries/scanpulseaudio.py | 98 ++++++++++++++
|
||||
.../tests/test_scanpulseaudio.py | 77 +++++++++++
|
||||
.../models/pulseaudioconfiguration.py | 24 ++++
|
||||
7 files changed, 452 insertions(+)
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/actor.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/libraries/checkpulseaudio.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/tests/test_checkpulseaudio.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/actor.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/libraries/scanpulseaudio.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/tests/test_scanpulseaudio.py
|
||||
create mode 100644 repos/system_upgrade/el9toel10/models/pulseaudioconfiguration.py
|
||||
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/actor.py b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..9417d6d6
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/actor.py
|
||||
@@ -0,0 +1,20 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.libraries.actor.checkpulseaudio import check_pulseaudio
|
||||
+from leapp.models import DistributionSignedRPM, PulseAudioConfiguration, Report
|
||||
+from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
+
|
||||
+
|
||||
+class CheckPulseAudio(Actor):
|
||||
+ """
|
||||
+ Check for custom PulseAudio configuration that won't carry over after upgrade.
|
||||
+
|
||||
+ PulseAudio is replaced by PipeWire with the pipewire-pulseaudio compatibility
|
||||
+ plugin in RHEL 10. Custom PulseAudio configuration will not be applied.
|
||||
+ """
|
||||
+ name = 'check_pulseaudio'
|
||||
+ consumes = (DistributionSignedRPM, PulseAudioConfiguration)
|
||||
+ produces = (Report,)
|
||||
+ tags = (ChecksPhaseTag, IPUWorkflowTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ check_pulseaudio()
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/libraries/checkpulseaudio.py b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/libraries/checkpulseaudio.py
|
||||
new file mode 100644
|
||||
index 00000000..0453ca05
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/libraries/checkpulseaudio.py
|
||||
@@ -0,0 +1,86 @@
|
||||
+from leapp import reporting
|
||||
+from leapp.libraries.common.distro import DISTRO_REPORT_NAMES
|
||||
+from leapp.libraries.common.rpms import has_package
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import DistributionSignedRPM, PulseAudioConfiguration
|
||||
+
|
||||
+FMT_LIST_SEPARATOR = '\n - '
|
||||
+
|
||||
+
|
||||
+def _report_custom_pulseaudio_config(modified_defaults, dropin_dirs, user_config_dirs):
|
||||
+ """
|
||||
+ Create a report warning about custom PulseAudio configuration.
|
||||
+
|
||||
+ :param modified_defaults: list of modified default config files
|
||||
+ :type modified_defaults: list
|
||||
+ :param dropin_dirs: list of drop-in directories with content
|
||||
+ :type dropin_dirs: list
|
||||
+ :param user_config_dirs: list of per-user config directories
|
||||
+ :type user_config_dirs: list
|
||||
+ """
|
||||
+ details = []
|
||||
+ if modified_defaults:
|
||||
+ details.append(
|
||||
+ 'The following default PulseAudio configuration files have been modified:{sep}{files}'.format(
|
||||
+ sep=FMT_LIST_SEPARATOR,
|
||||
+ files=FMT_LIST_SEPARATOR.join(modified_defaults),
|
||||
+ )
|
||||
+ )
|
||||
+ if dropin_dirs:
|
||||
+ details.append(
|
||||
+ 'The following PulseAudio drop-in configuration directories contain custom '
|
||||
+ 'fragments:{sep}{dirs}'.format(
|
||||
+ sep=FMT_LIST_SEPARATOR,
|
||||
+ dirs=FMT_LIST_SEPARATOR.join(dropin_dirs),
|
||||
+ )
|
||||
+ )
|
||||
+ if user_config_dirs:
|
||||
+ details.append(
|
||||
+ 'Per-user PulseAudio configuration was found in:{sep}{dirs}'.format(
|
||||
+ sep=FMT_LIST_SEPARATOR,
|
||||
+ dirs=FMT_LIST_SEPARATOR.join(user_config_dirs),
|
||||
+ )
|
||||
+ )
|
||||
+
|
||||
+ summary = (
|
||||
+ 'PulseAudio is replaced by PipeWire in {target_distro} 10. The PipeWire pipewire-pulseaudio plugin provides '
|
||||
+ 'compatibility with the default PulseAudio configuration, but custom PulseAudio configuration will '
|
||||
+ 'not be applied after the upgrade. Review your PulseAudio configuration and migrate any custom '
|
||||
+ 'settings to PipeWire equivalents after upgrading.'
|
||||
+ ).format_map(DISTRO_REPORT_NAMES)
|
||||
+ if details:
|
||||
+ summary += '\n\n' + '\n\n'.join(details)
|
||||
+
|
||||
+ all_paths = modified_defaults + dropin_dirs + user_config_dirs
|
||||
+ reporting.create_report([
|
||||
+ reporting.Title('Custom PulseAudio configuration detected'),
|
||||
+ reporting.Summary(summary),
|
||||
+ reporting.Severity(reporting.Severity.MEDIUM),
|
||||
+ reporting.Groups([reporting.Groups.SERVICES]),
|
||||
+ reporting.ExternalLink(title='Migrate PulseAudio to PipeWire',
|
||||
+ url='https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Migrate-PulseAudio'),
|
||||
+ reporting.Remediation(
|
||||
+ hint='Review your PulseAudio configuration and plan to migrate custom settings to PipeWire '
|
||||
+ 'after the upgrade. The pipewire-pulseaudio plugin handles default configuration automatically.'
|
||||
+ ),
|
||||
+ reporting.RelatedResource('package', 'pulseaudio'),
|
||||
+ ] + [reporting.RelatedResource('file', f) for f in all_paths])
|
||||
+
|
||||
+
|
||||
+def check_pulseaudio():
|
||||
+ """
|
||||
+ Consume PulseAudioConfiguration and generate report if custom config is found.
|
||||
+ """
|
||||
+ if not has_package(DistributionSignedRPM, 'pulseaudio'):
|
||||
+ api.current_logger().debug('PulseAudio is not installed, skipping check.')
|
||||
+ return
|
||||
+
|
||||
+ msg = next(api.consume(PulseAudioConfiguration), None)
|
||||
+ if not msg:
|
||||
+ api.current_logger().debug('No PulseAudioConfiguration message received.')
|
||||
+ return
|
||||
+
|
||||
+ if msg.modified_defaults or msg.dropin_dirs or msg.user_config_dirs:
|
||||
+ _report_custom_pulseaudio_config(msg.modified_defaults, msg.dropin_dirs, msg.user_config_dirs)
|
||||
+ else:
|
||||
+ api.current_logger().info('No custom PulseAudio configuration detected.')
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/tests/test_checkpulseaudio.py b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/tests/test_checkpulseaudio.py
|
||||
new file mode 100644
|
||||
index 00000000..518bfb73
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/checkpulseaudio/tests/test_checkpulseaudio.py
|
||||
@@ -0,0 +1,127 @@
|
||||
+from leapp import reporting
|
||||
+from leapp.libraries.actor.checkpulseaudio import check_pulseaudio
|
||||
+from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import DistributionSignedRPM, PulseAudioConfiguration, RPM
|
||||
+
|
||||
+
|
||||
+def _generate_rpm_with_name(name):
|
||||
+ """
|
||||
+ Generate new RPM model item with given name.
|
||||
+
|
||||
+ :param name: rpm name
|
||||
+ :type name: str
|
||||
+ :return: new RPM object with name parameter set
|
||||
+ :rtype: RPM
|
||||
+ """
|
||||
+ return RPM(name=name,
|
||||
+ version='0.1',
|
||||
+ release='1.sm01',
|
||||
+ epoch='1',
|
||||
+ pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 199e2f91fd431d51',
|
||||
+ packager='Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>',
|
||||
+ arch='noarch')
|
||||
+
|
||||
+
|
||||
+class TestCheckPulseaudio:
|
||||
+ """Tests for check_pulseaudio checker function."""
|
||||
+
|
||||
+ def test_pulseaudio_not_installed(self, monkeypatch):
|
||||
+ rpms = [_generate_rpm_with_name('some-other-package')]
|
||||
+ msg = PulseAudioConfiguration(modified_defaults=['/etc/pulse/daemon.conf'])
|
||||
+ curr_actor_mocked = CurrentActorMocked(msgs=[DistributionSignedRPM(items=rpms), msg])
|
||||
+ monkeypatch.setattr(api, 'current_actor', curr_actor_mocked)
|
||||
+ monkeypatch.setattr(reporting, 'create_report', create_report_mocked())
|
||||
+
|
||||
+ check_pulseaudio()
|
||||
+
|
||||
+ assert not reporting.create_report.called
|
||||
+
|
||||
+ def test_no_message(self, monkeypatch):
|
||||
+ rpms = [_generate_rpm_with_name('pulseaudio')]
|
||||
+ curr_actor_mocked = CurrentActorMocked(msgs=[DistributionSignedRPM(items=rpms)])
|
||||
+ monkeypatch.setattr(api, 'current_actor', curr_actor_mocked)
|
||||
+ monkeypatch.setattr(reporting, 'create_report', create_report_mocked())
|
||||
+
|
||||
+ check_pulseaudio()
|
||||
+
|
||||
+ assert not reporting.create_report.called
|
||||
+
|
||||
+ def test_no_custom_config(self, monkeypatch):
|
||||
+ rpms = [_generate_rpm_with_name('pulseaudio')]
|
||||
+ msg = PulseAudioConfiguration()
|
||||
+ curr_actor_mocked = CurrentActorMocked(msgs=[DistributionSignedRPM(items=rpms), msg])
|
||||
+ monkeypatch.setattr(api, 'current_actor', curr_actor_mocked)
|
||||
+ monkeypatch.setattr(reporting, 'create_report', create_report_mocked())
|
||||
+
|
||||
+ check_pulseaudio()
|
||||
+
|
||||
+ assert not reporting.create_report.called
|
||||
+
|
||||
+ def test_modified_defaults(self, monkeypatch):
|
||||
+ rpms = [_generate_rpm_with_name('pulseaudio')]
|
||||
+ msg = PulseAudioConfiguration(
|
||||
+ modified_defaults=['/etc/pulse/daemon.conf'],
|
||||
+ )
|
||||
+ curr_actor_mocked = CurrentActorMocked(msgs=[DistributionSignedRPM(items=rpms), msg])
|
||||
+ monkeypatch.setattr(api, 'current_actor', curr_actor_mocked)
|
||||
+ monkeypatch.setattr(reporting, 'create_report', create_report_mocked())
|
||||
+
|
||||
+ check_pulseaudio()
|
||||
+
|
||||
+ assert reporting.create_report.called == 1
|
||||
+ report_fields = reporting.create_report.report_fields
|
||||
+ assert 'Custom PulseAudio configuration detected' in report_fields['title']
|
||||
+ assert '/etc/pulse/daemon.conf' in report_fields['summary']
|
||||
+
|
||||
+ def test_dropin_dirs(self, monkeypatch):
|
||||
+ rpms = [_generate_rpm_with_name('pulseaudio')]
|
||||
+ msg = PulseAudioConfiguration(
|
||||
+ dropin_dirs=['/etc/pulse/default.pa.d'],
|
||||
+ )
|
||||
+ curr_actor_mocked = CurrentActorMocked(msgs=[DistributionSignedRPM(items=rpms), msg])
|
||||
+ monkeypatch.setattr(api, 'current_actor', curr_actor_mocked)
|
||||
+ monkeypatch.setattr(reporting, 'create_report', create_report_mocked())
|
||||
+
|
||||
+ check_pulseaudio()
|
||||
+
|
||||
+ assert reporting.create_report.called == 1
|
||||
+ report_fields = reporting.create_report.report_fields
|
||||
+ assert '/etc/pulse/default.pa.d' in report_fields['summary']
|
||||
+
|
||||
+ def test_user_config_dirs(self, monkeypatch):
|
||||
+ rpms = [_generate_rpm_with_name('pulseaudio')]
|
||||
+ msg = PulseAudioConfiguration(
|
||||
+ user_config_dirs=['/home/admin/.config/pulse'],
|
||||
+ )
|
||||
+ curr_actor_mocked = CurrentActorMocked(msgs=[DistributionSignedRPM(items=rpms), msg])
|
||||
+ monkeypatch.setattr(api, 'current_actor', curr_actor_mocked)
|
||||
+ monkeypatch.setattr(reporting, 'create_report', create_report_mocked())
|
||||
+
|
||||
+ check_pulseaudio()
|
||||
+
|
||||
+ assert reporting.create_report.called == 1
|
||||
+ report_fields = reporting.create_report.report_fields
|
||||
+ assert '/home/admin/.config/pulse' in report_fields['summary']
|
||||
+
|
||||
+ def test_report_all_sources(self, monkeypatch):
|
||||
+ rpms = [_generate_rpm_with_name('pulseaudio')]
|
||||
+ msg = PulseAudioConfiguration(
|
||||
+ modified_defaults=['/etc/pulse/daemon.conf'],
|
||||
+ dropin_dirs=['/etc/pulse/default.pa.d'],
|
||||
+ user_config_dirs=['/root/.config/pulse'],
|
||||
+ )
|
||||
+ curr_actor_mocked = CurrentActorMocked(msgs=[DistributionSignedRPM(items=rpms), msg])
|
||||
+ monkeypatch.setattr(api, 'current_actor', curr_actor_mocked)
|
||||
+ monkeypatch.setattr(reporting, 'create_report', create_report_mocked())
|
||||
+
|
||||
+ check_pulseaudio()
|
||||
+
|
||||
+ assert reporting.create_report.called == 1
|
||||
+ report_fields = reporting.create_report.report_fields
|
||||
+ resources = report_fields['detail']['related_resources']
|
||||
+ pkg_resources = [r for r in resources if r['scheme'] == 'package']
|
||||
+ file_resources = [r for r in resources if r['scheme'] == 'file']
|
||||
+ assert len(pkg_resources) == 1
|
||||
+ assert pkg_resources[0]['title'] == 'pulseaudio'
|
||||
+ assert len(file_resources) == 3
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/actor.py b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..5614c802
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/actor.py
|
||||
@@ -0,0 +1,20 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.libraries.actor.scanpulseaudio import scan_pulseaudio
|
||||
+from leapp.models import PulseAudioConfiguration
|
||||
+from leapp.tags import FactsPhaseTag, IPUWorkflowTag
|
||||
+
|
||||
+
|
||||
+class ScanPulseAudio(Actor):
|
||||
+ """
|
||||
+ Scan the system for PulseAudio custom configuration.
|
||||
+
|
||||
+ Detects whether PulseAudio is installed and checks for custom
|
||||
+ configuration that will not carry over to PipeWire after upgrade.
|
||||
+ """
|
||||
+ name = 'scan_pulseaudio'
|
||||
+ consumes = ()
|
||||
+ produces = (PulseAudioConfiguration,)
|
||||
+ tags = (FactsPhaseTag, IPUWorkflowTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ self.produce(scan_pulseaudio())
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/libraries/scanpulseaudio.py b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/libraries/scanpulseaudio.py
|
||||
new file mode 100644
|
||||
index 00000000..e5c2be53
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/libraries/scanpulseaudio.py
|
||||
@@ -0,0 +1,98 @@
|
||||
+import os
|
||||
+import pwd
|
||||
+
|
||||
+from leapp.libraries.common.rpms import check_file_modification
|
||||
+from leapp.models import PulseAudioConfiguration
|
||||
+
|
||||
+# System-wide PulseAudio configuration directory
|
||||
+PULSEAUDIO_CONFIG_DIR = '/etc/pulse'
|
||||
+
|
||||
+# Drop-in directories included from default.pa and system.pa
|
||||
+_DROPIN_DIRS = (
|
||||
+ '/etc/pulse/default.pa.d',
|
||||
+ '/etc/pulse/system.pa.d',
|
||||
+)
|
||||
+
|
||||
+# Files that are part of the default PulseAudio installation
|
||||
+_DEFAULT_CONFIG_FILES = frozenset((
|
||||
+ 'client.conf',
|
||||
+ 'daemon.conf',
|
||||
+ 'default.pa',
|
||||
+ 'system.pa',
|
||||
+))
|
||||
+
|
||||
+# Per-user PulseAudio config directory relative to home
|
||||
+_USER_CONFIG_SUBDIR = '.config/pulse'
|
||||
+
|
||||
+
|
||||
+def _get_dropin_dirs_with_content():
|
||||
+ """
|
||||
+ Return list of drop-in directories that exist and contain files.
|
||||
+
|
||||
+ PulseAudio includes fragments from /etc/pulse/default.pa.d/ and
|
||||
+ /etc/pulse/system.pa.d/ via .include directives. These directories
|
||||
+ do not exist by default.
|
||||
+
|
||||
+ :return: list of drop-in directory paths that contain files
|
||||
+ :rtype: list
|
||||
+ """
|
||||
+ found = []
|
||||
+ for dropin_dir in _DROPIN_DIRS:
|
||||
+ if os.path.isdir(dropin_dir) and os.listdir(dropin_dir):
|
||||
+ found.append(dropin_dir)
|
||||
+ return found
|
||||
+
|
||||
+
|
||||
+def _get_user_config_dirs():
|
||||
+ """
|
||||
+ Return list of user home directories that contain PulseAudio configuration.
|
||||
+
|
||||
+ Checks ~/.config/pulse/ for each user with a valid home directory.
|
||||
+
|
||||
+ :return: list of per-user PulseAudio config directory paths
|
||||
+ :rtype: list
|
||||
+ """
|
||||
+ found = []
|
||||
+ for user in pwd.getpwall():
|
||||
+ pulse_dir = os.path.join(user.pw_dir, _USER_CONFIG_SUBDIR)
|
||||
+ if os.path.isdir(pulse_dir) and os.listdir(pulse_dir):
|
||||
+ found.append(pulse_dir)
|
||||
+ return sorted(found)
|
||||
+
|
||||
+
|
||||
+def _check_default_configs_modified():
|
||||
+ """
|
||||
+ Check whether any of the default PulseAudio config files have been modified.
|
||||
+
|
||||
+ Uses RPM verification to detect changes to files owned by the pulseaudio
|
||||
+ package. Returns list of modified default config file paths.
|
||||
+
|
||||
+ :return: list of modified default config file paths
|
||||
+ :rtype: list
|
||||
+ """
|
||||
+ modified = []
|
||||
+ for filename in sorted(_DEFAULT_CONFIG_FILES):
|
||||
+ filepath = os.path.join(PULSEAUDIO_CONFIG_DIR, filename)
|
||||
+ if os.path.isfile(filepath):
|
||||
+ if check_file_modification(filepath):
|
||||
+ modified.append(filepath)
|
||||
+
|
||||
+ return modified
|
||||
+
|
||||
+
|
||||
+def scan_pulseaudio():
|
||||
+ """
|
||||
+ Scan the system for PulseAudio configuration and return findings.
|
||||
+
|
||||
+ :return: PulseAudioConfiguration message with scan results
|
||||
+ :rtype: PulseAudioConfiguration
|
||||
+ """
|
||||
+ modified_defaults = _check_default_configs_modified()
|
||||
+ dropin_dirs = _get_dropin_dirs_with_content()
|
||||
+ user_config_dirs = _get_user_config_dirs()
|
||||
+
|
||||
+ return PulseAudioConfiguration(
|
||||
+ modified_defaults=modified_defaults,
|
||||
+ dropin_dirs=dropin_dirs,
|
||||
+ user_config_dirs=user_config_dirs,
|
||||
+ )
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/tests/test_scanpulseaudio.py b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/tests/test_scanpulseaudio.py
|
||||
new file mode 100644
|
||||
index 00000000..f499aafe
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/pulseaudiocheck/scanpulseaudio/tests/test_scanpulseaudio.py
|
||||
@@ -0,0 +1,77 @@
|
||||
+import os
|
||||
+
|
||||
+from leapp.libraries.actor import scanpulseaudio
|
||||
+from leapp.libraries.actor.scanpulseaudio import _get_dropin_dirs_with_content, _get_user_config_dirs, scan_pulseaudio
|
||||
+
|
||||
+
|
||||
+class TestGetDropinDirsWithContent:
|
||||
+ """Tests for _get_dropin_dirs_with_content."""
|
||||
+
|
||||
+ def test_no_dropin_dirs(self, monkeypatch):
|
||||
+ monkeypatch.setattr(os.path, 'isdir', lambda _: False)
|
||||
+ assert _get_dropin_dirs_with_content() == []
|
||||
+
|
||||
+ def test_empty_dropin_dirs(self, monkeypatch):
|
||||
+ monkeypatch.setattr(os.path, 'isdir', lambda _: True)
|
||||
+ monkeypatch.setattr(os, 'listdir', lambda _: [])
|
||||
+ assert _get_dropin_dirs_with_content() == []
|
||||
+
|
||||
+ def test_dropin_dirs_with_content(self, monkeypatch):
|
||||
+ monkeypatch.setattr(os.path, 'isdir', lambda _: True)
|
||||
+ monkeypatch.setattr(os, 'listdir', lambda _: ['custom.conf'])
|
||||
+ result = _get_dropin_dirs_with_content()
|
||||
+ assert result == ['/etc/pulse/default.pa.d', '/etc/pulse/system.pa.d']
|
||||
+
|
||||
+ def test_only_one_dropin_dir_exists(self, monkeypatch):
|
||||
+ monkeypatch.setattr(os.path, 'isdir', lambda path: path == '/etc/pulse/default.pa.d')
|
||||
+ monkeypatch.setattr(os, 'listdir', lambda _: ['custom.conf'])
|
||||
+ result = _get_dropin_dirs_with_content()
|
||||
+ assert result == ['/etc/pulse/default.pa.d']
|
||||
+
|
||||
+
|
||||
+class TestGetUserConfigDirs:
|
||||
+ """Tests for _get_user_config_dirs."""
|
||||
+
|
||||
+ def test_no_user_config(self, monkeypatch):
|
||||
+ monkeypatch.setattr(os.path, 'isdir', lambda _: False)
|
||||
+ assert _get_user_config_dirs() == []
|
||||
+
|
||||
+ def test_user_config_found(self, monkeypatch):
|
||||
+ monkeypatch.setattr(os.path, 'isdir', lambda path: path == '/home/testuser/.config/pulse')
|
||||
+ monkeypatch.setattr(os, 'listdir', lambda _: ['default.pa'])
|
||||
+
|
||||
+ class FakeUser:
|
||||
+ pw_dir = '/home/testuser'
|
||||
+
|
||||
+ monkeypatch.setattr(scanpulseaudio.pwd, 'getpwall', lambda: [FakeUser()])
|
||||
+ result = _get_user_config_dirs()
|
||||
+ assert result == ['/home/testuser/.config/pulse']
|
||||
+
|
||||
+
|
||||
+class TestScanPulseaudio:
|
||||
+ """Tests for scan_pulseaudio main function."""
|
||||
+
|
||||
+ def test_no_custom_config(self, monkeypatch):
|
||||
+ monkeypatch.setattr(scanpulseaudio, '_check_default_configs_modified', lambda: [])
|
||||
+ monkeypatch.setattr(scanpulseaudio, '_get_dropin_dirs_with_content', lambda: [])
|
||||
+ monkeypatch.setattr(scanpulseaudio, '_get_user_config_dirs', lambda: [])
|
||||
+
|
||||
+ result = scan_pulseaudio()
|
||||
+
|
||||
+ assert result.modified_defaults == []
|
||||
+ assert result.dropin_dirs == []
|
||||
+ assert result.user_config_dirs == []
|
||||
+
|
||||
+ def test_with_all_findings(self, monkeypatch):
|
||||
+ monkeypatch.setattr(scanpulseaudio, '_check_default_configs_modified',
|
||||
+ lambda: ['/etc/pulse/daemon.conf'])
|
||||
+ monkeypatch.setattr(scanpulseaudio, '_get_dropin_dirs_with_content',
|
||||
+ lambda: ['/etc/pulse/default.pa.d'])
|
||||
+ monkeypatch.setattr(scanpulseaudio, '_get_user_config_dirs',
|
||||
+ lambda: ['/root/.config/pulse'])
|
||||
+
|
||||
+ result = scan_pulseaudio()
|
||||
+
|
||||
+ assert result.modified_defaults == ['/etc/pulse/daemon.conf']
|
||||
+ assert result.dropin_dirs == ['/etc/pulse/default.pa.d']
|
||||
+ assert result.user_config_dirs == ['/root/.config/pulse']
|
||||
diff --git a/repos/system_upgrade/el9toel10/models/pulseaudioconfiguration.py b/repos/system_upgrade/el9toel10/models/pulseaudioconfiguration.py
|
||||
new file mode 100644
|
||||
index 00000000..bfb7aa22
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el9toel10/models/pulseaudioconfiguration.py
|
||||
@@ -0,0 +1,24 @@
|
||||
+from leapp.models import fields, Model
|
||||
+from leapp.topics import SystemInfoTopic
|
||||
+
|
||||
+
|
||||
+class PulseAudioConfiguration(Model):
|
||||
+ """
|
||||
+ Model describing the state of PulseAudio configuration on the system.
|
||||
+ """
|
||||
+ topic = SystemInfoTopic
|
||||
+
|
||||
+ modified_defaults = fields.List(fields.String(), default=[])
|
||||
+ """
|
||||
+ Default config files modified from RPM originals (full paths)
|
||||
+ """
|
||||
+
|
||||
+ dropin_dirs = fields.List(fields.String(), default=[])
|
||||
+ """
|
||||
+ Drop-in directories that exist and contain files (full paths)
|
||||
+ """
|
||||
+
|
||||
+ user_config_dirs = fields.List(fields.String(), default=[])
|
||||
+ """
|
||||
+ Per-user config directories that exist and contain files (full paths)
|
||||
+ """
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From 87c192519e8764f59516cca563816f062428a533 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Mocary <pmocary@redhat.com>
|
||||
Date: Thu, 2 Apr 2026 16:28:48 +0200
|
||||
Subject: [PATCH 37/44] fix(checkyumpluginsenabled): correctly create
|
||||
remediation command
|
||||
|
||||
The remediation command for the inhibitor triggered when required dnf
|
||||
plugins are not enabled was created incorrectly. This patch fixes the
|
||||
command creation.
|
||||
---
|
||||
.../libraries/checkyumpluginsenabled.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py b/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py
|
||||
index 9afa51ac..869e2a88 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py
|
||||
@@ -36,8 +36,8 @@ def check_required_dnf_plugins_enabled(pkg_manager_info):
|
||||
product_id_plugin_conf = os.path.join(plugin_configs_dir, 'product-id.conf')
|
||||
|
||||
remediation_commands = [
|
||||
- f"sed -i 's/^plugins=0/plugins=1/' '{dnf_conf_path}'"
|
||||
- f"sed -i 's/^enabled=0/enabled=1/' '{rhsm_plugin_conf}'"
|
||||
+ f"sed -i 's/^plugins=0/plugins=1/' '{dnf_conf_path}'",
|
||||
+ f"sed -i 's/^enabled=0/enabled=1/' '{rhsm_plugin_conf}'",
|
||||
f"sed -i 's/^enabled=0/enabled=1/' '{product_id_plugin_conf}'"
|
||||
]
|
||||
|
||||
--
|
||||
2.53.0
|
||||
|
||||
53
SOURCES/0037-testutils-add-support-for-configs.patch
Normal file
53
SOURCES/0037-testutils-add-support-for-configs.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From a206a7f02c68f50ab50c9f547669d3a4178c4bd2 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Wed, 16 Oct 2024 17:38:36 +0200
|
||||
Subject: [PATCH 37/40] testutils: add support for configs
|
||||
|
||||
Extend the CurrentActorMocked class to accept a `config` value,
|
||||
allowing developers to mock actors that rely on configuration.
|
||||
A library function `_make_default_config` is also introduced,
|
||||
allowing to instantiate default configs from config schemas.
|
||||
---
|
||||
repos/system_upgrade/common/libraries/testutils.py | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/libraries/testutils.py b/repos/system_upgrade/common/libraries/testutils.py
|
||||
index c538af1a..afeb360a 100644
|
||||
--- a/repos/system_upgrade/common/libraries/testutils.py
|
||||
+++ b/repos/system_upgrade/common/libraries/testutils.py
|
||||
@@ -4,6 +4,7 @@ import os
|
||||
from collections import namedtuple
|
||||
|
||||
from leapp import reporting
|
||||
+from leapp.actors.config import _normalize_config, normalize_schemas
|
||||
from leapp.libraries.common.config import architecture
|
||||
from leapp.models import EnvVar
|
||||
from leapp.utils.deprecation import deprecated
|
||||
@@ -67,9 +68,15 @@ class logger_mocked(object):
|
||||
return self
|
||||
|
||||
|
||||
+def _make_default_config(actor_config_schema):
|
||||
+ """ Make a config dict populated with default values. """
|
||||
+ merged_schema = normalize_schemas((actor_config_schema, ))
|
||||
+ return _normalize_config({}, merged_schema) # Will fill default values during normalization
|
||||
+
|
||||
+
|
||||
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',
|
||||
- release_id='rhel', src_ver='7.8', dst_ver='8.1', msgs=None, flavour='default'):
|
||||
+ release_id='rhel', src_ver='7.8', dst_ver='8.1', msgs=None, flavour='default', config=None):
|
||||
envarsList = [EnvVar(name=k, value=v) for k, v in envars.items()] if envars else []
|
||||
version = namedtuple('Version', ['source', 'target'])(src_ver, dst_ver)
|
||||
release = namedtuple('OS_release', ['release_id', 'version_id'])(release_id, src_ver)
|
||||
@@ -82,6 +89,7 @@ class CurrentActorMocked(object): # pylint:disable=R0904
|
||||
'configuration', ['architecture', 'kernel', 'leapp_env_vars', 'os_release', 'version', 'flavour']
|
||||
)(arch, kernel, envarsList, release, version, flavour)
|
||||
self._msgs = msgs or []
|
||||
+ self.config = {} if config is None else config
|
||||
|
||||
def __call__(self):
|
||||
return self
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,201 +0,0 @@
|
||||
From 0cfeee9fa113690c7e58877edf65842aad7d7ce5 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Fri, 27 Mar 2026 13:53:49 +0100
|
||||
Subject: [PATCH 38/44] fix(rhui): consider source clients always signed
|
||||
|
||||
Previously, all RHUI clients mentioned in the cloud map in the rhui.py
|
||||
library were considered as signed by RH. However, configs allow using
|
||||
clients that are not known to leapp, and, therefore, such clients would
|
||||
not be considered as signed. Consequently, these packages would not be
|
||||
removed, causing the upgrade to fail. This patch changes this behavior
|
||||
so that all source clients mentioned in the RHUIInfo message are
|
||||
considered as signed.
|
||||
---
|
||||
.../filterrpmtransactionevents/actor.py | 12 +-
|
||||
.../tests/test_filterrpmtransactionevents.py | 120 +++++++++++++++++-
|
||||
2 files changed, 125 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/filterrpmtransactionevents/actor.py b/repos/system_upgrade/common/actors/filterrpmtransactionevents/actor.py
|
||||
index 582a5821..aa735da3 100644
|
||||
--- a/repos/system_upgrade/common/actors/filterrpmtransactionevents/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/filterrpmtransactionevents/actor.py
|
||||
@@ -1,8 +1,11 @@
|
||||
from leapp.actors import Actor
|
||||
+from leapp.libraries.common.rpms import has_package
|
||||
from leapp.models import (
|
||||
DistributionSignedRPM,
|
||||
FilteredRpmTransactionTasks,
|
||||
+ InstalledRPM,
|
||||
PESRpmTransactionTasks,
|
||||
+ RHUIInfo,
|
||||
RpmTransactionTasks
|
||||
)
|
||||
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
@@ -18,7 +21,7 @@ class FilterRpmTransactionTasks(Actor):
|
||||
"""
|
||||
|
||||
name = 'check_rpm_transaction_events'
|
||||
- consumes = (PESRpmTransactionTasks, RpmTransactionTasks, DistributionSignedRPM,)
|
||||
+ consumes = (PESRpmTransactionTasks, RpmTransactionTasks, DistributionSignedRPM, RHUIInfo, InstalledRPM)
|
||||
produces = (FilteredRpmTransactionTasks,)
|
||||
tags = (IPUWorkflowTag, ChecksPhaseTag)
|
||||
|
||||
@@ -27,6 +30,13 @@ class FilterRpmTransactionTasks(Actor):
|
||||
for rpm_pkgs in self.consume(DistributionSignedRPM):
|
||||
installed_pkgs.update([pkg.name for pkg in rpm_pkgs.items])
|
||||
|
||||
+ # Consider all RHUI source clients as signed, so that we can always remove them
|
||||
+ rhui_info = next(self.consume(RHUIInfo), None)
|
||||
+ if rhui_info:
|
||||
+ for source_client in rhui_info.src_client_pkg_names:
|
||||
+ if has_package(InstalledRPM, source_client):
|
||||
+ installed_pkgs.add(source_client)
|
||||
+
|
||||
local_rpms = set()
|
||||
to_install = set()
|
||||
to_remove = set()
|
||||
diff --git a/repos/system_upgrade/common/actors/filterrpmtransactionevents/tests/test_filterrpmtransactionevents.py b/repos/system_upgrade/common/actors/filterrpmtransactionevents/tests/test_filterrpmtransactionevents.py
|
||||
index 7173805e..a228ed07 100644
|
||||
--- a/repos/system_upgrade/common/actors/filterrpmtransactionevents/tests/test_filterrpmtransactionevents.py
|
||||
+++ b/repos/system_upgrade/common/actors/filterrpmtransactionevents/tests/test_filterrpmtransactionevents.py
|
||||
@@ -1,7 +1,37 @@
|
||||
-from leapp.models import DistributionSignedRPM, FilteredRpmTransactionTasks, Module, RPM, RpmTransactionTasks
|
||||
+from leapp.models import (
|
||||
+ DistributionSignedRPM,
|
||||
+ FilteredRpmTransactionTasks,
|
||||
+ InstalledRPM,
|
||||
+ Module,
|
||||
+ RHUIInfo,
|
||||
+ RPM,
|
||||
+ RpmTransactionTasks,
|
||||
+ TargetRHUIPostInstallTasks,
|
||||
+ TargetRHUIPreInstallTasks,
|
||||
+ TargetRHUISetupInfo
|
||||
+)
|
||||
from leapp.snactor.fixture import current_actor_context
|
||||
|
||||
RH_PACKAGER = 'Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>'
|
||||
+UNSIGNED_PACKAGER = 'Third Party <third@party.com>'
|
||||
+
|
||||
+
|
||||
+def _make_rpm(name, packager=RH_PACKAGER):
|
||||
+ return RPM(name=name, version='0.1', release='1.sm01', epoch='1',
|
||||
+ packager=packager, arch='noarch', pgpsig='SOME_PGP_SIG')
|
||||
+
|
||||
+
|
||||
+def _make_rhui_info(src_clients, target_clients, provider='azure'):
|
||||
+ setup_info = TargetRHUISetupInfo(
|
||||
+ preinstall_tasks=TargetRHUIPreInstallTasks(),
|
||||
+ postinstall_tasks=TargetRHUIPostInstallTasks(),
|
||||
+ )
|
||||
+ return RHUIInfo(
|
||||
+ provider=provider,
|
||||
+ src_client_pkg_names=src_clients,
|
||||
+ target_client_pkg_names=target_clients,
|
||||
+ target_client_setup_info=setup_info,
|
||||
+ )
|
||||
|
||||
|
||||
def test_actor_execution(current_actor_context):
|
||||
@@ -10,11 +40,7 @@ def test_actor_execution(current_actor_context):
|
||||
|
||||
|
||||
def test_actor_execution_with_sample_data(current_actor_context):
|
||||
- installed_rpm = [
|
||||
- RPM(name='sample01', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch',
|
||||
- pgpsig='SOME_PGP_SIG'),
|
||||
- RPM(name='sample02', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch',
|
||||
- pgpsig='SOME_PGP_SIG')]
|
||||
+ installed_rpm = [_make_rpm('sample01'), _make_rpm('sample02')]
|
||||
modules_to_enable = [Module(name='enable', stream='1'), Module(name='enable', stream='2')]
|
||||
modules_to_reset = [Module(name='reset', stream='1'), Module(name='reset', stream='2')]
|
||||
current_actor_context.feed(DistributionSignedRPM(items=installed_rpm))
|
||||
@@ -43,3 +69,85 @@ def test_actor_execution_with_sample_data(current_actor_context):
|
||||
assert all(m.name == 'reset' for m in result[0].modules_to_reset)
|
||||
assert '1' in {m.stream for m in result[0].modules_to_reset}
|
||||
assert '2' in {m.stream for m in result[0].modules_to_reset}
|
||||
+
|
||||
+
|
||||
+def test_rhui_source_client_treated_as_signed(current_actor_context):
|
||||
+ """Installed RHUI source clients should be removable even if they are not distribution-signed."""
|
||||
+ rhui_client_rpm = _make_rpm('rhui-azure-rhel8', packager=UNSIGNED_PACKAGER)
|
||||
+ signed_rpm = _make_rpm('sample01')
|
||||
+
|
||||
+ current_actor_context.feed(DistributionSignedRPM(items=[signed_rpm]))
|
||||
+ current_actor_context.feed(InstalledRPM(items=[rhui_client_rpm, signed_rpm]))
|
||||
+ current_actor_context.feed(_make_rhui_info(['rhui-azure-rhel8'], ['rhui-azure-rhel9']))
|
||||
+ current_actor_context.feed(RpmTransactionTasks(to_remove=['rhui-azure-rhel8']))
|
||||
+ current_actor_context.run()
|
||||
+
|
||||
+ result = current_actor_context.consume(FilteredRpmTransactionTasks)
|
||||
+ assert len(result) == 1
|
||||
+ assert 'rhui-azure-rhel8' in result[0].to_remove
|
||||
+
|
||||
+
|
||||
+def test_rhui_source_client_not_installed_is_ignored(current_actor_context):
|
||||
+ """RHUI source clients that are not installed should not be added to the installed set."""
|
||||
+ signed_rpm = _make_rpm('sample01')
|
||||
+
|
||||
+ current_actor_context.feed(DistributionSignedRPM(items=[signed_rpm]))
|
||||
+ current_actor_context.feed(InstalledRPM(items=[signed_rpm]))
|
||||
+ current_actor_context.feed(_make_rhui_info(['rhui-azure-rhel8'], ['rhui-azure-rhel9']))
|
||||
+ current_actor_context.feed(RpmTransactionTasks(to_remove=['rhui-azure-rhel8']))
|
||||
+ current_actor_context.run()
|
||||
+
|
||||
+ result = current_actor_context.consume(FilteredRpmTransactionTasks)
|
||||
+ assert len(result) == 1
|
||||
+ assert 'rhui-azure-rhel8' not in result[0].to_remove
|
||||
+
|
||||
+
|
||||
+def test_no_rhui_info_unsigned_pkg_not_removable(current_actor_context):
|
||||
+ """Without RHUIInfo, unsigned packages should not be removable (baseline behavior)."""
|
||||
+ unsigned_rpm = _make_rpm('some-unsigned-pkg', packager=UNSIGNED_PACKAGER)
|
||||
+ signed_rpm = _make_rpm('sample01')
|
||||
+
|
||||
+ current_actor_context.feed(DistributionSignedRPM(items=[signed_rpm]))
|
||||
+ current_actor_context.feed(InstalledRPM(items=[unsigned_rpm, signed_rpm]))
|
||||
+ current_actor_context.feed(RpmTransactionTasks(to_remove=['some-unsigned-pkg']))
|
||||
+ current_actor_context.run()
|
||||
+
|
||||
+ result = current_actor_context.consume(FilteredRpmTransactionTasks)
|
||||
+ assert len(result) == 1
|
||||
+ assert 'some-unsigned-pkg' not in result[0].to_remove
|
||||
+
|
||||
+
|
||||
+def test_rhui_multiple_source_clients(current_actor_context):
|
||||
+ """Multiple RHUI source clients should all be treated as signed when installed."""
|
||||
+ client_rpms = [
|
||||
+ _make_rpm('rhui-client-a', packager=UNSIGNED_PACKAGER),
|
||||
+ _make_rpm('rhui-client-b', packager=UNSIGNED_PACKAGER),
|
||||
+ ]
|
||||
+
|
||||
+ current_actor_context.feed(DistributionSignedRPM(items=[]))
|
||||
+ current_actor_context.feed(InstalledRPM(items=client_rpms))
|
||||
+ current_actor_context.feed(_make_rhui_info(['rhui-client-a', 'rhui-client-b'], ['rhui-client-target']))
|
||||
+ current_actor_context.feed(RpmTransactionTasks(
|
||||
+ to_remove=['rhui-client-a', 'rhui-client-b'],
|
||||
+ ))
|
||||
+ current_actor_context.run()
|
||||
+
|
||||
+ result = current_actor_context.consume(FilteredRpmTransactionTasks)
|
||||
+ assert len(result) == 1
|
||||
+ assert 'rhui-client-a' in result[0].to_remove
|
||||
+ assert 'rhui-client-b' in result[0].to_remove
|
||||
+
|
||||
+
|
||||
+def test_rhui_source_client_ends_up_in_upgrade_if_not_removed(current_actor_context):
|
||||
+ """An installed RHUI source client not in to_remove/to_install should be upgraded."""
|
||||
+ rhui_client_rpm = _make_rpm('rhui-azure-rhel8', packager=UNSIGNED_PACKAGER)
|
||||
+
|
||||
+ current_actor_context.feed(DistributionSignedRPM(items=[]))
|
||||
+ current_actor_context.feed(InstalledRPM(items=[rhui_client_rpm]))
|
||||
+ current_actor_context.feed(_make_rhui_info(['rhui-azure-rhel8'], ['rhui-azure-rhel9']))
|
||||
+ current_actor_context.feed(RpmTransactionTasks())
|
||||
+ current_actor_context.run()
|
||||
+
|
||||
+ result = current_actor_context.consume(FilteredRpmTransactionTasks)
|
||||
+ assert len(result) == 1
|
||||
+ assert 'rhui-azure-rhel8' in result[0].to_upgrade
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From 0147bc268607e5931ebca95e3253087ec71a3c66 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Sun, 20 Oct 2024 16:08:49 +0200
|
||||
Subject: [PATCH 38/40] userspacegen(rhui): remove repofiles only if now owned
|
||||
by an RPM
|
||||
|
||||
We copy files into the target userspace when setting up target
|
||||
repository content. If this file is named equally as some of the
|
||||
files installed by the target RHUI client installed during early
|
||||
phases of target userspace setup process, we would delete it in
|
||||
cleanup. Therefore, if we copy a repofile named /etc/yum.repos.d/X.repo
|
||||
and the target client also owns a file /etc/yum.repos.d/X.repo, we
|
||||
would remove it, making the container loose access to target content.
|
||||
This patch prevents us from blindly deleting files, keeping files that
|
||||
are owned by some RPM (usually that would be the target RHUI client).
|
||||
---
|
||||
.../libraries/userspacegen.py | 30 ++++++++++++++-----
|
||||
1 file changed, 22 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
index d7698056..12736ab7 100644
|
||||
--- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
+++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py
|
||||
@@ -1120,6 +1120,27 @@ def _get_target_userspace():
|
||||
return constants.TARGET_USERSPACE.format(get_target_major_version())
|
||||
|
||||
|
||||
+def _remove_injected_repofiles_from_our_rhui_packages(target_userspace_ctx, rhui_setup_info):
|
||||
+ target_userspace_path = _get_target_userspace()
|
||||
+ for copy in rhui_setup_info.preinstall_tasks.files_to_copy_into_overlay:
|
||||
+ dst_in_container = get_copy_location_from_copy_in_task(target_userspace_path, copy)
|
||||
+ dst_in_container = dst_in_container.strip('/')
|
||||
+ dst_in_host = os.path.join(target_userspace_path, dst_in_container)
|
||||
+
|
||||
+ if os.path.isfile(dst_in_host) and dst_in_host.endswith('.repo'):
|
||||
+ # The repofile might have been replaced by a new one provided by the RHUI client if names collide
|
||||
+ # Performance: Do the query here and not earlier, because we would be running rpm needlessly
|
||||
+ try:
|
||||
+ path_with_root = '/' + dst_in_container
|
||||
+ target_userspace_ctx.call(['rpm', '-q', '--whatprovides', path_with_root])
|
||||
+ api.current_logger().debug('Repofile {0} kept as it is owned by some RPM.'.format(dst_in_host))
|
||||
+ except CalledProcessError:
|
||||
+ # rpm exists with 1 if the file is not owned by any RPM. We might be catching all kinds of other
|
||||
+ # problems here, but still better than always removing repofiles.
|
||||
+ api.current_logger().debug('Removing repofile - not owned by any RPM: {0}'.format(dst_in_host))
|
||||
+ os.remove(dst_in_host)
|
||||
+
|
||||
+
|
||||
def _create_target_userspace(context, indata, packages, files, target_repoids):
|
||||
"""Create the target userspace."""
|
||||
target_path = _get_target_userspace()
|
||||
@@ -1139,14 +1160,7 @@ def _create_target_userspace(context, indata, packages, files, target_repoids):
|
||||
)
|
||||
setup_info = indata.rhui_info.target_client_setup_info
|
||||
if not setup_info.bootstrap_target_client:
|
||||
- target_userspace_path = _get_target_userspace()
|
||||
- for copy in setup_info.preinstall_tasks.files_to_copy_into_overlay:
|
||||
- dst_in_container = get_copy_location_from_copy_in_task(target_userspace_path, copy)
|
||||
- dst_in_container = dst_in_container.strip('/')
|
||||
- dst_in_host = os.path.join(target_userspace_path, dst_in_container)
|
||||
- if os.path.isfile(dst_in_host) and dst_in_host.endswith('.repo'):
|
||||
- api.current_logger().debug('Removing repofile: {0}'.format(dst_in_host))
|
||||
- os.remove(dst_in_host)
|
||||
+ _remove_injected_repofiles_from_our_rhui_packages(context, setup_info)
|
||||
|
||||
# and do not forget to set the rhsm into the container mode again
|
||||
with mounting.NspawnActions(_get_target_userspace()) as target_context:
|
||||
--
|
||||
2.47.0
|
||||
|
||||
857
SOURCES/0039-Enable-IPU-for-EL-9.6-and-drop-EL-8.8-9.2.patch
Normal file
857
SOURCES/0039-Enable-IPU-for-EL-9.6-and-drop-EL-8.8-9.2.patch
Normal file
@ -0,0 +1,857 @@
|
||||
From c2f2895bb570a75eb2aaa7b84a2bcd9dcd537b0e Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Thu, 14 Nov 2024 14:24:15 +0100
|
||||
Subject: [PATCH 39/40] Enable IPU for EL 9.6 (and drop EL 8.8/9.2)
|
||||
|
||||
* Add product certificates for RHEL 9.6
|
||||
* Introduce upgrade path 8.10 -> 9.6
|
||||
* Drop IPUs related to EL 8.8 and 9.2
|
||||
* This will not be supported in this release.
|
||||
* Keeping for now still IPU 8.10 -> 9.5 as it is a fresh release
|
||||
so it has a value for us to run tests there. We will drop it
|
||||
later during this lifecycle (CTC-2?).
|
||||
* Drop EL 8.8 from the list of supported versions
|
||||
* Update tests in packit
|
||||
* Note that tests for 9.6 could be failing for a while until
|
||||
composes are created.
|
||||
|
||||
jira: RHEL-67621
|
||||
---
|
||||
.packit.yaml | 257 +++++-------------
|
||||
.../common/files/prod-certs/9.6/279.pem | 37 +++
|
||||
.../common/files/prod-certs/9.6/362.pem | 37 +++
|
||||
.../common/files/prod-certs/9.6/363.pem | 37 +++
|
||||
.../common/files/prod-certs/9.6/419.pem | 36 +++
|
||||
.../common/files/prod-certs/9.6/433.pem | 37 +++
|
||||
.../common/files/prod-certs/9.6/479.pem | 36 +++
|
||||
.../common/files/prod-certs/9.6/486.pem | 37 +++
|
||||
.../common/files/prod-certs/9.6/72.pem | 36 +++
|
||||
.../common/files/upgrade_paths.json | 18 +-
|
||||
.../common/libraries/config/version.py | 2 +-
|
||||
11 files changed, 363 insertions(+), 207 deletions(-)
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/9.6/279.pem
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/9.6/362.pem
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/9.6/363.pem
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/9.6/419.pem
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/9.6/433.pem
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/9.6/479.pem
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/9.6/486.pem
|
||||
create mode 100644 repos/system_upgrade/common/files/prod-certs/9.6/72.pem
|
||||
|
||||
diff --git a/.packit.yaml b/.packit.yaml
|
||||
index fbfd0eea..48c3cbbb 100644
|
||||
--- a/.packit.yaml
|
||||
+++ b/.packit.yaml
|
||||
@@ -145,104 +145,6 @@ jobs:
|
||||
# ######################### Individual tests ########################### #
|
||||
# ###################################################################### #
|
||||
|
||||
-# Tests: 7.9 -> 8.8
|
||||
-- &sanity-79to88-aws
|
||||
- <<: *sanity-abstract-7to8-aws
|
||||
- trigger: pull_request
|
||||
- identifier: sanity-7.9to8.8-aws
|
||||
- tf_extra_params:
|
||||
- test:
|
||||
- tmt:
|
||||
- plan_filter: 'tag:7to8 & tag:upgrade_happy_path & enabled:true'
|
||||
- environments:
|
||||
- - tmt:
|
||||
- context:
|
||||
- distro: "rhel-7.9"
|
||||
- distro_target: "rhel-8.8"
|
||||
- settings:
|
||||
- provisioning:
|
||||
- post_install_script: "#!/bin/sh\nsudo sed -i s/.*ssh-rsa/ssh-rsa/ /root/.ssh/authorized_keys"
|
||||
- tags:
|
||||
- BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
- env:
|
||||
- SOURCE_RELEASE: "7.9"
|
||||
- TARGET_RELEASE: "8.8"
|
||||
- RHUI: "aws"
|
||||
- LEAPPDATA_BRANCH: "upstream"
|
||||
- LEAPP_NO_RHSM: "1"
|
||||
- USE_CUSTOM_REPOS: rhui
|
||||
-
|
||||
-- &sanity-79to88
|
||||
- <<: *sanity-abstract-7to8
|
||||
- trigger: pull_request
|
||||
- identifier: sanity-7.9to8.8
|
||||
- tf_extra_params:
|
||||
- test:
|
||||
- tmt:
|
||||
- plan_filter: 'tag:7to8 & tag:sanity & enabled:true'
|
||||
- environments:
|
||||
- - tmt:
|
||||
- context:
|
||||
- distro: "rhel-7.9"
|
||||
- distro_target: "rhel-8.8"
|
||||
- settings:
|
||||
- provisioning:
|
||||
- tags:
|
||||
- BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
- env:
|
||||
- SOURCE_RELEASE: "7.9"
|
||||
- TARGET_RELEASE: "8.8"
|
||||
-
|
||||
-- &beaker-minimal-79to88
|
||||
- <<: *beaker-minimal-7to8-abstract-ondemand
|
||||
- trigger: pull_request
|
||||
- labels:
|
||||
- - beaker-minimal
|
||||
- - beaker-minimal-7.9to8.8
|
||||
- - 7.9to8.8
|
||||
- identifier: sanity-7.9to8.8-beaker-minimal-ondemand
|
||||
- tf_extra_params:
|
||||
- test:
|
||||
- tmt:
|
||||
- plan_filter: 'tag:7to8 & tag:partitioning & enabled:true'
|
||||
- environments:
|
||||
- - tmt:
|
||||
- context:
|
||||
- distro: "rhel-7.9"
|
||||
- distro_target: "rhel-8.8"
|
||||
- settings:
|
||||
- provisioning:
|
||||
- tags:
|
||||
- BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
- env:
|
||||
- SOURCE_RELEASE: "7.9"
|
||||
- TARGET_RELEASE: "8.8"
|
||||
-
|
||||
-- &kernel-rt-79to88
|
||||
- <<: *kernel-rt-abstract-7to8-ondemand
|
||||
- trigger: pull_request
|
||||
- labels:
|
||||
- - kernel-rt
|
||||
- - kernel-rt-7.9to8.8
|
||||
- - 7.9to8.8
|
||||
- identifier: sanity-7.9to8.8-kernel-rt-ondemand
|
||||
- tf_extra_params:
|
||||
- test:
|
||||
- tmt:
|
||||
- plan_filter: 'tag:7to8 & tag:kernel-rt & enabled:true'
|
||||
- environments:
|
||||
- - tmt:
|
||||
- context:
|
||||
- distro: "rhel-7.9"
|
||||
- distro_target: "rhel-8.8"
|
||||
- settings:
|
||||
- provisioning:
|
||||
- tags:
|
||||
- BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
- env:
|
||||
- SOURCE_RELEASE: "7.9"
|
||||
- TARGET_RELEASE: "8.8"
|
||||
-
|
||||
# Tests: 7.9 -> 8.10
|
||||
- &sanity-79to810
|
||||
<<: *sanity-abstract-7to8
|
||||
@@ -397,14 +299,11 @@ jobs:
|
||||
# ######################### Individual tests ########################### #
|
||||
# ###################################################################### #
|
||||
|
||||
-# Tests: 8.8 -> 9.2
|
||||
-- &sanity-88to92
|
||||
+# Tests: 8.10 -> 9.4
|
||||
+- &sanity-810to94
|
||||
<<: *sanity-abstract-8to9
|
||||
trigger: pull_request
|
||||
- targets:
|
||||
- epel-8-x86_64:
|
||||
- distros: [RHEL-8.8.0-Nightly]
|
||||
- identifier: sanity-8.8to9.2
|
||||
+ identifier: sanity-8.10to9.4
|
||||
tf_extra_params:
|
||||
test:
|
||||
tmt:
|
||||
@@ -412,108 +311,74 @@ jobs:
|
||||
environments:
|
||||
- tmt:
|
||||
context:
|
||||
- distro: "rhel-8.8"
|
||||
- distro_target: "rhel-9.2"
|
||||
- settings:
|
||||
- provisioning:
|
||||
- tags:
|
||||
- BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
- env:
|
||||
- SOURCE_RELEASE: "8.8"
|
||||
- TARGET_RELEASE: "9.2"
|
||||
- RHSM_REPOS_EUS: "eus"
|
||||
-
|
||||
-- &sanity-88to92-aws
|
||||
- <<: *sanity-abstract-8to9-aws
|
||||
- trigger: pull_request
|
||||
- targets:
|
||||
- epel-8-x86_64:
|
||||
- distros: [RHEL-8.8-rhui]
|
||||
- identifier: sanity-8.8to9.2-aws
|
||||
- tf_extra_params:
|
||||
- test:
|
||||
- tmt:
|
||||
- plan_filter: 'tag:8to9 & tag:rhui-tier[0] & enabled:true'
|
||||
- environments:
|
||||
- - tmt:
|
||||
- context:
|
||||
- distro: "rhel-8.8"
|
||||
- distro_target: "rhel-9.2"
|
||||
+ distro: "rhel-8.10"
|
||||
+ distro_target: "rhel-9.4"
|
||||
settings:
|
||||
provisioning:
|
||||
- post_install_script: "#!/bin/sh\nsudo sed -i s/.*ssh-rsa/ssh-rsa/ /root/.ssh/authorized_keys"
|
||||
tags:
|
||||
BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
env:
|
||||
- SOURCE_RELEASE: "8.8"
|
||||
- TARGET_RELEASE: "9.2"
|
||||
- RHUI_HYPERSCALER: aws
|
||||
+ SOURCE_RELEASE: "8.10"
|
||||
+ TARGET_RELEASE: "9.4"
|
||||
|
||||
-- &beaker-minimal-88to92
|
||||
+# On-demand minimal beaker tests
|
||||
+- &beaker-minimal-810to94
|
||||
<<: *beaker-minimal-8to9-abstract-ondemand
|
||||
trigger: pull_request
|
||||
labels:
|
||||
- beaker-minimal
|
||||
- - beaker-minimal-8.8to9.2
|
||||
- - 8.8to9.2
|
||||
- targets:
|
||||
- epel-8-x86_64:
|
||||
- distros: [RHEL-8.8.0-Nightly]
|
||||
- identifier: sanity-8.8to9.2-beaker-minimal-ondemand
|
||||
+ - beaker-minimal-8.10to9.4
|
||||
+ - 8.10to9.4
|
||||
+ identifier: sanity-8.10to9.4-beaker-minimal-ondemand
|
||||
tf_extra_params:
|
||||
test:
|
||||
tmt:
|
||||
- plan_filter: 'tag:8to9 &tag:partitioning & enabled:true'
|
||||
+ plan_filter: 'tag:8to9 & tag:partitioning & enabled:true'
|
||||
environments:
|
||||
- tmt:
|
||||
context:
|
||||
- distro: "rhel-8.8"
|
||||
- distro_target: "rhel-9.2"
|
||||
+ distro: "rhel-8.10"
|
||||
+ distro_target: "rhel-9.4"
|
||||
settings:
|
||||
provisioning:
|
||||
- post_install_script: "#!/bin/sh\nsudo sed -i s/.*ssh-rsa/ssh-rsa/ /root/.ssh/authorized_keys"
|
||||
tags:
|
||||
BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
env:
|
||||
- SOURCE_RELEASE: "8.8"
|
||||
- TARGET_RELEASE: "9.2"
|
||||
- RHSM_REPOS_EUS: "eus"
|
||||
+ SOURCE_RELEASE: "8.10"
|
||||
+ TARGET_RELEASE: "9.4"
|
||||
|
||||
-- &kernel-rt-88to92
|
||||
+# On-demand kernel-rt tests
|
||||
+- &kernel-rt-810to94
|
||||
<<: *kernel-rt-abstract-8to9-ondemand
|
||||
trigger: pull_request
|
||||
labels:
|
||||
- kernel-rt
|
||||
- - kernel-rt-8.8to9.2
|
||||
- - 8.8to9.2
|
||||
- identifier: sanity-8.8to9.2-kernel-rt-ondemand
|
||||
- targets:
|
||||
- epel-8-x86_64:
|
||||
- distros: [RHEL-8.8.0-Nightly]
|
||||
+ - kernel-rt-8.10to9.4
|
||||
+ - 8.10to9.4
|
||||
+ identifier: sanity-8.10to9.4-kernel-rt-ondemand
|
||||
tf_extra_params:
|
||||
test:
|
||||
tmt:
|
||||
- plan_filter: 'tag:8to9 & tag:kernel-rt & enabled:true'
|
||||
+ plan_filter: 'tag:8to9 & tag:kernel-rt & enabled:true'
|
||||
environments:
|
||||
- tmt:
|
||||
context:
|
||||
- distro: "rhel-8.8"
|
||||
- distro_target: "rhel-9.2"
|
||||
+ distro: "rhel-8.10"
|
||||
+ distro_target: "rhel-9.4"
|
||||
settings:
|
||||
provisioning:
|
||||
tags:
|
||||
BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
env:
|
||||
- SOURCE_RELEASE: "8.8"
|
||||
- TARGET_RELEASE: "9.2"
|
||||
- RHSM_REPOS_EUS: "eus"
|
||||
+ SOURCE_RELEASE: "8.10"
|
||||
+ TARGET_RELEASE: "9.4"
|
||||
|
||||
|
||||
-# Tests: 8.10 -> 9.4
|
||||
-- &sanity-810to94
|
||||
+# Tests: 8.10 -> 9.5
|
||||
+- &sanity-810to95
|
||||
<<: *sanity-abstract-8to9
|
||||
trigger: pull_request
|
||||
- identifier: sanity-8.10to9.4
|
||||
+ identifier: sanity-8.10to9.5
|
||||
tf_extra_params:
|
||||
test:
|
||||
tmt:
|
||||
@@ -522,24 +387,24 @@ jobs:
|
||||
- tmt:
|
||||
context:
|
||||
distro: "rhel-8.10"
|
||||
- distro_target: "rhel-9.4"
|
||||
+ distro_target: "rhel-9.5"
|
||||
settings:
|
||||
provisioning:
|
||||
tags:
|
||||
BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
env:
|
||||
SOURCE_RELEASE: "8.10"
|
||||
- TARGET_RELEASE: "9.4"
|
||||
+ TARGET_RELEASE: "9.5"
|
||||
|
||||
# On-demand minimal beaker tests
|
||||
-- &beaker-minimal-810to94
|
||||
+- &beaker-minimal-810to95
|
||||
<<: *beaker-minimal-8to9-abstract-ondemand
|
||||
trigger: pull_request
|
||||
labels:
|
||||
- beaker-minimal
|
||||
- - beaker-minimal-8.10to9.4
|
||||
- - 8.10to9.4
|
||||
- identifier: sanity-8.10to9.4-beaker-minimal-ondemand
|
||||
+ - beaker-minimal-8.10to9.5
|
||||
+ - 8.10to9.5
|
||||
+ identifier: sanity-8.10to9.5-beaker-minimal-ondemand
|
||||
tf_extra_params:
|
||||
test:
|
||||
tmt:
|
||||
@@ -548,24 +413,24 @@ jobs:
|
||||
- tmt:
|
||||
context:
|
||||
distro: "rhel-8.10"
|
||||
- distro_target: "rhel-9.4"
|
||||
+ distro_target: "rhel-9.5"
|
||||
settings:
|
||||
provisioning:
|
||||
tags:
|
||||
BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
env:
|
||||
SOURCE_RELEASE: "8.10"
|
||||
- TARGET_RELEASE: "9.4"
|
||||
+ TARGET_RELEASE: "9.5"
|
||||
|
||||
# On-demand kernel-rt tests
|
||||
-- &kernel-rt-810to94
|
||||
+- &kernel-rt-810to95
|
||||
<<: *kernel-rt-abstract-8to9-ondemand
|
||||
trigger: pull_request
|
||||
labels:
|
||||
- kernel-rt
|
||||
- - kernel-rt-8.10to9.4
|
||||
- - 8.10to9.4
|
||||
- identifier: sanity-8.10to9.4-kernel-rt-ondemand
|
||||
+ - kernel-rt-8.10to9.5
|
||||
+ - 8.10to9.5
|
||||
+ identifier: sanity-8.10to9.5-kernel-rt-ondemand
|
||||
tf_extra_params:
|
||||
test:
|
||||
tmt:
|
||||
@@ -574,21 +439,21 @@ jobs:
|
||||
- tmt:
|
||||
context:
|
||||
distro: "rhel-8.10"
|
||||
- distro_target: "rhel-9.4"
|
||||
+ distro_target: "rhel-9.5"
|
||||
settings:
|
||||
provisioning:
|
||||
tags:
|
||||
BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
env:
|
||||
SOURCE_RELEASE: "8.10"
|
||||
- TARGET_RELEASE: "9.4"
|
||||
+ TARGET_RELEASE: "9.5"
|
||||
|
||||
|
||||
-# Tests: 8.10 -> 9.5
|
||||
-- &sanity-810to95
|
||||
+# Tests: 8.10 -> 9.6
|
||||
+- &sanity-810to96
|
||||
<<: *sanity-abstract-8to9
|
||||
trigger: pull_request
|
||||
- identifier: sanity-8.10to9.5
|
||||
+ identifier: sanity-8.10to9.6
|
||||
tf_extra_params:
|
||||
test:
|
||||
tmt:
|
||||
@@ -597,24 +462,24 @@ jobs:
|
||||
- tmt:
|
||||
context:
|
||||
distro: "rhel-8.10"
|
||||
- distro_target: "rhel-9.5"
|
||||
+ distro_target: "rhel-9.6"
|
||||
settings:
|
||||
provisioning:
|
||||
tags:
|
||||
BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
env:
|
||||
SOURCE_RELEASE: "8.10"
|
||||
- TARGET_RELEASE: "9.5"
|
||||
+ TARGET_RELEASE: "9.6"
|
||||
|
||||
# On-demand minimal beaker tests
|
||||
-- &beaker-minimal-810to95
|
||||
+- &beaker-minimal-810to96
|
||||
<<: *beaker-minimal-8to9-abstract-ondemand
|
||||
trigger: pull_request
|
||||
labels:
|
||||
- beaker-minimal
|
||||
- - beaker-minimal-8.10to9.5
|
||||
- - 8.10to9.5
|
||||
- identifier: sanity-8.10to9.5-beaker-minimal-ondemand
|
||||
+ - beaker-minimal-8.10to9.6
|
||||
+ - 8.10to9.6
|
||||
+ identifier: sanity-8.10to9.6-beaker-minimal-ondemand
|
||||
tf_extra_params:
|
||||
test:
|
||||
tmt:
|
||||
@@ -623,24 +488,24 @@ jobs:
|
||||
- tmt:
|
||||
context:
|
||||
distro: "rhel-8.10"
|
||||
- distro_target: "rhel-9.5"
|
||||
+ distro_target: "rhel-9.6"
|
||||
settings:
|
||||
provisioning:
|
||||
tags:
|
||||
BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
env:
|
||||
SOURCE_RELEASE: "8.10"
|
||||
- TARGET_RELEASE: "9.5"
|
||||
+ TARGET_RELEASE: "9.6"
|
||||
|
||||
# On-demand kernel-rt tests
|
||||
-- &kernel-rt-810to95
|
||||
+- &kernel-rt-810to96
|
||||
<<: *kernel-rt-abstract-8to9-ondemand
|
||||
trigger: pull_request
|
||||
labels:
|
||||
- kernel-rt
|
||||
- - kernel-rt-8.10to9.5
|
||||
- - 8.10to9.5
|
||||
- identifier: sanity-8.10to9.5-kernel-rt-ondemand
|
||||
+ - kernel-rt-8.10to9.6
|
||||
+ - 8.10to9.6
|
||||
+ identifier: sanity-8.10to9.6-kernel-rt-ondemand
|
||||
tf_extra_params:
|
||||
test:
|
||||
tmt:
|
||||
@@ -649,11 +514,11 @@ jobs:
|
||||
- tmt:
|
||||
context:
|
||||
distro: "rhel-8.10"
|
||||
- distro_target: "rhel-9.5"
|
||||
+ distro_target: "rhel-9.6"
|
||||
settings:
|
||||
provisioning:
|
||||
tags:
|
||||
BusinessUnit: sst_upgrades@leapp_upstream_test
|
||||
env:
|
||||
SOURCE_RELEASE: "8.10"
|
||||
- TARGET_RELEASE: "9.5"
|
||||
+ TARGET_RELEASE: "9.6"
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/9.6/279.pem b/repos/system_upgrade/common/files/prod-certs/9.6/279.pem
|
||||
new file mode 100644
|
||||
index 00000000..a9ef267b
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/9.6/279.pem
|
||||
@@ -0,0 +1,37 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGZTCCBE2gAwIBAgIJALDxRLt/tVEiMA0GCSqGSIb3DQEBCwUAMIGuMQswCQYD
|
||||
+VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFjAUBgNVBAoMDVJlZCBI
|
||||
+YXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0d29yazEuMCwGA1UEAwwlUmVk
|
||||
+IEhhdCBFbnRpdGxlbWVudCBQcm9kdWN0IEF1dGhvcml0eTEkMCIGCSqGSIb3DQEJ
|
||||
+ARYVY2Etc3VwcG9ydEByZWRoYXQuY29tMB4XDTI0MDgxMjE5MDIwNVoXDTQ0MDgx
|
||||
+MjE5MDIwNVowRDFCMEAGA1UEAww5UmVkIEhhdCBQcm9kdWN0IElEIFs1MzUwNTA4
|
||||
+OC05ZTk5LTQyODItYmE4OS1mMjhhNjAwZWNhZWFdMIICIjANBgkqhkiG9w0BAQEF
|
||||
+AAOCAg8AMIICCgKCAgEAxj9J04z+Ezdyx1U33kFftLv0ntNS1BSeuhoZLDhs18yk
|
||||
+sepG7hXXtHh2CMFfLZmTjAyL9i1XsxykQpVQdXTGpUF33C2qBQHB5glYs9+d781x
|
||||
+8p8m8zFxbPcW82TIJXbgW3ErVh8vk5qCbG1cCAAHb+DWMq0EAyy1bl/JgAghYNGB
|
||||
+RvKJObTdCrdpYh02KUqBLkSPZHvo6DUJFN37MXDpVeQq9VtqRjpKLLwuEfXb0Y7I
|
||||
+5xEOrR3kYbOaBAWVt3mYZ1t0L/KfY2jVOdU5WFyyB9PhbMdLi1xE801j+GJrwcLa
|
||||
+xmqvj4UaICRzcPATP86zVM1BBQa+lilkRQes5HyjZzZDiGYudnXhbqmLo/n0cuXo
|
||||
+QBVVjhzRTMx71Eiiahmiw+U1vGqkHhQNxb13HtN1lcAhUCDrxxeMvrAjYdWpYlpI
|
||||
+yW3NssPWt1YUHidMBSAJ4KctIf91dyE93aStlxwC/QnyFsZOmcEsBzVCnz9GmWMl
|
||||
+1/6XzBS1yDUqByklx0TLH+z/sK9A+O2rZAy1mByCYwVxvbOZhnqGxAuToIS+A81v
|
||||
+5hCjsCiOScVB+cil30YBu0cH85RZ0ILNkHdKdrLLWW4wjphK2nBn2g2i3+ztf+nQ
|
||||
+ED2pQqZ/rhuW79jcyCZl9kXqe1wOdF0Cwah4N6/3LzIXEEKyEJxNqQwtNc2IVE8C
|
||||
+AwEAAaOB7jCB6zAJBgNVHRMEAjAAMEMGDCsGAQQBkggJAYIXAQQzDDFSZWQgSGF0
|
||||
+IEVudGVycHJpc2UgTGludXggZm9yIFBvd2VyLCBsaXR0bGUgZW5kaWFuMBUGDCsG
|
||||
+AQQBkggJAYIXAgQFDAM5LjYwGQYMKwYBBAGSCAkBghcDBAkMB3BwYzY0bGUwJwYM
|
||||
+KwYBBAGSCAkBghcEBBcMFXJoZWwtOSxyaGVsLTktcHBjNjRsZTAdBgNVHQ4EFgQU
|
||||
+YeogtTV8r2dkOv9rCOYQeNDNH5UwHwYDVR0jBBgwFoAUlv27HEBA/0CErbIfCybB
|
||||
+w2pv1nwwDQYJKoZIhvcNAQELBQADggIBACRmyYbMhmuV+w4E+Hlonlt0mooB6EF6
|
||||
+h/xknuBRw/saSL+7sLfbItaxWH5euxDc/5XvII2t0Jjl+GDnAjI75xrTuN3gT88Z
|
||||
+9wd1kvDVqt46GI6VKVH1SujJoJpGenfhTVwenATZwdq260RgYgM3Zv1d3I4Lu/GY
|
||||
+65T//j0/8tBmgqMc6BRvIrDa1wtVUbEwH3b/jwZoeitps1hKIH9yKZV79HZ7WVdb
|
||||
+otDtsAk7VKZGRjGdvYsfWZrjmyyyc5wX2AemzpnhSm1kkGvOAjSMsJ0QcrSu/5vj
|
||||
+AAK64J1tDA93WKsAqDnK7tUOx6qwICllbgVmKWl/02JH8ELs/sJnsWBEigfdZmTh
|
||||
+/3Q8DPNni7scYkJ5Vs0tL8pke29C1bgAYjoBiQgf/ffNunTOWgdkdFHbd9I3+aLh
|
||||
+pO7qqkndEkl85xkQJrZWO35NvPD4NAwnsDrIP0oJg5mYNTB11C5SlHhllT/Iu374
|
||||
+8afWtoHaB50vsqM2dtvh/UsCyGynWYc93TLsU6a4gBl19D7VAx0fiOwdD+CyweUp
|
||||
+xcos6MIIuFAFUIVpD+/3w499Lw9m5dcfApl6HCyQgAoafXCJjM/aXsSsSWr2d9TF
|
||||
+c6S/uA2egh4fUv8zYnlZKUvCTu8kn4Lv439wW0xyIEB/sD/gXk9e8H9KkUuKDExx
|
||||
+yTSjzqnPM82N
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/9.6/362.pem b/repos/system_upgrade/common/files/prod-certs/9.6/362.pem
|
||||
new file mode 100644
|
||||
index 00000000..d7c1a6be
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/9.6/362.pem
|
||||
@@ -0,0 +1,37 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGdDCCBFygAwIBAgIJALDxRLt/tVE4MA0GCSqGSIb3DQEBCwUAMIGuMQswCQYD
|
||||
+VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFjAUBgNVBAoMDVJlZCBI
|
||||
+YXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0d29yazEuMCwGA1UEAwwlUmVk
|
||||
+IEhhdCBFbnRpdGxlbWVudCBQcm9kdWN0IEF1dGhvcml0eTEkMCIGCSqGSIb3DQEJ
|
||||
+ARYVY2Etc3VwcG9ydEByZWRoYXQuY29tMB4XDTI0MDgxMjE5MDIyNFoXDTQ0MDgx
|
||||
+MjE5MDIyNFowRDFCMEAGA1UEAww5UmVkIEhhdCBQcm9kdWN0IElEIFs2MjBmNzkx
|
||||
+MC0xNDk5LTRmMzAtYTk3NS1hYWFiOGQyMWE1NmNdMIICIjANBgkqhkiG9w0BAQEF
|
||||
+AAOCAg8AMIICCgKCAgEAxj9J04z+Ezdyx1U33kFftLv0ntNS1BSeuhoZLDhs18yk
|
||||
+sepG7hXXtHh2CMFfLZmTjAyL9i1XsxykQpVQdXTGpUF33C2qBQHB5glYs9+d781x
|
||||
+8p8m8zFxbPcW82TIJXbgW3ErVh8vk5qCbG1cCAAHb+DWMq0EAyy1bl/JgAghYNGB
|
||||
+RvKJObTdCrdpYh02KUqBLkSPZHvo6DUJFN37MXDpVeQq9VtqRjpKLLwuEfXb0Y7I
|
||||
+5xEOrR3kYbOaBAWVt3mYZ1t0L/KfY2jVOdU5WFyyB9PhbMdLi1xE801j+GJrwcLa
|
||||
+xmqvj4UaICRzcPATP86zVM1BBQa+lilkRQes5HyjZzZDiGYudnXhbqmLo/n0cuXo
|
||||
+QBVVjhzRTMx71Eiiahmiw+U1vGqkHhQNxb13HtN1lcAhUCDrxxeMvrAjYdWpYlpI
|
||||
+yW3NssPWt1YUHidMBSAJ4KctIf91dyE93aStlxwC/QnyFsZOmcEsBzVCnz9GmWMl
|
||||
+1/6XzBS1yDUqByklx0TLH+z/sK9A+O2rZAy1mByCYwVxvbOZhnqGxAuToIS+A81v
|
||||
+5hCjsCiOScVB+cil30YBu0cH85RZ0ILNkHdKdrLLWW4wjphK2nBn2g2i3+ztf+nQ
|
||||
+ED2pQqZ/rhuW79jcyCZl9kXqe1wOdF0Cwah4N6/3LzIXEEKyEJxNqQwtNc2IVE8C
|
||||
+AwEAAaOB/TCB+jAJBgNVHRMEAjAAMEgGDCsGAQQBkggJAYJqAQQ4DDZSZWQgSGF0
|
||||
+IEVudGVycHJpc2UgTGludXggZm9yIFBvd2VyLCBsaXR0bGUgZW5kaWFuIEJldGEw
|
||||
+GgYMKwYBBAGSCAkBgmoCBAoMCDkuNiBCZXRhMBkGDCsGAQQBkggJAYJqAwQJDAdw
|
||||
+cGM2NGxlMCwGDCsGAQQBkggJAYJqBAQcDBpyaGVsLTkscmhlbC05LWJldGEtcHBj
|
||||
+NjRsZTAdBgNVHQ4EFgQUYeogtTV8r2dkOv9rCOYQeNDNH5UwHwYDVR0jBBgwFoAU
|
||||
+lv27HEBA/0CErbIfCybBw2pv1nwwDQYJKoZIhvcNAQELBQADggIBADzaMxiligMU
|
||||
+vVUxGdlKgceVXcZR6TC/nACDxyRFm7JGKYC0Ncxum2RWQ10mMD1HM1xa0NVz3BLO
|
||||
+a+VrZ3MGTpKuWQgN0TKIzjykxxfJMip8AVYx6UvQ4SxxZWFIVPuC0XYfYc2pOV5A
|
||||
+OcO63O+R7QVvLpZ3q7tX3uAXCfWWvJkoJ+MzKCl3lEmeKAcaikcums+aOd/JwTSo
|
||||
+bt5ExLgC4J1cvevH+IBCUbmN1r+xrkHNiNWjys0MIo1JsPmi1A1kDeORXPN4xXvH
|
||||
+x69z9SuHrUd2iFXpMfezqZsmiaa/FP6UOKwpDyEqZGE+/aT/RBza9BeYX74vDpFI
|
||||
+h0vMtx3lHE+PGh7a6kfXV2GL4IP7w5MbdZQIJ/ZS4oT/zG3E2wRnGD4+oQ3Bm/TV
|
||||
+Or0IHnafxXYXgsQ6bsMsZN7BRZ8VfaEdM3IVRqVyPVWzo0kYkHZcnVQpabmCWPjc
|
||||
+NUwMJDni3LfjxKreHLDQBEkwX4XoZnSq/xMHO6ppe0sZ2XgAOsw/B92ekTTEdoKZ
|
||||
+dEQBkqv2FRUbMoILnNVWJp4yGMOPcTl7hrlcJjKRvKs1hKWkQKN6g4YDHCglkVfH
|
||||
+ltDGkolsUYFvoygoi8VCCDfz7whn6pXmzlpk1VkzE+V1R88Tf5ygrSNWETOZMU/B
|
||||
+5P07jdNriEBCZaCPq7T8odOt1cKZpVdg
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/9.6/363.pem b/repos/system_upgrade/common/files/prod-certs/9.6/363.pem
|
||||
new file mode 100644
|
||||
index 00000000..f75b478d
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/9.6/363.pem
|
||||
@@ -0,0 +1,37 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGZjCCBE6gAwIBAgIJALDxRLt/tVE3MA0GCSqGSIb3DQEBCwUAMIGuMQswCQYD
|
||||
+VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFjAUBgNVBAoMDVJlZCBI
|
||||
+YXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0d29yazEuMCwGA1UEAwwlUmVk
|
||||
+IEhhdCBFbnRpdGxlbWVudCBQcm9kdWN0IEF1dGhvcml0eTEkMCIGCSqGSIb3DQEJ
|
||||
+ARYVY2Etc3VwcG9ydEByZWRoYXQuY29tMB4XDTI0MDgxMjE5MDIyNFoXDTQ0MDgx
|
||||
+MjE5MDIyNFowRDFCMEAGA1UEAww5UmVkIEhhdCBQcm9kdWN0IElEIFs1MDE5NmU1
|
||||
+ZC1lNDgzLTQwNDAtYjcwYS03NDg5NDliZTRjZmFdMIICIjANBgkqhkiG9w0BAQEF
|
||||
+AAOCAg8AMIICCgKCAgEAxj9J04z+Ezdyx1U33kFftLv0ntNS1BSeuhoZLDhs18yk
|
||||
+sepG7hXXtHh2CMFfLZmTjAyL9i1XsxykQpVQdXTGpUF33C2qBQHB5glYs9+d781x
|
||||
+8p8m8zFxbPcW82TIJXbgW3ErVh8vk5qCbG1cCAAHb+DWMq0EAyy1bl/JgAghYNGB
|
||||
+RvKJObTdCrdpYh02KUqBLkSPZHvo6DUJFN37MXDpVeQq9VtqRjpKLLwuEfXb0Y7I
|
||||
+5xEOrR3kYbOaBAWVt3mYZ1t0L/KfY2jVOdU5WFyyB9PhbMdLi1xE801j+GJrwcLa
|
||||
+xmqvj4UaICRzcPATP86zVM1BBQa+lilkRQes5HyjZzZDiGYudnXhbqmLo/n0cuXo
|
||||
+QBVVjhzRTMx71Eiiahmiw+U1vGqkHhQNxb13HtN1lcAhUCDrxxeMvrAjYdWpYlpI
|
||||
+yW3NssPWt1YUHidMBSAJ4KctIf91dyE93aStlxwC/QnyFsZOmcEsBzVCnz9GmWMl
|
||||
+1/6XzBS1yDUqByklx0TLH+z/sK9A+O2rZAy1mByCYwVxvbOZhnqGxAuToIS+A81v
|
||||
+5hCjsCiOScVB+cil30YBu0cH85RZ0ILNkHdKdrLLWW4wjphK2nBn2g2i3+ztf+nQ
|
||||
+ED2pQqZ/rhuW79jcyCZl9kXqe1wOdF0Cwah4N6/3LzIXEEKyEJxNqQwtNc2IVE8C
|
||||
+AwEAAaOB7zCB7DAJBgNVHRMEAjAAMDoGDCsGAQQBkggJAYJrAQQqDChSZWQgSGF0
|
||||
+IEVudGVycHJpc2UgTGludXggZm9yIEFSTSA2NCBCZXRhMBoGDCsGAQQBkggJAYJr
|
||||
+AgQKDAg5LjYgQmV0YTAZBgwrBgEEAZIICQGCawMECQwHYWFyY2g2NDAsBgwrBgEE
|
||||
+AZIICQGCawQEHAwacmhlbC05LHJoZWwtOS1iZXRhLWFhcmNoNjQwHQYDVR0OBBYE
|
||||
+FGHqILU1fK9nZDr/awjmEHjQzR+VMB8GA1UdIwQYMBaAFJb9uxxAQP9AhK2yHwsm
|
||||
+wcNqb9Z8MA0GCSqGSIb3DQEBCwUAA4ICAQBiaXwTsDt1Kz79ZJ3TnNDuX3IntXuS
|
||||
+DxIGAhpgJ+ynaSULh8xL6pq5L6EtYnVzpO6T+j2ADbJlLkIRV0fMD6MMZo4YQtHH
|
||||
+NofoNgJoYI4uXcCKYS2vIUw+0Br7qx8BPTb5jP+VRl9LU8W299nYOTp+vY7GQ0Ny
|
||||
+hT66G+FJfo5CqHZpMTGgJbpjoP3DMpXZcARBnjQ0LhvjvcalGmPP4//tcPNwft6r
|
||||
+ei8fxBvpmCXDS9/vXwiEf6jEidqq1Q6bCdL20Y1ZPY13oUEYFqrf8PhexlV1yoD4
|
||||
+F4gEbVHPQ4yvH3D6xIAFE4959+H+dgMfXqn9gkUvnTMdyfzcUYGLTAib3zb4eW/J
|
||||
+anzwfBAcssBzjU1v/txWMRlZI1GJFNtboAixnRksj1epE848J3bjtiw3R/Z5grFn
|
||||
+dieJwjfM4AEDrpRmA5tDnv5z73k1djJbacL7fTIyTuSnDbjH2J5PtCAvWTLYq/kP
|
||||
+h8E3sJ9zXP2nJMBRgQiZJY98bPKLT63ngRScI+CZs1fLvaoCq0o+qkcfnDEja3aH
|
||||
+TQYXHVZblA4TYnD8Vh8gKwCt8+1WF5C9BGcMmKvozuuIaIJgT21V+DLzfTESpZz7
|
||||
+lcPKk/3dBFtFGOdA4SQ4o/dxItJ0Eay1SlOI9xL9KgTNqv6ftA+9kxZ0MSPwO7eG
|
||||
+b5Am4gNTK734uQ==
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/9.6/419.pem b/repos/system_upgrade/common/files/prod-certs/9.6/419.pem
|
||||
new file mode 100644
|
||||
index 00000000..e2d3ee5b
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/9.6/419.pem
|
||||
@@ -0,0 +1,36 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGVzCCBD+gAwIBAgIJALDxRLt/tVEhMA0GCSqGSIb3DQEBCwUAMIGuMQswCQYD
|
||||
+VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFjAUBgNVBAoMDVJlZCBI
|
||||
+YXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0d29yazEuMCwGA1UEAwwlUmVk
|
||||
+IEhhdCBFbnRpdGxlbWVudCBQcm9kdWN0IEF1dGhvcml0eTEkMCIGCSqGSIb3DQEJ
|
||||
+ARYVY2Etc3VwcG9ydEByZWRoYXQuY29tMB4XDTI0MDgxMjE5MDIwNVoXDTQ0MDgx
|
||||
+MjE5MDIwNVowRDFCMEAGA1UEAww5UmVkIEhhdCBQcm9kdWN0IElEIFtkN2E2ZDhi
|
||||
+Mi0yZjMzLTRhYzMtYmM5Ni1mMjU5MTNmZTQxNWNdMIICIjANBgkqhkiG9w0BAQEF
|
||||
+AAOCAg8AMIICCgKCAgEAxj9J04z+Ezdyx1U33kFftLv0ntNS1BSeuhoZLDhs18yk
|
||||
+sepG7hXXtHh2CMFfLZmTjAyL9i1XsxykQpVQdXTGpUF33C2qBQHB5glYs9+d781x
|
||||
+8p8m8zFxbPcW82TIJXbgW3ErVh8vk5qCbG1cCAAHb+DWMq0EAyy1bl/JgAghYNGB
|
||||
+RvKJObTdCrdpYh02KUqBLkSPZHvo6DUJFN37MXDpVeQq9VtqRjpKLLwuEfXb0Y7I
|
||||
+5xEOrR3kYbOaBAWVt3mYZ1t0L/KfY2jVOdU5WFyyB9PhbMdLi1xE801j+GJrwcLa
|
||||
+xmqvj4UaICRzcPATP86zVM1BBQa+lilkRQes5HyjZzZDiGYudnXhbqmLo/n0cuXo
|
||||
+QBVVjhzRTMx71Eiiahmiw+U1vGqkHhQNxb13HtN1lcAhUCDrxxeMvrAjYdWpYlpI
|
||||
+yW3NssPWt1YUHidMBSAJ4KctIf91dyE93aStlxwC/QnyFsZOmcEsBzVCnz9GmWMl
|
||||
+1/6XzBS1yDUqByklx0TLH+z/sK9A+O2rZAy1mByCYwVxvbOZhnqGxAuToIS+A81v
|
||||
+5hCjsCiOScVB+cil30YBu0cH85RZ0ILNkHdKdrLLWW4wjphK2nBn2g2i3+ztf+nQ
|
||||
+ED2pQqZ/rhuW79jcyCZl9kXqe1wOdF0Cwah4N6/3LzIXEEKyEJxNqQwtNc2IVE8C
|
||||
+AwEAAaOB4DCB3TAJBgNVHRMEAjAAMDUGDCsGAQQBkggJAYMjAQQlDCNSZWQgSGF0
|
||||
+IEVudGVycHJpc2UgTGludXggZm9yIEFSTSA2NDAVBgwrBgEEAZIICQGDIwIEBQwD
|
||||
+OS42MBkGDCsGAQQBkggJAYMjAwQJDAdhYXJjaDY0MCcGDCsGAQQBkggJAYMjBAQX
|
||||
+DBVyaGVsLTkscmhlbC05LWFhcmNoNjQwHQYDVR0OBBYEFGHqILU1fK9nZDr/awjm
|
||||
+EHjQzR+VMB8GA1UdIwQYMBaAFJb9uxxAQP9AhK2yHwsmwcNqb9Z8MA0GCSqGSIb3
|
||||
+DQEBCwUAA4ICAQCJqWcTJezGVGxsNvFkbsrvbHhJBuBMeDZZuOLaXaQVyfNwYRS2
|
||||
+2k/oUhhQQMfiDiaLkz7yz0Zw5clC/K5G6Sg9+nWDA57lsZuNV5CnSBYOJf2jY2fK
|
||||
+ue/1M75Y4fJAKtBxpvkFaIaKyMQ/0VC67OFYtbBZEOuwIpQh9aPFHnrh2WnpcUvJ
|
||||
+B93O0fsRjHK30E7jF8ncNmhevMLvVlxH0JjfbvcU3dGG964K41tFiozshvnAGFce
|
||||
+kFzxVVYQL3ZKycqonwFr3BbzgKwx5EXUFBg/ax694aijeeVA6yuQXWJvV42IjUeW
|
||||
+vn+dvRrHh2fv4MXuyc+oljbXaEZE7m9gtWBtUEBHqWoQz6rQ25uZylnK+SDWE5bt
|
||||
+xM+1qGUSf90VvyFO3fu1qeVVr0LbnMAgO9YnJjLRQax0mgj3tZTRvM72W4hfBy36
|
||||
+ndYnJE2le5xYWVl1Hd29dil70cokj5hN8nQI9eStfcOvs9Vw2ngIL/H3+QTRS/NO
|
||||
+l7MHQXbriLAaHavED6B50dEfw8pQXybEju4Rs+nDgm5hdE7FjbVflVQejSjyHIMd
|
||||
+AQnwrDSMPRezCJFHQeB0t7oaHpAHECc2zBpvcvy7qCN2Z08h6jdzfrp15UDkHEcy
|
||||
+Qa9dtYRUthI3pjGGu7WTPwX9y0veot3EZRnEzeIprIsHcMKfmkMg4HRJ3A==
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/9.6/433.pem b/repos/system_upgrade/common/files/prod-certs/9.6/433.pem
|
||||
new file mode 100644
|
||||
index 00000000..ac588c1c
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/9.6/433.pem
|
||||
@@ -0,0 +1,37 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGaTCCBFGgAwIBAgIJALDxRLt/tVE5MA0GCSqGSIb3DQEBCwUAMIGuMQswCQYD
|
||||
+VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFjAUBgNVBAoMDVJlZCBI
|
||||
+YXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0d29yazEuMCwGA1UEAwwlUmVk
|
||||
+IEhhdCBFbnRpdGxlbWVudCBQcm9kdWN0IEF1dGhvcml0eTEkMCIGCSqGSIb3DQEJ
|
||||
+ARYVY2Etc3VwcG9ydEByZWRoYXQuY29tMB4XDTI0MDgxMjE5MDIyNFoXDTQ0MDgx
|
||||
+MjE5MDIyNFowRDFCMEAGA1UEAww5UmVkIEhhdCBQcm9kdWN0IElEIFs4NzcwNzQ4
|
||||
+MS02MGEwLTQwYTUtYWVhMi0xNjNmODUyMzI3ZTFdMIICIjANBgkqhkiG9w0BAQEF
|
||||
+AAOCAg8AMIICCgKCAgEAxj9J04z+Ezdyx1U33kFftLv0ntNS1BSeuhoZLDhs18yk
|
||||
+sepG7hXXtHh2CMFfLZmTjAyL9i1XsxykQpVQdXTGpUF33C2qBQHB5glYs9+d781x
|
||||
+8p8m8zFxbPcW82TIJXbgW3ErVh8vk5qCbG1cCAAHb+DWMq0EAyy1bl/JgAghYNGB
|
||||
+RvKJObTdCrdpYh02KUqBLkSPZHvo6DUJFN37MXDpVeQq9VtqRjpKLLwuEfXb0Y7I
|
||||
+5xEOrR3kYbOaBAWVt3mYZ1t0L/KfY2jVOdU5WFyyB9PhbMdLi1xE801j+GJrwcLa
|
||||
+xmqvj4UaICRzcPATP86zVM1BBQa+lilkRQes5HyjZzZDiGYudnXhbqmLo/n0cuXo
|
||||
+QBVVjhzRTMx71Eiiahmiw+U1vGqkHhQNxb13HtN1lcAhUCDrxxeMvrAjYdWpYlpI
|
||||
+yW3NssPWt1YUHidMBSAJ4KctIf91dyE93aStlxwC/QnyFsZOmcEsBzVCnz9GmWMl
|
||||
+1/6XzBS1yDUqByklx0TLH+z/sK9A+O2rZAy1mByCYwVxvbOZhnqGxAuToIS+A81v
|
||||
+5hCjsCiOScVB+cil30YBu0cH85RZ0ILNkHdKdrLLWW4wjphK2nBn2g2i3+ztf+nQ
|
||||
+ED2pQqZ/rhuW79jcyCZl9kXqe1wOdF0Cwah4N6/3LzIXEEKyEJxNqQwtNc2IVE8C
|
||||
+AwEAAaOB8jCB7zAJBgNVHRMEAjAAMEEGDCsGAQQBkggJAYMxAQQxDC9SZWQgSGF0
|
||||
+IEVudGVycHJpc2UgTGludXggZm9yIElCTSB6IFN5c3RlbXMgQmV0YTAaBgwrBgEE
|
||||
+AZIICQGDMQIECgwIOS42IEJldGEwFwYMKwYBBAGSCAkBgzEDBAcMBXMzOTB4MCoG
|
||||
+DCsGAQQBkggJAYMxBAQaDBhyaGVsLTkscmhlbC05LWJldGEtczM5MHgwHQYDVR0O
|
||||
+BBYEFGHqILU1fK9nZDr/awjmEHjQzR+VMB8GA1UdIwQYMBaAFJb9uxxAQP9AhK2y
|
||||
+HwsmwcNqb9Z8MA0GCSqGSIb3DQEBCwUAA4ICAQC57eNKMpTQuIEEoYXkhD0oYkgD
|
||||
+RzDFyqKZgyK0IdOy6t0d9GcMY/nI/uYQltUC+HWBUJWYkHc84xjfP3ITfuHWP8KP
|
||||
+3qdXLPwTDcNVUGtLgXIfEz4FEM4OVwfM2X0jIcLfkDmZzffWjHgBpAUfZM6fBvXl
|
||||
+soPJ+s4/vIUFNbVtcJh9iw4glt/GFBOX/bNPV9kniAAYuyabW43X7GxfREJY18Db
|
||||
++Fv7c+z2eM4fQFpLkSEZwsNN68G4OHDC7tWsYtCRocipWGs6lN5MBNXC0q90ds5O
|
||||
+kOLRfHKOLFqbZnBNdgSOlsf+ENH3exUhoDvZE0gnAVALABVv6PCtsHn2rPLonsrB
|
||||
+l9ZKqCVVDpQMDXmZC79XKB0nVrNQ7qYorCVnYqnTAkuvw4BuXpKASaSCDSRWLQN0
|
||||
+H89phUM64VnyPD5pBTw+YJURDm8cwD5e6HaXhKzG1ca9PWL+RVxedB4Rl2VG00fE
|
||||
+QUBbHZktH+H1P3MtqALB7IUav4IuBgdF27W55GExCgshRuyV6/VHmYiD+L52XxCH
|
||||
+71mdWTp6JR1/hMYKPLhc5/ESBoMpqMXa4UWIOtMWiafWaDS4Cib+uyIIzCgqW8ee
|
||||
+t+yQtCs7MUUd6t87XP7/TTQJe6e0JsyDnME9br0E4g57Y8cXjOILGg/ihqBFOGt1
|
||||
+vhbX7w/YRjVpwJhi9w==
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/9.6/479.pem b/repos/system_upgrade/common/files/prod-certs/9.6/479.pem
|
||||
new file mode 100644
|
||||
index 00000000..c2bac3ee
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/9.6/479.pem
|
||||
@@ -0,0 +1,36 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGVTCCBD2gAwIBAgIJALDxRLt/tVEkMA0GCSqGSIb3DQEBCwUAMIGuMQswCQYD
|
||||
+VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFjAUBgNVBAoMDVJlZCBI
|
||||
+YXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0d29yazEuMCwGA1UEAwwlUmVk
|
||||
+IEhhdCBFbnRpdGxlbWVudCBQcm9kdWN0IEF1dGhvcml0eTEkMCIGCSqGSIb3DQEJ
|
||||
+ARYVY2Etc3VwcG9ydEByZWRoYXQuY29tMB4XDTI0MDgxMjE5MDIwNVoXDTQ0MDgx
|
||||
+MjE5MDIwNVowRDFCMEAGA1UEAww5UmVkIEhhdCBQcm9kdWN0IElEIFtjZWRlZTRi
|
||||
+My0xOGFhLTQwMzMtYjE3OS01OTkwMjk2OGFkZjhdMIICIjANBgkqhkiG9w0BAQEF
|
||||
+AAOCAg8AMIICCgKCAgEAxj9J04z+Ezdyx1U33kFftLv0ntNS1BSeuhoZLDhs18yk
|
||||
+sepG7hXXtHh2CMFfLZmTjAyL9i1XsxykQpVQdXTGpUF33C2qBQHB5glYs9+d781x
|
||||
+8p8m8zFxbPcW82TIJXbgW3ErVh8vk5qCbG1cCAAHb+DWMq0EAyy1bl/JgAghYNGB
|
||||
+RvKJObTdCrdpYh02KUqBLkSPZHvo6DUJFN37MXDpVeQq9VtqRjpKLLwuEfXb0Y7I
|
||||
+5xEOrR3kYbOaBAWVt3mYZ1t0L/KfY2jVOdU5WFyyB9PhbMdLi1xE801j+GJrwcLa
|
||||
+xmqvj4UaICRzcPATP86zVM1BBQa+lilkRQes5HyjZzZDiGYudnXhbqmLo/n0cuXo
|
||||
+QBVVjhzRTMx71Eiiahmiw+U1vGqkHhQNxb13HtN1lcAhUCDrxxeMvrAjYdWpYlpI
|
||||
+yW3NssPWt1YUHidMBSAJ4KctIf91dyE93aStlxwC/QnyFsZOmcEsBzVCnz9GmWMl
|
||||
+1/6XzBS1yDUqByklx0TLH+z/sK9A+O2rZAy1mByCYwVxvbOZhnqGxAuToIS+A81v
|
||||
+5hCjsCiOScVB+cil30YBu0cH85RZ0ILNkHdKdrLLWW4wjphK2nBn2g2i3+ztf+nQ
|
||||
+ED2pQqZ/rhuW79jcyCZl9kXqe1wOdF0Cwah4N6/3LzIXEEKyEJxNqQwtNc2IVE8C
|
||||
+AwEAAaOB3jCB2zAJBgNVHRMEAjAAMDUGDCsGAQQBkggJAYNfAQQlDCNSZWQgSGF0
|
||||
+IEVudGVycHJpc2UgTGludXggZm9yIHg4Nl82NDAVBgwrBgEEAZIICQGDXwIEBQwD
|
||||
+OS42MBgGDCsGAQQBkggJAYNfAwQIDAZ4ODZfNjQwJgYMKwYBBAGSCAkBg18EBBYM
|
||||
+FHJoZWwtOSxyaGVsLTkteDg2XzY0MB0GA1UdDgQWBBRh6iC1NXyvZ2Q6/2sI5hB4
|
||||
+0M0flTAfBgNVHSMEGDAWgBSW/bscQED/QIStsh8LJsHDam/WfDANBgkqhkiG9w0B
|
||||
+AQsFAAOCAgEADoQWjROe9jPuYIB5cW7URXgDPVK3cpGnlKxEINdXT+dL7N2qNijy
|
||||
+BcV0+SCHmswZ+F7OTozyGzGbJCrSHZrvF2lp2L8YddvkIFsWqrPkseU/0/oog5Qf
|
||||
+ULA5WzV12u0Ra/DWinhUq6NZWLAt/FvJ7+WHPdJ7B0WsiA751l7crvfKfen93Xzb
|
||||
+0eakHrotcPi9YH/Jez8xjs4Wc3ra/7CbLqpsHuWzgzwJabiuLaf5PK95VVedzQIx
|
||||
+lT+N6JydFIkXkofQJwTptPTh9lDbZDe33/dg5zX3l9CAQK7JYZKYoUzLirM2LO7s
|
||||
+TGejW1mKGB+O23bQBGRkLoD4kbY17UMCFcKD7mZSO6laoOBOk8NYUxTDjT4e3cUB
|
||||
+dHw5YVrj+BSHzgOGpc1KrmuBiOWZrZf4iaFuz4Kr88tL6TT6IH5UmfP3fuvvMyXs
|
||||
+OWqTAfr/CPeJjLhjmbEagkS0kpgkyXodY8sq2Ph5vpn0o1QYNfy6KRtD/m6YaF7G
|
||||
+SDkWEY5li338SROIFV6X8lKEzHMfQZzhqQWoJWQlFuAdByKrxz8x1RJZTkIT82h6
|
||||
+uM/GO3v5xT5UXXa2x1X0JtS9rPGdnmAKQLJJz07s+2WCRqCFuBxJsV+aWCRLsab4
|
||||
+jpo1NG0RH0KorjvBBMLx8bVSbl4YFJdOcomlRVrsC2iMUwl+PH5Ah4g=
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/9.6/486.pem b/repos/system_upgrade/common/files/prod-certs/9.6/486.pem
|
||||
new file mode 100644
|
||||
index 00000000..e130d5dc
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/9.6/486.pem
|
||||
@@ -0,0 +1,37 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGZDCCBEygAwIBAgIJALDxRLt/tVE6MA0GCSqGSIb3DQEBCwUAMIGuMQswCQYD
|
||||
+VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFjAUBgNVBAoMDVJlZCBI
|
||||
+YXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0d29yazEuMCwGA1UEAwwlUmVk
|
||||
+IEhhdCBFbnRpdGxlbWVudCBQcm9kdWN0IEF1dGhvcml0eTEkMCIGCSqGSIb3DQEJ
|
||||
+ARYVY2Etc3VwcG9ydEByZWRoYXQuY29tMB4XDTI0MDgxMjE5MDIyNFoXDTQ0MDgx
|
||||
+MjE5MDIyNFowRDFCMEAGA1UEAww5UmVkIEhhdCBQcm9kdWN0IElEIFsyMTM1ODk1
|
||||
+Yi1mMDRiLTRlNjUtOWYzMC04MmRlYmQ0Njc0NjNdMIICIjANBgkqhkiG9w0BAQEF
|
||||
+AAOCAg8AMIICCgKCAgEAxj9J04z+Ezdyx1U33kFftLv0ntNS1BSeuhoZLDhs18yk
|
||||
+sepG7hXXtHh2CMFfLZmTjAyL9i1XsxykQpVQdXTGpUF33C2qBQHB5glYs9+d781x
|
||||
+8p8m8zFxbPcW82TIJXbgW3ErVh8vk5qCbG1cCAAHb+DWMq0EAyy1bl/JgAghYNGB
|
||||
+RvKJObTdCrdpYh02KUqBLkSPZHvo6DUJFN37MXDpVeQq9VtqRjpKLLwuEfXb0Y7I
|
||||
+5xEOrR3kYbOaBAWVt3mYZ1t0L/KfY2jVOdU5WFyyB9PhbMdLi1xE801j+GJrwcLa
|
||||
+xmqvj4UaICRzcPATP86zVM1BBQa+lilkRQes5HyjZzZDiGYudnXhbqmLo/n0cuXo
|
||||
+QBVVjhzRTMx71Eiiahmiw+U1vGqkHhQNxb13HtN1lcAhUCDrxxeMvrAjYdWpYlpI
|
||||
+yW3NssPWt1YUHidMBSAJ4KctIf91dyE93aStlxwC/QnyFsZOmcEsBzVCnz9GmWMl
|
||||
+1/6XzBS1yDUqByklx0TLH+z/sK9A+O2rZAy1mByCYwVxvbOZhnqGxAuToIS+A81v
|
||||
+5hCjsCiOScVB+cil30YBu0cH85RZ0ILNkHdKdrLLWW4wjphK2nBn2g2i3+ztf+nQ
|
||||
+ED2pQqZ/rhuW79jcyCZl9kXqe1wOdF0Cwah4N6/3LzIXEEKyEJxNqQwtNc2IVE8C
|
||||
+AwEAAaOB7TCB6jAJBgNVHRMEAjAAMDoGDCsGAQQBkggJAYNmAQQqDChSZWQgSGF0
|
||||
+IEVudGVycHJpc2UgTGludXggZm9yIHg4Nl82NCBCZXRhMBoGDCsGAQQBkggJAYNm
|
||||
+AgQKDAg5LjYgQmV0YTAYBgwrBgEEAZIICQGDZgMECAwGeDg2XzY0MCsGDCsGAQQB
|
||||
+kggJAYNmBAQbDBlyaGVsLTkscmhlbC05LWJldGEteDg2XzY0MB0GA1UdDgQWBBRh
|
||||
+6iC1NXyvZ2Q6/2sI5hB40M0flTAfBgNVHSMEGDAWgBSW/bscQED/QIStsh8LJsHD
|
||||
+am/WfDANBgkqhkiG9w0BAQsFAAOCAgEAHhaEBX5fhB2zweFT0SuLB3OB11aE3Tjy
|
||||
+q0dNxm8t3d5glgtratmAkPD+6Ct0gkdoGJ8GcBsFVzzM2ig236YOy8dCPVWBzLtd
|
||||
+Oni5DpjSqnMX6yq4PuSViF1w+9pCKPJqzQK/u/F0njkwdu0mAwc1fkiCR0B6oB7s
|
||||
+m1rHhuyC4PkAj5RYQ6+M4MpGfce0HSpUCzlnAlHYgjvmT3qCUvlEYLPg4/Z+wihZ
|
||||
+1xdhhhoLNi43IdfmFQlTSNZqTwLB780qzHzi+UYgWg7wflTn8m1LAOlad5HWJFnE
|
||||
+y6JnX+c+vfzvxFBSZABKJsZY/YKIAV14g42XL8zhIpJHtdYnUaveo1M90UAvSECP
|
||||
+RAnPUIKWM1VYKfa2PpEC2/157KOQ4y7BUrAUlqs1qh8FoGCZYHMRmgYqHoycIvw+
|
||||
+gs1gH77O9EyOMMjwyQqBUnzylJfhjkEgINDIGbPEiQpI33TBniw5yMRZ74XWOoi3
|
||||
+rOIiaYxHBDpJ25LwbZsJOQUPmIKBTOpLK9N4IK7UvA7O8HCEEJz2+VLVf2svaoU1
|
||||
+fd7MUYh9aCjEocKRQknxScJLVBXcFRy0I+tfVQwkcLqWCOrp3qpNmYwhC+C0vYtR
|
||||
+/LZ58vf60+m+mKUmEJWF6X7QGFZptsc0ERme6sE1E41iNAIq3BsBMU/hQIVP50k4
|
||||
+T3KefQomWk4=
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/prod-certs/9.6/72.pem b/repos/system_upgrade/common/files/prod-certs/9.6/72.pem
|
||||
new file mode 100644
|
||||
index 00000000..35927fbc
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/files/prod-certs/9.6/72.pem
|
||||
@@ -0,0 +1,36 @@
|
||||
+-----BEGIN CERTIFICATE-----
|
||||
+MIIGVjCCBD6gAwIBAgIJALDxRLt/tVEjMA0GCSqGSIb3DQEBCwUAMIGuMQswCQYD
|
||||
+VQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFjAUBgNVBAoMDVJlZCBI
|
||||
+YXQsIEluYy4xGDAWBgNVBAsMD1JlZCBIYXQgTmV0d29yazEuMCwGA1UEAwwlUmVk
|
||||
+IEhhdCBFbnRpdGxlbWVudCBQcm9kdWN0IEF1dGhvcml0eTEkMCIGCSqGSIb3DQEJ
|
||||
+ARYVY2Etc3VwcG9ydEByZWRoYXQuY29tMB4XDTI0MDgxMjE5MDIwNVoXDTQ0MDgx
|
||||
+MjE5MDIwNVowRDFCMEAGA1UEAww5UmVkIEhhdCBQcm9kdWN0IElEIFs0ZDhmOTky
|
||||
+Yy04NDBjLTQ4MzYtODVkOS0zYWI5YjA1ZjViY2FdMIICIjANBgkqhkiG9w0BAQEF
|
||||
+AAOCAg8AMIICCgKCAgEAxj9J04z+Ezdyx1U33kFftLv0ntNS1BSeuhoZLDhs18yk
|
||||
+sepG7hXXtHh2CMFfLZmTjAyL9i1XsxykQpVQdXTGpUF33C2qBQHB5glYs9+d781x
|
||||
+8p8m8zFxbPcW82TIJXbgW3ErVh8vk5qCbG1cCAAHb+DWMq0EAyy1bl/JgAghYNGB
|
||||
+RvKJObTdCrdpYh02KUqBLkSPZHvo6DUJFN37MXDpVeQq9VtqRjpKLLwuEfXb0Y7I
|
||||
+5xEOrR3kYbOaBAWVt3mYZ1t0L/KfY2jVOdU5WFyyB9PhbMdLi1xE801j+GJrwcLa
|
||||
+xmqvj4UaICRzcPATP86zVM1BBQa+lilkRQes5HyjZzZDiGYudnXhbqmLo/n0cuXo
|
||||
+QBVVjhzRTMx71Eiiahmiw+U1vGqkHhQNxb13HtN1lcAhUCDrxxeMvrAjYdWpYlpI
|
||||
+yW3NssPWt1YUHidMBSAJ4KctIf91dyE93aStlxwC/QnyFsZOmcEsBzVCnz9GmWMl
|
||||
+1/6XzBS1yDUqByklx0TLH+z/sK9A+O2rZAy1mByCYwVxvbOZhnqGxAuToIS+A81v
|
||||
+5hCjsCiOScVB+cil30YBu0cH85RZ0ILNkHdKdrLLWW4wjphK2nBn2g2i3+ztf+nQ
|
||||
+ED2pQqZ/rhuW79jcyCZl9kXqe1wOdF0Cwah4N6/3LzIXEEKyEJxNqQwtNc2IVE8C
|
||||
+AwEAAaOB3zCB3DAJBgNVHRMEAjAAMDsGCysGAQQBkggJAUgBBCwMKlJlZCBIYXQg
|
||||
+RW50ZXJwcmlzZSBMaW51eCBmb3IgSUJNIHogU3lzdGVtczAUBgsrBgEEAZIICQFI
|
||||
+AgQFDAM5LjYwFgYLKwYBBAGSCAkBSAMEBwwFczM5MHgwJAYLKwYBBAGSCAkBSAQE
|
||||
+FQwTcmhlbC05LHJoZWwtOS1zMzkweDAdBgNVHQ4EFgQUYeogtTV8r2dkOv9rCOYQ
|
||||
+eNDNH5UwHwYDVR0jBBgwFoAUlv27HEBA/0CErbIfCybBw2pv1nwwDQYJKoZIhvcN
|
||||
+AQELBQADggIBANOzzfUKjlJsgJWUryjKfzPYISkCZXauHqBcST4N1HP1GA8tmMXi
|
||||
+bgh14+l7ZO8EloFvEGANsX2ffMfauuJx2NV6ks07NHWuM7W9kghDe5ZccrJCz88E
|
||||
+1zdvyWae5oSvTwfnvR/b63duOhs88u7NCQN2+n+pmJA0dPWbGTaIp3n4kJg8YKnd
|
||||
+O8Nct2doNS+1rrLpRmVKQy/E7fAXQzt1Bxqs2hORqbgffiSE9a+4akitY97GXRBm
|
||||
+nOO2DkyEW0xPtdy3zDvL7o7b1B0gdMOwqEolgGuDFsrfD+7ofpwOWjS+83gF6hMP
|
||||
+5YVD3sugu6xzCx6y7Yl/BfX4qvvT4YHtYob5rQA/t7JY4u4ryadkUxQLMEccMsyS
|
||||
+pKZQ8KFC5ZNJVK/ievkcBCsBlulbRftVJGF3TA2Hl2aBuMhGdUR5y/Q89WHUzeV6
|
||||
+U6AVzyEsvIJguswvKvFAyHwNuViCfFCkjNkJolvd/g03OSy1A7piQaU20QyltWmx
|
||||
+FILCR/DBUbCWIzKTfkLr93TbV2b1AH9uRW1SAGrftuevVXrNemWIwq1x/VgjDm3o
|
||||
+nk637pnEfZZzX8T2gO5z5yjlP0PR4s7hKkmp3TmAeG9015pFxPnD3AMI261srQ+c
|
||||
+KZBdIc5UseQo/4KvRKZ1CzxPh0WjJCzc/C/TKzIlEdELq/rnKGuqHKB9
|
||||
+-----END CERTIFICATE-----
|
||||
diff --git a/repos/system_upgrade/common/files/upgrade_paths.json b/repos/system_upgrade/common/files/upgrade_paths.json
|
||||
index 5399f148..cc9dcdb5 100644
|
||||
--- a/repos/system_upgrade/common/files/upgrade_paths.json
|
||||
+++ b/repos/system_upgrade/common/files/upgrade_paths.json
|
||||
@@ -1,19 +1,17 @@
|
||||
{
|
||||
"default": {
|
||||
- "7.9": ["8.8", "8.10"],
|
||||
- "8.8": ["9.2"],
|
||||
- "8.10": ["9.4", "9.5"],
|
||||
+ "7.9": ["8.10"],
|
||||
+ "8.10": ["9.4", "9.5", "9.6"],
|
||||
"9.6": ["10.0"],
|
||||
- "7": ["8.8", "8.10"],
|
||||
- "8": ["9.2", "9.4", "9.5"],
|
||||
+ "7": ["8.10"],
|
||||
+ "8": ["9.4", "9.5", "9.6"],
|
||||
"9": ["10.0"]
|
||||
},
|
||||
"saphana": {
|
||||
- "7.9": ["8.10", "8.8"],
|
||||
- "7": ["8.10", "8.8"],
|
||||
- "8.8": ["9.2"],
|
||||
- "8.10": ["9.4"],
|
||||
- "8": ["9.4", "9.2"],
|
||||
+ "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"]
|
||||
}
|
||||
diff --git a/repos/system_upgrade/common/libraries/config/version.py b/repos/system_upgrade/common/libraries/config/version.py
|
||||
index 152d9112..d710a647 100644
|
||||
--- a/repos/system_upgrade/common/libraries/config/version.py
|
||||
+++ b/repos/system_upgrade/common/libraries/config/version.py
|
||||
@@ -18,7 +18,7 @@ OP_MAP = {
|
||||
_SUPPORTED_VERSIONS = {
|
||||
# Note: 'rhel-alt' is detected when on 'rhel' with kernel 4.x
|
||||
'7': {'rhel': ['7.9'], 'rhel-alt': [], 'rhel-saphana': ['7.9']},
|
||||
- '8': {'rhel': ['8.8', '8.10'], 'rhel-saphana': ['8.8', '8.10']},
|
||||
+ '8': {'rhel': ['8.10'], 'rhel-saphana': ['8.10']},
|
||||
'9': {'rhel': ['9.4', '9.5', '9.6'], 'rhel-saphana': ['9.4', '9.6']},
|
||||
}
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
From f11f7c4c022b990f3cad15eff5149591e747a27b Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Thu, 2 Apr 2026 10:57:55 +0200
|
||||
Subject: [PATCH 39/44] Ensure that greenboot rpms are removed during IPU
|
||||
|
||||
The greenboot packages have a value just for rpm-ostree based systems.
|
||||
However, if someone install them anyway (e.g. configuration mistake..),
|
||||
they would damage the upgraded systems - mainly in case IPU 8.10 -> 9.8+.
|
||||
Systemd fails with error:
|
||||
```
|
||||
Failed to isolate the default target.
|
||||
```
|
||||
|
||||
Due to bugs in greenboot scriptlets, that do not count with DNF
|
||||
execution inside container, nor with the update of greenboot packages
|
||||
from 0.14.x to 0.16.x and newer.
|
||||
|
||||
As there is not value to have these packages on rpm based system
|
||||
at all, just remove them during the upgrade to stay on a safe side.
|
||||
---
|
||||
etc/leapp/transaction/to_remove | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/etc/leapp/transaction/to_remove b/etc/leapp/transaction/to_remove
|
||||
index 0feb7827..420078f4 100644
|
||||
--- a/etc/leapp/transaction/to_remove
|
||||
+++ b/etc/leapp/transaction/to_remove
|
||||
@@ -1,3 +1,11 @@
|
||||
### List of packages (each on new line) to be removed from the upgrade transaction
|
||||
# Removing initial-setup package to avoid it asking for EULA acceptance during upgrade - OAMG-1531
|
||||
initial-setup
|
||||
+
|
||||
+# greenboot packages have a value just for rpm-ostree based systems
|
||||
+# however, if someone would install them anyway, they would damage
|
||||
+# the upgraded systems (mainly in case IPU 8.10 -> 9.8+).
|
||||
+# As there is not value for of these packages on systems upgraded by leapp
|
||||
+# (rpm based only), let's just remove them to stay safe
|
||||
+greenboot
|
||||
+greenboot-default-health-checks
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -1,205 +0,0 @@
|
||||
From 83540ae7dbd6cb030a024249d6308c56f0d3216d Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Tue, 31 Mar 2026 17:23:39 +0200
|
||||
Subject: [PATCH 40/44] Regenerate grub config during 8->9 conversions
|
||||
|
||||
This is mainly a preventative action to make sure that the grub config
|
||||
is compatible with the target grub.
|
||||
|
||||
The actor only runs grub2-mkconfig when BLS is enabled in
|
||||
/etc/default/grub. When BLS is disabled, the regeneration is taken care
|
||||
of by the grub kernel install scripts (in /usr/lib/kernel/install/),
|
||||
which do call grub2-mkconfig as required.
|
||||
|
||||
On 9to10 conversions the kernel install scripts handle regeneration
|
||||
whether the BLS is enabled or not.
|
||||
|
||||
Note that in some cases grub2-mkconfig might be ran twice, as there are
|
||||
2 more actors that run it (ensurevalidgrubcfghybrid and
|
||||
grub2mkconfigonppc64). This shouldn't be a problem since the generation
|
||||
is quick. However a better solution could be designed in the future.
|
||||
|
||||
Jira: RHEL-110712
|
||||
---
|
||||
.../actors/regenerategrubcfg/actor.py | 23 ++++
|
||||
.../libraries/regenerategrubcfg.py | 28 +++++
|
||||
.../tests/test_regenerategrubcfg.py | 102 ++++++++++++++++++
|
||||
3 files changed, 153 insertions(+)
|
||||
create mode 100644 repos/system_upgrade/el8toel9/actors/regenerategrubcfg/actor.py
|
||||
create mode 100644 repos/system_upgrade/el8toel9/actors/regenerategrubcfg/libraries/regenerategrubcfg.py
|
||||
create mode 100644 repos/system_upgrade/el8toel9/actors/regenerategrubcfg/tests/test_regenerategrubcfg.py
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/regenerategrubcfg/actor.py b/repos/system_upgrade/el8toel9/actors/regenerategrubcfg/actor.py
|
||||
new file mode 100644
|
||||
index 00000000..d87e9c7b
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/regenerategrubcfg/actor.py
|
||||
@@ -0,0 +1,23 @@
|
||||
+from leapp.actors import Actor
|
||||
+from leapp.libraries.actor import regenerategrubcfg
|
||||
+from leapp.models import DefaultGrubInfo, TransactionCompleted
|
||||
+from leapp.tags import ApplicationsPhaseTag, IPUWorkflowTag
|
||||
+
|
||||
+
|
||||
+class RegenerateGrubCfg(Actor):
|
||||
+ """
|
||||
+ Regenerate GRUB2 configuration during conversion from EL8 to EL9.
|
||||
+
|
||||
+ During distribution conversions (e.g. CentOS to RHEL), the GRUB2
|
||||
+ configuration may need to be regenerated to ensure compatibility
|
||||
+ with the target distribution's GRUB2 tooling. This actor runs
|
||||
+ grub2-mkconfig when BLS is enabled in /etc/default/grub.
|
||||
+ """
|
||||
+
|
||||
+ name = 'regenerate_grub_cfg'
|
||||
+ consumes = (DefaultGrubInfo, TransactionCompleted)
|
||||
+ produces = ()
|
||||
+ tags = (IPUWorkflowTag, ApplicationsPhaseTag)
|
||||
+
|
||||
+ def process(self):
|
||||
+ regenerategrubcfg.process()
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/regenerategrubcfg/libraries/regenerategrubcfg.py b/repos/system_upgrade/el8toel9/actors/regenerategrubcfg/libraries/regenerategrubcfg.py
|
||||
new file mode 100644
|
||||
index 00000000..bedd0897
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/regenerategrubcfg/libraries/regenerategrubcfg.py
|
||||
@@ -0,0 +1,28 @@
|
||||
+from leapp.libraries.common import grub
|
||||
+from leapp.libraries.common.config import architecture, is_conversion
|
||||
+from leapp.libraries.stdlib import api, CalledProcessError, run
|
||||
+from leapp.models import DefaultGrubInfo
|
||||
+
|
||||
+GRUB_CFG_PATH = '/boot/grub2/grub.cfg'
|
||||
+
|
||||
+
|
||||
+def process():
|
||||
+ if architecture.matches_architecture(architecture.ARCH_S390X):
|
||||
+ return
|
||||
+
|
||||
+ if not is_conversion():
|
||||
+ return
|
||||
+
|
||||
+ default_grub_msg = next(api.consume(DefaultGrubInfo), None)
|
||||
+ if not default_grub_msg:
|
||||
+ api.current_logger().warning('No DefaultGrubInfo message, skipping GRUB config regeneration.')
|
||||
+ return
|
||||
+
|
||||
+ if not grub.is_blscfg_enabled_in_defaultgrub(default_grub_msg):
|
||||
+ return
|
||||
+
|
||||
+ api.current_logger().info('Conversion detected with BLS enabled, regenerating GRUB config')
|
||||
+ try:
|
||||
+ run(['grub2-mkconfig', '-o', GRUB_CFG_PATH])
|
||||
+ except CalledProcessError as e:
|
||||
+ api.current_logger().error('Failed to regenerate GRUB config: {}'.format(e))
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/regenerategrubcfg/tests/test_regenerategrubcfg.py b/repos/system_upgrade/el8toel9/actors/regenerategrubcfg/tests/test_regenerategrubcfg.py
|
||||
new file mode 100644
|
||||
index 00000000..7d8fb6f3
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/regenerategrubcfg/tests/test_regenerategrubcfg.py
|
||||
@@ -0,0 +1,102 @@
|
||||
+from unittest import mock
|
||||
+
|
||||
+import pytest
|
||||
+
|
||||
+from leapp.libraries.actor import regenerategrubcfg
|
||||
+from leapp.libraries.common.config import architecture
|
||||
+from leapp.libraries.common.testutils import CurrentActorMocked, logger_mocked
|
||||
+from leapp.libraries.stdlib import api, CalledProcessError
|
||||
+from leapp.models import DefaultGrub, DefaultGrubInfo
|
||||
+
|
||||
+GRUB2_MKCONFIG_CMD = ['grub2-mkconfig', '-o', '/boot/grub2/grub.cfg']
|
||||
+
|
||||
+BLS_ENABLED = DefaultGrubInfo(
|
||||
+ default_grub_info=[DefaultGrub(name='GRUB_ENABLE_BLSCFG', value='true')]
|
||||
+)
|
||||
+BLS_DISABLED = DefaultGrubInfo(
|
||||
+ default_grub_info=[DefaultGrub(name='GRUB_ENABLE_BLSCFG', value='false')]
|
||||
+)
|
||||
+
|
||||
+
|
||||
+@pytest.fixture
|
||||
+def mocked_run():
|
||||
+ with mock.patch.object(regenerategrubcfg, 'run') as m:
|
||||
+ yield m
|
||||
+
|
||||
+
|
||||
+@pytest.fixture(autouse=True)
|
||||
+def mocked_logger():
|
||||
+ with mock.patch.object(api, 'current_logger', logger_mocked()):
|
||||
+ yield api.current_logger
|
||||
+
|
||||
+
|
||||
+@pytest.fixture
|
||||
+def mock_actor(monkeypatch):
|
||||
+
|
||||
+ def make_mock(msgs, arch=architecture.ARCH_X86_64, is_conversion=False):
|
||||
+ instance = CurrentActorMocked(
|
||||
+ msgs=msgs,
|
||||
+ arch=arch,
|
||||
+ src_ver="8.10",
|
||||
+ dst_ver="9.6",
|
||||
+ )
|
||||
+ monkeypatch.setattr(api, 'current_actor', instance)
|
||||
+ # let's use this to cover all conversion paths
|
||||
+ monkeypatch.setattr(regenerategrubcfg, 'is_conversion', lambda: is_conversion)
|
||||
+ return instance
|
||||
+
|
||||
+ return make_mock
|
||||
+
|
||||
+
|
||||
+def test_conversion_bls_enabled_regenerates(mock_actor, mocked_run):
|
||||
+ """Conversion with BLS enabled -> regenerate."""
|
||||
+ mock_actor([BLS_ENABLED], is_conversion=True)
|
||||
+ regenerategrubcfg.process()
|
||||
+ mocked_run.assert_called_once_with(GRUB2_MKCONFIG_CMD)
|
||||
+
|
||||
+
|
||||
+def test_conversion_bls_disabled_skips(mock_actor, mocked_run):
|
||||
+ """Conversion with BLS not enabled -> skip."""
|
||||
+ mock_actor([BLS_DISABLED], is_conversion=True)
|
||||
+ regenerategrubcfg.process()
|
||||
+ mocked_run.assert_not_called()
|
||||
+
|
||||
+
|
||||
+def test_non_conversion_skips(mock_actor, mocked_run):
|
||||
+ """Non-conversion upgrade -> skip."""
|
||||
+ mock_actor([BLS_ENABLED])
|
||||
+ regenerategrubcfg.process()
|
||||
+ mocked_run.assert_not_called()
|
||||
+
|
||||
+
|
||||
+def test_s390x_skips(mock_actor, mocked_run):
|
||||
+ """s390x -> skip (uses ZIPL)."""
|
||||
+ mock_actor([BLS_ENABLED], arch=architecture.ARCH_S390X)
|
||||
+ regenerategrubcfg.process()
|
||||
+ mocked_run.assert_not_called()
|
||||
+
|
||||
+
|
||||
+def test_no_default_grub_info_skips(mock_actor, mocked_run, mocked_logger):
|
||||
+ """No DefaultGrubInfo -> skip."""
|
||||
+ mock_actor([], is_conversion=True)
|
||||
+ regenerategrubcfg.process()
|
||||
+ mocked_run.assert_not_called()
|
||||
+ assert any(
|
||||
+ "No DefaultGrubInfo message, skipping GRUB config regeneration." in msg
|
||||
+ for msg in mocked_logger.warnmsg
|
||||
+ )
|
||||
+
|
||||
+
|
||||
+def test_failure_nonfatal(mock_actor, mocked_run, mocked_logger):
|
||||
+ """grub2-mkconfig failure -> non-fatal, logs error."""
|
||||
+ mocked_run.side_effect = CalledProcessError(
|
||||
+ message='A Leapp Command Error occurred.',
|
||||
+ command=GRUB2_MKCONFIG_CMD,
|
||||
+ result={'signal': None, 'exit_code': 1, 'pid': 0, 'stdout': 'fake', 'stderr': 'fake'}
|
||||
+ )
|
||||
+ mock_actor([BLS_ENABLED], is_conversion=True)
|
||||
+
|
||||
+ regenerategrubcfg.process()
|
||||
+
|
||||
+ mocked_run.assert_called_once_with(GRUB2_MKCONFIG_CMD)
|
||||
+ assert any('Failed to regenerate GRUB config' in msg for msg in mocked_logger.errmsg)
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
From f50e3474a619ed338c2514933303320d986e6ffe Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Thu, 14 Nov 2024 16:26:55 +0100
|
||||
Subject: [PATCH 40/40] spec: drop the /etc/leapp/actor_confid.d dir
|
||||
|
||||
The directory should be provided by the framework. leapp-repository
|
||||
should provide only a content inside if any present.
|
||||
---
|
||||
packaging/leapp-repository.spec | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/packaging/leapp-repository.spec b/packaging/leapp-repository.spec
|
||||
index 2bb52505..6676d907 100644
|
||||
--- a/packaging/leapp-repository.spec
|
||||
+++ b/packaging/leapp-repository.spec
|
||||
@@ -250,9 +250,7 @@ install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/files/
|
||||
install -m 0644 etc/leapp/transaction/* %{buildroot}%{_sysconfdir}/leapp/transaction
|
||||
install -m 0644 etc/leapp/files/* %{buildroot}%{_sysconfdir}/leapp/files
|
||||
|
||||
-# Actor configuration dir
|
||||
-install -m 0755 -d %{buildroot}%{_sysconfdir}/leapp/actor_conf.d/
|
||||
-# uncomment to install existing configs
|
||||
+# uncomment to install existing configs if any exists
|
||||
#install -m 0644 etc/leapp/actor_conf.d/* %%{buildroot}%%{_sysconfdir}/leapp/actor_conf.d
|
||||
|
||||
# install CLI commands for the leapp utility on the expected path
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
From 9c07443b0148139b511bcd52ecac294c86a15826 Mon Sep 17 00:00:00 2001
|
||||
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
|
||||
Date: Wed, 16 Oct 2024 09:17:17 +0000
|
||||
Subject: [PATCH 41/53] chore(deps): update dependency ubuntu to v24
|
||||
|
||||
---
|
||||
.github/workflows/reuse-copr-build.yml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/.github/workflows/reuse-copr-build.yml b/.github/workflows/reuse-copr-build.yml
|
||||
index 3cf06254..c6702e1a 100644
|
||||
--- a/.github/workflows/reuse-copr-build.yml
|
||||
+++ b/.github/workflows/reuse-copr-build.yml
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
reusable_workflow_copr_build_job:
|
||||
# This job only runs for '/rerun' pull request comments by owner, member, or collaborator of the repo/organization.
|
||||
name: Build copr builds for tft tests
|
||||
- runs-on: ubuntu-22.04
|
||||
+ runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
artifacts: ${{ steps.gen_artifacts.outputs.artifacts }}
|
||||
if: |
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
From 971e5e329290d8e5047ac85c6c85943dfadd5fe6 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Tue, 14 Apr 2026 11:25:01 +0200
|
||||
Subject: [PATCH 41/44] python tests deps: update version requirements per
|
||||
python
|
||||
|
||||
tl;dr; We haven't updated the requirements.txt file for a long time
|
||||
(basically since IPU 7 -> 8; if we do not count some minor updates).
|
||||
Let's update dependencies to use newer python modules for newer
|
||||
versions of python.
|
||||
|
||||
* Pytest
|
||||
Originally we required pytest v6.2.5 for any python 3.6+. This is
|
||||
pretty old requirement coming from time of python ~ 3.8 and recently
|
||||
a CVE-2025-71176 occuared, which is fix in pytest v9.0.3.
|
||||
So let's update ranges to actually allow use of newer pytest on newer
|
||||
systems:
|
||||
|
||||
+----------------+---------------+
|
||||
| pytest version | python range |
|
||||
+----------------+---------------+
|
||||
| 6.2.5 | 3.6.x - 3.7.x |
|
||||
| 7.4.4 | 3.8.x - 3.9.x |
|
||||
| 9.0.3 | 3.10+ |
|
||||
+----------------+---------------+
|
||||
Note that Pytest 8.x is messing with imports which breaks leapp
|
||||
import handling unfortunately (race-condition). Seems that these
|
||||
problems are fixed for Pytest 9 with Python 3.10+. In case we
|
||||
figure out problems anyway, pytest will need to be executed with
|
||||
additional parameters to use old import style again. As there is
|
||||
no high demand for newer pytest on python 3.9, let's stick just
|
||||
with working pytest versions.
|
||||
|
||||
* Pyudev
|
||||
The original v0.22 is used up to CS 9 (pyton 3.9-). Use 0.24.1 for
|
||||
python 3.10+ (reflects CS 10 as well)
|
||||
|
||||
* Distro
|
||||
The original v1.5.0 can be used till CS 9 (python 3.9 included) safely
|
||||
as nowadays. Let's use version 1.9.0 for Python 3.10+
|
||||
|
||||
* Drop unsued dependencies (old python that is no longer supported
|
||||
in the project).
|
||||
---
|
||||
requirements.txt | 13 +++++++------
|
||||
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/requirements.txt b/requirements.txt
|
||||
index 3c79b23d..e4294718 100644
|
||||
--- a/requirements.txt
|
||||
+++ b/requirements.txt
|
||||
@@ -5,13 +5,14 @@ isort
|
||||
funcsigs==1.0.2
|
||||
mock==2.0.0
|
||||
pylint
|
||||
-pytest==4.6.11; python_version < '3.0'
|
||||
-pytest==6.2.5; python_version >= '3.6'
|
||||
-pyudev==0.22.0
|
||||
-distro==1.5.0
|
||||
+pytest==6.2.5; python_version >= '3.6' and python_version < '3.8'
|
||||
+pytest==7.4.4; python_version >= '3.8' and python_version < '3.10'
|
||||
+pytest==9.0.3; python_version >= '3.10'
|
||||
+pyudev==0.22.0; python_version < '3.10'
|
||||
+pyudev==0.24.1; python_version >= '3.10'
|
||||
+distro==1.5.0; python_version < '3.10'
|
||||
+distro==1.9.0; python_version >= '3.10'
|
||||
ipaddress==1.0.23
|
||||
git+https://github.com/oamg/leapp
|
||||
requests
|
||||
-# pinning a py27 troublemaking transitive dependency
|
||||
-lazy-object-proxy==1.5.2; python_version < '3'
|
||||
rpm
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -1,149 +0,0 @@
|
||||
From 0f0be8e4ca80721173d289a3db0b170334529c2c Mon Sep 17 00:00:00 2001
|
||||
From: Matej Matuska <mmatuska@redhat.com>
|
||||
Date: Wed, 29 Oct 2025 19:31:00 +0100
|
||||
Subject: [PATCH 42/44] Drop dependency on mock
|
||||
|
||||
The mock library is now a part of the Python standard library since
|
||||
Python 3.3 and is available as the unittest.mock. The 'mock' library is
|
||||
only a backport which is not needed anymore.
|
||||
|
||||
Also remove some unnecessary imports.
|
||||
---
|
||||
commands/tests/test_upgrade_paths.py | 2 +-
|
||||
.../common/actors/biosdevname/tests/test_biosdevname.py | 3 ++-
|
||||
.../actors/cephvolumescan/tests/test_cephvolumescan.py | 5 +----
|
||||
.../tests/test_distributionsignedrpmscanner.py | 3 +--
|
||||
.../actors/ifcfgscanner/tests/unit_test_ifcfgscanner.py | 2 +-
|
||||
.../common/actors/scanmemory/tests/test_scanmemory.py | 3 ++-
|
||||
.../tests/component_test_selinuxcontentscanner.py | 4 +---
|
||||
.../el8toel9/actors/nisscanner/tests/test_nisscan.py | 3 ++-
|
||||
requirements.txt | 1 -
|
||||
9 files changed, 11 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/commands/tests/test_upgrade_paths.py b/commands/tests/test_upgrade_paths.py
|
||||
index 773cdf1c..83e8b7f9 100644
|
||||
--- a/commands/tests/test_upgrade_paths.py
|
||||
+++ b/commands/tests/test_upgrade_paths.py
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
import resource
|
||||
+import unittest.mock as mock
|
||||
|
||||
-import mock
|
||||
import pytest
|
||||
|
||||
from leapp.cli.commands import command_utils
|
||||
diff --git a/repos/system_upgrade/common/actors/biosdevname/tests/test_biosdevname.py b/repos/system_upgrade/common/actors/biosdevname/tests/test_biosdevname.py
|
||||
index 3aa8c614..1b11174f 100644
|
||||
--- a/repos/system_upgrade/common/actors/biosdevname/tests/test_biosdevname.py
|
||||
+++ b/repos/system_upgrade/common/actors/biosdevname/tests/test_biosdevname.py
|
||||
@@ -1,7 +1,8 @@
|
||||
+from unittest.mock import mock_open, patch
|
||||
+
|
||||
import pytest
|
||||
import pyudev
|
||||
import six
|
||||
-from mock import mock_open, patch
|
||||
|
||||
from leapp.exceptions import StopActorExecutionError
|
||||
from leapp.libraries.actor import biosdevname
|
||||
diff --git a/repos/system_upgrade/common/actors/cephvolumescan/tests/test_cephvolumescan.py b/repos/system_upgrade/common/actors/cephvolumescan/tests/test_cephvolumescan.py
|
||||
index 168b8fc2..14e1f359 100644
|
||||
--- a/repos/system_upgrade/common/actors/cephvolumescan/tests/test_cephvolumescan.py
|
||||
+++ b/repos/system_upgrade/common/actors/cephvolumescan/tests/test_cephvolumescan.py
|
||||
@@ -1,9 +1,6 @@
|
||||
-import pytest
|
||||
-from mock import Mock, patch
|
||||
+from unittest.mock import patch
|
||||
|
||||
from leapp.libraries.actor import cephvolumescan
|
||||
-from leapp.models import InstalledRPM, LsblkEntry, RPM, StorageInfo
|
||||
-from leapp.reporting import Report
|
||||
|
||||
CONT_PS_COMMAND_OUTPUT = {
|
||||
"stdout":
|
||||
diff --git a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py
|
||||
index b0c616cb..e5db0c8f 100644
|
||||
--- a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py
|
||||
+++ b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-import mock
|
||||
+import unittest.mock as mock
|
||||
|
||||
from leapp.libraries.common import rpms
|
||||
from leapp.libraries.common.config import mock_configs
|
||||
@@ -8,7 +8,6 @@ from leapp.models import (
|
||||
fields,
|
||||
InstalledRPM,
|
||||
InstalledUnsignedRPM,
|
||||
- IPUConfig,
|
||||
Model,
|
||||
OSRelease,
|
||||
RPM,
|
||||
diff --git a/repos/system_upgrade/common/actors/ifcfgscanner/tests/unit_test_ifcfgscanner.py b/repos/system_upgrade/common/actors/ifcfgscanner/tests/unit_test_ifcfgscanner.py
|
||||
index d996de84..bef3d485 100644
|
||||
--- a/repos/system_upgrade/common/actors/ifcfgscanner/tests/unit_test_ifcfgscanner.py
|
||||
+++ b/repos/system_upgrade/common/actors/ifcfgscanner/tests/unit_test_ifcfgscanner.py
|
||||
@@ -1,9 +1,9 @@
|
||||
import errno
|
||||
import textwrap
|
||||
+import unittest.mock as mock
|
||||
from io import StringIO
|
||||
from os.path import basename
|
||||
|
||||
-import mock
|
||||
import six
|
||||
|
||||
from leapp.libraries.actor import ifcfgscanner
|
||||
diff --git a/repos/system_upgrade/common/actors/scanmemory/tests/test_scanmemory.py b/repos/system_upgrade/common/actors/scanmemory/tests/test_scanmemory.py
|
||||
index 13e4e724..20fa8e91 100644
|
||||
--- a/repos/system_upgrade/common/actors/scanmemory/tests/test_scanmemory.py
|
||||
+++ b/repos/system_upgrade/common/actors/scanmemory/tests/test_scanmemory.py
|
||||
@@ -1,4 +1,5 @@
|
||||
-import mock
|
||||
+import unittest.mock as mock
|
||||
+
|
||||
import six
|
||||
|
||||
from leapp.libraries.actor import scanmemory
|
||||
diff --git a/repos/system_upgrade/common/actors/selinux/selinuxcontentscanner/tests/component_test_selinuxcontentscanner.py b/repos/system_upgrade/common/actors/selinux/selinuxcontentscanner/tests/component_test_selinuxcontentscanner.py
|
||||
index 802e038a..15aef5d8 100644
|
||||
--- a/repos/system_upgrade/common/actors/selinux/selinuxcontentscanner/tests/component_test_selinuxcontentscanner.py
|
||||
+++ b/repos/system_upgrade/common/actors/selinux/selinuxcontentscanner/tests/component_test_selinuxcontentscanner.py
|
||||
@@ -4,9 +4,7 @@ import pytest
|
||||
|
||||
from leapp.libraries.common.config import mock_configs
|
||||
from leapp.libraries.stdlib import api, CalledProcessError, run
|
||||
-from leapp.models import SELinuxCustom, SELinuxFacts, SELinuxModule, SELinuxModules, SELinuxRequestRPMs
|
||||
-from leapp.reporting import Report
|
||||
-from leapp.snactor.fixture import current_actor_context
|
||||
+from leapp.models import SELinuxCustom, SELinuxFacts, SELinuxModules, SELinuxRequestRPMs
|
||||
|
||||
# compat module ensures compatibility with newer systems and is not part of testing
|
||||
TEST_MODULES = [
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/nisscanner/tests/test_nisscan.py b/repos/system_upgrade/el8toel9/actors/nisscanner/tests/test_nisscan.py
|
||||
index ed000ce0..d7e77a28 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/nisscanner/tests/test_nisscan.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/nisscanner/tests/test_nisscan.py
|
||||
@@ -1,4 +1,5 @@
|
||||
-import mock
|
||||
+import unittest.mock as mock
|
||||
+
|
||||
import pytest
|
||||
import six
|
||||
|
||||
diff --git a/requirements.txt b/requirements.txt
|
||||
index e4294718..ee1d9006 100644
|
||||
--- a/requirements.txt
|
||||
+++ b/requirements.txt
|
||||
@@ -3,7 +3,6 @@
|
||||
flake8
|
||||
isort
|
||||
funcsigs==1.0.2
|
||||
-mock==2.0.0
|
||||
pylint
|
||||
pytest==6.2.5; python_version >= '3.6' and python_version < '3.8'
|
||||
pytest==7.4.4; python_version >= '3.8' and python_version < '3.10'
|
||||
--
|
||||
2.53.0
|
||||
|
||||
74
SOURCES/0042-feat-net-naming-scheme-enable-by-default.patch
Normal file
74
SOURCES/0042-feat-net-naming-scheme-enable-by-default.patch
Normal file
@ -0,0 +1,74 @@
|
||||
From 3c3421a0f155fe3bdfaee74c5345e86874684a09 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Tue, 19 Nov 2024 10:56:50 +0100
|
||||
Subject: [PATCH 42/53] feat(net-naming-scheme): enable by default
|
||||
|
||||
This commit enables the use of net.naming-scheme for 8>9 upgrades by
|
||||
default. The previously used environmental variablel
|
||||
LEAPP_USE_NET_NAMING_SCHEMES is replaced with
|
||||
LEAPP_DISABLE_NET_NAMING_SCHEMES with inverse semantics.
|
||||
---
|
||||
.../libraries/persistentnetnamesconfig.py | 11 ++++++++---
|
||||
.../libraries/emit_net_naming.py | 4 ++--
|
||||
.../tests/test_emit_net_naming_scheme.py | 4 ++--
|
||||
3 files changed, 12 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py b/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
index b2c7f5ff..c90d13f2 100644
|
||||
--- a/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
+++ b/repos/system_upgrade/common/actors/persistentnetnamesconfig/libraries/persistentnetnamesconfig.py
|
||||
@@ -39,9 +39,14 @@ def generate_link_file(interface):
|
||||
|
||||
@suppress_deprecation(InitrdIncludes)
|
||||
def process():
|
||||
- if get_env('LEAPP_USE_NET_NAMING_SCHEMES', '0') == '1' and version.get_target_major_version() == '9':
|
||||
- # We can use this only for 8>9, for now
|
||||
- api.current_logger().info('Skipping generation of .link files renaming NICs as LEAPP_USE_NET_NAMING_SCHEMES=1')
|
||||
+ are_net_schemes_enabled = get_env('LEAPP_DISABLE_NET_NAMING_SCHEMES', '0') != '1'
|
||||
+ is_upgrade_8to9 = version.get_target_major_version() == '9'
|
||||
+
|
||||
+ if are_net_schemes_enabled and is_upgrade_8to9:
|
||||
+ # For 8>9 we are using net.naming_scheme kernel arg by default - do not generate link files
|
||||
+ msg = ('Skipping generation of .link files renaming NICs as net.naming-scheme '
|
||||
+ '{LEAPP_DISABLE_NET_NAMING_SCHEMES != 1} is enabled and upgrade is 8>9')
|
||||
+ api.current_logger().info(msg)
|
||||
return
|
||||
|
||||
if get_env('LEAPP_NO_NETWORK_RENAMING', '0') == '1':
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
index 726bb459..bab62a56 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/libraries/emit_net_naming.py
|
||||
@@ -44,9 +44,9 @@ def is_net_scheme_compatible_with_current_cmdline():
|
||||
|
||||
|
||||
def emit_msgs_to_use_net_naming_schemes():
|
||||
- is_env_var_set = get_env('LEAPP_USE_NET_NAMING_SCHEMES', '0') == '1'
|
||||
+ is_feature_enabled = get_env('LEAPP_DISABLE_NET_NAMING_SCHEMES', '0') != '1'
|
||||
is_upgrade_8to9 = version.get_target_major_version() == '9'
|
||||
- is_net_naming_enabled_and_permitted = is_env_var_set and is_upgrade_8to9
|
||||
+ is_net_naming_enabled_and_permitted = is_feature_enabled and is_upgrade_8to9
|
||||
if not is_net_naming_enabled_and_permitted:
|
||||
return
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py
|
||||
index 7a5eeba5..acf72241 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/emit_net_naming_scheme/tests/test_emit_net_naming_scheme.py
|
||||
@@ -51,11 +51,11 @@ def test_is_net_scheme_compatible_with_current_cmdline(monkeypatch, kernel_args,
|
||||
]
|
||||
)
|
||||
def test_emit_msgs_to_use_net_naming_schemes(monkeypatch, is_net_scheme_enabled, is_current_cmdline_compatible):
|
||||
- envvar_value = '1' if is_net_scheme_enabled else '0'
|
||||
+ envvar_value = '0' if is_net_scheme_enabled else '1'
|
||||
|
||||
mocked_actor = CurrentActorMocked(src_ver='8.10',
|
||||
dst_ver='9.5',
|
||||
- envars={'LEAPP_USE_NET_NAMING_SCHEMES': envvar_value})
|
||||
+ envars={'LEAPP_DISABLE_NET_NAMING_SCHEMES': envvar_value})
|
||||
monkeypatch.setattr(api, 'current_actor', mocked_actor)
|
||||
|
||||
monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
--
|
||||
2.47.1
|
||||
|
||||
48
SOURCES/0043-Fix-unreadable-output-in-upgrade-log.patch
Normal file
48
SOURCES/0043-Fix-unreadable-output-in-upgrade-log.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 1a0183b1a43e42891199efed9bd0891a24224142 Mon Sep 17 00:00:00 2001
|
||||
From: David Kubek <dkubek@redhat.com>
|
||||
Date: Wed, 8 Jan 2025 12:05:57 +0100
|
||||
Subject: [PATCH 43/53] Fix unreadable output in upgrade log
|
||||
|
||||
This commit resolves an issue where unwanted escape sequences (e.g.,
|
||||
ANSI codes) appear in the output of certain commands like `dnf` during
|
||||
upgrades.
|
||||
|
||||
The issue arises because, starting with version 242, `systemd-nspawn`
|
||||
introduced new pseudo-TTY capabilities (see the `Input/Output Options`
|
||||
section in `systemd-nspawn(1)`). As a result, commands run within
|
||||
container may include these escape sequences.
|
||||
|
||||
To address this, pseudo-TTY support is explicitly disabled in
|
||||
`systemd-nspawn` for upgrades on RHEL9 and later.
|
||||
|
||||
JIRA: RHEL-69829
|
||||
---
|
||||
repos/system_upgrade/common/libraries/mounting.py | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/libraries/mounting.py b/repos/system_upgrade/common/libraries/mounting.py
|
||||
index a546e9d0..2eb19d31 100644
|
||||
--- a/repos/system_upgrade/common/libraries/mounting.py
|
||||
+++ b/repos/system_upgrade/common/libraries/mounting.py
|
||||
@@ -5,7 +5,7 @@ import shutil
|
||||
from collections import namedtuple
|
||||
|
||||
from leapp.libraries.common.config import get_all_envs
|
||||
-from leapp.libraries.common.config.version import get_source_major_version
|
||||
+from leapp.libraries.common.config.version import get_source_major_version, matches_source_version
|
||||
from leapp.libraries.stdlib import api, CalledProcessError, run
|
||||
|
||||
# Using ALWAYS_BIND will crash the upgrade process if the file does not exist.
|
||||
@@ -88,6 +88,9 @@ class IsolationType(object):
|
||||
# in such a case, just add line into the previous solution..
|
||||
# TODO: the same about --capability=all
|
||||
final_cmd += ['--keep-unit', '--capability=all']
|
||||
+ if matches_source_version('>= 9.0'):
|
||||
+ # Disable pseudo-TTY in container
|
||||
+ final_cmd += ['--pipe']
|
||||
return final_cmd + ['-D', self.target] + binds + setenvs + cmd
|
||||
|
||||
class CHROOT(_Implementation):
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -1,194 +0,0 @@
|
||||
From d8c82c9460e2ab08ac735c7af06ec4a73a9b4de4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Peter=20Mo=C4=8D=C3=A1ry?=
|
||||
<68905580+PeterMocary@users.noreply.github.com>
|
||||
Date: Thu, 16 Apr 2026 23:00:14 +0200
|
||||
Subject: [PATCH 43/44] remove single quoting from remediation commands (#1520)
|
||||
|
||||
The framework now uses shlex.quote to always make literals out of
|
||||
remediation command arguments. Some of the existing remediation commands used single
|
||||
quotes in their subcommands so the resulting command in leapp-report.txt used
|
||||
unintuitive escaping of single quotes.
|
||||
|
||||
The chackrootsymlinks can still end up with a single quote if the user
|
||||
has it in one of the symlinks that need to be adjusted. However, it is
|
||||
not possible to handle this differently without introducing side effects.
|
||||
|
||||
jira: RHEL-156521
|
||||
---
|
||||
packaging/leapp-repository.spec | 2 +-
|
||||
.../common/actors/checkrootsymlinks/actor.py | 53 +--------------
|
||||
.../libraries/checkrootsymlinks.py | 65 +++++++++++++++++++
|
||||
.../libraries/checkyumpluginsenabled.py | 6 +-
|
||||
4 files changed, 71 insertions(+), 55 deletions(-)
|
||||
create mode 100644 repos/system_upgrade/common/actors/checkrootsymlinks/libraries/checkrootsymlinks.py
|
||||
|
||||
diff --git a/packaging/leapp-repository.spec b/packaging/leapp-repository.spec
|
||||
index 3ffafafa..70b1d7d3 100644
|
||||
--- a/packaging/leapp-repository.spec
|
||||
+++ b/packaging/leapp-repository.spec
|
||||
@@ -120,7 +120,7 @@ Requires: leapp-repository-dependencies = %{leapp_repo_deps}
|
||||
|
||||
# IMPORTANT: this is capability provided by the leapp framework rpm.
|
||||
# Check that 'version' instead of the real framework rpm version.
|
||||
-Requires: leapp-framework >= 6.4, leapp-framework < 7
|
||||
+Requires: leapp-framework >= 6.5, leapp-framework < 7
|
||||
|
||||
# Since we provide sub-commands for the leapp utility, we expect the leapp
|
||||
# tool to be installed as well.
|
||||
diff --git a/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py b/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py
|
||||
index 2e805542..391e5589 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkrootsymlinks/actor.py
|
||||
@@ -1,8 +1,5 @@
|
||||
-import os
|
||||
-
|
||||
-from leapp import reporting
|
||||
from leapp.actors import Actor
|
||||
-from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.actor import checkrootsymlinks
|
||||
from leapp.models import Report, RootDirectory
|
||||
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
||||
|
||||
@@ -20,50 +17,4 @@ class CheckRootSymlinks(Actor):
|
||||
tags = (IPUWorkflowTag, ChecksPhaseTag)
|
||||
|
||||
def process(self):
|
||||
- rootdir = next(self.consume(RootDirectory), None)
|
||||
- if not rootdir:
|
||||
- raise StopActorExecutionError('Cannot check root symlinks',
|
||||
- details={'Problem': 'Did not receive a message with '
|
||||
- 'root subdirectories'})
|
||||
- absolute_links = [item for item in rootdir.items if item.target and os.path.isabs(item.target)]
|
||||
- absolute_links_nonutf = [item for item in rootdir.invalid_items if item.target and os.path.isabs(item.target)]
|
||||
- if not absolute_links and not absolute_links_nonutf:
|
||||
- return
|
||||
-
|
||||
- report_fields = [
|
||||
- reporting.Title('Upgrade requires links in root directory to be relative'),
|
||||
- reporting.Summary(
|
||||
- 'After rebooting, parts of the upgrade process can fail if symbolic links in / '
|
||||
- 'point to absolute paths.\n'
|
||||
- 'Please change these links to relative ones.'
|
||||
- ),
|
||||
- reporting.ExternalLink(
|
||||
- url='https://access.redhat.com/solutions/6989732',
|
||||
- title='leapp upgrade stops with Inhibitor "Upgrade requires links in root '
|
||||
- 'directory to be relative"'
|
||||
- ),
|
||||
- reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups([reporting.Groups.INHIBITOR])]
|
||||
-
|
||||
- # Generate reports about absolute links presence
|
||||
- rem_commands = []
|
||||
- if absolute_links:
|
||||
- commands = []
|
||||
- for item in absolute_links:
|
||||
- command = ' '.join(['ln',
|
||||
- '-snf',
|
||||
- f"'{os.path.relpath(item.target, '/')}'",
|
||||
- f"'{os.path.join('/', item.name)}'"])
|
||||
- commands.append(command)
|
||||
- rem_commands = [['bash', '-c', '{}'.format(' && '.join(commands))]]
|
||||
- # Generate reports about non-utf8 absolute links presence
|
||||
- nonutf_count = len(absolute_links_nonutf)
|
||||
- if nonutf_count > 0:
|
||||
- # for non-utf encoded filenames can't provide a remediation command, so will mention this fact in a hint
|
||||
- rem_hint = ("{} symbolic links point to absolute paths that have non-utf8 encoding and need to be"
|
||||
- " fixed additionally".format(nonutf_count))
|
||||
- report_fields.append(reporting.Remediation(hint=rem_hint, commands=rem_commands))
|
||||
- else:
|
||||
- report_fields.append(reporting.Remediation(commands=rem_commands))
|
||||
-
|
||||
- reporting.create_report(report_fields)
|
||||
+ checkrootsymlinks.process()
|
||||
diff --git a/repos/system_upgrade/common/actors/checkrootsymlinks/libraries/checkrootsymlinks.py b/repos/system_upgrade/common/actors/checkrootsymlinks/libraries/checkrootsymlinks.py
|
||||
new file mode 100644
|
||||
index 00000000..2c5676bd
|
||||
--- /dev/null
|
||||
+++ b/repos/system_upgrade/common/actors/checkrootsymlinks/libraries/checkrootsymlinks.py
|
||||
@@ -0,0 +1,65 @@
|
||||
+import os
|
||||
+
|
||||
+from leapp import reporting
|
||||
+from leapp.exceptions import StopActorExecutionError
|
||||
+from leapp.libraries.stdlib import api
|
||||
+from leapp.models import RootDirectory
|
||||
+
|
||||
+
|
||||
+def _dquote(s):
|
||||
+ """Double-quote a string for use inside a non-interactive shell script."""
|
||||
+ escaped = (s.replace('\\', '\\\\')
|
||||
+ .replace('"', '\\"')
|
||||
+ .replace('$', '\\$')
|
||||
+ .replace('`', '\\`'))
|
||||
+ return '"{}"'.format(escaped)
|
||||
+
|
||||
+
|
||||
+def process():
|
||||
+ rootdir = next(api.consume(RootDirectory), None)
|
||||
+ if not rootdir:
|
||||
+ raise StopActorExecutionError('Cannot check root symlinks',
|
||||
+ details={'Problem': 'Did not receive a message with '
|
||||
+ 'root subdirectories'})
|
||||
+ absolute_links = [item for item in rootdir.items if item.target and os.path.isabs(item.target)]
|
||||
+ absolute_links_nonutf = [item for item in rootdir.invalid_items if item.target and os.path.isabs(item.target)]
|
||||
+ if not absolute_links and not absolute_links_nonutf:
|
||||
+ return
|
||||
+
|
||||
+ report_fields = [
|
||||
+ reporting.Title('Upgrade requires links in root directory to be relative'),
|
||||
+ reporting.Summary(
|
||||
+ 'After rebooting, parts of the upgrade process can fail if symbolic links in / '
|
||||
+ 'point to absolute paths.\n'
|
||||
+ 'Please change these links to relative ones.'
|
||||
+ ),
|
||||
+ reporting.ExternalLink(
|
||||
+ url='https://access.redhat.com/solutions/6989732',
|
||||
+ title='leapp upgrade stops with Inhibitor "Upgrade requires links in root '
|
||||
+ 'directory to be relative"'
|
||||
+ ),
|
||||
+ reporting.Severity(reporting.Severity.HIGH),
|
||||
+ reporting.Groups([reporting.Groups.INHIBITOR])]
|
||||
+
|
||||
+ # Generate reports about absolute links presence
|
||||
+ rem_commands = []
|
||||
+ if absolute_links:
|
||||
+ commands = []
|
||||
+ for item in absolute_links:
|
||||
+ command = ' '.join(['ln',
|
||||
+ '-snf',
|
||||
+ _dquote(os.path.relpath(item.target, '/')),
|
||||
+ _dquote(os.path.join('/', item.name))])
|
||||
+ commands.append(command)
|
||||
+ rem_commands = [['bash', '-c', '{}'.format(' && '.join(commands))]]
|
||||
+ # Generate reports about non-utf8 absolute links presence
|
||||
+ nonutf_count = len(absolute_links_nonutf)
|
||||
+ if nonutf_count > 0:
|
||||
+ # for non-utf encoded filenames can't provide a remediation command, so will mention this fact in a hint
|
||||
+ rem_hint = ("{} symbolic links point to absolute paths that have non-utf8 encoding and need to be"
|
||||
+ " fixed additionally".format(nonutf_count))
|
||||
+ report_fields.append(reporting.Remediation(hint=rem_hint, commands=rem_commands))
|
||||
+ else:
|
||||
+ report_fields.append(reporting.Remediation(commands=rem_commands))
|
||||
+
|
||||
+ reporting.create_report(report_fields)
|
||||
diff --git a/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py b/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py
|
||||
index 869e2a88..5c99a0d9 100644
|
||||
--- a/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py
|
||||
+++ b/repos/system_upgrade/common/actors/checkyumpluginsenabled/libraries/checkyumpluginsenabled.py
|
||||
@@ -36,9 +36,9 @@ def check_required_dnf_plugins_enabled(pkg_manager_info):
|
||||
product_id_plugin_conf = os.path.join(plugin_configs_dir, 'product-id.conf')
|
||||
|
||||
remediation_commands = [
|
||||
- f"sed -i 's/^plugins=0/plugins=1/' '{dnf_conf_path}'",
|
||||
- f"sed -i 's/^enabled=0/enabled=1/' '{rhsm_plugin_conf}'",
|
||||
- f"sed -i 's/^enabled=0/enabled=1/' '{product_id_plugin_conf}'"
|
||||
+ f'sed -i "s/^plugins=0/plugins=1/" "{dnf_conf_path}"',
|
||||
+ f'sed -i "s/^enabled=0/enabled=1/" "{rhsm_plugin_conf}"',
|
||||
+ f'sed -i "s/^enabled=0/enabled=1/" "{product_id_plugin_conf}"',
|
||||
]
|
||||
|
||||
reporting.create_report([
|
||||
--
|
||||
2.53.0
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
From c92dbb41fc3d3c3c77ae33a723ad9f961b8b8215 Mon Sep 17 00:00:00 2001
|
||||
From: dosas <dosas@users.noreply.github.com>
|
||||
Date: Thu, 9 Jan 2025 14:58:54 +0100
|
||||
Subject: [PATCH 44/53] Remove unmaintained .gitlab-ci.yml config file
|
||||
|
||||
---
|
||||
.gitlab-ci.yml | 34 ----------------------------------
|
||||
1 file changed, 34 deletions(-)
|
||||
delete mode 100644 .gitlab-ci.yml
|
||||
|
||||
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
|
||||
deleted file mode 100644
|
||||
index 24e91dbb..00000000
|
||||
--- a/.gitlab-ci.yml
|
||||
+++ /dev/null
|
||||
@@ -1,34 +0,0 @@
|
||||
-stages:
|
||||
-- build-initrd
|
||||
-- build-srpm
|
||||
-# - build-rpms
|
||||
-
|
||||
-build_initrd:
|
||||
- only:
|
||||
- - master@leapp/leapp-actors-internal
|
||||
- stage: build-initrd
|
||||
- cache:
|
||||
- key: "${CI_PIPELINE_ID}"
|
||||
- paths:
|
||||
- - sources/dracut/upgrade-boot-files.tgz
|
||||
- script:
|
||||
- - 'export BASEDIR="$PWD"'
|
||||
- - helpers/docker/docker-run.sh
|
||||
- image: docker-registry.engineering.redhat.com/leapp-builds/leapp-initrd-rhel8-build:latest
|
||||
-
|
||||
-build_srpm:
|
||||
- only:
|
||||
- - master@leapp/leapp-actors-internal
|
||||
- stage: build-srpm
|
||||
- dependencies:
|
||||
- - build_initrd
|
||||
- cache:
|
||||
- key: "${CI_PIPELINE_ID}"
|
||||
- paths:
|
||||
- - sources/dracut/upgrade-boot-files.tgz
|
||||
- script:
|
||||
- - dnf install -y git-core make rpm-build copr-cli
|
||||
- - export LEAPP_INITRD_SKIP=1
|
||||
- - make srpm
|
||||
- image: fedora:28
|
||||
-
|
||||
--
|
||||
2.47.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,55 @@
|
||||
From e10968202016575ed4431f67a09ab7a3aef8dfcc Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Wed, 18 Sep 2024 00:40:25 +0200
|
||||
Subject: [PATCH 45/53] fix(pes_events_scanner): ensure output contains no
|
||||
duplicates
|
||||
|
||||
RpmTransactionTasks messages have higher priority than instructions
|
||||
based on PES data. Previously, if multiple such messages existed
|
||||
with duplicate instructions, this could lead to the crash of
|
||||
the actor - especially in case when an existing package has been
|
||||
asked to be removed several times. Ensure the occurance of each
|
||||
instruction is unique (list -> set).
|
||||
|
||||
jira: RHEL-50076
|
||||
---
|
||||
.../libraries/pes_events_scanner.py | 17 ++++++++++-------
|
||||
1 file changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py b/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py
|
||||
index f5cb2613..a798017f 100644
|
||||
--- a/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py
|
||||
+++ b/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py
|
||||
@@ -78,19 +78,22 @@ def get_installed_pkgs():
|
||||
|
||||
def get_transaction_configuration():
|
||||
"""
|
||||
- Get pkgs to install, keep and remove from the user configuration files in /etc/leapp/transaction/.
|
||||
+ Get pkgs to install, keep and remove from RpmTransactionTasks messages.
|
||||
|
||||
- These configuration files have higher priority than PES data.
|
||||
- :return: RpmTransactionTasks model instance
|
||||
+ Note these messages reflects inputs from various actors and configuration
|
||||
+ files in /etc/leapp/transaction/. As these are explicit instruction, they
|
||||
+ have higher priority than instructions from PES data.
|
||||
+
|
||||
+ :return: TransactionConfiguration
|
||||
"""
|
||||
- transaction_configuration = TransactionConfiguration(to_install=[], to_remove=[], to_keep=[])
|
||||
+ transaction_configuration = TransactionConfiguration(to_install=set(), to_remove=set(), to_keep=set())
|
||||
|
||||
_Pkg = partial(Package, repository=None, modulestream=None)
|
||||
|
||||
for tasks in api.consume(RpmTransactionTasks):
|
||||
- transaction_configuration.to_install.extend(_Pkg(name=pkg_name) for pkg_name in tasks.to_install)
|
||||
- transaction_configuration.to_remove.extend(_Pkg(name=pkg_name) for pkg_name in tasks.to_remove)
|
||||
- transaction_configuration.to_keep.extend(_Pkg(name=pkg_name) for pkg_name in tasks.to_keep)
|
||||
+ transaction_configuration.to_install.update(_Pkg(name=pkg_name) for pkg_name in tasks.to_install)
|
||||
+ transaction_configuration.to_remove.update(_Pkg(name=pkg_name) for pkg_name in tasks.to_remove)
|
||||
+ transaction_configuration.to_keep.update(_Pkg(name=pkg_name) for pkg_name in tasks.to_keep)
|
||||
return transaction_configuration
|
||||
|
||||
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -0,0 +1,247 @@
|
||||
From 49627082e79744d9b7831356f87c71e2e67add03 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Hecko <mhecko@redhat.com>
|
||||
Date: Thu, 31 Oct 2024 18:13:49 +0100
|
||||
Subject: [PATCH 46/53] fix(pes_event_scanner): respect user's trasaction
|
||||
configuration
|
||||
|
||||
Previously, pes_events_scanner used transaction configuration to
|
||||
only modify the way it initializes event application. As a consequence,
|
||||
if a user specified to_remove=['pkg'], then the information would
|
||||
not make it to pes_events_scanner's output. Similar situation would
|
||||
arise with to_install/to_keep. This patch adds a post-processing to
|
||||
explicitly add transaction configuration to the result of applying PES
|
||||
events.
|
||||
---
|
||||
.../libraries/pes_events_scanner.py | 64 +++++++++++++--
|
||||
.../tests/test_pes_event_scanner.py | 78 +++++++++++++++----
|
||||
2 files changed, 120 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py b/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py
|
||||
index a798017f..50336150 100644
|
||||
--- a/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py
|
||||
+++ b/repos/system_upgrade/common/actors/peseventsscanner/libraries/pes_events_scanner.py
|
||||
@@ -470,9 +470,8 @@ def replace_pesids_with_repoids_in_packages(packages, source_pkgs_repoids):
|
||||
return packages_with_repoid.union(packages_without_pesid)
|
||||
|
||||
|
||||
-def apply_transaction_configuration(source_pkgs):
|
||||
+def apply_transaction_configuration(source_pkgs, transaction_configuration):
|
||||
source_pkgs_with_conf_applied = set(source_pkgs)
|
||||
- transaction_configuration = get_transaction_configuration()
|
||||
|
||||
source_pkgs_with_conf_applied = source_pkgs.union(transaction_configuration.to_install)
|
||||
|
||||
@@ -504,6 +503,50 @@ def remove_leapp_related_events(events):
|
||||
return res
|
||||
|
||||
|
||||
+def include_instructions_from_transaction_configuration(rpm_tasks, transaction_configuration, installed_pkgs):
|
||||
+ """
|
||||
+ Extend current rpm_tasks applying data from transaction_configuration
|
||||
+
|
||||
+ :param PESRpmTransactionTasks rpm_tasks: Currently calculated rpm tasks based on PES data.
|
||||
+ :param TransactionConfiguration transaction_configuration: Tasked configured by user manually.
|
||||
+ :param set(str) installed_pkgs: Set of distribution signed packages installed on the system.
|
||||
+ :returns: updated tasks respecting configuration changes made by user
|
||||
+ :rtype: PESRpmTransactionTasks
|
||||
+ """
|
||||
+ to_install_from_rpm_tasks = set() if not rpm_tasks else set(rpm_tasks.to_install)
|
||||
+ to_remove_from_rpm_tasks = set() if not rpm_tasks else set(rpm_tasks.to_remove)
|
||||
+ to_keep_from_rpm_tasks = set() if not rpm_tasks else set(rpm_tasks.to_keep)
|
||||
+
|
||||
+ # We don't want to try removing packages that are not installed - include only installed ones
|
||||
+ installed_pkgs_requested_to_be_removed = transaction_configuration.to_remove.intersection(installed_pkgs)
|
||||
+ pkgs_names_to_extend_to_remove_with = set(pkg.name for pkg in installed_pkgs_requested_to_be_removed)
|
||||
+
|
||||
+ # Add packages to 'to_install' only if they are not already requested to be installed by rpm_tasks
|
||||
+ pkgs_names_requested_to_be_installed = set(pkg.name for pkg in transaction_configuration.to_install)
|
||||
+ to_install_pkgs_names_missing_from_tasks = pkgs_names_requested_to_be_installed - to_install_from_rpm_tasks
|
||||
+
|
||||
+ pkg_names_user_wants_to_keep = {pkg.name for pkg in transaction_configuration.to_keep}
|
||||
+
|
||||
+ # Remove packages that were requested by rpm_tasks or by user, but exclude those that should be kept
|
||||
+ new_to_remove_set = (to_remove_from_rpm_tasks | pkgs_names_to_extend_to_remove_with) - pkg_names_user_wants_to_keep
|
||||
+ new_to_remove_list = sorted(new_to_remove_set)
|
||||
+
|
||||
+ new_to_install_list = sorted(to_install_from_rpm_tasks | to_install_pkgs_names_missing_from_tasks)
|
||||
+ new_to_keep_list = sorted(to_keep_from_rpm_tasks | pkg_names_user_wants_to_keep)
|
||||
+
|
||||
+ if not any((new_to_remove_list, new_to_keep_list, new_to_install_list)): # Are all empty?
|
||||
+ return rpm_tasks # We do not modify the original tasks
|
||||
+
|
||||
+ modules_to_enable = rpm_tasks.modules_to_enable if rpm_tasks else []
|
||||
+ modules_to_reset = rpm_tasks.modules_to_reset if rpm_tasks else []
|
||||
+
|
||||
+ return PESRpmTransactionTasks(to_install=new_to_install_list,
|
||||
+ to_remove=new_to_remove_list,
|
||||
+ to_keep=new_to_keep_list,
|
||||
+ modules_to_enable=modules_to_enable,
|
||||
+ modules_to_reset=modules_to_reset)
|
||||
+
|
||||
+
|
||||
def process():
|
||||
# Retrieve data - installed_pkgs, transaction configuration, pes events
|
||||
events = get_pes_events('/etc/leapp/files', 'pes-events.json')
|
||||
@@ -511,24 +554,27 @@ def process():
|
||||
return
|
||||
|
||||
releases = get_relevant_releases(events)
|
||||
- source_pkgs = get_installed_pkgs()
|
||||
- source_pkgs = apply_transaction_configuration(source_pkgs)
|
||||
+ installed_pkgs = get_installed_pkgs()
|
||||
+ transaction_configuration = get_transaction_configuration()
|
||||
+ pkgs_to_begin_computation_with = apply_transaction_configuration(installed_pkgs, transaction_configuration)
|
||||
|
||||
# Keep track of what repoids have the source packages to be able to determine what are the PESIDs of the computed
|
||||
# packages of the target system, so we can distinguish what needs to be repomapped
|
||||
- repoids_of_source_pkgs = {pkg.repository for pkg in source_pkgs}
|
||||
+ repoids_of_source_pkgs = {pkg.repository for pkg in pkgs_to_begin_computation_with}
|
||||
|
||||
events = remove_leapp_related_events(events)
|
||||
events = remove_undesired_events(events, releases)
|
||||
|
||||
# Apply events - compute what packages should the target system have
|
||||
- target_pkgs, pkgs_to_demodularize = compute_packages_on_target_system(source_pkgs, events, releases)
|
||||
+ target_pkgs, pkgs_to_demodularize = compute_packages_on_target_system(pkgs_to_begin_computation_with,
|
||||
+ events, releases)
|
||||
|
||||
# Packages coming out of the events have PESID as their repository, however, we need real repoid
|
||||
target_pkgs = replace_pesids_with_repoids_in_packages(target_pkgs, repoids_of_source_pkgs)
|
||||
|
||||
# Apply the desired repository blacklisting
|
||||
- blacklisted_repoids, target_pkgs = remove_new_packages_from_blacklisted_repos(source_pkgs, target_pkgs)
|
||||
+ blacklisted_repoids, target_pkgs = remove_new_packages_from_blacklisted_repos(pkgs_to_begin_computation_with,
|
||||
+ target_pkgs)
|
||||
|
||||
# Look at the target packages and determine what repositories to enable
|
||||
target_repoids = sorted(set(p.repository for p in target_pkgs) - blacklisted_repoids - repoids_of_source_pkgs)
|
||||
@@ -536,6 +582,8 @@ def process():
|
||||
api.produce(repos_to_enable)
|
||||
|
||||
# Compare the packages on source system and the computed packages on target system and determine what to install
|
||||
- rpm_tasks = compute_rpm_tasks_from_pkg_set_diff(source_pkgs, target_pkgs, pkgs_to_demodularize)
|
||||
+ rpm_tasks = compute_rpm_tasks_from_pkg_set_diff(pkgs_to_begin_computation_with, target_pkgs, pkgs_to_demodularize)
|
||||
+ rpm_tasks = include_instructions_from_transaction_configuration(rpm_tasks, transaction_configuration,
|
||||
+ installed_pkgs)
|
||||
if rpm_tasks:
|
||||
api.produce(rpm_tasks)
|
||||
diff --git a/repos/system_upgrade/common/actors/peseventsscanner/tests/test_pes_event_scanner.py b/repos/system_upgrade/common/actors/peseventsscanner/tests/test_pes_event_scanner.py
|
||||
index 80ece770..9a499baa 100644
|
||||
--- a/repos/system_upgrade/common/actors/peseventsscanner/tests/test_pes_event_scanner.py
|
||||
+++ b/repos/system_upgrade/common/actors/peseventsscanner/tests/test_pes_event_scanner.py
|
||||
@@ -9,9 +9,7 @@ from leapp.libraries.actor.pes_events_scanner import (
|
||||
api,
|
||||
compute_packages_on_target_system,
|
||||
compute_rpm_tasks_from_pkg_set_diff,
|
||||
- get_installed_pkgs,
|
||||
Package,
|
||||
- process,
|
||||
reporting,
|
||||
TransactionConfiguration
|
||||
)
|
||||
@@ -27,8 +25,8 @@ from leapp.models import (
|
||||
RepositoriesSetupTasks,
|
||||
RepositoryData,
|
||||
RepositoryFile,
|
||||
- RHUIInfo,
|
||||
- RPM
|
||||
+ RPM,
|
||||
+ RpmTransactionTasks
|
||||
)
|
||||
|
||||
|
||||
@@ -286,17 +284,14 @@ def test_actor_performs(monkeypatch):
|
||||
def test_transaction_configuration_has_effect(monkeypatch):
|
||||
_Pkg = partial(Package, repository=None, modulestream=None)
|
||||
|
||||
- def mocked_transaction_conf():
|
||||
- return TransactionConfiguration(
|
||||
- to_install=[_Pkg('pkg-a'), _Pkg('pkg-b')],
|
||||
- to_remove=[_Pkg('pkg-c'), _Pkg('pkg-d')],
|
||||
- to_keep=[]
|
||||
- )
|
||||
-
|
||||
- monkeypatch.setattr(pes_events_scanner, 'get_transaction_configuration', mocked_transaction_conf)
|
||||
+ transaction_cfg = TransactionConfiguration(
|
||||
+ to_install=[_Pkg('pkg-a'), _Pkg('pkg-b')],
|
||||
+ to_remove=[_Pkg('pkg-c'), _Pkg('pkg-d')],
|
||||
+ to_keep=[]
|
||||
+ )
|
||||
|
||||
packages = {_Pkg('pkg-a'), _Pkg('pkg-c')}
|
||||
- _result = pes_events_scanner.apply_transaction_configuration(packages)
|
||||
+ _result = pes_events_scanner.apply_transaction_configuration(packages, transaction_cfg)
|
||||
result = {(p.name, p.repository, p.modulestream) for p in _result}
|
||||
expected = {('pkg-a', None, None), ('pkg-b', None, None)}
|
||||
|
||||
@@ -340,7 +335,7 @@ def test_blacklisted_repoid_is_not_produced(monkeypatch):
|
||||
|
||||
monkeypatch.setattr(pes_events_scanner, 'get_installed_pkgs', lambda: installed_pkgs)
|
||||
monkeypatch.setattr(pes_events_scanner, 'get_pes_events', lambda folder, filename: events)
|
||||
- monkeypatch.setattr(pes_events_scanner, 'apply_transaction_configuration', lambda pkgs: pkgs)
|
||||
+ monkeypatch.setattr(pes_events_scanner, 'apply_transaction_configuration', lambda pkgs, transaction_cfg: pkgs)
|
||||
monkeypatch.setattr(pes_events_scanner, 'get_blacklisted_repoids', lambda: {'blacklisted-rhel8'})
|
||||
monkeypatch.setattr(pes_events_scanner, 'replace_pesids_with_repoids_in_packages',
|
||||
lambda pkgs, src_pkgs_repoids: pkgs)
|
||||
@@ -475,3 +470,58 @@ def test_remove_leapp_related_events(monkeypatch):
|
||||
|
||||
out_events = pes_events_scanner.remove_leapp_related_events(in_events)
|
||||
assert out_events == expected_out_events
|
||||
+
|
||||
+
|
||||
+def test_transaction_configuration_is_applied(monkeypatch):
|
||||
+ installed_pkgs = {
|
||||
+ Package(name='moved-in', repository='rhel7-base', modulestream=None),
|
||||
+ Package(name='split-in', repository='rhel7-base', modulestream=None),
|
||||
+ Package(name='pkg-not-in-events', repository='rhel7-base', modulestream=None),
|
||||
+ }
|
||||
+ monkeypatch.setattr(pes_events_scanner, 'get_installed_pkgs', lambda *args, **kwags: installed_pkgs)
|
||||
+
|
||||
+ Pkg = partial(Package, modulestream=None)
|
||||
+ events = [
|
||||
+ Event(1, Action.SPLIT,
|
||||
+ {Pkg('split-in', 'rhel7-base')},
|
||||
+ {Pkg('split-out0', 'rhel8-BaseOS'), Pkg('split-out1', 'rhel8-BaseOS')},
|
||||
+ (7, 9), (8, 0), []),
|
||||
+ Event(3, Action.MOVED,
|
||||
+ {Pkg('moved-in', 'rhel7-base')}, {Pkg('moved-out', 'rhel8-BaseOS')},
|
||||
+ (7, 9), (8, 0), []),
|
||||
+ ]
|
||||
+ monkeypatch.setattr(pes_events_scanner, 'get_pes_events', lambda *args, **kwargs: events)
|
||||
+ monkeypatch.setattr(pes_events_scanner, 'remove_leapp_related_events', lambda events: events)
|
||||
+ monkeypatch.setattr(pes_events_scanner, 'remove_undesired_events', lambda events, releases: events)
|
||||
+ monkeypatch.setattr(pes_events_scanner, '_get_enabled_modules', lambda *args: [])
|
||||
+ monkeypatch.setattr(pes_events_scanner, 'replace_pesids_with_repoids_in_packages',
|
||||
+ lambda target_pkgs, repoids_of_source_pkgs: target_pkgs)
|
||||
+ monkeypatch.setattr(pes_events_scanner,
|
||||
+ 'remove_new_packages_from_blacklisted_repos',
|
||||
+ lambda source_pkgs, target_pkgs: (set(), target_pkgs))
|
||||
+
|
||||
+ msgs = [
|
||||
+ RpmTransactionTasks(to_remove=['pkg-not-in-events']),
|
||||
+ RpmTransactionTasks(to_remove=['pkg-not-in-events', 'pkg-not-in-events']),
|
||||
+ RpmTransactionTasks(to_install=['pkg-to-install']),
|
||||
+ RpmTransactionTasks(to_keep=['keep-me']),
|
||||
+ ]
|
||||
+ mocked_actor = CurrentActorMocked(arch='x86_64', src_ver='7.9', dst_ver='8.8', msgs=msgs)
|
||||
+ monkeypatch.setattr(api, 'current_actor', mocked_actor)
|
||||
+
|
||||
+ monkeypatch.setattr(api, 'produce', produce_mocked())
|
||||
+
|
||||
+ pes_events_scanner.process()
|
||||
+
|
||||
+ assert api.produce.called == 2
|
||||
+
|
||||
+ produced_rpm_transaction_tasks = [
|
||||
+ msg for msg in api.produce.model_instances if isinstance(msg, PESRpmTransactionTasks)
|
||||
+ ]
|
||||
+
|
||||
+ assert len(produced_rpm_transaction_tasks) == 1
|
||||
+ rpm_transaction_tasks = produced_rpm_transaction_tasks[0]
|
||||
+ # It is important to see 'pkg-not-in-events' in the list - if the user says remove pkg A, we really remove it
|
||||
+ assert sorted(rpm_transaction_tasks.to_remove) == ['moved-in', 'pkg-not-in-events', 'split-in']
|
||||
+ assert sorted(rpm_transaction_tasks.to_install) == ['moved-out', 'pkg-to-install', 'split-out0', 'split-out1']
|
||||
+ assert sorted(rpm_transaction_tasks.to_keep) == ['keep-me']
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
From 75b8b96f8b7b6705fe52135dab32cc6c8d886db3 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Fri, 10 Jan 2025 15:16:05 +0100
|
||||
Subject: [PATCH 47/53] IPU 9 -> 10: obsolete GPG key with SHA1 signature
|
||||
|
||||
When upgrading to RHEL 10, we have analogical problem as we had for
|
||||
IPU 8 -> 9 due to GPG keys with SHA1 signatures. The SHA1 algorithm
|
||||
is considered unsecure since RHEL 9 and all RPMs are required to be
|
||||
signed by keys with SHA2 signatures. The RHEL 9 GPG (auxiliary) key
|
||||
is unfortunately still signed with SHA1 and RHEL 10 tooling refuse
|
||||
to use it for any operations.
|
||||
|
||||
To resolve this apply the same solution as we did in the past:
|
||||
* obsolete original key
|
||||
* install the target RHEL 10 GPG keys during the upgrade
|
||||
|
||||
jira: RHEL-71517
|
||||
---
|
||||
.../system_upgrade/common/files/distro/rhel/gpg-signatures.json | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/files/distro/rhel/gpg-signatures.json b/repos/system_upgrade/common/files/distro/rhel/gpg-signatures.json
|
||||
index 8a5471a8..3cc67f82 100644
|
||||
--- a/repos/system_upgrade/common/files/distro/rhel/gpg-signatures.json
|
||||
+++ b/repos/system_upgrade/common/files/distro/rhel/gpg-signatures.json
|
||||
@@ -14,6 +14,6 @@
|
||||
"gpg-pubkey-db42a60e-37ea5438"
|
||||
],
|
||||
"9": ["gpg-pubkey-d4082792-5b32db75"],
|
||||
- "10": []
|
||||
+ "10": ["gpg-pubkey-fd431d51-4ae0493b"]
|
||||
}
|
||||
}
|
||||
--
|
||||
2.47.1
|
||||
|
||||
49
SOURCES/0048-Fix-storage-scanner-parsing-error.patch
Normal file
49
SOURCES/0048-Fix-storage-scanner-parsing-error.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From d183370047ab5ef139825dfce7a1b4d6f987092f Mon Sep 17 00:00:00 2001
|
||||
From: tomasfratrik <tomasfratrik8@gmail.com>
|
||||
Date: Fri, 28 Jun 2024 14:27:41 +0200
|
||||
Subject: [PATCH 48/53] Fix storage scanner parsing error
|
||||
|
||||
Fix storagescanner actor crash when parsing the output of,
|
||||
e.g., 'pvs -a', which used ':' as a separator and caused errors.
|
||||
The issue occurred because separator ':' is used to split the outputs of executed commands.
|
||||
This commit resolves the problem by changing the separator to '|'.
|
||||
|
||||
Jira: RHEL-34570
|
||||
---
|
||||
.../actors/storagescanner/libraries/storagescanner.py | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/storagescanner/libraries/storagescanner.py b/repos/system_upgrade/common/actors/storagescanner/libraries/storagescanner.py
|
||||
index cad6bd32..cae38731 100644
|
||||
--- a/repos/system_upgrade/common/actors/storagescanner/libraries/storagescanner.py
|
||||
+++ b/repos/system_upgrade/common/actors/storagescanner/libraries/storagescanner.py
|
||||
@@ -206,7 +206,7 @@ def _get_lsblk_info():
|
||||
@aslist
|
||||
def _get_pvs_info():
|
||||
""" Collect storage info from pvs command """
|
||||
- for entry in _get_cmd_output(['pvs', '--noheadings', '--separator', r':'], ':', 6):
|
||||
+ for entry in _get_cmd_output(['pvs', '--noheadings', '--separator', r'|'], '|', 6):
|
||||
pv, vg, fmt, attr, psize, pfree = entry
|
||||
yield PvsEntry(
|
||||
pv=pv,
|
||||
@@ -220,7 +220,7 @@ def _get_pvs_info():
|
||||
@aslist
|
||||
def _get_vgs_info():
|
||||
""" Collect storage info from vgs command """
|
||||
- for entry in _get_cmd_output(['vgs', '--noheadings', '--separator', r':'], ':', 7):
|
||||
+ for entry in _get_cmd_output(['vgs', '--noheadings', '--separator', r'|'], '|', 7):
|
||||
vg, pv, lv, sn, attr, vsize, vfree = entry
|
||||
yield VgsEntry(
|
||||
vg=vg,
|
||||
@@ -235,7 +235,7 @@ def _get_vgs_info():
|
||||
@aslist
|
||||
def _get_lvdisplay_info():
|
||||
""" Collect storage info from lvdisplay command """
|
||||
- for entry in _get_cmd_output(['lvdisplay', '-C', '--noheadings', '--separator', r':'], ':', 12):
|
||||
+ for entry in _get_cmd_output(['lvdisplay', '-C', '--noheadings', '--separator', r'|'], '|', 12):
|
||||
lv, vg, attr, lsize, pool, origin, data, meta, move, log, cpy_sync, convert = entry
|
||||
yield LvdisplayEntry(
|
||||
lv=lv,
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
From a46f20841ef32b9de23553591dd7ae8ff5150eff Mon Sep 17 00:00:00 2001
|
||||
From: "Bryn M. Reeves" <bmr@redhat.com>
|
||||
Date: Tue, 14 Jan 2025 19:57:37 +0000
|
||||
Subject: [PATCH 49/53] Use --sysinit when calling vgchange from mount_usr.sh
|
||||
|
||||
The mount_usr.sh script runs 'lvm vgchange': if there are logical
|
||||
volumes present that require monitoring (snapshots, thin pools, RAID,
|
||||
etc.) the command will attempt to launch dmeventd.
|
||||
|
||||
Since dmeventd is not installed in the dracut initramfs this produces a
|
||||
warning and causes the lvm command to exit with non-zero exit status
|
||||
even though the volume group has been activated and LV block devices are
|
||||
available.
|
||||
|
||||
This in turn triggers the retry logic in mount_usr.sh: once the retries
|
||||
are exhausted the script carries on and successfully initiates the
|
||||
upgrade process.
|
||||
|
||||
The --sysinit switch is used by the LVM dracut modules for this reason.
|
||||
From vgchange(8):
|
||||
|
||||
--sysinit
|
||||
Indicates that vgchange/lvchange is being invoked from early
|
||||
system initialisation scripts (e.g. rc.sysinit or an initrd),
|
||||
before writable filesystems are available. As such, some
|
||||
functionality needs to be disabled and this option acts as a
|
||||
shortcut which selects an appropriate set of options. Currently,
|
||||
this is equivalent to using --ignorelockingfailure,
|
||||
--ignoremonitoring, --poll n, and setting env var
|
||||
LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES. vgchange/lvchange skip
|
||||
autoactivation, and defer to pvscan autoactivation.
|
||||
|
||||
Testing with this change I no longer see the long delay booting the
|
||||
upgrade initramfs when snapshot LVs are present.
|
||||
---
|
||||
.../files/dracut/85sys-upgrade-redhat/mount_usr.sh | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/mount_usr.sh b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/mount_usr.sh
|
||||
index 84f4857d..9366ac13 100755
|
||||
--- a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/mount_usr.sh
|
||||
+++ b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/mount_usr.sh
|
||||
@@ -107,7 +107,7 @@ try_to_mount_usr() {
|
||||
|
||||
# In case we have the LVM command available try make it activate all partitions
|
||||
if command -v lvm 2>/dev/null 1>/dev/null; then
|
||||
- lvm vgchange -a y || {
|
||||
+ lvm vgchange --sysinit -a y || {
|
||||
warn "Detected problem when tried to activate LVM VG."
|
||||
if [ "$_last_attempt" != "true" ]; then
|
||||
# this is not last execution, retry
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
From 246405173d8ff633e180f0c5f3d4bd8117ea852d Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Fri, 10 Jan 2025 22:46:02 +0100
|
||||
Subject: [PATCH 50/53] redhatsignedrpmcheck: Add remediation hint and URL
|
||||
|
||||
Users do not have an idea what they should do about the third party
|
||||
packages - and quite often they do not understand the report itself.
|
||||
Adding the remediation hint with a link to related KB solution to
|
||||
help them to understand what they can do about this.
|
||||
|
||||
Note the actor needs significant changes to cover also other non-RHEL
|
||||
distributions. I decided to keep the change simple and resolve that
|
||||
in a follow up when we enable upgrades on other distributions as well.
|
||||
|
||||
jira: RHEL-44596
|
||||
---
|
||||
.../libraries/redhatsignedrpmcheck.py | 23 ++++++++++++++++---
|
||||
1 file changed, 20 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/common/actors/redhatsignedrpmcheck/libraries/redhatsignedrpmcheck.py b/repos/system_upgrade/common/actors/redhatsignedrpmcheck/libraries/redhatsignedrpmcheck.py
|
||||
index efdb8f40..14ade534 100644
|
||||
--- a/repos/system_upgrade/common/actors/redhatsignedrpmcheck/libraries/redhatsignedrpmcheck.py
|
||||
+++ b/repos/system_upgrade/common/actors/redhatsignedrpmcheck/libraries/redhatsignedrpmcheck.py
|
||||
@@ -3,8 +3,6 @@ from leapp.libraries.stdlib import api
|
||||
from leapp.libraries.stdlib.config import is_verbose
|
||||
from leapp.models import InstalledUnsignedRPM
|
||||
|
||||
-COMMON_REPORT_TAGS = [reporting.Groups.SANITY]
|
||||
-
|
||||
|
||||
def generate_report(packages):
|
||||
""" Generate a report if there are unsigned packages installed on the system """
|
||||
@@ -16,11 +14,30 @@ def generate_report(packages):
|
||||
' and may be removed during the upgrade process in case Red Hat-signed'
|
||||
' packages to be removed during the upgrade depend on them:\n{}'
|
||||
.format(unsigned_packages_new_line))
|
||||
+ hint = (
|
||||
+ 'The most simple solution that does not require additional knowledge'
|
||||
+ ' about the upgrade process'
|
||||
+ ' is the uninstallation of such packages before the upgrade and'
|
||||
+ ' installing these (or their newer versions compatible with the target'
|
||||
+ ' system) back after the upgrade. Also you can just try to upgrade the'
|
||||
+ ' system on a testing machine (or after the full system backup) to see'
|
||||
+ ' the result.\n'
|
||||
+ 'However, it is common use case to migrate or upgrade installed third'
|
||||
+ ' party packages together with the system during the in-place upgrade'
|
||||
+ ' process. To examine how to customize the process to deal with such'
|
||||
+ ' packages, follow the documentation in the attached link'
|
||||
+ ' for more details.'
|
||||
+ )
|
||||
reporting.create_report([
|
||||
reporting.Title(title),
|
||||
reporting.Summary(summary),
|
||||
reporting.Severity(reporting.Severity.HIGH),
|
||||
- reporting.Groups(COMMON_REPORT_TAGS)
|
||||
+ reporting.Groups([reporting.Groups.SANITY]),
|
||||
+ reporting.Remediation(hint=hint),
|
||||
+ reporting.ExternalLink(
|
||||
+ url='https://red.ht/customize-rhel-upgrade-actors',
|
||||
+ title='Handling the migration of your custom and third-party applications'
|
||||
+ )
|
||||
])
|
||||
|
||||
if is_verbose():
|
||||
--
|
||||
2.47.1
|
||||
|
||||
28
SOURCES/0051-Update-postgresqlcheck.py.patch
Normal file
28
SOURCES/0051-Update-postgresqlcheck.py.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From fb4131a6c05e26060ab8b49a39a64047d9f2b691 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Filip=20Janu=C5=A1?= <fjanus@redhat.com>
|
||||
Date: Thu, 21 Nov 2024 11:30:56 +0100
|
||||
Subject: [PATCH 51/53] Update postgresqlcheck.py
|
||||
|
||||
Improve the report to clarify the upgrade path for already upgraded PostgreSQL
|
||||
---
|
||||
.../actors/postgresqlcheck/libraries/postgresqlcheck.py | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/postgresqlcheck/libraries/postgresqlcheck.py b/repos/system_upgrade/el8toel9/actors/postgresqlcheck/libraries/postgresqlcheck.py
|
||||
index 42519aaf..68997ef4 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/postgresqlcheck/libraries/postgresqlcheck.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/postgresqlcheck/libraries/postgresqlcheck.py
|
||||
@@ -7,8 +7,9 @@ from leapp.models import DistributionSignedRPM
|
||||
report_server_inst_summary = (
|
||||
'PostgreSQL server component will be upgraded. Since RHEL-9 includes'
|
||||
' PostgreSQL server 13 by default, which is incompatible with 9.6, 10 and 12'
|
||||
- ' included in RHEL-8, it is necessary to proceed with additional steps'
|
||||
+ ' included in RHEL-8, in those cases, it is necessary to proceed with additional steps'
|
||||
' for the complete upgrade of the PostgreSQL data.'
|
||||
+ 'If the database has already been upgraded, then no further actions are required.'
|
||||
)
|
||||
|
||||
report_server_inst_hint = (
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
From 724e0527f394f06f1bcbef42d6b3384d29b672f3 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Filip=20Janu=C5=A1?= <fjanus@redhat.com>
|
||||
Date: Thu, 21 Nov 2024 11:39:08 +0100
|
||||
Subject: [PATCH 52/53] Update
|
||||
repos/system_upgrade/el8toel9/actors/postgresqlcheck/libraries/postgresqlcheck.py
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Co-authored-by: Petr Stodůlka <xstodu05@gmail.com>
|
||||
---
|
||||
.../actors/postgresqlcheck/libraries/postgresqlcheck.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el8toel9/actors/postgresqlcheck/libraries/postgresqlcheck.py b/repos/system_upgrade/el8toel9/actors/postgresqlcheck/libraries/postgresqlcheck.py
|
||||
index 68997ef4..eefe583b 100644
|
||||
--- a/repos/system_upgrade/el8toel9/actors/postgresqlcheck/libraries/postgresqlcheck.py
|
||||
+++ b/repos/system_upgrade/el8toel9/actors/postgresqlcheck/libraries/postgresqlcheck.py
|
||||
@@ -9,7 +9,7 @@ report_server_inst_summary = (
|
||||
' PostgreSQL server 13 by default, which is incompatible with 9.6, 10 and 12'
|
||||
' included in RHEL-8, in those cases, it is necessary to proceed with additional steps'
|
||||
' for the complete upgrade of the PostgreSQL data.'
|
||||
- 'If the database has already been upgraded, then no further actions are required.'
|
||||
+ 'If the database has already been upgraded, meaning the system is already using PostgreSQL 13, then no further actions are required.'
|
||||
)
|
||||
|
||||
report_server_inst_hint = (
|
||||
--
|
||||
2.47.1
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
From bd6e7597c8a125479345c07f2901ecc505218b37 Mon Sep 17 00:00:00 2001
|
||||
From: Beniamino Galvani <bgalvani@redhat.com>
|
||||
Date: Wed, 15 Jan 2025 17:57:20 +0100
|
||||
Subject: [PATCH 53/53] Fix remediation message in the networkdeprecations
|
||||
actor
|
||||
|
||||
The message should suggest to remove "dhclient", not "internal".
|
||||
---
|
||||
.../el9toel10/actors/networkdeprecations/actor.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repos/system_upgrade/el9toel10/actors/networkdeprecations/actor.py b/repos/system_upgrade/el9toel10/actors/networkdeprecations/actor.py
|
||||
index 94868476..d1d58511 100644
|
||||
--- a/repos/system_upgrade/el9toel10/actors/networkdeprecations/actor.py
|
||||
+++ b/repos/system_upgrade/el9toel10/actors/networkdeprecations/actor.py
|
||||
@@ -25,7 +25,7 @@ class CheckNetworkDeprecations9to10(Actor):
|
||||
summary = ('NetworkManager is configured to use the "dhclient" DHCP module.'
|
||||
' In Red Hat Enterprise Linux 10, this setting will be ignored'
|
||||
' along with any dhcp-client specific configuration.')
|
||||
- remediation = ('Remove "dhcp=internal" line from "[main]" section from all'
|
||||
+ remediation = ('Remove "dhcp=dhclient" line from "[main]" section from all'
|
||||
' configuration files in "/etc/NetworkManager". Review'
|
||||
' configuration in "/etc/dhcp", which will be ignored.')
|
||||
reporting.create_report([
|
||||
--
|
||||
2.47.1
|
||||
|
||||
5551
SOURCES/leapp-repository-0.21.0-elevate.patch
Normal file
5551
SOURCES/leapp-repository-0.21.0-elevate.patch
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user