all lists on 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
  2025-12-18  9:52 ` [pdm-devel] superseded: " Lukas Wagner
  0 siblings, 1 reply; 2+ messages 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] 2+ messages in thread

end of thread, other threads:[~2025-12-18  9:51 UTC | newest]

Thread overview: 2+ messages (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
2025-12-18  9:52 ` [pdm-devel] superseded: " Lukas Wagner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal