- agent-linux/: Kompletter Linux/Proxmox RMM Agent - Collectors: CPU, Memory, Disk, Network, Services, Updates, Proxmox (VMs, Container, Storage, ZFS), Backups - Backup Collector: Jobs nach Node gefiltert (Cluster-aware) - WebSocket: Tunnel-Support, writeMux fuer stabile Verbindungen - Systemd Service Template - updater/: Plattform-unabhaengiger Updater (FreeBSD + Linux) - runtime.GOOS erkennt Plattform automatisch - FreeBSD: /usr/local/rmm/, service rmm_agent - Linux: /usr/local/bin/, /etc/rmm/, systemctl rmm-agent - Firmware-Download mit ?platform= Parameter - frontend/: Proxmox-Bereich - ProxmoxServers.jsx: Eigene Seite fuer PVE Server mit VM/CT Counts - ProxmoxPanel.jsx: Detail-Panel mit Uebersicht, VMs, Container, Storage, ZFS, Tunnel, Dienste, Updates, Backups - Agents.jsx: Filtert Linux-Agents raus (nur OPNsense) - Sidebar: Proxmox Navigationspunkt - Installationsanleitung mit rmm-agent-linux + rmm-updater-linux - backend: Platform-Feld fuer Agents, Firmware multi-platform
133 lines
2.9 KiB
Go
133 lines
2.9 KiB
Go
package collector
|
|
|
|
import (
|
|
"os/exec"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
)
|
|
|
|
type DiskInfo struct {
|
|
Filesystem string `json:"filesystem"`
|
|
TotalBytes int64 `json:"total_bytes"`
|
|
UsedBytes int64 `json:"used_bytes"`
|
|
FreeBytes int64 `json:"free_bytes"`
|
|
MountPoint string `json:"mount_point"`
|
|
}
|
|
|
|
func CollectDisks() []DiskInfo {
|
|
var disks []DiskInfo
|
|
|
|
// df -T zur Anzeige aller mounted filesystems
|
|
output, err := exec.Command("/usr/bin/df", "-T", "-P").CombinedOutput()
|
|
if err != nil {
|
|
return disks
|
|
}
|
|
|
|
lines := strings.Split(string(output), "\n")
|
|
if len(lines) < 2 {
|
|
return disks
|
|
}
|
|
|
|
// Erste Zeile ist Header, überspringen
|
|
for _, line := range lines[1:] {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" {
|
|
continue
|
|
}
|
|
|
|
fields := strings.Fields(line)
|
|
if len(fields) < 7 {
|
|
continue
|
|
}
|
|
|
|
filesystem := fields[0]
|
|
fstype := fields[1]
|
|
totalKB := fields[2]
|
|
usedKB := fields[3]
|
|
availKB := fields[4]
|
|
mountpoint := fields[6]
|
|
|
|
// Überspringe spezielle Filesysteme
|
|
if shouldSkipFilesystem(filesystem, fstype, mountpoint) {
|
|
continue
|
|
}
|
|
|
|
// Konvertiere kB zu Bytes
|
|
total, _ := strconv.ParseInt(totalKB, 10, 64)
|
|
used, _ := strconv.ParseInt(usedKB, 10, 64)
|
|
avail, _ := strconv.ParseInt(availKB, 10, 64)
|
|
|
|
// Für bessere Genauigkeit: Versuche statvfs syscall
|
|
if stat := getStatvfs(mountpoint); stat != nil {
|
|
total = int64(stat.Blocks) * int64(stat.Bsize)
|
|
avail = int64(stat.Bavail) * int64(stat.Bsize)
|
|
used = total - avail
|
|
} else {
|
|
// Fallback: df-Werte in Bytes konvertieren
|
|
total *= 1024
|
|
used *= 1024
|
|
avail *= 1024
|
|
}
|
|
|
|
disks = append(disks, DiskInfo{
|
|
Filesystem: filesystem,
|
|
TotalBytes: total,
|
|
UsedBytes: used,
|
|
FreeBytes: avail,
|
|
MountPoint: mountpoint,
|
|
})
|
|
}
|
|
|
|
return disks
|
|
}
|
|
|
|
// Bestimmt ob ein Filesystem übersprungen werden soll
|
|
func shouldSkipFilesystem(filesystem, fstype, mountpoint string) bool {
|
|
// Überspringe virtuelle Filesysteme
|
|
skipTypes := []string{
|
|
"proc", "sysfs", "devfs", "devtmpfs", "tmpfs", "debugfs",
|
|
"securityfs", "cgroup", "cgroup2", "pstore", "bpf",
|
|
"tracefs", "configfs", "fusectl", "binfmt_misc",
|
|
"autofs", "mqueue", "hugetlbfs", "sunrpc",
|
|
}
|
|
|
|
for _, skipType := range skipTypes {
|
|
if fstype == skipType {
|
|
return true
|
|
}
|
|
}
|
|
|
|
// Überspringe spezielle Mount-Points
|
|
skipMounts := []string{
|
|
"/dev", "/proc", "/sys", "/run", "/tmp",
|
|
"/dev/shm", "/run/lock", "/run/user",
|
|
}
|
|
|
|
for _, skipMount := range skipMounts {
|
|
if strings.HasPrefix(mountpoint, skipMount) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
// Überspringe Loop-Devices außer root
|
|
if strings.HasPrefix(filesystem, "/dev/loop") && mountpoint != "/" {
|
|
return true
|
|
}
|
|
|
|
// Überspringe Bind-Mounts (heuristic)
|
|
if strings.Contains(mountpoint, "/snap/") {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// Holt präzise Filesystem-Statistiken via statvfs syscall
|
|
func getStatvfs(path string) *syscall.Statfs_t {
|
|
var stat syscall.Statfs_t
|
|
if err := syscall.Statfs(path, &stat); err != nil {
|
|
return nil
|
|
}
|
|
return &stat
|
|
} |