Li3, NVMe watchdog, Home Assistant/ESPHome, Frigate and Cockpit are installed, enabled and restarted only when their ENABLE_* flag is 1. --diff shows what would change in /etc. A unit that fails to restart is recorded as a warning instead of aborting the deploy. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
101 lines
4.6 KiB
Bash
Executable File
101 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Static checks for the host-config templating. No root needed.
|
|
# ./tests/check-templates.sh
|
|
set -euo pipefail
|
|
cd "$(dirname "$(readlink -f "$0")")/.."
|
|
|
|
fail=0
|
|
ok() { echo "ok - $*"; }
|
|
bad() { echo "FAIL - $*"; fail=1; }
|
|
|
|
# 1. shell syntax
|
|
for f in deploy.sh failover/sync-usb-backup.sh failover/sync-sd-backup.sh tests/check-templates.sh; do
|
|
if bash -n "$f"; then ok "bash -n $f"; else bad "bash -n $f"; fi
|
|
done
|
|
|
|
# 3. every host file passes deploy.sh --check (validates vars, renders all templates)
|
|
for c in hosts/*.conf; do
|
|
if out=$(./deploy.sh --check "$c" 2>&1); then
|
|
ok "--check $c"
|
|
else
|
|
bad "--check $c"; echo "$out" | sed 's/^/ /'
|
|
fi
|
|
done
|
|
|
|
# 4. the example defines exactly the variables deploy.sh knows about
|
|
known=$(sed -n '/^REQUIRED_VARS=(/,/^)/p;/^OPTIONAL_VARS=(/,/^)/p' deploy.sh \
|
|
| grep -vE '^[A-Z_]+=\(|^\)' | tr -s ' \t' '\n' | grep -v '^$' | sort || true)
|
|
defined=$(grep -oE '^[A-Z][A-Z0-9_]*=' hosts/vanlink.conf.example 2>/dev/null | tr -d = | sort || true)
|
|
if [ -n "$known" ] && [ "$known" = "$defined" ]; then
|
|
ok "hosts/vanlink.conf.example defines exactly the variables deploy.sh knows"
|
|
else
|
|
bad "hosts/vanlink.conf.example differs from deploy.sh's variable lists"
|
|
diff <(echo "$known") <(echo "$defined") | sed 's/^/ /' || true
|
|
fi
|
|
|
|
# 2. every file carrying an @TOKEN@ is installed through install_rendered
|
|
# (plain `install` would ship the placeholder unrendered — the 2026-09-23 failure)
|
|
# vanrouter.js: installed by the loop in the cockpit block; 50-van-wan.yaml: reference copy,
|
|
# rendered by hand via `deploy.sh render` (deploy.sh only warns when it differs)
|
|
exempt=" cockpit/vanrouter/vanrouter.js ap/50-van-wan.yaml "
|
|
for f in $(./deploy.sh --templates); do
|
|
case "$exempt" in *" $f "*) continue ;; esac
|
|
if grep -qE "^[[:space:]]*install_rendered +$f[[:space:]]" deploy.sh; then
|
|
ok "install_rendered $f"
|
|
else
|
|
bad "$f contains an @TOKEN@ but deploy.sh does not install it with install_rendered"
|
|
fi
|
|
done
|
|
|
|
# 5. host-specific values land in the rendered output
|
|
r() { VANLINK_CONF="hosts/$1.conf" ./deploy.sh render "$2"; }
|
|
expect() { # expect <host> <file> <fixed string that must appear>
|
|
if r "$1" "$2" | grep -qF -- "$3"; then ok "$1: $2 has '$3'"; else bad "$1: $2 lacks '$3'"; fi
|
|
}
|
|
expect van ap/nftables.conf 'ip saddr 10.42.1.0/24'
|
|
expect wan ap/nftables.conf 'ip saddr 10.42.0.0/24'
|
|
expect van ap/van-br0-setup.service 'brctl addif br0 enP1p17s0'
|
|
expect wan ap/van-br0-setup.service 'brctl addif br0 enx00e04c331140'
|
|
expect van failover/config.json '"device": "wlan0"'
|
|
expect van router-status/config.json '"wifi_wan_iface": "wlan0"'
|
|
expect van failover/van-wlan-watchdog.service 'van-wlan-watchdog wlan0'
|
|
expect van ap/van-ap-unmanaged.conf 'interface-name:enP1p17s0'
|
|
expect wan ap/van-ap-unmanaged.conf 'interface-name:enx00e04c331140;interface-name:eth0'
|
|
expect wan ap/23-van-lan-eth0.network 'Name=eth0'
|
|
expect van power/nvme-watch-config.json '"nvme_device": ""'
|
|
if r van ap/van-ap-unmanaged.conf | grep -q 'eth0'; then
|
|
bad "van: unmanaged-devices must not mention eth0 (ONBOARD_LAN_IFACE is empty)"
|
|
else
|
|
ok "van: unmanaged-devices has no eth0"
|
|
fi
|
|
|
|
# 6. flagged units/paths only appear inside their ENABLE_* guard in deploy.sh.
|
|
# Convention: guards are column-0 `if [ "$ENABLE_X" = 1 ]; then` ... `fi`,
|
|
# contents indented (so a nested `fi` never sits in column 0).
|
|
if awk '
|
|
BEGIN {
|
|
need["van-li3-battery"]="ENABLE_LI3"
|
|
need["van-nvme-watch"]="ENABLE_NVME_WATCH"
|
|
need["nvme-watch-config"]="ENABLE_NVME_WATCH"
|
|
need["homeassistant"]="ENABLE_HA"
|
|
need["esphome"]="ENABLE_HA"
|
|
need["frigate"]="ENABLE_FRIGATE"
|
|
need["cockpit"]="ENABLE_COCKPIT"
|
|
}
|
|
/^if \[ "\$ENABLE_[A-Z0-9_]+" = 1 \]/ { match($0, /ENABLE_[A-Z0-9_]+/); guard=substr($0, RSTART, RLENGTH); next }
|
|
/^fi([[:space:]]|$)/ { guard=""; next }
|
|
/^[[:space:]]*(#|echo)/ { next }
|
|
{ for (u in need) if (index($0, u) && guard != need[u]) {
|
|
printf " deploy.sh:%d mentions %s outside an %s guard: %s\n", NR, u, need[u], $0; bad=1 } }
|
|
END { exit bad }
|
|
' deploy.sh; then ok "flagged units are only touched inside their ENABLE_* guard"; else bad "flag gating"; fi
|
|
|
|
# 8. ./deploy.sh --diff runs (no root) and lists rendered files
|
|
if out=$(./deploy.sh --diff hosts/van.conf 2>&1) && echo "$out" | grep -qE '^(NEW|CHANGED) '; then
|
|
ok "deploy.sh --diff hosts/van.conf"
|
|
else
|
|
bad "deploy.sh --diff hosts/van.conf"; echo "$out" | sed 's/^/ /'
|
|
fi
|
|
|
|
exit "$fail"
|