Chargement...
+EduBox Agent
+Connexion en cours...
+diff --git a/agent/instance.go b/agent/instance.go new file mode 100644 index 0000000..be217d8 --- /dev/null +++ b/agent/instance.go @@ -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" +} diff --git a/agent/ui.go b/agent/ui.go index d27f8cc..e97cce6 100644 --- a/agent/ui.go +++ b/agent/ui.go @@ -5,8 +5,6 @@ import ( "fmt" "log" "net/http" - "os" - "path/filepath" "github.com/gorilla/websocket" ) @@ -81,17 +79,28 @@ func startUI(dataDir, nodeID, serverAddr string) { } func listInstances(dataDir string, conn *websocket.Conn) { - dir := filepath.Join(dataDir, "instances") - entries, err := os.ReadDir(dir) + instances, err := loadInstances(dataDir) if err != nil { + log.Printf("loadInstances error: %v", err) conn.WriteJSON(map[string]interface{}{"action": "instances_list", "instances": []interface{}{}}) return } - var instances []map[string]interface{} - for _, e := range entries { - if e.IsDir() { - instances = append(instances, map[string]interface{}{"id": e.Name()}) + + var list []map[string]interface{} + for _, inst := range instances { + status := getInstanceStatus(dataDir, inst.ID) + if status != inst.Status { + inst.Status = status + _ = upsertInstance(dataDir, inst) } + list = append(list, map[string]interface{}{ + "id": inst.ID, + "templateName": inst.TemplateName, + "port": inst.Port, + "status": inst.Status, + "url": instanceURL(inst), + }) } - conn.WriteJSON(map[string]interface{}{"action": "instances_list", "instances": instances}) + + conn.WriteJSON(map[string]interface{}{"action": "instances_list", "instances": list}) } diff --git a/agent/ui/index.html b/agent/ui/index.html index 30cff67..e72b720 100644 --- a/agent/ui/index.html +++ b/agent/ui/index.html @@ -3,32 +3,54 @@
Chargement...
+Connexion en cours...
+