From 7895424b785cb783367ce20d3a08c8a4afa2ef84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hozza?= Date: Mon, 19 Feb 2024 17:34:12 +0100 Subject: [PATCH] Stages/grub2.legacy: extend default config options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend the stage to allow explicitly configuring more grub2 default config options. Preserve the defaults for options which were previously hard-coded. Extend the stage unit test to verify setting of the new grub2 default config options. Related to https://issues.redhat.com/browse/RHEL-19583 Signed-off-by: Tomáš Hozza --- stages/org.osbuild.grub2.legacy | 39 ++++++++++++++++++--- stages/test/test_grub2_legacy.py | 59 +++++++++++++++++++++++++++----- 2 files changed, 85 insertions(+), 13 deletions(-) diff --git a/stages/org.osbuild.grub2.legacy b/stages/org.osbuild.grub2.legacy index 16e676ff..56b7e997 100755 --- a/stages/org.osbuild.grub2.legacy +++ b/stages/org.osbuild.grub2.legacy @@ -174,15 +174,26 @@ SCHEMA = """ "description": "Additional kernel command line options", "type": "string" }, + "disable_recovery": { + "type": "boolean", + "default": true + }, + "disable_submenu": { + "type": "boolean", + "default": true + }, "distributor": { "description": "Name of the distributor", "type": "string" }, + "terminal": { + "$ref": "#/definitions/terminal" + }, "terminal_input": { - "$ref": "#/definitions/terminal" + "$ref": "#/definitions/terminal" }, "terminal_output": { - "$ref": "#/definitions/terminal" + "$ref": "#/definitions/terminal" }, "timeout": { "description": "Timeout in seconds", @@ -190,6 +201,11 @@ SCHEMA = """ "minimum": 0, "default": 0 }, + "timeout_style": { + "type": "string", + "enum": ["hidden", "menu", "countdown"], + "default": "countdown" + }, "serial": { "description": "The command to configure the serial console", "type": "string" @@ -331,6 +347,7 @@ class GrubEntry: return entry +# pylint: disable=too-many-instance-attributes class GrubConfig: def __init__(self, bios, rootfs, bootfs): self.bios = bios @@ -338,11 +355,15 @@ class GrubConfig: self.bootfs = bootfs self.entries = [] self.cmdline = "" + self.disable_recovery = True + self.disable_submenu = True self.distributor = "" self.serial = "" + self.terminal = None self.terminal_input = None self.terminal_output = None self.timeout = 0 + self.timeout_style = "countdown" @property def grubfs(self): @@ -432,9 +453,9 @@ class GrubConfig: data = ( f"GRUB_TIMEOUT={self.timeout}\n" f'GRUB_CMDLINE_LINUX="{self.cmdline}"\n' - "GRUB_DISABLE_SUBMENU=true\n" - "GRUB_DISABLE_RECOVERY=true\n" - "GRUB_TIMEOUT_STYLE=countdown\n" + f"GRUB_DISABLE_SUBMENU={str(self.disable_submenu).lower()}\n" + f"GRUB_DISABLE_RECOVERY={str(self.disable_recovery).lower()}\n" + f"GRUB_TIMEOUT_STYLE={self.timeout_style}\n" "GRUB_DEFAULT=saved\n" ) @@ -444,6 +465,10 @@ class GrubConfig: if self.serial: data += f'GRUB_SERIAL_COMMAND="{self.serial}"\n' + if self.terminal: + val = " ".join(self.terminal) + data += f'GRUB_TERMINAL="{val}"\n' + if self.terminal_input: val = " ".join(self.terminal_input) data += f'GRUB_TERMINAL_INPUT="{val}"\n' @@ -467,11 +492,15 @@ def main(tree, options): cfg = options.get("config", {}) config = GrubConfig(bios, root_fs, boot_fs) config.cmdline = cfg.get("cmdline", "") + config.disable_recovery = cfg.get("disable_recovery", True) + config.disable_submenu = cfg.get("disable_submenu", True) config.distributor = cfg.get("distributor") config.serial = cfg.get("serial") + config.terminal = cfg.get("terminal") config.terminal_input = cfg.get("terminal_input") config.terminal_output = cfg.get("terminal_output") config.timeout = cfg.get("timeout", 0) + config.timeout_style = cfg.get("timeout_style", "countdown") config.entries = [GrubEntry.from_json(e) for e in options["entries"]] # Create the configuration file that determines how grub.cfg is generated. diff --git a/stages/test/test_grub2_legacy.py b/stages/test/test_grub2_legacy.py index 455188c2..5e0b346c 100644 --- a/stages/test/test_grub2_legacy.py +++ b/stages/test/test_grub2_legacy.py @@ -2,11 +2,58 @@ import os.path +import pytest + STAGE_NAME = "org.osbuild.grub2.legacy" # Test that the /etc/default/grub file is created with the correct content -def test_grub2_default_conf(tmp_path, stage_module): +@pytest.mark.parametrize("test_data,expected_conf", [ + # default + ({}, """GRUB_TIMEOUT=0 +GRUB_CMDLINE_LINUX="" +GRUB_DISABLE_SUBMENU=true +GRUB_DISABLE_RECOVERY=true +GRUB_TIMEOUT_STYLE=countdown +GRUB_DEFAULT=saved +"""), + # custom + ({ + "disable_submenu": False, + "disable_recovery": False, + "timeout": 10, + "timeout_style": "hidden", + }, """GRUB_TIMEOUT=10 +GRUB_CMDLINE_LINUX="" +GRUB_DISABLE_SUBMENU=false +GRUB_DISABLE_RECOVERY=false +GRUB_TIMEOUT_STYLE=hidden +GRUB_DEFAULT=saved +"""), + # custom (Azure) + ({ + "cmdline": "loglevel=3 crashkernel=auto console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300", + "disable_submenu": True, + "disable_recovery": True, + "distributor": "$(sed 's, release .*$,,g' /etc/system-release)", + "serial": "serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1", + "terminal": ["serial", "console"], + "terminal_output": ["console"], + "timeout": 10, + "timeout_style": "countdown", + }, """GRUB_TIMEOUT=10 +GRUB_CMDLINE_LINUX="loglevel=3 crashkernel=auto console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300" +GRUB_DISABLE_SUBMENU=true +GRUB_DISABLE_RECOVERY=true +GRUB_TIMEOUT_STYLE=countdown +GRUB_DEFAULT=saved +GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" +GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1" +GRUB_TERMINAL="serial console" +GRUB_TERMINAL_OUTPUT="console" +"""), +]) +def test_grub2_default_conf(tmp_path, stage_module, test_data, expected_conf): treedir = tmp_path / "tree" confpath = treedir / "etc/default/grub" confpath.parent.mkdir(parents=True, exist_ok=True) @@ -27,12 +74,8 @@ def test_grub2_default_conf(tmp_path, stage_module): ] } + options["config"] = test_data stage_module.main(treedir, options) + assert os.path.exists(confpath) - assert confpath.read_text() == """GRUB_TIMEOUT=0 -GRUB_CMDLINE_LINUX="" -GRUB_DISABLE_SUBMENU=true -GRUB_DISABLE_RECOVERY=true -GRUB_TIMEOUT_STYLE=countdown -GRUB_DEFAULT=saved -""" + assert confpath.read_text() == expected_conf