diff options
-rw-r--r-- | src/utils/bios.py | 53 | ||||
-rw-r--r-- | src/utils/boot.py | 18 |
2 files changed, 70 insertions, 1 deletions
diff --git a/src/utils/bios.py b/src/utils/bios.py new file mode 100644 index 0000000..e064ca0 --- /dev/null +++ b/src/utils/bios.py @@ -0,0 +1,53 @@ +# +# Copyright (C) 2023 Soleta Networks <info@soleta.eu> +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +import logging +import os + + +def get_grub_boot_params(mountpoint, device): + grub_conf = f'{mountpoint}/etc/default/grub' + res = [] + + with open(grub_conf, 'r') as f: + for line in f: + if line.find('=') == -1: + continue + key, value = line.split('=', 1) + if key == 'GRUB_CMDLINE_LINUX' or key == 'GRUB_CMDLINE_LINUE_DEFAULT': + value = value.replace('\n', '') + value = value.strip('"') + res.append(value) + res.append(f'root={device}') + return " ".join(res) + +def get_vmlinuz_path(mountpoint): + linuz_dir = os.path.join(mountpoint, 'boot') + target_file = None + + for file in sorted(os.listdir(linuz_dir)): + if file.startswith('vmlinuz-'): + target_file = file + + if not target_file: + raise FileNotFoundError('vmlinuz not found in {initrd_dir}') + + return os.path.join(linuz_dir, target_file) + +def get_initrd_path(mountpoint): + initrd_dir = os.path.join(mountpoint, 'boot') + target_file = None + + for file in sorted(os.listdir(initrd_dir)): + if file.startswith('initrd.img-') or file.startswith('initramfs-') and file.endswith('.img'): + target_file = file + + if not target_file: + raise FileNotFoundError('initrd not found in {initrd_dir}') + + return os.path.join(initrd_dir, target_file) diff --git a/src/utils/boot.py b/src/utils/boot.py index 07a29ba..724fc06 100644 --- a/src/utils/boot.py +++ b/src/utils/boot.py @@ -14,6 +14,7 @@ import subprocess from src.utils.probe import OSFamily, get_os_family, get_linux_distro_id, os_probe from src.utils.disk import get_partition_device, get_efi_partition +from src.utils.bios import * from src.utils.uefi import * from src.utils.fs import * @@ -27,7 +28,22 @@ def _boot_bios_linux(disk, part, mountpoint): if not get_linux_distro_id(mountpoint) == 'ubuntu': raise NotImplementedError(f'{os_probe(mountpoint)} detected, only Ubuntu is supported for legacy BIOS boot') - _boot_bios_legacy(disk, part, mountpoint) + kernel_path = get_vmlinuz_path(mountpoint) + initrd_path = get_initrd_path(mountpoint) + + device = get_partition_device(disk, part) + grub_boot_params = get_grub_boot_params(mountpoint, device) + + kexec_cmd = f'kexec -l {kernel_path} --append="{grub_boot_params}" --initrd="{initrd_path}"' + kexec_reboot_cmd = 'kexec -e' + + logging.info(f'Booting with: {kexec_cmd}') + try: + subprocess.run(shlex.split(kexec_cmd), check=True, text=True) + subprocess.run(shlex.split(kexec_reboot_cmd), check=True, text=True) + except subprocess.CalledProcessError as e: + logging.error(f'Error processing kexec: {e}') + raise e def _boot_bios_windows(disk, part, mountpoint): logging.info(f'Booting Windows system') |