package web import ( "net/http" "strings" "syscall" "github.com/darroyo/nasctl/internal/system" ) type diskUsage struct { Path string `json:"path"` TotalBytes uint64 `json:"total_bytes"` FreeBytes uint64 `json:"free_bytes"` UsedBytes uint64 `json:"used_bytes"` UsedPercent float64 `json:"used_percent"` } type serviceStatus struct { Name string `json:"name"` Active bool `json:"active"` State string `json:"state"` } func (s *Server) handleSystemStatus(w http.ResponseWriter, r *http.Request) { status := map[string]any{ "disks": collectDiskUsage(), "services": collectServiceStatus(r), } writeJSON(w, http.StatusOK, status) } func collectDiskUsage() []diskUsage { paths := []string{"/"} var usages []diskUsage for _, path := range paths { var stat syscall.Statfs_t if err := syscall.Statfs(path, &stat); err != nil { continue } total := stat.Blocks * uint64(stat.Bsize) free := stat.Bavail * uint64(stat.Bsize) used := total - free var pct float64 if total > 0 { pct = float64(used) / float64(total) * 100 } usages = append(usages, diskUsage{ Path: path, TotalBytes: total, FreeBytes: free, UsedBytes: used, UsedPercent: pct, }) } return usages } func collectServiceStatus(r *http.Request) []serviceStatus { services := []string{"smbd", "nfs-server"} var statuses []serviceStatus for _, name := range services { stdout, _, err := system.Run(r.Context(), "systemctl", "is-active", name) state := strings.TrimSpace(stdout) if state == "" && err != nil { state = "unknown" } statuses = append(statuses, serviceStatus{ Name: name, Active: state == "active", State: state, }) } return statuses }