import os import subprocess import sys import DiskLib #!/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 = DiskLib.ogDevToDisk(device) if DiskLib.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 = DiskLib.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()