Stages/grub2: extend default config options

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 <thozza@redhat.com>
This commit is contained in:
Tomáš Hozza 2024-02-19 17:34:12 +01:00 committed by Tomáš Hozza
parent 84fc4c9903
commit be1ba5be08
2 changed files with 75 additions and 6 deletions

View file

@ -202,11 +202,24 @@ SCHEMA = """
"description": "Default boot entry",
"type": "string"
},
"disable_recovery": {
"type": "boolean"
},
"disable_submenu": {
"type": "boolean"
},
"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",
@ -214,6 +227,10 @@ SCHEMA = """
"minimum": 0,
"default": 0
},
"timeout_style": {
"type": "string",
"enum": ["hidden", "menu", "countdown"]
},
"serial": {
"description": "The command to configure the serial console",
"type": "string"
@ -371,10 +388,15 @@ class GrubConfig:
self.ignition = False
self.greenboot = False
self.kernel_opts = ""
self.disable_recovery = None
self.disable_submenu = None
self.distributor = None
self.serial = ""
self.terminal = None
self.terminal_input = None
self.terminal_output = None
self.timeout = 0
self.timeout_style = None
@property
def grubfs(self):
@ -472,9 +494,22 @@ class GrubConfig:
"GRUB_ENABLE_BLSCFG=true\n"
)
if self.disable_recovery is not None:
data += f"GRUB_DISABLE_RECOVERY={str(self.disable_recovery).lower()}\n"
if self.disable_submenu is not None:
data += f"GRUB_DISABLE_SUBMENU={str(self.disable_submenu).lower()}\n"
if self.distributor:
data += f'GRUB_DISTRIBUTOR="{self.distributor}"\n'
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'
@ -483,6 +518,9 @@ class GrubConfig:
val = " ".join(self.terminal_output)
data += f'GRUB_TERMINAL_OUTPUT="{val}"\n'
if self.timeout_style:
data += f'GRUB_TIMEOUT_STYLE={self.timeout_style}\n'
if self.default_entry is not None:
data += f'GRUB_DEFAULT={self.default_entry}\n'
@ -525,10 +563,15 @@ def main(tree, options):
config.ignition = ignition
config.greenboot = options.get("greenboot", False)
config.kernel_opts = kernel_opts
config.disable_recovery = cfg.get("disable_recovery")
config.disable_submenu = cfg.get("disable_submenu")
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")
config.default_entry = cfg.get("default")
# Create the configuration file that determines how grub.cfg is generated.

View file

@ -33,9 +33,9 @@ def test_grub2_copy_efi_data(tmp_path, stage_module):
# Test that the /etc/default/grub file is created with the correct content
@pytest.mark.parametrize("test_data,expected_conf", [
@pytest.mark.parametrize("test_data,kernel_opts,expected_conf", [
# default
({}, """GRUB_CMDLINE_LINUX=""
({}, "", """GRUB_CMDLINE_LINUX=""
GRUB_TIMEOUT=0
GRUB_ENABLE_BLSCFG=true
"""),
@ -46,16 +46,41 @@ GRUB_ENABLE_BLSCFG=true
"terminal_input": ["console"],
"terminal_output": ["serial"],
"serial": "serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1",
}, """GRUB_CMDLINE_LINUX=""
}, "", """GRUB_CMDLINE_LINUX=""
GRUB_TIMEOUT=10
GRUB_ENABLE_BLSCFG=true
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
GRUB_TERMINAL_INPUT="console"
GRUB_TERMINAL_OUTPUT="serial"
GRUB_DEFAULT=0
"""),
# custom (Azure)
({
"default": "saved",
"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",
},
"loglevel=3 crashkernel=auto console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300",
"""GRUB_CMDLINE_LINUX="loglevel=3 crashkernel=auto console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300"
GRUB_TIMEOUT=10
GRUB_ENABLE_BLSCFG=true
GRUB_DISABLE_RECOVERY=true
GRUB_DISABLE_SUBMENU=true
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"
GRUB_TIMEOUT_STYLE=countdown
GRUB_DEFAULT=saved
"""),
])
def test_grub2_default_conf(tmp_path, stage_module, test_data, expected_conf):
def test_grub2_default_conf(tmp_path, stage_module, test_data, kernel_opts, expected_conf):
treedir = tmp_path / "tree"
confpath = treedir / "etc/default/grub"
confpath.parent.mkdir(parents=True, exist_ok=True)
@ -77,6 +102,7 @@ def test_grub2_default_conf(tmp_path, stage_module, test_data, expected_conf):
}
options["config"] = test_data
options["kernel_opts"] = kernel_opts
stage_module.main(treedir, options)
assert os.path.exists(confpath)