ogclone-engine/client/shared/scripts/grubSyntax.py

196 lines
8.4 KiB
Python

import os
import subprocess
import sys
#!/usr/bin/env python3
def run_command(command):
result = subprocess.run(command, shell=True, capture_output=True, text=True)
return result.stdout.strip()
def copy_files(src, dest):
if os.path.exists(src):
subprocess.run(f"cp -r {src} {dest}", shell=True)
def prepare_grub_to_access_device(device):
loop_file = None
if device.startswith("/dev/loop"):
grub_loop_device = device.split('/')[-1]
loop_file = run_command(f"losetup {device} | sed -e 's/^[^(]*(\\([^)]\\+\\)).*/\\1/'")
if not loop_file.startswith("/dev"):
loop_device = device
device = run_command(f"{grub_probe} --target=device {loop_file}")
if "crypt" in run_command(f"dmsetup status {device}"):
print(f"{device} is a crypto device, which GRUB cannot read directly.")
return
abstraction = run_command(f"{grub_probe} --device {device} --target=abstraction")
for module in abstraction.split():
print(f"insmod {module}")
partmap = run_command(f"{grub_probe} --device {device} --target=partmap")
for module in partmap.split():
if module in ["netbsd", "openbsd"]:
print("insmod part_bsd")
else:
print(f"insmod part_{module}")
fs = run_command(f"{grub_probe} --device {device} --target=fs")
for module in fs.split():
print(f"insmod {module}")
if "nvme" in device:
d, p = ogDevToDisk(device)
if ogGetPartitionTableType(d) == "GPT":
nvme_device = f"hd{d-1},gpt{p}"
else:
nvme_device = f"hd{d-1},{p-1}"
print(f"set root='{nvme_device}'")
else:
print(f"set root='{run_command(f'{grub_probe} --device {device} --target=drive')}'")
if loop_file:
loop_mountpoint = run_command(f"awk '{loop_file} ~ \"^\"$2 && $2 != \"/\" {{ print $2 }}' /proc/mounts | tail -n1")
if loop_mountpoint:
print(f"loopback {grub_loop_device} {loop_file[len(loop_mountpoint):]}")
print(f"set root=({grub_loop_device})")
def main():
disk = part = kernel_param = None
if len(sys.argv) == 4:
disk, part, kernel_param = sys.argv[1:4]
elif len(sys.argv) == 3:
disk, part = sys.argv[1:3]
elif len(sys.argv) == 2:
kernel_param = sys.argv[1]
grub_probe = os.getenv("grub_probe", f"{os.getenv('OGBIN')}/grub-probe1.99_{os.uname().machine}")
if "1.99" in run_command("grub-install --version"):
copy_files("/opt/opengnsys/lib/os-probes/*", "/usr/lib/os-probes/")
else:
osprobe_ms_part = "/opt/opengnsys/lib/os-probes/mounted/efi/31part-x-y"
if os.path.isfile(osprobe_ms_part):
copy_files(osprobe_ms_part, "/usr/lib/os-probes/mounted/efi")
if os.path.exists(f"/opt/opengnsys/cache/boot/{oglivedir}/ogvmlinuz"):
subprocess.run(f"sed -i 's|/boot/{{oglivedir}}/ogvmlinuz |/vmlinuz |i' /usr/lib/linux-boot-probes/mounted/90fallback", shell=True)
subprocess.run(f"sed -i 's|/vmlinuz |/vmlinuz /boot/{{oglivedir}}/ogvmlinuz |1' /usr/lib/linux-boot-probes/mounted/90fallback", shell=True)
os.makedirs("/opt/opengnsys/cache/etc/", exist_ok=True)
with open("/opt/opengnsys/cache/etc/lsb-release", "w") as f:
f.write("DISTRIB_ID=Ubuntu\n")
f.write("DISTRIB_RELEASE= \n")
f.write(f"DISTRIB_CODENAME={oglivedir.split('-')[1]}\n")
f.write("DISTRIB_DESCRIPTION=OpenGnsys Live\n")
if disk:
os_search = ogDiskToDev(disk, part)
os_probed = run_command(f"os-prober | grep {os_search} | tr ' ' '^' | paste -s -d ' '")
else:
os_probed = run_command("os-prober | tr ' ' '^' | paste -s -d ' '")
if not os_probed:
adjust_timeout()
sys.exit(0)
for os_entry in os_probed.split():
device, longname, label, boot = os_entry.split(':')
longname = longname.replace('^', ' ')
label = label.replace('^', ' ')
if not longname:
longname = label
print(f"Found {longname} on {device}", file=sys.stderr)
if boot == "chain":
if "Windows" in longname:
if not wubi:
if os.path.exists("/usr/share/lupin-support/grub-mkimage") and run_command("/usr/share/lupin-support/grub-mkimage --test"):
wubi = "yes"
else:
wubi = "no"
if wubi == "yes":
print(f"Skipping {longname} on Wubi system", file=sys.stderr)
continue
label_class = ''.join(longname.lower().split()[:2])
print(f"menuentry \"{longname} (on {device})\" --class {label_class} --class windows {{")
save_default_entry()
prepare_grub_to_access_device(device)
if "Windows Vista" in longname or "Windows 7" in longname or "Windows Server 2008" in longname:
pass
else:
pass
print("chainloader +1")
print("}")
elif boot == "efi":
efipath = device.split('@')[1]
device = device.split('@')[0]
onstr = f"(on {device})"
print(f"menuentry '{longname} {onstr}' --class windows --class os {{")
save_default_entry()
prepare_grub_to_access_device(device)
print(f"chainloader {efipath}")
print("}")
elif boot == "linux":
linux_probed = run_command(f"linux-boot-prober {device} 2> /dev/null | tr ' ' '^' | paste -s -d ' '")
linux_probed = linux_probed.split()[0]
prepare_boot_cache = None
for linux_entry in linux_probed.split():
lroot, lboot, llabel, lkernel, linitrd, lparams = linux_entry.split(':')
llabel = llabel.replace('^', ' ')
lparams = lparams.replace('^', ' ')
uuid = run_command(f"blkid -s UUID -o value {lroot}")
lparams = lparams.replace(f"UUID={uuid}", lroot)
if not llabel:
llabel = longname
if lroot != lboot:
lkernel = lkernel.replace('/boot', '')
linitrd = linitrd.replace('/boot', '')
label_class = llabel.split()[0].lower()
print(f"menuentry \"{llabel} (on {device})\" --class {label_class} --class linux --class os {{")
save_default_entry()
if not prepare_boot_cache:
prepare_boot_cache = prepare_grub_to_access_device(lboot)
print(prepare_boot_cache)
if label_class == "opengnsys":
kernel_param = run_command("cat /proc/cmdline")
print(f"linux {lkernel} {lparams} {kernel_param}")
if linitrd:
print(f"initrd {linitrd}")
print("}")
elif boot == "macosx":
osx_uuid = run_command(f"grub-probe --target=fs_uuid --device {device} 2> /dev/null")
osx_entry("xnu_kernel", 32, device, longname, osx_uuid)
osx_entry("xnu_kernel64", 64, device, longname, osx_uuid)
elif boot == "hurd":
print(f"menuentry \"{longname} (on {device})\" --class hurd --class gnu --class os {{")
save_default_entry()
prepare_grub_to_access_device(device)
grub_device = run_command(f"{grub_probe} --device {device} --target=drive")
mach_device = grub_device.replace("(hd", "").replace(",msdos", "s")
grub_fs = run_command(f"{grub_probe} --device {device} --target=fs")
hurd_fs = grub_fs if grub_fs.endswith("fs") else f"{grub_fs}fs"
print(f"multiboot /boot/gnumach.gz root=device:{mach_device}")
print(f"module /hurd/{hurd_fs}.static {hurd_fs} --readonly \\")
print(f" --multiboot-command-line='{{kernel-command-line}}' \\")
print(f" --host-priv-port='{{host-port}}' \\")
print(f" --device-master-port='{{device-port}}' \\")
print(f" --exec-server-task='{{exec-task}}' -T typed '{{root}}' \\")
print(f" '{{task-create}}' '{{task-resume}}'")
print(f"module /lib/ld.so.1 exec /hurd/exec '{{exec-task=task-create}}'")
print("}")
else:
print(f" {longname} is not yet supported by grub-mkconfig.", file=sys.stderr)
adjust_timeout()
os.remove("/opt/opengnsys/cache/etc/lsb-release")
if __name__ == "__main__":
main()