feat(agent): amélioration UI étudiante - instances, statut et lien site
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type InstanceInfo struct {
|
||||
ID string `json:"id"`
|
||||
TemplateName string `json:"templateName,omitempty"`
|
||||
Port int `json:"port"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
func instancesFile(dataDir string) string {
|
||||
return filepath.Join(dataDir, "instances.json")
|
||||
}
|
||||
|
||||
func loadInstances(dataDir string) (map[string]*InstanceInfo, error) {
|
||||
f := instancesFile(dataDir)
|
||||
data, err := os.ReadFile(f)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return make(map[string]*InstanceInfo), nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
var list []*InstanceInfo
|
||||
if err := json.Unmarshal(data, &list); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[string]*InstanceInfo)
|
||||
for _, inst := range list {
|
||||
m[inst.ID] = inst
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func saveInstances(dataDir string, instances map[string]*InstanceInfo) error {
|
||||
if err := os.MkdirAll(dataDir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
list := make([]*InstanceInfo, 0, len(instances))
|
||||
for _, inst := range instances {
|
||||
list = append(list, inst)
|
||||
}
|
||||
data, err := json.MarshalIndent(list, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(instancesFile(dataDir), data, 0644)
|
||||
}
|
||||
|
||||
func upsertInstance(dataDir string, inst *InstanceInfo) error {
|
||||
instances, err := loadInstances(dataDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
instances[inst.ID] = inst
|
||||
return saveInstances(dataDir, instances)
|
||||
}
|
||||
|
||||
func removeInstance(dataDir, instanceID string) error {
|
||||
instances, err := loadInstances(dataDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete(instances, instanceID)
|
||||
return saveInstances(dataDir, instances)
|
||||
}
|
||||
|
||||
func instanceURL(inst *InstanceInfo) string {
|
||||
return fmt.Sprintf("http://localhost:%d", inst.Port)
|
||||
}
|
||||
|
||||
func getInstanceStatus(dataDir, instanceID string) string {
|
||||
dir := instanceDir(dataDir, instanceID)
|
||||
composeFile := filepath.Join(dir, "docker-compose.yml")
|
||||
if _, err := os.Stat(composeFile); err != nil {
|
||||
return "stopped"
|
||||
}
|
||||
|
||||
engine := getContainerEngine()
|
||||
cmd := exec.Command(engine, "compose", "-f", composeFile, "ps", "--format", "json")
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "error"
|
||||
}
|
||||
|
||||
outStr := strings.TrimSpace(string(out))
|
||||
if outStr == "" || outStr == "[]" {
|
||||
return "stopped"
|
||||
}
|
||||
|
||||
// Docker compose JSON output can be a single object or an array
|
||||
if strings.HasPrefix(outStr, "[") {
|
||||
var containers []map[string]interface{}
|
||||
if err := json.Unmarshal(out, &containers); err != nil {
|
||||
return "error"
|
||||
}
|
||||
for _, c := range containers {
|
||||
state, _ := c["State"].(string)
|
||||
if state == "running" {
|
||||
return "running"
|
||||
}
|
||||
}
|
||||
return "stopped"
|
||||
}
|
||||
|
||||
var c map[string]interface{}
|
||||
if err := json.Unmarshal(out, &c); err != nil {
|
||||
return "error"
|
||||
}
|
||||
state, _ := c["State"].(string)
|
||||
if state == "running" {
|
||||
return "running"
|
||||
}
|
||||
return "stopped"
|
||||
}
|
||||
Reference in New Issue
Block a user