From afaf42e6469206e181f6373c1ded209217539e71 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Mon, 17 Jul 2023 00:14:44 +0200 Subject: Enable separate /boot and /boot/esp via XBOOTLDR in systemd-boot (#1859) * Disabled /boot check for now * Making '/boot' more dynamic * str() on boot_partition didn't work * _pacstrap -> pacman.strap() * Added 'finding' the EFI partition logic * f-string qotations * Locked down so get_boot_partition() looks for /boot and get_efi_partition() looks for /boot/efi - essentially hardcoding it for now, as there's no easy way to distinguish between the EFI partition or BOOT partition if they are both FAT32 for some reason. * Added some debugging output * Fixed some mypy complaints * Fixed PosixPath() vs str comparison * Changed FAT32 comparitor, should be FilesystemType.Fat32 now * Fixed PosixPath() vs str comparison * Re-ordered _add_systemd_bootloader() argument order, to match the other functions. This will cause the function to break on scripts that call this explicitly. * is_boot() now returns True if any type of valid boot flags are set, not just the 'Boot' flag. This allows us to check for XBOOTLDR flag as well. * Converted static INT to _ped.PARTITION_ definition. This matches the way pyparted checks for flags on partitions. * /boot/efi -> /boot/EFI (while the recommendation from bootctl is to mount it to /efi, I want to test it with custom paths first) * Removed _ped from mypy checks * flake8 fix * Added ESP flag to partitions * Added more docs in the docstring * Renamed *efi_partition to *xbootldr_partition within this PR changes * Naming collision, PartitionType -> PartitionGUIDs to avoid overwriting existing PartitionType * Check for XBOOTLDR instead of fixed EFI mountpoint in get_xbootldr_partition() * Mixed up XBOOTLDR and EFI partitions a bit, brought back get_efi_partition() which now filters out XBOOTLDR partitions and only returns a partition when there is a boot partition found by get_boot_partition() * Fixed symbiosis between get_boot() and get_efi() so that they don't report the same potential partition * Removed debugging code * Improved comments surrounding why /loader/ rather than /loader/ - this may change --- archinstall/lib/installer.py | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'archinstall/lib/installer.py') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 083bd7c9..9582df77 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -172,7 +172,7 @@ class Installer: ) def sanity_check(self): - self._verify_boot_part() + # self._verify_boot_part() self._verify_service_stop() def mount_ordered_layout(self): @@ -677,6 +677,12 @@ class Installer: else: raise ValueError(f"Archinstall currently only supports setting up swap on zram") + def _get_efi_partition(self) -> Optional[disk.PartitionModification]: + for layout in self._disk_config.device_modifications: + if partition := layout.get_efi_partition(): + return partition + return None + def _get_boot_partition(self) -> Optional[disk.PartitionModification]: for layout in self._disk_config.device_modifications: if boot := layout.get_boot_partition(): @@ -689,7 +695,12 @@ class Installer: return root return None - def _add_systemd_bootloader(self, root_partition: disk.PartitionModification): + def _add_systemd_bootloader( + self, + boot_partition: disk.PartitionModification, + root_partition: disk.PartitionModification, + efi_partition: Optional[disk.PartitionModification] + ): self.pacman.strap('efibootmgr') if not SysInfo.has_uefi(): @@ -698,15 +709,24 @@ class Installer: # TODO: Ideally we would want to check if another config # points towards the same disk and/or partition. # And in which case we should do some clean up. + bootctl_options = [ + f'--esp-path={efi_partition.mountpoint}' if efi_partition else '', + f'--boot-path={boot_partition.mountpoint}' if boot_partition else '' + ] # Install the boot loader try: - SysCommand(f'/usr/bin/arch-chroot {self.target} bootctl --esp-path=/boot install') + SysCommand(f"/usr/bin/arch-chroot {self.target} bootctl {' '.join(bootctl_options)} install") except SysCallError: # Fallback, try creating the boot loader without touching the EFI variables - SysCommand(f'/usr/bin/arch-chroot {self.target} bootctl --no-variables --esp-path=/boot install') + SysCommand(f"/usr/bin/arch-chroot {self.target} bootctl --no-variables {' '.join(bootctl_options)} install") - # Ensure that the /boot/loader directory exists before we try to create files in it + # Ensure that the $BOOT/loader/ directory exists before we try to create files in it. + # + # As mentioned in https://github.com/archlinux/archinstall/pull/1859 - we store the + # loader entries in $BOOT/loader/ rather than $ESP/loader/ + # The current reasoning being that $BOOT works in both use cases as well + # as being tied to the current installation. This may change. loader_dir = self.target / 'boot/loader' loader_dir.mkdir(parents=True, exist_ok=True) @@ -732,7 +752,7 @@ class Installer: else: loader.write(f"{line}\n") - # Ensure that the /boot/loader/entries directory exists before we try to create files in it + # Ensure that the $BOOT/loader/entries/ directory exists before we try to create files in it entries_dir = loader_dir / 'entries' entries_dir.mkdir(parents=True, exist_ok=True) @@ -836,12 +856,12 @@ class Installer: self.pacman.strap('efibootmgr') # TODO: Do we need? Yes, but remove from minimal_installation() instead? try: - SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --debug --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB --removable', peek_output=True) + SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --debug --target=x86_64-efi --efi-directory={boot_partition.mountpoint} --bootloader-id=GRUB --removable', peek_output=True) except SysCallError: try: - SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --debug --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB --removable', peek_output=True) + SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --debug --target=x86_64-efi --efi-directory={boot_partition.mountpoint} --bootloader-id=GRUB --removable', peek_output=True) except SysCallError as err: - raise DiskError(f"Could not install GRUB to {self.target}/boot: {err}") + raise DiskError(f"Could not install GRUB to {self.target}{boot_partition.mountpoint}: {err}") else: device = disk.device_handler.get_device_by_partition_path(boot_partition.safe_dev_path) @@ -861,7 +881,7 @@ class Installer: raise DiskError(f"Failed to install GRUB boot on {boot_partition.dev_path}: {err}") try: - SysCommand(f'/usr/bin/arch-chroot {self.target} grub-mkconfig -o /boot/grub/grub.cfg') + SysCommand(f'/usr/bin/arch-chroot {self.target} grub-mkconfig -o {boot_partition.mountpoint}/grub/grub.cfg') except SysCallError as err: raise DiskError(f"Could not configure GRUB: {err}") @@ -1055,6 +1075,7 @@ TIMEOUT=5 if plugin.on_add_bootloader(self): return True + efi_partition = self._get_efi_partition() boot_partition = self._get_boot_partition() root_partition = self._get_root_partition() @@ -1068,7 +1089,7 @@ TIMEOUT=5 match bootloader: case Bootloader.Systemd: - self._add_systemd_bootloader(root_partition) + self._add_systemd_bootloader(boot_partition, root_partition, efi_partition) case Bootloader.Grub: self._add_grub_bootloader(boot_partition, root_partition) case Bootloader.Efistub: -- cgit v1.2.3-54-g00ecf