diff --git a/pkg/proxmox/client.go b/pkg/proxmox/client.go index 813ec191b..ad96850b2 100644 --- a/pkg/proxmox/client.go +++ b/pkg/proxmox/client.go @@ -1415,23 +1415,25 @@ func (c *Client) GetVMAgentVersion(ctx context.Context, node string, vmid int) ( // VMFileSystem represents filesystem information from QEMU guest agent type VMFileSystem struct { - Name string `json:"name"` - Type string `json:"type"` - Mountpoint string `json:"mountpoint"` - TotalBytes uint64 `json:"total-bytes"` - UsedBytes uint64 `json:"used-bytes"` - Disk string // Extracted disk device name for duplicate detection - DiskRaw []interface{} `json:"disk"` // Raw disk device info from API + Name string `json:"name"` + Type string `json:"type"` + Mountpoint string `json:"mountpoint"` + TotalBytes uint64 `json:"total-bytes"` + TotalBytesPrivileged uint64 `json:"total-bytes-privileged"` + UsedBytes uint64 `json:"used-bytes"` + Disk string // Extracted disk device name for duplicate detection + DiskRaw []interface{} `json:"disk"` // Raw disk device info from API } func (fs *VMFileSystem) UnmarshalJSON(data []byte) error { type rawVMFileSystem struct { - Name string `json:"name"` - Type string `json:"type"` - Mountpoint string `json:"mountpoint"` - TotalBytes interface{} `json:"total-bytes"` - UsedBytes interface{} `json:"used-bytes"` - DiskRaw []interface{} `json:"disk"` + Name string `json:"name"` + Type string `json:"type"` + Mountpoint string `json:"mountpoint"` + TotalBytes interface{} `json:"total-bytes"` + TotalBytesPrivileged interface{} `json:"total-bytes-privileged"` + UsedBytes interface{} `json:"used-bytes"` + DiskRaw []interface{} `json:"disk"` } var raw rawVMFileSystem @@ -1443,15 +1445,23 @@ func (fs *VMFileSystem) UnmarshalJSON(data []byte) error { if err != nil { return err } + totalPrivileged, err := parseUint64Flexible(raw.TotalBytesPrivileged) + if err != nil { + return err + } used, err := parseUint64Flexible(raw.UsedBytes) if err != nil { return err } + if total == 0 && totalPrivileged > 0 { + total = totalPrivileged + } fs.Name = raw.Name fs.Type = raw.Type fs.Mountpoint = raw.Mountpoint fs.TotalBytes = total + fs.TotalBytesPrivileged = totalPrivileged fs.UsedBytes = used fs.DiskRaw = raw.DiskRaw fs.Disk = "" diff --git a/pkg/proxmox/client_api_more3_test.go b/pkg/proxmox/client_api_more3_test.go index c00a2b8e0..d273ea9e0 100644 --- a/pkg/proxmox/client_api_more3_test.go +++ b/pkg/proxmox/client_api_more3_test.go @@ -54,6 +54,45 @@ func TestClientVMFSInfoParsing(t *testing.T) { } } +func TestClientVMFSInfoParsingPrivilegedCapacityFallback(t *testing.T) { + client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/api2/json/nodes/node1/qemu/100/agent/get-fsinfo": + writeJSON(t, w, map[string]interface{}{ + "data": map[string]interface{}{ + "result": []map[string]interface{}{ + { + "name": "windows", + "type": "ntfs", + "mountpoint": "C:\\Windows", + "total-bytes": 0, + "total-bytes-privileged": 500, + "used-bytes": 200, + }, + }, + }, + }) + default: + http.NotFound(w, r) + } + }) + + ctx := context.Background() + filesystems, err := client.GetVMFSInfo(ctx, "node1", 100) + if err != nil { + t.Fatalf("GetVMFSInfo error: %v", err) + } + if len(filesystems) != 1 { + t.Fatalf("expected 1 filesystem, got %d", len(filesystems)) + } + if filesystems[0].TotalBytes != 500 { + t.Fatalf("expected privileged total-bytes fallback, got %d", filesystems[0].TotalBytes) + } + if filesystems[0].Disk != "C:" { + t.Fatalf("expected windows drive disk, got %q", filesystems[0].Disk) + } +} + func TestClientVMFSInfoObjectResult(t *testing.T) { client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { diff --git a/pkg/proxmox/client_test.go b/pkg/proxmox/client_test.go index 67fbe32a6..4bdf06899 100644 --- a/pkg/proxmox/client_test.go +++ b/pkg/proxmox/client_test.go @@ -254,6 +254,17 @@ func TestVMFileSystemUnmarshalFlexibleNumbers(t *testing.T) { t.Fatalf("unexpected float string values: got total=%d used=%d", fs.TotalBytes, fs.UsedBytes) } }) + + t.Run("falls back to total-bytes-privileged when total-bytes is missing", func(t *testing.T) { + payload := `{"name":"windows","type":"ntfs","mountpoint":"C:\\\\","total-bytes-privileged":536870912000,"used-bytes":214748364800}` + var fs VMFileSystem + if err := json.Unmarshal([]byte(payload), &fs); err != nil { + t.Fatalf("unexpected error unmarshalling privileged total-bytes: %v", err) + } + if fs.TotalBytes != 536870912000 || fs.TotalBytesPrivileged != 536870912000 || fs.UsedBytes != 214748364800 { + t.Fatalf("unexpected privileged values: got total=%d privileged=%d used=%d", fs.TotalBytes, fs.TotalBytesPrivileged, fs.UsedBytes) + } + }) } func TestVMFileSystemUnmarshalJSON_InvalidValues(t *testing.T) {