Commit Graph
134 Commits
Author SHA1 Message Date
andreasandClaude Sonnet 5 5ce6996716 deploy: non-fatal service restarts; mosquitto password_file safeguard and post-check probe
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 22:29:51 -04:00
andreasandClaude Sonnet 5 da59562511 van-leds: fix stale-state test carrier
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 22:20:14 -04:00
andreasandClaude Sonnet 5 e2da20a1b9 van-leds fix round 2: state_max_age_s default 180, non-finite/invalid config guards, log-recurrence test
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 22:19:26 -04:00
andreasandClaude Sonnet 5 c7dff14807 van-leds fix round 1: realistic sysfs fake, error paths, stale failover state, log-once, interval and empty-iface guards
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 22:14:15 -04:00
andreasandClaude Sonnet 5 0f643be719 van-leds: drive the R5C power/LAN/WAN/WiFi LEDs (ENABLE_LEDS, LED_* vars, post-check probe)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 22:04:11 -04:00
andreasandClaude Sonnet 5 e2036c295d van-router-mqtt: subscribe and publish discovery in on_connect
Clean sessions lose subscriptions on reconnect and a refused first connect
loses the retained discovery, so both now happen on every successful connect.
Adds reason codes 132-136 and behavioural tests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 21:50:14 -04:00
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 Sonnet 5 1ce4a30336 Docs: README --force semantics; spec amendments for the pending conf, preflight and byte-identical netplan
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 20:01:45 -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 5c18bcdad6 Spec: record review-driven amendments to the NM WAN design
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 19:16:12 -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 640d6d245c Add implementation plan: NetworkManager-owned WANs
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 18:25:49 -04:00
andreasandClaude Sonnet 5 223652b834 Add design spec: NetworkManager-owned WANs provisioned by deploy.sh
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
2026-09-23 18:06:44 -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 3d117e714c Backup scripts read device/UUID/target from the host config
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 14:36:46 -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
andreasandClaude Sonnet 5 ab6c3b7c64 Add implementation plan for host-local /etc/vanlink.conf
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 13:42:57 -04:00
andreasandClaude Sonnet 5 06a16568f7 Spec: LAN_IFACE rename, host files in repo via /etc/vanlink.conf symlink
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 13:35:12 -04:00
andreasandClaude Sonnet 5 97dd23f5a6 Add design spec for host-local /etc/vanlink.conf
Moves host-specific configuration out of the repo so the Pi 5 and R5C
can share one git checkout, with feature flags and template checks.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 13:08:08 -04:00
andreasandClaude Sonnet 5 ebb2bcc626 Adapt sync-sd-backup.sh to eMMC-primary R5C layout
The eMMC is now the boot/root device and the SD card is a manual
failsafe. U-Boot has no persistent env and always prefers an SD with a
boot.scr, so the SD's boot script is kept dormant as
boot-failesafe-rename-to:boot.scr.

- Locate the SD by root UUID instead of /dev/mmcblk0p2
- Preserve the SD's dormant boot script; never create a live boot.scr
  and refresh the dormant copy from the eMMC
- Copy fstab and armbianEnv.txt with the root UUID rewritten to the SD's
- Add rsync -x; drop the Pi-specific /boot/firmware exclude

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 12:26:03 -04:00
andreas 4b7c360095 Document R5C boot failure and recovery plan
SD card filesystem corrupted: ext4 journal version incompatible with
standard e2fsck (1.47.2 from Linux host). Filesystem inaccessible.

Root cause: Podman homeassistant container startup during network
instability and system reconfiguration caused unclean shutdown and
filesystem corruption.

Recovery: Flash fresh Armbian 6.18, run deploy.sh with fixes:
- DNS resolution fix added to HOMEASSISTANT.md
- resolv.conf fix should be added to deploy.sh post-processing
- Deploy containers after network is stable

All scripts and configs are ready and committed. Only need fresh SD card.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-19 15:37:25 -04:00
andreas 6d9c4f69cd Fix DNS resolver after disabling systemd-resolved
Root cause: /etc/resolv.conf was a broken symlink to systemd-resolved's
stub resolver, which doesn't exist after disabling the service.

Fixed by creating proper /etc/resolv.conf pointing to dnsmasq on 10.42.1.1
and upstream resolvers (1.1.1.1, 8.8.8.8).

This fix allows apt-get to work again and enables podman installation.

**Result: ✅ podman installed, homeassistant container starting**
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-19 13:52:05 -04:00
andreas a12869ceb1 Document homeassistant migration and network blocker
Added HOMEASSISTANT.md with migration steps and configuration details.
Home Assistant config copied to R5C at /srv/homeassistant.

**BLOCKED**: podman installation fails on R5C due to extreme network latency
(1000+ ms Starlink connection) and DNS resolution failures. Package downloads
fail consistently.

Migration can proceed once R5C network is stable enough for apt-get to complete.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-19 13:46:22 -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