forked from rpms/leapp-repository
539 lines
19 KiB
Diff
539 lines
19 KiB
Diff
From 9966eb19daca97c18d798080c62af5638c1e0eab Mon Sep 17 00:00:00 2001
|
|
From: David Kubek <dkubek@redhat.com>
|
|
Date: Tue, 20 Aug 2024 12:57:42 +0200
|
|
Subject: [PATCH 46/66] Resolve boot issues in hybrid azure during upgrades
|
|
from RHEL 7 > 8 > 9.
|
|
|
|
This commit addresses the issue where the `/boot/grub2/grub.cfg` file is
|
|
overwritten during the upgrade process by an old RHEL7 configuration
|
|
leftover on the system, causing the system to fail to boot.
|
|
|
|
The problem occurs on hybrid Azure images, which support both UEFI and
|
|
Legacy systems and have both `grub-pc` and `grub-efi` packages installed.
|
|
It is caused by one of the scriplets in `grub-efi` which overwrites the old
|
|
configuration.
|
|
|
|
If old configuration is detected, this actor regenerates the grub
|
|
configuration using `grub2-mkconfig -o /boot/grub2/grub.cfg` after
|
|
installing rpms to ensure the correct boot configuration is in place.
|
|
|
|
The fix is applied specifically to Azure hybrid cloud systems.
|
|
|
|
JIRA: RHEL-38255
|
|
---
|
|
.../cloud/ensurevalidgrubcfghybrid/actor.py | 34 +++
|
|
.../libraries/ensurevalidgrubcfghybrid.py | 66 ++++++
|
|
.../tests/files/invalid_grub.cfg | 51 +++++
|
|
.../tests/files/valid_grub.cfg | 195 ++++++++++++++++++
|
|
.../tests/test_ensurevalidgrubcfghybrid.py | 124 +++++++++++
|
|
5 files changed, 470 insertions(+)
|
|
create mode 100644 repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/actor.py
|
|
create mode 100644 repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/libraries/ensurevalidgrubcfghybrid.py
|
|
create mode 100644 repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/files/invalid_grub.cfg
|
|
create mode 100644 repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/files/valid_grub.cfg
|
|
create mode 100644 repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/test_ensurevalidgrubcfghybrid.py
|
|
|
|
diff --git a/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/actor.py b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/actor.py
|
|
new file mode 100644
|
|
index 00000000..68de0433
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/actor.py
|
|
@@ -0,0 +1,34 @@
|
|
+from leapp.actors import Actor
|
|
+from leapp.libraries.actor import ensurevalidgrubcfghybrid
|
|
+from leapp.models import HybridImage
|
|
+from leapp.tags import ApplicationsPhaseTag, IPUWorkflowTag
|
|
+
|
|
+
|
|
+class EnsureValidGrubcfgHybrid(Actor):
|
|
+ """
|
|
+ Resolve boot failures in Azure Gen1 VMs during upgrades from RHEL 7 to RHEL 8 to RHEL 9.
|
|
+
|
|
+ This actor addresses the issue where the `/boot/grub2/grub.cfg` file is
|
|
+ overwritten during the upgrade process by an old RHEL7 configuration
|
|
+ leftover on the system, causing the system to fail to boot.
|
|
+
|
|
+ The problem occurs on hybrid Azure images, which support both UEFI and
|
|
+ Legacy systems and have both `grub-pc` and `grub-efi` packages installed.
|
|
+ It is caused by one of the scriplets in `grub-efi` which overwrites the old
|
|
+ configuration.
|
|
+
|
|
+ If old configuration is detected, this actor regenerates the grub
|
|
+ configuration using `grub2-mkconfig -o /boot/grub2/grub.cfg` after
|
|
+ installing rpms to ensure the correct boot configuration is in place.
|
|
+
|
|
+ The fix is applied specifically to Azure hybrid cloud systems.
|
|
+
|
|
+ """
|
|
+
|
|
+ name = 'ensure_valid_grubcfg_hybrid'
|
|
+ consumes = (HybridImage,)
|
|
+ produces = ()
|
|
+ tags = (ApplicationsPhaseTag, IPUWorkflowTag)
|
|
+
|
|
+ def process(self):
|
|
+ ensurevalidgrubcfghybrid.process()
|
|
diff --git a/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/libraries/ensurevalidgrubcfghybrid.py b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/libraries/ensurevalidgrubcfghybrid.py
|
|
new file mode 100644
|
|
index 00000000..127eccfc
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/libraries/ensurevalidgrubcfghybrid.py
|
|
@@ -0,0 +1,66 @@
|
|
+import re
|
|
+
|
|
+from leapp.exceptions import StopActorExecutionError
|
|
+from leapp.libraries.common.config.architecture import ARCH_ACCEPTED
|
|
+from leapp.libraries.stdlib import api, CalledProcessError, run
|
|
+from leapp.models import HybridImage
|
|
+
|
|
+GRUB_CFG_PATH = '/boot/grub2/grub.cfg'
|
|
+
|
|
+MATCH_ARCH = r'({})'.format('|'.join(ARCH_ACCEPTED))
|
|
+MATCH_RHEL7_KERNEL_VERSION = r"\d+\.\d+\.\d+-\d+(\.\d+)*\.el7\.{}".format(MATCH_ARCH)
|
|
+MATCH_RHEL7_KERNEL_DEFINITION = r"vmlinuz-{}".format(MATCH_RHEL7_KERNEL_VERSION)
|
|
+
|
|
+
|
|
+def process():
|
|
+ if not _is_hybrid_image():
|
|
+ api.current_logger().info('System is not a hybrid image. Skipping.')
|
|
+ return
|
|
+
|
|
+ grubcfg = _read_grubcfg()
|
|
+ if _is_grubcfg_invalid(grubcfg):
|
|
+ _run_grub2_mkconfig()
|
|
+
|
|
+
|
|
+def _is_hybrid_image():
|
|
+ return next(api.consume(HybridImage), None) is not None
|
|
+
|
|
+
|
|
+def _read_grubcfg():
|
|
+ api.current_logger().debug('Reading {}:'.format(GRUB_CFG_PATH))
|
|
+ with open(GRUB_CFG_PATH, 'r') as fin:
|
|
+ grubcfg = fin.read()
|
|
+
|
|
+ api.current_logger().debug(grubcfg)
|
|
+ return grubcfg
|
|
+
|
|
+
|
|
+def _is_grubcfg_invalid(grubcfg):
|
|
+ return _contains_rhel7_kernel_definition(grubcfg)
|
|
+
|
|
+
|
|
+def _contains_rhel7_kernel_definition(grubcfg):
|
|
+ api.current_logger().debug("Looking for RHEL7 kernel version ...")
|
|
+
|
|
+ match = re.search(MATCH_RHEL7_KERNEL_DEFINITION, grubcfg)
|
|
+
|
|
+ api.current_logger().debug(
|
|
+ "Matched: {}".format(match.group() if match else "[NO MATCH]")
|
|
+ )
|
|
+
|
|
+ return match is not None
|
|
+
|
|
+
|
|
+def _run_grub2_mkconfig():
|
|
+ api.current_logger().info("Regenerating {}".format(GRUB_CFG_PATH))
|
|
+
|
|
+ try:
|
|
+ run([
|
|
+ 'grub2-mkconfig',
|
|
+ '-o',
|
|
+ GRUB_CFG_PATH
|
|
+ ])
|
|
+ except CalledProcessError as err:
|
|
+ msg = 'Could not regenerate {}: {}'.format(GRUB_CFG_PATH, str(err))
|
|
+ api.current_logger().error(msg)
|
|
+ raise StopActorExecutionError(msg)
|
|
diff --git a/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/files/invalid_grub.cfg b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/files/invalid_grub.cfg
|
|
new file mode 100644
|
|
index 00000000..58f55c53
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/files/invalid_grub.cfg
|
|
@@ -0,0 +1,51 @@
|
|
+
|
|
+# Created by osbuild
|
|
+
|
|
+set timeout=10
|
|
+
|
|
+# load the grubenv file
|
|
+load_env
|
|
+
|
|
+# selection of the next boot entry
|
|
+if [ "${next_entry}" ] ; then
|
|
+ set default="${next_entry}"
|
|
+ set next_entry=
|
|
+ save_env next_entry
|
|
+ set boot_once=true
|
|
+else
|
|
+ set default="${saved_entry}"
|
|
+fi
|
|
+
|
|
+if [ "${prev_saved_entry}" ]; then
|
|
+ set saved_entry="${prev_saved_entry}"
|
|
+ save_env saved_entry
|
|
+ set prev_saved_entry=
|
|
+ save_env prev_saved_entry
|
|
+ set boot_once=true
|
|
+fi
|
|
+
|
|
+function savedefault {
|
|
+ if [ -z "${boot_once}" ]; then
|
|
+ saved_entry="${chosen}"
|
|
+ save_env saved_entry
|
|
+ fi
|
|
+}
|
|
+
|
|
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
|
|
+terminal_input serial console
|
|
+terminal_output serial console
|
|
+
|
|
+menuentry 'Red Hat Enterprise Linux Server (3.10.0-1160.119.1.el7.x86_64) 7.9 (Maipo)' --class red --class gnu-linux --class gnu --class os --unrestricted --id 'gnulinux-3.10.0-1160.99.1.el7.x86_64-advanced-76a22bf4-f153-4541-b6c7-0332c0dfaeac' {
|
|
+ insmod all_video
|
|
+ set gfxpayload=keep
|
|
+ search --no-floppy --set=root --fs-uuid 61779359-8d11-49ba-bc9d-8d038ee4b108
|
|
+ linuxefi /vmlinuz-3.10.0-1160.119.1.el7.x86_64 root=UUID=d3c9a2bd-7ffb-4113-9b8f-234c13b18274 ro crashkernel=auto console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300 scsi_mod.use_blk_mq=y LANG=en_US.UTF-8
|
|
+ initrdefi /initramfs-3.10.0-1160.119.1.el7.x86_64.img
|
|
+}
|
|
+menuentry 'Red Hat Enterprise Linux (3.10.0-1160.99.1.el7.x86_64) 7.9 (Maipo)' --class red --class gnu-linux --class gnu --class os --unrestricted --id 'gnulinux-3.10.0-1160.99.1.el7.x86_64-advanced-76a22bf4-f153-4541-b6c7-0332c0dfaeac' {
|
|
+ insmod all_video
|
|
+ set gfxpayload=keep
|
|
+ search --no-floppy --set=root --fs-uuid 61779359-8d11-49ba-bc9d-8d038ee4b108
|
|
+ linuxefi /vmlinuz-3.10.0-1160.99.1.el7.x86_64 root=UUID=d3c9a2bd-7ffb-4113-9b8f-234c13b18274 ro crashkernel=auto console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300 scsi_mod.use_blk_mq=y
|
|
+ initrdefi /initramfs-3.10.0-1160.99.1.el7.x86_64.img
|
|
+}
|
|
diff --git a/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/files/valid_grub.cfg b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/files/valid_grub.cfg
|
|
new file mode 100644
|
|
index 00000000..8192665e
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/files/valid_grub.cfg
|
|
@@ -0,0 +1,195 @@
|
|
+#
|
|
+# DO NOT EDIT THIS FILE
|
|
+#
|
|
+# It is automatically generated by grub2-mkconfig using templates
|
|
+# from /etc/grub.d and settings from /etc/default/grub
|
|
+#
|
|
+
|
|
+### BEGIN /etc/grub.d/00_header ###
|
|
+set pager=1
|
|
+
|
|
+if [ -f ${config_directory}/grubenv ]; then
|
|
+ load_env -f ${config_directory}/grubenv
|
|
+elif [ -s $prefix/grubenv ]; then
|
|
+ load_env
|
|
+fi
|
|
+if [ "${next_entry}" ] ; then
|
|
+ set default="${next_entry}"
|
|
+ set next_entry=
|
|
+ save_env next_entry
|
|
+ set boot_once=true
|
|
+else
|
|
+ set default="${saved_entry}"
|
|
+fi
|
|
+
|
|
+if [ x"${feature_menuentry_id}" = xy ]; then
|
|
+ menuentry_id_option="--id"
|
|
+else
|
|
+ menuentry_id_option=""
|
|
+fi
|
|
+
|
|
+export menuentry_id_option
|
|
+
|
|
+if [ "${prev_saved_entry}" ]; then
|
|
+ set saved_entry="${prev_saved_entry}"
|
|
+ save_env saved_entry
|
|
+ set prev_saved_entry=
|
|
+ save_env prev_saved_entry
|
|
+ set boot_once=true
|
|
+fi
|
|
+
|
|
+function savedefault {
|
|
+ if [ -z "${boot_once}" ]; then
|
|
+ saved_entry="${chosen}"
|
|
+ save_env saved_entry
|
|
+ fi
|
|
+}
|
|
+
|
|
+function load_video {
|
|
+ if [ x$feature_all_video_module = xy ]; then
|
|
+ insmod all_video
|
|
+ else
|
|
+ insmod efi_gop
|
|
+ insmod efi_uga
|
|
+ insmod ieee1275_fb
|
|
+ insmod vbe
|
|
+ insmod vga
|
|
+ insmod video_bochs
|
|
+ insmod video_cirrus
|
|
+ fi
|
|
+}
|
|
+
|
|
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
|
|
+terminal_input serial console
|
|
+terminal_output serial console
|
|
+if [ x$feature_timeout_style = xy ] ; then
|
|
+ set timeout_style=countdown
|
|
+ set timeout=10
|
|
+# Fallback hidden-timeout code in case the timeout_style feature is
|
|
+# unavailable.
|
|
+elif sleep --interruptible 10 ; then
|
|
+ set timeout=0
|
|
+fi
|
|
+### END /etc/grub.d/00_header ###
|
|
+
|
|
+### BEGIN /etc/grub.d/00_tuned ###
|
|
+set tuned_params=""
|
|
+set tuned_initrd=""
|
|
+### END /etc/grub.d/00_tuned ###
|
|
+
|
|
+### BEGIN /etc/grub.d/01_users ###
|
|
+if [ -f ${prefix}/user.cfg ]; then
|
|
+ source ${prefix}/user.cfg
|
|
+ if [ -n "${GRUB2_PASSWORD}" ]; then
|
|
+ set superusers="root"
|
|
+ export superusers
|
|
+ password_pbkdf2 root ${GRUB2_PASSWORD}
|
|
+ fi
|
|
+fi
|
|
+### END /etc/grub.d/01_users ###
|
|
+
|
|
+### BEGIN /etc/grub.d/08_fallback_counting ###
|
|
+insmod increment
|
|
+# Check if boot_counter exists and boot_success=0 to activate this behaviour.
|
|
+if [ -n "${boot_counter}" -a "${boot_success}" = "0" ]; then
|
|
+ # if countdown has ended, choose to boot rollback deployment,
|
|
+ # i.e. default=1 on OSTree-based systems.
|
|
+ if [ "${boot_counter}" = "0" -o "${boot_counter}" = "-1" ]; then
|
|
+ set default=1
|
|
+ set boot_counter=-1
|
|
+ # otherwise decrement boot_counter
|
|
+ else
|
|
+ decrement boot_counter
|
|
+ fi
|
|
+ save_env boot_counter
|
|
+fi
|
|
+### END /etc/grub.d/08_fallback_counting ###
|
|
+
|
|
+### BEGIN /etc/grub.d/10_linux ###
|
|
+insmod part_gpt
|
|
+insmod xfs
|
|
+set root='hd0,gpt2'
|
|
+if [ x$feature_platform_search_hint = xy ]; then
|
|
+ search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 61779359-8d11-49ba-bc9d-8d038ee4b108
|
|
+else
|
|
+ search --no-floppy --fs-uuid --set=root 61779359-8d11-49ba-bc9d-8d038ee4b108
|
|
+fi
|
|
+insmod part_gpt
|
|
+insmod xfs
|
|
+set boot='hd0,gpt2'
|
|
+if [ x$feature_platform_search_hint = xy ]; then
|
|
+ search --no-floppy --fs-uuid --set=boot --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 61779359-8d11-49ba-bc9d-8d038ee4b108
|
|
+else
|
|
+ search --no-floppy --fs-uuid --set=boot 61779359-8d11-49ba-bc9d-8d038ee4b108
|
|
+fi
|
|
+
|
|
+# This section was generated by a script. Do not modify the generated file - all changes
|
|
+# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
|
|
+#
|
|
+# The blscfg command parses the BootLoaderSpec files stored in /boot/loader/entries and
|
|
+# populates the boot menu. Please refer to the Boot Loader Specification documentation
|
|
+# for the files format: https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/.
|
|
+
|
|
+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu
|
|
+# entries populated from BootLoaderSpec files that use this variable work correctly even
|
|
+# without a grubenv file, define a fallback kernelopts variable if this has not been set.
|
|
+#
|
|
+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by
|
|
+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX
|
|
+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both
|
|
+# the kernelopts variable in the grubenv file and the fallback kernelopts variable.
|
|
+if [ -z "${kernelopts}" ]; then
|
|
+ set kernelopts="root=/dev/mapper/rootvg-rootlv ro ro crashkernel=auto console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300 scsi_mod.use_blk_mq=y "
|
|
+fi
|
|
+
|
|
+insmod blscfg
|
|
+blscfg
|
|
+### END /etc/grub.d/10_linux ###
|
|
+
|
|
+### BEGIN /etc/grub.d/10_reset_boot_success ###
|
|
+# Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry
|
|
+if [ "${boot_success}" = "1" -o "${boot_indeterminate}" = "1" ]; then
|
|
+ set menu_hide_ok=1
|
|
+else
|
|
+ set menu_hide_ok=0
|
|
+fi
|
|
+# Reset boot_indeterminate after a successful boot
|
|
+if [ "${boot_success}" = "1" ] ; then
|
|
+ set boot_indeterminate=0
|
|
+# Avoid boot_indeterminate causing the menu to be hidden more then once
|
|
+elif [ "${boot_indeterminate}" = "1" ]; then
|
|
+ set boot_indeterminate=2
|
|
+fi
|
|
+# Reset boot_success for current boot
|
|
+set boot_success=0
|
|
+save_env boot_success boot_indeterminate
|
|
+### END /etc/grub.d/10_reset_boot_success ###
|
|
+
|
|
+### BEGIN /etc/grub.d/12_menu_auto_hide ###
|
|
+### END /etc/grub.d/12_menu_auto_hide ###
|
|
+
|
|
+### BEGIN /etc/grub.d/20_linux_xen ###
|
|
+### END /etc/grub.d/20_linux_xen ###
|
|
+
|
|
+### BEGIN /etc/grub.d/20_ppc_terminfo ###
|
|
+### END /etc/grub.d/20_ppc_terminfo ###
|
|
+
|
|
+### BEGIN /etc/grub.d/30_os-prober ###
|
|
+### END /etc/grub.d/30_os-prober ###
|
|
+
|
|
+### BEGIN /etc/grub.d/30_uefi-firmware ###
|
|
+### END /etc/grub.d/30_uefi-firmware ###
|
|
+
|
|
+### BEGIN /etc/grub.d/40_custom ###
|
|
+# This file provides an easy way to add custom menu entries. Simply type the
|
|
+# menu entries you want to add after this comment. Be careful not to change
|
|
+# the 'exec tail' line above.
|
|
+### END /etc/grub.d/40_custom ###
|
|
+
|
|
+### BEGIN /etc/grub.d/41_custom ###
|
|
+if [ -f ${config_directory}/custom.cfg ]; then
|
|
+ source ${config_directory}/custom.cfg
|
|
+elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then
|
|
+ source $prefix/custom.cfg;
|
|
+fi
|
|
+### END /etc/grub.d/41_custom ###
|
|
diff --git a/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/test_ensurevalidgrubcfghybrid.py b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/test_ensurevalidgrubcfghybrid.py
|
|
new file mode 100644
|
|
index 00000000..c0fb0a0d
|
|
--- /dev/null
|
|
+++ b/repos/system_upgrade/el8toel9/actors/cloud/ensurevalidgrubcfghybrid/tests/test_ensurevalidgrubcfghybrid.py
|
|
@@ -0,0 +1,124 @@
|
|
+import os
|
|
+
|
|
+import pytest
|
|
+
|
|
+from leapp.exceptions import StopActorExecutionError
|
|
+from leapp.libraries.actor import ensurevalidgrubcfghybrid
|
|
+from leapp.libraries.common.testutils import CurrentActorMocked, logger_mocked
|
|
+from leapp.libraries.stdlib import api, CalledProcessError
|
|
+from leapp.models import HybridImage
|
|
+
|
|
+CUR_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
+
|
|
+
|
|
+def raise_call_error(args=None):
|
|
+ raise CalledProcessError(
|
|
+ message='A Leapp Command Error occurred.',
|
|
+ command=args,
|
|
+ result={'signal': None, 'exit_code': 1, 'pid': 0, 'stdout': 'fake', 'stderr': 'fake'}
|
|
+ )
|
|
+
|
|
+
|
|
+class run_mocked(object):
|
|
+ def __init__(self, raise_err=False):
|
|
+ self.called = 0
|
|
+ self.args = []
|
|
+ self.raise_err = raise_err
|
|
+
|
|
+ def __call__(self, *args):
|
|
+ self.called += 1
|
|
+ self.args.append(args)
|
|
+ if self.raise_err:
|
|
+ raise_call_error(args)
|
|
+
|
|
+
|
|
+def test_not_hybrid_image(monkeypatch):
|
|
+ """
|
|
+ Skip when system is not a hybrid.
|
|
+ """
|
|
+
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=[]))
|
|
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
|
+ monkeypatch.setattr(ensurevalidgrubcfghybrid, 'run', run_mocked(raise_err=False))
|
|
+
|
|
+ ensurevalidgrubcfghybrid.process()
|
|
+
|
|
+ assert api.current_logger.infomsg[0].startswith('System is not a hybrid image')
|
|
+ assert ensurevalidgrubcfghybrid.run.called == 0
|
|
+
|
|
+
|
|
+@pytest.mark.parametrize("is_invalid", [True, False])
|
|
+def test_is_grubcfg_valid(monkeypatch, is_invalid):
|
|
+
|
|
+ grubcfg_filename = ('invalid' if is_invalid else 'valid') + '_grub.cfg'
|
|
+ grubcfg_filepath = os.path.join(CUR_DIR, 'files', grubcfg_filename)
|
|
+ with open(grubcfg_filepath, 'r') as fin:
|
|
+ grubcfg = fin.read()
|
|
+
|
|
+ assert ensurevalidgrubcfghybrid._is_grubcfg_invalid(grubcfg) == is_invalid
|
|
+
|
|
+
|
|
+def test_valid_grubcfg(monkeypatch):
|
|
+ """
|
|
+ Test valid configuration does not trigger grub2-mkconfig
|
|
+ """
|
|
+
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=[HybridImage()]))
|
|
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
|
+ monkeypatch.setattr(ensurevalidgrubcfghybrid, 'run', run_mocked(raise_err=False))
|
|
+
|
|
+ grubcfg_filepath = os.path.join(CUR_DIR, 'files', 'valid_grub.cfg')
|
|
+ with open(grubcfg_filepath, 'r') as fin:
|
|
+ grubcfg = fin.read()
|
|
+
|
|
+ monkeypatch.setattr(ensurevalidgrubcfghybrid, '_read_grubcfg', lambda: grubcfg)
|
|
+
|
|
+ ensurevalidgrubcfghybrid.process()
|
|
+
|
|
+ assert ensurevalidgrubcfghybrid.run.called == 0
|
|
+
|
|
+
|
|
+def test_invalid_grubcfg(monkeypatch):
|
|
+ """
|
|
+ Test invalid configuration triggers grub2-mkconfig
|
|
+ """
|
|
+
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=[HybridImage()]))
|
|
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
|
+ monkeypatch.setattr(ensurevalidgrubcfghybrid, 'run', run_mocked(raise_err=False))
|
|
+
|
|
+ grubcfg_filepath = os.path.join(CUR_DIR, 'files', 'invalid_grub.cfg')
|
|
+ with open(grubcfg_filepath, 'r') as fin:
|
|
+ grubcfg = fin.read()
|
|
+
|
|
+ monkeypatch.setattr(ensurevalidgrubcfghybrid, '_read_grubcfg', lambda: grubcfg)
|
|
+
|
|
+ ensurevalidgrubcfghybrid.process()
|
|
+
|
|
+ assert ensurevalidgrubcfghybrid.run.called == 1
|
|
+ assert any(msg.startswith('Regenerating') for msg in api.current_logger.infomsg)
|
|
+
|
|
+
|
|
+def test_run_error(monkeypatch):
|
|
+ """
|
|
+ Test invalid configuration triggers grub2-mkconfig
|
|
+ """
|
|
+
|
|
+ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=[HybridImage()]))
|
|
+ monkeypatch.setattr(api, 'current_logger', logger_mocked())
|
|
+ monkeypatch.setattr(ensurevalidgrubcfghybrid, 'run', run_mocked(raise_err=True))
|
|
+
|
|
+ grubcfg_filepath = os.path.join(CUR_DIR, 'files', 'invalid_grub.cfg')
|
|
+ with open(grubcfg_filepath, 'r') as fin:
|
|
+ grubcfg = fin.read()
|
|
+
|
|
+ monkeypatch.setattr(ensurevalidgrubcfghybrid, '_read_grubcfg', lambda: grubcfg)
|
|
+
|
|
+ with pytest.raises(StopActorExecutionError):
|
|
+ ensurevalidgrubcfghybrid.process()
|
|
+
|
|
+ assert ensurevalidgrubcfghybrid.run.called == 1
|
|
+ assert any(
|
|
+ msg.startswith('Could not regenerate')
|
|
+ for msg in api.current_logger.err
|
|
+ )
|
|
--
|
|
2.50.1
|
|
|