* [pdm-devel] [PATCH datacenter-manager 1/8] pdm-api-types: move RemoteUpid to its own module
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
@ 2025-11-11 10:50 ` Lukas Wagner
2025-11-11 10:50 ` [pdm-devel] [PATCH datacenter-manager 2/8] pdm-api-types: remote upid: make upid field private Lukas Wagner
` (8 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Lukas Wagner @ 2025-11-11 10:50 UTC (permalink / raw)
To: pdm-devel
lib.rs re-exports all public member of the new remote_upid module, so
for callers this change is non-breaking.
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
lib/pdm-api-types/src/lib.rs | 91 ++-------------------------
lib/pdm-api-types/src/remote_upid.rs | 93 ++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 87 deletions(-)
create mode 100644 lib/pdm-api-types/src/remote_upid.rs
diff --git a/lib/pdm-api-types/src/lib.rs b/lib/pdm-api-types/src/lib.rs
index ee4dfb2b..ad52372e 100644
--- a/lib/pdm-api-types/src/lib.rs
+++ b/lib/pdm-api-types/src/lib.rs
@@ -1,13 +1,11 @@
//! Basic API types used by most of the PDM code.
use std::collections::HashMap;
-use std::fmt;
-use anyhow::{bail, Error};
use const_format::concatcp;
use serde::{Deserialize, Serialize};
-use proxmox_schema::api_types::{DNS_NAME_STR, IPRE_BRACKET_STR, PORT_REGEX_STR, SAFE_ID_REGEX};
+use proxmox_schema::api_types::{DNS_NAME_STR, IPRE_BRACKET_STR, PORT_REGEX_STR};
use proxmox_schema::{
api, const_regex, ApiStringFormat, ApiType, ArraySchema, IntegerSchema, ReturnType, Schema,
StringSchema, Updater,
@@ -23,6 +21,9 @@ pub use node_config::*;
mod metric_collection;
pub use metric_collection::*;
+mod remote_upid;
+pub use remote_upid::*;
+
mod proxy;
pub use proxy::HTTP_PROXY_SCHEMA;
@@ -410,90 +411,6 @@ impl ConfigurationState {
serde_plain::derive_display_from_serialize!(ConfigurationState);
serde_plain::derive_fromstr_from_deserialize!(ConfigurationState);
-pub const REMOTE_UPID_SCHEMA: Schema = StringSchema::new("A remote UPID")
- .min_length("C!UPID:N:12345678:12345678:12345678:::".len())
- .schema();
-
-#[derive(Clone, Debug, Eq, PartialEq, Hash)]
-pub struct RemoteUpid {
- remote: String,
- /// This is usually a pve upid, but may also be a pbs upid, they have distinct formats.
- pub upid: String,
-}
-
-impl RemoteUpid {
- pub fn remote(&self) -> &str {
- &self.remote
- }
-
- pub fn into_remote(self) -> String {
- self.remote
- }
-}
-
-impl ApiType for RemoteUpid {
- const API_SCHEMA: Schema = REMOTE_UPID_SCHEMA;
-}
-
-impl TryFrom<(String, String)> for RemoteUpid {
- type Error = Error;
-
- fn try_from((remote, upid): (String, String)) -> Result<Self, Error> {
- if !SAFE_ID_REGEX.is_match(&remote) {
- bail!("bad remote id in remote upid");
- }
- Ok(Self { remote, upid })
- }
-}
-
-impl TryFrom<(String, &str)> for RemoteUpid {
- type Error = Error;
-
- fn try_from((remote, upid): (String, &str)) -> Result<Self, Error> {
- if !SAFE_ID_REGEX.is_match(&remote) {
- bail!("bad remote id in remote upid");
- }
- Ok(Self {
- remote,
- upid: upid.to_string(),
- })
- }
-}
-
-impl TryFrom<(&str, &str)> for RemoteUpid {
- type Error = Error;
-
- fn try_from((remote, upid): (&str, &str)) -> Result<Self, Error> {
- if !SAFE_ID_REGEX.is_match(remote) {
- bail!("bad remote id in remote upid");
- }
- Ok(Self {
- remote: remote.to_string(),
- upid: upid.to_string(),
- })
- }
-}
-
-impl std::str::FromStr for RemoteUpid {
- type Err = Error;
-
- fn from_str(s: &str) -> Result<Self, Error> {
- match s.find('!') {
- None => bail!("missing '!' separator in remote upid"),
- Some(pos) => (&s[..pos], &s[(pos + 1)..]).try_into(),
- }
- }
-}
-
-impl fmt::Display for RemoteUpid {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}!{}", self.remote, self.upid)
- }
-}
-
-serde_plain::derive_deserialize_from_fromstr!(RemoteUpid, "valid remote upid");
-serde_plain::derive_serialize_from_display!(RemoteUpid);
-
fn limit_default() -> u64 {
50
}
diff --git a/lib/pdm-api-types/src/remote_upid.rs b/lib/pdm-api-types/src/remote_upid.rs
new file mode 100644
index 00000000..bf7c1797
--- /dev/null
+++ b/lib/pdm-api-types/src/remote_upid.rs
@@ -0,0 +1,93 @@
+use std::fmt;
+
+use anyhow::{bail, Error};
+
+use proxmox_schema::api_types::SAFE_ID_REGEX;
+use proxmox_schema::{ApiType, Schema, StringSchema};
+
+pub const REMOTE_UPID_SCHEMA: Schema = StringSchema::new("A remote UPID")
+ .min_length("C!UPID:N:12345678:12345678:12345678:::".len())
+ .schema();
+
+#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+pub struct RemoteUpid {
+ remote: String,
+ /// This is usually a pve upid, but may also be a pbs upid, they have distinct formats.
+ pub upid: String,
+}
+
+impl RemoteUpid {
+ pub fn remote(&self) -> &str {
+ &self.remote
+ }
+
+ pub fn into_remote(self) -> String {
+ self.remote
+ }
+}
+
+impl ApiType for RemoteUpid {
+ const API_SCHEMA: Schema = REMOTE_UPID_SCHEMA;
+}
+
+impl TryFrom<(String, String)> for RemoteUpid {
+ type Error = Error;
+
+ fn try_from((remote, upid): (String, String)) -> Result<Self, Error> {
+ if !SAFE_ID_REGEX.is_match(&remote) {
+ bail!("bad remote id in remote upid");
+ }
+
+ Ok(Self { remote, upid })
+ }
+}
+
+impl TryFrom<(String, &str)> for RemoteUpid {
+ type Error = Error;
+
+ fn try_from((remote, upid): (String, &str)) -> Result<Self, Error> {
+ if !SAFE_ID_REGEX.is_match(&remote) {
+ bail!("bad remote id in remote upid");
+ }
+
+ Ok(Self {
+ remote,
+ upid: upid.to_string(),
+ })
+ }
+}
+
+impl TryFrom<(&str, &str)> for RemoteUpid {
+ type Error = Error;
+
+ fn try_from((remote, upid): (&str, &str)) -> Result<Self, Error> {
+ if !SAFE_ID_REGEX.is_match(remote) {
+ bail!("bad remote id in remote upid");
+ }
+
+ Ok(Self {
+ remote: remote.to_string(),
+ upid: upid.to_string(),
+ })
+ }
+}
+
+impl std::str::FromStr for RemoteUpid {
+ type Err = Error;
+
+ fn from_str(s: &str) -> Result<Self, Error> {
+ match s.find('!') {
+ None => bail!("missing '!' separator in remote upid"),
+ Some(pos) => (&s[..pos], &s[(pos + 1)..]).try_into(),
+ }
+ }
+}
+
+impl fmt::Display for RemoteUpid {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}!{}", self.remote, self.upid)
+ }
+}
+
+serde_plain::derive_deserialize_from_fromstr!(RemoteUpid, "valid remote upid");
+serde_plain::derive_serialize_from_display!(RemoteUpid);
--
2.47.3
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* [pdm-devel] [PATCH datacenter-manager 2/8] pdm-api-types: remote upid: make upid field private
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
2025-11-11 10:50 ` [pdm-devel] [PATCH datacenter-manager 1/8] pdm-api-types: move RemoteUpid to its own module Lukas Wagner
@ 2025-11-11 10:50 ` Lukas Wagner
2025-11-11 10:50 ` [pdm-devel] [PATCH datacenter-manager 3/8] pdm-api-types: remote upid: add missing doc strings Lukas Wagner
` (7 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Lukas Wagner @ 2025-11-11 10:50 UTC (permalink / raw)
To: pdm-devel
Shielding members behind a getter is beneficial in most cases. This
makes it easier to change the internal representation of the type
later.
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
lib/pdm-api-types/src/remote_upid.rs | 12 +++++++++++-
server/src/api/pve/tasks.rs | 18 +++++++++---------
server/src/remote_tasks/mod.rs | 2 +-
server/src/remote_tasks/task_cache.rs | 2 +-
server/src/sdn_client.rs | 2 +-
ui/src/tasks.rs | 4 ++--
6 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/lib/pdm-api-types/src/remote_upid.rs b/lib/pdm-api-types/src/remote_upid.rs
index bf7c1797..6b0f8461 100644
--- a/lib/pdm-api-types/src/remote_upid.rs
+++ b/lib/pdm-api-types/src/remote_upid.rs
@@ -13,7 +13,7 @@ pub const REMOTE_UPID_SCHEMA: Schema = StringSchema::new("A remote UPID")
pub struct RemoteUpid {
remote: String,
/// This is usually a pve upid, but may also be a pbs upid, they have distinct formats.
- pub upid: String,
+ upid: String,
}
impl RemoteUpid {
@@ -24,6 +24,16 @@ impl RemoteUpid {
pub fn into_remote(self) -> String {
self.remote
}
+
+ /// Get the raw UPID.
+ pub fn upid(&self) -> &str {
+ &self.upid
+ }
+
+ /// Get the raw UPID, consuming self.
+ pub fn into_upid(self) -> String {
+ self.upid
+ }
}
impl ApiType for RemoteUpid {
diff --git a/server/src/api/pve/tasks.rs b/server/src/api/pve/tasks.rs
index 0371fa00..9f04a448 100644
--- a/server/src/api/pve/tasks.rs
+++ b/server/src/api/pve/tasks.rs
@@ -89,13 +89,13 @@ async fn stop_task(remote: String, upid: RemoteUpid) -> Result<(), Error> {
let pve = get_remote(&remotes, upid.remote())?;
let pve_upid: PveUpid = upid
- .upid
+ .upid()
.parse()
- .map_err(|err| format_err!("invalid upid for PVE: {} - {err}", upid.upid))?;
+ .map_err(|err| format_err!("invalid upid for PVE: {} - {err}", upid.upid()))?;
let pve = connect(pve)?;
- Ok(pve.stop_task(&pve_upid.node, &upid.upid).await?)
+ Ok(pve.stop_task(&pve_upid.node, upid.upid()).await?)
}
#[api(
@@ -135,14 +135,14 @@ pub async fn get_task_status(
let pve = get_remote(&remotes, upid.remote())?;
let pve_upid: PveUpid = upid
- .upid
+ .upid()
.parse()
- .map_err(|err| format_err!("invalid upid for PVE: {} - {err}", upid.upid))?;
+ .map_err(|err| format_err!("invalid upid for PVE: {} - {err}", upid.upid()))?;
let pve = connect(pve)?;
loop {
- let status = pve.get_task_status(&pve_upid.node, &upid.upid).await?;
+ let status = pve.get_task_status(&pve_upid.node, upid.upid()).await?;
if !wait || !status.is_running() {
break Ok(status);
}
@@ -218,14 +218,14 @@ async fn read_task_log(
let pve = get_remote(&remotes, upid.remote())?;
let pve_upid: PveUpid = upid
- .upid
+ .upid()
.parse()
- .map_err(|err| format_err!("invalid upid for PVE: {} - {err}", upid.upid))?;
+ .map_err(|err| format_err!("invalid upid for PVE: {} - {err}", upid.upid()))?;
let pve = connect(pve)?;
let response = pve
- .get_task_log(&pve_upid.node, &upid.upid, download, limit, start)
+ .get_task_log(&pve_upid.node, upid.upid(), download, limit, start)
.await?;
for (key, value) in response.attribs {
diff --git a/server/src/remote_tasks/mod.rs b/server/src/remote_tasks/mod.rs
index c4939742..37e689e0 100644
--- a/server/src/remote_tasks/mod.rs
+++ b/server/src/remote_tasks/mod.rs
@@ -53,7 +53,7 @@ pub async fn get_tasks(
}
}
// TODO: Handle PBS tasks
- let pve_upid: Result<PveUpid, Error> = task.upid.upid.parse();
+ let pve_upid: Result<PveUpid, Error> = task.upid.upid().parse();
match pve_upid {
Ok(pve_upid) => Some(TaskListItem {
upid: task.upid.to_string(),
diff --git a/server/src/remote_tasks/task_cache.rs b/server/src/remote_tasks/task_cache.rs
index 040266ad..cb3b6687 100644
--- a/server/src/remote_tasks/task_cache.rs
+++ b/server/src/remote_tasks/task_cache.rs
@@ -407,7 +407,7 @@ impl WritableTaskCache {
// TODO:: Handle PBS tasks correctly.
// TODO: This is awkward, maybe overhaul RemoteUpid type to make this easier
- match task.upid.upid.parse::<PveUpid>() {
+ match task.upid.upid().parse::<PveUpid>() {
Ok(upid) => {
let node = &upid.node;
let remote = task.upid.remote();
diff --git a/server/src/sdn_client.rs b/server/src/sdn_client.rs
index f88d2a52..6b6bdfa9 100644
--- a/server/src/sdn_client.rs
+++ b/server/src/sdn_client.rs
@@ -334,7 +334,7 @@ impl<C> LockedSdnClients<C> {
loop {
tokio::time::sleep(Self::POLLING_INTERVAL).await;
- let status = client.get_task_status(&node, &upid.upid).await?;
+ let status = client.get_task_status(&node, upid.upid()).await?;
if !status.is_running() {
if status.finished_successfully() == Some(true) {
diff --git a/ui/src/tasks.rs b/ui/src/tasks.rs
index 4ff29755..41a8648d 100644
--- a/ui/src/tasks.rs
+++ b/ui/src/tasks.rs
@@ -112,9 +112,9 @@ pub fn register_pve_tasks() {
/// If it's a [`RemoteUpid`], prefixes it with the remote name
pub fn format_optional_remote_upid(upid: &str, include_remote: bool) -> String {
if let Ok(remote_upid) = upid.parse::<RemoteUpid>() {
- let description = match remote_upid.upid.parse::<PveUpid>() {
+ let description = match remote_upid.upid().parse::<PveUpid>() {
Ok(upid) => format_task_description(&upid.worker_type, upid.worker_id.as_deref()),
- Err(_) => format_upid(&remote_upid.upid),
+ Err(_) => format_upid(&remote_upid.upid()),
};
if include_remote {
format!("{} - {}", remote_upid.remote(), description)
--
2.47.3
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* [pdm-devel] [PATCH datacenter-manager 3/8] pdm-api-types: remote upid: add missing doc strings
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
2025-11-11 10:50 ` [pdm-devel] [PATCH datacenter-manager 1/8] pdm-api-types: move RemoteUpid to its own module Lukas Wagner
2025-11-11 10:50 ` [pdm-devel] [PATCH datacenter-manager 2/8] pdm-api-types: remote upid: make upid field private Lukas Wagner
@ 2025-11-11 10:50 ` Lukas Wagner
2025-11-11 10:50 ` [pdm-devel] [PATCH datacenter-manager 4/8] pdm-api-types: remote upid: add basic tests for RemoteUpid ser/deserialization Lukas Wagner
` (6 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Lukas Wagner @ 2025-11-11 10:50 UTC (permalink / raw)
To: pdm-devel
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
lib/pdm-api-types/src/remote_upid.rs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/pdm-api-types/src/remote_upid.rs b/lib/pdm-api-types/src/remote_upid.rs
index 6b0f8461..b4a32769 100644
--- a/lib/pdm-api-types/src/remote_upid.rs
+++ b/lib/pdm-api-types/src/remote_upid.rs
@@ -10,17 +10,20 @@ pub const REMOTE_UPID_SCHEMA: Schema = StringSchema::new("A remote UPID")
.schema();
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+/// A UPID type for tasks on a specific remote.
pub struct RemoteUpid {
remote: String,
- /// This is usually a pve upid, but may also be a pbs upid, they have distinct formats.
+ // This can either be a PVE UPID or a PBS UPID, both have distinct, incompatible formats.
upid: String,
}
impl RemoteUpid {
+ /// Get the remote for this UPID.
pub fn remote(&self) -> &str {
&self.remote
}
+ /// Get the remote for this UPID, consuming self.
pub fn into_remote(self) -> String {
self.remote
}
--
2.47.3
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* [pdm-devel] [PATCH datacenter-manager 4/8] pdm-api-types: remote upid: add basic tests for RemoteUpid ser/deserialization
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
` (2 preceding siblings ...)
2025-11-11 10:50 ` [pdm-devel] [PATCH datacenter-manager 3/8] pdm-api-types: remote upid: add missing doc strings Lukas Wagner
@ 2025-11-11 10:50 ` Lukas Wagner
2025-11-11 10:50 ` [pdm-devel] [RFC datacenter-manager 5/8] pdm-api-types: remote upid: add type field to RemoteUpid Lukas Wagner
` (5 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Lukas Wagner @ 2025-11-11 10:50 UTC (permalink / raw)
To: pdm-devel
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
lib/pdm-api-types/src/remote_upid.rs | 53 ++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/lib/pdm-api-types/src/remote_upid.rs b/lib/pdm-api-types/src/remote_upid.rs
index b4a32769..454c9b1f 100644
--- a/lib/pdm-api-types/src/remote_upid.rs
+++ b/lib/pdm-api-types/src/remote_upid.rs
@@ -104,3 +104,56 @@ impl fmt::Display for RemoteUpid {
serde_plain::derive_deserialize_from_fromstr!(RemoteUpid, "valid remote upid");
serde_plain::derive_serialize_from_display!(RemoteUpid);
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_from_str() {
+ let pve_upid: RemoteUpid =
+ "pve-remote!UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:"
+ .parse()
+ .unwrap();
+
+ assert_eq!(pve_upid.remote(), "pve-remote");
+ assert_eq!(
+ pve_upid.upid(),
+ "UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:"
+ );
+
+ let pbs_upid: RemoteUpid =
+ "pbs-remote!UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:"
+ .parse()
+ .unwrap();
+
+ assert_eq!(pbs_upid.remote(), "pbs-remote");
+ assert_eq!(
+ pbs_upid.upid(),
+ "UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:"
+ );
+ }
+
+ #[test]
+ fn test_display() {
+ let pve_upid = RemoteUpid {
+ remote: "pve-remote".to_string(),
+ upid: "UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:".to_string(),
+ };
+
+ assert_eq!(
+ pve_upid.to_string(),
+ "pve-remote!UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:"
+ );
+
+ let pbs_upid = RemoteUpid {
+ remote: "pbs-remote".to_string(),
+ upid: "UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:".to_string(),
+ };
+
+ assert_eq!(
+ pbs_upid.to_string(),
+ "pbs-remote!UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:"
+ );
+ }
+}
--
2.47.3
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* [pdm-devel] [RFC datacenter-manager 5/8] pdm-api-types: remote upid: add type field to RemoteUpid
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
` (3 preceding siblings ...)
2025-11-11 10:50 ` [pdm-devel] [PATCH datacenter-manager 4/8] pdm-api-types: remote upid: add basic tests for RemoteUpid ser/deserialization Lukas Wagner
@ 2025-11-11 10:50 ` Lukas Wagner
2025-11-12 20:00 ` Thomas Lamprecht
2025-11-11 10:50 ` [pdm-devel] [RFC datacenter-manager 6/8] pdm-api-types: remote upid: allow to get native UPID type Lukas Wagner
` (4 subsequent siblings)
9 siblings, 1 reply; 12+ messages in thread
From: Lukas Wagner @ 2025-11-11 10:50 UTC (permalink / raw)
To: pdm-devel
In quite a few places in the code where we handle RemoteUpids, we need
to know the actual type of the remote, for instance to
- build correct API paths from it, if the UPID is passed to a
product-specific API endpoint
- get fields from the actual UPID, which requires parsing the native
UPID type - if the type is unknown here, we have to either guess
(attempt to parse one type, and if it does not work, try the other
type), or get the type from somewhere else (some other parameter, or
from remotes.cfg)
These can be easily solved by storing the type of the remote in the
RemoteUpid. The serialized representation is changed in such a way that
the type is prepended to the original represenation, e.g.
pve:remote-name!<original UPID>
This change aims to avoid breakage by being backward-compatible with the
old representation without the type field. In this case the type is
simply inferred by parsing the UPID. This adds some runtime cost, but
this is only really relevant for migrating the contents of the remote
task cache over to the new format. Once it has been migrated (which
happens automatically when rewriting the archive files, or if that does
not happen, they are simply rotated out after a while), the inefficient
code path is not really needed any more.
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
lib/pdm-api-types/Cargo.toml | 1 +
lib/pdm-api-types/src/remote_upid.rs | 122 +++++++++++++++++++++++----
lib/pdm-api-types/src/remotes.rs | 4 +-
3 files changed, 110 insertions(+), 17 deletions(-)
diff --git a/lib/pdm-api-types/Cargo.toml b/lib/pdm-api-types/Cargo.toml
index e66558bb..8e70c092 100644
--- a/lib/pdm-api-types/Cargo.toml
+++ b/lib/pdm-api-types/Cargo.toml
@@ -24,4 +24,5 @@ proxmox-time.workspace = true
proxmox-serde.workspace = true
proxmox-subscription = { workspace = true, features = ["api-types"], default-features = false }
+pbs-api-types = { workspace = true }
pve-api-types = { workspace = true }
diff --git a/lib/pdm-api-types/src/remote_upid.rs b/lib/pdm-api-types/src/remote_upid.rs
index 454c9b1f..32106e42 100644
--- a/lib/pdm-api-types/src/remote_upid.rs
+++ b/lib/pdm-api-types/src/remote_upid.rs
@@ -5,19 +5,30 @@ use anyhow::{bail, Error};
use proxmox_schema::api_types::SAFE_ID_REGEX;
use proxmox_schema::{ApiType, Schema, StringSchema};
+use crate::remotes::RemoteType;
+
pub const REMOTE_UPID_SCHEMA: Schema = StringSchema::new("A remote UPID")
- .min_length("C!UPID:N:12345678:12345678:12345678:::".len())
+ .min_length("abc:C!UPID:N:12345678:12345678:12345678:::".len())
.schema();
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
/// A UPID type for tasks on a specific remote.
pub struct RemoteUpid {
remote: String,
+ remote_type: RemoteType,
// This can either be a PVE UPID or a PBS UPID, both have distinct, incompatible formats.
upid: String,
}
impl RemoteUpid {
+ /// Create a new remote UPID.
+ pub fn new(remote: String, remote_type: RemoteType, upid: String) -> Self {
+ Self {
+ remote,
+ upid,
+ remote_type,
+ }
+ }
/// Get the remote for this UPID.
pub fn remote(&self) -> &str {
&self.remote
@@ -37,6 +48,21 @@ impl RemoteUpid {
pub fn into_upid(self) -> String {
self.upid
}
+
+ /// Return the type of the remote which corresponds to this UPID.
+ pub fn remote_type(&self) -> RemoteType {
+ self.remote_type
+ }
+
+ fn deduce_type(raw_upid: &str) -> Result<RemoteType, Error> {
+ if raw_upid.parse::<pve_api_types::PveUpid>().is_ok() {
+ Ok(RemoteType::Pve)
+ } else if raw_upid.parse::<pbs_api_types::UPID>().is_ok() {
+ Ok(RemoteType::Pbs)
+ } else {
+ bail!("invalid upid: {raw_upid}");
+ }
+ }
}
impl ApiType for RemoteUpid {
@@ -51,7 +77,13 @@ impl TryFrom<(String, String)> for RemoteUpid {
bail!("bad remote id in remote upid");
}
- Ok(Self { remote, upid })
+ let ty = Self::deduce_type(&upid)?;
+
+ Ok(Self {
+ remote,
+ upid,
+ remote_type: ty,
+ })
}
}
@@ -63,9 +95,12 @@ impl TryFrom<(String, &str)> for RemoteUpid {
bail!("bad remote id in remote upid");
}
+ let ty = Self::deduce_type(upid)?;
+
Ok(Self {
remote,
upid: upid.to_string(),
+ remote_type: ty,
})
}
}
@@ -78,9 +113,30 @@ impl TryFrom<(&str, &str)> for RemoteUpid {
bail!("bad remote id in remote upid");
}
+ let ty = Self::deduce_type(upid)?;
+
Ok(Self {
remote: remote.to_string(),
upid: upid.to_string(),
+ remote_type: ty,
+ })
+ }
+}
+
+impl TryFrom<(&str, &str, &str)> for RemoteUpid {
+ type Error = Error;
+
+ fn try_from((ty, remote, upid): (&str, &str, &str)) -> Result<Self, Error> {
+ if !SAFE_ID_REGEX.is_match(remote) {
+ bail!("bad remote id in remote upid");
+ }
+
+ let ty = ty.parse()?;
+
+ Ok(Self {
+ remote: remote.to_string(),
+ upid: upid.to_string(),
+ remote_type: ty,
})
}
}
@@ -89,16 +145,19 @@ impl std::str::FromStr for RemoteUpid {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
- match s.find('!') {
+ match s.split_once('!') {
None => bail!("missing '!' separator in remote upid"),
- Some(pos) => (&s[..pos], &s[(pos + 1)..]).try_into(),
+ Some((remote_and_type, upid)) => match remote_and_type.split_once(':') {
+ Some((ty, remote)) => (ty, remote, upid).try_into(),
+ None => (remote_and_type, upid).try_into(),
+ },
}
}
}
impl fmt::Display for RemoteUpid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}!{}", self.remote, self.upid)
+ write!(f, "{}:{}!{}", self.remote_type, self.remote, self.upid)
}
}
@@ -110,13 +169,14 @@ mod tests {
use super::*;
#[test]
- fn test_from_str() {
+ fn test_from_str_old_format() {
let pve_upid: RemoteUpid =
"pve-remote!UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:"
.parse()
.unwrap();
assert_eq!(pve_upid.remote(), "pve-remote");
+ assert_eq!(pve_upid.remote_type(), RemoteType::Pve);
assert_eq!(
pve_upid.upid(),
"UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:"
@@ -128,6 +188,34 @@ mod tests {
.unwrap();
assert_eq!(pbs_upid.remote(), "pbs-remote");
+ assert_eq!(pbs_upid.remote_type(), RemoteType::Pbs);
+ assert_eq!(
+ pbs_upid.upid(),
+ "UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:"
+ );
+ }
+
+ #[test]
+ fn test_from_str_new_format() {
+ let pve_upid: RemoteUpid =
+ "pve:pve-remote!UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:"
+ .parse()
+ .unwrap();
+
+ assert_eq!(pve_upid.remote(), "pve-remote");
+ assert_eq!(pve_upid.remote_type(), RemoteType::Pve);
+ assert_eq!(
+ pve_upid.upid(),
+ "UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:"
+ );
+
+ let pbs_upid: RemoteUpid =
+ "pbs:pbs-remote!UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:"
+ .parse()
+ .unwrap();
+
+ assert_eq!(pbs_upid.remote(), "pbs-remote");
+ assert_eq!(pbs_upid.remote_type(), RemoteType::Pbs);
assert_eq!(
pbs_upid.upid(),
"UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:"
@@ -136,24 +224,26 @@ mod tests {
#[test]
fn test_display() {
- let pve_upid = RemoteUpid {
- remote: "pve-remote".to_string(),
- upid: "UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:".to_string(),
- };
+ let pve_upid = RemoteUpid::new(
+ "pve-remote".to_string(),
+ RemoteType::Pve,
+ "UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:".to_string(),
+ );
assert_eq!(
pve_upid.to_string(),
- "pve-remote!UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:"
+ "pve:pve-remote!UPID:pve:00039E4D:002638B8:67B4A9D1:stopall::root@pam:"
);
- let pbs_upid = RemoteUpid {
- remote: "pbs-remote".to_string(),
- upid: "UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:".to_string(),
- };
+ let pbs_upid = RemoteUpid::new(
+ "pbs-remote".to_string(),
+ RemoteType::Pbs,
+ "UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:".to_string(),
+ );
assert_eq!(
pbs_upid.to_string(),
- "pbs-remote!UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:"
+ "pbs:pbs-remote!UPID:pbs:000002B2:00000158:00000000:674D828C:logrotate::root@pam:"
);
}
}
diff --git a/lib/pdm-api-types/src/remotes.rs b/lib/pdm-api-types/src/remotes.rs
index dd6afa68..bd90ef1e 100644
--- a/lib/pdm-api-types/src/remotes.rs
+++ b/lib/pdm-api-types/src/remotes.rs
@@ -39,7 +39,9 @@ pub struct NodeUrl {
#[api]
/// The type of a remote entry.
-#[derive(Clone, Copy, Default, Debug, Eq, PartialEq, Deserialize, Serialize, Ord, PartialOrd)]
+#[derive(
+ Clone, Copy, Default, Debug, Eq, PartialEq, Deserialize, Serialize, Ord, PartialOrd, Hash,
+)]
#[serde(rename_all = "lowercase")]
pub enum RemoteType {
/// A Proxmox VE node.
--
2.47.3
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [pdm-devel] [RFC datacenter-manager 5/8] pdm-api-types: remote upid: add type field to RemoteUpid
2025-11-11 10:50 ` [pdm-devel] [RFC datacenter-manager 5/8] pdm-api-types: remote upid: add type field to RemoteUpid Lukas Wagner
@ 2025-11-12 20:00 ` Thomas Lamprecht
0 siblings, 0 replies; 12+ messages in thread
From: Thomas Lamprecht @ 2025-11-12 20:00 UTC (permalink / raw)
To: Proxmox Datacenter Manager development discussion, Lukas Wagner
Am 11.11.25 um 11:50 schrieb Lukas Wagner:
> diff --git a/lib/pdm-api-types/src/remote_upid.rs b/lib/pdm-api-types/src/remote_upid.rs
> index 454c9b1f..32106e42 100644
> --- a/lib/pdm-api-types/src/remote_upid.rs
> +++ b/lib/pdm-api-types/src/remote_upid.rs
> @@ -5,19 +5,30 @@ use anyhow::{bail, Error};
> use proxmox_schema::api_types::SAFE_ID_REGEX;
> use proxmox_schema::{ApiType, Schema, StringSchema};
>
> +use crate::remotes::RemoteType;
> +
> pub const REMOTE_UPID_SCHEMA: Schema = StringSchema::new("A remote UPID")
> - .min_length("C!UPID:N:12345678:12345678:12345678:::".len())
> + .min_length("abc:C!UPID:N:12345678:12345678:12345678:::".len())
This shouldn't be a problem as all real UPIDs should be quite a bit longer,
but if the string would have been close to the actual realistic minimum
before, increasing the minimum length would be a breaking change, or do I
miss something?
Again, should not matter in practice.
> .schema();
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread
* [pdm-devel] [RFC datacenter-manager 6/8] pdm-api-types: remote upid: allow to get native UPID type
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
` (4 preceding siblings ...)
2025-11-11 10:50 ` [pdm-devel] [RFC datacenter-manager 5/8] pdm-api-types: remote upid: add type field to RemoteUpid Lukas Wagner
@ 2025-11-11 10:50 ` Lukas Wagner
2025-11-11 10:50 ` [pdm-devel] [RFC datacenter-manager 7/8] ui: remote tasks: use correct base url for PBS tasks Lukas Wagner
` (3 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Lukas Wagner @ 2025-11-11 10:50 UTC (permalink / raw)
To: pdm-devel
In some places where RemoteUpids are handled, the native UPID type needs
to be accessed, e.g. to access some of its fields. This commit adds the
`native_upid` function, which will parse the raw UPID based on the type
and return the native, product-specific UPID type.
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
lib/pdm-api-types/src/remote_upid.rs | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/lib/pdm-api-types/src/remote_upid.rs b/lib/pdm-api-types/src/remote_upid.rs
index 32106e42..10d3c1dc 100644
--- a/lib/pdm-api-types/src/remote_upid.rs
+++ b/lib/pdm-api-types/src/remote_upid.rs
@@ -20,6 +20,12 @@ pub struct RemoteUpid {
upid: String,
}
+/// Type containing the parsed, native UPID for each type of remote.
+pub enum NativeUpid {
+ PveUpid(pve_api_types::PveUpid),
+ PbsUpid(pbs_api_types::UPID),
+}
+
impl RemoteUpid {
/// Create a new remote UPID.
pub fn new(remote: String, remote_type: RemoteType, upid: String) -> Self {
@@ -54,6 +60,16 @@ impl RemoteUpid {
self.remote_type
}
+ /// Get the parsed, native UPID type.
+ ///
+ /// This function will return an error if the UPID could not be parsed.
+ pub fn native_upid(&self) -> Result<NativeUpid, Error> {
+ Ok(match self.remote_type() {
+ RemoteType::Pve => NativeUpid::PveUpid(self.upid.parse()?),
+ RemoteType::Pbs => NativeUpid::PbsUpid(self.upid.parse()?),
+ })
+ }
+
fn deduce_type(raw_upid: &str) -> Result<RemoteType, Error> {
if raw_upid.parse::<pve_api_types::PveUpid>().is_ok() {
Ok(RemoteType::Pve)
--
2.47.3
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* [pdm-devel] [RFC datacenter-manager 7/8] ui: remote tasks: use correct base url for PBS tasks
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
` (5 preceding siblings ...)
2025-11-11 10:50 ` [pdm-devel] [RFC datacenter-manager 6/8] pdm-api-types: remote upid: allow to get native UPID type Lukas Wagner
@ 2025-11-11 10:50 ` Lukas Wagner
2025-11-11 10:50 ` [pdm-devel] [RFC datacenter-manager 8/8] remote task cache: handle PBS tasks correctly Lukas Wagner
` (2 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Lukas Wagner @ 2025-11-11 10:50 UTC (permalink / raw)
To: pdm-devel
This base URL will be used to retrieve the task log when clicking on a
remote task in the task list. The corresponding PBS API endpoint will be
added later.
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
ui/src/remotes/tasks.rs | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/ui/src/remotes/tasks.rs b/ui/src/remotes/tasks.rs
index 4853a1cf..825bd57f 100644
--- a/ui/src/remotes/tasks.rs
+++ b/ui/src/remotes/tasks.rs
@@ -124,8 +124,11 @@ impl Component for PbsRemoteTaskList {
.as_ref()
.and_then(|(upid, endtime)| upid.parse::<RemoteUpid>().ok().map(|upid| (upid, endtime)))
.map(|(remote_upid, endtime)| {
- // TODO PBS
- let base_url = format!("/pve/remotes/{}/tasks", remote_upid.remote());
+ let base_url = format!(
+ "/{}/remotes/{}/tasks",
+ remote_upid.remote_type(),
+ remote_upid.remote()
+ );
TaskViewer::new(remote_upid.to_string())
.endtime(endtime)
.base_url(base_url)
--
2.47.3
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* [pdm-devel] [RFC datacenter-manager 8/8] remote task cache: handle PBS tasks correctly
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
` (6 preceding siblings ...)
2025-11-11 10:50 ` [pdm-devel] [RFC datacenter-manager 7/8] ui: remote tasks: use correct base url for PBS tasks Lukas Wagner
@ 2025-11-11 10:50 ` Lukas Wagner
2025-11-12 15:50 ` [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Shannon Sterz
2025-11-12 20:27 ` [pdm-devel] applied-series: " Thomas Lamprecht
9 siblings, 0 replies; 12+ messages in thread
From: Lukas Wagner @ 2025-11-11 10:50 UTC (permalink / raw)
To: pdm-devel
The remote task cache assumed in some cases that all UPIDs were PVE
UPIDs; mostly for simplicity, since PBS remotes were not implemented yet
at the time of implementation of the task cache.
The new remote_type and native_upid functions for the RemoteUpid struct
makes it pretty simple to add support for PBS.
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
server/src/remote_tasks/mod.rs | 21 ++++++++++++++++-----
server/src/remote_tasks/task_cache.rs | 19 ++++++++++++-------
2 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/server/src/remote_tasks/mod.rs b/server/src/remote_tasks/mod.rs
index 37e689e0..f39d0b77 100644
--- a/server/src/remote_tasks/mod.rs
+++ b/server/src/remote_tasks/mod.rs
@@ -2,7 +2,7 @@ use std::path::Path;
use anyhow::Error;
-use pdm_api_types::{RemoteUpid, TaskFilters, TaskListItem, TaskStateType};
+use pdm_api_types::{NativeUpid, RemoteUpid, TaskFilters, TaskListItem, TaskStateType};
use pve_api_types::PveUpid;
pub mod task_cache;
@@ -52,10 +52,9 @@ pub async fn get_tasks(
return None;
}
}
- // TODO: Handle PBS tasks
- let pve_upid: Result<PveUpid, Error> = task.upid.upid().parse();
- match pve_upid {
- Ok(pve_upid) => Some(TaskListItem {
+
+ match task.upid.native_upid() {
+ Ok(NativeUpid::PveUpid(pve_upid)) => Some(TaskListItem {
upid: task.upid.to_string(),
node: pve_upid.node,
pid: pve_upid.pid as i64,
@@ -67,6 +66,18 @@ pub async fn get_tasks(
endtime: task.endtime,
status: task.status,
}),
+ Ok(NativeUpid::PbsUpid(pbs_upid)) => Some(TaskListItem {
+ upid: task.upid.to_string(),
+ node: pbs_upid.node,
+ pid: pbs_upid.pid as i64,
+ pstart: pbs_upid.pstart,
+ starttime: pbs_upid.starttime,
+ worker_type: pbs_upid.worker_type,
+ worker_id: pbs_upid.worker_id,
+ user: pbs_upid.auth_id,
+ endtime: task.endtime,
+ status: task.status,
+ }),
Err(err) => {
log::error!("could not parse UPID: {err:#}");
None
diff --git a/server/src/remote_tasks/task_cache.rs b/server/src/remote_tasks/task_cache.rs
index cb3b6687..1eee46a6 100644
--- a/server/src/remote_tasks/task_cache.rs
+++ b/server/src/remote_tasks/task_cache.rs
@@ -15,8 +15,7 @@ use serde::{Deserialize, Serialize};
use proxmox_sys::fs::CreateOptions;
-use pdm_api_types::RemoteUpid;
-use pve_api_types::PveUpid;
+use pdm_api_types::{NativeUpid, RemoteUpid};
/// Filename for the file containing running tasks.
const ACTIVE_FILENAME: &str = "active";
@@ -405,15 +404,21 @@ impl WritableTaskCache {
// Remove this finished task from our set of active tasks.
active_tasks.remove(&task.upid);
- // TODO:: Handle PBS tasks correctly.
- // TODO: This is awkward, maybe overhaul RemoteUpid type to make this easier
- match task.upid.upid().parse::<PveUpid>() {
- Ok(upid) => {
+ match task.upid.native_upid() {
+ Ok(NativeUpid::PveUpid(upid)) => {
let node = &upid.node;
let remote = task.upid.remote();
if node_success_map.node_successful(remote, node) {
- state.update_cutoff_timestamp(task.upid.remote(), node, task.starttime);
+ state.update_cutoff_timestamp(remote, node, task.starttime);
+ }
+ }
+ Ok(NativeUpid::PbsUpid(upid)) => {
+ let node = &upid.node;
+ let remote = task.upid.remote();
+
+ if node_success_map.node_successful(remote, node) {
+ state.update_cutoff_timestamp(remote, node, task.starttime);
}
}
Err(error) => {
--
2.47.3
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
` (7 preceding siblings ...)
2025-11-11 10:50 ` [pdm-devel] [RFC datacenter-manager 8/8] remote task cache: handle PBS tasks correctly Lukas Wagner
@ 2025-11-12 15:50 ` Shannon Sterz
2025-11-12 20:27 ` [pdm-devel] applied-series: " Thomas Lamprecht
9 siblings, 0 replies; 12+ messages in thread
From: Shannon Sterz @ 2025-11-12 15:50 UTC (permalink / raw)
To: Lukas Wagner; +Cc: Proxmox Datacenter Manager development discussion
these look fine to me. just a high level note: we already have some edge
cases in pbs where the length of the upid is reaching limits imposed by
the file system [1]. this isn't much of a problem here from what i can
tell, as these fields could be easily separated out when persisting this
to disk (not sure why we'd need that here in the first place, though).
however, computing the type of a upid isn't that difficult either, since
it they differ only in the amount of segments they have. with pve upid's
having one segment less than pbs ones. so i'm not sure that is really so
much overhead.
imo there is nothing wrong this approach though, so consider this:
Reviewed-by: Shannon Sterz <s.sterz@proxmox.com>
Tested-by: Shannon Sterz <s.sterz@proxmox.com>
note that i did not do in-depth testing, just a quick smoke test whether
everything still works. so i can't say anything about performance here.
[1]: https://bugzilla.proxmox.com/show_bug.cgi?id=6282
On Tue Nov 11, 2025 at 11:50 AM CET, Lukas Wagner wrote:
> In quite a few places in the code where we handle RemoteUpids, we need
> to know the actual type of the remote, for instance to
> - build correct API paths from it, if the UPID is passed to a
> product-specific API endpoint (e.g. see [1])
> - get fields from the actual UPID, which requires parsing the native
> UPID type - if the type is unknown here, we have to either guess
> (attempt to parse one type, and if it does not work, try the other
> type), or get the type from somewhere else (some other parameter, or
> from remotes.cfg) (e.g. see [2])
>
> These can be easily solved by storing the type of the remote in the
> RemoteUpid. The serialized representation is changed in such a way that
> the type is prepended to the original represenation, e.g.
>
> pve:remote-name!<original UPID>
>
> This change aims to avoid breakage by being backward-compatible with the old
> representation without the type field. In this case the type is simply inferred
> by parsing the UPID. This adds some runtime cost, but this is only really
> relevant for migrating the contents of the remote task cache over to the new
> format. Once it has been migrated (which happens automatically when rewriting
> the archive files, or if that does not happen, they are simply rotated out
> after a while), the inefficient code path is not really needed any more (once
> all the call sites producing a remote UPID have been adapted to use the new
> constructor, not part of this series yet).
>
> The following commits are a bit of cleanup/best-practices and can be
> applied unconditionally:
> pdm-api-types: move RemoteUpid to its own module
> pdm-api-types: remote upid: make upid field private
> pdm-api-types: remote upid: add missing doc strings
> pdm-api-types: remote upid: add basic tests for RemoteUpid ser/deserialization
>
> These commits then actually change the RemoteUpid type so that includes
> a type:
> pdm-api-types: remote upid: add type field to RemoteUpid
> pdm-api-types: remote upid: allow to get native UPID type
>
> The last commits show how the existing code can make use of
> the changes:
> [1]: ui: remote tasks: use correct base url for PBS tasks
> [2]: remote task cache: handle PBS tasks correctly
>
>
> proxmox-datacenter-manager:
>
> Lukas Wagner (8):
> pdm-api-types: move RemoteUpid to its own module
> pdm-api-types: remote upid: make upid field private
> pdm-api-types: remote upid: add missing doc strings
> pdm-api-types: remote upid: add basic tests for RemoteUpid
> ser/deserialization
> pdm-api-types: remote upid: add type field to RemoteUpid
> pdm-api-types: remote upid: allow to get native UPID type
> ui: remote tasks: use correct base url for PBS tasks
> remote task cache: handle PBS tasks correctly
>
> lib/pdm-api-types/Cargo.toml | 1 +
> lib/pdm-api-types/src/lib.rs | 91 +--------
> lib/pdm-api-types/src/remote_upid.rs | 265 ++++++++++++++++++++++++++
> lib/pdm-api-types/src/remotes.rs | 4 +-
> server/src/api/pve/tasks.rs | 18 +-
> server/src/remote_tasks/mod.rs | 21 +-
> server/src/remote_tasks/task_cache.rs | 19 +-
> server/src/sdn_client.rs | 2 +-
> ui/src/remotes/tasks.rs | 7 +-
> ui/src/tasks.rs | 4 +-
> 10 files changed, 318 insertions(+), 114 deletions(-)
> create mode 100644 lib/pdm-api-types/src/remote_upid.rs
>
>
> Summary over all repositories:
> 10 files changed, 318 insertions(+), 114 deletions(-)
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread* [pdm-devel] applied-series: [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid
2025-11-11 10:50 [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Lukas Wagner
` (8 preceding siblings ...)
2025-11-12 15:50 ` [pdm-devel] [PATCH/RFC datacenter-manager 0/8] add type field to RemoteUpid Shannon Sterz
@ 2025-11-12 20:27 ` Thomas Lamprecht
9 siblings, 0 replies; 12+ messages in thread
From: Thomas Lamprecht @ 2025-11-12 20:27 UTC (permalink / raw)
To: pdm-devel, Lukas Wagner
On Tue, 11 Nov 2025 11:50:51 +0100, Lukas Wagner wrote:
> In quite a few places in the code where we handle RemoteUpids, we need
> to know the actual type of the remote, for instance to
> - build correct API paths from it, if the UPID is passed to a
> product-specific API endpoint (e.g. see [1])
> - get fields from the actual UPID, which requires parsing the native
> UPID type - if the type is unknown here, we have to either guess
> (attempt to parse one type, and if it does not work, try the other
> type), or get the type from somewhere else (some other parameter, or
> from remotes.cfg) (e.g. see [2])
>
> [...]
Applied, thanks!
[1/8] pdm-api-types: move RemoteUpid to its own module
commit: 918f726a68a015921f3dfbb8327f97ef5eb11a9c
[2/8] pdm-api-types: remote upid: make upid field private
commit: f4ee979b0df83e39bf7bfe0e63386a36a86644f9
[3/8] pdm-api-types: remote upid: add missing doc strings
commit: e504946434c9aff65600fc9bb4466849d36045b2
[4/8] pdm-api-types: remote upid: add basic tests for RemoteUpid ser/deserialization
commit: b1950a74dcd277ff3457bde966a3c9ae9b9734e2
[5/8] pdm-api-types: remote upid: add type field to RemoteUpid
commit: 61612234e4560f539fa7bd9ee9fcde99c74ec069
[6/8] pdm-api-types: remote upid: allow to get native UPID type
commit: f789510e02a5c439e5ac2fe289b6ab3e59e32bd9
[7/8] ui: remote tasks: use correct base url for PBS tasks
commit: 4fb44296018113f2385bc2a885285cb797c44d6f
[8/8] remote task cache: handle PBS tasks correctly
commit: 5a02860b95fd17f5c20938f0557c3a2f6f3fd378
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 12+ messages in thread