fix: UEFI boot fallback — search by file when label fails
The embedded GRUB EFI config only searched by volume label ARCHIPELAGO. Some UEFI firmware presents USB devices differently, causing the search to fail and GRUB to stall. Added fallbacks: 1. search --file /archipelago/auto-install.sh (known ISO file) 2. Fall back to $cmdpath (EFI partition itself) 3. Use configfile before normal for explicit config loading 4. Added search_fs_file module to grub-mkstandalone Also added same fallback to the main ISO grub.cfg. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -561,9 +561,10 @@ export INSTALLER_STARTED=1
|
||||
sleep 1
|
||||
clear
|
||||
echo ""
|
||||
echo -e "\033[1;37m a r c h i p e l a g o\033[0m"
|
||||
echo -e "\033[1;33m ━━━━━━━━━━━━━━━━━━━━━\033[0m"
|
||||
echo -e "\033[37m automatic installer\033[0m"
|
||||
echo -e "\033[38;5;208m ▄▀█ █▀▄ █▀▀ █ █ █ █▀█ █▀▀ █ ▄▀█ █▀▀ █▀█\033[0m"
|
||||
echo -e "\033[38;5;208m █▀█ █▀▄ █ █▀█ █ █▀▀ ██▀ █ █▀█ █ █ █ █\033[0m"
|
||||
echo -e "\033[38;5;208m ▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀\033[0m"
|
||||
echo -e " \033[38;5;130mbitcoin node os\033[0m"
|
||||
echo ""
|
||||
|
||||
BOOT_MEDIA=""
|
||||
@@ -687,19 +688,38 @@ mksquashfs /installer /output/filesystem.squashfs -comp xz -Xbcj x86 -noappend -
|
||||
echo " [container] Building GRUB EFI image..."
|
||||
cat > /tmp/grub-embed.cfg <<GRUBEMBED
|
||||
insmod part_gpt
|
||||
insmod part_msdos
|
||||
insmod fat
|
||||
insmod iso9660
|
||||
insmod search
|
||||
insmod search_label
|
||||
insmod search_fs_file
|
||||
insmod normal
|
||||
insmod linux
|
||||
insmod all_video
|
||||
|
||||
# Try label first (standard path)
|
||||
search --no-floppy --set=root --label ARCHIPELAGO
|
||||
|
||||
# Fallback: search for a known file on the ISO
|
||||
if [ -z "\$root" ]; then
|
||||
search --no-floppy --set=root --file /archipelago/auto-install.sh
|
||||
fi
|
||||
|
||||
# Fallback: try configfile from the EFI partition path
|
||||
if [ -z "\$root" ]; then
|
||||
set root=\$cmdpath
|
||||
fi
|
||||
|
||||
set prefix=(\$root)/boot/grub
|
||||
configfile (\$root)/boot/grub/grub.cfg
|
||||
|
||||
# If configfile fails, try normal
|
||||
normal
|
||||
GRUBEMBED
|
||||
|
||||
grub-mkstandalone -O x86_64-efi \
|
||||
--modules="part_gpt part_msdos fat iso9660 search search_label normal linux all_video font gfxterm configfile echo cat ls test true loopback png" \
|
||||
--modules="part_gpt part_msdos fat iso9660 search search_label search_fs_file normal linux all_video font gfxterm configfile echo cat ls test true loopback png" \
|
||||
--locales="" \
|
||||
--themes="" \
|
||||
--fonts="" \
|
||||
@@ -1405,81 +1425,56 @@ case "$(uname -m)" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# Colors (basic ANSI — works on bare-metal Linux console)
|
||||
# Colors — 256-color ANSI (works on Linux fbcon console)
|
||||
ORANGE=$'\033[38;5;208m'
|
||||
ORANGE_DIM=$'\033[38;5;130m'
|
||||
ORANGE_BRIGHT=$'\033[38;5;214m'
|
||||
RED=$'\033[31m'
|
||||
GREEN=$'\033[32m'
|
||||
YELLOW=$'\033[1;33m'
|
||||
ORANGE=$'\033[1;33m'
|
||||
DIM=$'\033[37m'
|
||||
CYAN=$'\033[36m'
|
||||
WHITE=$'\033[1;37m'
|
||||
DIM=$'\033[38;5;242m'
|
||||
DIMMER=$'\033[38;5;238m'
|
||||
NC=$'\033[0m'
|
||||
BOLD=$'\033[1m'
|
||||
|
||||
# Adaptive centering
|
||||
# Fixed left-margin layout (no more mixed centering)
|
||||
TW=$(tput cols 2>/dev/null || echo 60)
|
||||
[ "$TW" -gt 120 ] && TW=120
|
||||
cc() { local s=$(echo -e "$1" | sed 's/\x1b\[[0-9;]*m//g'); local p=$(( (TW - ${#s}) / 2 )); [ $p -lt 0 ] && p=0; printf "%*s" "$p" ""; echo -e "$1"; }
|
||||
hrule() { local len=$((TW > 50 ? 50 : TW - 4)); local hr=""; for i in $(seq 1 $len); do hr="${hr}─"; done; cc "${DIM}${hr}${NC}"; }
|
||||
[ "$TW" -gt 100 ] && TW=100
|
||||
PAD=$(( (TW - 50) / 2 ))
|
||||
[ "$PAD" -lt 0 ] && PAD=0
|
||||
PADS=$(printf "%*s" "$PAD" "")
|
||||
|
||||
box() {
|
||||
local bw=$((TW > 52 ? 52 : TW - 4))
|
||||
local inner=$((bw - 2))
|
||||
local top="╭"; local bot="╰"
|
||||
for i in $(seq 1 $inner); do top="${top}─"; bot="${bot}─"; done
|
||||
top="${top}╮"; bot="${bot}╯"
|
||||
cc "${DIM}${top}${NC}"
|
||||
}
|
||||
boxend() {
|
||||
local bw=$((TW > 52 ? 52 : TW - 4))
|
||||
local inner=$((bw - 2))
|
||||
local bot="╰"
|
||||
for i in $(seq 1 $inner); do bot="${bot}─"; done
|
||||
bot="${bot}╯"
|
||||
cc "${DIM}${bot}${NC}"
|
||||
}
|
||||
boxline() {
|
||||
local bw=$((TW > 52 ? 52 : TW - 4))
|
||||
local inner=$((bw - 2))
|
||||
local stripped=$(echo -e "$1" | sed 's/\x1b\[[0-9;]*m//g')
|
||||
local pad=$((inner - ${#stripped}))
|
||||
[ $pad -lt 0 ] && pad=0
|
||||
local right=""
|
||||
for i in $(seq 1 $pad); do right="${right} "; done
|
||||
cc "${DIM}│${NC} $1${right}${DIM}│${NC}"
|
||||
}
|
||||
p() { printf "%s%b\n" "$PADS" "$1"; }
|
||||
hrule() { local hr=""; for i in $(seq 1 48); do hr="${hr}*"; done; p "${ORANGE_DIM}${hr}${NC}"; }
|
||||
|
||||
# TUI helpers — Claude Code-inspired status display
|
||||
# Phase display
|
||||
STEP=0
|
||||
TOTAL_STEPS=8
|
||||
step() {
|
||||
STEP=$((STEP + 1))
|
||||
echo ""
|
||||
cc "${WHITE}[$STEP/$TOTAL_STEPS]${NC} ${DIM}$1${NC}"
|
||||
p "${ORANGE}[$STEP/$TOTAL_STEPS] $1${NC}"
|
||||
}
|
||||
ok() { cc " ${GREEN}$1${NC}"; }
|
||||
warn() { cc " ${YELLOW}$1${NC}"; }
|
||||
fail() { cc " ${RED}$1${NC}"; }
|
||||
ok() { p " ${ORANGE_BRIGHT}✓ $1${NC}"; }
|
||||
warn() { p " ${ORANGE}⚠ $1${NC}"; }
|
||||
fail() { p " ${RED}✗ $1${NC}"; }
|
||||
spinner() {
|
||||
local pid=$1 msg=$2
|
||||
local frames='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
|
||||
local i=0
|
||||
while kill -0 "$pid" 2>/dev/null; do
|
||||
printf "\r ${DIM}%s %s${NC}" "${frames:i%10:1}" "$msg"
|
||||
printf "\r%s %b%s %s%b" "$PADS" "$ORANGE" "${frames:i%10:1}" "$msg" "$NC"
|
||||
i=$((i + 1))
|
||||
sleep 0.1
|
||||
done
|
||||
printf "\r ${GREEN}✓ %s${NC}\n" "$msg"
|
||||
printf "\r%s %b✓ %s%b\n" "$PADS" "$ORANGE_BRIGHT" "$msg" "$NC"
|
||||
}
|
||||
|
||||
clear
|
||||
echo ""
|
||||
box
|
||||
boxline ""
|
||||
boxline "${WHITE}a r c h i p e l a g o${NC}"
|
||||
boxline "${ORANGE}━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
boxline "${DIM}automatic installation${NC}"
|
||||
boxline ""
|
||||
boxend
|
||||
echo -e " ${ORANGE}▄▀█ █▀▄ █▀▀ █ █ █ █▀█ █▀▀ █ ▄▀█ █▀▀ █▀█${NC}"
|
||||
echo -e " ${ORANGE}█▀█ █▀▄ █ █▀█ █ █▀▀ ██▀ █ █▀█ █ █ █ █${NC}"
|
||||
echo -e " ${ORANGE}▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀${NC}"
|
||||
echo -e " ${ORANGE_DIM}bitcoin node os${NC}"
|
||||
echo ""
|
||||
|
||||
# Check required tools are present (should be bundled in ISO)
|
||||
@@ -1582,9 +1577,9 @@ ok "$TARGET_DISK ($TARGET_SIZE)"
|
||||
echo ""
|
||||
hrule
|
||||
echo ""
|
||||
cc "${RED}all data on $TARGET_DISK will be erased${NC}"
|
||||
p "${ORANGE} ⚠ all data on $TARGET_DISK will be erased${NC}"
|
||||
echo ""
|
||||
cc "${DIM}press enter to install | ctrl+c to cancel${NC}"
|
||||
p "${ORANGE_DIM} press enter to install | ctrl+c to cancel${NC}"
|
||||
read -s
|
||||
echo ""
|
||||
|
||||
@@ -1631,7 +1626,7 @@ mkfs.ext4 -F -L archipelago "$ROOT_PART"
|
||||
# Mount root + extract rootfs (need cryptsetup from rootfs for LUKS)
|
||||
ok "Partitions created"
|
||||
echo ""
|
||||
cc "${DIM}Mounting filesystems...${NC}"
|
||||
p " ${ORANGE_DIM}Mounting filesystems...${NC}"
|
||||
mkdir -p /mnt/target
|
||||
mount "$ROOT_PART" /mnt/target
|
||||
mkdir -p /mnt/target/boot/efi
|
||||
@@ -1877,31 +1872,29 @@ if [ -t 0 ] && [ -z "$ARCHIPELAGO_WELCOMED" ]; then
|
||||
done
|
||||
|
||||
O='\033[38;5;208m'
|
||||
D='\033[38;5;242m'
|
||||
OD='\033[38;5;130m'
|
||||
W='\033[1;37m'
|
||||
N='\033[0m'
|
||||
|
||||
clear
|
||||
echo ""
|
||||
echo -e " ${O}█▀█ █▀▄ █▀▀ █ █ █ █▀▄▀█ █▀▀ █ █▀█ █▀▀ █▀█${N}"
|
||||
echo -e " ${O}█▀█ █▀▄ █ █▀█ █ █ ▀ █ ██▀ █ █▀█ █ █ █ █${N}"
|
||||
echo -e " ${O}▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀${N}"
|
||||
echo -e " ${D}bitcoin node os${N}"
|
||||
echo ""
|
||||
echo -e " ${O}▄▀█ █▀▄ █▀▀ █ █ █ █▀█ █▀▀ █ ▄▀█ █▀▀ █▀█${N}"
|
||||
echo -e " ${O}█▀█ █▀▄ █ █▀█ █ █▀▀ ██▀ █ █▀█ █ █ █ █${N}"
|
||||
echo -e " ${O}▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀${N}"
|
||||
echo -e " ${OD}bitcoin node os${N}"
|
||||
if [ -n "$IP" ]; then
|
||||
echo -e " ${D}web ui${N} http://$IP"
|
||||
echo -e " ${D}ssh${N} archipelago@$IP"
|
||||
echo -e " ${D}password${N} archipelago (SSH) / password123 (Web)"
|
||||
echo -e " ${W}web ui http://$IP${N}"
|
||||
echo -e " ${W}ssh archipelago@$IP${N}"
|
||||
echo -e " ${W}password archipelago (SSH) / password123 (Web)${N}"
|
||||
else
|
||||
echo -e " ${D}Waiting for network...${N}"
|
||||
echo -e " ${OD}Waiting for network...${N}"
|
||||
fi
|
||||
echo ""
|
||||
if [ -b /dev/mapper/archipelago-data ]; then
|
||||
echo -e " ${D}storage${N} LUKS2 encrypted"
|
||||
echo -e " ${OD}storage LUKS2 encrypted${N}"
|
||||
fi
|
||||
if systemctl is-active archipelago-kiosk.service >/dev/null 2>&1; then
|
||||
echo -e " ${D}display${N} Kiosk active (Ctrl+Alt+F1 for terminal)"
|
||||
echo -e " ${OD}display Kiosk active (Ctrl+Alt+F1 for terminal)${N}"
|
||||
else
|
||||
echo -e " ${D}display${N} Console (Ctrl+Alt+F7 for kiosk)"
|
||||
echo -e " ${OD}display Console (Ctrl+Alt+F7 for kiosk)${N}"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
@@ -2533,25 +2526,20 @@ cryptsetup close archipelago-data 2>/dev/null || true
|
||||
umount /mnt/target 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo -e " ${ORANGE}▄▀█ █▀▄ █▀▀ █ █ █ █▀█ █▀▀ █ ▄▀█ █▀▀ █▀█${NC}"
|
||||
echo -e " ${ORANGE}█▀█ █▀▄ █ █▀█ █ █▀▀ ██▀ █ █▀█ █ █ █ █${NC}"
|
||||
echo -e " ${ORANGE}▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀${NC}"
|
||||
echo -e " ${ORANGE_DIM}bitcoin node os${NC}"
|
||||
echo ""
|
||||
box
|
||||
boxline ""
|
||||
boxline "${WHITE}A R C H I P E L A G O${NC}"
|
||||
boxline "${GREEN}━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
boxline "${GREEN}Installation Complete${NC}"
|
||||
boxline ""
|
||||
boxend
|
||||
p "${ORANGE_BRIGHT} ✓ Installation Complete${NC}"
|
||||
echo ""
|
||||
cc "${DIM}After reboot, open the Web UI from any device on your network.${NC}"
|
||||
p "${ORANGE_DIM} After reboot, access from any device:${NC}"
|
||||
echo ""
|
||||
cc "${DIM}Web UI:${NC} ${WHITE}http://<this machine's IP>${NC}"
|
||||
cc "${DIM}SSH:${NC} ${DIM}ssh archipelago@<IP>${NC}"
|
||||
cc "${DIM}Password:${NC} ${DIM}archipelago${NC}"
|
||||
cc "${DIM}Web Login:${NC} ${DIM}password123${NC}"
|
||||
p "${ORANGE} http://<this machine's IP>${NC}"
|
||||
echo ""
|
||||
cc "${DIM}Pre-loaded apps (start via Web UI):${NC}"
|
||||
cc "${DIM}Bitcoin Knots, LND, Home Assistant,${NC}"
|
||||
cc "${DIM}BTCPay Server, Mempool, Nostr Relay${NC}"
|
||||
p "${WHITE} SSH ssh archipelago@<IP>${NC}"
|
||||
p "${WHITE} Password archipelago${NC}"
|
||||
p "${WHITE} Web Login password123${NC}"
|
||||
echo ""
|
||||
hrule
|
||||
echo ""
|
||||
@@ -2562,19 +2550,19 @@ echo 1 > /proc/sys/kernel/printk 2>/dev/null || true
|
||||
cat > /tmp/archipelago-reboot.sh <<'REBOOTSCRIPT'
|
||||
#!/bin/bash
|
||||
# This script runs from tmpfs — safe after USB removal
|
||||
TW=$(tput cols 2>/dev/null || echo 60)
|
||||
[ "$TW" -gt 120 ] && TW=120
|
||||
cc() { local s=$(echo -e "$1" | sed 's/\x1b\[[0-9;]*m//g'); local p=$(( (TW - ${#s}) / 2 )); [ $p -lt 0 ] && p=0; printf "%*s" "$p" ""; echo -e "$1"; }
|
||||
O=$'\033[38;5;208m'
|
||||
OD=$'\033[38;5;130m'
|
||||
N=$'\033[0m'
|
||||
|
||||
cc "\033[1;33m>>> REMOVE THE USB DRIVE NOW <<<\033[0m"
|
||||
echo -e " ${O}>>> REMOVE THE USB DRIVE NOW <<<${N}"
|
||||
echo ""
|
||||
cc "\033[37mPress Enter to reboot (or wait 30 seconds)\033[0m"
|
||||
echo -e " ${OD}Press Enter to reboot (or wait 30 seconds)${N}"
|
||||
|
||||
# Wait for Enter or timeout
|
||||
read -t 30 -s 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
cc "\033[37mRebooting...\033[0m"
|
||||
echo -e " ${OD}Rebooting...${N}"
|
||||
sleep 1
|
||||
reboot -f
|
||||
REBOOTSCRIPT
|
||||
@@ -2628,8 +2616,15 @@ insmod part_msdos
|
||||
insmod fat
|
||||
insmod iso9660
|
||||
insmod all_video
|
||||
insmod search
|
||||
insmod search_label
|
||||
insmod search_fs_file
|
||||
|
||||
# Find boot media — try label first, then known file fallback
|
||||
search --no-floppy --set=root --label ARCHIPELAGO
|
||||
if [ -z "$root" ]; then
|
||||
search --no-floppy --set=root --file /archipelago/auto-install.sh
|
||||
fi
|
||||
|
||||
set timeout=5
|
||||
set default=0
|
||||
|
||||
Reference in New Issue
Block a user