public inbox for pdm-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pdm-devel] [PATCH datacenter-manager] ui: add task descriptions for PBS tasks
@ 2025-12-17 14:39 Lukas Wagner
  0 siblings, 0 replies; only message in thread
From: Lukas Wagner @ 2025-12-17 14:39 UTC (permalink / raw)
  To: pdm-devel

Tried to match the JS-implementation as exactly as possible. Some of the
definitions could definitely be improved, but this should be done in
tandem with the JS code. Maybe we could could even attempt to have a
canonical definition somewhere and then generate both the Rust and JS
implementations from that - but not sure if this is worth the effort.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---

This patch requires

https://lore.proxmox.com/pdm-devel/20251216131518.241022-7-l.wagner@proxmox.com/T/#u

to be applied first. This patch is pretty much independent of the series
it is contained in, so it could be applied ahead of the rest.

 ui/Cargo.toml   |   2 +
 ui/src/tasks.rs | 162 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 164 insertions(+)

diff --git a/ui/Cargo.toml b/ui/Cargo.toml
index 1b4f0a23..735a31ac 100644
--- a/ui/Cargo.toml
+++ b/ui/Cargo.toml
@@ -18,6 +18,7 @@ http = "1"
 js-sys = "0.3.69"
 log = "0.4.6"
 percent-encoding = "2.1"
+regex = "1"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 wasm-bindgen = "0.2.92"
@@ -42,6 +43,7 @@ proxmox-schema = "5"
 proxmox-subscription = { version = "1.0.1", features = ["api-types"], default-features = false }
 proxmox-rrd-api-types = "1"
 proxmox-node-status = "1"
+proxmox-time = "2.1"
 pbs-api-types = { version = "1.0.3", features = [ "enum-fallback" ] }
 
 pdm-api-types = { version = "1.0", path = "../lib/pdm-api-types" }
diff --git a/ui/src/tasks.rs b/ui/src/tasks.rs
index 7e40863d..964ba47c 100644
--- a/ui/src/tasks.rs
+++ b/ui/src/tasks.rs
@@ -6,6 +6,7 @@ use yew::virtual_dom::Key;
 
 pub fn register_tasks() {
     register_pve_tasks();
+    register_pbs_tasks();
     register_pdm_tasks();
 }
 
@@ -112,6 +113,96 @@ fn register_pve_tasks() {
     register_task_description("zfsremove", ("ZFS Pool", tr!("Remove")));
 }
 
+pub fn register_pbs_tasks() {
+    register_task_description("acme-deativate", |_ty, id: Option<String>| {
+        let id = id.unwrap_or_else(|| "default".to_string());
+        tr!("Deactivate ACME Account - {0}", id)
+    });
+    register_task_description("acme-register", |_ty, id: Option<String>| {
+        let id = id.unwrap_or_else(|| "default".to_string());
+        tr!("Register ACME Account - {0}", id)
+    });
+    register_task_description("acme-update", |_ty, id: Option<String>| {
+        let id = id.unwrap_or_else(|| "default".to_string());
+        tr!("Update ACME Account - {0}", id)
+    });
+    register_task_description("acme-new-cert", ("", tr!("Order Certificate")));
+    register_task_description("acme-renew-cert", ("", tr!("Renew Certificate")));
+    register_task_description("acme-revoke-cert", ("", tr!("Revoke Certificate")));
+    register_task_description("backup", |_ty, id: Option<String>| {
+        render_datastore_worker_id(&id.unwrap_or_default(), &tr!("Backup"))
+    });
+    register_task_description("barcode-label-media", ("Drive", tr!("Barcode-Label Media")));
+    register_task_description("catalog-media", ("Drive", tr!("Catalog Media")));
+    register_task_description(
+        "create-datastore",
+        (tr!("Datastore"), tr!("Create Datastore")),
+    );
+    register_task_description(
+        "delete-datastore",
+        (tr!("Datastore"), tr!("Remove Datastore")),
+    );
+    register_task_description(
+        "delete-namespace",
+        (tr!("Namespace"), tr!("Remove Namespace")),
+    );
+    register_task_description("dircreate", (tr!("Directory Storage"), tr!("Create")));
+    register_task_description("dirremove", (tr!("Directory Storage"), tr!("Remove")));
+    register_task_description("eject-media", (tr!("Drive"), tr!("Eject Media")));
+    register_task_description("format-media", (tr!("Drive"), tr!("Format Media")));
+    register_task_description("forget-group", (tr!("Group"), tr!("Remove Group")));
+    register_task_description(
+        "garbage_collection",
+        (tr!("Datastore"), tr!("Garbage Collect")),
+    );
+    register_task_description("realm-sync", ("Realm", tr!("User Sync")));
+    register_task_description("inventory-update", (tr!("Drive"), tr!("Inventory Update")));
+    register_task_description("label-media", (tr!("Drive"), tr!("Label Media")));
+    register_task_description("load-media", |_ty, id: Option<String>| {
+        render_drive_load_media_id(&id.unwrap_or_default(), &tr!("Load Media"))
+    });
+    register_task_description("logrotate", tr!("Log Rotation"));
+    register_task_description("mount-device", (tr!("Datastore"), tr!("Mount Device")));
+    register_task_description(
+        "mount-sync-jobs",
+        (
+            tr!("Datastore"),
+            tr!("sync jobs handler triggered by mount"),
+        ),
+    );
+    register_task_description("prune", |_ty, id: Option<String>| {
+        render_datastore_worker_id(&id.unwrap_or_default(), "Prune")
+    });
+    register_task_description("prunejob", |_ty, id: Option<String>| {
+        render_prune_job_worker_id(&id.unwrap_or_default(), &tr!("Prune Job"))
+    });
+    register_task_description("reader", |_ty, id: Option<String>| {
+        render_datastore_worker_id(&id.unwrap_or_default(), &tr!("Read Objects"))
+    });
+    register_task_description("rewind-media", (tr!("Drive"), tr!("Rewind Media")));
+    register_task_description("s3-refresh", (tr!("Datastore"), tr!("S3 Refresh")));
+    register_task_description("sync", (tr!("Datastore"), tr!("Remote Sync")));
+    register_task_description("syncjob", (tr!("Sync Job"), tr!("Remote Sync")));
+    register_task_description("tape-backup", |_ty, id: Option<String>| {
+        render_tape_backup_id(&id.unwrap_or_default(), &tr!("Tape Backup"))
+    });
+    register_task_description("tape-backup-job", |_ty, id: Option<String>| {
+        render_tape_backup_id(&id.unwrap_or_default(), &tr!("Tape Backup Job"))
+    });
+    register_task_description("tape-restore", (tr!("Datastore"), tr!("Tape Restore")));
+    register_task_description("unload-media", (tr!("Drive"), tr!("Unload Media")));
+    register_task_description("unmount-device", (tr!("Datastore"), tr!("Unmount Device")));
+    register_task_description(
+        "verificationjob",
+        (tr!("Verify Job"), tr!("Scheduled Verification")),
+    );
+    register_task_description("verify", (tr!("Datastore"), tr!("Verification")));
+    register_task_description("verify_group", (tr!("Group"), tr!("Verification")));
+    register_task_description("verify_snapshot", (tr!("Snapshot"), tr!("Verification")));
+    register_task_description("wipedisk", (tr!("Device"), tr!("Wipe Disk")));
+    register_task_description("zfscreate", (tr!("ZFS Storage"), tr!("Create")));
+}
+
 fn register_pdm_tasks() {
     register_task_description("logrotate", tr!("Log Rotation"));
     register_task_description(
@@ -124,6 +215,77 @@ fn register_pdm_tasks() {
     );
 }
 
+proxmox_schema::const_regex! {
+    DATASTORE_WORKER_ID_REGEX = r"^(\S+?):(\S+?)/(\S+?)(/(.+))?$";
+}
+
+fn render_datastore_worker_id(id: &str, what: &str) -> String {
+    if let Some(caps) = DATASTORE_WORKER_ID_REGEX.captures(id) {
+        let datastore = &caps[1];
+        let backup_group = format!("{}/{}", &caps[2], &caps[3]);
+
+        if caps.get(4).is_some() {
+            if let Some(hex_ts) = caps.get(5) {
+                if let Ok(seconds) = u64::from_str_radix(hex_ts.as_str(), 16) {
+                    let utctime =
+                        proxmox_time::epoch_to_rfc3339_utc(seconds as i64).unwrap_or_default();
+
+                    return format!("Datastore {datastore} {what} {backup_group}/{utctime}");
+                }
+            }
+        }
+
+        return format!("Datastore {datastore} {what} {backup_group}");
+    }
+
+    format!("Datastore {what} {id}")
+}
+
+proxmox_schema::const_regex! {
+    PRUNE_JOB_WORKER_ID_REGEX = r"^(\S+?):(\S+)$";
+}
+
+fn render_prune_job_worker_id(id: &str, what: &str) -> String {
+    if let Some(caps) = PRUNE_JOB_WORKER_ID_REGEX.captures(id) {
+        let datastore = &caps[1];
+        let namespace = &caps[2];
+
+        return format!("{what} on Datastore {datastore} Namespace  {namespace}",);
+    }
+
+    format!("{what} on Datastore {id}")
+}
+
+proxmox_schema::const_regex! {
+    TAPE_WORKER_ID_REGEX = r"^(\S+?):(\S+?):(\S+?)(:(.+))?$";
+}
+
+fn render_tape_backup_id(id: &str, what: &str) -> String {
+    if let Some(caps) = TAPE_WORKER_ID_REGEX.captures(id) {
+        let datastore = &caps[1];
+        let pool = &caps[2];
+        let drive = &caps[3];
+
+        return format!("{what} {datastore} (pool {pool}, drive {drive})");
+    }
+
+    format!("{what} {id}")
+}
+
+proxmox_schema::const_regex! {
+    DRIVE_LOAD_WORKER_ID_REGEX = r"^(\S+?):(\S+?)$";
+}
+
+fn render_drive_load_media_id(id: &str, what: &str) -> String {
+    if let Some(caps) = DRIVE_LOAD_WORKER_ID_REGEX.captures(id) {
+        let drive = &caps[1];
+        let label = &caps[2];
+        return format!("{} {drive} - {what} '{label}'", tr!("Drive"));
+    }
+
+    format!("{what} {id}")
+}
+
 /// Format a UPID that is either [`RemoteUpid`] or a [`UPID`]
 /// If it's a [`RemoteUpid`], prefixes it with the remote name
 pub fn format_optional_remote_upid(upid: &str, include_remote: bool) -> String {
-- 
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] only message in thread

only message in thread, other threads:[~2025-12-17 14:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-17 14:39 [pdm-devel] [PATCH datacenter-manager] ui: add task descriptions for PBS tasks Lukas Wagner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal