package collector import ( "encoding/json" "log" "os" "os/exec" ) type PBSInfo struct { Available bool `json:"available"` Version string `json:"version,omitempty"` Datastores []PBSDatastore `json:"datastores,omitempty"` Tasks []PBSTask `json:"tasks,omitempty"` GC []PBSGCStatus `json:"gc,omitempty"` } type PBSDatastore struct { Name string `json:"name"` Path string `json:"path,omitempty"` Total int64 `json:"total"` Used int64 `json:"used"` Available int64 `json:"available"` Namespaces int `json:"namespaces,omitempty"` } type PBSTask struct { ID string `json:"id,omitempty"` Node string `json:"node,omitempty"` Type string `json:"type,omitempty"` Status string `json:"status,omitempty"` StartTime int64 `json:"start_time,omitempty"` EndTime int64 `json:"end_time,omitempty"` Duration int64 `json:"duration,omitempty"` User string `json:"user,omitempty"` Datastore string `json:"datastore,omitempty"` } type PBSGCStatus struct { Datastore string `json:"datastore"` Status string `json:"status,omitempty"` LastRun int64 `json:"last_run,omitempty"` Duration int64 `json:"duration,omitempty"` } func CollectPBS() *PBSInfo { // PBS erkennen if _, err := os.Stat("/usr/sbin/proxmox-backup-manager"); err != nil { return nil // PBS nicht installiert } log.Printf("PBS: proxmox-backup-manager gefunden, sammle Daten...") pbs := &PBSInfo{Available: true} // Version if out, err := exec.Command("/usr/sbin/proxmox-backup-manager", "versions", "--output-format", "json").Output(); err == nil { var versions []map[string]interface{} if json.Unmarshal(out, &versions) == nil { for _, v := range versions { if pkg, ok := v["Package"].(string); ok && pkg == "proxmox-backup-server" { if ver, ok := v["Version"].(string); ok { pbs.Version = ver } } } } } // Datastores if out, err := exec.Command("/usr/sbin/proxmox-backup-manager", "datastore", "list", "--output-format", "json").Output(); err == nil { var list []map[string]interface{} if json.Unmarshal(out, &list) == nil { for _, d := range list { ds := PBSDatastore{} if name, ok := d["name"].(string); ok { ds.Name = name } if path, ok := d["path"].(string); ok { ds.Path = path } if total, ok := d["total"].(float64); ok { ds.Total = int64(total) } if used, ok := d["used"].(float64); ok { ds.Used = int64(used) } if avail, ok := d["avail"].(float64); ok { ds.Available = int64(avail) } pbs.Datastores = append(pbs.Datastores, ds) } } } else { log.Printf("PBS: datastore list fehler: %v", err) } // Letzte Tasks (max 20) if out, err := exec.Command("/usr/sbin/proxmox-backup-manager", "task", "list", "--limit", "20", "--output-format", "json").Output(); err == nil { var list []map[string]interface{} if json.Unmarshal(out, &list) == nil { for _, t := range list { task := PBSTask{} if id, ok := t["upid"].(string); ok { task.ID = id } if node, ok := t["node"].(string); ok { task.Node = node } if typ, ok := t["type"].(string); ok { task.Type = typ } if status, ok := t["status"].(string); ok { task.Status = status } if start, ok := t["starttime"].(float64); ok { task.StartTime = int64(start) } if end, ok := t["endtime"].(float64); ok { task.EndTime = int64(end) if task.StartTime > 0 { task.Duration = task.EndTime - task.StartTime } } if user, ok := t["user"].(string); ok { task.User = user } pbs.Tasks = append(pbs.Tasks, task) } } } else { log.Printf("PBS: task list fehler: %v", err) } // Garbage Collection Status pro Datastore for _, ds := range pbs.Datastores { gc := PBSGCStatus{Datastore: ds.Name} if out, err := exec.Command("/usr/sbin/proxmox-backup-manager", "garbage-collection", "status", ds.Name, "--output-format", "json").Output(); err == nil { var status map[string]interface{} if json.Unmarshal(out, &status) == nil { if upid, ok := status["upid"].(string); ok && upid != "" { gc.Status = "running" } else if lastRun, ok := status["last-run-starttime"].(float64); ok { gc.LastRun = int64(lastRun) if duration, ok := status["last-run-duration"].(float64); ok { gc.Duration = int64(duration) } gc.Status = "ok" } else { gc.Status = "never" } } } pbs.GC = append(pbs.GC, gc) } log.Printf("PBS: %d Datastores, %d Tasks gesammelt", len(pbs.Datastores), len(pbs.Tasks)) return pbs }