Files
Pulse/internal/monitoring/container_disk_usage.go
2025-10-11 23:29:47 +00:00

123 lines
2.3 KiB
Go

package monitoring
import (
"context"
"math"
"strconv"
"strings"
"github.com/rs/zerolog/log"
)
type containerDiskOverride struct {
Used uint64
Total uint64
}
func clampToInt64(value uint64) int64 {
if value > math.MaxInt64 {
return math.MaxInt64
}
return int64(value)
}
func storageSupportsContainerVolumes(content string) bool {
if content == "" {
return false
}
for _, part := range strings.Split(content, ",") {
switch strings.TrimSpace(strings.ToLower(part)) {
case "rootdir", "images", "subvol":
return true
}
}
return false
}
func isRootVolumeForContainer(volid string, vmid int) bool {
if vmid <= 0 || volid == "" {
return false
}
normalized := strings.ToLower(volid)
if idx := strings.Index(normalized, "@"); idx != -1 {
normalized = normalized[:idx]
}
id := strconv.Itoa(vmid)
patterns := []string{
"subvol-" + id + "-disk-0",
"vm-" + id + "-disk-0",
}
for _, pattern := range patterns {
if strings.Contains(normalized, pattern) {
return true
}
}
return false
}
func (m *Monitor) collectContainerRootUsage(ctx context.Context, client PVEClientInterface, node string, vmIDs []int) map[int]containerDiskOverride {
overrides := make(map[int]containerDiskOverride)
if len(vmIDs) == 0 {
return overrides
}
vmidSet := make(map[int]struct{}, len(vmIDs))
for _, id := range vmIDs {
vmidSet[id] = struct{}{}
}
storages, err := client.GetStorage(ctx, node)
if err != nil {
log.Debug().
Err(err).
Str("node", node).
Msg("Unable to list storages for container disk overrides")
return overrides
}
for _, storage := range storages {
if !storageSupportsContainerVolumes(storage.Content) {
continue
}
contents, err := client.GetStorageContent(ctx, node, storage.Storage)
if err != nil {
log.Debug().
Err(err).
Str("node", node).
Str("storage", storage.Storage).
Msg("Unable to query storage content for container disk overrides")
continue
}
for _, item := range contents {
vmid := item.VMID
if vmid == 0 {
continue
}
if _, ok := vmidSet[vmid]; !ok {
continue
}
if !isRootVolumeForContainer(item.Volid, vmid) {
continue
}
if item.Used == 0 {
continue
}
overrides[vmid] = containerDiskOverride{
Used: item.Used,
Total: item.Size,
}
}
}
return overrides
}