feat: système de rebuild Docker pour installation de modules has_backend

- internal/docker/client.go : client HTTP brut sur socket Unix
  - BuildImage() : build depuis repo git avec ARG MODULES
  - RebuildAndRestart() : rebuild async + remplacement de container
  - HandleReplacement() : le container successeur arrête et renomme l'ancien
  - Restart() : redémarrage simple (enable/disable sans rebuild)
- cmd/gen-modules/main.go : générateur de registered_modules.go
  Lit MODULES env var, génère imports + appels RegisterModules()
- registered_modules.go : version par défaut (aucun module)
- main.go : appel RegisterModules(loader) + HandleReplacement() au démarrage
- settings.go : inject DockerClient, has_backend dans moduleResp/moduleJSON,
  trigger rebuild à l'install, restart à l'enable/disable
- migrations/006 : colonne has_backend sur table modules
- Dockerfile : ARG MODULES, git clone modules, go run ./cmd/gen-modules
- docker-compose.yml : socket Docker, group_add, env vars CONTAINER_NAME/GIT_REPO/GIT_BRANCH

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
enzo 2026-03-22 16:54:21 +01:00
parent dcf3b937fa
commit a61f805cd0
8 changed files with 658 additions and 27 deletions

View file

@ -13,6 +13,7 @@ import (
"git.geronzi.fr/proxmoxPanel/core/backend/internal/auth"
"git.geronzi.fr/proxmoxPanel/core/backend/internal/crypto"
"git.geronzi.fr/proxmoxPanel/core/backend/internal/db"
dockerclient "git.geronzi.fr/proxmoxPanel/core/backend/internal/docker"
"git.geronzi.fr/proxmoxPanel/core/backend/internal/logbuffer"
sshpool "git.geronzi.fr/proxmoxPanel/core/backend/internal/ssh"
"git.geronzi.fr/proxmoxPanel/core/backend/internal/websocket"
@ -26,6 +27,14 @@ func main() {
// Brancher le buffer de logs (stderr + mémoire) avant tout autre log
log.SetOutput(io.MultiWriter(os.Stderr, logbuffer.Global))
// ── Gestion du remplacement de container (rebuild module) ──────────────
// Si REPLACING_CONTAINER est défini, ce container est un successeur issu d'un rebuild.
// Il arrête l'ancien container et se renomme avant de continuer le démarrage normal.
docker := dockerclient.New()
if docker.Available() {
docker.HandleReplacement()
}
// Répertoire de données persistantes (volume Docker)
dataDir := getEnv("DATA_DIR", "/app/data")
@ -68,6 +77,7 @@ func main() {
// ── Chargement des modules actifs ──────────────────────────────────────
loader := modules.NewLoader(database, sshPool, encryptor)
RegisterModules(loader) // généré par cmd/gen-modules selon les modules compilés
if err := loader.LoadActive(); err != nil {
log.Fatalf("Erreur chargement modules : %v", err)
}
@ -77,7 +87,7 @@ func main() {
authHandler := api.NewAuthHandler(database, jwtManager, sshAuthenticator, auditLogger)
proxmoxHandler := api.NewProxmoxHandler(database, hub, auditLogger, encryptor)
updatesHandler := api.NewUpdatesHandler(database, sshPool, hub, auditLogger, encryptor)
settingsHandler := api.NewSettingsHandler(database, auditLogger, encryptor)
settingsHandler := api.NewSettingsHandler(database, auditLogger, encryptor, docker)
terminalHandler := api.NewTerminalHandler(database, auditLogger, encryptor)
// Démarrer le polling Proxmox en arrière-plan