Skip to content

Commit c26cf6f

Browse files
mparamas-zzclaude
andcommitted
ci: detect USB boot entry by scanning existing UEFI entries
bootable-usb-prepare.sh does not create a new UEFI boot entry, and the firmware's auto-created USB entry uses the USB controller device path (PciRoot/.../USB(...)) with no GPT PARTUUID. The old before/after diff and PARTUUID-only matching both found nothing and the stage errored. Replace with a scan of all existing entries, most specific first: PARTUUID of the target device, then dynamic model/vendor token from lsblk on TARGET_USB_DEVICE, then a generic "USB" description match. Verified against real efibootmgr -v output (resolves to the USB entry). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 43ef7ca commit c26cf6f

1 file changed

Lines changed: 36 additions & 18 deletions

File tree

Jenkinsfile

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -654,36 +654,54 @@ fi
654654
echo "Unmounting any partitions on ${USB_DEVICE}..."
655655
sudo umount ${USB_DEVICE}* 2>/dev/null || true
656656
657-
# Snapshot UEFI boot entries so we can identify the one the installer adds.
658-
BOOT_BEFORE=$(sudo efibootmgr | grep -oE '^Boot[0-9A-Fa-f]{4}' | sort -u || true)
659-
660657
echo "Running bootable-usb-prepare.sh on ${USB_DEVICE}..."
661658
sudo ./bootable-usb-prepare.sh "$USB_DEVICE" usb-bootable-files.tar.gz config-file
662659
663660
echo "Current UEFI boot entries:"
664661
sudo efibootmgr -v
662+
EFI_OUT=$(sudo efibootmgr -v)
663+
664+
# Identify the USB boot entry to boot from. bootable-usb-prepare.sh does NOT create a
665+
# new UEFI entry; the USB is reached via the firmware's auto-created removable entry,
666+
# whose device path is the USB controller (PciRoot/.../USB(...)) with no GPT PARTUUID.
667+
# So we scan all existing entries and pick the USB one, most specific match first.
668+
USB_ENTRY=""
669+
670+
# Strategy 1: match a partition PARTUUID of the target device (works if the installer
671+
# wrote an ESP the firmware indexed as HD(GPT,<partuuid>)).
672+
for uuid in $(lsblk -no PARTUUID "$USB_DEVICE" 2>/dev/null); do
673+
[ -z "$uuid" ] && continue
674+
m=$(echo "$EFI_OUT" | grep -iE "^Boot[0-9A-Fa-f]{4}.*${uuid}" | grep -oE '^Boot[0-9A-Fa-f]{4}' | head -1 | sed 's/^Boot//')
675+
if [ -n "$m" ]; then USB_ENTRY="$m"; echo "Matched USB boot entry by PARTUUID ${uuid}."; break; fi
676+
done
665677
666-
BOOT_AFTER=$(sudo efibootmgr | grep -oE '^Boot[0-9A-Fa-f]{4}' | sort -u || true)
667-
# Prefer a newly-created entry; fall back to matching the target device PARTUUID.
668-
NEW_ENTRY=$(comm -13 <(echo "$BOOT_BEFORE") <(echo "$BOOT_AFTER") | head -1 | sed 's/^Boot//')
669-
if [ -z "$NEW_ENTRY" ]; then
670-
echo "No new boot entry detected; matching by device PARTUUID..."
671-
for uuid in $(lsblk -no PARTUUID "$USB_DEVICE" 2>/dev/null); do
672-
[ -z "$uuid" ] && continue
673-
MATCH=$(sudo efibootmgr -v | grep -iE "Boot[0-9A-Fa-f]{4}.*${uuid}" | grep -oE '^Boot[0-9A-Fa-f]{4}' | head -1 | sed 's/^Boot//')
674-
if [ -n "$MATCH" ]; then NEW_ENTRY="$MATCH"; break; fi
678+
# Strategy 2: match by the target device's model/vendor tokens (ties the entry to THIS
679+
# exact USB drive, avoiding a wrong pick if several USB entries exist).
680+
if [ -z "$USB_ENTRY" ]; then
681+
MODELVEND="$(lsblk -dno MODEL "$USB_DEVICE" 2>/dev/null) $(lsblk -dno VENDOR "$USB_DEVICE" 2>/dev/null)"
682+
for tok in $(echo "$MODELVEND" | tr '_/.-' ' '); do
683+
[ ${#tok} -ge 4 ] || continue
684+
m=$(echo "$EFI_OUT" | grep -E '^Boot[0-9A-Fa-f]{4}' | grep -iF "$tok" | grep -oE '^Boot[0-9A-Fa-f]{4}' | head -1 | sed 's/^Boot//')
685+
if [ -n "$m" ]; then USB_ENTRY="$m"; echo "Matched USB boot entry by device token '${tok}'."; break; fi
675686
done
676687
fi
677-
if [ -z "$NEW_ENTRY" ]; then
678-
echo "ERROR: could not determine the installer UEFI boot entry automatically."
688+
689+
# Strategy 3: match the firmware's removable USB entry by "USB" in its description.
690+
if [ -z "$USB_ENTRY" ]; then
691+
m=$(echo "$EFI_OUT" | grep -E '^Boot[0-9A-Fa-f]{4}' | grep -iE 'usb' | grep -oE '^Boot[0-9A-Fa-f]{4}' | head -1 | sed 's/^Boot//')
692+
if [ -n "$m" ]; then USB_ENTRY="$m"; echo "Matched USB boot entry by 'USB' description."; fi
693+
fi
694+
695+
if [ -z "$USB_ENTRY" ]; then
696+
echo "ERROR: could not determine the USB installer UEFI boot entry automatically."
679697
echo " Inspect 'efibootmgr -v' above and set BootNext manually."
680698
exit 1
681699
fi
682-
echo "Installer UEFI boot entry: Boot${NEW_ENTRY}"
700+
echo "USB installer UEFI boot entry: Boot${USB_ENTRY}"
683701
684-
# One-time boot into the installer entry, then reboot (backgrounded so ssh returns first).
685-
sudo efibootmgr -n "$NEW_ENTRY"
686-
echo "BootNext set to ${NEW_ENTRY}. Rebooting the flashing host in 5s..."
702+
# One-time boot into the USB entry, then reboot (backgrounded so ssh returns first).
703+
sudo efibootmgr -n "$USB_ENTRY"
704+
echo "BootNext set to ${USB_ENTRY}. Rebooting the flashing host in 5s..."
687705
sudo bash -c 'nohup sh -c "sleep 5; reboot" >/dev/null 2>&1 &'
688706
echo "Reboot scheduled."
689707
REMOTE_SCRIPT

0 commit comments

Comments
 (0)