[pbs-devel] [PATCH proxmox-backup 2/9] api2/tape: add api call to list media sets

Dominik Csapak d.csapak at proxmox.com
Wed May 26 15:48:04 CEST 2021


we want a 'media-set' selector in the gui, this makes it
very easy to do and is not as costly as reusing the media list,
since we do not need to iterate over all media (e.g. unassigned)

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
 src/api2/tape/media.rs       | 75 ++++++++++++++++++++++++++++++++++++
 src/api2/types/tape/media.rs | 20 ++++++++++
 2 files changed, 95 insertions(+)

diff --git a/src/api2/tape/media.rs b/src/api2/tape/media.rs
index 683c74b8..8351b2be 100644
--- a/src/api2/tape/media.rs
+++ b/src/api2/tape/media.rs
@@ -1,4 +1,5 @@
 use std::path::Path;
+use std::collections::HashSet;
 
 use anyhow::{bail, format_err, Error};
 use serde::{Serialize, Deserialize};
@@ -28,6 +29,7 @@ use crate::{
         CHANGER_NAME_SCHEMA,
         MediaPoolConfig,
         MediaListEntry,
+        MediaSetListEntry,
         MediaStatus,
         MediaContentEntry,
         VAULT_NAME_SCHEMA,
@@ -44,6 +46,74 @@ use crate::{
     },
 };
 
+#[api(
+    returns: {
+        description: "List of media sets.",
+        type: Array,
+        items: {
+            type: MediaSetListEntry,
+        },
+    },
+    access: {
+        description: "List of media sets filtered by Tape.Audit privileges on pool",
+        permission: &Permission::Anybody,
+    },
+)]
+/// List Media sets
+pub async fn list_media_sets(
+    rpcenv: &mut dyn RpcEnvironment,
+) -> Result<Vec<MediaSetListEntry>, Error> {
+    let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+    let user_info = CachedUserInfo::new()?;
+
+    let (config, _digest) = config::media_pool::config()?;
+
+    let status_path = Path::new(TAPE_STATUS_DIR);
+
+    let mut media_sets: HashSet<Uuid> = HashSet::new();
+    let mut list = Vec::new();
+
+    for (_section_type, data) in config.sections.values() {
+        let pool_name = match data["name"].as_str() {
+            None => continue,
+            Some(name) => name,
+        };
+
+        let privs = user_info.lookup_privs(&auth_id, &["tape", "pool", pool_name]);
+        if (privs & PRIV_TAPE_AUDIT) == 0  {
+            continue;
+        }
+
+        let config: MediaPoolConfig = config.lookup("pool", pool_name)?;
+
+        let changer_name = None; // assume standalone drive
+        let pool = MediaPool::with_config(status_path, &config, changer_name, true)?;
+
+        for media in pool.list_media() {
+            if let Some(label) = media.media_set_label() {
+                if media_sets.contains(&label.uuid) {
+                    continue;
+                }
+
+                let media_set_uuid = label.uuid.clone();
+                let media_set_ctime = label.ctime;
+                let media_set_name = pool
+                    .generate_media_set_name(&media_set_uuid, config.template.clone())
+                    .unwrap_or_else(|_| media_set_uuid.to_string());
+
+                media_sets.insert(media_set_uuid.clone());
+                list.push(MediaSetListEntry {
+                    media_set_name,
+                    media_set_uuid,
+                    media_set_ctime,
+                    pool: pool_name.to_string(),
+                });
+            }
+        }
+    }
+
+    Ok(list)
+}
 #[api(
     input: {
         properties: {
@@ -546,6 +616,11 @@ const SUBDIRS: SubdirMap = &[
             .get(&API_METHOD_DESTROY_MEDIA)
     ),
     ( "list", &MEDIA_LIST_ROUTER ),
+    (
+        "media-sets",
+        &Router::new()
+        .get(&API_METHOD_LIST_MEDIA_SETS)
+    ),
     (
         "move",
         &Router::new()
diff --git a/src/api2/types/tape/media.rs b/src/api2/types/tape/media.rs
index 554efa7a..b53ce28b 100644
--- a/src/api2/types/tape/media.rs
+++ b/src/api2/types/tape/media.rs
@@ -12,6 +12,26 @@ use crate::api2::types::{
     MediaLocation,
 };
 
+#[api(
+    properties: {
+        "media-set-uuid": {
+            schema: MEDIA_SET_UUID_SCHEMA,
+        },
+    },
+)]
+#[derive(Serialize,Deserialize)]
+#[serde(rename_all = "kebab-case")]
+/// Media Set list entry
+pub struct MediaSetListEntry {
+    /// Media set name
+    pub media_set_name: String,
+    pub media_set_uuid: Uuid,
+    /// MediaSet creation time stamp
+    pub media_set_ctime: i64,
+    /// Media Pool
+    pub pool: String,
+}
+
 #[api(
     properties: {
         location: {
-- 
2.20.1






More information about the pbs-devel mailing list