First catalog apps to exercise core 26.17's app-to-app dependency feature — until now every app was standalone. - mosquitto: MQTT broker, first dependency *provider*. Mandatory auth; per-consumer accounts created by on_install/on_start hooks (scripts/provision-client.sh, scripts/ensure-client.sh) that run inside the broker container via `docker compose exec`. Provider-side password stash so on_start can restore an account after a volume wipe. - zigbee2mqtt: first dependency *consumer*. `requires` mosquitto; MQTT creds wired in from the provisioning hook via ZIGBEE2MQTT_CONFIG_* env. Serial coordinator path as a text setting + devices mapping. Supporting changes: - Bump vendored furtka_manifest.py (26.10-era -> 26.17) so the validator actually validates the `requires` schema instead of ignoring it. - Document `requires`/hooks in apps/README.md (was undocumented), including the three framework gaps building this pair surfaced. - CI now shellchecks app hook scripts (apps/*/scripts/*.sh), not just repo-root scripts/. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
40 lines
1.7 KiB
Bash
Executable file
40 lines
1.7 KiB
Bash
Executable file
#!/bin/sh
|
|
# on_install hook (provider: mosquitto).
|
|
#
|
|
# Runs ONCE, INSIDE the mosquitto container, via `docker compose exec sh -s`
|
|
# while a consumer app that `requires` mosquitto is being installed. The
|
|
# reconciler/install-runner exports FURTKA_CONSUMER_APP (the app being
|
|
# installed) into our environment. stdout KEY=VALUE lines are merged into the
|
|
# consumer's .env (hook wins on conflict), so this is how the consumer learns
|
|
# its broker address and credentials.
|
|
#
|
|
# Why we stash the password provider-side: the on_start hook (ensure-client.sh)
|
|
# gets NO access to the consumer's stored password and its stdout is discarded,
|
|
# so it cannot re-create the same account after a passwd wipe unless we keep a
|
|
# copy here, on mosquitto's own persistent data volume.
|
|
set -eu
|
|
|
|
user="${FURTKA_CONSUMER_APP:?provision-client: FURTKA_CONSUMER_APP not set}"
|
|
passwd_file=/mosquitto/data/passwd
|
|
stash_dir=/mosquitto/data/furtka-clients
|
|
stash="${stash_dir}/${user}.pw"
|
|
|
|
umask 077
|
|
mkdir -p "$stash_dir"
|
|
|
|
# One random 32-char password per consumer, generated once and stashed.
|
|
pass="$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 32)"
|
|
printf '%s' "$pass" > "$stash"
|
|
|
|
# -b: batch mode (user + password as args). Creates the account, or updates
|
|
# it if this consumer is being reinstalled.
|
|
mosquitto_passwd -b "$passwd_file" "$user" "$pass"
|
|
|
|
# Reload the password file so the new account is usable without bouncing the
|
|
# broker. PID 1 in this container is mosquitto (see compose `exec mosquitto`).
|
|
kill -HUP 1 2>/dev/null || true
|
|
|
|
# Handed back to the install runner and merged into the consumer's .env.
|
|
echo "MQTT_SERVER=mqtt://host.docker.internal:1883"
|
|
echo "MQTT_USER=${user}"
|
|
echo "MQTT_PASS=${pass}"
|