Paillasse/docs/bilan.md
Adam Belkacemi 7b0a8583eb écrit le bilan de mission et note le maintien temporaire de sudo sans mot de passe (étape 16)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:04:00 +02:00

12 KiB
Raw Blame History

Bilan de la mission de déploiement — Syllabus

Mission : docs/prompt-deploiement-paillasse.md, étapes 1 à 16, exécutée du 2026-10-07 au 2026-10-12 sur la Dedibox 163.172.4.195 (Debian 12, Xeon D-1531, 32 Go, RAID 1). Le détail de chaque étape (commandes, problèmes, explications) est dans docs/journal.md ; ce document en est la synthèse.

Ce qui fonctionne, avec la preuve de chaque critère

Étape Critère Preuve (journal)
1. Reconnaissance Inventaire, KVM, version de Kolla justifiée docs/inventaire-serveur.md ; /dev/kvm présent ; Kolla 2025.2, seule série maintenue qui supporte Debian 12 (ADR 0001)
2. Durcissement Clé OK, mot de passe et root refusés, seuls 22/80/443 Permission denied (publickey) pour le mot de passe et pour root ; nmap depuis le Mac : 22 seul ouvert (80/443 autorisés, rien n'écoutait encore)
3. Sauvegardes Une sauvegarde envoyée, un fichier restauré quotidienne-20261007.tar.zst.age présente sur Dedibackup ; etc/hostname restauré dans /tmp (sd-124443)
4. Réseau OpenStack Après redémarrage : SSH, dummy0, veth, Internet Redémarrage 11:37, SSH 11:39 ; interfaces et IP présentes ; ping 9.9.9.9 et DNS OK ; RAID [UU]
5. Kolla Services OK, aucune API joignable de l'extérieur openstack service list et compute service list OK ; nmap sur tous les ports OpenStack + 1-1024 : 22 seul
6. Console série Invite affichée, commande exécutée Script WebSocket : localhost login:, puis whoami && hostname → eleve, localhost
7. Supervision Une alerte de test reçue par Adam Alerte injectée dans Alertmanager ; reçue par Adam sur ntfy
8. Portail Pest OK, élève fictif voit son tableau de bord 11/11 tests ; lea.m connectée voit « Salut Léa »
9. Console web ip a dans le navigateur ; un autre élève refusé Sortie de ip a par navigateur → Nginx → proxy Go → Nova ; autre élève : 403 ; écriture du prof ignorée côté serveur
10. Heat, lab 08 Stack CREATE_COMPLETE, terminaux ouverts Stack créée en 26 s, 3 VM, topologie conforme au lab.yaml ; 3 terminaux ouverts ; expiration automatique vérifiée
11. Stock et correction < 5 s ; correct → réussi ; incorrect → échoué + message 4,06 s (mesure pessimiste, voir étape 13) ; « Pas encore réussi » 6/10 avec les messages du lab, puis « Réussi » 10/10 ; 3 essais puis échec visible du prof, vérifiés
12. HTTPS Certificat valide, parcours prof → élève → lab → correction Let's Encrypt, TLS 1.2/1.3, HSTS, CSP ; parcours en https/wss : 4,35 s, 6/10 puis 10/10 ; VM sans IP publique ni sortie
13. Capacité et résistance Chiffres écrits, restauration, retour seul après redémarrage docs/capacite.md ; « RESTAURATION RÉUSSIE » (17 tables identiques) ; tout revenu seul en 11 min, parcours 10/10 ensuite ; ouverture mesurée à 2,80 / 2,85 / 2,85 s
14. Légal et RGPD Pages en ligne, purge prouvée par Pest /legal, /confidentialite en 200, /statut → page de statut ; PurgeRgpdTest (5 tests)
15. Visio Prof + 2 élèves ; main levée → parole ; intrus refusé Test Playwright à 3 navigateurs + intrus : « CRITÈRE DE L’ÉTAPE 15 : RÉUSSI » ; élève sans parole reste en sourdine ; intrus : « Authentication required »
16. Nettoyage Proposer le retrait de 90-adam Proposé avec ses conséquences ; Adam a choisi de le garder jusqu'à la fin du bloc A (voir risques)

État relevé le 2026-10-12 à la fin de la mission : 0 unité systemd en échec ; 53 conteneurs, 0 en mauvaise santé ; Nginx, PHP-FPM, Horizon, proxy console, correcteur et relais d'alertes actifs ; https://syllabuslab.fr et la page de statut en 200 ; certificat valable jusqu'au 2027-01-10 pour syllabuslab.fr, www, status et meet ; une stack prête dans le stock du lab 08 ; dernière sauvegarde le 2026-10-12 à 03:16, test de restauration automatique du 2026-10-12 à 04:30 réussi ; 47 tests Pest et 4 tests Go.

Temps réel passé par étape

Pas de chronométrage pendant la mission : ce sont des fenêtres entre commits, pauses, attentes des réponses d'Adam et nuits comprises. Elles majorent le temps de travail réel.

Étape Fenêtre Durée Ce qui a pris du temps
1 2026-10-07, jusqu'à 06:54 — Accès SSH (passphrase de la clé)
2 06:54 → 10:32 ≈ 3 h 40 Deux retours arrière du filet anti-coupure, auto-bannissement fail2ban (post-mortem)
3 10:32 → 11:08 ≈ 35 min Identifiants Dedibackup corrigés par Adam
4 11:08 → 11:40 ≈ 30 min Redémarrage avec accord
5 11:40 → 15:57 ≈ 4 h 15 Deux deploy (ProxySQL contre MariaDB), tables IPv6 de Docker
6 15:57 → 16:24 ≈ 30 min —
7 16:24 → 21:20 ≈ 5 h Attente de l'adresse de notification, configuration oubliée sur le serveur (2 fois)
8 21:20 → 10-08 02:01 ≈ 4 h 40 Taille du portail, deux guards, déploiement
9 02:01 → 09:35 ≈ 7 h 30 (nuit comprise) —
10 09:35 → 10:14, puis ADR jusqu'à 21:01 ≈ 40 min + questions Trust Heat refusé aux application credentials (ADR 0002)
11 10-08 → 21:52 > 1 h 30 (journal) Trois défauts des étapes 8 et 9 trouvés par le parcours réel
12 10-09 09:38 → 15:04 ≈ 1 h + DNS de status Faille XSS, /cours en 500
13 15:04 → 20:12 ≈ 5 h Test de capacité, sauvegarde du portail ajoutée, redémarrage
14 20:12 → 22:18 ≈ 2 h Pages légales réécrites, polices auto-hébergées, retours d'Adam
15 10-12 matin → 12:35 une demi-journée Pare-feu entre conteneurs (br_netfilter), rôles Jitsi
16 et bilan 10-12 après-midi ≈ 1 h —

En tout : six jours calendaires, dont environ quatre jours de travail.

Capacité mesurée

  • 20 VM eleve.petit (1 vCPU, 768 Mo) en même temps, sessions et stock chaud compris : par exemple une classe de 20 élèves sur un lab à une VM, ou 6 élèves sur le lab 08 (3 VM chacun). Limite appliquée par Nova (reserved_host_memory_mb = 16500) et par le portail (LABS_CAPACITE_VM).
  • Pourquoi 20 : la mémoire est la limite (≈ 600 Mo par VM active, ≈ 250 Mo au repos), pas le CPU (20 vCPU à 100 % → hôte à 89 %, correction en 0,6 s). 22 avant la visio, 20 depuis qu'1,5 Go est réservé à Jitsi.
  • Ouverture d'un lab pris dans le stock : 2,8 s (critère < 5 s). Lancement à froid de 20 VM : 53 s en médiane, 75 s au p95. D'où le pré-remplissage 10 minutes avant une séance.
  • Visio : non mesurée au-delà de 3 participants. Une classe de 30 en visio est à tester au pilote (CPU de JVB, débit sortant).

Détails : docs/capacite.md.

Dettes et risques connus

La liste complète, tenue à jour, est dans docs/dette.md. Les risques qui comptent avant une vraie classe :

Risque Conséquence Réponse
Copie de la clé age non confirmée Si le serveur est perdu, aucune sauvegarde n'est déchiffrable Adam (voir plus bas)
Base OpenStack non sauvegardée Perte du serveur → projet, compte, gabarits et stacks à recréer à la main kolla-ansible mariadb_backup dans la sauvegarde quotidienne
Un seul serveur, pas de sonde extérieure Si le serveur tombe, aucune alerte, et la classe s'arrête Sonde externe (à décider et commander par Adam) ; self-healing ne couvre pas la panne totale
Visio sans TURN sur 443 Sur un réseau scolaire qui bloque l'UDP : ni son ni image coturn derrière 443 avant le pilote
sudo sans mot de passe pour adam La clé SSH de Claude Code donne un accès root complet Gardé par choix d'Adam jusqu'à la fin du bloc A ; retrait ensuite (commande prête ci-dessous)
Images Kuma non figée, Jitsi sans procédure de mise à jour Mise à jour non testée au prochain redéploiement Variables de version dans les rôles
Vitrine : Tailwind par CDN, scripts en ligne, Pyodide depuis jsDelivr CSP de la vitrine moins stricte que celle de l'application Compilation par Vite avant ouverture publique
Peu de vérifications dans un vrai navigateur Hors visio et /ide, les pages n'ont été vérifiées qu'en HTML Playwright est maintenant installé : l'étendre aux parcours clés
Kolla installé depuis une branche Pas reproductible à l'identique À régler lors de la montée de version

Deux incidents de ma part, déjà traités : un secret d'application credential de test affiché en clair (credential supprimée aussitôt) ; un déploiement en échec pris pour un succès (règle depuis : toujours lire PLAY RECAP).

Ce qu'Adam doit faire lui-même

Secrets et sécurité

  1. Copier la clé age hors du serveur et le prouver : procédure dans docs/runbooks/sauvegardes.md (déchiffrer ~/Desktop/test-cle-sauvegardes.age avec la copie). Ranger ensuite la copie dans un gestionnaire de mots de passe.
  2. Changer la passphrase SSH si l'ancienne clé ou la même passphrase sert ailleurs : elle avait été collée dans la conversation à l'étape 1.
  3. Retirer /etc/sudoers.d/90-adam à la fin du bloc A (la clé de Claude Code n'a pas de passphrase : ce fichier est la seule barrière entre elle et root). D'abord vérifier son mot de passe dans sa propre session (sudo -k && sudo -v), garder cette session ouverte, puis : sudo rm /etc/sudoers.d/90-adam. Les playbooks se lancent ensuite avec -K.
  4. Faire tourner le mot de passe du compte paillasse-service une fois par an (docs/runbooks/compte-service-openstack.md).

Comptes et contenus

  1. Créer le premier vrai compte prof (le sien) sur https://syllabuslab.fr/inscription et une vraie classe.
  2. Compléter les CGU (article « Disponibilité et responsabilité ») et indiquer un DPO s'il en désigne un.
  3. Trancher les slogans « du lycée au master » et le sort des 32 pages d'aperçu.
  4. Dire si l'ancien storage/logs/laravel.log peut être supprimé.

Tests avec un prof

  1. Faire jouer une séance complète par un collègue prof, sur un vrai réseau d'établissement : inscription des élèves (fiches et code de classe), séance planifiée, lab 08, correction, visio (son et image à travers le filtrage de l'établissement, c'est là que l'absence de TURN se verra), archivage de la classe.
  2. Vérifier dans son navigateur : /ide (Python et SQL), une console de lab, la visio sur Chromebook ou vieux PC.

Décisions et achats (jamais par Claude)

  1. Sonde de supervision hors du serveur (petite VM ailleurs, ou service externe) et nom DNS turn.syllabuslab.fr pour la visio.

Prochaines étapes du bloc A

1. Self-healing et post-mortem (semaine 6 du CLAUDE.md)

  • Détecter et relancer : VM figée (l'agent invité ne répond plus → nova reboot --hard), stack du stock en erreur (supprimée et recréée : déjà en partie fait par le ménage du stock), service arrêté (Restart=on-failure sur toutes les unités maison, à vérifier une par une), conteneur Kolla arrêté.
  • Une panne provoquée par cas (kill -STOP du QEMU d'une VM du stock, arrêt du correcteur, arrêt de nova_compute), réparée sans intervention, chacune suivie d'un post-mortem dans docs/postmortems/.
  • Avant : sauvegarde de la base OpenStack, sinon une réparation ratée n'a pas de filet.

2. Montée de version d'OpenStack (semaine 7)

  • Passer de la branche stable/2025.2 à un tag (version figée), puis préparer la série suivante. Attention : 2026.1 ne supporte plus Debian 12. Une montée de version d'OpenStack passe donc d'abord par Debian 13 (montée de version de l'OS sur un serveur unique, à préparer avec le mode rescue).
  • Runbook : sauvegarde des bases, kolla-ansible upgrade en service systemd, vérifications (capacite.py réduit, parcours-lab.py, visio-e2e.mjs), retour arrière. Retour d'expérience dans le journal.

3. Pilote avec une vraie classe (semaine 8)

  • Prérequis : TURN 443, base OpenStack sauvegardée, clé age confirmée, sonde extérieure, mentions légales complètes, test avec un collègue (point 9).
  • Pendant : relever le temps d'ouverture réel (p95), la mémoire, la charge de la visio, les corrections réussies et échouées, les mains levées.
  • Après : retours des élèves et du prof, métriques dans docs/capacite.md, liste des priorités du bloc B.