From 4606f34353aa7ef1d55dbbe4ec8111b8c25f8d07 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 10 Dec 2020 13:20:39 +0100 Subject: [PATCH] tape: implement read-label command --- src/api2/tape/drive.rs | 49 +++++++++++++++++++++++++++++++++++++ src/api2/types/tape/mod.rs | 3 +++ src/bin/proxmox-tape.rs | 50 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/src/api2/tape/drive.rs b/src/api2/tape/drive.rs index 6b398117..cb360364 100644 --- a/src/api2/tape/drive.rs +++ b/src/api2/tape/drive.rs @@ -24,6 +24,7 @@ use crate::{ LinuxTapeDrive, ScsiTapeChanger, TapeDeviceInfo, + MediaLabelInfoFlat, }, tape::{ TAPE_STATUS_DIR, @@ -358,6 +359,54 @@ fn write_media_label( Ok(()) } +#[api( + input: { + properties: { + drive: { + schema: DRIVE_ID_SCHEMA, + }, + }, + }, + returns: { + type: MediaLabelInfoFlat, + }, +)] +/// Read media label +pub fn read_label(drive: String) -> Result { + + let (config, _digest) = config::drive::config()?; + + let mut drive = open_drive(&config, &drive)?; + + let info = drive.read_label()?; + + let info = match info { + Some(info) => { + let mut flat = MediaLabelInfoFlat { + uuid: info.label.uuid.to_string(), + changer_id: info.label.changer_id.clone(), + ctime: info.label.ctime, + media_set_ctime: None, + media_set_uuid: None, + pool: None, + seq_nr: None, + }; + if let Some((set, _)) = info.media_set_label { + flat.pool = Some(set.pool.clone()); + flat.seq_nr = Some(set.seq_nr); + flat.media_set_uuid = Some(set.uuid.to_string()); + flat.media_set_ctime = Some(set.ctime); + } + flat + } + None => { + bail!("Media is empty (no label)."); + } + }; + + Ok(info) +} + #[sortable] pub const SUBDIRS: SubdirMap = &sorted!([ ( diff --git a/src/api2/types/tape/mod.rs b/src/api2/types/tape/mod.rs index 6c3b8770..58abecc6 100644 --- a/src/api2/types/tape/mod.rs +++ b/src/api2/types/tape/mod.rs @@ -11,3 +11,6 @@ pub use media_pool::*; mod media_status; pub use media_status::*; + +mod media; +pub use media::*; diff --git a/src/bin/proxmox-tape.rs b/src/bin/proxmox-tape.rs index a16b06ac..a038680a 100644 --- a/src/bin/proxmox-tape.rs +++ b/src/bin/proxmox-tape.rs @@ -12,6 +12,7 @@ use proxmox::{ }; use proxmox_backup::{ + tools::format::render_epoch, api2::{ self, types::{ @@ -229,6 +230,50 @@ fn label_media( Ok(()) } +#[api( + input: { + properties: { + drive: { + schema: DRIVE_ID_SCHEMA, + optional: true, + }, + "output-format": { + schema: OUTPUT_FORMAT, + optional: true, + }, + }, + }, +)] +/// Read media label +fn read_label( + mut param: Value, + rpcenv: &mut dyn RpcEnvironment, +) -> Result<(), Error> { + let (config, _digest) = config::drive::config()?; + + param["drive"] = lookup_drive_name(¶m, &config)?.into(); + + let output_format = get_output_format(¶m); + let info = &api2::tape::drive::API_METHOD_READ_LABEL; + let mut data = match info.handler { + ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, + _ => unreachable!(), + }; + + let options = default_table_format_options() + .column(ColumnConfig::new("changer-id")) + .column(ColumnConfig::new("uuid")) + .column(ColumnConfig::new("ctime").renderer(render_epoch)) + .column(ColumnConfig::new("pool")) + .column(ColumnConfig::new("media-set-uuid")) + .column(ColumnConfig::new("media-set-ctime").renderer(render_epoch)) + ; + + format_and_print_result_full(&mut data, info.returns, &output_format, &options); + + Ok(()) + +} fn main() { let cmd_def = CliCommandMap::new() @@ -247,6 +292,11 @@ fn main() { CliCommand::new(&API_METHOD_EJECT_MEDIA) .completion_cb("drive", complete_drive_name) ) + .insert( + "read-label", + CliCommand::new(&API_METHOD_READ_LABEL) + .completion_cb("drive", complete_drive_name) + ) .insert( "label", CliCommand::new(&API_METHOD_LABEL_MEDIA)