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:
parent
dcf3b937fa
commit
a61f805cd0
8 changed files with 658 additions and 27 deletions
104
backend/cmd/gen-modules/main.go
Normal file
104
backend/cmd/gen-modules/main.go
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// cmd/gen-modules génère registered_modules.go à partir de la variable d'env MODULES.
|
||||
// Appelé pendant le build Docker : go run ./cmd/gen-modules
|
||||
// MODULES = liste d'IDs séparés par des virgules (ex: "viewLogs,viewServices")
|
||||
// Le fichier généré déclare RegisterModules(*modules.Loader) qui enregistre chaque module.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
const outputFile = "registered_modules.go"
|
||||
|
||||
// moduleDef décrit un module à importer.
|
||||
type moduleDef struct {
|
||||
ID string // ex: "viewLogs"
|
||||
Alias string // ex: "viewlogs" (alias Go valide)
|
||||
Pkg string // ex: "git.geronzi.fr/proxmoxPanel/viewLogs"
|
||||
}
|
||||
|
||||
// tplNoModules : fichier généré quand aucun module n'est installé.
|
||||
const tplNoModules = `// Code généré automatiquement par cmd/gen-modules — ne pas modifier manuellement.
|
||||
// Régénéré lors du build Docker avec la liste des modules compilés.
|
||||
package main
|
||||
|
||||
import "git.geronzi.fr/proxmoxPanel/core/backend/modules"
|
||||
|
||||
// RegisterModules enregistre les modules compilés dans le binaire.
|
||||
func RegisterModules(l *modules.Loader) {}
|
||||
`
|
||||
|
||||
// tplWithModules : fichier généré avec des modules.
|
||||
const tplWithModules = `// Code généré automatiquement par cmd/gen-modules — ne pas modifier manuellement.
|
||||
// Régénéré lors du build Docker avec la liste des modules compilés.
|
||||
package main
|
||||
|
||||
import (
|
||||
"git.geronzi.fr/proxmoxPanel/core/backend/modules"
|
||||
{{- range .}}
|
||||
{{.Alias}} "{{.Pkg}}"
|
||||
{{- end}}
|
||||
)
|
||||
|
||||
// RegisterModules enregistre les modules compilés dans le binaire.
|
||||
func RegisterModules(l *modules.Loader) {
|
||||
{{- range .}}
|
||||
l.RegisterModule({{.Alias}}.New())
|
||||
{{- end}}
|
||||
}
|
||||
`
|
||||
|
||||
func main() {
|
||||
modulesEnv := strings.TrimSpace(os.Getenv("MODULES"))
|
||||
|
||||
// Pas de modules : générer la version vide
|
||||
if modulesEnv == "" {
|
||||
if err := os.WriteFile(outputFile, []byte(tplNoModules), 0644); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Erreur écriture %s : %v\n", outputFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Généré %s (aucun module)\n", outputFile)
|
||||
return
|
||||
}
|
||||
|
||||
// Parser la liste des modules
|
||||
ids := strings.Split(modulesEnv, ",")
|
||||
defs := make([]moduleDef, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
id = strings.TrimSpace(id)
|
||||
if id == "" {
|
||||
continue
|
||||
}
|
||||
// Alias Go = ID en minuscules sans tirets ni underscores
|
||||
alias := strings.ToLower(strings.NewReplacer("-", "", "_", "").Replace(id))
|
||||
defs = append(defs, moduleDef{
|
||||
ID: id,
|
||||
Alias: alias,
|
||||
Pkg: "git.geronzi.fr/proxmoxPanel/" + id,
|
||||
})
|
||||
}
|
||||
|
||||
// Générer le fichier avec les imports et les appels RegisterModule
|
||||
tmpl, err := template.New("modules").Parse(tplWithModules)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Erreur template : %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
f, err := os.Create(outputFile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Erreur création %s : %v\n", outputFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := tmpl.Execute(f, defs); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Erreur génération : %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("Généré %s avec %d module(s) : %s\n", outputFile, len(defs), modulesEnv)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue