Spec: LAN_IFACE rename, host files in repo via /etc/vanlink.conf symlink
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Host-local configuration for multi-host vanlink
|
# Host-local configuration for multi-host vanlink
|
||||||
|
|
||||||
Date: 2026-09-23. Status: draft for review.
|
Date: 2026-09-23. Status: approved by user; revised 2026-09-23 (LAN_IFACE rename, symlinked host config).
|
||||||
|
|
||||||
## Problem
|
## Problem
|
||||||
|
|
||||||
@@ -28,16 +28,34 @@ Other host-specific values are hardcoded outside `deploy.conf`: `van-br0-setup.s
|
|||||||
## Decisions already made
|
## Decisions already made
|
||||||
|
|
||||||
- One git repo, cloned on every host, same branch; no per-host copies or branches.
|
- One git repo, cloned on every host, same branch; no per-host copies or branches.
|
||||||
- All host-specific values live in `/etc/vanlink.conf` on the host, outside the repo.
|
- All host-specific values live in one file per host under `hosts/` in the repo, and
|
||||||
|
`/etc/vanlink.conf` on each host is a symlink to that host's file. (Revised from
|
||||||
|
"outside the repo": one versioned source of truth per host, no drift, `git pull`
|
||||||
|
carries config changes.)
|
||||||
- Per-host optional services are controlled by explicit feature flags in that file.
|
- Per-host optional services are controlled by explicit feature flags in that file.
|
||||||
- `deploy.sh` keeps rendering `@TOKEN@` placeholders at deploy time (approach A);
|
- `deploy.sh` keeps rendering `@TOKEN@` placeholders at deploy time (approach A);
|
||||||
services do not read `/etc/vanlink.conf` at runtime, except the two backup shell scripts.
|
services do not read `/etc/vanlink.conf` at runtime, except the two backup shell scripts.
|
||||||
|
|
||||||
## Design
|
## Design
|
||||||
|
|
||||||
### 1. `/etc/vanlink.conf`
|
### 1. Host config file and the `/etc/vanlink.conf` symlink
|
||||||
|
|
||||||
Plain `KEY=value` lines, comments allowed, no secrets (mode 0644). It is valid shell,
|
Each host has `hosts/<hostname>.conf` (named by `hostname -s`, so `hosts/van.conf`
|
||||||
|
for the R5C and `hosts/wan.conf` for the Pi 5; a hardware swap does not rename a
|
||||||
|
host). `/etc/vanlink.conf` is an absolute symlink to it:
|
||||||
|
`sudo ln -sfn "$PWD/hosts/$(hostname -s).conf" /etc/vanlink.conf`. Everything reads
|
||||||
|
`/etc/vanlink.conf`, so there is one fixed path. Consequences, accepted:
|
||||||
|
|
||||||
|
- Editing a host's values means committing to `hosts/<hostname>.conf` (on the host or
|
||||||
|
the laptop) and pulling; there is no invisible per-host drift, but a dirty checkout
|
||||||
|
on a host is still possible and `deploy.sh` reports it (see 3).
|
||||||
|
- Root `source`s a file writable by the checkout's owner. Fine on these single-user
|
||||||
|
boxes (that user has sudo anyway); it is also why the file must never hold secrets.
|
||||||
|
- If the checkout is moved the symlink dangles; `deploy.sh` says so and prints the
|
||||||
|
`ln` command.
|
||||||
|
|
||||||
|
Plain `KEY=value` lines, comments allowed, **no secrets** (it is in git and read by
|
||||||
|
root). It is valid shell,
|
||||||
so `deploy.sh` and the backup scripts `source` it. Every variable below is **required**
|
so `deploy.sh` and the backup scripts `source` it. Every variable below is **required**
|
||||||
unless marked optional: `deploy.sh` aborts naming any missing one, so a variable added
|
unless marked optional: `deploy.sh` aborts naming any missing one, so a variable added
|
||||||
in a later release fails loudly on hosts that have not adopted it instead of silently
|
in a later release fails loudly on hosts that have not adopted it instead of silently
|
||||||
@@ -46,7 +64,7 @@ defaulting.
|
|||||||
| Group | Variable | Meaning / used by |
|
| Group | Variable | Meaning / used by |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Interfaces | `WIFI_5G_IFACE`, `WIFI_2G_IFACE` | AP radios (hostapd, networkd, br0-setup) |
|
| Interfaces | `WIFI_5G_IFACE`, `WIFI_2G_IFACE` | AP radios (hostapd, networkd, br0-setup) |
|
||||||
| | `LAN_USB_IFACE` | wired LAN port bridged into br0 (name kept to limit churn) |
|
| | `LAN_IFACE` | wired LAN port bridged into br0 (renamed from `LAN_USB_IFACE`; the R5C's is PCIe) |
|
||||||
| | `STARLINK_IFACE` | Starlink uplink (netplan, failover, status) |
|
| | `STARLINK_IFACE` | Starlink uplink (netplan, failover, status) |
|
||||||
| | `WIFI_WAN_IFACE` (new) | Wi-Fi uplink, currently hardcoded `wlan0` |
|
| | `WIFI_WAN_IFACE` (new) | Wi-Fi uplink, currently hardcoded `wlan0` |
|
||||||
| | `ONBOARD_LAN_IFACE` (new, optional) | extra onboard LAN port bridged into br0 (Pi: `eth0`); empty = none |
|
| | `ONBOARD_LAN_IFACE` (new, optional) | extra onboard LAN port bridged into br0 (Pi: `eth0`); empty = none |
|
||||||
@@ -69,10 +87,9 @@ because a host uses one backup method or neither.
|
|||||||
|
|
||||||
- `deploy.conf` is deleted.
|
- `deploy.conf` is deleted.
|
||||||
- `hosts/vanlink.conf.example`: every variable with a comment (the reference).
|
- `hosts/vanlink.conf.example`: every variable with a comment (the reference).
|
||||||
- `hosts/r5c.conf`, `hosts/pi5.conf`: known-good values for the two hosts. Used as test
|
- `hosts/van.conf` (R5C), `hosts/wan.conf` (Pi 5): the real, versioned values for the
|
||||||
input for `--check` and as the starting point on a host:
|
two hosts, also the test input for `--check`. `deploy.sh` never creates the symlink or
|
||||||
`sudo install -m0644 hosts/r5c.conf /etc/vanlink.conf`. `deploy.sh` never writes or
|
edits these files.
|
||||||
overwrites `/etc/vanlink.conf`.
|
|
||||||
- New tokens: `@WIFI_WAN_IFACE@`, `@ONBOARD_LAN_IFACE@`, `@NVME_DEVICE@`,
|
- New tokens: `@WIFI_WAN_IFACE@`, `@ONBOARD_LAN_IFACE@`, `@NVME_DEVICE@`,
|
||||||
`@NVME_FS_DEVICE@`. `van-br0-setup.service`, `failover/config.json`,
|
`@NVME_FS_DEVICE@`. `van-br0-setup.service`, `failover/config.json`,
|
||||||
`router-status/config.json`, `ap/50-van-wan.yaml`, `ap/van-ap-unmanaged.conf`,
|
`router-status/config.json`, `ap/50-van-wan.yaml`, `ap/van-ap-unmanaged.conf`,
|
||||||
@@ -82,8 +99,10 @@ because a host uses one backup method or neither.
|
|||||||
|
|
||||||
### 3. `deploy.sh` behaviour
|
### 3. `deploy.sh` behaviour
|
||||||
|
|
||||||
- Config path is `${VANLINK_CONF:-/etc/vanlink.conf}`. Missing file: abort with the
|
- Config path is `${VANLINK_CONF:-/etc/vanlink.conf}`. Missing or dangling symlink:
|
||||||
install command above. Missing/empty required variable: abort naming it.
|
abort with the `ln` command for this host. Missing/empty required variable: abort
|
||||||
|
naming it. It prints the resolved file it is using, and warns if that file has
|
||||||
|
uncommitted changes (`git status`) so a deploy from unreviewed values is visible.
|
||||||
- `install_rendered` refuses to install any output that still matches
|
- `install_rendered` refuses to install any output that still matches
|
||||||
`@[A-Z][A-Z0-9_]*@` and aborts before anything is restarted. Every file containing a
|
`@[A-Z][A-Z0-9_]*@` and aborts before anything is restarted. Every file containing a
|
||||||
token must be installed through it (enforced by the test below).
|
token must be installed through it (enforced by the test below).
|
||||||
@@ -124,13 +143,14 @@ or with the cabling settled (see Migration); a deploy restarts `systemd-networkd
|
|||||||
## Migration
|
## Migration
|
||||||
|
|
||||||
1. Implement and merge on `wan`, run the test script, push.
|
1. Implement and merge on `wan`, run the test script, push.
|
||||||
2. **R5C:** write `/etc/vanlink.conf` from its current `deploy.conf` (interfaces as
|
2. **R5C:** create `hosts/van.conf` from its current `deploy.conf` (interfaces as
|
||||||
currently swapped), `git clone` the repo next to the stale copy, keep the old
|
currently swapped) in the repo, commit and push; on the R5C `git clone` next to the
|
||||||
directory as `vanlink.old`, run `--check`, then deploy.
|
stale copy, keep the old directory as `vanlink.old`, make the symlink, run
|
||||||
3. **Pi 5:** write `/etc/vanlink.conf` from its `deploy.conf` (its real interfaces,
|
`--check`, then deploy.
|
||||||
|
3. **Pi 5:** create `hosts/wan.conf` from its `deploy.conf` (its real interfaces,
|
||||||
`10.42.0.x`, `ENABLE_LI3=0`, `ENABLE_COCKPIT=0`, `ENABLE_HA` etc. as it is today);
|
`10.42.0.x`, `ENABLE_LI3=0`, `ENABLE_COCKPIT=0`, `ENABLE_HA` etc. as it is today);
|
||||||
copy its 4 modified files to a backup directory; `git checkout -- .` and fast-forward
|
copy its 4 modified files to a backup directory; `git checkout -- .` and fast-forward
|
||||||
to the shared `wan`; `--check`; deploy. Its existing behaviour must not change: `diff`
|
to the shared `wan`; make the symlink; `--check`; deploy. Its existing behaviour must not change: `diff`
|
||||||
the rendered files against what is currently in `/etc` before restarting anything.
|
the rendered files against what is currently in `/etc` before restarting anything.
|
||||||
4. `main` is brought up to date with `wan` afterwards (separate decision; hosts follow
|
4. `main` is brought up to date with `wan` afterwards (separate decision; hosts follow
|
||||||
`wan`).
|
`wan`).
|
||||||
@@ -150,7 +170,6 @@ the safety net for the Pi 5).
|
|||||||
|
|
||||||
## Open questions for review
|
## Open questions for review
|
||||||
|
|
||||||
1. Keep `LAN_USB_IFACE` as the name even though the R5C's port is PCIe, or rename to
|
None open. Resolved: `LAN_USB_IFACE` becomes `LAN_IFACE` (the `lan_usb_iface` key in
|
||||||
`LAN_IFACE` (touches 5 templates)? Draft keeps it.
|
`router-status/config.json` is a consumer-facing name and stays); host files live in
|
||||||
2. Are `hosts/r5c.conf` / `hosts/pi5.conf` acceptable in the repo as reference values
|
the repo and are reached through the `/etc/vanlink.conf` symlink.
|
||||||
(interface names and IPs, no secrets)? They deliberately are not read by deploy.sh.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user