#!/usr/bin/python3
"""
Fix paths in /boot/loader/entries
Fixes paths in /boot/loader/entries that have incorrect paths for /boot.
This happens because some boot loader config tools (e.g. grub2-mkrelpath)
examine /proc/self/mountinfo to find the "real" path to /boot, and find the
path to the osbuild tree - which won't be valid at boot time for this image.
The paths in the Bootloader Specification are relative to the partition
they are located on, i.e. `/boot/loader/...` if `/boot` is on the root
file-system partition. If `/boot` is on a separate partition, the correct
path would be `/loader/.../` The `prefix` can be used to adjust for that.
By default it is `/boot`, i.e. assumes `/boot` is on the root file-system.
This stage reads and (re)writes all .conf files in /boot/loader/entries.
"""
import glob
import json
import re
import sys
SCHEMA = """
"additionalProperties": false,
"properties": {
"prefix": {
"description": "Prefix to use, normally `/boot`",
"type": "string",
"default": "/boot"
}
}
"""
def main(tree, options):
"""Fix broken paths in /boot/loader/entries.
grub2-mkrelpath uses /proc/self/mountinfo to find the source of the file
system it is installed to. This breaks in a container, because we
bind-mount the tree from the host.
"""
prefix = options.get("prefix", "/boot")
path_re = re.compile(r"(/.*)+/boot")
for name in glob.glob(f"{tree}/boot/loader/entries/*.conf"):
with open(name) as f:
entry = f.read().splitlines(keepends=True)
with open(name, "w") as f:
for line in entry:
f.write(path_re.sub(prefix, line))
return 0
if __name__ == '__main__':
args = json.load(sys.stdin)
r = main(args["tree"], args["options"])
sys.exit(r)