From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 501931FF13E for ; Fri, 20 Mar 2026 10:27:22 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 131FD11EAB; Fri, 20 Mar 2026 10:27:38 +0100 (CET) From: Dominik Csapak To: pdm-devel@lists.proxmox.com Subject: [PATCH datacenter-manager 5/5] fake remotes: make use of ClusterResource more resilient to changes Date: Fri, 20 Mar 2026 10:25:42 +0100 Message-ID: <20260320092702.1069143-6-d.csapak@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260320092702.1069143-1-d.csapak@proxmox.com> References: <20260320092702.1069143-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.041 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: OIECMCLZDPSD2WLQDWGXKJMPNXQ6YILG X-Message-ID-Hash: OIECMCLZDPSD2WLQDWGXKJMPNXQ6YILG X-MailFrom: d.csapak@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: since all new properties have to be optional due to backwards compatibility, we can simply use a json object to parse from with serde. This is less type safe, but it's more flexible and less prone to compile errors. note that we have to explicitly specify u64 for the values, otherwise rust will assume i32 and overflow. Signed-off-by: Dominik Csapak --- server/src/test_support/fake_remote.rs | 223 +++++++++---------------- 1 file changed, 80 insertions(+), 143 deletions(-) diff --git a/server/src/test_support/fake_remote.rs b/server/src/test_support/fake_remote.rs index ae367f68..d38753d5 100644 --- a/server/src/test_support/fake_remote.rs +++ b/server/src/test_support/fake_remote.rs @@ -1,7 +1,8 @@ use std::{sync::Arc, time::Duration}; -use anyhow::{bail, Error}; +use anyhow::{bail, format_err, Error}; use serde::Deserialize; +use serde_json::json; use pdm_api_types::{remotes::Remote, Authid, ConfigDigest}; use pdm_config::remotes::RemoteConfig; @@ -10,8 +11,7 @@ use proxmox_product_config::ApiLockGuard; use proxmox_section_config::typed::SectionConfigData; use pve_api_types::{ ClusterMetrics, ClusterMetricsData, ClusterNodeIndexResponse, ClusterNodeIndexResponseStatus, - ClusterResource, ClusterResourceKind, ClusterResourceType, ListTasks, ListTasksResponse, - PveUpid, StorageContent, + ClusterResource, ClusterResourceKind, ListTasks, ListTasksResponse, PveUpid, }; use crate::{ @@ -152,163 +152,100 @@ impl pve_api_types::client::PveClient for FakePveClient { for _ in 0..self.nr_of_vms { vmid += 1; let jitter = ((vmid as f64).sin() * bytejitter).round() as i64; - result.push(ClusterResource { - cgroup_mode: None, - content: None, - cpu: Some(cpu), - diskread: Some(1034), - diskwrite: Some(1034), - disk: Some(disk.saturating_add_signed(jitter)), - hastate: None, - id: format!("qemu/{vmid}"), - level: Some("".into()), - maxcpu: Some(maxcpu), - maxdisk: Some(maxdisk), - maxmem: Some(maxmem), - mem: Some(mem.saturating_sub_signed(jitter)), - memhost: Some(memhost.saturating_add_signed(jitter)), - name: Some(format!("vm-{vmid}")), - netin: Some(1034), - netout: Some(1034), - node: Some(format!("node-{}", vmid % self.nr_of_nodes)), - plugintype: None, - pool: None, - status: Some("running".into()), - storage: None, - template: Some(false), - ty: ClusterResourceType::Qemu, - uptime: Some(1234), - vmid: Some(vmid), - lock: None, - tags: None, - sdn: None, - network: None, - network_type: None, - protocol: None, - shared: None, - zone_type: None, + let val = json!({ + "cpu": cpu, + "diskread": 1034, + "diskwrite": 1034, + "disk": disk.saturating_add_signed(jitter), + "id": format!("qemu/{vmid}"), + "level": "", + "maxcpu": maxcpu, + "maxdisk": maxdisk, + "maxmem": maxmem, + "mem": mem.saturating_add_signed(jitter), + "memhost": memhost.saturating_add_signed(jitter), + "name": format!("vm-{vmid}"), + "netin": 1034, + "netout": 1034, + "node": format!("node-{}", vmid % self.nr_of_nodes), + "status": "running", + "template": false, + "type": "qemu", + "uptime": 1234, + "vmid": vmid, }); + result.push(serde_json::from_value(val).map_err(|err| { + proxmox_client::Error::Anyhow(format_err!("error on vm {vmid}: {err}")) + })?); } for _ in 0..self.nr_of_cts { vmid += 1; let jitter = ((vmid as f64).sin() * bytejitter).round() as i64; - result.push(ClusterResource { - cgroup_mode: None, - content: None, - cpu: Some(cpu), - disk: Some(disk.saturating_add_signed(jitter)), - diskread: Some(1034), - diskwrite: Some(1034), - hastate: None, - id: format!("lxc/{vmid}"), - level: Some("".into()), - maxcpu: Some(maxcpu), - maxdisk: Some(maxdisk), - maxmem: Some(maxmem), - memhost: Some(memhost), - mem: Some(mem.saturating_add_signed(jitter)), - name: Some(format!("ct-{vmid}")), - netin: Some(1034), - netout: Some(1034), - node: Some(format!("node-{}", vmid % self.nr_of_nodes)), - plugintype: None, - pool: None, - status: Some("running".into()), - storage: None, - template: Some(false), - ty: ClusterResourceType::Lxc, - uptime: Some(1234), - vmid: Some(vmid), - lock: None, - tags: None, - sdn: None, - network: None, - network_type: None, - protocol: None, - shared: None, - zone_type: None, + let val = json!({ + "cpu": cpu, + "diskread": 1034, + "diskwrite": 1034, + "disk": disk.saturating_add_signed(jitter), + "id": format!("lxc/{vmid}"), + "level": "", + "maxcpu": maxcpu, + "maxdisk": maxdisk, + "maxmem": maxmem, + "mem": mem.saturating_add_signed(jitter), + "memhost": memhost.saturating_add_signed(jitter), + "name": format!("ct-{vmid}"), + "netin": 1034, + "netout": 1034, + "node": format!("node-{}", vmid % self.nr_of_nodes), + "status": "running", + "template": false, + "type": "lxc", + "uptime": 1234, + "vmid": vmid, }); + result.push(serde_json::from_value(val).map_err(|err| { + proxmox_client::Error::Anyhow(format_err!("error on ct {vmid}: {err}")) + })?); } for i in 0..self.nr_of_nodes { let jitter = ((i as f64).sin() * bytejitter).round() as i64; - result.push(ClusterResource { - cgroup_mode: None, - content: None, - cpu: Some(cpu), - disk: Some(disk.saturating_add_signed(jitter)), - diskread: None, - diskwrite: None, - hastate: None, - id: format!("node/node-{i}"), - level: Some("".into()), - maxcpu: Some(16.), - maxdisk: Some(maxdisk), - maxmem: Some(maxmem), - mem: Some(mem.saturating_add_signed(jitter)), - memhost: None, - name: None, - netin: None, - netout: None, - node: Some(format!("node-{i}")), - plugintype: None, - pool: None, - status: Some("online".into()), - storage: None, - template: None, - ty: ClusterResourceType::Node, - uptime: Some(1234), - vmid: Some(vmid), - lock: None, - tags: None, - sdn: None, - network: None, - network_type: None, - protocol: None, - shared: None, - zone_type: None, + let val = json!({ + "cpu": cpu, + "disk": disk.saturating_add_signed(jitter), + "id": format!("node/node-{i}"), + "level": "", + "maxcpu": 16.0, + "maxdisk": maxdisk, + "maxmem": maxmem, + "mem": mem.saturating_add_signed(jitter), + "node": format!("node-{i}"), + "status": "online", + "type": "node", + "uptime": 1234, }); + result.push(serde_json::from_value(val).map_err(|err| { + proxmox_client::Error::Anyhow(format_err!("error on node {i}: {err}")) + })?); } for i in 0..self.nr_of_storages { let jitter = ((i as f64).sin() * bytejitter).round() as i64; - result.push(ClusterResource { - cgroup_mode: None, - content: Some(vec![StorageContent::Images, StorageContent::Rootdir]), - cpu: None, - disk: Some(disk.saturating_add_signed(jitter)), - diskread: None, - diskwrite: None, - hastate: None, - id: format!("storage/node-0/storage-{i}"), - level: None, - maxcpu: None, - maxdisk: Some(maxdisk), - maxmem: None, - mem: None, - memhost: None, - name: None, - netin: None, - netout: None, - node: Some(format!("node-{}", i % self.nr_of_nodes)), - plugintype: Some("dir".into()), - pool: None, - status: Some("available".into()), - storage: Some(format!("storage-{i}")), - template: None, - ty: ClusterResourceType::Storage, - uptime: None, - vmid: None, - lock: None, - tags: None, - sdn: None, - network: None, - network_type: None, - protocol: None, - shared: None, - zone_type: None, + let val = json!({ + "content": "images,rootdir", + "disk": disk.saturating_add_signed(jitter), + "id": format!("storage/node-0/storage-{i}"), + "maxdisk": maxdisk, + "node": format!("node-{}", i % self.nr_of_nodes), + "plugintype": "dir", + "status": "available", + "storage": format!("storage-{i}"), + "type": "storage", }); + result.push(serde_json::from_value(val).map_err(|err| { + proxmox_client::Error::Anyhow(format_err!("error on storage {i}: {err}")) + })?); } tokio::time::sleep(Duration::from_millis(self.api_delay_ms as u64)).await; -- 2.47.3