]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/bin/sg-tape-cmd.rs
tree-wide: fix needless borrows
[proxmox-backup.git] / src / bin / sg-tape-cmd.rs
index d63f595f3e4ab47476a05a672a4a4e8112f0e1dd..7edfe5c57644e8e652dfcd3c6b8182a82d61c169 100644 (file)
@@ -1,7 +1,5 @@
-/// Tape command implemented using scsi-generic raw commands
-///
-/// SCSI-generic command needs root priviledges, so this binary need
-/// to be setuid root.
+/// Helper to run tape commands as root. Currently only required
+/// to read and set the encryption key.
 ///
 /// This command can use STDIN as tape device handle.
 
@@ -11,68 +9,62 @@ use std::os::unix::io::{AsRawFd, FromRawFd};
 use anyhow::{bail, Error};
 use serde_json::Value;
 
-use proxmox::{
-    api::{
-        api,
-        cli::*,
-        RpcEnvironment,
-    },
+use proxmox_router::{cli::*, RpcEnvironment};
+use proxmox_schema::api;
+use proxmox_uuid::Uuid;
+
+use pbs_api_types::{
+    Fingerprint, LTO_DRIVE_PATH_SCHEMA, DRIVE_NAME_SCHEMA, TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
+    MEDIA_SET_UUID_SCHEMA, LtoTapeDrive,
 };
 
+use pbs_tape::linux_list_drives::{open_lto_tape_device, check_tape_is_lto_tape_device};
+
 use proxmox_backup::{
-    config,
-    backup::Fingerprint,
-    api2::types::{
-        LINUX_DRIVE_PATH_SCHEMA,
-        DRIVE_NAME_SCHEMA,
-        TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
-        LinuxTapeDrive,
-    },
     tape::{
-        TapeDriver,
-        linux_tape::{
-            LinuxTapeHandle,
-            open_linux_tape_device,
-            check_tape_is_linux_tape_device,
+        drive::{
+            TapeDriver,
+            LtoTapeHandle,
+            open_lto_tape_drive,
         },
     },
 };
 
-fn get_tape_handle(param: &Value) -> Result<LinuxTapeHandle, Error> {
+fn get_tape_handle(param: &Value) -> Result<LtoTapeHandle, Error> {
 
     let handle = if let Some(name) = param["drive"].as_str() {
-        let (config, _digest) = config::drive::config()?;
-        let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
+        let (config, _digest) = pbs_config::drive::config()?;
+        let drive: LtoTapeDrive = config.lookup("lto", name)?;
         eprintln!("using device {}", drive.path);
-        drive.open()?
+        open_lto_tape_drive(&drive)?
     } else if let Some(device) = param["device"].as_str() {
         eprintln!("using device {}", device);
-        LinuxTapeHandle::new(open_linux_tape_device(&device)?)
+        LtoTapeHandle::new(open_lto_tape_device(device)?)?
     } else if let Some(true) = param["stdin"].as_bool() {
         eprintln!("using stdin");
         let fd = std::io::stdin().as_raw_fd();
         let file = unsafe { File::from_raw_fd(fd) };
-        check_tape_is_linux_tape_device(&file)?;
-        LinuxTapeHandle::new(file)
-    } else if let Some(name) = std::env::var("PROXMOX_TAPE_DRIVE").ok() {
-        let (config, _digest) = config::drive::config()?;
-        let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
+        check_tape_is_lto_tape_device(&file)?;
+        LtoTapeHandle::new(file)?
+    } else if let Ok(name) = std::env::var("PROXMOX_TAPE_DRIVE") {
+        let (config, _digest) = pbs_config::drive::config()?;
+        let drive: LtoTapeDrive = config.lookup("lto", &name)?;
         eprintln!("using device {}", drive.path);
-        drive.open()?
+        open_lto_tape_drive(&drive)?
     } else {
-        let (config, _digest) = config::drive::config()?;
+        let (config, _digest) = pbs_config::drive::config()?;
 
         let mut drive_names = Vec::new();
         for (name, (section_type, _)) in config.sections.iter() {
-            if section_type != "linux" { continue; }
+            if section_type != "lto" { continue; }
             drive_names.push(name);
         }
 
         if drive_names.len() == 1 {
             let name = drive_names[0];
-            let drive: LinuxTapeDrive = config.lookup("linux", &name)?;
+            let drive: LtoTapeDrive = config.lookup("lto", name)?;
             eprintln!("using device {}", drive.path);
-            drive.open()?
+            open_lto_tape_drive(&drive)?
         } else {
             bail!("no drive/device specified");
         }
@@ -81,111 +73,6 @@ fn get_tape_handle(param: &Value) -> Result<LinuxTapeHandle, Error> {
     Ok(handle)
 }
 
-#[api(
-   input: {
-        properties: {
-            drive: {
-                schema: DRIVE_NAME_SCHEMA,
-                optional: true,
-            },
-            device: {
-                schema: LINUX_DRIVE_PATH_SCHEMA,
-                optional: true,
-            },
-            stdin: {
-                description: "Use standard input as device handle.",
-                type: bool,
-                optional: true,
-            },
-        },
-    },
-)]
-/// Tape/Media Status
-fn status(
-    param: Value,
-) -> Result<(), Error> {
-
-    let result = proxmox::try_block!({
-        let mut handle = get_tape_handle(&param)?;
-        handle.get_drive_and_media_status()
-   }).map_err(|err: Error| err.to_string());
-
-    println!("{}", serde_json::to_string_pretty(&result)?);
-
-    Ok(())
-}
-
-#[api(
-   input: {
-        properties: {
-            drive: {
-                schema: DRIVE_NAME_SCHEMA,
-                optional: true,
-            },
-            device: {
-                schema: LINUX_DRIVE_PATH_SCHEMA,
-                optional: true,
-            },
-            stdin: {
-                description: "Use standard input as device handle.",
-                type: bool,
-                optional: true,
-            },
-        },
-    },
-)]
-/// Read Cartridge Memory (Medium auxiliary memory attributes)
-fn cartridge_memory(
-    param: Value,
-) -> Result<(), Error> {
-
-    let result = proxmox::try_block!({
-        let mut handle = get_tape_handle(&param)?;
-
-        handle.cartridge_memory()
-    }).map_err(|err| err.to_string());
-
-    println!("{}", serde_json::to_string_pretty(&result)?);
-
-    Ok(())
-}
-
-#[api(
-   input: {
-        properties: {
-            drive: {
-                schema: DRIVE_NAME_SCHEMA,
-                optional: true,
-            },
-            device: {
-                schema: LINUX_DRIVE_PATH_SCHEMA,
-                optional: true,
-            },
-            stdin: {
-                description: "Use standard input as device handle.",
-                type: bool,
-                optional: true,
-            },
-        },
-    },
-)]
-/// Read Tape Alert Flags
-fn tape_alert_flags(
-    param: Value,
-) -> Result<(), Error> {
-
-    let result = proxmox::try_block!({
-        let mut handle = get_tape_handle(&param)?;
-
-        let flags = handle.tape_alert_flags()?;
-        Ok(flags.bits())
-    }).map_err(|err: Error| err.to_string());
-
-    println!("{}", serde_json::to_string_pretty(&result)?);
-
-    Ok(())
-}
-
 #[api(
     input: {
         properties: {
@@ -193,12 +80,16 @@ fn tape_alert_flags(
                 schema: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
                 optional: true,
             },
+            uuid: {
+                schema: MEDIA_SET_UUID_SCHEMA,
+                optional: true,
+            },
             drive: {
                 schema: DRIVE_NAME_SCHEMA,
                 optional: true,
             },
             device: {
-                schema: LINUX_DRIVE_PATH_SCHEMA,
+                schema: LTO_DRIVE_PATH_SCHEMA,
                 optional: true,
             },
             stdin: {
@@ -212,48 +103,26 @@ fn tape_alert_flags(
 /// Set or clear encryption key
 fn set_encryption(
     fingerprint: Option<Fingerprint>,
+    uuid: Option<Uuid>,
     param: Value,
 ) -> Result<(), Error> {
 
-    let result = proxmox::try_block!({
+    let result = proxmox_lang::try_block!({
         let mut handle = get_tape_handle(&param)?;
 
-        handle.set_encryption(fingerprint)?;
-        Ok(())
-    }).map_err(|err: Error| err.to_string());
-
-    println!("{}", serde_json::to_string_pretty(&result)?);
-
-    Ok(())
-}
-
-#[api(
-   input: {
-        properties: {
-            drive: {
-                schema: DRIVE_NAME_SCHEMA,
-                optional: true,
-            },
-            device: {
-                schema: LINUX_DRIVE_PATH_SCHEMA,
-                optional: true,
-            },
-            stdin: {
-                description: "Use standard input as device handle.",
-                type: bool,
-                optional: true,
-            },
-        },
-    },
-)]
-/// Read volume statistics
-fn volume_statistics(
-    param: Value,
-) -> Result<(), Error> {
+        match (fingerprint, uuid) {
+            (Some(fingerprint), Some(uuid)) => {
+                handle.set_encryption(Some((fingerprint, uuid)))?;
+            }
+            (Some(_), None) => {
+                bail!("missing media set uuid");
+            }
+            (None, _) => {
+                handle.set_encryption(None)?;
+            }
+        }
 
-    let result = proxmox::try_block!({
-        let mut handle = get_tape_handle(&param)?;
-        handle.volume_statistics()
+        Ok(())
     }).map_err(|err: Error| err.to_string());
 
     println!("{}", serde_json::to_string_pretty(&result)?);
@@ -264,8 +133,8 @@ fn volume_statistics(
 fn main() -> Result<(), Error> {
 
     // check if we are user root or backup
-    let backup_uid = proxmox_backup::backup::backup_user()?.uid;
-    let backup_gid = proxmox_backup::backup::backup_group()?.gid;
+    let backup_uid = pbs_config::backup_user()?.uid;
+    let backup_gid = pbs_config::backup_group()?.gid;
     let running_uid = nix::unistd::Uid::current();
     let running_gid = nix::unistd::Gid::current();
 
@@ -274,32 +143,14 @@ fn main() -> Result<(), Error> {
         bail!("this program needs to be run with setuid root");
     }
 
-    if !running_uid.is_root() {
-        if running_uid != backup_uid || running_gid != backup_gid {
-            bail!(
-                "Not running as backup user or group (got uid {} gid {})",
-                running_uid, running_gid,
-            );
-        }
+    if !running_uid.is_root() && (running_uid != backup_uid || running_gid != backup_gid) {
+        bail!(
+            "Not running as backup user or group (got uid {} gid {})",
+            running_uid, running_gid,
+        );
     }
 
     let cmd_def = CliCommandMap::new()
-        .insert(
-            "status",
-            CliCommand::new(&API_METHOD_STATUS)
-        )
-        .insert(
-            "cartridge-memory",
-            CliCommand::new(&API_METHOD_CARTRIDGE_MEMORY)
-        )
-        .insert(
-            "tape-alert-flags",
-            CliCommand::new(&API_METHOD_TAPE_ALERT_FLAGS)
-        )
-        .insert(
-            "volume-statistics",
-            CliCommand::new(&API_METHOD_VOLUME_STATISTICS)
-        )
         .insert(
             "encryption",
             CliCommand::new(&API_METHOD_SET_ENCRYPTION)