diff --git a/roles/configuration/tasks/bootloader.yml b/roles/configuration/tasks/bootloader.yml index c0c842a..3484a67 100644 --- a/roles/configuration/tasks/bootloader.yml +++ b/roles/configuration/tasks/bootloader.yml @@ -18,13 +18,24 @@ register: configuration_bootloader_result changed_when: configuration_bootloader_result.rc == 0 - - name: Check existing EFI boot entries - ansible.builtin.command: efibootmgr - register: configuration_efi_entries - changed_when: false + - name: Remove stale EFI boot entries for this OS + # UEFI NVRAM entries survive a disk wipe (they live in firmware, not on disk). + # A prior install leaves a dead entry, and a case-insensitive duplicate label + # ("ArchLinux" vs "archlinux") would otherwise win the boot order - the firmware + # then falls through to removable media. Delete every entry carrying our label, + # then recreate exactly one clean entry. + ansible.builtin.shell: + cmd: >- + set -o pipefail; + efibootmgr | grep -iP '^Boot[0-9A-F]{4}\*?\s+{{ _efi_vendor }}\s*$' + | grep -oP '^Boot\K[0-9A-F]{4}' + | xargs -r -I{} efibootmgr -b {} -B + executable: /bin/bash + register: _efi_gc_result + changed_when: _efi_gc_result.stdout | length > 0 + failed_when: false - - name: Ensure EFI boot entry exists - when: ('* ' + _efi_vendor) not in configuration_efi_entries.stdout + - name: Create EFI boot entry (efibootmgr -c prepends it to BootOrder) ansible.builtin.command: >- efibootmgr -c -L '{{ _efi_vendor }}' @@ -34,15 +45,16 @@ register: configuration_efi_entry_result changed_when: configuration_efi_entry_result.rc == 0 - - name: Set installed OS as first EFI boot entry - ansible.builtin.shell: - cmd: >- - set -o pipefail && - efibootmgr | grep -i '{{ _efi_vendor }}' | grep -oP 'Boot\K[0-9A-F]+' | head -1 - | xargs -I{} efibootmgr -o {} - executable: /bin/bash - register: _efi_bootorder_result - changed_when: _efi_bootorder_result.rc == 0 + - name: Install removable EFI fallback loader + # Firmware-agnostic fallback (\EFI\BOOT\BOOTX64.EFI): many consumer firmwares + # ignore or reset custom NVRAM entries and boot only the removable path. + when: _configuration_platform.grub_install + ansible.builtin.command: >- + {{ chroot_command }} /usr/bin/install -Dm644 + {{ partitioning_efi_mountpoint }}/EFI/{{ _efi_vendor }}/{{ _efi_loader }} + {{ partitioning_efi_mountpoint }}/EFI/BOOT/BOOTX64.EFI + register: _efi_fallback_result + changed_when: _efi_fallback_result.rc == 0 - name: Ensure lvm2 for non btrfs filesystems when: os == "archlinux" and system_cfg.filesystem != "btrfs"