diff options
author | Jose M. Guisado <jguisado@soleta.eu> | 2023-08-16 14:25:49 +0200 |
---|---|---|
committer | Jose M. Guisado <jguisado@soleta.eu> | 2023-09-13 15:18:11 +0200 |
commit | a72ad3e637f1d4800bd80bf75d8a9a5847ae326a (patch) | |
tree | 43dc04b7a11f7b7a15fb49c36d1d2fea9fc030c1 /src | |
parent | 65f1cbc7eb8033d6dc9aca3c23feaf1cfc01ac04 (diff) |
utils: add boot.py
Add utility module related to the process of booting a system from a
client's partition.
The main utility function to boot a clients system is boot_os_at(), from
which firmware (UEFI or BIOS) and os-family specific private functions are invoked.
This initial commit adds UEFI windows boot function.
Diffstat (limited to 'src')
-rw-r--r-- | src/utils/boot.py | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/utils/boot.py b/src/utils/boot.py new file mode 100644 index 0000000..06ac2d7 --- /dev/null +++ b/src/utils/boot.py @@ -0,0 +1,60 @@ +# +# 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 json +import logging +import os +import shlex +import subprocess + +from src.utils.probe import OSFamily, get_os_family +from src.utils.disk import get_partition_device, get_efi_partition +from src.utils.uefi import * +from src.utils.fs import * + + +def _boot_uefi_windows(disk, part, mountpoint): + logging.info(f'Booting windows system') + bootlabel = f'Part-{disk:02d}-{part:02d}' + esp, esp_disk, esp_part_number = get_efi_partition(disk) + esp_mountpoint = esp.replace('dev', 'mnt') + if not mount_mkdir(esp, esp_mountpoint): + raise RuntimeError(f'Unable to mount detected EFI System Partition at {esp} into {esp_mountpoint}') + + for efi_app in [f'{esp_mountpoint}/EFI/{bootlabel}/Boot/bootmgfw.efi', + f'{esp_mountpoint}/EFI/Microsoft/Boot/bootmgfw.efi']: + if os.path.exists(efi_app): + loader = efi_app[len(esp_mountpoint):] + logging.info(f'Found bootloader at ESP partition: {loader}') + break + else: + raise RuntimeError(f'Unable to locate Windows EFI bootloader bootmgfw.efi') + + efibootmgr_delete_bootentry(bootlabel) + efibootmgr_create_bootentry(esp_disk, esp_part_number, loader, bootlabel) + efibootmgr_bootnext(bootlabel) + + umount(mountpoint) + +def boot_os_at(disk, part): + if not is_uefi_supported(): + raise NotImplementedError('BIOS booting is not implemented yet') + + device = get_partition_device(disk, part) + mountpoint = device.replace('dev', 'mnt') + if not mount_mkdir(device, mountpoint): + raise RuntimeError(f'Cannot probe OS family. Unable to mount {device} at {esp_mountpoint}.') + + logging.info(f'Booting system at {device}. Probing OS family...') + os_family = get_os_family(mountpoint) + if os_family == OSFamily.WINDOWS: + _boot_uefi_windows(disk, part, mountpoint) + elif os_family == OSFamily.LINUX: + raise NotImplementedError('WIP: Linux UEFI boot not implemented yet.') + else: + raise RuntimeError('Unknown OS family') |