Enhance provisioning documentation and scripts for improved network boot and DNS management</message>

<message>Add new documentation files for device DNS management via DHCP and dnsmasq configuration. Update cloud-init scripts to ensure proper handling of /etc/resolv.conf and DNS settings, allowing for seamless integration with file.server. Modify existing scripts to support dynamic LAN subnet configuration and improve overall network boot functionality. These changes enhance user experience and streamline the setup process for the CM4 eMMC provisioning service.
This commit is contained in:
nearxos
2026-03-04 19:15:38 +02:00
parent b5134098c0
commit 031e1c3415
16 changed files with 658 additions and 60 deletions

View File

@@ -17,8 +17,8 @@ exec >> "$LOG_FILE" 2>&1
# Configuration - adjust paths and size for your setup
RPIBOOT_DIR="${RPIBOOT_DIR:-/opt/usbboot}"
GOLDEN_IMAGE="${GOLDEN_IMAGE:-/var/lib/cm4-provisioning/golden.img}"
# Expected eMMC size in bytes. reTerminal DM (CM4) has 32 GB eMMC (~31268536320 bytes).
EMMC_SIZE_BYTES="${EMMC_SIZE_BYTES:-$(( 32 * 1024 * 1024 * 1024 ))}"
# Expected eMMC size in bytes (optional). If set, used to prefer among multiple new devices; if unset, any new block device after rpiboot is accepted (works for 8/16/32 GB CM4).
EMMC_SIZE_BYTES="${EMMC_SIZE_BYTES:-}"
LOG_TAG="cm4-flash"
STATUS_FILE="${STATUS_FILE:-/var/lib/cm4-provisioning/status.json}"
LOG_FILE="${LOG_FILE:-/var/lib/cm4-provisioning/flash.log}"
@@ -51,7 +51,7 @@ trap 'rm -f "$LOCK_FILE" "$CURRENT_DEVICE_FILE" "$DEVICE_SOURCE_FILE" 2>/dev/nul
ENABLE_FILE="${ENABLE_FILE:-/etc/cm4-provisioning/enabled}"
if [[ -n "$ENABLE_FILE" && ! -f "$ENABLE_FILE" ]]; then
log "Skipping: $ENABLE_FILE not present"
write_status "idle" "Provisioning disabled (remove /etc/cm4-provisioning/enabled to enable)" "null" 2>/dev/null || true
write_status "idle" "Provisioning disabled (touch /etc/cm4-provisioning/enabled to enable)" "null" 2>/dev/null || true
exit 0
fi
@@ -90,8 +90,8 @@ if [[ -z "$RPIBOOT_GADGET" ]]; then
write_status "error" "rpiboot gadget missing" "null" "Copy mass-storage-gadget(64) to $RPIBOOT_DIR"
exit 1
fi
# rpiboot requires bootfiles.bin or one of bootcode*.bin in the gadget dir; empty dir causes "No 'bootcode' files found"
if [[ ! -f "$RPIBOOT_GADGET/bootfiles.bin" && ! -f "$RPIBOOT_GADGET/bootcode.bin" && ! -f "$RPIBOOT_GADGET/bootcode4.bin" && ! -f "$RPIBOOT_GADGET/bootcode5.bin" ]]; then
# rpiboot requires bootfiles.bin, bootcode*.bin, or boot.img in the gadget dir; empty dir causes "No 'bootcode' files found"
if [[ ! -f "$RPIBOOT_GADGET/bootfiles.bin" && ! -f "$RPIBOOT_GADGET/bootcode.bin" && ! -f "$RPIBOOT_GADGET/bootcode4.bin" && ! -f "$RPIBOOT_GADGET/bootcode5.bin" && ! -f "$RPIBOOT_GADGET/boot.img" ]]; then
log "rpiboot gadget dir has no boot files: $RPIBOOT_GADGET (reinstall usbboot)"
write_status "error" "rpiboot gadget empty" "null" "No boot files in $RPIBOOT_GADGET. On the host run: fix-gadget-bootcode-on-host.sh (or from your machine: ssh root@HOST 'bash -s' < scripts/fix-gadget-bootcode-on-host.sh). See docs troubleshooting."
exit 1
@@ -104,51 +104,86 @@ write_status "rpiboot" "Connecting to CM4 in boot mode…" "0"
# Block devices before rpiboot (so we can detect new one after)
before_devs=$(lsblk -nd -o NAME 2>/dev/null | sort)
log "Starting rpiboot to expose CM4 eMMC as mass storage..."
# Run rpiboot with 90s timeout so we don't hang if it doesn't exit cleanly when device switches to mass storage
log "Starting rpiboot to expose CM4 eMMC as mass storage (gadget: $RPIBOOT_GADGET)..."
# Run rpiboot with 180s timeout so device has time to receive bootcode and switch to mass storage; -v for verbose
rpiboot_exit=0
timeout 90 "$RPIBOOT_BIN" -d "$RPIBOOT_GADGET" || rpiboot_exit=$?
timeout 180 "$RPIBOOT_BIN" -v -d "$RPIBOOT_GADGET" || rpiboot_exit=$?
# timeout returns 124 if killed by timeout; 0 or other if rpiboot exited on its own
if [[ "$rpiboot_exit" -eq 124 ]]; then
log "rpiboot timed out after 90s (device may have switched to mass storage)"
log "rpiboot timed out after 180s (device may have switched to mass storage)"
elif [[ "$rpiboot_exit" -ne 0 ]]; then
log "rpiboot exited with code $rpiboot_exit"
log "Common causes: (1) No device in USB boot mode — set eMMC disable jumper and use USB slave port. (2) Wrong USB port or cable. (3) Run on host: tail -50 /var/lib/cm4-provisioning/flash.log"
write_status "error" "rpiboot failed" "null" "rpiboot failed or no device connected. Check flash.log on host. Try unplug/replug USB."
exit 1
fi
echo "[$(date -Iseconds)] rpiboot finished (exit=$rpiboot_exit); starting device scan"
log "rpiboot completed; waiting for block device..."
log "rpiboot completed; waiting for new block device (any size — 8/16/32 GB CM4 supported)..."
write_status "rpiboot" "rpiboot done, waiting for block device…" "10"
# rpiboot exits when device switches to mass storage; udev may need several seconds to create /dev/sdX
# Poll for new block device for up to 30s (device switch can be slow)
# rpiboot exits when device switches to mass storage; udev may need many seconds to create /dev/sdX
# Dynamic detection: accept any NEW block device (not present before rpiboot). No fixed eMMC size required.
# When rpiboot timed out (124), device may still be switching — wait longer in that case
max_wait=60
[[ "$rpiboot_exit" -eq 124 ]] && max_wait=90
target_dev=""
for wait_sec in $(seq 2 2 10) $(seq 12 2 30); do
new_devs=""
for wait_sec in $(seq 2 2 20) $(seq 22 2 $max_wait); do
sleep 2
new_devs=""
for dev in /dev/sd[a-z] /dev/sd[a-z][a-z]; do
[[ -b "$dev" ]] || continue
[[ "$dev" =~ [0-9]$ ]] && continue
size=$(blockdev --getsize64 "$dev" 2>/dev/null || true)
if [[ -n "$size" ]]; then
if (( size >= EMMC_SIZE_BYTES * 95 / 100 && size <= EMMC_SIZE_BYTES * 105 / 100 )); then
target_dev=$dev
break 2
fi
if [[ -z "$target_dev" && "$before_devs" != *"${dev#/dev/}"* ]]; then
target_dev=$dev
fi
# Only consider devices that appeared after rpiboot (the CM4 eMMC)
if [[ "$before_devs" != *"${dev#/dev/}"* ]]; then
size=$(blockdev --getsize64 "$dev" 2>/dev/null || true)
[[ -n "$size" ]] && new_devs="$new_devs $dev:$size"
fi
done
[[ -n "$target_dev" ]] && break
new_devs="${new_devs# }"
if [[ -n "$new_devs" ]]; then
# One new device: use it (dynamic — works for any eMMC size)
# Multiple new devices: prefer one matching EMMC_SIZE_BYTES if set, else largest
if [[ "$new_devs" != *" "* ]]; then
target_dev="${new_devs%%:*}"
break
else
best_dev="" best_size=0 best_delta=999999999999
for entry in $new_devs; do
dev="${entry%%:*}"
size="${entry##*:}"
if [[ -z "$EMMC_SIZE_BYTES" || "$EMMC_SIZE_BYTES" -eq 0 ]]; then
# No size hint: take largest new device
[[ "$size" -gt "$best_size" ]] && { best_dev="$dev"; best_size="$size"; }
else
delta=$(( size - EMMC_SIZE_BYTES )); [[ "$delta" -lt 0 ]] && delta=$(( -delta ))
[[ "$delta" -lt "$best_delta" ]] && { best_dev="$dev"; best_delta="$delta"; }
fi
done
[[ -n "$best_dev" ]] && target_dev="$best_dev" && break
fi
fi
log "Waiting for block device... ${wait_sec}s"
write_status "rpiboot" "Waiting for eMMC block device… (${wait_sec}s)" "10"
done
log "Device scan complete. before_devs=[$before_devs] target_dev=[$target_dev]"
if [[ -n "$target_dev" ]]; then
detected_size=$(blockdev --getsize64 "$target_dev" 2>/dev/null || true)
log "Using $target_dev (size=${detected_size:-?} bytes, $(( ${detected_size:-0} / 1024 / 1024 / 1024 )) GB)"
fi
if [[ -z "$target_dev" ]]; then
log "No suitable block device found after rpiboot (expected ~${EMMC_SIZE_BYTES} bytes)"
write_status "error" "No eMMC device found" "null" "No suitable block device after rpiboot"
log "No new block device found after rpiboot"
log "Current block devices (for debugging):"
lsblk -nd -o NAME,SIZE,TYPE 2>/dev/null | while read -r line; do log " $line"; done
for d in /dev/sd[a-z] /dev/sd[a-z][a-z]; do
[[ -b "$d" ]] || continue
[[ "$d" =~ [0-9]$ ]] && continue
s=$(blockdev --getsize64 "$d" 2>/dev/null || true)
log " $d size=$s ($((${s:-0} / 1024 / 1024 / 1024)) GB)"
done
write_status "error" "No eMMC device found" "null" "No suitable block device after rpiboot. Check flash.log on host; unplug/replug and ensure eMMC disable jumper is set."
exit 1
fi