forked from rpms/leapp-repository
177 lines
8.1 KiB
Diff
177 lines
8.1 KiB
Diff
|
From 8fe2a2d35395a43b8449354d68479d8339ef49ab Mon Sep 17 00:00:00 2001
|
||
|
From: mhecko <mhecko@redhat.com>
|
||
|
Date: Sun, 21 Apr 2024 22:40:38 +0200
|
||
|
Subject: [PATCH 11/34] check_grub_legacy: inhibit when GRUB legacy is present
|
||
|
|
||
|
Adds a new actor checking for whether any of the GRUB devices
|
||
|
have the old GRUB Legacy installed. If any of such devices
|
||
|
is detected, the upgrade is inhibited. The GRUB Legacy is detected
|
||
|
by searching for the string 'GRUB version 0.94' in `file -s`
|
||
|
of the device.
|
||
|
---
|
||
|
.../el7toel8/actors/checklegacygrub/actor.py | 20 ++++++
|
||
|
.../libraries/check_legacy_grub.py | 71 +++++++++++++++++++
|
||
|
.../tests/test_check_legacy_grub.py | 45 ++++++++++++
|
||
|
3 files changed, 136 insertions(+)
|
||
|
create mode 100644 repos/system_upgrade/el7toel8/actors/checklegacygrub/actor.py
|
||
|
create mode 100644 repos/system_upgrade/el7toel8/actors/checklegacygrub/libraries/check_legacy_grub.py
|
||
|
create mode 100644 repos/system_upgrade/el7toel8/actors/checklegacygrub/tests/test_check_legacy_grub.py
|
||
|
|
||
|
diff --git a/repos/system_upgrade/el7toel8/actors/checklegacygrub/actor.py b/repos/system_upgrade/el7toel8/actors/checklegacygrub/actor.py
|
||
|
new file mode 100644
|
||
|
index 00000000..1fc7dde4
|
||
|
--- /dev/null
|
||
|
+++ b/repos/system_upgrade/el7toel8/actors/checklegacygrub/actor.py
|
||
|
@@ -0,0 +1,20 @@
|
||
|
+from leapp.actors import Actor
|
||
|
+from leapp.libraries.actor import check_legacy_grub as check_legacy_grub_lib
|
||
|
+from leapp.reporting import Report
|
||
|
+from leapp.tags import FactsPhaseTag, IPUWorkflowTag
|
||
|
+
|
||
|
+
|
||
|
+class CheckLegacyGrub(Actor):
|
||
|
+ """
|
||
|
+ Check whether GRUB Legacy is installed in the MBR.
|
||
|
+
|
||
|
+ GRUB Legacy is deprecated since RHEL 7 in favour of GRUB2.
|
||
|
+ """
|
||
|
+
|
||
|
+ name = 'check_grub_legacy'
|
||
|
+ consumes = ()
|
||
|
+ produces = (Report,)
|
||
|
+ tags = (FactsPhaseTag, IPUWorkflowTag)
|
||
|
+
|
||
|
+ def process(self):
|
||
|
+ check_legacy_grub_lib.check_grub_disks_for_legacy_grub()
|
||
|
diff --git a/repos/system_upgrade/el7toel8/actors/checklegacygrub/libraries/check_legacy_grub.py b/repos/system_upgrade/el7toel8/actors/checklegacygrub/libraries/check_legacy_grub.py
|
||
|
new file mode 100644
|
||
|
index 00000000..d02c14f9
|
||
|
--- /dev/null
|
||
|
+++ b/repos/system_upgrade/el7toel8/actors/checklegacygrub/libraries/check_legacy_grub.py
|
||
|
@@ -0,0 +1,71 @@
|
||
|
+from leapp import reporting
|
||
|
+from leapp.exceptions import StopActorExecution
|
||
|
+from leapp.libraries.common import grub as grub_lib
|
||
|
+from leapp.libraries.stdlib import api, CalledProcessError, run
|
||
|
+from leapp.reporting import create_report
|
||
|
+
|
||
|
+# There is no grub legacy package on RHEL7, therefore, the system must have been upgraded from RHEL6
|
||
|
+MIGRATION_TO_GRUB2_GUIDE_URL = 'https://access.redhat.com/solutions/2643721'
|
||
|
+
|
||
|
+
|
||
|
+def has_legacy_grub(device):
|
||
|
+ try:
|
||
|
+ output = run(['file', '-s', device])
|
||
|
+ except CalledProcessError as err:
|
||
|
+ msg = 'Failed to determine the file type for the special device `{0}`. Full error: `{1}`'
|
||
|
+ api.current_logger().warning(msg.format(device, str(err)))
|
||
|
+
|
||
|
+ # According to `file` manpage, the exit code > 0 iff the file does not exists (meaning)
|
||
|
+ # that grub_lib.get_grub_devices() is unreliable for some reason (better stop the upgrade),
|
||
|
+ # or because the file type could not be determined. However, its manpage directly gives examples
|
||
|
+ # of file -s being used on block devices, so this should be unlikely - especially if one would
|
||
|
+ # consider that get_grub_devices was able to determine that it is a grub device.
|
||
|
+ raise StopActorExecution()
|
||
|
+
|
||
|
+ grub_legacy_version_string = 'GRUB version 0.94'
|
||
|
+ return grub_legacy_version_string in output['stdout']
|
||
|
+
|
||
|
+
|
||
|
+def check_grub_disks_for_legacy_grub():
|
||
|
+ # Both GRUB2 and Grub Legacy are recognized by `get_grub_devices`
|
||
|
+ grub_devices = grub_lib.get_grub_devices()
|
||
|
+
|
||
|
+ legacy_grub_devices = []
|
||
|
+ for device in grub_devices:
|
||
|
+ if has_legacy_grub(device):
|
||
|
+ legacy_grub_devices.append(device)
|
||
|
+
|
||
|
+ if legacy_grub_devices:
|
||
|
+ details = (
|
||
|
+ 'Leapp detected GRUB Legacy to be installed on the system. '
|
||
|
+ 'The GRUB Legacy bootloader is unsupported on RHEL7 and GRUB2 must be used instead. '
|
||
|
+ 'The presence of GRUB Legacy is possible on systems that have been upgraded from RHEL 6 in the past, '
|
||
|
+ 'but required manual post-upgrade steps have not been performed. '
|
||
|
+ 'Note that the in-place upgrade from RHEL 6 to RHEL 7 systems is in such a case '
|
||
|
+ 'considered as unfinished.\n\n'
|
||
|
+
|
||
|
+ 'GRUB Legacy has been detected on following devices:\n'
|
||
|
+ '{block_devices_fmt}\n'
|
||
|
+ )
|
||
|
+
|
||
|
+ hint = (
|
||
|
+ 'Migrate to the GRUB2 bootloader on the reported devices. '
|
||
|
+ 'Also finish other post-upgrade steps related to the previous in-place upgrade, the majority of which '
|
||
|
+ 'is a part of the related preupgrade report for upgrades from RHEL 6 to RHEL 7.'
|
||
|
+ 'If you are not sure whether all previously required post-upgrade steps '
|
||
|
+ 'have been performed, consider a clean installation of the RHEL 8 system instead. '
|
||
|
+ 'Note that the in-place upgrade to RHEL 8 can fail in various ways '
|
||
|
+ 'if the RHEL 7 system is misconfigured.'
|
||
|
+ )
|
||
|
+
|
||
|
+ block_devices_fmt = '\n'.join(legacy_grub_devices)
|
||
|
+ create_report([
|
||
|
+ reporting.Title("GRUB Legacy is used on the system"),
|
||
|
+ reporting.Summary(details.format(block_devices_fmt=block_devices_fmt)),
|
||
|
+ reporting.Severity(reporting.Severity.HIGH),
|
||
|
+ reporting.Groups([reporting.Groups.BOOT]),
|
||
|
+ reporting.Remediation(hint=hint),
|
||
|
+ reporting.Groups([reporting.Groups.INHIBITOR]),
|
||
|
+ reporting.ExternalLink(url=MIGRATION_TO_GRUB2_GUIDE_URL,
|
||
|
+ title='How to install GRUB2 after a RHEL6 to RHEL7 upgrade'),
|
||
|
+ ])
|
||
|
diff --git a/repos/system_upgrade/el7toel8/actors/checklegacygrub/tests/test_check_legacy_grub.py b/repos/system_upgrade/el7toel8/actors/checklegacygrub/tests/test_check_legacy_grub.py
|
||
|
new file mode 100644
|
||
|
index 00000000..d6e5008e
|
||
|
--- /dev/null
|
||
|
+++ b/repos/system_upgrade/el7toel8/actors/checklegacygrub/tests/test_check_legacy_grub.py
|
||
|
@@ -0,0 +1,45 @@
|
||
|
+import pytest
|
||
|
+
|
||
|
+from leapp.libraries.actor import check_legacy_grub as check_legacy_grub_lib
|
||
|
+from leapp.libraries.common import grub as grub_lib
|
||
|
+from leapp.libraries.common.testutils import create_report_mocked
|
||
|
+from leapp.utils.report import is_inhibitor
|
||
|
+
|
||
|
+VDA_WITH_LEGACY_GRUB = (
|
||
|
+ '/dev/vda: x86 boot sector; GRand Unified Bootloader, stage1 version 0x3, '
|
||
|
+ 'stage2 address 0x2000, stage2 segment 0x200, GRUB version 0.94; partition 1: ID=0x83, '
|
||
|
+ 'active, starthead 32, startsector 2048, 1024000 sectors; partition 2: ID=0x83, starthead 221, '
|
||
|
+ 'startsector 1026048, 19945472 sectors, code offset 0x48\n'
|
||
|
+)
|
||
|
+
|
||
|
+NVME0N1_VDB_WITH_GRUB = (
|
||
|
+ '/dev/nvme0n1: x86 boot sector; partition 1: ID=0x83, active, starthead 32, startsector 2048, 6291456 sectors; '
|
||
|
+ 'partition 2: ID=0x83, starthead 191, startsector 6293504, 993921024 sectors, code offset 0x63'
|
||
|
+)
|
||
|
+
|
||
|
+
|
||
|
+@pytest.mark.parametrize(
|
||
|
+ ('grub_device_to_file_output', 'should_inhibit'),
|
||
|
+ [
|
||
|
+ ({'/dev/vda': VDA_WITH_LEGACY_GRUB}, True),
|
||
|
+ ({'/dev/nvme0n1': NVME0N1_VDB_WITH_GRUB}, False),
|
||
|
+ ({'/dev/vda': VDA_WITH_LEGACY_GRUB, '/dev/nvme0n1': NVME0N1_VDB_WITH_GRUB}, True)
|
||
|
+ ]
|
||
|
+)
|
||
|
+def test_check_legacy_grub(monkeypatch, grub_device_to_file_output, should_inhibit):
|
||
|
+
|
||
|
+ def file_cmd_mock(cmd, *args, **kwargs):
|
||
|
+ assert cmd[:2] == ['file', '-s']
|
||
|
+ return {'stdout': grub_device_to_file_output[cmd[2]]}
|
||
|
+
|
||
|
+ monkeypatch.setattr(check_legacy_grub_lib, 'create_report', create_report_mocked())
|
||
|
+ monkeypatch.setattr(grub_lib, 'get_grub_devices', lambda: list(grub_device_to_file_output.keys()))
|
||
|
+ monkeypatch.setattr(check_legacy_grub_lib, 'run', file_cmd_mock)
|
||
|
+
|
||
|
+ check_legacy_grub_lib.check_grub_disks_for_legacy_grub()
|
||
|
+
|
||
|
+ assert bool(check_legacy_grub_lib.create_report.called) == should_inhibit
|
||
|
+ if should_inhibit:
|
||
|
+ assert len(check_legacy_grub_lib.create_report.reports) == 1
|
||
|
+ report = check_legacy_grub_lib.create_report.reports[0]
|
||
|
+ assert is_inhibitor(report)
|
||
|
--
|
||
|
2.42.0
|
||
|
|