diff --git a/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddebugkernels/actor.py b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddebugkernels/actor.py new file mode 100644 index 0000000000..2dccf4bd52 --- /dev/null +++ b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddebugkernels/actor.py @@ -0,0 +1,23 @@ +from leapp.actors import Actor +from leapp.models import InstalledRedHatSignedRPM +from leapp.tags import IPUWorkflowTag, ChecksPhaseTag +from leapp.reporting import Report +from leapp.libraries.actor import checkinstalleddebugkernels + + +class CheckInstalledDebugKernels(Actor): + """ + Inhibit IPU (in-place upgrade) when multiple debug kernels are installed. + + Because of an issue in DNF, the transaction can't be validated if there's + more than one package named kernel-debug. Therefore, in this case, we + inhibit the upgrade with a clearer remediation. + """ + + name = 'check_installed_debug_kernels' + consumes = (InstalledRedHatSignedRPM,) + produces = (Report,) + tags = (IPUWorkflowTag, ChecksPhaseTag) + + def process(self): + checkinstalleddebugkernels.process() diff --git a/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddebugkernels/libraries/checkinstalleddebugkernels.py b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddebugkernels/libraries/checkinstalleddebugkernels.py new file mode 100644 index 0000000000..00c245b211 --- /dev/null +++ b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddebugkernels/libraries/checkinstalleddebugkernels.py @@ -0,0 +1,42 @@ +from leapp import reporting +from leapp.libraries.stdlib import api +from leapp.models import InstalledRedHatSignedRPM + + +def get_kernel_rpm_release(rpm): + """ + Get the release of a kernel RPM as an integer. + + :param rpm: An instance of an RPM derived model. + """ + return int(rpm.release.split('.')[0]) + + +def get_kernel_debug_rpms(): + """ + Get all installed kernel-debug packages ordered by release number (ascending). + """ + rpms = next(api.consume(InstalledRedHatSignedRPM), InstalledRedHatSignedRPM()) + return sorted([pkg for pkg in rpms.items if pkg.name == 'kernel-debug'], key=get_kernel_rpm_release) + + +def process(): + pkgs = get_kernel_debug_rpms() + if len(pkgs) > 1: + title = 'Multiple debug kernels installed' + summary = ('DNF cannot produce a valid upgrade transaction when' + ' multiple kernel-debug packages are installed.') + hint = ('Remove all but one kernel-debug packages before running Leapp again.') + all_but_latest_kernel_debug = pkgs[:-1] + packages = ['{n}-{v}-{r}'.format(n=pkg.name, v=pkg.version, r=pkg.release) + for pkg in all_but_latest_kernel_debug] + commands = [['yum', '-y', 'remove'] + packages] + reporting.create_report([ + reporting.Title(title), + reporting.Summary(summary), + reporting.Severity(reporting.Severity.HIGH), + reporting.Tags([reporting.Tags.KERNEL]), + reporting.Flags([reporting.Flags.INHIBITOR]), + reporting.Remediation(hint=hint, commands=commands), + reporting.RelatedResource('package', 'kernel-debug') + ]) diff --git a/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddebugkernels/tests/unit_test_checkinstalleddebugkernels.py b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddebugkernels/tests/unit_test_checkinstalleddebugkernels.py new file mode 100644 index 0000000000..365b729bc7 --- /dev/null +++ b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddebugkernels/tests/unit_test_checkinstalleddebugkernels.py @@ -0,0 +1,36 @@ +import pytest + +from leapp.models import InstalledRedHatSignedRPM, RPM, Report +from leapp.snactor.fixture import current_actor_context + + +RH_PACKAGER = 'Red Hat, Inc. ' + +ballast1 = [ + RPM(name='b1', version='1', release='1', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='s'), + RPM(name='kernel', version='1', release='1', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='s'), + RPM(name='b2', version='1', release='1', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='s') +] +ballast2 = [ + RPM(name='b3', version='1', release='1', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='s'), + RPM(name='kernel', version='1', release='1', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='s'), + RPM(name='b4', version='1', release='1', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='s') +] +debug_kernels = [ + RPM(name='kernel-debug', version='3.10.0', release='957.27.4.el7', + epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='s'), + RPM(name='kernel-debug', version='3.10.0', release='957.35.1.el7', + epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='s'), + RPM(name='kernel-debug', version='3.10.0', release='957.43.1.el7', + epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='s') +] + + +@pytest.mark.parametrize('n', [0, 1, 2, 3]) +def test_process_debug_kernels(current_actor_context, n): + current_actor_context.feed(InstalledRedHatSignedRPM(items=ballast1+debug_kernels[:n]+ballast2)) + current_actor_context.run() + if n < 2: + assert not current_actor_context.consume(Report) + else: + assert current_actor_context.consume(Report) diff --git a/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddevelkernels/libraries/checkinstalleddevelkernels.py b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddevelkernels/libraries/checkinstalleddevelkernels.py index 99c6a4bbaa..35d6a6705d 100644 --- a/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddevelkernels/libraries/checkinstalleddevelkernels.py +++ b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalleddevelkernels/libraries/checkinstalleddevelkernels.py @@ -38,5 +38,5 @@ def process(): reporting.Tags([reporting.Tags.KERNEL]), reporting.Flags([reporting.Flags.INHIBITOR]), reporting.Remediation(hint=hint, commands=commands), - reporting.RelatedResource('package', 'kernel') + reporting.RelatedResource('package', 'kernel-devel') ])