Files
vanlink/deploy.sh
T
Andreas WredeandClaude Opus 4.8 8fcc959551 robustness: hardware watchdog + hbc heartbeat client
Two TODO Tier-1 items:

- Hardware watchdog: power/10-vanlink-watchdog.conf drop-in sets
  RuntimeWatchdogSec=20s + RebootWatchdogSec=5min; deploy.sh applies it via
  daemon-reexec. PID1 pets intel_oc_wdt; a >20s systemd hang hard-resets the box.

- Heartbeat / dead-man's switch: vendored hbc.yaml + hbc.service report to
  hbd.wrede.pvt (UDP 50003) every 15s as user andreas, shipping cpu/mem/disk/
  network/zfs metrics. The hbc binary is installed once via the heartbeat
  project's installer (README §4); deploy.sh starts the service when present.

Auto-power-on-when-mains-returns: documented as a BIOS-only option (not
OS-controllable on this ZenBook) in README §3 + TODO, per decision.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 22:20:09 -04:00

102 lines
5.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Deploy vanlink configs/scripts from this directory to their system locations.
# Usage: cd ~/vanlink && sudo ./deploy.sh
# Idempotent. See README.md §4 for the two manual steps this does NOT do
# (zerotier-systemd-manager binary install, hostapd unmask).
set -euo pipefail
cd "$(dirname "$(readlink -f "$0")")"
[ "$(id -u)" = 0 ] || { echo "Run with sudo (writes to /etc, /usr)."; exit 1; }
echo "== access point =="
install -D -m0644 ap/hostapd.conf /etc/hostapd/hostapd.conf
install -D -m0644 ap/default-hostapd /etc/default/hostapd
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 -D -m0644 ap/van-ap-unmanaged.conf /etc/NetworkManager/conf.d/van-ap-unmanaged.conf
install -D -m0644 ap/nftables.conf /etc/nftables.conf
install -D -m0644 ap/regdomain.service /etc/systemd/system/regdomain.service
install -D -m0644 ap/rtw89.conf /etc/modprobe.d/rtw89.conf
install -D -m0644 ap/99-van-router.conf /etc/sysctl.d/99-van-router.conf
echo "== failover =="
install -D -m0755 failover/van-failover /usr/local/sbin/van-failover
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
echo "== zerotier managed dns =="
install -D -m0644 dns/zt-search.conf /etc/systemd/network/99-ztuga7c2kh.network.d/search.conf
echo "== cockpit plugin =="
install -d /usr/share/cockpit/vanrouter
install -m0644 cockpit/vanrouter/* /usr/share/cockpit/vanrouter/
echo "== thermal monitor =="
install -D -m0755 power/van-thermal /usr/local/sbin/van-thermal
install -D -m0644 power/thermal-config.json /etc/van-thermal/config.json
install -D -m0644 power/van-thermal.service /etc/systemd/system/van-thermal.service
echo "== battery monitor =="
install -D -m0755 power/van-battery /usr/local/sbin/van-battery
install -D -m0644 power/battery-config.json /etc/van-battery/config.json
install -D -m0644 power/van-battery.service /etc/systemd/system/van-battery.service
# Pushover secrets live only on the system (0600), never in the repo. Seed from the
# template on first deploy; never clobber a filled-in file on later deploys.
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)"
fi
echo "== power / never-sleep =="
install -D -m0644 power/10-vanlink-nolid.conf /etc/systemd/logind.conf.d/10-vanlink-nolid.conf
# Belt-and-suspenders: a router must never suspend from idle, GUI, or a stray `systemctl suspend`.
systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target >/dev/null 2>&1 || true
echo "== hardware watchdog =="
install -D -m0644 power/10-vanlink-watchdog.conf /etc/systemd/system.conf.d/10-vanlink-watchdog.conf
echo "== heartbeat client (dead-man's switch) =="
install -D -m0644 heartbeat/hbc.yaml /etc/hbc.yaml
install -D -m0644 heartbeat/hbc.service /etc/systemd/system/hbc.service
# The hbc binary itself (~/bin/hbc + venv) is installed once via the heartbeat
# project's installer — see README §4. Only start the service if it's present.
if [ ! -x /home/andreas/bin/hbc ]; then
echo " -> /home/andreas/bin/hbc not found; run 'sh ~/git/heartbeat/scripts/hb_install.sh client' (README §4)"
fi
echo "== apply =="
sysctl --system >/dev/null
systemctl daemon-reload
# Re-exec PID1 so the system.conf.d watchdog drop-in takes effect (daemon-reload alone
# does NOT re-arm RuntimeWatchdogSec). Safe online: re-exec keeps all services running.
systemctl daemon-reexec
# networkd here owns only the AP + ZT overlay (neither a real uplink), so its wait-online
# can never satisfy "online" and just burns its 120s timeout, stalling network-online.target
# and ZeroTier by ~2min every boot. Real uplink readiness is covered by NetworkManager-wait-online.
systemctl mask systemd-networkd-wait-online.service >/dev/null 2>&1 || true
# pick up the lid drop-in (re-execs logind; does NOT drop the network)
systemctl restart systemd-logind >/dev/null 2>&1 || true
systemctl unmask hostapd >/dev/null 2>&1 || true
systemctl enable regdomain.service hostapd van-ap-dnsmasq nftables systemd-networkd van-failover van-thermal van-battery >/dev/null 2>&1 || true
systemctl restart van-thermal van-battery
# Heartbeat: only enable/start once the client binary is installed (README §4).
if [ -x /home/andreas/bin/hbc ]; then
systemctl enable hbc >/dev/null 2>&1 || true
systemctl restart hbc
fi
# restart in dependency order; AP iface IP first, then hostapd/dnsmasq, then NAT/failover
systemctl restart systemd-networkd
systemctl restart hostapd van-ap-dnsmasq nftables van-failover
networkctl reload 2>/dev/null || true
echo
echo "Deployed. Verify:"
echo " iw dev wlxc83a35a4ee55 info | grep -E 'ssid|channel|width'"
echo " cat /run/van-failover/state.json"
echo " cat /run/van-thermal/state.json # CPU + NVMe temps"
echo " cat /run/van-battery/state.json # mains/battery + charge %"
echo " systemctl status hbc # heartbeat client -> hbd.wrede.pvt"
echo "Manual one-time steps (see README §4): zerotier-systemd-manager binary + 'zerotier-cli set <nwid> allowDNS=1'."