actes : persistance des messages — diagnostic et dossier préparé
Diagnostic en lecture seule sur sonic (26/10) : le conteneur tourne
dans /app, les montages visent /src/data et /src/public (dossiers
vides de l'hôte), les messages vivent dans la couche du conteneur et
la graine est rejouée à chaque déploiement ; ADMIN_GIT_SYNC=false,
pas de .git, aucun commit [admin]. Rien perdu depuis le 29/09 ;
avant, invérifiable.
Dossier PRÉPARÉ (mot « déploie ») : sauvegarde et volume semé sur
sonic, veille de l'ancien conteneur, push de a6ba0a6
(fix/persistance-messages), vérification et redémarrage à froid.
Scripts déroulés en entier en local avec le vrai docker.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
# Acte 2026-10-26-persistance-messages — étape 4, sur sonic, sous yvv, après le déploiement.
|
||||
# Vérifie la bascule, puis un redémarrage à froid, puis revérifie.
|
||||
# Lancement : ssh yvv@161.97.174.60 'bash /tmp/lb-apres.sh' </dev/null
|
||||
set -euo pipefail
|
||||
|
||||
C=lpk-librodrome-main-app-1
|
||||
V=librodrome-data
|
||||
D="$HOME/librodrome-sauvegardes/2026-10-26"
|
||||
|
||||
stop() { echo "ARRÊT : $*" >&2; exit 1; }
|
||||
|
||||
check() {
|
||||
[ "$(docker inspect -f '{{.State.Running}}' "$C")" = true ] || stop "$C ne tourne pas"
|
||||
src=$(docker inspect -f '{{range .Mounts}}{{if eq .Destination "/app/data"}}{{.Type}} {{.Name}}{{end}}{{end}}' "$C")
|
||||
[ "$src" = "volume $V" ] || stop "/app/data n'est pas le volume $V (trouvé : '$src')"
|
||||
others=$(docker inspect -f '{{range .Mounts}}{{.Destination}} {{end}}' "$C")
|
||||
[ "$others" = "/app/data " ] || stop "montages inattendus : $others"
|
||||
s=$(docker logs "$C" 2>&1 | grep -c 'seed-messages' || true)
|
||||
[ "$s" = 0 ] || stop "la graine a été rejouée ($s ligne(s) seed-messages)"
|
||||
hc=$(docker exec "$C" sha256sum /app/data/messages.yml | cut -d' ' -f1)
|
||||
nc=$(docker exec "$C" grep -c '^ - id:' /app/data/messages.yml || true)
|
||||
if [ "$hc" = "$h" ]; then
|
||||
echo " fichier du volume = sauvegarde ($nc message(s))"
|
||||
else
|
||||
echo " NOTE : le fichier du volume a changé depuis la sauvegarde ($nc message(s)) : message reçu après la bascule, à regarder"
|
||||
fi
|
||||
}
|
||||
|
||||
wait_up() {
|
||||
for _ in $(seq 1 30); do
|
||||
if docker exec "$C" node -e "fetch('http://127.0.0.1:3000/api/health').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
stop "$C ne répond pas sur /api/health après 60 s"
|
||||
}
|
||||
|
||||
[ -s "$D/ancien-conteneur.id" ] || stop "étape 1 non jouée"
|
||||
old=$(cat "$D/ancien-conteneur.id")
|
||||
h=$(cut -d' ' -f1 "$D/SHA256SUMS")
|
||||
new=$(docker inspect -f '{{.Id}}' "$C")
|
||||
[ "$new" != "$old" ] || stop "conteneur non recréé : le déploiement n'a pas eu lieu"
|
||||
|
||||
# La veille doit avoir vu l'ancien conteneur partir, sans message arrivé après la sauvegarde.
|
||||
[ -s "$D/veille.fin" ] || stop "la veille n'a pas constaté la bascule (encore en cours ?) : attendre 10 s et relancer cette étape"
|
||||
[ -s "$D/messages-derniere-releve.yml" ] || stop "aucune relève de la veille"
|
||||
hl=$(sha256sum "$D/messages-derniere-releve.yml" | cut -d' ' -f1)
|
||||
[ "$hl" = "$h" ] || stop "un message est arrivé dans l'ancien conteneur après la sauvegarde ($(cat "$D/derniere-releve.date")) : le reporter dans le volume avant toute autre chose (hors acte, décision d'Yvv)"
|
||||
echo "veille : dernière relève = sauvegarde ($(head -1 "$D/derniere-releve.date"))"
|
||||
|
||||
echo "bascule :"
|
||||
wait_up
|
||||
check
|
||||
|
||||
echo "redémarrage à froid :"
|
||||
docker restart "$C" >/dev/null
|
||||
wait_up
|
||||
check
|
||||
|
||||
rm -f -- "$0"
|
||||
echo "ÉTAPE 4 OK"
|
||||
Reference in New Issue
Block a user