Template NM WAN pieces: netplan split, cellular keyfile, new host variables

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
This commit is contained in:
2026-09-23 18:27:19 -04:00
co-authored by Claude Sonnet 5
parent 640d6d245c
commit 65c0356463
9 changed files with 109 additions and 37 deletions
+22 -7
View File
@@ -9,6 +9,7 @@
# # POSTCHECK_WAIT=<s>: seconds retried probes may wait in total (default 15; 0 = single attempt)
# ./deploy.sh --classify-unit <ActiveState> <Result> <ExecMainStatus> # prints ok|finished|wait|warn (used by post_check; for tests)
# ./deploy.sh --classify-radio # reads `iw dev <if> info` text on stdin, prints beaconing|silent (no ssid line = silent; used by post_check; for tests)
# ./deploy.sh --render-wan-netplan # rendered /etc/netplan/50-van-wan.yaml (ethernet part + wifis stanza when WIFI_WAN_IFACE is set)
# ./deploy.sh render <file> # preview a templated file on stdout
# ./deploy.sh --redact # filter stdin, masking secret values (used by --diff; for tests)
# Idempotent. Netplan (wlan0 + Starlink NIC = NM-managed WANs; eth0 is a LAN
@@ -25,18 +26,20 @@ VANLINK_CONF=${VANLINK_CONF:-/etc/vanlink.conf}
# Must be defined (non-empty) in the host file; deploy aborts naming any missing.
REQUIRED_VARS=(
WIFI_5G_IFACE WIFI_2G_IFACE LAN_IFACE STARLINK_IFACE WIFI_WAN_IFACE
WIFI_5G_IFACE WIFI_2G_IFACE LAN_IFACE STARLINK_IFACE
GATEWAY_IP GATEWAY_PREFIX GATEWAY_NETWORK DHCP_RANGE_START DHCP_RANGE_END
DNS_RESOLVERS MODEM_USB_VENDOR AP_SSID_5G AP_SSID_2G AP_5G_RADIO
ENABLE_COCKPIT ENABLE_LI3 ENABLE_NVME_WATCH ENABLE_HA ENABLE_FRIGATE
ENABLE_NM_WAN
)
# May be empty or absent; NVME_* are required only when ENABLE_NVME_WATCH=1.
OPTIONAL_VARS=(
WIFI_WAN_IFACE CELLULAR_CONN_NAME CELLULAR_APN
ONBOARD_LAN_IFACE NVME_DEVICE NVME_FS_DEVICE
USB_BACKUP_ROOT_PART USB_BACKUP_MOUNT SD_BACKUP_UUID
)
# Computed in load_conf; usable as @TOKEN@ like the rest.
DERIVED_VARS=(ONBOARD_LAN_UNMANAGED)
DERIVED_VARS=(ONBOARD_LAN_UNMANAGED CELLULAR_UUID)
TOKEN_VARS=("${REQUIRED_VARS[@]}" "${OPTIONAL_VARS[@]}" "${DERIVED_VARS[@]}")
TOKEN_RE='@[A-Z][A-Z0-9_]*@'
@@ -53,7 +56,7 @@ load_conf() { # load_conf <file> — source and validate a host config
[ -n "${!v:-}" ] || missing+=("$v")
done
[ ${#missing[@]} -eq 0 ] || die "$f is missing required variable(s): ${missing[*]}"
for flag in ENABLE_COCKPIT ENABLE_LI3 ENABLE_NVME_WATCH ENABLE_HA ENABLE_FRIGATE; do
for flag in ENABLE_COCKPIT ENABLE_LI3 ENABLE_NVME_WATCH ENABLE_HA ENABLE_FRIGATE ENABLE_NM_WAN; do
case ${!flag} in
0|1) ;;
*) die "$f: $flag must be 0 or 1 (got '${!flag}')" ;;
@@ -64,6 +67,7 @@ load_conf() { # load_conf <file> — source and validate a host config
|| die "$f: ENABLE_NVME_WATCH=1 needs NVME_DEVICE and NVME_FS_DEVICE"
fi
ONBOARD_LAN_UNMANAGED=${ONBOARD_LAN_IFACE:+;interface-name:$ONBOARD_LAN_IFACE}
CELLULAR_UUID=$(uuidgen -s -n @dns -N "vanlink-${CELLULAR_CONN_NAME:-}" 2>/dev/null || true)
}
render() { # render <file> -> stdout, with @TOKEN@ placeholders substituted
@@ -74,6 +78,16 @@ render() { # render <file> -> stdout, with @TOKEN@ placeholders substituted
sed "${args[@]}" "$1"
}
# The netplan is two templates: ap/50-van-wan.yaml (ethernet/Starlink) and
# ap/50-van-wan-wifi.yaml (the wifis: stanza, appended verbatim only for hosts
# with a Wi-Fi uplink, so a host without one gets no empty/invalid wifis: block).
render_wan_netplan() { # ap/50-van-wan.yaml, plus the wifis stanza when the host has a Wi-Fi uplink
render ap/50-van-wan.yaml
if [ -n "${WIFI_WAN_IFACE:-}" ]; then
render ap/50-van-wan-wifi.yaml
fi
}
check_rendered() { # check_rendered <src> <rendered-file> — fail on a leftover @TOKEN@
local left
left=$(grep -oE "$TOKEN_RE" "$2" | sort -u | tr '\n' ' ') || true
@@ -277,6 +291,7 @@ case "${1:-}" in
--redact) # ./deploy.sh --redact — stdin through redact_secrets (no config, no root)
redact_secrets
exit 0 ;;
--render-wan-netplan) load_conf "$VANLINK_CONF"; render_wan_netplan; exit 0 ;;
--classify-unit) # ./deploy.sh --classify-unit <ActiveState> <Result> <ExecMainStatus>
classify_unit "${2:-}" "${3:-}" "${4:-}"
exit 0 ;;
@@ -365,10 +380,10 @@ echo "== netplan drift check =="
# see note below), so it's easy to edit ap/50-van-wan.yaml and forget the
# manual `netplan apply` step. Warn loudly rather than silently drifting.
if [ ! -f /etc/netplan/50-van-wan.yaml ]; then
warn "netplan: /etc/netplan/50-van-wan.yaml is missing — repo config was never deployed. Run: sudo ./deploy.sh render ap/50-van-wan.yaml | sudo tee /etc/netplan/50-van-wan.yaml && sudo netplan generate && sudo netplan apply"
elif ! diff -q <(render ap/50-van-wan.yaml) /etc/netplan/50-van-wan.yaml >/dev/null 2>&1; then
warn "netplan: /etc/netplan/50-van-wan.yaml differs from ap/50-van-wan.yaml (rendered). Deploy manually: sudo ./deploy.sh render ap/50-van-wan.yaml | sudo tee /etc/netplan/50-van-wan.yaml && sudo netplan generate && sudo netplan apply"
diff -u /etc/netplan/50-van-wan.yaml <(render ap/50-van-wan.yaml) || true
warn "netplan: /etc/netplan/50-van-wan.yaml is missing — repo config was never deployed. Run: sudo ./deploy.sh --render-wan-netplan | sudo tee /etc/netplan/50-van-wan.yaml && sudo netplan generate && sudo netplan apply"
elif ! diff -q <(render_wan_netplan) /etc/netplan/50-van-wan.yaml >/dev/null 2>&1; then
warn "netplan: /etc/netplan/50-van-wan.yaml differs from ap/50-van-wan.yaml (rendered). Deploy manually: sudo ./deploy.sh --render-wan-netplan | sudo tee /etc/netplan/50-van-wan.yaml && sudo netplan generate && sudo netplan apply"
diff -u /etc/netplan/50-van-wan.yaml <(render_wan_netplan) || true
fi
echo "== access point =="