[pdm-devel] [PATCH datacenter-manager 2/2] api: migrate: use arrays for storage and bridge mappings
Hannes Laimer
h.laimer at proxmox.com
Tue Nov 18 13:21:05 CET 2025
With [1] we generate actual arrays for string-lists, so the generated
functions we use for migration take these types containing Vec's instead
of Strings. This updates the PDM migrate endpoints to accept arrays so
they can be passed to the functions.
This also updates the strigify function used by the UI to create those
mapping strings. Now, instead of a single string it produces a list of
mapping strings.
[1] bd8eca6 ("pve-api-types: schema2rust: generate arrays for types with format `-list`")
Signed-off-by: Hannes Laimer <h.laimer at proxmox.com>
---
lib/pdm-client/src/lib.rs | 31 +++++++++++++------------------
server/src/api/pve/lxc.rs | 27 +++++++++++++++++++++------
server/src/api/pve/qemu.rs | 27 +++++++++++++++++++++------
3 files changed, 55 insertions(+), 30 deletions(-)
diff --git a/lib/pdm-client/src/lib.rs b/lib/pdm-client/src/lib.rs
index df2ebe0..642a6c1 100644
--- a/lib/pdm-client/src/lib.rs
+++ b/lib/pdm-client/src/lib.rs
@@ -1395,32 +1395,27 @@ where
return serializer.serialize_none();
}
- let mut output = String::new();
+ let mut list = Vec::with_capacity(mapping.len());
+
if mapping.len() == 1 {
let (key, value) = mapping.iter().next().unwrap();
- // special case 1: '* = *' => identity mapping
if key == "*" && value == "*" {
- return serializer.serialize_str("1");
- }
-
- // special case 2: '* = <something>' => single value of <something> )
- return serializer.serialize_str(value);
- }
-
- for (from, to) in mapping.iter() {
- if !output.is_empty() {
- output.reserve(from.len() + to.len() + 2);
- output.push(',');
+ // special case 1: '* = *' => identity mapping
+ list.push("1".to_string());
+ } else if key == "*" {
+ // special case 2: '* = <something>' => single value of <something>
+ list.push(value.clone());
} else {
- output.reserve(from.len() + to.len() + 1);
+ list.push(format!("{key}:{value}"));
+ }
+ } else {
+ for (from, to) in mapping.iter() {
+ list.push(format!("{from}:{to}"));
}
- output.push_str(from);
- output.push(':');
- output.push_str(to);
}
- serializer.serialize_str(&output)
+ list.serialize(serializer)
}
#[derive(Serialize)]
diff --git a/server/src/api/pve/lxc.rs b/server/src/api/pve/lxc.rs
index 1ef936d..ecf0bef 100644
--- a/server/src/api/pve/lxc.rs
+++ b/server/src/api/pve/lxc.rs
@@ -301,8 +301,13 @@ pub async fn lxc_shutdown(
optional: true,
},
"target-storage": {
- description: "Mapping of source storages to target storages.",
+ description: "List of storage mappings",
optional: true,
+ items: {
+ description: "Mappings of source storages to target storages.",
+ type: String,
+ },
+ type: Array,
},
bwlimit: {
description: "Override I/O bandwidth limit (in KiB/s).",
@@ -331,7 +336,7 @@ pub async fn lxc_migrate(
restart: Option<bool>,
online: Option<bool>,
target: String,
- target_storage: Option<String>,
+ target_storage: Option<Vec<String>>,
timeout: Option<i64>,
) -> Result<RemoteUpid, Error> {
let bwlimit = bwlimit.map(|n| n as f64);
@@ -386,10 +391,20 @@ pub async fn lxc_migrate(
default: false,
},
"target-storage": {
- description: "Mapping of source storages to target storages.",
+ description: "List of storage mappings",
+ items: {
+ description: "Mappings of source storages to target storages.",
+ type: String,
+ },
+ type: Array,
},
"target-bridge": {
- description: "Mapping of source bridges to remote bridges.",
+ description: "List of bridge mappings",
+ items: {
+ description: "Mappings of source bridges to remote bridges.",
+ type: String,
+ },
+ type: Array,
},
bwlimit: {
description: "Override I/O bandwidth limit (in KiB/s).",
@@ -428,8 +443,8 @@ pub async fn lxc_remote_migrate(
target_vmid: Option<u32>,
delete: bool,
online: bool,
- target_storage: String,
- target_bridge: String,
+ target_storage: Vec<String>,
+ target_bridge: Vec<String>,
bwlimit: Option<u64>,
restart: Option<bool>,
timeout: Option<i64>,
diff --git a/server/src/api/pve/qemu.rs b/server/src/api/pve/qemu.rs
index 5e66a48..4f144b7 100644
--- a/server/src/api/pve/qemu.rs
+++ b/server/src/api/pve/qemu.rs
@@ -303,8 +303,13 @@ pub async fn qemu_shutdown(
optional: true,
},
"target-storage": {
- description: "Mapping of source storages to target storages.",
+ description: "List of storage mappings",
optional: true,
+ items: {
+ description: "Mappings of source storages to target storages.",
+ type: String,
+ },
+ type: Array,
},
bwlimit: {
description: "Override I/O bandwidth limit (in KiB/s).",
@@ -350,7 +355,7 @@ pub async fn qemu_migrate(
migration_type: Option<StartQemuMigrationType>,
online: Option<bool>,
target: String,
- target_storage: Option<String>,
+ target_storage: Option<Vec<String>>,
with_local_disks: Option<bool>,
) -> Result<RemoteUpid, Error> {
log::info!("in-cluster migration requested for remote {remote:?} vm {vmid} to node {target:?}");
@@ -443,10 +448,20 @@ async fn qemu_migrate_preconditions(
default: false,
},
"target-storage": {
- description: "Mapping of source storages to target storages.",
+ description: "List of storage mappings",
+ items: {
+ description: "Mappings of source storages to target storages.",
+ type: String,
+ },
+ type: Array,
},
"target-bridge": {
- description: "Mapping of source bridges to remote bridges.",
+ description: "List of bridge mappings",
+ items: {
+ description: "Mappings of source bridges to remote bridges.",
+ type: String,
+ },
+ type: Array,
},
bwlimit: {
description: "Override I/O bandwidth limit (in KiB/s).",
@@ -477,8 +492,8 @@ pub async fn qemu_remote_migrate(
target_vmid: Option<u32>,
delete: bool,
online: bool,
- target_storage: String,
- target_bridge: String,
+ target_storage: Vec<String>,
+ target_bridge: Vec<String>,
bwlimit: Option<u64>,
target_endpoint: Option<String>,
rpcenv: &mut dyn RpcEnvironment,
--
2.47.3
More information about the pdm-devel
mailing list