Document the Raspberry Pi Imager customisation gotcha and current repo layout

1.9.6 (the newest Flathub offers) silently no-ops on cloud-init
customisation for this Trixie image, only writing the kernel
regdomain cmdline param — looks exactly like a wifi bug but is really
a missing-credentials-on-the-card bug. Also brings the README's
host_vars paths, vault usage, and role list up to date with the
wifi role / vault work.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-07-06 21:17:39 +01:00
co-authored by Claude Sonnet 5
parent a1ba1a9603
commit 77562b1591
+23 -20
View File
@@ -19,19 +19,17 @@ pip install ansible
```
**New Pi node checklist:**
1. Flash Raspberry Pi OS Lite (Trixie), connect to WiFi
2. Install Tailscale and join the network
3. Ensure `david` user exists with sudo access
4. Connect the MeshCore device via USB, then find its serial ID:
```bash
ls /dev/serial/by-id/
```
5. Set `serial_port` in `ansible/host_vars/<hostname>.yml`
1. Flash Raspberry Pi OS Lite (Trixie) with Raspberry Pi Imager, using "Edit Settings" (OS customisation) to set hostname, the `david` user + password, and the `dotnetwork` wifi (SSID/password only — the imager only supports one network at flash time; the deployed-location and `dotmobile` networks get added later by the `wifi` role, see below)
2. **Before ejecting the card**, verify the customisation actually got written — mount the boot partition and check `network-config`/`user-data` aren't just the commented-out stock template (see "Imager gotcha" below). Only `cmdline.txt`'s regdomain getting a fresh timestamp while the rest stay at the image's build date is the tell that it silently failed.
3. Boot the Pi, confirm SSH access (password auth, since no key is seeded at flash time)
4. Add `serial_port` (and `wifi_ssid_location`) to `ansible/host_vars/<hostname>/vars.yml`, and the location wifi password to `ansible/host_vars/<hostname>/vault.yml` (see "Vault" below)
5. Run `site.yml` against just that host (see Usage) — this authorizes your SSH keys, joins the deployed-location + dotmobile wifi networks, installs Tailscale, and deploys everything else in one pass
SSH key auth is required. From this machine:
```bash
ssh-copy-id david@<hostname>.tail740bb.ts.net
```
### Imager gotcha (2026-07)
The Raspberry Pi Imager available via Flathub (`org.raspberrypi.rpi-imager`) is stuck on **1.9.6** and there's no newer `.deb`/Flatpak in the Ubuntu or Flathub repos either — Flathub hasn't published the 2.0.x rewrite. 1.9.6 silently fails to apply OS customisation (hostname, user, SSH, wifi) on newer Raspberry Pi OS Trixie images: it only writes the kernel `cfg80211.ieee80211_regdom=` cmdline parameter and leaves `user-data`/`network-config` as the stock commented-out template, with no error. The result looks exactly like a wifi problem (Pi never appears on the network) but is actually "the card has no credentials on it at all."
Fix: grab the real `.deb` from the [GitHub releases page](https://github.com/raspberrypi/rpi-imager/releases) (e.g. `rpi-imager_2.0.10_amd64.deb`) and `sudo dpkg -i` it — that version writes the customisation correctly.
## Usage
@@ -57,20 +55,25 @@ You'll be prompted for a Tailscale auth key — leave blank if the node is alrea
## What it does
1. **base** — apt upgrade, installs screen/pipx/vnstat/git, sets MOTD, installs and authenticates Tailscale
2. **meshcore_cli** — installs `meshcore-cli` via pipx
3. **meshcore_capture** — runs the agessaman/meshcore-packet-capture install script, writes `.env.local` config, enables `meshcore-capture.service`, deploys update/log helper scripts
4. **scripts** — deploys `voltage.sh` and `bandwidth.sh`
1. **wifi**configures NetworkManager connections for `dotnetwork` (home), `dotmobile` (phone hotspot, field troubleshooting fallback), and the host's deployed-location network
2. **base**apt upgrade, installs screen/pipx/vnstat/git, sets MOTD, authorizes SSH keys for both laptop partitions, installs and authenticates Tailscale
3. **meshcore_cli**installs `meshcore-cli` via pipx
4. **meshcore_capture**runs the agessaman/meshcore-packet-capture install script, writes `.env.local` config, enables `meshcore-capture.service`, deploys update/log helper scripts
5. **scripts** — deploys `voltage.sh` and `bandwidth.sh`
## Config
Shared MQTT config lives in `group_vars/meshcore.yml`. Per-host serial port is in `host_vars/<hostname>.yml`.
Shared MQTT config lives in `group_vars/meshcore.yml`. Per-host serial port and wifi SSID are in `host_vars/<hostname>/vars.yml`.
Running the playbook again re-applies `.env.local` and restarts the service if it changed — safe to run on already-deployed nodes.
## Credentials note
## Vault
`group_vars/meshcore.yml` contains MQTT credentials in plaintext. Consider encrypting with Ansible Vault if this repo is shared:
`group_vars/all/vault.yml` (shared wifi/SSH secrets) and `host_vars/<hostname>/vault.yml` (per-host deployed-location wifi password) are encrypted with Ansible Vault. `ansible.cfg` points at `../.vault_pass` (gitignored, not committed) for the password — ask David for a copy, or generate a fresh one and re-encrypt if starting over:
```bash
ansible-vault encrypt_string 'yourpassword' --name mqtt_ukmesh_password
ansible-vault view --vault-password-file ../.vault_pass group_vars/all/vault.yml
ansible-vault edit --vault-password-file ../.vault_pass host_vars/dm-edworth/vault.yml
```
`*/vault.yml.example` shows the expected keys.
`group_vars/meshcore.yml` (MQTT credentials) is still plaintext — consider moving it into the vault too if this repo is shared further.