diff --git a/convert2rhel/checks.py b/convert2rhel/checks.py
index a2605de141..0ea4d3762f 100644
--- a/convert2rhel/checks.py
+++ b/convert2rhel/checks.py
@@ -15,7 +15,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-
import itertools
import logging
import os
@@ -28,6 +27,7 @@
from convert2rhel import __version__ as convert2rhel_version
from convert2rhel import grub, pkgmanager, utils
from convert2rhel.pkghandler import (
+ _package_version_cmp,
call_yum_cmd,
compare_package_versions,
get_installed_pkg_objects,
@@ -47,6 +47,7 @@
BAD_KERNEL_RELEASE_SUBSTRINGS = ("uek", "rt", "linode")
LINK_KMODS_RH_POLICY = "https://access.redhat.com/third-party-software-support"
+LINK_PREVENT_KMODS_FROM_LOADING = "https://access.redhat.com/solutions/41278"
# The kernel version stays the same throughout a RHEL major version
COMPATIBLE_KERNELS_VERS = {
6: "2.6.32",
@@ -54,8 +55,46 @@
8: "4.18.0",
}
+# Python 2.6 compatibility.
+# This code is copied from Pthon-3.10's functools module,
+# licensed under the Python Software Foundation License, version 2
+try:
+ from functools import cmp_to_key
+except ImportError:
+
+ def cmp_to_key(mycmp):
+ """Convert a cmp= function into a key= function"""
+
+ class K(object):
+ __slots__ = ["obj"]
+
+ def __init__(self, obj):
+ self.obj = obj
+
+ def __lt__(self, other):
+ return mycmp(self.obj, other.obj) < 0
+
+ def __gt__(self, other):
+ return mycmp(self.obj, other.obj) > 0
+
+ def __eq__(self, other):
+ return mycmp(self.obj, other.obj) == 0
+
+ def __le__(self, other):
+ return mycmp(self.obj, other.obj) <= 0
+
+ def __ge__(self, other):
+ return mycmp(self.obj, other.obj) >= 0
+
+ __hash__ = None
+
+ return K
-def perform_pre_checks():
+
+# End of PSF Licensed code
+
+
+def perform_system_checks():
"""Early checks after system facts should be added here."""
check_custom_repos_are_valid()
@@ -202,18 +241,20 @@ def check_tainted_kmods():
multipath 20480 0 - Live 0x0000000000000000
linear 20480 0 - Live 0x0000000000000000
system76_io 16384 0 - Live 0x0000000000000000 (OE) <<<<<< Tainted
- system76_acpi 16384 0 - Live 0x0000000000000000 (OE) <<<<< Tainted
+ system76_acpi 16384 0 - Live 0x0000000000000000 (OE) <<<<<< Tainted
"""
logger.task("Prepare: Checking if loaded kernel modules are not tainted")
unsigned_modules, _ = run_subprocess(["grep", "(", "/proc/modules"])
module_names = "\n ".join([mod.split(" ")[0] for mod in unsigned_modules.splitlines()])
if unsigned_modules:
logger.critical(
- "Tainted kernel module(s) detected. "
+ "Tainted kernel modules detected:\n {0}\n"
"Third-party components are not supported per our "
- "software support policy\n{0}\n\n"
- "Uninstall or disable the following module(s) and run convert2rhel "
- "again to continue with the conversion:\n {1}".format(LINK_KMODS_RH_POLICY, module_names)
+ "software support policy:\n {1}\n"
+ "Prevent the modules from loading by following {2}"
+ " and run convert2rhel again to continue with the conversion.".format(
+ module_names, LINK_KMODS_RH_POLICY, LINK_PREVENT_KMODS_FROM_LOADING
+ )
)
logger.info("No tainted kernel module is loaded.")
@@ -261,7 +302,9 @@ def check_custom_repos_are_valid():
return
output, ret_code = call_yum_cmd(
- command="makecache", args=["-v", "--setopt=*.skip_if_unavailable=False"], print_output=False
+ command="makecache",
+ args=["-v", "--setopt=*.skip_if_unavailable=False"],
+ print_output=False,
)
if ret_code != 0:
logger.critical(
@@ -274,11 +317,19 @@ def check_custom_repos_are_valid():
def ensure_compatibility_of_kmods():
- """Ensure if the host kernel modules are compatible with RHEL."""
+ """Ensure that the host kernel modules are compatible with RHEL.
+
+ :raises SystemExit: Interrupts the conversion because some kernel modules are not supported in RHEL.
+ """
host_kmods = get_loaded_kmods()
rhel_supported_kmods = get_rhel_supported_kmods()
unsupported_kmods = get_unsupported_kmods(host_kmods, rhel_supported_kmods)
- if unsupported_kmods:
+
+ # Validate the best case first. If we don't have any unsupported_kmods, this means
+ # that everything is compatible and good to go.
+ if not unsupported_kmods:
+ logger.debug("All loaded kernel modules are available in RHEL.")
+ else:
not_supported_kmods = "\n".join(
map(
lambda kmod: "/lib/modules/{kver}/{kmod}".format(kver=system_info.booted_kernel, kmod=kmod),
@@ -286,14 +337,13 @@ def ensure_compatibility_of_kmods():
)
)
logger.critical(
- (
- "The following kernel modules are not supported in RHEL:\n{kmods}\n"
- "Make sure you have updated the kernel to the latest available version and rebooted the system. "
- "Remove the unsupported modules and run convert2rhel again to continue with the conversion."
- ).format(kmods=not_supported_kmods, system=system_info.name)
+ "The following loaded kernel modules are not available in RHEL:\n{0}\n"
+ "First, make sure you have updated the kernel to the latest available version and rebooted the system.\n"
+ "If this message appears again after doing the above, prevent the modules from loading by following {1}"
+ " and run convert2rhel again to continue with the conversion.".format(
+ "\n".join(not_supported_kmods), LINK_PREVENT_KMODS_FROM_LOADING
+ )
)
- else:
- logger.info("Kernel modules are compatible.")
def validate_package_manager_transaction():
@@ -391,64 +441,46 @@ def get_most_recent_unique_kernel_pkgs(pkgs):
kernel pkg do not deprecate kernel modules we only select
the most recent ones.
- All RHEL kmods packages starts with kernel* or kmod*
-
- For example, we have the following packages list:
- kernel-core-0:4.18.0-240.10.1.el8_3.x86_64
- kernel-core-0:4.19.0-240.10.1.el8_3.x86_64
- kmod-debug-core-0:4.18.0-240.10.1.el8_3.x86_64
- kmod-debug-core-0:4.18.0-245.10.1.el8_3.x86_64
- ==> (output of this function will be)
- kernel-core-0:4.19.0-240.10.1.el8_3.x86_64
- kmod-debug-core-0:4.18.0-245.10.1.el8_3.x86_64
-
- _repos_version_key extract the version of a package
- into the tuple, i.e.
- kernel-core-0:4.18.0-240.10.1.el8_3.x86_64 ==>
- (4, 15, 0, 240, 10, 1)
-
-
- :type pkgs: Iterable[str]
- :type pkgs_groups:
- Iterator[
- Tuple[
- package_name_without_version,
- Iterator[package_name, ...],
- ...,
- ]
+ .. note::
+ All RHEL kmods packages starts with kernel* or kmod*
+
+ For example, consider the following list of packages::
+
+ list_of_pkgs = [
+ 'kernel-core-0:4.18.0-240.10.1.el8_3.x86_64',
+ 'kernel-core-0:4.19.0-240.10.1.el8_3.x86_64',
+ 'kmod-debug-core-0:4.18.0-240.10.1.el8_3.x86_64',
+ 'kmod-debug-core-0:4.18.0-245.10.1.el8_3.x86_64
]
- """
- pkgs_groups = itertools.groupby(sorted(pkgs), lambda pkg_name: pkg_name.split(":")[0])
- return tuple(
- max(distinct_kernel_pkgs[1], key=_repos_version_key)
- for distinct_kernel_pkgs in pkgs_groups
- if distinct_kernel_pkgs[0].startswith(("kernel", "kmod"))
- )
+ And when this function gets called with that same list of packages,
+ we have the following output::
+ result = get_most_recent_unique_kernel_pkgs(pkgs=list_of_pkgs)
+ print(result)
+ # (
+ # 'kernel-core-0:4.19.0-240.10.1.el8_3.x86_64',
+ # 'kmod-debug-core-0:4.18.0-245.10.1.el8_3.x86_64'
+ # )
-def _repos_version_key(pkg_name):
- try:
- rpm_version = KERNEL_REPO_RE.search(pkg_name).group("version")
- except AttributeError:
- logger.critical(
- "Unexpected package:\n%s\n is a source of kernel modules.",
- pkg_name,
- )
- else:
- return tuple(
- map(
- _convert_to_int_or_zero,
- KERNEL_REPO_VER_SPLIT_RE.split(rpm_version),
- )
- )
+ :param pkgs: A list of package names to be analyzed.
+ :type pkgs: list[str]
+ :return: A tuple of packages name sorted and normalized
+ :rtype: tuple[str]
+ """
+ pkgs_groups = itertools.groupby(sorted(pkgs), lambda pkg_name: pkg_name.split(":")[0])
+ list_of_sorted_pkgs = []
+ for distinct_kernel_pkgs in pkgs_groups:
+ if distinct_kernel_pkgs[0].startswith(("kernel", "kmod")):
+ list_of_sorted_pkgs.append(
+ max(
+ distinct_kernel_pkgs[1],
+ key=cmp_to_key(_package_version_cmp),
+ )
+ )
-def _convert_to_int_or_zero(s):
- try:
- return int(s)
- except ValueError:
- return 0
+ return tuple(list_of_sorted_pkgs)
def get_rhel_kmods_keys(rhel_kmods_str):
@@ -462,11 +494,19 @@ def get_rhel_kmods_keys(rhel_kmods_str):
def get_unsupported_kmods(host_kmods, rhel_supported_kmods):
- """Return a set of those installed kernel modules that are not available in RHEL repositories.
+ """Return a set of full paths to those installed kernel modules that are
+ not available in RHEL repositories.
- Ignore certain kmods mentioned in the system configs. These kernel modules moved to kernel core, meaning that the
- functionality is retained and we would be incorrectly saying that the modules are not supported in RHEL."""
- return host_kmods - rhel_supported_kmods - set(system_info.kmods_to_ignore)
+ Ignore certain kmods mentioned in the system configs. These kernel modules
+ moved to kernel core, meaning that the functionality is retained and we
+ would be incorrectly saying that the modules are not supported in RHEL.
+ """
+ unsupported_kmods_subpaths = host_kmods - rhel_supported_kmods - set(system_info.kmods_to_ignore)
+ unsupported_kmods_full_paths = [
+ "/lib/modules/{kver}/{kmod}".format(kver=system_info.booted_kernel, kmod=kmod)
+ for kmod in unsupported_kmods_subpaths
+ ]
+ return unsupported_kmods_full_paths
def check_rhel_compatible_kernel_is_used():
@@ -527,7 +567,10 @@ def _bad_kernel_version(kernel_release):
def _bad_kernel_package_signature(kernel_release):
"""Return True if the booted kernel is not signed by the original OS vendor, i.e. it's a custom kernel."""
vmlinuz_path = "/boot/vmlinuz-%s" % kernel_release
- kernel_pkg, return_code = run_subprocess(["rpm", "-qf", "--qf", "%{NAME}", vmlinuz_path], print_output=False)
+ kernel_pkg, return_code = run_subprocess(
+ ["rpm", "-qf", "--qf", "%{NAME}", vmlinuz_path],
+ print_output=False,
+ )
logger.debug("Booted kernel package name: {0}".format(kernel_pkg))
os_vendor = system_info.name.split()[0]
diff --git a/convert2rhel/main.py b/convert2rhel/main.py
index e6dad54574..70f467d773 100644
--- a/convert2rhel/main.py
+++ b/convert2rhel/main.py
@@ -97,7 +97,7 @@ def main():
pkghandler.clean_yum_metadata()
# check the system prior the conversion (possible inhibit)
- checks.perform_pre_checks()
+ checks.perform_system_checks()
# backup system release file before starting conversion process
loggerinst.task("Prepare: Backup System")
diff --git a/convert2rhel/pkghandler.py b/convert2rhel/pkghandler.py
index 683a55d5c3..596679c873 100644
--- a/convert2rhel/pkghandler.py
+++ b/convert2rhel/pkghandler.py
@@ -1111,3 +1111,54 @@ def clean_yum_metadata():
return
loggerinst.info("Cached yum metadata cleaned successfully.")
+
+
+def _package_version_cmp(pkg_1, pkg_2):
+ """Compare the version key in a given package name.
+
+ Consider the following variables that will be passed to this function::
+
+ pkg_1 = 'kernel-core-0:4.18.0-240.10.1.el8_3.x86_64'
+ pkg_2 = 'kernel-core-0:4.18.0-239.0.0.el8_3.x86_64'
+
+ The output of this will be a tuple containing the package version in a
+ tuple::
+
+ result = _package_version_cmp(pkg_1, pkg_2)
+ print("Result is: %s" % result)
+ # Result is: -1
+
+ The function will ignore the package name as it is not an important
+ information here and will only care about the version that is tied to it's
+ name.
+
+ :param pkg_1: The first package to extract the version
+ :type pkg_1: str
+ :param pkg_2: The second package to extract the version
+ :type pkg_2: str
+ :return: An integer resulting in the package comparision
+ :rtype: int
+ """
+
+ # TODO(r0x0d): This function still needs some enhancements code-wise, it
+ # workes perfectly, but the way we are handling the versions is not 100%
+ # complete yet. will be done in a future work. Right now, all the list of
+ # changes are listed in this comment:
+ # https://github.com/oamg/convert2rhel/pull/469#discussion_r873971400
+ pkg_ver_components = []
+ for pkg in pkg_1, pkg_2:
+ # Remove the package name and split the rest between epoch + version
+ # and release + arch
+ epoch_version, release_arch = pkg.rsplit("-", 2)[-2:]
+ # Separate the (optional) epoch from the version
+ epoch_version = epoch_version.split(":", 1)
+ if len(epoch_version) == 1:
+ epoch = "0"
+ version = epoch_version[0]
+ else:
+ epoch, version = epoch_version
+ # Discard the arch
+ release = release_arch.rsplit(".", 1)[0]
+ pkg_ver_components.append((epoch, version, release))
+
+ return rpm.labelCompare(pkg_ver_components[0], pkg_ver_components[1])
diff --git a/convert2rhel/systeminfo.py b/convert2rhel/systeminfo.py
index 8f2d95f500..f6892e445b 100644
--- a/convert2rhel/systeminfo.py
+++ b/convert2rhel/systeminfo.py
@@ -332,12 +332,18 @@ def is_rpm_installed(name):
_, return_code = run_subprocess(["rpm", "-q", name], print_cmd=False, print_output=False)
return return_code == 0
- # TODO write unit tests
def get_enabled_rhel_repos(self):
- """Return a tuple of repoids containing RHEL packages.
+ """Get a list of enabled repositories containing RHEL packages.
- These are either the repos enabled through RHSM or the custom
- repositories passed though CLI.
+ This function can return either the repositories enabled throught the RHSM tool during the conversion or, if
+ the user manually specified the repositories throught the CLI, it will return them based on the
+ `tool_opts.enablerepo` option.
+
+ .. note::
+ The repositories passed through the CLI have more priority than the ones get get from RHSM.
+
+ :return: A list of enabled repos to use during the conversion
+ :rtype: list[str]
"""
# TODO:
# if not self.submgr_enabled_repos:
diff --git a/convert2rhel/unit_tests/checks_test.py b/convert2rhel/unit_tests/checks_test.py
index 8a00a2e23f..3bb0c063cb 100644
--- a/convert2rhel/unit_tests/checks_test.py
+++ b/convert2rhel/unit_tests/checks_test.py
@@ -157,7 +157,7 @@ def test_perform_pre_checks(monkeypatch):
monkeypatch.setattr(checks, "is_loaded_kernel_latest", value=is_loaded_kernel_latest_mock)
monkeypatch.setattr(checks, "check_dbus_is_running", value=check_dbus_is_running_mock)
- checks.perform_pre_checks()
+ checks.perform_system_checks()
check_convert2rhel_latest_mock.assert_called_once()
check_thirdparty_kmods_mock.assert_called_once()
@@ -169,7 +169,7 @@ def test_perform_pre_checks(monkeypatch):
check_dbus_is_running_mock.assert_called_once()
-def test_pre_ponr_checks(monkeypatch):
+def test_perform_pre_ponr_checks(monkeypatch):
ensure_compatibility_of_kmods_mock = mock.Mock()
create_transaction_handler_mock = mock.Mock()
monkeypatch.setattr(
@@ -315,14 +315,14 @@ def test_c2r_up_to_date(caplog, monkeypatch, convert2rhel_latest_version_test):
(
HOST_MODULES_STUB_GOOD,
None,
- "Kernel modules are compatible",
+ "loaded kernel modules are available in RHEL",
None,
),
(
HOST_MODULES_STUB_BAD,
SystemExit,
None,
- "Kernel modules are compatible",
+ "loaded kernel modules are available in RHEL",
),
),
)
@@ -383,13 +383,13 @@ def test_validate_package_manager_transaction(monkeypatch, caplog):
# ff-memless specified to be ignored in the config, so no exception raised
(
"kernel/drivers/input/ff-memless.ko.xz",
- "Kernel modules are compatible",
- "The following kernel modules are not supported in RHEL",
+ "loaded kernel modules are available in RHEL",
+ "The following loaded kernel modules are not available in RHEL",
None,
),
(
"kernel/drivers/input/other.ko.xz",
- "The following kernel modules are not supported in RHEL",
+ "The following loaded kernel modules are not available in RHEL",
None,
SystemExit,
),
@@ -477,9 +477,18 @@ def test_get_loaded_kmods(monkeypatch):
0,
),
),
- (("modinfo", "-F", "filename", "a"), (MODINFO_STUB.split()[0] + "\n", 0)),
- (("modinfo", "-F", "filename", "b"), (MODINFO_STUB.split()[1] + "\n", 0)),
- (("modinfo", "-F", "filename", "c"), (MODINFO_STUB.split()[2] + "\n", 0)),
+ (
+ ("modinfo", "-F", "filename", "a"),
+ (MODINFO_STUB.split()[0] + "\n", 0),
+ ),
+ (
+ ("modinfo", "-F", "filename", "b"),
+ (MODINFO_STUB.split()[1] + "\n", 0),
+ ),
+ (
+ ("modinfo", "-F", "filename", "c"),
+ (MODINFO_STUB.split()[2] + "\n", 0),
+ ),
),
)
monkeypatch.setattr(
@@ -491,10 +500,10 @@ def test_get_loaded_kmods(monkeypatch):
@pytest.mark.parametrize(
- ("repoquery_f_stub", "repoquery_l_stub", "exception"),
+ ("repoquery_f_stub", "repoquery_l_stub"),
(
- (REPOQUERY_F_STUB_GOOD, REPOQUERY_L_STUB_GOOD, None),
- (REPOQUERY_F_STUB_BAD, REPOQUERY_L_STUB_GOOD, SystemExit),
+ (REPOQUERY_F_STUB_GOOD, REPOQUERY_L_STUB_GOOD),
+ (REPOQUERY_F_STUB_BAD, REPOQUERY_L_STUB_GOOD),
),
)
@centos8
@@ -503,7 +512,6 @@ def test_get_rhel_supported_kmods(
pretend_os,
repoquery_f_stub,
repoquery_l_stub,
- exception,
):
run_subprocess_mock = mock.Mock(
side_effect=run_subprocess_side_effect(
@@ -522,24 +530,21 @@ def test_get_rhel_supported_kmods(
"run_subprocess",
value=run_subprocess_mock,
)
- if exception:
- with pytest.raises(exception):
- checks.get_rhel_supported_kmods()
- else:
- res = checks.get_rhel_supported_kmods()
- assert res == set(
- (
- "kernel/lib/a.ko",
- "kernel/lib/a.ko.xz",
- "kernel/lib/b.ko.xz",
- "kernel/lib/c.ko.xz",
- "kernel/lib/c.ko",
- )
+
+ res = checks.get_rhel_supported_kmods()
+ assert res == set(
+ (
+ "kernel/lib/a.ko",
+ "kernel/lib/a.ko.xz",
+ "kernel/lib/b.ko.xz",
+ "kernel/lib/c.ko.xz",
+ "kernel/lib/c.ko",
)
+ )
@pytest.mark.parametrize(
- ("pkgs", "exp_res", "exception"),
+ ("pkgs", "exp_res"),
(
(
(
@@ -552,7 +557,6 @@ def test_get_rhel_supported_kmods(
"kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",
"kernel-debug-core-0:4.18.0-240.15.1.el8_3.x86_64",
),
- None,
),
(
(
@@ -560,7 +564,6 @@ def test_get_rhel_supported_kmods(
"kmod-core-0:4.18.0-240.15.1.el8_3.x86_64",
),
("kmod-core-0:4.18.0-240.15.1.el8_3.x86_64",),
- None,
),
(
(
@@ -568,7 +571,6 @@ def test_get_rhel_supported_kmods(
"kmod-core-0:4.18.0-240.15.1.el8_3.x86_64",
),
("kmod-core-0:4.18.0-240.15.1.el8_3.x86_64",),
- None,
),
(
(
@@ -576,7 +578,6 @@ def test_get_rhel_supported_kmods(
"kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",
),
("kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",),
- None,
),
(
(
@@ -584,7 +585,6 @@ def test_get_rhel_supported_kmods(
"kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",
),
("kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",),
- None,
),
(
(
@@ -592,27 +592,23 @@ def test_get_rhel_supported_kmods(
"kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",
),
("kernel-core-0:4.18.0-240.16.beta5.1.el8_3.x86_64",),
- None,
),
- (("kernel_bad_package:111111",), (), SystemExit),
+ (("kernel_bad_package:111111",), ("kernel_bad_package:111111",)),
(
(
"kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",
"kernel_bad_package:111111",
"kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",
),
- (),
- SystemExit,
+ (
+ "kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",
+ "kernel_bad_package:111111",
+ ),
),
),
)
-def test_get_most_recent_unique_kernel_pkgs(pkgs, exp_res, exception):
- if not exception:
- most_recent_pkgs = tuple(checks.get_most_recent_unique_kernel_pkgs(pkgs))
- assert exp_res == most_recent_pkgs
- else:
- with pytest.raises(exception):
- tuple(checks.get_most_recent_unique_kernel_pkgs(pkgs))
+def test_get_most_recent_unique_kernel_pkgs(pkgs, exp_res):
+ assert tuple(checks.get_most_recent_unique_kernel_pkgs(pkgs)) == exp_res
@pytest.mark.parametrize(
@@ -733,7 +729,11 @@ def test_check_efi_old_sys(self):
@unit_tests.mock(checks.system_info, "version", _gen_version(7, 9))
@unit_tests.mock(checks, "logger", GetLoggerMocked())
@unit_tests.mock(os.path, "exists", lambda x: not x == "/usr/sbin/efibootmgr")
- @unit_tests.mock(grub, "EFIBootInfo", EFIBootInfoMocked(exception=grub.BootloaderError("errmsg")))
+ @unit_tests.mock(
+ grub,
+ "EFIBootInfo",
+ EFIBootInfoMocked(exception=grub.BootloaderError("errmsg")),
+ )
def test_check_efi_efi_detected_without_efibootmgr(self):
self._check_efi_critical("Install efibootmgr to continue converting the UEFI-based system.")
@@ -743,7 +743,11 @@ def test_check_efi_efi_detected_without_efibootmgr(self):
@unit_tests.mock(checks.system_info, "version", _gen_version(7, 9))
@unit_tests.mock(checks, "logger", GetLoggerMocked())
@unit_tests.mock(os.path, "exists", lambda x: x == "/usr/sbin/efibootmgr")
- @unit_tests.mock(grub, "EFIBootInfo", EFIBootInfoMocked(exception=grub.BootloaderError("errmsg")))
+ @unit_tests.mock(
+ grub,
+ "EFIBootInfo",
+ EFIBootInfoMocked(exception=grub.BootloaderError("errmsg")),
+ )
def test_check_efi_efi_detected_non_intel(self):
self._check_efi_critical("Only x86_64 systems are supported for UEFI conversions.")
@@ -753,7 +757,11 @@ def test_check_efi_efi_detected_non_intel(self):
@unit_tests.mock(checks.system_info, "version", _gen_version(7, 9))
@unit_tests.mock(checks, "logger", GetLoggerMocked())
@unit_tests.mock(os.path, "exists", lambda x: x == "/usr/sbin/efibootmgr")
- @unit_tests.mock(grub, "EFIBootInfo", EFIBootInfoMocked(exception=grub.BootloaderError("errmsg")))
+ @unit_tests.mock(
+ grub,
+ "EFIBootInfo",
+ EFIBootInfoMocked(exception=grub.BootloaderError("errmsg")),
+ )
def test_check_efi_efi_detected_secure_boot(self):
self._check_efi_critical(
"The conversion with secure boot is currently not possible.\n"
@@ -767,7 +775,11 @@ def test_check_efi_efi_detected_secure_boot(self):
@unit_tests.mock(checks.system_info, "version", _gen_version(7, 9))
@unit_tests.mock(checks, "logger", GetLoggerMocked())
@unit_tests.mock(os.path, "exists", lambda x: x == "/usr/sbin/efibootmgr")
- @unit_tests.mock(grub, "EFIBootInfo", EFIBootInfoMocked(exception=grub.BootloaderError("errmsg")))
+ @unit_tests.mock(
+ grub,
+ "EFIBootInfo",
+ EFIBootInfoMocked(exception=grub.BootloaderError("errmsg")),
+ )
def test_check_efi_efi_detected_bootloader_error(self):
self._check_efi_critical("errmsg")
@@ -986,7 +998,11 @@ def __call__(self, command, *args, **kwargs):
return self.return_string, self.return_code
@unit_tests.mock(system_info, "version", namedtuple("Version", ["major", "minor"])(7, 0))
- @unit_tests.mock(checks, "call_yum_cmd", CallYumCmdMocked(ret_code=0, ret_string="Abcdef"))
+ @unit_tests.mock(
+ checks,
+ "call_yum_cmd",
+ CallYumCmdMocked(ret_code=0, ret_string="Abcdef"),
+ )
@unit_tests.mock(checks, "logger", GetLoggerMocked())
@unit_tests.mock(tool_opts, "no_rhsm", True)
def test_custom_repos_are_valid(self):
@@ -998,7 +1014,11 @@ def test_custom_repos_are_valid(self):
)
@unit_tests.mock(system_info, "version", namedtuple("Version", ["major", "minor"])(7, 0))
- @unit_tests.mock(checks, "call_yum_cmd", CallYumCmdMocked(ret_code=1, ret_string="Abcdef"))
+ @unit_tests.mock(
+ checks,
+ "call_yum_cmd",
+ CallYumCmdMocked(ret_code=1, ret_string="Abcdef"),
+ )
@unit_tests.mock(checks, "logger", GetLoggerMocked())
@unit_tests.mock(tool_opts, "no_rhsm", True)
def test_custom_repos_are_invalid(self):
diff --git a/convert2rhel/unit_tests/main_test.py b/convert2rhel/unit_tests/main_test.py
index 20befc0e7e..5c18bb1e06 100644
--- a/convert2rhel/unit_tests/main_test.py
+++ b/convert2rhel/unit_tests/main_test.py
@@ -17,7 +17,6 @@
import os
-import sys
import unittest
from collections import OrderedDict
@@ -181,7 +180,7 @@ def test_rollback_changes(self):
@unit_tests.mock(cert.SystemCert, "_get_cert", lambda _get_cert: ("anything", "anything"))
@mock_calls(main.special_cases, "check_and_resolve", CallOrderMocked)
@mock_calls(pkghandler, "install_gpg_keys", CallOrderMocked)
- @mock_calls(main.checks, "perform_pre_checks", CallOrderMocked)
+ @mock_calls(main.checks, "perform_system_checks", CallOrderMocked)
@mock_calls(main.checks, "perform_pre_ponr_checks", CallOrderMocked)
@mock_calls(pkghandler, "remove_excluded_pkgs", CallOrderMocked)
@mock_calls(subscription, "replace_subscription_manager", CallOrderMocked)
@@ -217,7 +216,7 @@ def test_pre_ponr_conversion_order_with_rhsm(self):
intended_call_order["remove_repofile_pkgs"] = 1
intended_call_order["enable_repos"] = 1
intended_call_order["perform_pre_ponr_checks"] = 1
- intended_call_order["perform_pre_checks"] = 1
+ intended_call_order["perform_system_checks"] = 1
# Merge the two together like a zipper, creates a tuple which we can assert with - including method call order!
zipped_call_order = zip(intended_call_order.items(), self.CallOrderMocked.calls.items())
@@ -230,7 +229,7 @@ def test_pre_ponr_conversion_order_with_rhsm(self):
@unit_tests.mock(cert.SystemCert, "_get_cert", lambda _get_cert: ("anything", "anything"))
@mock_calls(main.special_cases, "check_and_resolve", CallOrderMocked)
@mock_calls(pkghandler, "install_gpg_keys", CallOrderMocked)
- @mock_calls(main.checks, "perform_pre_checks", CallOrderMocked)
+ @mock_calls(main.checks, "perform_system_checks", CallOrderMocked)
@mock_calls(main.checks, "perform_pre_ponr_checks", CallOrderMocked)
@mock_calls(pkghandler, "remove_excluded_pkgs", CallOrderMocked)
@mock_calls(subscription, "replace_subscription_manager", CallOrderMocked)
@@ -270,6 +269,59 @@ def test_pre_ponr_conversion_order_without_rhsm(self):
intended_call_order["remove_repofile_pkgs"] = 1
intended_call_order["enable_repos"] = 0
+ intended_call_order["perform_pre_ponr_checks"] = 1
+ intended_call_order["perform_system_checks"] = 1
+
+ # Merge the two together like a zipper, creates a tuple which we can assert with - including method call order!
+ zipped_call_order = zip(intended_call_order.items(), self.CallOrderMocked.calls.items())
+ for expected, actual in zipped_call_order:
+ if expected[1] > 0:
+ self.assertEqual(expected, actual)
+
+ @unit_tests.mock(main.logging, "getLogger", GetLoggerMocked())
+ @unit_tests.mock(tool_opts, "no_rhsm", False)
+ @unit_tests.mock(cert.SystemCert, "_get_cert", lambda _get_cert: ("anything", "anything"))
+ @mock_calls(main.special_cases, "check_and_resolve", CallOrderMocked)
+ @mock_calls(pkghandler, "install_gpg_keys", CallOrderMocked)
+ @mock_calls(main.checks, "perform_pre_ponr_checks", CallOrderMocked)
+ @mock_calls(pkghandler, "remove_excluded_pkgs", CallOrderMocked)
+ @mock_calls(subscription, "replace_subscription_manager", CallOrderMocked)
+ @mock_calls(subscription, "verify_rhsm_installed", CallOrderMocked)
+ @mock_calls(pkghandler, "remove_repofile_pkgs", CallOrderMocked)
+ @mock_calls(cert.SystemCert, "install", CallOrderMocked)
+ @mock_calls(pkghandler, "list_third_party_pkgs", CallOrderMocked)
+ @mock_calls(subscription, "subscribe_system", CallOrderMocked)
+ @mock_calls(repo, "get_rhel_repoids", CallOrderMocked)
+ @mock_calls(subscription, "check_needed_repos_availability", CallOrderMocked)
+ @mock_calls(subscription, "disable_repos", CallOrderMocked)
+ @mock_calls(subscription, "enable_repos", CallOrderMocked)
+ @mock_calls(subscription, "download_rhsm_pkgs", CallOrderMocked)
+ @unit_tests.mock(checks, "check_readonly_mounts", GetFakeFunctionMocked)
+ def test_pre_ponr_conversion_order_without_rhsm(self):
+ self.CallOrderMocked.reset()
+ main.pre_ponr_conversion()
+
+ intended_call_order = OrderedDict()
+
+ intended_call_order["list_third_party_pkgs"] = 1
+ intended_call_order["remove_excluded_pkgs"] = 1
+ intended_call_order["check_and_resolve"] = 1
+ intended_call_order["install_gpg_keys"] = 1
+
+ # Do not expect this one to be called - related to RHSM
+ intended_call_order["download_rhsm_pkgs"] = 0
+ intended_call_order["replace_subscription_manager"] = 0
+ intended_call_order["verify_rhsm_installed"] = 0
+ intended_call_order["install"] = 0
+ intended_call_order["subscribe_system"] = 0
+ intended_call_order["get_rhel_repoids"] = 0
+ intended_call_order["check_needed_repos_availability"] = 0
+ intended_call_order["disable_repos"] = 0
+
+ intended_call_order["remove_repofile_pkgs"] = 1
+
+ intended_call_order["enable_repos"] = 0
+
intended_call_order["perform_pre_ponr_checks"] = 1
# Merge the two together like a zipper, creates a tuple which we can assert with - including method call order!
@@ -340,12 +392,12 @@ def test_main(monkeypatch):
resolve_system_info_mock = mock.Mock()
collect_early_data_mock = mock.Mock()
clean_yum_metadata_mock = mock.Mock()
- perform_pre_checks_mock = mock.Mock()
system_release_file_mock = mock.Mock()
os_release_file_mock = mock.Mock()
backup_varsdir_mock = mock.Mock()
backup_yum_repos_mock = mock.Mock()
clear_versionlock_mock = mock.Mock()
+ perform_system_checks_mock = mock.Mock()
pre_ponr_conversion_mock = mock.Mock()
ask_to_continue_mock = mock.Mock()
post_ponr_conversion_mock = mock.Mock()
@@ -364,11 +416,11 @@ def test_main(monkeypatch):
monkeypatch.setattr(breadcrumbs, "collect_early_data", collect_early_data_mock)
monkeypatch.setattr(pkghandler, "clear_versionlock", clear_versionlock_mock)
monkeypatch.setattr(pkghandler, "clean_yum_metadata", clean_yum_metadata_mock)
- monkeypatch.setattr(checks, "perform_pre_checks", perform_pre_checks_mock)
monkeypatch.setattr(system_release_file, "backup", system_release_file_mock)
monkeypatch.setattr(os_release_file, "backup", os_release_file_mock)
monkeypatch.setattr(repo, "backup_yum_repos", backup_yum_repos_mock)
monkeypatch.setattr(repo, "backup_varsdir", backup_varsdir_mock)
+ monkeypatch.setattr(checks, "perform_system_checks", perform_system_checks_mock)
monkeypatch.setattr(main, "pre_ponr_conversion", pre_ponr_conversion_mock)
monkeypatch.setattr(utils, "ask_to_continue", ask_to_continue_mock)
monkeypatch.setattr(main, "post_ponr_conversion", post_ponr_conversion_mock)
@@ -387,7 +439,6 @@ def test_main(monkeypatch):
assert resolve_system_info_mock.call_count == 1
assert collect_early_data_mock.call_count == 1
assert clean_yum_metadata_mock.call_count == 1
- assert perform_pre_checks_mock.call_count == 1
assert system_release_file_mock.call_count == 1
assert os_release_file_mock.call_count == 1
assert backup_yum_repos_mock.call_count == 1
@@ -435,7 +486,7 @@ def test_main_rollback_pre_ponr_changes_phase(monkeypatch):
resolve_system_info_mock = mock.Mock()
collect_early_data_mock = mock.Mock()
clean_yum_metadata_mock = mock.Mock()
- perform_pre_checks_mock = mock.Mock()
+ perform_system_checks_mock = mock.Mock()
system_release_file_mock = mock.Mock()
os_release_file_mock = mock.Mock()
backup_yum_repos_mock = mock.Mock()
@@ -455,7 +506,7 @@ def test_main_rollback_pre_ponr_changes_phase(monkeypatch):
monkeypatch.setattr(breadcrumbs, "collect_early_data", collect_early_data_mock)
monkeypatch.setattr(pkghandler, "clear_versionlock", clear_versionlock_mock)
monkeypatch.setattr(pkghandler, "clean_yum_metadata", clean_yum_metadata_mock)
- monkeypatch.setattr(checks, "perform_pre_checks", perform_pre_checks_mock)
+ monkeypatch.setattr(checks, "perform_system_checks", perform_system_checks_mock)
monkeypatch.setattr(system_release_file, "backup", system_release_file_mock)
monkeypatch.setattr(os_release_file, "backup", os_release_file_mock)
monkeypatch.setattr(repo, "backup_yum_repos", backup_yum_repos_mock)
@@ -472,7 +523,7 @@ def test_main_rollback_pre_ponr_changes_phase(monkeypatch):
assert resolve_system_info_mock.call_count == 1
assert collect_early_data_mock.call_count == 1
assert clean_yum_metadata_mock.call_count == 1
- assert perform_pre_checks_mock.call_count == 1
+ assert perform_system_checks_mock.call_count == 1
assert system_release_file_mock.call_count == 1
assert os_release_file_mock.call_count == 1
assert backup_yum_repos_mock.call_count == 1
@@ -491,7 +542,7 @@ def test_main_rollback_post_ponr_changes_phase(monkeypatch, caplog):
resolve_system_info_mock = mock.Mock()
collect_early_data_mock = mock.Mock()
clean_yum_metadata_mock = mock.Mock()
- perform_pre_checks_mock = mock.Mock()
+ perform_system_checks_mock = mock.Mock()
system_release_file_mock = mock.Mock()
os_release_file_mock = mock.Mock()
backup_yum_repos_mock = mock.Mock()
@@ -513,7 +564,7 @@ def test_main_rollback_post_ponr_changes_phase(monkeypatch, caplog):
monkeypatch.setattr(breadcrumbs, "collect_early_data", collect_early_data_mock)
monkeypatch.setattr(pkghandler, "clear_versionlock", clear_versionlock_mock)
monkeypatch.setattr(pkghandler, "clean_yum_metadata", clean_yum_metadata_mock)
- monkeypatch.setattr(checks, "perform_pre_checks", perform_pre_checks_mock)
+ monkeypatch.setattr(checks, "perform_system_checks", perform_system_checks_mock)
monkeypatch.setattr(system_release_file, "backup", system_release_file_mock)
monkeypatch.setattr(os_release_file, "backup", os_release_file_mock)
monkeypatch.setattr(repo, "backup_yum_repos", backup_yum_repos_mock)
@@ -532,7 +583,7 @@ def test_main_rollback_post_ponr_changes_phase(monkeypatch, caplog):
assert resolve_system_info_mock.call_count == 1
assert collect_early_data_mock.call_count == 1
assert clean_yum_metadata_mock.call_count == 1
- assert perform_pre_checks_mock.call_count == 1
+ assert perform_system_checks_mock.call_count == 1
assert system_release_file_mock.call_count == 1
assert os_release_file_mock.call_count == 1
assert backup_yum_repos_mock.call_count == 1
diff --git a/convert2rhel/unit_tests/pkghandler_test.py b/convert2rhel/unit_tests/pkghandler_test.py
index 9790049c06..1a894265ee 100644
--- a/convert2rhel/unit_tests/pkghandler_test.py
+++ b/convert2rhel/unit_tests/pkghandler_test.py
@@ -1935,3 +1935,37 @@ def test_get_system_packages_for_replacement(pretend_os, monkeypatch):
result = pkghandler.get_system_packages_for_replacement()
for pkg in pkgs:
assert pkg in result
+
+
+@pytest.mark.parametrize(
+ ("pkg_1", "pkg_2", "expected"),
+ (
+ (
+ "kernel-core-0:4.18.0-240.10.1.el8_3.x86_64",
+ "kernel-core-0:4.18.0-240.15.1.el8_3.x86_64",
+ -1,
+ ),
+ (
+ "kmod-core-0:4.18.0-240.15.1.el8_3.x86_64",
+ "kmod-core-0:4.18.0-240.10.1.el8_3.x86_64",
+ 1,
+ ),
+ (
+ "kmod-core-0:4.18.0-240.15.1.el8_3.x86_64",
+ "kmod-core-0:4.18.0-240.15.1.el8_3.x86_64",
+ 0,
+ ),
+ (
+ "no-arch-0:4.18.0-240.15.1.el8_3",
+ "no-arch-0:4.18.0-240.15.1.el8_3",
+ 0,
+ ),
+ (
+ "kmod-core-0.4.18.0-240.15.1.el8_3.x86_64",
+ "kmod-core-0.4.18.0-240.15.1.el8_3.x86_64",
+ 0,
+ ),
+ ),
+)
+def test__package_version_cmp(pkg_1, pkg_2, expected):
+ assert pkghandler._package_version_cmp(pkg_1, pkg_2) == expected
diff --git a/convert2rhel/unit_tests/systeminfo_test.py b/convert2rhel/unit_tests/systeminfo_test.py
index 6961025dbf..b877325120 100644
--- a/convert2rhel/unit_tests/systeminfo_test.py
+++ b/convert2rhel/unit_tests/systeminfo_test.py
@@ -15,7 +15,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-# Required imports:
import logging
import os
import shutil
@@ -247,10 +246,23 @@ def test_get_release_ver_other(
):
monkeypatch.setattr(systeminfo.SystemInfo, "_get_cfg_opt", mock.Mock(return_value=releasever_val))
monkeypatch.setattr(systeminfo.SystemInfo, "_check_internet_access", mock.Mock(return_value=has_internet))
+ monkeypatch.setattr(
+ systeminfo.SystemInfo,
+ "_get_cfg_opt",
+ mock.Mock(return_value=releasever_val),
+ )
if self_name:
- monkeypatch.setattr(systeminfo.SystemInfo, "_get_system_name", mock.Mock(return_value=self_name))
+ monkeypatch.setattr(
+ systeminfo.SystemInfo,
+ "_get_system_name",
+ mock.Mock(return_value=self_name),
+ )
if self_version:
- monkeypatch.setattr(systeminfo.SystemInfo, "_get_system_version", mock.Mock(return_value=self_version))
+ monkeypatch.setattr(
+ systeminfo.SystemInfo,
+ "_get_system_version",
+ mock.Mock(return_value=self_version),
+ )
# calling resolve_system_info one more time to enable our monkeypatches
if exception:
with pytest.raises(exception):
@@ -389,3 +401,41 @@ def test_get_system_distribution_id(system_release_content, expected):
@centos8
def test_get_system_distribution_id_default_system_release_content(pretend_os):
assert system_info._get_system_distribution_id() == None
+
+
+@pytest.mark.parametrize(
+ (
+ "submgr_enabled_repos",
+ "tool_opts_no_rhsm",
+ "tool_opts_enablerepo",
+ "expected",
+ ),
+ (
+ (
+ ["rhel-repo1.repo", "rhel-repo2.repo"],
+ False,
+ [],
+ ["rhel-repo1.repo", "rhel-repo2.repo"],
+ ),
+ (
+ ["rhel-repo1.repo", "rhel-repo2.repo"],
+ True,
+ ["cli-rhel-repo1.repo", "cli-rhel-repo2.repo"],
+ ["cli-rhel-repo1.repo", "cli-rhel-repo2.repo"],
+ ),
+ ),
+)
+def test_get_enabled_rhel_repos(
+ submgr_enabled_repos,
+ tool_opts_no_rhsm,
+ tool_opts_enablerepo,
+ expected,
+ global_tool_opts,
+ monkeypatch,
+):
+ monkeypatch.setattr(systeminfo, "tool_opts", global_tool_opts)
+ system_info.submgr_enabled_repos = submgr_enabled_repos
+ global_tool_opts.enablerepo = tool_opts_enablerepo
+ global_tool_opts.no_rhsm = tool_opts_no_rhsm
+
+ assert system_info.get_enabled_rhel_repos() == expected
diff --git a/convert2rhel/unit_tests/toolopts_test.py b/convert2rhel/unit_tests/toolopts_test.py
index 676557e762..4872a2cae5 100644
--- a/convert2rhel/unit_tests/toolopts_test.py
+++ b/convert2rhel/unit_tests/toolopts_test.py
@@ -20,7 +20,6 @@
import os
import sys
-import unittest
from collections import namedtuple
@@ -30,7 +29,6 @@
import convert2rhel.toolopts
import convert2rhel.utils
-from convert2rhel import unit_tests # Imports unit_tests/__init__.py
from convert2rhel.toolopts import tool_opts
diff --git a/tests/integration/tier0/inhibit-if-kmods-is-not-supported/main.fmf b/tests/integration/tier0/inhibit-if-kmods-is-not-supported/main.fmf
index 6c71abc431..83ac071dfa 100644
--- a/tests/integration/tier0/inhibit-if-kmods-is-not-supported/main.fmf
+++ b/tests/integration/tier0/inhibit-if-kmods-is-not-supported/main.fmf
@@ -1,6 +1,11 @@
-summary: kmods tests
+summary: Handle custom, tainted and force loaded kernel modules.
+description: |
+ Verify, that Convert2RHEL is able to handle custom, tainted and force loaded kernel modules.
tier: 0
+tag+:
+ - kernel
+
test: |
pytest -svv
diff --git a/tests/integration/tier0/inhibit-if-kmods-is-not-supported/test_kmods_not_supported.py b/tests/integration/tier0/inhibit-if-kmods-is-not-supported/test_kmods_not_supported.py
index 498ac9c0af..a16ee11c8f 100644
--- a/tests/integration/tier0/inhibit-if-kmods-is-not-supported/test_kmods_not_supported.py
+++ b/tests/integration/tier0/inhibit-if-kmods-is-not-supported/test_kmods_not_supported.py
@@ -7,8 +7,16 @@
from envparse import env
+system_version = platform.platform()
+
+
@pytest.fixture()
def insert_custom_kmod(shell):
+ """
+ Move the kernel module to custom location, so it is marked as custom.
+ Then load the kernel module.
+ """
+
def factory():
origin_kmod_loc = Path("/lib/modules/$(uname -r)/kernel/drivers/net/bonding/bonding.ko.xz")
new_kmod_dir = origin_kmod_loc.parent / "custom_module_location"
@@ -22,25 +30,31 @@ def factory():
def test_inhibit_if_custom_module_loaded(insert_custom_kmod, convert2rhel):
- # This test checks that rpmquery works correctly.
- # If custom module is loaded the conversion has to be inhibited.
+ """
+ This test verifies that rpmquery for detecting supported kernel modules in RHEL works correctly.
+ If custom module is loaded the conversion has to be inhibited.
+ """
insert_custom_kmod()
with convert2rhel(
- ("-y --no-rpm-va --serverurl {} --username {} --password {} --pool {} --debug").format(
+ "-y --no-rpm-va --serverurl {} --username {} --password {} --pool {} --debug".format(
env.str("RHSM_SERVER_URL"),
env.str("RHSM_USERNAME"),
env.str("RHSM_PASSWORD"),
env.str("RHSM_POOL"),
)
) as c2r:
- c2r.expect("The following kernel modules are not supported in RHEL")
+ c2r.expect("The following loaded kernel modules are not available in RHEL")
assert c2r.exitstatus != 0
def test_do_not_inhibit_if_module_is_not_loaded(shell, convert2rhel):
+ """
+ Test removes previously loaded custom module and runs the conversion.
+ The kmod compatibility checks is right before the point of no return.
+ Abort the conversion right after the check.
+ """
assert shell("modprobe -r -v bonding").returncode == 0
- system_version = platform.platform()
if "oracle-7" in system_version or "centos-7" in system_version:
prompt_amount = 3
elif "oracle-8" in system_version:
@@ -49,7 +63,7 @@ def test_do_not_inhibit_if_module_is_not_loaded(shell, convert2rhel):
prompt_amount = 3
# If custom module is not loaded the conversion is not inhibited.
with convert2rhel(
- ("--no-rpm-va --serverurl {} --username {} --password {} --pool {} --debug").format(
+ "--no-rpm-va --serverurl {} --username {} --password {} --pool {} --debug".format(
env.str("RHSM_SERVER_URL"),
env.str("RHSM_USERNAME"),
env.str("RHSM_PASSWORD"),
@@ -61,16 +75,44 @@ def test_do_not_inhibit_if_module_is_not_loaded(shell, convert2rhel):
c2r.sendline("y")
prompt_amount -= 1
- assert c2r.expect("Kernel modules are compatible.", timeout=600) == 0
+ # Stop conversion before the point of no return as we do not need to run the full conversion
+ # with the check for kompatible kernel modules being right before the PONR.
+ assert c2r.expect("All loaded kernel modules are available in RHEL.", timeout=600) == 0
c2r.expect("Continue with the system conversion?")
c2r.sendline("n")
assert c2r.exitstatus != 0
-def test_tainted_kernel_inhibitor(shell, convert2rhel):
- # This test marks the kernel as tainted which is not supported by convert2rhel.
+def test_do_not_inhibit_if_module_is_force_loaded(shell, convert2rhel):
+ """
+ Test force loads kmod and verifies that Convert2RHEL run is being inhibited.
+ Force loaded kmods are denoted (FE) where F = module was force loaded E = unsigned module was loaded.
+ Convert2RHEL sees force loaded kmod as tainted.
+ """
+ if "oracle-7" not in system_version and "centos-7" not in system_version:
+ # Force load the kernel module
+ assert shell("modprobe -f -v bonding").returncode == 0
+ # Check for force loaded modules being flagged FE in /proc/modules
+ assert "(FE)" in shell("cat /proc/modules").output
- # We need to install specific kernel packages to build own custom kernel module.
+ with convert2rhel("--no-rpm-va --debug") as c2r:
+ assert c2r.expect("Tainted kernel modules detected") == 0
+ assert c2r.exitstatus != 0
+
+ # Clean up - unload kmod and check for force loaded modules not being in /proc/modules
+ assert shell("modprobe -r -v bonding").returncode == 0
+ assert "(FE)" not in shell("cat /proc/modules").output
+
+
+def test_tainted_kernel_inhibitor(shell, convert2rhel):
+ """
+ This test marks the kernel as tainted which is not supported by Convert2RHEL.
+ We need to install specific kernel packages to build own custom kernel module.
+ Build own kmod from source file that has been copied to the testing machine during preparation phase.
+ This kmod marks the system with the P, O and E flags.
+ """
+
+ # Install kernel packages
shell("yum -y install gcc make kernel-headers kernel-devel-$(uname -r) elfutils-libelf-devel")
# Build own kmod form source file that has been copied to the testing machine during preparation phase.
@@ -79,12 +121,12 @@ def test_tainted_kernel_inhibitor(shell, convert2rhel):
assert shell("insmod /tmp/my-test/my_kmod.ko").returncode == 0
with convert2rhel(
- ("-y --no-rpm-va --serverurl {} --username {} --password {} --pool {} --debug").format(
+ "-y --no-rpm-va --serverurl {} --username {} --password {} --pool {} --debug".format(
env.str("RHSM_SERVER_URL"),
env.str("RHSM_USERNAME"),
env.str("RHSM_PASSWORD"),
env.str("RHSM_POOL"),
)
) as c2r:
- c2r.expect("Tainted kernel module\(s\) detected")
+ c2r.expect("Tainted kernel modules detected")
assert c2r.exitstatus != 0