Files
Ansible-Bootstrap/roles/configuration/tasks/bootloader.yml

132 lines
5.3 KiB
YAML

---
- name: Configure Bootloader
vars:
_efi_vendor: >-
{{
"redhat" if os == "rhel"
else ("ubuntu" if os in ["ubuntu", "ubuntu-lts"] else os)
}}
_efi_loader: "{{ _configuration_platform.efi_loader }}"
block:
- name: Install GRUB EFI binary
when: _configuration_platform.grub_install
ansible.builtin.command: >-
{{ chroot_command }} /usr/sbin/grub-install --target=x86_64-efi
--efi-directory={{ partitioning_efi_mountpoint }}
--bootloader-id={{ _efi_vendor }}
--no-nvram
register: configuration_bootloader_result
changed_when: configuration_bootloader_result.rc == 0
- 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: Create EFI boot entry (efibootmgr -c prepends it to BootOrder)
ansible.builtin.command: >-
efibootmgr -c
-L '{{ _efi_vendor }}'
-d '{{ install_drive }}'
-p 1
-l '\EFI\{{ _efi_vendor }}\{{ _efi_loader }}'
register: configuration_efi_entry_result
changed_when: configuration_efi_entry_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"
ansible.builtin.lineinfile:
path: /mnt/etc/mkinitcpio.conf
regexp: "^(HOOKS=.*block)(?!.*lvm2)(.*)"
line: "\\1 lvm2\\2"
backrefs: true
- name: Regenerate initramfs
when: _configuration_platform.initramfs_cmd | length > 0
ansible.builtin.command: "{{ chroot_command }} {{ _configuration_platform.initramfs_cmd }}"
register: configuration_initramfs_result
changed_when: configuration_initramfs_result.rc == 0
- name: Generate grub config (RedHat)
when: os_family == 'RedHat'
ansible.builtin.command: >-
{{ chroot_command }} /usr/sbin/{{ _configuration_platform.grub_mkconfig_prefix }}
-o /boot/grub2/grub.cfg
register: configuration_grub_result
changed_when: configuration_grub_result.rc == 0
- name: Fix btrfs BLS boot variable in grub config
when:
- os_family == 'RedHat'
- system_cfg.filesystem == 'btrfs'
ansible.builtin.replace:
path: /mnt/boot/grub2/grub.cfg
regexp: 'search --no-floppy --fs-uuid --set=boot \S+'
replace: 'set boot=$root'
- name: Create EFI grub.cfg wrapper for RedHat
when: os_family == 'RedHat'
vars:
_grub2_path: >-
{{
'/grub2'
if (partitioning_separate_boot | bool)
else ('/@/boot/grub2' if system_cfg.filesystem == 'btrfs' else '/boot/grub2')
}}
ansible.builtin.shell:
cmd: |
set -o pipefail
uuid=$(grep -m1 'search.*--set=root' /mnt/boot/grub2/grub.cfg | grep -oP '[\da-f]{8}(-[\da-f]{4}){3}-[\da-f]{12}')
cat > /mnt{{ partitioning_efi_mountpoint }}/EFI/{{ _efi_vendor }}/grub.cfg <<GRUBEOF
search --no-floppy --fs-uuid --set=dev $uuid
set prefix=(\$dev){{ _grub2_path }}
export \$prefix
configfile \$prefix/grub.cfg
GRUBEOF
executable: /bin/bash
register: _grub_wrapper_result
changed_when: _grub_wrapper_result.rc == 0
- name: Generate grub config (non-RedHat)
when: os_family != 'RedHat'
ansible.builtin.command: "{{ chroot_command }} /usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg"
register: configuration_grub_result
changed_when: configuration_grub_result.rc == 0
- name: Rebuild GRUB as standalone EFI for Secure Boot
when:
- system_cfg.features.secure_boot.enabled | default(false) | bool
- os == 'archlinux'
ansible.builtin.command: >-
{{ chroot_command }} grub-mkstandalone
-d /usr/lib/grub/x86_64-efi
-O x86_64-efi
--disable-shim-lock
-o {{ partitioning_efi_mountpoint }}/EFI/{{ _efi_vendor }}/grubx64.efi
boot/grub/grub.cfg=/boot/grub/grub.cfg
register: _grub_standalone_result
changed_when: _grub_standalone_result.rc == 0