188 lines
7.2 KiB
Diff
188 lines
7.2 KiB
Diff
From f7ccf5aefdd87856c4dda80c2c410d5cb34d0c1d Mon Sep 17 00:00:00 2001
|
|
From: Petr Stodulka <pstodulk@redhat.com>
|
|
Date: Wed, 24 Jun 2026 08:58:38 +0200
|
|
Subject: [PATCH 108/108] el8toel9: checkkernelarm: Install 64k kernel
|
|
|
|
On RHEL 8 for ARM, the default kernel is 64k (pagesize) and there is
|
|
no 4k alternative. On RHEL 9 it's the opposite nowadays (since 9.4?),
|
|
where the default kernel is 4k, but for 64k the kernel-64k RPMs
|
|
need to be installed.
|
|
|
|
So for the upgrade 8 -> 9 on ARM, it's important to create explicit
|
|
instruction for the installation of kernel-64k packages. On other
|
|
systems we do not have this problem so leaving it just in el8toel9
|
|
repository.
|
|
|
|
Also, we cannot prevent installation of standard kernel packages,
|
|
so the system after the upgrade will have both kernels installed
|
|
(4k & 64k versions).
|
|
|
|
At this moment, no report is generated to informing user about the
|
|
need of manual 4k kernel removal. But it's a better situation than
|
|
in case of the requirement to manually install 64k kernel, reboot,
|
|
and then remove the 4k one. The report can be eventually created
|
|
as a follow up.
|
|
|
|
Note that without this fix, the upgrade 8 -> 9 would end in emergency
|
|
mode on ARM machines after previously introduced changes dealing with
|
|
various kernel flavours - where a specific kernel is expected to be
|
|
discovered after the upgrade.
|
|
|
|
Used AI to prepare unit-tests.
|
|
|
|
JIRA: RHEL-111860
|
|
Assisted-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Signed-off-by: Petr Stodulka <pstodulk@redhat.com>
|
|
---
|
|
.../el8toel9/actors/checkkernelarm/actor.py | 22 ++++++
|
|
.../libraries/checkkernelarm.py | 28 ++++++++
|
|
.../tests/unit_test_checkkernelarm.py | 72 +++++++++++++++++++
|
|
3 files changed, 122 insertions(+)
|
|
create mode 100644 repos/system_upgrade/el8toel9/actors/checkkernelarm/actor.py
|
|
create mode 100644 repos/system_upgrade/el8toel9/actors/checkkernelarm/libraries/checkkernelarm.py
|
|
create mode 100644 repos/system_upgrade/el8toel9/actors/checkkernelarm/tests/unit_test_checkkernelarm.py
|
|
|
|
diff --git a/repos/system_upgrade/el8toel9/actors/checkkernelarm/actor.py b/repos/system_upgrade/el8toel9/actors/checkkernelarm/actor.py
|
|
new file mode 100644
|
|
index 00000000..9fa9eaa1
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/el8toel9/actors/checkkernelarm/actor.py
|
|
@@ -0,0 +1,22 @@
|
|
+from leapp.actors import Actor
|
|
+from leapp.libraries.actor import checkkernelarm
|
|
+from leapp.models import KernelInfo, RpmTransactionTasks
|
|
+from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
|
|
+
|
|
+
|
|
+class CheckKernelARM(Actor):
|
|
+ """
|
|
+ Instruct the installation of 64k kernel on ARM machines.
|
|
+
|
|
+ On RHEL 8 all ARM machines use kernel with the 64k pagesize.
|
|
+ However, in case of RHEL 9 the default ARM kernel has 4k pagesize instead.
|
|
+ Ensure that 64k kernel is installed on the target system for ARM.
|
|
+ """
|
|
+
|
|
+ name = 'check_kernel_arm'
|
|
+ consumes = (KernelInfo,)
|
|
+ produces = (RpmTransactionTasks,)
|
|
+ tags = (IPUWorkflowTag, ChecksPhaseTag)
|
|
+
|
|
+ def process(self):
|
|
+ checkkernelarm.process()
|
|
diff --git a/repos/system_upgrade/el8toel9/actors/checkkernelarm/libraries/checkkernelarm.py b/repos/system_upgrade/el8toel9/actors/checkkernelarm/libraries/checkkernelarm.py
|
|
new file mode 100644
|
|
index 00000000..78bf0bb6
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/el8toel9/actors/checkkernelarm/libraries/checkkernelarm.py
|
|
@@ -0,0 +1,28 @@
|
|
+from leapp.exceptions import StopActorExecutionError
|
|
+from leapp.libraries.common import kernel as kernel_lib
|
|
+from leapp.libraries.common.config import architecture
|
|
+from leapp.libraries.stdlib import api
|
|
+from leapp.models import KernelInfo, RpmTransactionTasks
|
|
+
|
|
+
|
|
+def process():
|
|
+ if not architecture.matches_architecture(architecture.ARCH_ARM64):
|
|
+ # Nothing to do.
|
|
+ return
|
|
+
|
|
+ kernel_info = next(api.consume(KernelInfo), None)
|
|
+ if not kernel_info:
|
|
+ raise StopActorExecutionError('Could not retrieve KernelInfo message.')
|
|
+
|
|
+ target_pkgs = kernel_lib.get_target_kernel_pkg_names(
|
|
+ kernel_info.type,
|
|
+ kernel_info.page_size,
|
|
+ api.current_actor().configuration.architecture
|
|
+ )
|
|
+
|
|
+ api.current_logger().debug(
|
|
+ "Register expected target kernel RPMs for installation on ARM."
|
|
+ )
|
|
+ api.produce(RpmTransactionTasks(
|
|
+ to_install=sorted(list(target_pkgs)))
|
|
+ )
|
|
diff --git a/repos/system_upgrade/el8toel9/actors/checkkernelarm/tests/unit_test_checkkernelarm.py b/repos/system_upgrade/el8toel9/actors/checkkernelarm/tests/unit_test_checkkernelarm.py
|
|
new file mode 100644
|
|
index 00000000..9d34fd4a
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/el8toel9/actors/checkkernelarm/tests/unit_test_checkkernelarm.py
|
|
@@ -0,0 +1,72 @@
|
|
+import pytest
|
|
+
|
|
+from leapp.exceptions import StopActorExecutionError
|
|
+from leapp.libraries.actor import checkkernelarm
|
|
+from leapp.libraries.common.config.architecture import ARCH_ARM64, ARCH_X86_64
|
|
+from leapp.libraries.common.kernel import KernelPageSize, KernelType
|
|
+from leapp.libraries.common.testutils import CurrentActorMocked, produce_mocked
|
|
+from leapp.libraries.stdlib import api
|
|
+from leapp.models import KernelInfo, RPM, RpmTransactionTasks
|
|
+
|
|
+_KERNEL_PKG = RPM(name='kernel-core', arch='aarch64', version='4.18.0', release='1.el8',
|
|
+ epoch='0', packager='', pgpsig='SIG')
|
|
+
|
|
+
|
|
+def _make_kernel_info(kernel_type=KernelType.ORDINARY, page_size=KernelPageSize.PAGE_SIZE_64K):
|
|
+ return KernelInfo(
|
|
+ pkg=_KERNEL_PKG, type=kernel_type, page_size=page_size, uname_r='4.18.0-1.el8.aarch64'
|
|
+ )
|
|
+
|
|
+
|
|
+def test_skip_non_arm_architecture(monkeypatch):
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_X86_64))
|
|
+ monkeypatch.setattr(api, 'produce', produce_mocked())
|
|
+
|
|
+ checkkernelarm.process()
|
|
+
|
|
+ assert not api.produce.called
|
|
+
|
|
+
|
|
+def test_raises_when_no_kernel_info(monkeypatch):
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_ARM64))
|
|
+
|
|
+ with pytest.raises(StopActorExecutionError, match='Could not retrieve KernelInfo'):
|
|
+ checkkernelarm.process()
|
|
+
|
|
+
|
|
+@pytest.mark.parametrize(
|
|
+ ('kernel_type', 'page_size', 'expected_pkgs'),
|
|
+ [
|
|
+ (
|
|
+ KernelType.ORDINARY,
|
|
+ KernelPageSize.PAGE_SIZE_64K,
|
|
+ ['kernel-64k', 'kernel-64k-core', 'kernel-64k-modules'],
|
|
+ ),
|
|
+ (
|
|
+ KernelType.ORDINARY,
|
|
+ KernelPageSize.PAGE_SIZE_4K,
|
|
+ ['kernel', 'kernel-core', 'kernel-modules'],
|
|
+ ),
|
|
+ (
|
|
+ KernelType.REALTIME,
|
|
+ KernelPageSize.PAGE_SIZE_64K,
|
|
+ ['kernel-rt-64k', 'kernel-rt-64k-core', 'kernel-rt-64k-modules'],
|
|
+ ),
|
|
+ (
|
|
+ KernelType.REALTIME,
|
|
+ KernelPageSize.PAGE_SIZE_4K,
|
|
+ ['kernel-rt', 'kernel-rt-core', 'kernel-rt-modules'],
|
|
+ ),
|
|
+ ]
|
|
+)
|
|
+def test_produces_rpm_transaction_tasks(monkeypatch, kernel_type, page_size, expected_pkgs):
|
|
+ kernel_info = _make_kernel_info(kernel_type=kernel_type, page_size=page_size)
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_ARM64, msgs=[kernel_info]))
|
|
+ monkeypatch.setattr(api, 'produce', produce_mocked())
|
|
+
|
|
+ checkkernelarm.process()
|
|
+
|
|
+ assert api.produce.called == 1
|
|
+ produced = api.produce.model_instances[0]
|
|
+ assert isinstance(produced, RpmTransactionTasks)
|
|
+ assert sorted(produced.to_install) == sorted(expected_pkgs)
|
|
--
|
|
2.54.0
|
|
|