From 504296802f3993459d13d82fdc67aa7d8bf8c8ca Mon Sep 17 00:00:00 2001 From: Ahmed Abdelhalim Date: Sat, 25 Jul 2026 23:58:48 +0200 Subject: Fix Mac dual-boot rEFInd never showing OS entries A legacy NVRAM entry (registered by an old refind-install run before --usedefault existed) points at EFI/refind/, a copy this role used to maintain for "Mac NVRAM compatibility". That mirroring predates the refind.conf split into per-distro includes (ubuntu.conf/archlinux.conf) and was never updated to copy them too, so the entry Mac actually boots by default could never show any OS menu entries. Drop the EFI/refind mirroring entirely and manage one explicit NVRAM entry pointing at EFI/BOOT/bootx64.efi instead: delete any existing "rEFInd Boot Manager" entries and recreate exactly one every run, so it never accumulates duplicates and self-heals whenever the partition GUID changes after a disk wipe. Avoids relying on Mac firmware's undocumented and noticeably slower fallback boot scan. Co-Authored-By: Claude.ai --- roles/bootstrap/tasks/install-archlinux-mac.yml | 48 ++++++++++++++----------- roles/bootstrap/tasks/install-ubuntu-mac.yml | 48 ++++++++++++++----------- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/roles/bootstrap/tasks/install-archlinux-mac.yml b/roles/bootstrap/tasks/install-archlinux-mac.yml index 9184207..a919827 100644 --- a/roles/bootstrap/tasks/install-archlinux-mac.yml +++ b/roles/bootstrap/tasks/install-archlinux-mac.yml @@ -1,27 +1,33 @@ --- -- name: "Ensure EFI/refind directory exists for Mac NVRAM compatibility" - ansible.builtin.file: - path: "{{ mnt_boot_path }}/EFI/refind" - state: directory - mode: "0755" - # Mac NVRAM entries persist across disk wipes (stored in firmware) and point to EFI/refind/ - # refind-install --usedefault only creates EFI/BOOT/ so we must create this explicitly - tags: ["molecule-notest"] +- name: "Find existing rEFInd NVRAM boot entries" + ansible.builtin.shell: + cmd: | + set -euo pipefail + efibootmgr | awk '/rEFInd Boot Manager/{print substr($1,5,4)}' + executable: /bin/bash + register: bootstrap_refind_boot_ids + changed_when: false -- name: "Copy rEFInd binary to EFI/refind for Mac NVRAM entries" - ansible.builtin.copy: - src: "{{ mnt_boot_path }}/EFI/BOOT/bootx64.efi" - dest: "{{ mnt_boot_path }}/EFI/refind/refind_x64.efi" - remote_src: true - mode: "0644" - tags: ["molecule-notest"] +- name: "Remove existing rEFInd NVRAM boot entries" + # Rebuilt fresh below instead of updated in place, so this never accumulates + # duplicate entries across reruns (each disk wipe changes the partition GUID + # efibootmgr encodes, so an old entry can never just be "updated"). + ansible.builtin.command: + cmd: "efibootmgr -b {{ item }} -B" + loop: "{{ bootstrap_refind_boot_ids.stdout_lines }}" + changed_when: true -- name: "Configure rEFInd base settings in EFI/refind for Mac NVRAM entries" - ansible.builtin.template: - src: "refind.conf.j2" - dest: "{{ mnt_boot_path }}/EFI/refind/refind.conf" - mode: "0644" - tags: ["molecule-notest"] +- name: "Register rEFInd NVRAM boot entry" + # Explicit NVRAM entry instead of relying on Mac firmware's fallback scan of + # EFI/BOOT/bootx64.efi, which is slow and its timing/reliability is undocumented. + ansible.builtin.command: + cmd: > + efibootmgr --create + --disk {{ partition_disk }} + --part {{ partition_boot.num }} + --loader '\EFI\BOOT\bootx64.efi' + --label "rEFInd Boot Manager" + changed_when: true - name: "Install broadcom-wl driver" ansible.builtin.command: diff --git a/roles/bootstrap/tasks/install-ubuntu-mac.yml b/roles/bootstrap/tasks/install-ubuntu-mac.yml index 69b9a88..5db9448 100644 --- a/roles/bootstrap/tasks/install-ubuntu-mac.yml +++ b/roles/bootstrap/tasks/install-ubuntu-mac.yml @@ -1,27 +1,33 @@ --- -- name: "Ensure EFI/refind directory exists for Mac NVRAM compatibility" - ansible.builtin.file: - path: "{{ mnt_boot_path }}/EFI/refind" - state: directory - mode: "0755" - # Mac NVRAM entries persist across disk wipes (stored in firmware) and point to EFI/refind/ - # refind-install --usedefault only creates EFI/BOOT/ so we must create this explicitly - tags: ["molecule-notest"] +- name: "Find existing rEFInd NVRAM boot entries" + ansible.builtin.shell: + cmd: | + set -euo pipefail + efibootmgr | awk '/rEFInd Boot Manager/{print substr($1,5,4)}' + executable: /bin/bash + register: bootstrap_refind_boot_ids + changed_when: false -- name: "Copy rEFInd binary to EFI/refind for Mac NVRAM entries" - ansible.builtin.copy: - src: "{{ mnt_boot_path }}/EFI/BOOT/bootx64.efi" - dest: "{{ mnt_boot_path }}/EFI/refind/refind_x64.efi" - remote_src: true - mode: "0644" - tags: ["molecule-notest"] +- name: "Remove existing rEFInd NVRAM boot entries" + # Rebuilt fresh below instead of updated in place, so this never accumulates + # duplicate entries across reruns (each disk wipe changes the partition GUID + # efibootmgr encodes, so an old entry can never just be "updated"). + ansible.builtin.command: + cmd: "efibootmgr -b {{ item }} -B" + loop: "{{ bootstrap_refind_boot_ids.stdout_lines }}" + changed_when: true -- name: "Configure rEFInd base settings in EFI/refind for Mac NVRAM entries" - ansible.builtin.template: - src: "refind.conf.j2" - dest: "{{ mnt_boot_path }}/EFI/refind/refind.conf" - mode: "0644" - tags: ["molecule-notest"] +- name: "Register rEFInd NVRAM boot entry" + # Explicit NVRAM entry instead of relying on Mac firmware's fallback scan of + # EFI/BOOT/bootx64.efi, which is slow and its timing/reliability is undocumented. + ansible.builtin.command: + cmd: > + efibootmgr --create + --disk {{ partition_disk }} + --part {{ partition_boot.num }} + --loader '\EFI\BOOT\bootx64.efi' + --label "rEFInd Boot Manager" + changed_when: true - name: "Install broadcom-sta-dkms in chroot" ansible.builtin.command: -- cgit v1.2.3