stages: add kernel-cmdline.bls-append stage

This adds a stage to be able to add kernel arguments on a system by
appending to the BLS [1] config directly either in the tree or in
a mount. This is useful on say systems that don't use `grubby` and
thus can't use the org.osbuild.kernel-cmdline stage.

[1] https://freedesktop.org/wiki/Specifications/BootLoaderSpec/
This commit is contained in:
Dusty Mabe 2023-11-06 20:01:39 -05:00 committed by Achilleas Koutsou
parent 5c345fb3fa
commit 52adfe01f7

View file

@ -0,0 +1,86 @@
#!/usr/bin/python3
"""
Add kernel command line parameters to a BLS [1] config either in
the tree or in a mount.
[1] https://freedesktop.org/wiki/Specifications/BootLoaderSpec/
"""
import glob
import sys
from urllib.parse import urlparse
import osbuild.api
SCHEMA_2 = r"""
"options": {
"additionalProperties": false,
"required": ["kernel_opts"],
"properties": {
"kernel_opts": {
"description": "Additional kernel command line options",
"type": "array",
"items": {
"description": "A single kernel command line option",
"type": "string"
}
},
"bootpath": {
"type": "string",
"description": "The mounted location of the boot filesystem tree where the BLS entries will be under ./loader/entries/*.conf",
"pattern": "^(mount|tree):\/\/\/",
"examples": ["tree:///boot", "mount:///", "mount:///boot"],
"default": "tree:///boot"
}
}
},
"devices": {
"type": "object",
"additionalProperties": true
},
"mounts": {
"type": "array"
}
"""
def main(paths, tree, options):
kopts = options.get("kernel_opts", [])
bootpath = options.get("bootpath", "tree:///boot")
url = urlparse(bootpath)
scheme = url.scheme
if scheme == "tree":
root = tree
elif scheme == "mount":
root = paths["mounts"]
else:
raise ValueError(f"Unsupported scheme '{scheme}'")
assert url.path.startswith("/")
bootroot = root + url.path
# There is unlikely to be more than one bls config, but just
# in case we'll iterate over them.
entries = []
for entry in glob.glob(f"{bootroot}/loader/entries/*.conf"):
entries.append(entry)
# Read in the file and then append to the options line.
with open(entry, encoding="utf8") as f:
lines = f.read().splitlines()
with open(entry, "w", encoding="utf8") as f:
for line in lines:
if line.startswith('options '):
f.write(f"{line} {' '.join(kopts)}\n")
else:
f.write(f"{line}\n")
assert len(entries) != 0
print(f"Added {','.join(kopts)} to: {','.join(entries)}")
return 0
if __name__ == '__main__':
args = osbuild.api.arguments()
r = main(args["paths"], args["tree"], args["options"])
sys.exit(r)