Commit Graph

2 Commits (aa4bc7ae1ea14096fd4e4b9d96714dd93b272063)

Author SHA1 Message Date
Amir Alexander Abdelbaki ea82ee70ad Add tools/ and CoreSystemConfig.json — one source of truth for every build
Installation was six scripts each carrying its own copy of the container host's
IP, three that had to agree on IDENTITY_TOKEN, and every service URL typed by
hand with a port in it. Any one could be wrong, and the symptom was always the
same and always late: an image that boots fine and then can't reach something,
found after a 40-minute build and a reboot.

Two properties fix that class of bug:

- Nothing is written twice. No script in tools/ contains an IP, port or token.
- Anything derivable is derived. You give the subnet prefix once and one last
  octet per host; every address and service URL is computed from those.

THE TWINNED PAIR. container_host.ip_last_octet 12 and llm_host 13 mean the
container host's OLLAMA_HOST *is* http://<prefix>.13:11434 — computed in the
same build, not typed into two files and kept in sync. Move the LLM host to .21
and the container host's Ollama URL follows; change the subnet and both halves
move along with every kiosk's URLs. Neither image can be built pointing at an
address the other isn't using. Both carry the same SMARTHOME_PAIR_ID (a hash of
the config's meaning, not its bytes) so two USB sticks can be checked against
each other later.

validate-config.py runs before every build and refuses to start on an error, so
a mistake costs seconds not an hour. It catches duplicate ports (including the
music_assistant/pantry_vision 8095 clash that Compose can't see because MA runs
network_mode:host — open decision #31), both hosts on one address, duplicate
hostnames across kiosks and audio endpoints, placeholder tokens (checked before
the length check, so padding "changeme" to 32 chars doesn't pass), a private key
pasted where the public one goes, and a kiosk pointed at a disabled service.

build-all.sh is the normal entry point — the images are a set that has to agree
with itself, so building one is the exception. It builds the core pair, every
kiosk, and every audio endpoint including both architectures (amd64 live-build
ISO and arm64 rpi-image-gen img are different toolchains, not one image).

The two new host ISOs install unattended with everything burnt in, including
service env files generated from derived values — which permanently removes the
class of bug that had chores.env shipping IDENTITY_URL=http://127.0.0.1:8097.
setup-container-host.sh and setup-llm-host.sh now read every config value as
${VAR:-default} so the images configure them without editing.

That also makes every ISO a credential: Wi-Fi PSK, tokens, MQTT and HA
credentials are readable by anyone holding the stick. .gitignore covers the
filled-in CoreSystemConfig.json and build-output/.

Tested: 43 config validation/derivation checks and 44 builder checks against the
real code paths with only `lb` stubbed — every generated env file, preseed,
network config, first-boot unit and build stamp is verified, including that a
port collision refuses the build before writing anything. No ISO has been built;
`lb build` needs live-build, root and a long fetch. tools/README.md says so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-31 13:22:25 +02:00
Amir Alexander Abdelbaki bfca1c7eb0 Add idle-gallery weather/clock overlay and headless audio endpoint images
Two additions:

- Thin client: an eww weather/clock overlay over the idle-gallery slideshow.
  Time/date come from the local clock, weather from a new retained MQTT topic
  (smarthome/weather/current) an HA automation has to publish — degrades to
  clock-only if that never happens. idle-gallery.sh owns the overlay's
  visibility, mirroring how fullscreen-watcher.sh already owns the
  now-playing widget's.

- hosts/audio-endpoint/: headless, per-room-independent Spotify Connect
  appliances for rooms without a thin client, no shared/synced stream. Two
  build pipelines sharing one architecture-independent systemd
  unit/wrapper: arm64 (Raspberry Pi + HiFiBerry Amp2) via rpi-image-gen
  producing a real flashable .img, and amd64 (mini PC + USB DAC/amp) reusing
  the thin client's own live-build toolchain stripped of its graphical/kiosk
  stack. Both reuse the thin client's existing apt-first/documented-fallback
  Spotify Connect install logic rather than reinventing it. rpi-image-gen's
  exact config schema is flagged explicitly as unverified — no ARM build
  environment was available to validate it against the real tool.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WgTwMqiho8DT6ue5S49WBP
2026-07-29 11:37:29 +02:00