auto flash
This commit is contained in:
parent
ede4100286
commit
9e48a99318
163
rebuild.sh
163
rebuild.sh
|
|
@ -1,8 +1,15 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
IMG="$HOME/Documents/toes-image-builder/toes-ubuntu-base.img"
|
IMG="$HOME/Documents/toes-image-builder/toes-ubuntu-base.img"
|
||||||
USBBOOT="$HOME/apps/forks/usbboot"
|
USBBOOT="$HOME/apps/forks/usbboot"
|
||||||
|
PROVISION_SCRIPT="${PROVISION_SCRIPT:-$SCRIPT_DIR/scripts/provision-device.sh}"
|
||||||
|
PROVISION_DEVICE_ID="${PROVISION_DEVICE_ID:-${DEVICE_ID:-device-001}}"
|
||||||
|
DEFAULT_SERIAL_LOGIN="toes"
|
||||||
|
DEFAULT_SERIAL_PASSWORD="nicetrywiseguy"
|
||||||
|
REBOOT_SETTLE_SECS="${REBOOT_SETTLE_SECS:-45}"
|
||||||
|
SERIAL_BOOT_TIMEOUT_SECS="${SERIAL_BOOT_TIMEOUT_SECS:-180}"
|
||||||
|
|
||||||
list_external_disks() {
|
list_external_disks() {
|
||||||
diskutil list external physical 2>/dev/null | awk '/^\/dev\/disk[0-9]+ / { sub("^/dev/", "", $1); print $1 }' | sort || true
|
diskutil list external physical 2>/dev/null | awk '/^\/dev\/disk[0-9]+ / { sub("^/dev/", "", $1); print $1 }' | sort || true
|
||||||
|
|
@ -12,6 +19,145 @@ disk_bytes() {
|
||||||
diskutil info "/dev/$1" | awk -F'[()]' '/Disk Size:/ { sub(/ Bytes.*/, "", $2); print $2; exit }'
|
diskutil info "/dev/$1" | awk -F'[()]' '/Disk Size:/ { sub(/ Bytes.*/, "", $2); print $2; exit }'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detect_serial_port() {
|
||||||
|
local pattern port
|
||||||
|
local -a matches
|
||||||
|
|
||||||
|
matches=()
|
||||||
|
for pattern in /dev/cu.usbserial\* /dev/cu.usbmodem\*; do
|
||||||
|
for port in $pattern; do
|
||||||
|
[[ -e "$port" ]] || continue
|
||||||
|
matches+=("$port")
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( ${#matches[@]} == 1 )); then
|
||||||
|
printf '%s\n' "${matches[0]}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( ${#matches[@]} > 1 )); then
|
||||||
|
echo "multiple serial ports detected; set SERIAL_PORT to one of:" >&2
|
||||||
|
printf ' %s\n' "${matches[@]}" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
matches=()
|
||||||
|
for pattern in /dev/tty.usbserial\* /dev/tty.usbmodem\*; do
|
||||||
|
for port in $pattern; do
|
||||||
|
[[ -e "$port" ]] || continue
|
||||||
|
matches+=("$port")
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( ${#matches[@]} == 1 )); then
|
||||||
|
printf '%s\n' "${matches[0]}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( ${#matches[@]} > 1 )); then
|
||||||
|
echo "multiple serial ports detected; set SERIAL_PORT to one of:" >&2
|
||||||
|
printf ' %s\n' "${matches[@]}" >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_serial_port() {
|
||||||
|
local port status
|
||||||
|
|
||||||
|
if [[ -n "${SERIAL_PORT:-}" ]]; then
|
||||||
|
[[ -e "$SERIAL_PORT" ]] || { echo "serial port does not exist: $SERIAL_PORT" >&2; return 1; }
|
||||||
|
printf '%s\n' "$SERIAL_PORT"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if port="$(detect_serial_port)"; then
|
||||||
|
printf '%s\n' "$port"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
status=$?
|
||||||
|
if (( status == 1 )); then
|
||||||
|
echo "no serial port detected; set SERIAL_PORT=/dev/cu.*" >&2
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_serial_port() {
|
||||||
|
local timeout="$1"
|
||||||
|
local deadline=$((SECONDS + timeout))
|
||||||
|
local port status
|
||||||
|
|
||||||
|
if [[ -n "${SERIAL_PORT:-}" ]]; then
|
||||||
|
while (( SECONDS < deadline )); do
|
||||||
|
[[ -e "$SERIAL_PORT" ]] && { printf '%s\n' "$SERIAL_PORT"; return 0; }
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "timed out waiting for serial port: $SERIAL_PORT" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while (( SECONDS < deadline )); do
|
||||||
|
if port="$(detect_serial_port 2>/dev/null)"; then
|
||||||
|
printf '%s\n' "$port"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
status=$?
|
||||||
|
if (( status == 2 )); then
|
||||||
|
detect_serial_port >/dev/null || true
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "timed out waiting for serial port; set SERIAL_PORT=/dev/cu.*" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_rpiboot_mass_storage() {
|
||||||
|
pkill -f 'rpiboot.*mass-storage-gadget' 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
reboot_target_over_serial() {
|
||||||
|
local port="$1"
|
||||||
|
|
||||||
|
echo "Requesting target reboot over $port"
|
||||||
|
stty -f "$port" 115200 raw -echo clocal 2>/dev/null || true
|
||||||
|
{
|
||||||
|
sleep 0.2
|
||||||
|
printf '\r'
|
||||||
|
sleep 0.5
|
||||||
|
printf 'root\r'
|
||||||
|
sleep 0.5
|
||||||
|
printf '\r'
|
||||||
|
sleep 0.5
|
||||||
|
printf 'sync\r'
|
||||||
|
sleep 0.5
|
||||||
|
printf 'reboot -f\r'
|
||||||
|
} >"$port"
|
||||||
|
}
|
||||||
|
|
||||||
|
provision_device() {
|
||||||
|
local port="$1"
|
||||||
|
local provision_login="${SERIAL_LOGIN:-$DEFAULT_SERIAL_LOGIN}"
|
||||||
|
local provision_password="${SERIAL_PASSWORD:-$DEFAULT_SERIAL_PASSWORD}"
|
||||||
|
local provision_prompt="${SERIAL_PROMPT:-${provision_login}@}"
|
||||||
|
|
||||||
|
[[ -x "$PROVISION_SCRIPT" ]] || { echo "provision script is not executable: $PROVISION_SCRIPT" >&2; return 1; }
|
||||||
|
|
||||||
|
echo "Provisioning $PROVISION_DEVICE_ID over $port"
|
||||||
|
SERIAL_PORT="$port" \
|
||||||
|
SERIAL_LOGIN="$provision_login" \
|
||||||
|
SERIAL_PASSWORD="$provision_password" \
|
||||||
|
SERIAL_PROMPT="$provision_prompt" \
|
||||||
|
SERIAL_LOGIN_TIMEOUT_SECS="${SERIAL_LOGIN_TIMEOUT_SECS:-$SERIAL_BOOT_TIMEOUT_SECS}" \
|
||||||
|
"$PROVISION_SCRIPT" "$PROVISION_DEVICE_ID"
|
||||||
|
}
|
||||||
|
|
||||||
if [[ "${SKIP_BUILD:-0}" != 1 ]]; then
|
if [[ "${SKIP_BUILD:-0}" != 1 ]]; then
|
||||||
ssh toes-image-builder 'cd toes-image-builder && ./build.sh && cp build/toes-ubuntu-base.img /mnt/utm/toes-image-builder/'
|
ssh toes-image-builder 'cd toes-image-builder && ./build.sh && cp build/toes-ubuntu-base.img /mnt/utm/toes-image-builder/'
|
||||||
fi
|
fi
|
||||||
|
|
@ -64,3 +210,20 @@ diskutil unmountDisk "/dev/$target"
|
||||||
sudo dd if="$IMG" of="/dev/r$target" bs=16m status=progress conv=fsync
|
sudo dd if="$IMG" of="/dev/r$target" bs=16m status=progress conv=fsync
|
||||||
sync
|
sync
|
||||||
diskutil eject "/dev/$target"
|
diskutil eject "/dev/$target"
|
||||||
|
|
||||||
|
if [[ "${SKIP_REBOOT:-0}" != 1 ]]; then
|
||||||
|
reboot_port="$(resolve_serial_port)"
|
||||||
|
stop_rpiboot_mass_storage
|
||||||
|
reboot_target_over_serial "$reboot_port"
|
||||||
|
echo "Waiting ${REBOOT_SETTLE_SECS}s for target to start booting..."
|
||||||
|
sleep "$REBOOT_SETTLE_SECS"
|
||||||
|
else
|
||||||
|
echo "Skipping target reboot because SKIP_REBOOT=1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${SKIP_PROVISION:-0}" != 1 ]]; then
|
||||||
|
provision_port="$(wait_for_serial_port "$SERIAL_BOOT_TIMEOUT_SECS")"
|
||||||
|
provision_device "$provision_port"
|
||||||
|
else
|
||||||
|
echo "Skipping provisioning because SKIP_PROVISION=1"
|
||||||
|
fi
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user