clawdie-iso/firstboot/zfs-pool-detect.sh
Sam & Claude 8cc7b2dcaf Wire ZFS pool detection into firstboot pipeline (Sam & Claude)
New shell-zfs.sh module: detects existing clawdie pool, presents
boot mode menu (install/upgrade/maintenance/shell). Runs as first
step in firstboot.sh before wizard. Upgrade mode loads existing
.env and skips wizard. Maintenance mode exec's to maintenance-mode.sh.

Also: fix POSIX herestrings in maintenance-mode.sh, fix paren
mismatch in snapshot age calc, add nda (NVMe) to disk detection
patterns across all ZFS scripts for FreeBSD 15.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 20:04:22 +02:00

149 lines
4.4 KiB
Bash

#!/bin/sh
# zfs-pool-detect.sh — Detect existing Clawdie pools and show boot menu
#
# This runs early in the USB boot process to detect existing
# clawdie pools and offer install/upgrade/maintenance options.
set -e
POOL_NAME="clawdie"
SHARE="/usr/local/share/clawdie-iso"
dialog() { bsddialog --backtitle "Clawdie USB Boot" "$@" ; }
die() { echo "ERROR: $1" >&2; exit 1; }
detect_pools() {
kldload zfs 2>/dev/null || true
local all_pools=$(zpool import 2>/dev/null | grep "pool:" | awk '{print $2}')
for pool in $all_pools; do
if [ "$pool" = "$POOL_NAME" ]; then
echo "$pool"
fi
done
}
get_pool_info() {
local pool=$1
local info=""
if zpool import $pool >/dev/null 2>&1; then
zpool import -o altroot=/tmp/pool-inspect $pool 2>/dev/null || true
local size=$(zpool list -Hp -o size $pool 2>/dev/null || echo "0")
local size_tb=$((size / 1099511627776))
local used=$(zpool list -Hp -o allocated $pool 2>/dev/null || echo "0")
local used_tb=$((used / 1099511627776))
local vdev_type=$(zpool status $pool 2>/dev/null | grep -A1 "config:" | head -1 | awk '{print $2}')
local disk_count=$(zpool status $pool 2>/dev/null | grep -E '^\s+(ada|da|nvd|nda)' | wc -l)
info="Pool: ${pool}\n"
info+="Type: ${vdev_type}, ${disk_count} disks\n"
info+="Size: ${used_tb} TB / ${size_tb} TB\n"
local status=$(zpool status $pool 2>/dev/null | grep "state:" | head -1 | awk '{print $2}')
info+="Status: ${status}\n"
if [ -f "/tmp/pool-inspect/home/clawdie/clawdie-ai/.env" ]; then
info+="Clawdie-AI: Detected\n"
fi
if [ -f "/tmp/pool-inspect/home/clawdie/clawdie-ai/VERSION" ]; then
local version=$(cat /tmp/pool-inspect/home/clawdie/clawdie-ai/VERSION)
info+="Version: ${version}\n"
fi
zpool export $pool 2>/dev/null || true
fi
echo "$info"
}
show_boot_menu() {
local clawdie_pool=$(detect_pools | head -1)
if [ -n "$clawdie_pool" ]; then
local pool_info=$(get_pool_info "$clawdie_pool")
local choice=$(dialog --menu \
"Clawdie Pool Detected\n\n${pool_info}\nSelect action:" \
16 70 4 \
"install" "Fresh install (destroy existing)" \
"upgrade" "Upgrade existing system" \
"maintenance" "Maintenance mode (cleanup, repair)" \
"shell" "Drop to shell (advanced)" \
3>&1 1>&2 2>&3)
case "$choice" in
"install")
local confirm=$(dialog --yesno \
"\n⚠ WARNING\n\nThis will DESTROY all data on pool '${clawdie_pool}'.\n\nAre you sure?" \
10 60)
if [ "$confirm" = "yes" ]; then
export CLAWDIE_BOOT_MODE="install"
return 0
else
show_boot_menu
fi
;;
"upgrade")
export CLAWDIE_BOOT_MODE="upgrade"
return 0
;;
"maintenance")
export CLAWDIE_BOOT_MODE="maintenance"
exec "${SHARE}/firstboot/maintenance-mode.sh"
;;
"shell")
exec /bin/sh
;;
*)
show_boot_menu
;;
esac
else
local choice=$(dialog --menu \
"No Clawdie Pool Found\n\nThis USB can:\n" \
12 60 3 \
"install" "Fresh install (create new pool)" \
"shell" "Drop to shell (advanced)" \
"reboot" "Reboot" \
3>&1 1>&2 2>&3)
case "$choice" in
"install")
export CLAWDIE_BOOT_MODE="install"
return 0
;;
"shell")
exec /bin/sh
;;
"reboot")
reboot
;;
*)
export CLAWDIE_BOOT_MODE="install"
return 0
;;
esac
fi
}
main() {
echo "Clawdie USB Boot - Pool Detection"
echo "========================================="
show_boot_menu
echo "Boot mode: $CLAWDIE_BOOT_MODE"
export CLAWDIE_BOOT_MODE
}
main "$@"