agent v0.3.8: fix crash UI notifications, auto Podman machine DNS, WordPress 7.0.0 ready template
This commit is contained in:
+238
-2
@@ -64,6 +64,68 @@ HTTP/2 200
|
||||
- Certificat Let’s Encrypt obtenu automatiquement par Caddy (`tls { on_demand }`).
|
||||
- Le resolver réécrit les en-têtes `Location` et le contenu HTML pour passer de `http://` à `https://`.
|
||||
|
||||
## 📝 Template WordPress prêt à l’emploi
|
||||
|
||||
Un nouveau template `wordpress-ready-wordpress-latest` a été créé et validé le 2026-06-26. Il fournit un WordPress déjà initialisé en français, prêt à l’usage en classe ou en examen.
|
||||
|
||||
### Contenu du template
|
||||
|
||||
| Élément | Valeur / État |
|
||||
|---|---|
|
||||
| Langue | **Français** (`fr_FR`) |
|
||||
| Titre du site | **Mon site wordpress** |
|
||||
| Compte administrateur | **admin / admin** |
|
||||
| Thème actif | **Astra** |
|
||||
| Spectra | installé et **actif** |
|
||||
| Yoast SEO | installé mais **inactif** |
|
||||
| Mises à jour automatiques | **désactivées** (core, plugins, thèmes) |
|
||||
| DNS conteneur | `8.8.8.8` + `1.1.1.1` pour permettre l’accès à `api.wordpress.org` |
|
||||
|
||||
### Architecture technique
|
||||
|
||||
- Le modèle `Template` de Prisma dispose d’un nouveau champ `initScript` (`TEXT?`).
|
||||
- Le seed génère le template avec :
|
||||
- une section `dns` dans le service `app` du `docker-compose.yml` ;
|
||||
- un service sidecar `wp-init` (image `wordpress:cli`) exécutant le script d’initialisation.
|
||||
- L’agent écrit le script `wp-init.sh` dans le dossier de l’instance au démarrage.
|
||||
- Le conteneur `wp-init` attend que WordPress soit prêt, puis exécute WP-CLI en tant que `www-data`.
|
||||
- Un fichier flag `.studioe5-init-done` évite de réinitialiser l’instance à chaque redémarrage.
|
||||
|
||||
### Fichiers modifiés / ajoutés
|
||||
|
||||
- `server/prisma/schema.prisma` – champ `initScript` sur `Template`.
|
||||
- `server/prisma/seed.ts` – génération du template `wordpress-ready-wordpress-latest`.
|
||||
- `server/templates/wordpress-ready/wp-init.sh` – script d’initialisation WP-CLI.
|
||||
- `server/app/api/instances/route.ts` – envoi de `initScript` à l’agent avec remplacement des placeholders.
|
||||
- `agent/websocket.go` – réception et transmission de `InitScript`.
|
||||
- `agent/docker.go` – écriture du script dans le dossier instance (`writeInitScript`).
|
||||
|
||||
### Validation
|
||||
|
||||
Instance de test créée via l’API (`cmqv03a6v0001vg8zrpe8zqfy`) :
|
||||
|
||||
```bash
|
||||
$ curl -sS -I -L https://cmqv03a6v0001vg8zrpe8zqfy.studioe5.edudeploy.com/
|
||||
HTTP/2 200
|
||||
```
|
||||
|
||||
- Page d’accueil en français, titre **« Mon site wordpress »**.
|
||||
- Connexion admin `/wp-login.php` avec **admin / admin** fonctionnelle.
|
||||
- Tableau de bord en français.
|
||||
- Plugins : Spectra actif, Yoast SEO inactif.
|
||||
- `wp-config.php` contient les constantes de désactivation des mises à jour automatiques.
|
||||
|
||||
Les instances de test ont été nettoyées après validation.
|
||||
|
||||
### Template versionné WordPress 7.0.0
|
||||
|
||||
Un second template `wordpress-ready-wordpress-7.0.0-php8.3` a été ajouté pour figer WordPress sur la version **7.0.0** (PHP 8.3) au lieu de `latest`. Cela garantit que tous les postes déploient exactement la même version, sans dépendre du cache local de `wordpress:latest`.
|
||||
|
||||
| Template | Image Docker |
|
||||
|---|---|
|
||||
| `wordpress-ready-wordpress-latest` | `wordpress:latest` |
|
||||
| `wordpress-ready-wordpress-7.0.0-php8.3` | `wordpress:7.0.0-php8.3` |
|
||||
|
||||
## 📁 Fichiers modifiés (non exhaustif)
|
||||
|
||||
- `agent/tailscale.go` – lancement `tailscaled` + `tailscale up`, gestion start/stop/status.
|
||||
@@ -79,7 +141,7 @@ Agent de test lancé en arrière-plan :
|
||||
- data-dir : `/tmp/studioe5-test-clienta`
|
||||
- node-id : `vps-8fc665eb`
|
||||
- tailnet IP actuelle : `100.64.0.8`
|
||||
- PID : `3151830` (lancé le 2026-06-23 09:36 UTC)
|
||||
- PID : voir `/tmp/studioe5-test-clienta/agent.pid` (relancé le 2026-06-26 11:53 UTC avec l’agent v0.3.5 corrigé)
|
||||
|
||||
Instance de test créée :
|
||||
- ID : `test-wp-001`
|
||||
@@ -165,6 +227,127 @@ L’agent redémarre `tailscaled` automatiquement au lancement, même si la clé
|
||||
- **Windows (exe)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.5.exe`
|
||||
- **Linux** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.5`
|
||||
|
||||
## 🪟 Agent v0.3.6 – recover() dans les goroutines de démarrage d’instance
|
||||
|
||||
### Problème
|
||||
|
||||
Lors de la création d’une instance depuis le dashboard vers certains agents (notamment Windows), l’agent s’arrêtait brutalement. Le `recover()` présent dans `handleMessage` ne capturait pas le panic car celui-ci survenait dans les goroutines lancées par `go handleStartInstance(...)`.
|
||||
|
||||
### Corrections apportées
|
||||
|
||||
- Ajout d’un `defer recover()` dans `handleStartInstance` ; en cas de panic, l’instance passe en statut `error` et un message `instance_error` est envoyé au serveur.
|
||||
- Ajout d’un `defer recover()` dans toutes les goroutines critiques du WebSocket :
|
||||
- `start_vpn`
|
||||
- `stop_vpn`
|
||||
- `start`
|
||||
- `reset`
|
||||
- `startTailscaleAndReport`
|
||||
- cleanup au shutdown
|
||||
- Ajout de logs de traçage au début de `handleStartInstance` (`instance`, `type`, `port`, `dataDir`, `initScriptLen`).
|
||||
|
||||
### Téléchargement
|
||||
|
||||
- **Windows (archive)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.6-windows.zip`
|
||||
- **Windows (exe)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.6.exe`
|
||||
- **Linux** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.6`
|
||||
|
||||
### Redeploiement
|
||||
|
||||
- Agent rebuildé en v0.3.6 pour Windows et Linux.
|
||||
- Binaires versionnés copiés dans `server/public/`.
|
||||
- Page `/dashboard/download` mise à jour vers la v0.3.6.
|
||||
- Serveur rebuildé et redémarré.
|
||||
|
||||
## 🪟 Agent v0.3.7 – recover() dans les notifications UI
|
||||
|
||||
### Problème
|
||||
|
||||
L’agent continuait de s’arrêter brutalement lors de la création d’une instance depuis le dashboard. Le crash survenait juste après les logs `Start instance ...` et `notifyUI: broadcasting to ...`, sans laisser de trace de panic. Cela pointait vers une panique dans les goroutines de notification UI ou dans l’écriture des logs vers les clients UI locaux.
|
||||
|
||||
### Corrections apportées
|
||||
|
||||
- Ajout d’un `defer recover()` dans `notifyUI` pour chaque goroutine de notification.
|
||||
- Ajout d’un `defer recover()` dans `sendUILog` (logs diffusés aux clients UI).
|
||||
- Ajout d’un `defer recover()` dans `broadcastUI` (messages diffusés aux clients UI).
|
||||
|
||||
### Téléchargement
|
||||
|
||||
- **Windows (archive)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.7-windows.zip`
|
||||
- **Windows (exe)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.7.exe`
|
||||
- **Linux** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.7`
|
||||
|
||||
## 🪟 Agent v0.3.8 – DNS automatique pour Podman machine (Windows/macOS)
|
||||
|
||||
### Problème
|
||||
|
||||
Après correction du crash, l’agent Windows avec Podman échouait au `docker compose up` avec :
|
||||
```text
|
||||
lookup registry-1.docker.io: Temporary failure in name resolution
|
||||
```
|
||||
La VM Podman machine n’avait pas de DNS fonctionnel, ce qui empêchait le téléchargement des images Docker. Le DNS des conteneurs (`dns: 8.8.8.8` dans le compose) résout le problème à l’intérieur des conteneurs, mais pas pour le pull d’images par Podman machine.
|
||||
|
||||
### Solution
|
||||
|
||||
L’agent configure automatiquement le DNS des machines Podman en cours d’exécution au démarrage :
|
||||
- Détection de Podman sur Windows/macOS.
|
||||
- Liste des machines Podman (`podman machine list --format json`).
|
||||
- Pour chaque machine `running`, exécution de :
|
||||
```bash
|
||||
podman machine ssh <name> sudo sh -c 'echo nameserver 8.8.8.8 > /etc/resolv.conf && echo nameserver 1.1.1.1 >> /etc/resolv.conf'
|
||||
```
|
||||
|
||||
Fichier ajouté : `agent/podman.go`. Appel depuis `agent/main.go` au démarrage.
|
||||
|
||||
### Téléchargement
|
||||
|
||||
- **Windows (archive)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.8-windows.zip`
|
||||
- **Windows (exe)** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.8.exe`
|
||||
- **Linux** : `https://studioe5.edudeploy.com/studioE5-agent-v0.3.8`
|
||||
|
||||
## 🐛 Fix synchronisation agent / dashboard
|
||||
|
||||
### Problème
|
||||
|
||||
Le statut affiché dans le dashboard pouvait diverger de l’état réel de l’agent :
|
||||
- Après un **Arrêter** lancé depuis le dashboard, l’instance restait affichée comme elle l’était avant, ou disparaissait avec perte des données.
|
||||
- Après une **Suppression**, l’instance n’était pas retirée de la liste.
|
||||
|
||||
### Causes racines
|
||||
|
||||
1. **Action `stop` du dashboard envoyée comme `delete` à l’agent** (`server/app/api/instances/route.ts`).
|
||||
L’agent exécutait alors `docker compose down -v` + suppression des fichiers, c’est-à-dire une suppression réelle, tout en marquant l’instance `stopped` en base.
|
||||
2. **L’agent ne confirmait pas les actions serveur** (`agent/websocket.go`).
|
||||
Les handlers `stop` et `delete` ne renvoyaient jamais les messages `instance_stopped` / `instance_deleted` au serveur ; seule l’UI locale le faisait.
|
||||
3. **Le handler `stop` de l’agent utilisait `dockerComposeDown`** au lieu de `dockerComposeStop`, ne respectant pas le cycle de vie documenté (arrêt = conteneurs et volumes conservés).
|
||||
|
||||
### Corrections apportées
|
||||
|
||||
| Fichier | Changement |
|
||||
|---------|------------|
|
||||
| `server/app/api/instances/route.ts` | L’action dashboard `stop` envoie désormais `action: "stop"` à l’agent (et non plus `"delete"`). |
|
||||
| `agent/websocket.go` | Le cas `stop` utilise `dockerComposeStop`, puis envoie `instance_stopped` au serveur. Le cas `delete` envoie `instance_deleted` au serveur. |
|
||||
| `server/lib/websocket.ts` | Utilisation de `updateMany`/`deleteMany` pour ignorer silencieusement les messages d’instances déjà absentes/supprimées (évite les erreurs Prisma en double suppression). |
|
||||
|
||||
### Résultat
|
||||
|
||||
Le dashboard reflète désormais l’état réel après une action serveur-initiée, dès le rechargement de la page. Le cycle de vie respecte la sémantique attendue :
|
||||
- **Arrêter** : `docker compose stop` → statut `stopped`.
|
||||
- **Démarrer** : `docker compose up -d` → statut `running`.
|
||||
- **Redémarrer** : `docker compose down -v` + recréation.
|
||||
- **Supprimer** : `docker compose down -v` + suppression fichiers.
|
||||
|
||||
### Redeploiement effectué le 2026-06-26
|
||||
|
||||
- **Agent rebuildé** en v0.3.5 (`agent/studioE5-agent`, `.exe`, `.zip` et `server/public/` mis à jour).
|
||||
- **Serveur rebuildé et redémarré** (`docker compose up -d --build server`) pour intégrer les corrections TypeScript.
|
||||
- **Page `/dashboard/download` mise à jour** : passage à la version 0.3.5 et ajout des liens Windows (.exe, .zip) et Linux.
|
||||
- **Corrections défensives agent** après signalement d’arrêt brutal lors d’actions dashboard :
|
||||
- `sendMessage` exécuté de manière asynchrone (`go`) dans les handlers `stop`, `delete`, `stop_vpn` et cleanup, pour ne pas bloquer la boucle de lecture WebSocket.
|
||||
- Ajout d’un `recover` dans `handleMessage` pour capturer d’éventuels panics sans tuer l’agent.
|
||||
- Correction du cleanup `main.go` : modification de `inst[id].Status` (et non de la copie locale `info`).
|
||||
- **Agent de test Linux relancé** (PID dans `/tmp/studioe5-test-clienta/agent.pid`).
|
||||
- **Agents clients** : il faut redémarrer l’agent sur chaque poste, ou télécharger à nouveau le binaire v0.3.5 depuis le dashboard pour Windows.
|
||||
|
||||
## 🛠️ Commandes utiles pour reprendre
|
||||
|
||||
### Voir l’agent de test
|
||||
@@ -551,6 +734,50 @@ Si la clé doit être changée :
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Installateur agent professionnel
|
||||
|
||||
### Objectif
|
||||
|
||||
Créer un package d’installation unique et professionnel par OS, incluant l’agent studioE5, Tailscale et **Podman CLI**, afin de ne plus dépendre d’installations manuelles préalables par l’utilisateur.
|
||||
|
||||
### Choix des outils
|
||||
|
||||
| OS | Outil | Format | Justification |
|
||||
|---|---|---|---|
|
||||
| **Windows** | **Inno Setup** | `.exe` | Gratuit, open source, très répandu, personnalisable, exécution de scripts PowerShell/silencieux. |
|
||||
| **macOS** | **`pkgbuild`** | `.pkg` | Outil natif Apple, gratuit, format professionnel pour la distribution macOS. |
|
||||
| **Linux** | **Script shell** (+ `.deb`/`.rpm` optionnels) | `.sh` | Universel, détecte le package manager, simple à maintenir. |
|
||||
|
||||
### Contenu du package par OS
|
||||
|
||||
- **Windows** (Inno Setup) :
|
||||
- Installer l’agent dans `C:\Program Files\studioE5-agent\`.
|
||||
- Extraire Tailscale dans `C:\Program Files\studioE5-agent\tailscale-bin\windows\`.
|
||||
- Installer Podman CLI via le MSI officiel en mode silencieux.
|
||||
- Exécuter `podman machine init` puis `podman machine start`.
|
||||
- Créer un raccourci de démarrage et/ou un service Windows.
|
||||
|
||||
- **macOS** (`pkgbuild`) :
|
||||
- Installer l’agent dans `/Applications/studioE5-agent/`.
|
||||
- Installer Podman CLI.
|
||||
- Exécuter `podman machine init` puis `podman machine start`.
|
||||
- Optionnellement créer un LaunchAgent pour démarrer l’agent au login.
|
||||
|
||||
- **Linux** (script shell) :
|
||||
- Détecter le package manager (`apt`, `dnf`, `pacman`, etc.).
|
||||
- Installer Podman et Podman Compose.
|
||||
- Copier l’agent dans `/opt/studioe5-agent/`.
|
||||
- Créer le service systemd `studioe5-agent.service`.
|
||||
- Activer et démarrer le service.
|
||||
|
||||
### Adaptations nécessaires dans l’agent
|
||||
|
||||
- Détecter si Podman est utilisé et si une machine est requise (Windows/macOS).
|
||||
- Vérifier au démarrage que la machine Podman est démarrée, et lancer `podman machine start` si besoin.
|
||||
- Gérer proprement l’arrêt de la machine à la fermeture de l’agent (optionnel).
|
||||
|
||||
---
|
||||
|
||||
## 📋 Prochaines étapes à faire
|
||||
|
||||
### ✅ Terminé
|
||||
@@ -568,7 +795,8 @@ Si la clé doit être changée :
|
||||
- [x] **Agent v0.3.5 – UI locale moderne** (dashboard, logs, progression, actions d’instance).
|
||||
- [x] **Agent v0.3.5 – cycle de vie des instances** (`stop`/`start` préservent les volumes, `reset`/`delete` effacent).
|
||||
- [x] **Agent v0.3.5 – cleanup au shutdown** (arrêt propre de Tailscale et des instances, notification serveur).
|
||||
- [x] **Synchronisation dashboard** (messages `instance_stopped` / `instance_deleted` traités côté serveur).
|
||||
- [x] **Synchronisation dashboard** (messages `instance_stopped` / `instance_deleted` traités côté serveur, et agent renvoyant correctement ces messages après un ordre serveur `stop`/`delete`).
|
||||
- [x] **Template WordPress prêt à l’emploi** (`wordpress-ready-wordpress-latest`) : WordPress en français, titre « Mon site wordpress », compte admin/admin, thème Astra, Spectra actif, Yoast SEO inactif, mises à jour automatiques désactivées, DNS `8.8.8.8`/`1.1.1.1` pour `api.wordpress.org`.
|
||||
|
||||
### ⏳ Reste à faire
|
||||
|
||||
@@ -577,6 +805,14 @@ Si la clé doit être changée :
|
||||
- [ ] **Nettoyer les anciens nodes/volumes Headscale** de test (nœuds `edubox`, `prof`, `invalid-*` hors ligne à supprimer).
|
||||
- [ ] **Pousser la branche** vers Gitea dès que le remote sera accessible.
|
||||
- [ ] **Documenter la procédure de mise en production** pour le client A (config agent, clés Headscale, ports, ACL, etc.).
|
||||
- [ ] **Installateur agent professionnel (Windows / macOS / Linux)** : créer un package d’installation unique incluant l’agent studioE5, Tailscale et **Podman CLI**. Voir la section « 🖥️ Installateur agent professionnel » ci-dessous pour le détail des outils (Inno Setup, pkgbuild, script shell) et du contenu par OS.
|
||||
- [ ] **Template WordPress prêt à l’emploi (usage examen/classe)** :
|
||||
- Forcer le DNS (`8.8.8.8`, `1.1.1.1`) dans le `docker-compose.yml` pour permettre l’accès à la bibliothèque de plugins/mises à jour depuis le conteneur.
|
||||
- Pré-installer WordPress en **français** via WP-CLI avec le titre **“Mon site wordpress”** et le compte **admin / admin**.
|
||||
- Désactiver les **mises à jour automatiques** (core, plugins, thèmes) pour figer l’environnement.
|
||||
- Installer et activer le **thème Astra**.
|
||||
- Installer **Yoast SEO** (inactif) et **Spectra** (actif).
|
||||
- [ ] **Barre de progression basée sur les logs d’installation** : enrichir la barre de progression agent/dashboard en lisant les logs Podman/Docker (`podman logs -f`) pendant le premier démarrage d’une instance. Définir des patterns de logs par template (ex. `Installation successful` pour PrestaShop) et relayer les étapes réelles au dashboard via WebSocket.
|
||||
- [ ] **Étude – interface de déploiement multi-clients** : outil de provisionning d’un nouveau serveur client + agent générique (option A : URL serveur déterminée à l’activation).
|
||||
- [ ] **Sécurité – gestion et rotation des secrets** (`INTERNAL_API_KEY`, `HEADSCALE_API_KEY`, `NEXTAUTH_SECRET`, `DATABASE_URL`).
|
||||
- [ ] **Sécurité – durcissement des conteneurs** (`cap_add`, utilisateurs non-root, scans CVE).
|
||||
|
||||
Reference in New Issue
Block a user