From 9700d5374af3db53a1f7a54e9d8e8dbe0db51647 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 10 Dec 2020 11:08:29 +0100 Subject: [PATCH] tape: add media pool cli --- src/api2/config/media_pool.rs | 12 +-- src/api2/types/tape/media_pool.rs | 2 +- src/bin/proxmox-tape.rs | 1 + src/bin/proxmox_tape/mod.rs | 3 + src/bin/proxmox_tape/pool.rs | 137 ++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 src/bin/proxmox_tape/pool.rs diff --git a/src/api2/config/media_pool.rs b/src/api2/config/media_pool.rs index 65cb4687..86a42157 100644 --- a/src/api2/config/media_pool.rs +++ b/src/api2/config/media_pool.rs @@ -51,7 +51,7 @@ use crate::{ }, )] /// Create a new media pool -fn create_pool( +pub fn create_pool( name: String, drive: String, allocation: Option, @@ -95,7 +95,7 @@ fn create_pool( }, )] /// List media pools -fn list_pools( +pub fn list_pools( mut rpcenv: &mut dyn RpcEnvironment, ) -> Result, Error> { @@ -121,7 +121,7 @@ fn list_pools( }, )] /// Get media pool configuration -fn get_config(name: String) -> Result { +pub fn get_config(name: String) -> Result { let (config, _digest) = config::media_pool::config()?; @@ -134,7 +134,7 @@ fn get_config(name: String) -> Result { #[derive(Serialize, Deserialize)] #[allow(non_camel_case_types)] /// Deletable property name -enum DeletableProperty { +pub enum DeletableProperty { /// Delete media set allocation policy. allocation, /// Delete pool retention policy @@ -177,7 +177,7 @@ enum DeletableProperty { }, )] /// Update media pool settings -fn update_pool( +pub fn update_pool( name: String, drive: Option, allocation: Option, @@ -224,7 +224,7 @@ fn update_pool( }, )] /// Delete a media pool configuration -fn delete_pool(name: String) -> Result<(), Error> { +pub fn delete_pool(name: String) -> Result<(), Error> { let _lock = config::media_pool::lock()?; diff --git a/src/api2/types/tape/media_pool.rs b/src/api2/types/tape/media_pool.rs index da3508d2..f65d5cc1 100644 --- a/src/api2/types/tape/media_pool.rs +++ b/src/api2/types/tape/media_pool.rs @@ -29,7 +29,7 @@ use crate::{ pub const MEDIA_POOL_NAME_SCHEMA: Schema = StringSchema::new("Media pool name.") .format(&PROXMOX_SAFE_ID_FORMAT) - .min_length(3) + .min_length(2) .max_length(32) .schema(); diff --git a/src/bin/proxmox-tape.rs b/src/bin/proxmox-tape.rs index 1df64ab4..b0f2cf59 100644 --- a/src/bin/proxmox-tape.rs +++ b/src/bin/proxmox-tape.rs @@ -210,6 +210,7 @@ fn main() { ) .insert("changer", changer_commands()) .insert("drive", drive_commands()) + .insert("pool", pool_commands()) .insert( "load-media", CliCommand::new(&API_METHOD_LOAD_MEDIA) diff --git a/src/bin/proxmox_tape/mod.rs b/src/bin/proxmox_tape/mod.rs index 5d7476c1..4db89d44 100644 --- a/src/bin/proxmox_tape/mod.rs +++ b/src/bin/proxmox_tape/mod.rs @@ -3,3 +3,6 @@ pub use changer::*; mod drive; pub use drive::*; + +mod pool; +pub use pool::*; diff --git a/src/bin/proxmox_tape/pool.rs b/src/bin/proxmox_tape/pool.rs new file mode 100644 index 00000000..23e8e83e --- /dev/null +++ b/src/bin/proxmox_tape/pool.rs @@ -0,0 +1,137 @@ +use anyhow::{Error}; +use serde_json::Value; + +use proxmox::{ + api::{ + api, + cli::*, + RpcEnvironment, + ApiHandler, + }, +}; + +use proxmox_backup::{ + api2::{ + self, + types::{ + MEDIA_POOL_NAME_SCHEMA, + }, + }, + config::{ + drive::{ + complete_drive_name, + }, + media_pool::{ + complete_pool_name, + }, + }, +}; + +pub fn pool_commands() -> CommandLineInterface { + + let cmd_def = CliCommandMap::new() + .insert("list", CliCommand::new(&API_METHOD_LIST_POOLS)) + .insert("config", + CliCommand::new(&API_METHOD_GET_CONFIG) + .arg_param(&["name"]) + .completion_cb("name", complete_pool_name) + ) + .insert( + "remove", + CliCommand::new(&api2::config::media_pool::API_METHOD_DELETE_POOL) + .arg_param(&["name"]) + .completion_cb("name", complete_pool_name) + ) + .insert( + "create", + CliCommand::new(&api2::config::media_pool::API_METHOD_CREATE_POOL) + .arg_param(&["name"]) + .completion_cb("name", complete_pool_name) + .completion_cb("drive", complete_drive_name) + ) + .insert( + "update", + CliCommand::new(&api2::config::media_pool::API_METHOD_UPDATE_POOL) + .arg_param(&["name"]) + .completion_cb("name", complete_pool_name) + .completion_cb("drive", complete_drive_name) + ) + ; + + cmd_def.into() +} + +#[api( + input: { + properties: { + "output-format": { + schema: OUTPUT_FORMAT, + optional: true, + }, + }, + }, +)] +/// List media pool +fn list_pools( + param: Value, + rpcenv: &mut dyn RpcEnvironment, +) -> Result<(), Error> { + + let output_format = get_output_format(¶m); + let info = &api2::config::media_pool::API_METHOD_LIST_POOLS; + let mut data = match info.handler { + ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, + _ => unreachable!(), + }; + + let options = default_table_format_options() + .column(ColumnConfig::new("name")) + .column(ColumnConfig::new("drive")) + .column(ColumnConfig::new("allocation")) + .column(ColumnConfig::new("retention")) + .column(ColumnConfig::new("template")) + ; + + format_and_print_result_full(&mut data, info.returns, &output_format, &options); + + Ok(()) +} + +#[api( + input: { + properties: { + "output-format": { + schema: OUTPUT_FORMAT, + optional: true, + }, + name: { + schema: MEDIA_POOL_NAME_SCHEMA, + }, + }, + }, +)] +/// Get media pool configuration +fn get_config( + param: Value, + rpcenv: &mut dyn RpcEnvironment, +) -> Result<(), Error> { + + let output_format = get_output_format(¶m); + let info = &api2::config::media_pool::API_METHOD_GET_CONFIG; + let mut data = match info.handler { + ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, + _ => unreachable!(), + }; + + let options = default_table_format_options() + .column(ColumnConfig::new("name")) + .column(ColumnConfig::new("drive")) + .column(ColumnConfig::new("allocation")) + .column(ColumnConfig::new("retention")) + .column(ColumnConfig::new("template")) + ; + + format_and_print_result_full(&mut data, info.returns, &output_format, &options); + + Ok(()) +}