org.osbuild.grub2.iso.legacy: Add grub2 setup for booting BIOS ISO

This is the BIOS version of the grub2 iso stage. It installs the config
file and copies over the grub2 modules to /boot/grub2/
This commit is contained in:
Brian C. Lane 2024-12-04 11:10:42 -08:00 committed by Michael Vogt
parent 5a8b2edaa0
commit 41658da9cf
3 changed files with 157 additions and 0 deletions

View file

@ -7,6 +7,7 @@ import sys
import osbuild.api import osbuild.api
# The main grub2 configuration file template. Used for UEFI. # The main grub2 configuration file template. Used for UEFI.
# NOTE: Changes to this should also be applied to the org.osbuild.grub2.iso.legacy stage
GRUB2_EFI_CFG_TEMPLATE = """ GRUB2_EFI_CFG_TEMPLATE = """
function load_video { function load_video {
insmod efi_gop insmod efi_gop

View file

@ -0,0 +1,90 @@
#!/usr/bin/python3
import os
import shutil
import string
import sys
import osbuild.api
# The main grub2 configuration file template. Used for BIOS.
# NOTE: Changes to this should also be applied to the org.osbuild.grub2.iso stage
GRUB2_CFG_TEMPLATE = """
function load_video {
insmod all_video
}
load_video
set gfxpayload=keep
insmod gzio
insmod part_gpt
insmod ext2
insmod chain
set timeout=${timeout}
### END /etc/grub.d/00_header ###
search --no-floppy --set=root -l '${isolabel}'
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Install ${product} ${version}' --class fedora --class gnu-linux --class gnu --class os {
linux ${kernelpath} ${root} quiet
initrd ${initrdpath}
}
menuentry 'Test this media & install ${product} ${version}' --class fedora --class gnu-linux --class gnu --class os {
linux ${kernelpath} ${root} rd.live.check quiet
initrd ${initrdpath}
}
submenu 'Troubleshooting -->' {
menuentry 'Install ${product} ${version} in basic graphics mode' --class fedora --class gnu-linux --class gnu --class os {
linux ${kernelpath} ${root} nomodeset quiet
initrd ${initrdpath}
}
menuentry 'Rescue a ${product} system' --class fedora --class gnu-linux --class gnu --class os {
linux ${kernelpath} ${root} inst.rescue quiet
initrd ${initrdpath}
}
menuentry 'Boot first drive' --class fedora --class gnu-linux --class gnu --class os {
chainloader (hd0)+1
}
}
"""
def main(root, options):
name = options["product"]["name"]
version = options["product"]["version"]
isolabel = options["isolabel"]
kdir = options["kernel"].get("dir", "/images/pxeboot")
kopts = options["kernel"].get("opts")
cfg = options.get("config", {})
timeout = cfg.get("timeout", 60)
grub2dir = os.path.join(root, "boot", "grub2")
os.makedirs(grub2dir, exist_ok=True)
# grub2 modules
moduledir = os.path.join(grub2dir, "i386-pc")
shutil.copytree("/usr/lib/grub/i386-pc", moduledir, dirs_exist_ok=True)
print(f"kernel dir at {kdir}")
tplt = string.Template(GRUB2_CFG_TEMPLATE)
data = tplt.safe_substitute({
"version": version,
"product": name,
"kernelpath": os.path.join(kdir, "vmlinuz"),
"initrdpath": os.path.join(kdir, "initrd.img"),
"isolabel": isolabel,
"root": " ".join(kopts),
"timeout": timeout
})
config = os.path.join(grub2dir, "grub.cfg")
with open(config, "w", encoding="utf8") as cfg:
cfg.write(data)
if __name__ == '__main__':
args = osbuild.api.arguments()
ret = main(args["tree"], args["options"])
sys.exit(ret)

View file

@ -0,0 +1,66 @@
{
"summary": "Install a grub config and supporting files, suitable for a BIOS booting ISO",
"description": [],
"schema_2": {
"options": {
"additionalProperties": false,
"required": [
"product",
"kernel",
"isolabel"
],
"properties": {
"product": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"version"
],
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"kernel": {
"type": "object",
"required": [
"dir"
],
"properties": {
"dir": {
"type": "string"
},
"opts": {
"description": "Array options to append to the kernel command",
"type": "array",
"items": {
"type": "string"
}
}
}
},
"isolabel": {
"type": "string"
},
"config": {
"description": "Configuration options for grub itself",
"type": "object",
"additionalProperties": false,
"properties": {
"timeout": {
"description": "Timeout in seconds",
"type": "integer",
"minimum": 0,
"default": 60
}
}
}
}
}
}
}