07 Runbook opérations

Diagnostic et recovery sur incidents en production

Symptômes à observer côté Indaba alerting

Alerte IndabaCause probableAction runbook
life_counter figé entre 2 health POSTs Flow LuvitRED bloqué ou crashed § Flow freeze
Pas de health POST reçu depuis 1 h WAN down OR auth DAP perdue OR CG down § Health silent
401 répétés sur uplinks Token DAP invalide/expiré, retry auto en boucle § DAP 401 loop
425 sur Token Device pas encore validé par Jean-Marc dans IoBase portal § DAP pending validation
Asystom 401 Mauvais credentials Basic auth § Asystom auth
Pas d'uplink balise depuis > 30 min Balise morte, trop loin, magnet à refaire § Balise silencieuse

Flow freeze (life_counter figé)

  1. SSH la CG : ssh admin@<ip>
  2. Vérifier que LuvitRED tourne : ps | grep luvit
  3. Si crashé : /etc/init.d/luvitred restart (au boot suivant le flow se reload + restore tokens)
  4. Si le flow tourne mais figé : ouvrir LuvitRED admin, regarder le debug sidebar pour erreurs Lua
  5. Last resort : factory reset → re-provisionner depuis CloudGate Universe → re-enrôlement DAP avec Jean-Marc

Health silent

  1. Check WAN : depuis l'admin CG /api/internetConnectionconnectionStatus: 1 attendu
  2. Si WAN OK mais health silent : check tokens DAP (§ DAP 401)
  3. Si WAN KO : c'est attendu, les health sont en queue offline (15 j max)
  4. Vérifier que le canvas debug montre les HEALTH_OUT + HEALTH_RESP alternés

DAP 401 loop

Comportement normal du canvas :

  1. POST IoBase prend 401
  2. handle_iobase_resp détecte → fn_trigger_refresh_on_401build_dap_refresh (mutex)
  3. POST /refresh → nouveaux tokens
  4. Trame en queue replay automatiquement avec le nouveau token

Pathologies à investiguer :

DAP 425 — pending admin validation

Au premier enrôlement seulement. Réponse 425 Authorization Pending sur /Token = Jean-Marc n'a pas encore validé le device dans le portail IoBase.

Action : appeler Jean-Marc, lui demander de :

  1. Se connecter à IoBase
  2. ⚙ Settings → « Services et équipements »
  3. Trouver le device cloudgate-terega-XX (statut Attente de validation)
  4. Cliquer « Valider l'équipement » + sélectionner un compte de service dédié + valider
  5. Côté CG, retirer l'inject DAP get token

Asystom 401

Asystom utilise Basic auth (pas DAP). Un 401 = mauvais credentials. Le canvas ne déclenche pas le refresh DAP dans ce cas (depuis le fix tâche #29).

Action : vérifier global.asystom_auth_b64 avec Patrick Duc, regenerate base64 si nécessaire :

echo -n "user:password" | base64

Balise silencieuse

  1. Vérifier dans LuvitRED admin → LoRa → OTA Devices → la balise est-elle marquée Joined ?
  2. Si oui mais pas d'uplink : balise endormie (cadence trop longue ou en hibernation)
    • Tirer downlink reboot (FPort 64) pour forcer un nouveau cycle
    • Ou tirer downlink set freq (FPort 70) pour réduire la cadence
  3. Si non marquée Joined : refaire la séquence magnet × 3 sur la balise. Vérifier piles.
  4. Si pas dans la liste : pas enrôlée. Voir Chap. 05.

Maintenance préventive

TâcheCadenceComment
Audit jsonl rotationQuotidien 02:00 UTCAutomatique par cron canvas. Garde 15 jours, supprime au-delà.
DAP refreshToutes les 50 minAutomatique par cron + retry sur 401 + WAN-up.
life_counter persistToutes les 60 sAutomatique. Restauré au boot.
Backup canvasManuel, après chaque modificationExporter flows.json via LuvitRED admin → Export.
Vérification stockageMensueldf -h /mnt/data /overlay via SSH. /mnt/data < 80% utilisé attendu.
Vérification tokens DAPMensuelcat /mnt/data/luvitred/dap_state.json + check saved_at < 24 h.

Backup & restore

Backup canvas + tokens (avant modif)

# Mac
SSH_OPTS="-o KexAlgorithms=+diffie-hellman-group1-sha1 -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa"

# Flow LuvitRED
curl -b /tmp/lc.cookies http://<cg-ip>:8080/flows > backup-flows-$(date +%s).json

# Tokens + state
sshpass -p '...' scp $SSH_OPTS \
  admin@<cg-ip>:/mnt/data/luvitred/dap_state.json \
  ./backup-dap-$(date +%s).json

# Audit récent
sshpass -p '...' scp $SSH_OPTS -r \
  admin@<cg-ip>:/mnt/data/luvitred/uplinks-*.jsonl \
  ./backup-audit/

Restore après corruption flow

# 1. Restore flow
curl -b /tmp/lc.cookies -X POST -H "Content-Type: application/json" \
   -d @backup-flows-XXX.json http://<cg-ip>:8080/flows

# 2. Restore tokens
sshpass -p '...' scp $SSH_OPTS \
   backup-dap-XXX.json admin@<cg-ip>:/mnt/data/luvitred/dap_state.json

# 3. Re-deploy via LuvitRED admin → Deploy
# 4. Vérifier DAP_RESTORE_OK dans le debug sidebar