Files
dotmesh-monitor/README.md
T
davidandClaude Sonnet 5 77562b1591 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]>
2026-07-06 21:17:39 +01:00

4.5 KiB

dotmesh-monitor

Ansible playbooks for deploying MeshCore monitoring nodes (Raspberry Pi Zero W / Zero 2 W).

Hosts

Host Hardware Group
dm-baldock Pi Zero W (armv6) zero_w
dm-ashwell Pi Zero 2 W (armv7) zero2_w
dm-edworth Pi Zero 2 W (armv7) zero2_w

Prerequisites

Local machine:

pip install ansible
# or: sudo apt install ansible

New Pi node checklist:

  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

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 (e.g. rpi-imager_2.0.10_amd64.deb) and sudo dpkg -i it — that version writes the customisation correctly.

Usage

Deploy to a single host (recommended for first run / testing):

cd ansible
ansible-playbook -i inventory.yml site.yml --limit dm-edworth

Deploy to all nodes:

ansible-playbook -i inventory.yml site.yml

Dry run:

ansible-playbook -i inventory.yml site.yml --limit dm-edworth --check

If sudo requires a password, add --ask-become-pass.

You'll be prompted for a Tailscale auth key — leave blank if the node is already authenticated.

What it does

  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 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.

Vault

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:

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.