- Command intake (reboot/shutdown) on infoscreen/{uuid}/commands with ack lifecycle
- MQTT_USER/MQTT_PASSWORD_BROKER split from identity vars; configure_mqtt_security() updated
- infoscreen-simclient.service: Type=notify, WatchdogSec=60, Restart=on-failure
- infoscreen-notify-failure@.service + script: retained MQTT alert when systemd gives up (Gap 3)
- _sd_notify() watchdog keepalive in simclient main loop (Gap 1)
- broker_connection block in health payload: reconnect_count, last_disconnect_at (Gap 2)
- COMMAND_MOCK_REBOOT_IMMEDIATE_COMPLETE canary flag with safety guard
- SERVER_TEAM_ACTIONS.md: server-side integration action items
- Docs: README, CHANGELOG, src/README, copilot-instructions updated
- 43 tests passing
56 lines
1.8 KiB
Bash
Executable File
56 lines
1.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Publishes a service-failed MQTT notification when called by systemd OnFailure=.
|
|
# Usage: infoscreen-notify-failure.sh <failing-unit-name>
|
|
#
|
|
# Designed to be called from infoscreen-notify-failure@.service.
|
|
# Reads broker credentials from .env; reads client UUID from config.
|
|
# Safe to run even if MQTT is unreachable (exits cleanly, errors logged to journal).
|
|
|
|
set -euo pipefail
|
|
|
|
FAILING_UNIT="${1:-unknown}"
|
|
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
ENV_FILE="$PROJECT_DIR/.env"
|
|
UUID_FILE="$PROJECT_DIR/src/config/client_uuid.txt"
|
|
|
|
# Load .env (skip comments and blank lines)
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
set -a
|
|
# shellcheck source=/dev/null
|
|
source <(grep -v '^\s*#' "$ENV_FILE" | grep -v '^\s*$')
|
|
set +a
|
|
fi
|
|
|
|
MQTT_BROKER="${MQTT_BROKER:-localhost}"
|
|
MQTT_PORT="${MQTT_PORT:-1883}"
|
|
MQTT_USER="${MQTT_USER:-}"
|
|
MQTT_PASSWORD_BROKER="${MQTT_PASSWORD_BROKER:-}"
|
|
|
|
CLIENT_UUID="unknown"
|
|
if [[ -f "$UUID_FILE" ]]; then
|
|
CLIENT_UUID="$(cat "$UUID_FILE" | tr -d '[:space:]')"
|
|
fi
|
|
|
|
TOPIC="infoscreen/${CLIENT_UUID}/service_failed"
|
|
TIMESTAMP="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
|
|
PAYLOAD=$(printf '{"event":"service_failed","unit":"%s","client_uuid":"%s","failed_at":"%s"}' \
|
|
"$FAILING_UNIT" "$CLIENT_UUID" "$TIMESTAMP")
|
|
|
|
# Build mosquitto_pub auth args
|
|
AUTH_ARGS=()
|
|
if [[ -n "$MQTT_USER" ]]; then AUTH_ARGS+=(-u "$MQTT_USER"); fi
|
|
if [[ -n "$MQTT_PASSWORD_BROKER" ]]; then AUTH_ARGS+=(-P "$MQTT_PASSWORD_BROKER"); fi
|
|
|
|
echo "Publishing service-failed notification: unit=$FAILING_UNIT client=$CLIENT_UUID"
|
|
|
|
mosquitto_pub \
|
|
-h "$MQTT_BROKER" \
|
|
-p "$MQTT_PORT" \
|
|
"${AUTH_ARGS[@]}" \
|
|
-t "$TOPIC" \
|
|
-m "$PAYLOAD" \
|
|
-q 1 \
|
|
--retain \
|
|
2>&1 || echo "WARNING: mosquitto_pub failed (broker unreachable?); notification not delivered"
|