Thomas Stallinger d496adad09 installer: Installations-Meilensteine/Fehlschlaege an anode melden
Neue scripts/lib/reporting.sh (tuxflotte_report_installation_event())
meldet best-effort an POST /api/v1/devices/{device_id}/installation-events
(device_fingerprint-authentifiziert, siehe provisioning-server-Commit
51fbf0f) - ein Fehlschlag beim Melden selbst darf die eigentliche
Installation nie aufhalten.

Vier Meldepunkte:
- "activation_confirmed" direkt nach erfolgreichem Provisioning-Handshake
  (15_server_handshake.sh)
- "installation_started" direkt nach bestaetigtem Commit Point
  (installer.sh)
- "installation_completed" ganz am Ende von backend_postinstall(), vor dem
  finalen Reboot (backend.sh)
- "installation_failed" zentral in boot-autostart.sh (einziger Ort, an dem
  der echte Exit-Code von installer.sh bekannt ist, ohne jedes Modul
  einzeln instrumentieren zu muessen) - Detail = letzte 40 Logzeilen,
  enthalten bereits die eigentliche [FEHLER]-Meldung des gescheiterten
  Moduls. Nur bei STATUS != 0, nicht bei einem kontrollierten Abbruch an
  einem Commit-Gate (STATUS = 0).

Nutzer-Wunsch (01.09.2026, nach dem ersten echten Hardware-Test):
Fehlschlaege waehrend der Installation sichtbar machen, ohne am
Bildschirm mitschreiben zu muessen ("das ist kein Flow... fuer die
Weiterentwicklung eines irgendwann fehlerfreien Betriebs sind fuer uns
diese Meldungen Gold wert").

Live in QEMU end-to-end verifiziert: alle drei Erfolgs-Meilensteine
korrekt in device_installation_events angekommen (activation_confirmed,
installation_started, installation_completed), vollstaendiger Durchlauf
bis zum echten Mint-Cinnamon-Login-Bildschirm nach Reboot bestaetigt.
2026-09-01 16:52:15 +02:00

62 lines
2.7 KiB
Bash

#!/usr/bin/env bash
# Meldet Installations-Meilensteine/Fehlschlaege an anode (device_installation_events,
# siehe Migration 0025 in provisioning-server) - ausschliesslich fuer die eigene
# Fehlersuche/Betriebsentwicklung gedacht ("Gold wert" fuer den Support, Nutzer-Wunsch
# 01.09.2026 nach dem ersten echten Hardware-Test), noch NICHT zwangslaeufig auf der
# Kunden-Oberflaeche sichtbar - das ist eine separate, noch offene Entscheidung.
#
# Rein melde-basiert und best effort: das Geraet hat waehrend der Installation noch
# kein agent_secret (das entsteht erst ganz am Ende in backend_postinstall()), deshalb
# device_fingerprint als Nachweis statt eines Service-Tokens (siehe
# InstallationEventRequest/device_fingerprint_matches() serverseitig - gleiches
# Vertrauensniveau wie /api/v1/activate selbst). Ein Fehlschlag beim Melden selbst
# (Netzwerk gerade weg, Server nicht erreichbar, Geraet noch nicht aktiviert) darf die
# eigentliche Installation NIE aufhalten - deshalb "|| true" ueberall, kein "set -e"-
# Abbruch moeglich, keine Rueckgabewert-Pruefung durch die Aufrufer noetig.
tuxflotte_report_installation_event() {
local event_type="$1"
local detail="${2:-}"
local response_file="/run/tuxflotte/server/response.json"
local hardware_file="/run/tuxflotte/hardware/hardware.json"
local network_state="/run/tuxflotte/network/state.env"
[[ -r "${response_file}" && -r "${hardware_file}" && -r "${network_state}" ]] || return 0
local device_id device_fingerprint server_url payload
device_id="$(jq --raw-output '.device.id // empty' "${response_file}" 2>/dev/null)"
device_fingerprint="$(jq --raw-output '.identity.device_fingerprint // empty' "${hardware_file}" 2>/dev/null)"
[[ -n "${device_id}" && -n "${device_fingerprint}" ]] || return 0
# shellcheck disable=SC1090
source "${network_state}" 2>/dev/null || return 0
server_url="${TUXFLOTTE_SERVER_URL%/health}"
[[ -n "${server_url}" ]] || return 0
payload="$(
jq --null-input \
--arg device_fingerprint "${device_fingerprint}" \
--arg event_type "${event_type}" \
--arg detail "${detail}" \
'{
device_fingerprint: $device_fingerprint,
event_type: $event_type,
detail: (if $detail == "" then null else $detail end)
}' 2>/dev/null
)"
[[ -n "${payload}" ]] || return 0
curl \
--silent \
--show-error \
--fail \
--location \
--max-time 5 \
--header 'Content-Type: application/json' \
--data-binary "${payload}" \
"${server_url}/api/v1/devices/${device_id}/installation-events" \
>/dev/null 2>&1 || true
}