198 lines
8.4 KiB
Python
198 lines
8.4 KiB
Python
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()
|