Commit Graph
70 Commits
Author SHA1 Message Date
andreasandClaude Sonnet 5 e0792fade2 van-router-mqtt: broker credentials in a separate 0600 file; log refused connects
config.json is re-rendered every deploy, so credentials go in
/etc/van-router-mqtt/credentials.json (seeded empty if absent, never
overwritten). The service logs MQTT connect/refuse/disconnect state changes,
and --post-check warns when the broker refuses the service.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 21:45:16 -04:00
andreasandClaude Sonnet 5 594213138e apply-network fix round 1: reload networkd after the NM reload on rollback; harden post-check tests
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 21:04:33 -04:00
andreasandClaude Sonnet 5 4f62b9f770 apply-network: reload networkd after each netplan apply; post-check flags a networkd/NM double claim
Live R5C run: after the Armbian catch-all .network was removed, networkd kept its
in-memory claim on the uplink port (two addresses, extra proto dhcp default route)
until `networkctl reload`. The helper now reloads networkd after the forward apply
and after the rollback re-apply (not fatal, not gating; logs the port state and a
"networkd still manages" note on the forward path), the AN_* time budget includes
it, and --post-check warns when the netplan matches but networkd still lists the
uplink port configured/configuring.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 20:58:29 -04:00
andreasandClaude Opus 5.5 722cad1ac3 netplan: restore the Pi-identical comment; rollback re-runs van-br0-setup
- ap/50-van-wan.yaml: revert the comment to "see STARLINK_IFACE in deploy.conf" so the
  rendered file is byte-identical to the Pi 5's installed netplan (it otherwise reports
  "differs" forever); note in deploy.sh next to render_wan_netplan.
- check 14: baseline 3d117e7, keep byte-identity for wan.conf, assert no /etc/vanlink.conf;
  the failure branch no longer aborts the suite under pipefail.
- helper restore(): restart van-br0-setup (unit present, timeout 30, non-fatal) after the
  re-apply, before the connectivity re-check; asserted in the rollback sandbox scenario.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 19:54:25 -04:00
andreasandClaude Opus 5.5 3fce6a7907 apply-network: final-review fixes (diagnostics, NM off the uplink until handover, preflight, stricter stage 2)
I-1 helper logs diagnostics (nmcli, DHCP routers, networkctl -n 0, ip addr, ip route; each
    under timeout 5) before a stage 1/2 restore, and the port's networkctl list line on success
    (information only, never gating).
I-2 ap/nm-uplink-pending.conf -> /etc/NetworkManager/conf.d/zz-van-wan-pending.conf keeps NM
    off STARLINK_IFACE while the WAN netplan is missing; installed before network-manager,
    removed once the netplan matches, left as is when it differs (port already handed to NM).
    apply_network backs it up as nm-pending.conf; the helper removes it + reloads NM conf right
    before netplan generate/apply, restore() puts it back and reloads after the re-apply.
    --wan-plan prints "uplink NM pending conf: ...".
I-3 nm_wan_state_netplan: "unreadable" (0600 file, non-root); --wan-plan and post-check say so
    without warning.
I-4 apply_preflight_problems (+ hidden --apply-preflight, VANLINK_HOSTNAME test knob ignored as
    root): port absent / conf of another host -> refused without --force. Stage 2 also needs
    van-failover's own "proto static" default route on the port.
M-1 helper restarts van-br0-setup (if the unit exists) after the forward netplan apply.
M-3 nm_pkg_installed (dpkg-query Status) in deploy, --wan-plan and --apply-network.
M-5 header documents VANLINK_CONF; stale test comment fixed.
M-6 cellular_profile_exists ignores VANLINK_NM_DIR as root.
M-7 tests: NM-off files installed before network-manager; read-only sub-commands never apt-get.
M-8 an existing, differing WAN netplan is shown (redact_secrets now masks YAML password:) and
    refused without --force.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 19:41:02 -04:00
andreasandClaude Sonnet 5 8baddceb96 apply-network: ignore VANLINK_WAN_NETPLAN; pin with a test
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 19:13:43 -04:00
andreasandClaude Sonnet 5 698f9ee446 post-check: failover check warns only on link without NM connection; retry, stub-nmcli tests
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 19:11:55 -04:00
andreasandClaude Sonnet 5 2601472576 post-check and docs for NetworkManager WANs
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 19:06:43 -04:00
andreasandClaude Sonnet 5 50ac006894 deploy: apply helper hardening (signal ordering, timeout -k, self-cleanup, checked pristine mv)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 19:01:25 -04:00
andreasandClaude Sonnet 5 cefca06dac deploy: apply helper gateway from DHCP routers, trap/timeouts, running status, per-stamp files
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 18:55:04 -04:00
andreasandClaude Sonnet 5 ca7d22384b deploy: apply helper reboots only when the rollback itself failed
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 18:46:16 -04:00
andreasandClaude Sonnet 5 d46fd5a1e4 deploy: --apply-network changes nothing itself; helper does install/apply, two-stage gate, checked rollback, status file
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 18:44:59 -04:00
andreasandClaude Sonnet 5 eaec8eb8b9 deploy: --apply-network with detached apply, connectivity gate and automatic rollback
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 18:35:43 -04:00
andreasandClaude Sonnet 5 7be698a5f1 deploy: find cellular profile by id, no-auto-default NM conf, warn on NM enable failure
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 18:33:38 -04:00
andreasandClaude Sonnet 5 e8fa2e025f deploy: install missing packages, NetworkManager WAN section, --wan-plan
Pure-bash SHA-1 derived CELLULAR_UUID (no uuidgen); skip keyfile if empty.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 18:30:17 -04:00
andreasandClaude Sonnet 5 65c0356463 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
2026-09-23 18:27:19 -04:00
andreasandClaude Sonnet 5 7333c1a1b3 post_check: radio present but not beaconing (no ssid) is a warning, not ok
Adds classify_radio + hidden --classify-radio seam and check 13.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 17:35:33 -04:00
andreasandClaude Sonnet 5 c4d9def8e3 post_check: run-to-completion units that exited 0 are ok, not warnings
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 17:26:33 -04:00
andreasandClaude Sonnet 5 6142935e29 post_check: shared bounded retry for br0/LAN/NAT/DHCP probes, pipefail-safe matching
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 17:23:36 -04:00
andreasandClaude Sonnet 5 5b43add677 deploy.sh: post-deploy check, --post-check, host-aware verify list
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 17:20:48 -04:00
andreasandClaude Sonnet 5 667edc8621 deploy --diff: never diff seeded secret files, redact secret values
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 16:41:31 -04:00
andreasandClaude Sonnet 5 f4bb65de9c deploy --diff: cover plain install files and removals
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 14:48:50 -04:00
andreasandClaude Sonnet 5 ac897799e6 Template hostapd interface/SSIDs/5GHz radio lines; guard against other-host hardcodes
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 14:48:22 -04:00
andreasandClaude Sonnet 5 a39fd5a654 Docs: shared checkout model, /etc/vanlink.conf references
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 14:39:22 -04:00
andreasandClaude Sonnet 5 83974f731d deploy: feature flags, --diff, tolerate failed restarts
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>
2026-09-23 14:34:13 -04:00
andreasandClaude Sonnet 5 d704069ffc 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>
2026-09-23 14:32:09 -04:00
andreasandClaude Sonnet 5 164cb30d93 deploy: gate cockpit block on ENABLE_COCKPIT
SKIP_COCKPIT only existed in the deleted deploy.conf; under set -u the
cockpit block would abort with an unbound variable.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 14:30:05 -04:00
andreasandClaude Sonnet 5 0cbbeb7aba deploy: host config from /etc/vanlink.conf (hosts/<hostname>.conf)
deploy.conf is replaced by one versioned file per host plus an example.
deploy.sh validates the config, renders every template with a generic
token loop, refuses to install output with leftover @TOKENs and gains
--check/--templates. LAN_USB_IFACE is renamed LAN_IFACE.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 14:28:11 -04:00
andreasandClaude Sonnet 5 442010c4b8 deploy: render dnsmasq/br0 configs, install LAN file as 05-van-lan
van-ap-dnsmasq.conf and 21-van-br0.network carry @TOKEN@ placeholders but
were installed unrendered. Armbian's netplan-generated 10-netplan-* file
matched the LAN port before 22-van-lan.network, so it was never bridged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 14:27:04 -04:00
andreas b4dfc88780 Add podman and homeassistant/esphome container support
Added podman to REQUIRED_PACKAGES for running homeassistant and esphome
containers on R5C.

Created docker/start-containers.sh script to start both containers with
persistent /srv volumes for configuration.

Ready for migration of homeassistant + esphome from 10.42.0 to 10.42.1.
Configs can be copied from old vanrouter at /srv/homeassistant and
/srv/esphome, then containers started on R5C.

Ports:
- Home Assistant: 8123 (accessed via --network=host)
- ESPHome: 6052
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-19 12:42:55 -04:00
andreasandClaude Haiku 4.5 4a4d80db4b Disable systemd-resolved DNS to allow dnsmasq DHCP
systemd-resolved listening on port 53 (even localhost-only) blocks
dnsmasq from binding to port 53 globally, causing DHCP to fail on reboot.

Created drop-in systemd-resolved-disable.conf to prevent the service from
listening on DNS. dnsmasq becomes the sole DNS+DHCP server on bridge br0.

Critical fix: without this, clients don't receive DHCP after reboot.

Verified: 5+ active DHCP leases, clients receiving 10.42.1.x addresses.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-19 11:57:42 -04:00
andreas 62eac3c389 Make all packages required (no optional packages)
Moved all packages from OPTIONAL_PACKAGES to REQUIRED_PACKAGES:
- rsync, mosquitto, python3-paho-mqtt
- mobile-broadband-provider-info, zerotier-one
- gpsd, gpsd-clients

Deploy will now fail if any package is missing, ensuring all
van-* services have their dependencies available.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-19 11:25:46 -04:00
andreas f5b29630ae Add usb-modeswitch config for RTL8188GU CDROM mode bypass
RTL8188GU WiFi adapter (0bda:1a2b) ships in CDROM mode on initial connection.
Install usb-modeswitch package and config to automatically switch to network
mode on boot.

Required for 2.4GHz AP to function when using D-Link DWA-171 or similar
RTL8188GU-based adapters.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-19 10:06:16 -04:00
andreas f564886a4a Make GPS, Bluetooth, and modem packages required
Move python3-gps, python3-bleak to REQUIRED_PACKAGES (needed for van-li3-battery,
van-gps-owntracks). Add modemmanager to REQUIRED_PACKAGES (provides mmcli for
van-sms-* services).

Deploy will now fail if these packages are missing, preventing silent failures
when GPS or SMS services are needed.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-19 10:01:59 -04:00
andreas 3593655fff Add van-br0-setup.service to fix bridge member persistence on boot
systemd-networkd Bridge= directive wasn't reliably adding interfaces to br0
on Armbian. Created persistent systemd service to ensure enP2p33s0 and wlp1s0
are added to the bridge after boot, maintaining 10.42.1.0/24 network.

This ensures the gateway bridge stays configured even after R5C reboots.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-19 08:07:47 -04:00
andreasandClaude Haiku 4.5 1002f86172 Fix regulatory domain persistence for 5GHz AP on boot
Problem: wlan1 regulatory domain not set on boot, defaults to 2.4GHz-only mode,
preventing channel 149 (5GHz) from being available. hostapd fails on startup.

Solution:
1. Modified regdomain.service to:
   - Run BEFORE hostapd/hostapd-2g services (Before= directive)
   - Run earlier in boot (After= sysinit.target)
   - RemainAfterExit=yes to persist setting

2. Added 80-regdomain.rules udev rule:
   - Triggers on regulatory device changes
   - Executes 'iw reg set CA' automatically

3. Added hostapd drop-in config:
   - Explicitly requires regdomain.service
   - Adds Wants= to ensure it starts

This ensures the regulatory domain is set BEFORE hostapd attempts to use
channel 149, fixing the boot-time AP failure loop.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-18 18:45:59 -04:00
andreasandClaude Haiku 4.5 565e8f31ab Fix watchdog timeout and MQTT connectivity issues
Problem: R5C spontaneously rebooted due to hardware watchdog timeout
Cause 1: van-gps-owntracks in infinite restart loop (MQTT connect failed)
Cause 2: mosquitto only listening on localhost, so clients couldn't connect
Solution:
- Add restart limits to van-gps-owntracks and van-li3-battery services
  (max 3 restarts per 5 minutes prevents infinite restart loops)
- Configure mosquitto to listen on all interfaces (0.0.0.0:1883)
- Deploy mosquitto listener config via deploy.sh
- Restart mosquitto during deploy to apply config changes

This prevents the system from hitting the 11-second hardware watchdog timeout
when services crash and systemd auto-restarts them indefinitely.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-18 18:20:11 -04:00
andreasandClaude Haiku 4.5 bb2e9c4618 Disable system dnsmasq.service to avoid port 53 conflicts
The system dnsmasq.service from the Debian dnsmasq package conflicts with
van-ap-dnsmasq.service on port 53 (DNS/DHCP). Explicitly disable the system
service during deploy so only van-ap-dnsmasq (bound to br0 for AP DHCP) runs.

Fixes DHCP failures where clients connect to the AP but don't get IP addresses
because port 53 is already in use.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-18 18:00:33 -04:00
andreasandClaude Haiku 4.5 af241339a3 Add package dependency checks to deploy.sh
Check for required packages (hostapd, iw, nftables, dnsmasq, systemd-resolved)
at deploy start and fail if any are missing. Also warn about optional packages
used by specific components (rsync, mosquitto, gpsd, python3-paho-mqtt, etc.).

Missing required packages halt deployment with clear error message. Optional
packages generate warnings that are captured in deploy-warnings.json for the
router-status MQTT dashboard.

This prevents silent failures when the R5C or other hardware doesn't have
expected dependencies installed.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-18 17:51:22 -04:00
andreasandClaude Haiku 4.5 ad199fb0b0 Make router IP address configurable via deploy.conf
Add GATEWAY_IP, GATEWAY_PREFIX, GATEWAY_NETWORK, DHCP_RANGE_START, and
DHCP_RANGE_END variables to deploy.conf. Update ap/21-van-br0.network,
ap/van-ap-dnsmasq.conf, and ap/nftables.conf to use @TOKEN@ placeholders
for IP configuration instead of hardcoding 10.42.x addresses.

This allows deploying the same configuration to multiple routers on
different networks (e.g., Pi 5 on 10.42.0.x and R5C on 10.42.1.x) by
simply editing deploy.conf before running ./deploy.sh.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-18 17:31:18 -04:00
Andreas WredeandClaude Sonnet 5 ec5130ea7d router-status: replace Cockpit's Van Router plugin with MQTT -> Home Assistant
Cockpit's login was unreliable (Firefox rejected sometimes, Android failed
outright with a TLS handshake error) and it was a resource hog on this Pi.
van-router-mqtt publishes the same AP/client/WAN/Starlink/modem status and
accepts the same control actions (AP/modem restart, WAN connect/disconnect,
prefer) via MQTT with HA discovery, using the local Mosquitto broker already
running here. It republishes van-failover/van-thermal's own state.json files
verbatim rather than modifying either daemon (van-thermal is deliberately
stdlib-only; van-failover's control loop wasn't worth an added dependency).

Adds a Lovelace dashboard (ha/dashboards/van-router.yaml) consuming those
entities. Cockpit's plugin is left deployed for now, not yet retired.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2tpeaiHUriQbbnQ4SCbkf
2026-09-14 16:28:01 -04:00
Andreas WredeandClaude Sonnet 5 db22cb50d6 modem: add van-sms-send CLI for sending SMS ad hoc
mmcli's inline "number=...,text=..." properties string breaks on plain
spaces/quotes/colons in the text — found while testing van-sms-watch.
Sidesteps that entirely by passing the message via
--messaging-create-sms-with-text=<tempfile> instead. Tested live
(multi-word text, punctuation, multi-line stdin input all delivered).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 15:40:22 -04:00
Andreas WredeandClaude Sonnet 5 d002058701 modem: add van-sms-watch to archive inbound SMS + Pushover alert
Polls ModemManager for SMS on the EC25's own flash storage, appends each
inbound message to /var/log/van-sms.jsonl, pages via Pushover (shared
van-battery creds), then deletes it from modem storage so it doesn't
silently fill up. MMS can't be decoded (WAP-push notification needs the
carrier's separate MMS APN) — detected and paged as notification-only.

Wired into deploy.sh; installed/verified live on the Pi (backlog SMS
archived + paged successfully) ahead of committing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 15:12:54 -04:00
Andreas Wrede 7a1c47d34c li3: add Lithionics Li3 house battery BMS -> Home Assistant MQTT
Publishes the RV's 12V LiFePO4 house battery to HA via MQTT discovery
(pack voltage, 4 cell voltages, current, SOC, BMS/battery temp, status).
Connects over the battery's BLE HM-10 UART module (service ffe0/char
ffe1, no pairing) using bleak; protocol reverse-engineered from the
com.lithionics.bms Android app's own BLE/parsing code.

Deliberately named li3/ and van-li3-battery, not battery/van-battery —
that name is reserved for the host's own AC/UPS power-supply monitor
(different hardware, unrelated concern).

Self-heals a bluetoothd discovery-state wedge (Discovering stuck "yes",
connects failing with le-connection-abort-by-local) that shows up after
repeated failed connects to this device on the Pi's onboard adapter: the
daemon retries scan/connect internally (MQTT session and HA entities
stay up across retries) and restarts bluetooth.service itself after 3
consecutive scan failures, rate-limited to once per 5 min.
2026-08-17 17:26:14 -04:00
Andreas WredeandClaude Sonnet 5 b7758c9cd5 ha: add Frigate NVR as a Podman Quadlet, wire into deploy.sh
Same sibling-container pattern as HA/ESPHome. The hand-written unit used
Privileged=true, which isn't a real Quadlet key — the generator silently
drops the whole file on an unsupported key, so frigate.service was never
generated (hence `systemctl enable frigate` saying the unit doesn't exist).
Fixed with PodmanArgs=--privileged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 21:12:45 -04:00
Andreas WredeandClaude Sonnet 5 af18dc0755 failover: wire up van-modem-watch in deploy.sh
Completes the van-modem-usb-kick -> van-modem-watch swap from the
previous commit: deploy.sh was still installing/enabling the old unit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 20:28:46 -04:00
Andreas WredeandClaude Sonnet 5 a1bad186b1 failover: add van-modem-usb-kick — recover EC25 modem when it never enumerates at boot
Seen after moving the modem onto the new powered UGreen hub: the port
sometimes never signals a connect during boot (no descriptor-read attempt at
all in dmesg), so the hub never rescans it. Unbind/rebinding the inner hub
chip reproduces the same connect edge a physical unplug/replug does.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 10:17:36 -04:00
Andreas Wrede e7a82126f2 power: add van-nvme-watch — pages on NVMe I/O-timeout/reset recurrence
Tails journalctl -kf for the "nvme nvmeN: I/O tag ... timeout, reset
controller" signature that crashed and corrupted the root fs on 2026-08-02
(and recurred 2026-08-04, that time self-healing). Watches a short grace
window to tell a clean self-heal from an escalation (repeated timeout or a
following ext4 error) before paging via the existing Pushover credentials,
with a live SMART/superblock snapshot in the alert body.
2026-08-04 08:44:53 -04:00
Andreas Wrede 86fa9509df failover: fix Starlink interface + template config.json from deploy.conf
STARLINK_IFACE pointed at the wrong device after the USB hub swap (was
accidentally set to the 5GHz AP dongle's interface). failover/config.json
also hardcoded the old interface name instead of being templated like the
other configs, so deploy.conf changes never reached it — switched it to
@STARLINK_IFACE@ and deploy.sh now renders it.
2026-08-04 08:35:18 -04:00
Andreas WredeandClaude Sonnet 5 8efb8dba5f dns: fixed 1.1.1.1/8.8.8.8 lockdown + scoped mDNS, esphome sibling container
- deploy.conf: DNS_RESOLVERS, always 1.1.1.1/8.8.8.8, never a WAN's own
  DHCP/RA-provided servers (previously whatever Wapana handed out).
- ap/99-van-router-dns.conf: global resolved config (fixed DNS, Domains=~.,
  global MulticastDNS=yes — a prerequisite for any per-link mDNS to work at
  all, not just an on/off toggle).
- failover/60-van-wan-dns: NM dispatcher that strips each WAN's DNS/search-
  domain and disables its mDNS via resolvectl on every connect/lease event
  (NM's own ipv4/ipv6.ignore-auto-dns can't be set as a config-file default —
  confirmed rejected as an unknown key — so this enforces it directly
  instead), retried over ~5s to beat NM's own async DNS commit. Also logs
  what each WAN advertised, never used, to /run/van-wan-dns/.
- ap/21-van-br0.network: MulticastDNS=yes, scoped to the van's own LAN only
  — .local/mDNS now resolves for ESPHome and other LAN devices without
  leaking mDNS onto Wapana/Starlink/cellular.
- dns/: ZeroTier-managed DNS (zt.wrede.pvt) made reproducible — installed
  the official zerotier-systemd-manager package (verified against upstream
  checksums), additive to the above so *.zt.wrede.pvt keeps resolving over
  the overlay independent of WAN.
- ha/esphome.container: ESPHome dashboard as a sibling Podman Quadlet to
  Home Assistant, same host-network/config-volume pattern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 16:09:01 -04:00