Skip to content

Commit

Permalink
Inhibit incompatible ARM upgrades
Browse files Browse the repository at this point in the history
Due to an incompatibility of RHEL8 bootloader with newer versions of
kernel on RHEL9 since version 9.5 the upgrade cannot be performed as
the old bootloader is used to load the new versions of kernel during
the upgrade.

JIRA: [41193](https://issues.redhat.com/browse/RHEL-41193)
  • Loading branch information
dkubek committed Jul 22, 2024
1 parent 0ef7402 commit 2280fb3
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
22 changes: 22 additions & 0 deletions repos/system_upgrade/el8toel9/actors/checkarmbootloader/actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import leapp.libraries.actor.checkarmbootloader as checkarmbootloader
from leapp.actors import Actor
from leapp.reporting import Report
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag


class CheckArmBootloader(Actor):
"""
Inhibit ARM system upgrades on path with incompatible kernel/bootloader
Due to an incompatibility of RHEL8 bootloader with newer versions of kernel
on RHEL9 since version 9.5 the upgrade cannot be performed as the old
bootloader is used to load the new versions of kernel during the upgrade.
"""

name = 'check_arm_bootloader'
consumes = ()
produces = (Report,)
tags = (ChecksPhaseTag, IPUWorkflowTag,)

def process(self):
checkarmbootloader.process()
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from leapp import reporting
from leapp.libraries.common.config.architecture import ARCH_ARM64, matches_architecture
from leapp.libraries.common.config.version import get_target_version, get_source_version
from leapp.libraries.stdlib import api


def _inhibit_upgrade():
title = 'Upgrade {} to {} unsupported for ARM machines.'.format(
get_source_version(), get_target_version())
summary = ('Due to the incompatibility of the RHEL8 bootloader with a '
'newer version of kernel on RHEL9 a direct upgrade '
'cannot be performed for versions 9.5 and up.')

reporting.create_report([
reporting.Title(title),
reporting.Summary(summary),
reporting.ExternalLink(
title='Upgrading ARM architecture from RHEL 8.10 to 9.5 and up.',
# FIXME:
url='INSERT-KCS-LINK'),
reporting.Severity(reporting.Severity.HIGH),
reporting.Groups([reporting.Groups.INHIBITOR]),
reporting.Groups([reporting.Groups.SANITY]),
reporting.Remediation(hint=(
'To upgrade to a RHEL version 9.5 and up, first perform an upgrade '
'to version 9.4 using the leapp `--target` option and then perform '
'a minor dnf update after the upgrade')),
])


def process():
"""
Check whether ARM system uses path with compatible kernel/bootloader.
"""

if not matches_architecture(ARCH_ARM64):
api.current_logger().info('Architecture not ARM. Skipping bootloader check.')
return

target_major, target_minor = tuple(map(int, get_target_version().split('.')))
if (target_major, target_minor) < (9, 5):
api.current_logger().info((
'Upgrade on ARM architecture on a compatible path ({} to {}). '
'Skipping bootloader check.').format(get_source_version(), get_target_version()))
return

_inhibit_upgrade()
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import pytest

from leapp import reporting
from leapp.libraries.actor import checkarmbootloader
from leapp.libraries.common.config.architecture import ARCH_SUPPORTED, ARCH_ARM64
from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked, logger_mocked
from leapp.libraries.stdlib import api
from leapp.utils.report import is_inhibitor


@pytest.mark.parametrize("arch", [arch for arch in ARCH_SUPPORTED if not arch == ARCH_ARM64])
def test_not_x86_64_passes(monkeypatch, arch):
"""
Test no report is generated on an architecture different from ARM
"""

monkeypatch.setattr(reporting, "create_report", create_report_mocked())
monkeypatch.setattr(api, 'current_logger', logger_mocked())
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=arch))

checkarmbootloader.process()

assert 'Architecture not ARM.' in api.current_logger.infomsg[0]
assert not reporting.create_report.called


@pytest.mark.parametrize("target_version", ["9.2", "9.4"])
def test_valid_path(monkeypatch, target_version):
"""
Test no report is generated on a supported path
"""

monkeypatch.setattr(reporting, "create_report", create_report_mocked())
monkeypatch.setattr(api, 'current_logger', logger_mocked())
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_ARM64))
monkeypatch.setattr(checkarmbootloader, 'get_target_version', lambda: target_version)

checkarmbootloader.process()

assert 'Upgrade on ARM architecture on a compatible path' in api.current_logger.infomsg[0]
assert not reporting.create_report.called


def test_invalid_path(monkeypatch):
"""
Test report is generated on a invalid upgrade path
"""

monkeypatch.setattr(reporting, "create_report", create_report_mocked())
monkeypatch.setattr(api, 'current_logger', logger_mocked())
monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_ARM64))
monkeypatch.setattr(checkarmbootloader, 'get_target_version', lambda: '9.5')

checkarmbootloader.process()

produced_title = reporting.create_report.report_fields.get('title')
produced_summary = reporting.create_report.report_fields.get('summary')

assert reporting.create_report.called == 1
assert 'unsupported for ARM machines' in produced_title
assert 'Due to the incompatibility' in produced_summary
assert reporting.create_report.report_fields['severity'] == reporting.Severity.HIGH
assert is_inhibitor(reporting.create_report.report_fields)

0 comments on commit 2280fb3

Please sign in to comment.