Template remaining host-specific values (WAN wifi, LAN/eth0, NVMe, nftables)

nftables.conf hardcoded the R5C network, van-br0-setup.service the R5C
interfaces and several configs wlan0/eth0. All now come from the host
config; the onboard LAN port is skipped when ONBOARD_LAN_IFACE is empty.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-23 14:32:09 -04:00
co-authored by Claude Sonnet 5
parent 164cb30d93
commit d704069ffc
11 changed files with 57 additions and 17 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
# Starlink + cellular as uplinks, the wired port earns its keep as LAN instead.
# NM must leave it alone (see van-ap-unmanaged.conf) for networkd to own it here.
[Match]
Name=eth0
Name=@ONBOARD_LAN_IFACE@
[Link]
RequiredForOnline=no
+1 -1
View File
@@ -34,7 +34,7 @@ network:
passthrough:
ipv4.never-default: "true"
wifis:
wlan0:
@WIFI_WAN_IFACE@:
renderer: NetworkManager
optional: true
dhcp4: true
+1 -1
View File
@@ -6,6 +6,6 @@ delete table ip van_router_nat
table ip van_router_nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.42.1.0/24 oifname != "br0" masquerade;
ip saddr @GATEWAY_NETWORK@ oifname != "br0" masquerade;
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
[keyfile]
# The AP wlans (5GHz + 2.4GHz) and the wired LAN ports (USB dongle + onboard
# eth0) are all owned by systemd-networkd/hostapd (bridged into br0), so
# port) are all owned by systemd-networkd/hostapd (bridged into br0), so
# NetworkManager must not touch them.
unmanaged-devices=interface-name:@WIFI_5G_IFACE@;interface-name:@WIFI_2G_IFACE@;interface-name:@LAN_IFACE@;interface-name:eth0
unmanaged-devices=interface-name:@WIFI_5G_IFACE@;interface-name:@WIFI_2G_IFACE@;interface-name:@LAN_IFACE@@ONBOARD_LAN_UNMANAGED@
+2 -2
View File
@@ -5,8 +5,8 @@ Wants=systemd-networkd.service hostapd.service
[Service]
Type=oneshot
ExecStart=/bin/bash -c "brctl addif br0 enP2p33s0 2>/dev/null || true"
ExecStart=/bin/bash -c "brctl addif br0 wlp1s0 2>/dev/null || true"
ExecStart=/bin/bash -c "brctl addif br0 @LAN_IFACE@ 2>/dev/null || true"
ExecStart=/bin/bash -c "brctl addif br0 @WIFI_5G_IFACE@ 2>/dev/null || true"
RemainAfterExit=yes
[Install]
+9 -5
View File
@@ -209,7 +209,11 @@ install_rendered ap/21-van-br0.network /etc/systemd/network/21-van-br0.netw
# filename), leaving the LAN port un-bridged.
install_rendered ap/22-van-lan.network /etc/systemd/network/05-van-lan.network
rm -f /etc/systemd/network/22-van-lan.network
install -D -m0644 ap/23-van-lan-eth0.network /etc/systemd/network/23-van-lan-eth0.network
if [ -n "${ONBOARD_LAN_IFACE:-}" ]; then
install_rendered ap/23-van-lan-eth0.network /etc/systemd/network/23-van-lan-eth0.network
else
rm -f /etc/systemd/network/23-van-lan-eth0.network
fi
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
@@ -217,9 +221,9 @@ install_rendered ap/van-ap-unmanaged.conf /etc/NetworkManager/conf.d/van-ap-un
# DHCPv4 client on wlan0 and IPv6 that worked only by accident. NM owns WAN
# IPv6 now (see ap/50-van-wan.yaml). /etc overrides /run; /dev/null masks.
ln -sfn /dev/null /etc/systemd/network/zzzz-dracut-default.network
install -D -m0644 ap/nftables.conf /etc/nftables.conf
install_rendered ap/nftables.conf /etc/nftables.conf
install -D -m0644 ap/regdomain.service /etc/systemd/system/regdomain.service
install -D -m0644 ap/van-br0-setup.service /etc/systemd/system/van-br0-setup.service
install_rendered ap/van-br0-setup.service /etc/systemd/system/van-br0-setup.service
install -D -m0644 ap/80-regdomain.rules /etc/udev/rules.d/80-regdomain.rules
install -D -m0644 ap/rtl8188gu-modeswitch.conf /etc/usb-modeswitch.d/0bda:1a2b
install -D -m0644 ap/rtw89.conf /etc/modprobe.d/rtw89.conf
@@ -256,7 +260,7 @@ install -D -m0755 failover/50-disable-eee /etc/NetworkManager/dispatcher.d
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
install_rendered 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
@@ -368,7 +372,7 @@ fi
echo "== nvme watchdog =="
install -D -m0755 power/van-nvme-watch /usr/local/sbin/van-nvme-watch
install -D -m0644 power/nvme-watch-config.json /etc/van-nvme-watch/config.json
install_rendered power/nvme-watch-config.json /etc/van-nvme-watch/config.json
install -D -m0644 power/van-nvme-watch.service /etc/systemd/system/van-nvme-watch.service
echo "== home assistant =="
+1 -1
View File
@@ -7,7 +7,7 @@
"http://connectivity-check.ubuntu.com/"
],
"wans": [
{ "name": "wifi", "device": "wlan0", "metric": 100 },
{ "name": "wifi", "device": "@WIFI_WAN_IFACE@", "metric": 100 },
{ "name": "starlink", "device": "@STARLINK_IFACE@", "metric": 200 },
{ "name": "cellular", "connection": "Koodo", "metric": 300 }
]
+1 -1
View File
@@ -5,7 +5,7 @@ Wants=NetworkManager.service
[Service]
Type=simple
ExecStart=/usr/local/sbin/van-wlan-watchdog
ExecStart=/usr/local/sbin/van-wlan-watchdog @WIFI_WAN_IFACE@
[Install]
WantedBy=multi-user.target
+2 -2
View File
@@ -1,6 +1,6 @@
{
"nvme_device": "nvme0",
"fs_device": "/dev/nvme0n1p2",
"nvme_device": "@NVME_DEVICE@",
"fs_device": "@NVME_FS_DEVICE@",
"grace_period": 20,
"cooldown": 300,
"credentials_path": "/etc/van-battery/pushover.json"
+1 -1
View File
@@ -13,5 +13,5 @@
"starlink_iface": "@STARLINK_IFACE@",
"starlink_dish": "192.168.100.1:9200",
"modem_usb_vendor": "@MODEM_USB_VENDOR@",
"wifi_wan_iface": "wlan0"
"wifi_wan_iface": "@WIFI_WAN_IFACE@"
}
+36
View File
@@ -33,4 +33,40 @@ else
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
exit "$fail"