deploy: hardware-instance templating, wlan0 boot watchdog, deploy-time warnings in Cockpit
- deploy.conf templates interface names/USB IDs (@TOKEN@ substitution) across ap/* configs so a dongle swap only needs deploy.conf edited, not the repo configs themselves; drops ap/rtw88.conf (old 2.4GHz dongle retired for the DWA-171, which needs no such power-save override). - failover/van-wlan-watchdog: recovers wlan0 from NM's post-boot no-secrets wedge (a boot-time supplicant race, not a real credential failure). - deploy.sh: warn() collects dependency/config warnings (missing python3-gps, python3-paho-mqtt, mobile-broadband-provider-info, grpcurl, gpsd; netplan drift; unedited example configs) into /var/lib/vanlink/deploy-warnings.json, rendered as an amber Cockpit card so they're visible without reading deploy output. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
8d5415f326
commit
5d88e1b30c
@@ -1,49 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deploy vanlink configs/scripts (Pi 4 "wan" port) to their system locations.
|
||||
# Usage: cd ~/vanlink && sudo ./deploy.sh
|
||||
# sudo ./deploy.sh render <file> # preview a templated file on stdout
|
||||
# Idempotent. Netplan (wlan0 + Starlink NIC = NM-managed WANs; eth0 is a LAN
|
||||
# port on br0) is NOT deployed here — reference copy in ap/50-van-wan.yaml,
|
||||
# applied once manually (apply flaps uplinks). We do check it for drift below.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$(readlink -f "$0")")"
|
||||
|
||||
# deploy.conf holds hardware-instance identifiers (interface names, USB vendor
|
||||
# IDs) that change when a dongle/adapter gets physically swapped. Config files
|
||||
# below carry @TOKEN@ placeholders substituted from these variables via
|
||||
# render()/install_rendered() — edit deploy.conf, not the individual configs.
|
||||
set -a
|
||||
source ./deploy.conf
|
||||
set +a
|
||||
|
||||
render() { # render <file> -> stdout, with @TOKEN@ placeholders substituted
|
||||
sed -e "s|@WIFI_5G_IFACE@|$WIFI_5G_IFACE|g" \
|
||||
-e "s|@WIFI_2G_IFACE@|$WIFI_2G_IFACE|g" \
|
||||
-e "s|@LAN_USB_IFACE@|$LAN_USB_IFACE|g" \
|
||||
-e "s|@STARLINK_IFACE@|$STARLINK_IFACE|g" \
|
||||
-e "s|@MODEM_USB_VENDOR@|$MODEM_USB_VENDOR|g" \
|
||||
"$1"
|
||||
}
|
||||
install_rendered() { # install_rendered <src> <dst> [mode]
|
||||
local tmp
|
||||
tmp=$(mktemp)
|
||||
render "$1" > "$tmp"
|
||||
install -D -m"${3:-0644}" "$tmp" "$2"
|
||||
rm -f "$tmp"
|
||||
}
|
||||
|
||||
if [ "${1:-}" = "render" ]; then
|
||||
[ -n "${2:-}" ] || { echo "Usage: $0 render <file>"; exit 1; }
|
||||
render "$2"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
[ "$(id -u)" = 0 ] || { echo "Run with sudo (writes to /etc, /usr)."; exit 1; }
|
||||
|
||||
# Collected below and persisted to WARNINGS_FILE so the Cockpit vanrouter page
|
||||
# can surface deploy-time issues (missing deps, unedited example configs, drift)
|
||||
# without someone having to remember to scroll back through deploy output.
|
||||
WARNINGS=()
|
||||
WARNINGS_FILE=/var/lib/vanlink/deploy-warnings.json
|
||||
warn() { # warn <message...> — prints " -> <message>" (as before) and records it
|
||||
echo " -> $*"
|
||||
WARNINGS+=("$*")
|
||||
}
|
||||
write_warnings() {
|
||||
install -d -m0755 "$(dirname "$WARNINGS_FILE")"
|
||||
{
|
||||
printf '{\n "deployed": "%s",\n "warnings": [' "$(date -Iseconds)"
|
||||
local first=1 w e
|
||||
for w in "${WARNINGS[@]}"; do
|
||||
[ "$first" = 1 ] || printf ','
|
||||
first=0
|
||||
e=${w//\\/\\\\}; e=${e//\"/\\\"}
|
||||
printf '\n "%s"' "$e"
|
||||
done
|
||||
printf '\n ]\n}\n'
|
||||
} > "$WARNINGS_FILE"
|
||||
}
|
||||
|
||||
echo "== netplan drift check =="
|
||||
# Netplan is never installed by this script (applying it flaps the uplinks —
|
||||
# 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
|
||||
echo " -> WARNING: /etc/netplan/50-van-wan.yaml is missing. Repo config"
|
||||
echo " was never deployed to this system. Run manually:"
|
||||
echo " sudo cp ap/50-van-wan.yaml /etc/netplan/50-van-wan.yaml"
|
||||
echo " sudo netplan generate && sudo netplan apply"
|
||||
elif ! diff -q ap/50-van-wan.yaml /etc/netplan/50-van-wan.yaml >/dev/null 2>&1; then
|
||||
echo " -> WARNING: /etc/netplan/50-van-wan.yaml differs from ap/50-van-wan.yaml."
|
||||
diff -u /etc/netplan/50-van-wan.yaml ap/50-van-wan.yaml || true
|
||||
echo " Deploy the change manually:"
|
||||
echo " sudo cp ap/50-van-wan.yaml /etc/netplan/50-van-wan.yaml"
|
||||
echo " sudo netplan generate && sudo netplan apply"
|
||||
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
|
||||
fi
|
||||
|
||||
echo "== access point =="
|
||||
install -D -m0644 ap/hostapd.conf /etc/hostapd/hostapd.conf
|
||||
install_rendered ap/hostapd.conf /etc/hostapd/hostapd.conf
|
||||
install -D -m0644 ap/hostapd-restart.conf /etc/systemd/system/hostapd.service.d/restart.conf
|
||||
install -D -m0644 ap/default-hostapd /etc/default/hostapd
|
||||
install -D -m0644 ap/hostapd-2g.conf /etc/hostapd/hostapd-2g.conf
|
||||
install -D -m0644 ap/hostapd-2g.service /etc/systemd/system/hostapd-2g.service
|
||||
install -D -m0644 ap/11-van-ap-2g.network /etc/systemd/network/11-van-ap-2g.network
|
||||
install_rendered ap/hostapd-2g.conf /etc/hostapd/hostapd-2g.conf
|
||||
install_rendered ap/hostapd-2g.service /etc/systemd/system/hostapd-2g.service
|
||||
install_rendered ap/11-van-ap-2g.network /etc/systemd/network/11-van-ap-2g.network
|
||||
install -D -m0644 ap/van-ap-watchdog-2g.service /etc/systemd/system/van-ap-watchdog-2g.service
|
||||
install -D -m0644 ap/rtw88.conf /etc/modprobe.d/rtw88.conf
|
||||
install -D -m0755 ap/van-ap-watchdog /usr/local/sbin/van-ap-watchdog
|
||||
install -D -m0644 ap/van-ap-watchdog.service /etc/systemd/system/van-ap-watchdog.service
|
||||
install -D -m0644 ap/van-ap-dnsmasq.conf /etc/van-ap/dnsmasq.conf
|
||||
install -D -m0644 ap/van-ap-dnsmasq.service /etc/systemd/system/van-ap-dnsmasq.service
|
||||
install -D -m0644 ap/10-van-ap.network /etc/systemd/network/10-van-ap.network
|
||||
install_rendered ap/10-van-ap.network /etc/systemd/network/10-van-ap.network
|
||||
install -D -m0644 ap/20-van-br0.netdev /etc/systemd/network/20-van-br0.netdev
|
||||
install -D -m0644 ap/21-van-br0.network /etc/systemd/network/21-van-br0.network
|
||||
install -D -m0644 ap/22-van-lan.network /etc/systemd/network/22-van-lan.network
|
||||
install_rendered ap/22-van-lan.network /etc/systemd/network/22-van-lan.network
|
||||
install -D -m0644 ap/23-van-lan-eth0.network /etc/systemd/network/23-van-lan-eth0.network
|
||||
install -D -m0644 ap/van-ap-unmanaged.conf /etc/NetworkManager/conf.d/van-ap-unmanaged.conf
|
||||
install_rendered ap/van-ap-unmanaged.conf /etc/NetworkManager/conf.d/van-ap-unmanaged.conf
|
||||
# Mask dracut's initramfs-generated catch-all (/run/systemd/network/
|
||||
# zzzz-dracut-default.network, regenerated every boot): it matches every
|
||||
# unconfigured link, so networkd co-managed the NM-owned WANs — a second
|
||||
@@ -61,15 +110,34 @@ install -D -m0644 failover/config.json /etc/van-failover/config.json
|
||||
install -D -m0644 failover/van-failover.service /etc/systemd/system/van-failover.service
|
||||
install -D -m0755 failover/50-disable-eee /etc/NetworkManager/dispatcher.d/50-disable-eee
|
||||
install -D -m0644 failover/99-van-arp.conf /etc/sysctl.d/99-van-arp.conf
|
||||
# Backstop for wlan0's post-boot NM no-secrets wedge (see the script's docstring).
|
||||
install -D -m0755 failover/van-wlan-watchdog /usr/local/sbin/van-wlan-watchdog
|
||||
install -D -m0644 failover/van-wlan-watchdog.service /etc/systemd/system/van-wlan-watchdog.service
|
||||
|
||||
echo "== cellular modem (GSM/LTE) =="
|
||||
# NM's gsm.auto-config APN lookup needs this apt-only carrier database; without
|
||||
# it even the right APN can't be auto-detected, and MVNOs (e.g. Koodo, which
|
||||
# isn't listed under its own name — only under host network "Telus Mobility")
|
||||
# often aren't in it anyway, so the modem's NM connection profile may still
|
||||
# need an explicit gsm.apn set by hand regardless.
|
||||
dpkg -s mobile-broadband-provider-info >/dev/null 2>&1 \
|
||||
|| warn "mobile-broadband-provider-info missing (apt install mobile-broadband-provider-info) — GSM APN auto-config will fail"
|
||||
|
||||
echo "== cockpit plugin =="
|
||||
install -d /usr/share/cockpit/vanrouter
|
||||
install -m0644 cockpit/vanrouter/* /usr/share/cockpit/vanrouter/
|
||||
for f in cockpit/vanrouter/*; do
|
||||
b=$(basename "$f")
|
||||
if [ "$b" = "vanrouter.js" ]; then
|
||||
install_rendered "$f" "/usr/share/cockpit/vanrouter/$b"
|
||||
else
|
||||
install -m0644 "$f" "/usr/share/cockpit/vanrouter/$b"
|
||||
fi
|
||||
done
|
||||
# Bridge fd headroom (Python bridge frees spawn pipes only at GC; 1024 is too tight)
|
||||
install -D -m0644 cockpit/cockpit-session-nofile.conf /etc/systemd/system/cockpit-session@.service.d/nofile.conf
|
||||
# The Starlink card queries the dish's gRPC API; grpcurl isn't packaged in apt.
|
||||
command -v grpcurl >/dev/null 2>&1 \
|
||||
|| echo " -> grpcurl missing (Starlink card will say so): install linux_arm64 binary from github.com/fullstorydev/grpcurl/releases"
|
||||
|| warn "grpcurl missing (Starlink card will say so): install linux_arm64 binary from github.com/fullstorydev/grpcurl/releases"
|
||||
|
||||
echo "== gps (cellular modem GNSS -> gpsd) =="
|
||||
if dpkg -s gpsd >/dev/null 2>&1; then
|
||||
@@ -77,7 +145,7 @@ if dpkg -s gpsd >/dev/null 2>&1; then
|
||||
install -D -m0644 gps/gpsd.default /etc/default/gpsd
|
||||
udevadm control --reload
|
||||
else
|
||||
echo " -> gpsd not installed (apt install gpsd gpsd-clients) — skipping GPS setup"
|
||||
warn "gpsd not installed (apt install gpsd gpsd-clients) — skipping GPS setup"
|
||||
fi
|
||||
# OwnTracks publisher: gpsd fix -> MQTT (broker + creds live only on the
|
||||
# system, 0600 — same pattern as pushover.json).
|
||||
@@ -85,10 +153,12 @@ install -D -m0755 gps/van-gps-owntracks /usr/local/sbin/van-gps-owntrack
|
||||
install -D -m0644 gps/van-gps-owntracks.service /etc/systemd/system/van-gps-owntracks.service
|
||||
if [ ! -f /etc/van-gps/config.json ]; then
|
||||
install -D -m0600 gps/config.json.example /etc/van-gps/config.json
|
||||
echo " -> seeded /etc/van-gps/config.json (EDIT IT: add MQTT username + password)"
|
||||
warn "seeded /etc/van-gps/config.json (EDIT IT: add MQTT username + password)"
|
||||
fi
|
||||
python3 -c 'import gps' 2>/dev/null \
|
||||
|| warn "python3-gps missing (apt install python3-gps) — van-gps-owntracks won't start"
|
||||
python3 -c 'import paho.mqtt' 2>/dev/null \
|
||||
|| echo " -> python3-paho-mqtt missing (apt install python3-paho-mqtt) — van-gps-owntracks won't start"
|
||||
|| warn "python3-paho-mqtt missing (apt install python3-paho-mqtt) — van-gps-owntracks won't start"
|
||||
|
||||
echo "== thermal monitor =="
|
||||
install -D -m0755 power/van-thermal /usr/local/sbin/van-thermal
|
||||
@@ -98,7 +168,7 @@ install -D -m0644 power/van-thermal.service /etc/systemd/system/van-thermal.serv
|
||||
# under /etc/van-battery/ for parity with wayback's van-thermal default.
|
||||
if [ ! -f /etc/van-battery/pushover.json ]; then
|
||||
install -D -m0600 power/pushover.json.example /etc/van-battery/pushover.json
|
||||
echo " -> seeded /etc/van-battery/pushover.json (EDIT IT: add Pushover token + user)"
|
||||
warn "seeded /etc/van-battery/pushover.json (EDIT IT: add Pushover token + user)"
|
||||
fi
|
||||
|
||||
echo "== home assistant =="
|
||||
@@ -121,10 +191,10 @@ systemctl daemon-reexec
|
||||
# its wait-online would just stall network-online.target. NM-wait-online covers WANs.
|
||||
systemctl mask systemd-networkd-wait-online.service >/dev/null 2>&1 || true
|
||||
systemctl unmask hostapd >/dev/null 2>&1 || true
|
||||
systemctl enable regdomain.service hostapd hostapd-2g van-ap-dnsmasq nftables systemd-networkd van-failover van-thermal van-ap-watchdog van-ap-watchdog-2g van-gps-owntracks >/dev/null 2>&1 || true
|
||||
systemctl enable regdomain.service hostapd hostapd-2g van-ap-dnsmasq nftables systemd-networkd van-failover van-thermal van-ap-watchdog van-ap-watchdog-2g van-wlan-watchdog van-gps-owntracks >/dev/null 2>&1 || true
|
||||
# bluetooth: host BlueZ serves the onboard hci0 to the HA container over D-Bus
|
||||
systemctl enable --now bluetooth >/dev/null 2>&1 || true
|
||||
systemctl start homeassistant || echo " -> homeassistant failed to start (podman/quadlet — check journalctl -u homeassistant)"
|
||||
systemctl start homeassistant || warn "homeassistant failed to start (podman/quadlet — check journalctl -u homeassistant)"
|
||||
systemctl restart van-thermal
|
||||
systemctl restart van-gps-owntracks
|
||||
# Pick up unmanaged-devices changes so NM releases/keeps the right interfaces.
|
||||
@@ -132,7 +202,7 @@ nmcli general reload 2>/dev/null || systemctl reload NetworkManager 2>/dev/null
|
||||
# restart in dependency order: bridge + members first, then hostapd enslaves the
|
||||
# radios, then dnsmasq binds br0, then NAT/failover
|
||||
systemctl restart systemd-networkd
|
||||
systemctl restart van-ap-dnsmasq nftables van-failover
|
||||
systemctl restart van-ap-dnsmasq nftables van-failover van-wlan-watchdog
|
||||
# The AP radios live on the USB hub and may be absent; the start then fails but
|
||||
# Restart=always keeps retrying and claims them the moment they enumerate.
|
||||
systemctl restart hostapd hostapd-2g \
|
||||
@@ -141,11 +211,13 @@ systemctl restart hostapd hostapd-2g \
|
||||
systemctl restart van-ap-watchdog van-ap-watchdog-2g
|
||||
networkctl reload 2>/dev/null || true
|
||||
|
||||
write_warnings
|
||||
|
||||
echo
|
||||
echo "Deployed. NOTE: until the USB hub (AP radios + LAN/Starlink adapters) is"
|
||||
echo "plugged in, hostapd/hostapd-2g just retry every 5s — that is by design."
|
||||
echo "Verify (with hub present):"
|
||||
echo " iw dev wlxc83a35a4ee55 info | grep -E 'ssid|channel|width'"
|
||||
echo " iw dev wlxd8ec5e2faa8c info | grep -E 'ssid|channel|width'"
|
||||
echo " iw dev $WIFI_5G_IFACE info | grep -E 'ssid|channel|width'"
|
||||
echo " iw dev $WIFI_2G_IFACE info | grep -E 'ssid|channel|width'"
|
||||
echo " cat /run/van-failover/state.json"
|
||||
echo " cat /run/van-thermal/state.json"
|
||||
|
||||
Reference in New Issue
Block a user