cli: tape: rust format
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
5525ec246f
commit
938a1f137c
|
@ -4,48 +4,34 @@ use anyhow::{bail, format_err, Error};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
use proxmox_io::ReadExt;
|
use proxmox_io::ReadExt;
|
||||||
use proxmox_router::RpcEnvironment;
|
|
||||||
use proxmox_router::cli::*;
|
use proxmox_router::cli::*;
|
||||||
|
use proxmox_router::RpcEnvironment;
|
||||||
use proxmox_schema::api;
|
use proxmox_schema::api;
|
||||||
use proxmox_section_config::SectionConfigData;
|
use proxmox_section_config::SectionConfigData;
|
||||||
use proxmox_time::strftime_local;
|
use proxmox_time::strftime_local;
|
||||||
|
|
||||||
use pbs_client::view_task_result;
|
use pbs_client::view_task_result;
|
||||||
use pbs_tools::format::{
|
use pbs_tools::format::{render_bytes_human_readable, render_epoch};
|
||||||
render_epoch,
|
|
||||||
render_bytes_human_readable,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
use pbs_config::datastore::complete_datastore_name;
|
||||||
use pbs_config::drive::complete_drive_name;
|
use pbs_config::drive::complete_drive_name;
|
||||||
use pbs_config::media_pool::complete_pool_name;
|
use pbs_config::media_pool::complete_pool_name;
|
||||||
use pbs_config::datastore::complete_datastore_name;
|
|
||||||
|
|
||||||
use pbs_api_types::{
|
use pbs_api_types::{
|
||||||
Userid, Authid, DATASTORE_SCHEMA, DATASTORE_MAP_LIST_SCHEMA,
|
Authid, GroupListItem, HumanByte, Userid, DATASTORE_MAP_LIST_SCHEMA, DATASTORE_SCHEMA,
|
||||||
DRIVE_NAME_SCHEMA, MEDIA_LABEL_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
|
DRIVE_NAME_SCHEMA, GROUP_FILTER_LIST_SCHEMA, MEDIA_LABEL_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
|
||||||
TAPE_RESTORE_SNAPSHOT_SCHEMA, GROUP_FILTER_LIST_SCHEMA, GroupListItem,
|
TAPE_RESTORE_SNAPSHOT_SCHEMA,
|
||||||
HumanByte
|
|
||||||
};
|
|
||||||
use pbs_tape::{
|
|
||||||
PROXMOX_BACKUP_CONTENT_HEADER_MAGIC_1_0, BlockReadError, MediaContentHeader,
|
|
||||||
};
|
};
|
||||||
|
use pbs_tape::{BlockReadError, MediaContentHeader, PROXMOX_BACKUP_CONTENT_HEADER_MAGIC_1_0};
|
||||||
|
|
||||||
use proxmox_backup::{
|
use proxmox_backup::{
|
||||||
api2,
|
api2,
|
||||||
tape::{
|
|
||||||
drive::{
|
|
||||||
open_drive,
|
|
||||||
lock_tape_device,
|
|
||||||
set_tape_device_state,
|
|
||||||
},
|
|
||||||
complete_media_label_text,
|
|
||||||
complete_media_set_uuid,
|
|
||||||
complete_media_set_snapshots,
|
|
||||||
file_formats::{
|
|
||||||
proxmox_tape_magic_to_text,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
client_helpers::connect_to_localhost,
|
client_helpers::connect_to_localhost,
|
||||||
|
tape::{
|
||||||
|
complete_media_label_text, complete_media_set_snapshots, complete_media_set_uuid,
|
||||||
|
drive::{lock_tape_device, open_drive, set_tape_device_state},
|
||||||
|
file_formats::proxmox_tape_magic_to_text,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod proxmox_tape;
|
mod proxmox_tape;
|
||||||
|
@ -58,14 +44,15 @@ async fn get_backup_groups(store: &str) -> Result<Vec<GroupListItem>, Error> {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
match api_res.get("data") {
|
match api_res.get("data") {
|
||||||
Some(data) => Ok(serde_json::from_value::<Vec<GroupListItem>>(data.to_owned())?),
|
Some(data) => Ok(serde_json::from_value::<Vec<GroupListItem>>(
|
||||||
|
data.to_owned(),
|
||||||
|
)?),
|
||||||
None => bail!("could not get group list"),
|
None => bail!("could not get group list"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// shell completion helper
|
// shell completion helper
|
||||||
pub fn complete_datastore_group_filter(_arg: &str, param: &HashMap<String, String>) -> Vec<String> {
|
pub fn complete_datastore_group_filter(_arg: &str, param: &HashMap<String, String>) -> Vec<String> {
|
||||||
|
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
|
|
||||||
list.push("regex:".to_string());
|
list.push("regex:".to_string());
|
||||||
|
@ -73,33 +60,32 @@ pub fn complete_datastore_group_filter(_arg: &str, param: &HashMap<String, Strin
|
||||||
list.push("type:host".to_string());
|
list.push("type:host".to_string());
|
||||||
list.push("type:vm".to_string());
|
list.push("type:vm".to_string());
|
||||||
|
|
||||||
if let Some(store) = param.get("store") {
|
if let Some(store) = param.get("store") {
|
||||||
let groups = proxmox_async::runtime::block_on(async { get_backup_groups(store).await });
|
let groups = proxmox_async::runtime::block_on(async { get_backup_groups(store).await });
|
||||||
if let Ok(groups) = groups {
|
if let Ok(groups) = groups {
|
||||||
list.extend(groups.iter().map(|group| format!("group:{}/{}", group.backup_type, group.backup_id)));
|
list.extend(
|
||||||
|
groups
|
||||||
|
.iter()
|
||||||
|
.map(|group| format!("group:{}/{}", group.backup_type, group.backup_id)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list
|
list
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_drive_name(
|
pub fn extract_drive_name(param: &mut Value, config: &SectionConfigData) -> Result<String, Error> {
|
||||||
param: &mut Value,
|
|
||||||
config: &SectionConfigData,
|
|
||||||
) -> Result<String, Error> {
|
|
||||||
|
|
||||||
let drive = param["drive"]
|
let drive = param["drive"]
|
||||||
.as_str()
|
.as_str()
|
||||||
.map(String::from)
|
.map(String::from)
|
||||||
.or_else(|| std::env::var("PROXMOX_TAPE_DRIVE").ok())
|
.or_else(|| std::env::var("PROXMOX_TAPE_DRIVE").ok())
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
|
|
||||||
let mut drive_names = Vec::new();
|
let mut drive_names = Vec::new();
|
||||||
|
|
||||||
for (name, (section_type, _)) in config.sections.iter() {
|
for (name, (section_type, _)) in config.sections.iter() {
|
||||||
|
if section_type == "linux" || section_type == "virtual" {
|
||||||
if !(section_type == "linux" || section_type == "virtual") { continue; }
|
drive_names.push(name);
|
||||||
drive_names.push(name);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if drive_names.len() == 1 {
|
if drive_names.len() == 1 {
|
||||||
|
@ -139,7 +125,6 @@ pub fn extract_drive_name(
|
||||||
)]
|
)]
|
||||||
/// Format media
|
/// Format media
|
||||||
async fn format_media(mut param: Value) -> Result<(), Error> {
|
async fn format_media(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -172,7 +157,6 @@ async fn format_media(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Rewind tape
|
/// Rewind tape
|
||||||
async fn rewind(mut param: Value) -> Result<(), Error> {
|
async fn rewind(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -205,7 +189,6 @@ async fn rewind(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Eject/Unload drive media
|
/// Eject/Unload drive media
|
||||||
async fn eject_media(mut param: Value) -> Result<(), Error> {
|
async fn eject_media(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -241,7 +224,6 @@ async fn eject_media(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Load media with specified label
|
/// Load media with specified label
|
||||||
async fn load_media(mut param: Value) -> Result<(), Error> {
|
async fn load_media(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -273,7 +255,6 @@ async fn load_media(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Export media with specified label
|
/// Export media with specified label
|
||||||
async fn export_media(mut param: Value) -> Result<(), Error> {
|
async fn export_media(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
|
||||||
let drive = extract_drive_name(&mut param, &config)?;
|
let drive = extract_drive_name(&mut param, &config)?;
|
||||||
|
@ -303,7 +284,6 @@ async fn export_media(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Load media from the specified slot
|
/// Load media from the specified slot
|
||||||
async fn load_media_from_slot(mut param: Value) -> Result<(), Error> {
|
async fn load_media_from_slot(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
|
||||||
let drive = extract_drive_name(&mut param, &config)?;
|
let drive = extract_drive_name(&mut param, &config)?;
|
||||||
|
@ -338,7 +318,6 @@ async fn load_media_from_slot(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Unload media via changer
|
/// Unload media via changer
|
||||||
async fn unload_media(mut param: Value) -> Result<(), Error> {
|
async fn unload_media(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -378,7 +357,6 @@ async fn unload_media(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Label media
|
/// Label media
|
||||||
async fn label_media(mut param: Value) -> Result<(), Error> {
|
async fn label_media(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -416,7 +394,6 @@ async fn label_media(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Read media label
|
/// Read media label
|
||||||
async fn read_label(mut param: Value) -> Result<(), Error> {
|
async fn read_label(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -438,8 +415,7 @@ async fn read_label(mut param: Value) -> Result<(), Error> {
|
||||||
.column(ColumnConfig::new("pool"))
|
.column(ColumnConfig::new("pool"))
|
||||||
.column(ColumnConfig::new("media-set-uuid"))
|
.column(ColumnConfig::new("media-set-uuid"))
|
||||||
.column(ColumnConfig::new("media-set-ctime").renderer(render_epoch))
|
.column(ColumnConfig::new("media-set-ctime").renderer(render_epoch))
|
||||||
.column(ColumnConfig::new("encryption-key-fingerprint"))
|
.column(ColumnConfig::new("encryption-key-fingerprint"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -476,7 +452,6 @@ async fn inventory(
|
||||||
read_all_labels: Option<bool>,
|
read_all_labels: Option<bool>,
|
||||||
mut param: Value,
|
mut param: Value,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -489,7 +464,6 @@ async fn inventory(
|
||||||
let path = format!("api2/json/tape/drive/{}/inventory", drive);
|
let path = format!("api2/json/tape/drive/{}/inventory", drive);
|
||||||
|
|
||||||
if do_read {
|
if do_read {
|
||||||
|
|
||||||
let mut param = json!({});
|
let mut param = json!({});
|
||||||
if let Some(true) = read_all_labels {
|
if let Some(true) = read_all_labels {
|
||||||
param["read-all-labels"] = true.into();
|
param["read-all-labels"] = true.into();
|
||||||
|
@ -506,8 +480,7 @@ async fn inventory(
|
||||||
|
|
||||||
let options = default_table_format_options()
|
let options = default_table_format_options()
|
||||||
.column(ColumnConfig::new("label-text"))
|
.column(ColumnConfig::new("label-text"))
|
||||||
.column(ColumnConfig::new("uuid"))
|
.column(ColumnConfig::new("uuid"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -534,7 +507,6 @@ async fn inventory(
|
||||||
)]
|
)]
|
||||||
/// Label media with barcodes from changer device
|
/// Label media with barcodes from changer device
|
||||||
async fn barcode_label_media(mut param: Value) -> Result<(), Error> {
|
async fn barcode_label_media(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -563,7 +535,6 @@ async fn barcode_label_media(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Move to end of media (MTEOM, used to debug)
|
/// Move to end of media (MTEOM, used to debug)
|
||||||
fn move_to_eom(mut param: Value) -> Result<(), Error> {
|
fn move_to_eom(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
|
||||||
let drive = extract_drive_name(&mut param, &config)?;
|
let drive = extract_drive_name(&mut param, &config)?;
|
||||||
|
@ -593,7 +564,6 @@ fn move_to_eom(mut param: Value) -> Result<(), Error> {
|
||||||
/// Note: This reads unless the driver returns an IO Error, so this
|
/// Note: This reads unless the driver returns an IO Error, so this
|
||||||
/// method is expected to fails when we reach EOT.
|
/// method is expected to fails when we reach EOT.
|
||||||
fn debug_scan(mut param: Value) -> Result<(), Error> {
|
fn debug_scan(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
|
||||||
let drive = extract_drive_name(&mut param, &config)?;
|
let drive = extract_drive_name(&mut param, &config)?;
|
||||||
|
@ -628,8 +598,12 @@ fn debug_scan(mut param: Value) -> Result<(), Error> {
|
||||||
match header {
|
match header {
|
||||||
Ok(header) => {
|
Ok(header) => {
|
||||||
if header.magic != PROXMOX_BACKUP_CONTENT_HEADER_MAGIC_1_0 {
|
if header.magic != PROXMOX_BACKUP_CONTENT_HEADER_MAGIC_1_0 {
|
||||||
println!("got MediaContentHeader with wrong magic: {:?}", header.magic);
|
println!(
|
||||||
} else if let Some(name) = proxmox_tape_magic_to_text(&header.content_magic) {
|
"got MediaContentHeader with wrong magic: {:?}",
|
||||||
|
header.magic
|
||||||
|
);
|
||||||
|
} else if let Some(name) = proxmox_tape_magic_to_text(&header.content_magic)
|
||||||
|
{
|
||||||
println!("got content header: {}", name);
|
println!("got content header: {}", name);
|
||||||
println!(" uuid: {}", header.content_uuid());
|
println!(" uuid: {}", header.content_uuid());
|
||||||
println!(" ctime: {}", strftime_local("%c", header.ctime)?);
|
println!(" ctime: {}", strftime_local("%c", header.ctime)?);
|
||||||
|
@ -673,7 +647,6 @@ fn debug_scan(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Read Cartridge Memory (Medium auxiliary memory attributes)
|
/// Read Cartridge Memory (Medium auxiliary memory attributes)
|
||||||
async fn cartridge_memory(mut param: Value) -> Result<(), Error> {
|
async fn cartridge_memory(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -691,8 +664,7 @@ async fn cartridge_memory(mut param: Value) -> Result<(), Error> {
|
||||||
let options = default_table_format_options()
|
let options = default_table_format_options()
|
||||||
.column(ColumnConfig::new("id"))
|
.column(ColumnConfig::new("id"))
|
||||||
.column(ColumnConfig::new("name"))
|
.column(ColumnConfig::new("name"))
|
||||||
.column(ColumnConfig::new("value"))
|
.column(ColumnConfig::new("value"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -714,7 +686,6 @@ async fn cartridge_memory(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Read Volume Statistics (SCSI log page 17h)
|
/// Read Volume Statistics (SCSI log page 17h)
|
||||||
async fn volume_statistics(mut param: Value) -> Result<(), Error> {
|
async fn volume_statistics(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -752,7 +723,6 @@ async fn volume_statistics(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Get drive/media status
|
/// Get drive/media status
|
||||||
async fn status(mut param: Value) -> Result<(), Error> {
|
async fn status(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -769,7 +739,7 @@ async fn status(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let render_percentage = |value: &Value, _record: &Value| {
|
let render_percentage = |value: &Value, _record: &Value| {
|
||||||
match value.as_f64() {
|
match value.as_f64() {
|
||||||
Some(wearout) => Ok(format!("{:.2}%", wearout*100.0)),
|
Some(wearout) => Ok(format!("{:.2}%", wearout * 100.0)),
|
||||||
None => Ok(String::from("ERROR")), // should never happen
|
None => Ok(String::from("ERROR")), // should never happen
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -788,8 +758,7 @@ async fn status(mut param: Value) -> Result<(), Error> {
|
||||||
.column(ColumnConfig::new("bytes-read").renderer(render_bytes_human_readable))
|
.column(ColumnConfig::new("bytes-read").renderer(render_bytes_human_readable))
|
||||||
.column(ColumnConfig::new("medium-passes"))
|
.column(ColumnConfig::new("medium-passes"))
|
||||||
.column(ColumnConfig::new("medium-wearout").renderer(render_percentage))
|
.column(ColumnConfig::new("medium-wearout").renderer(render_percentage))
|
||||||
.column(ColumnConfig::new("volume-mounts"))
|
.column(ColumnConfig::new("volume-mounts"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -812,7 +781,6 @@ async fn status(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Clean drive
|
/// Clean drive
|
||||||
async fn clean_drive(mut param: Value) -> Result<(), Error> {
|
async fn clean_drive(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -887,7 +855,6 @@ async fn clean_drive(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Backup datastore to tape media pool
|
/// Backup datastore to tape media pool
|
||||||
async fn backup(mut param: Value) -> Result<(), Error> {
|
async fn backup(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -942,7 +909,6 @@ async fn backup(mut param: Value) -> Result<(), Error> {
|
||||||
)]
|
)]
|
||||||
/// Restore data from media-set
|
/// Restore data from media-set
|
||||||
async fn restore(mut param: Value) -> Result<(), Error> {
|
async fn restore(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -988,8 +954,7 @@ async fn restore(mut param: Value) -> Result<(), Error> {
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Scan media and record content
|
/// Scan media and record content
|
||||||
async fn catalog_media(mut param: Value) -> Result<(), Error> {
|
async fn catalog_media(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = extract_output_format(&mut param);
|
let output_format = extract_output_format(&mut param);
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
@ -1007,7 +972,6 @@ async fn catalog_media(mut param: Value) -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
let cmd_def = CliCommandMap::new()
|
let cmd_def = CliCommandMap::new()
|
||||||
.insert(
|
.insert(
|
||||||
"backup",
|
"backup",
|
||||||
|
@ -1016,7 +980,7 @@ fn main() {
|
||||||
.completion_cb("drive", complete_drive_name)
|
.completion_cb("drive", complete_drive_name)
|
||||||
.completion_cb("store", complete_datastore_name)
|
.completion_cb("store", complete_datastore_name)
|
||||||
.completion_cb("pool", complete_pool_name)
|
.completion_cb("pool", complete_pool_name)
|
||||||
.completion_cb("groups", complete_datastore_group_filter)
|
.completion_cb("groups", complete_datastore_group_filter),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"restore",
|
"restore",
|
||||||
|
@ -1024,80 +988,69 @@ fn main() {
|
||||||
.arg_param(&["media-set", "store", "snapshots"])
|
.arg_param(&["media-set", "store", "snapshots"])
|
||||||
.completion_cb("store", complete_datastore_name)
|
.completion_cb("store", complete_datastore_name)
|
||||||
.completion_cb("media-set", complete_media_set_uuid)
|
.completion_cb("media-set", complete_media_set_uuid)
|
||||||
.completion_cb("snapshots", complete_media_set_snapshots)
|
.completion_cb("snapshots", complete_media_set_snapshots),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"barcode-label",
|
"barcode-label",
|
||||||
CliCommand::new(&API_METHOD_BARCODE_LABEL_MEDIA)
|
CliCommand::new(&API_METHOD_BARCODE_LABEL_MEDIA)
|
||||||
.completion_cb("drive", complete_drive_name)
|
.completion_cb("drive", complete_drive_name)
|
||||||
.completion_cb("pool", complete_pool_name)
|
.completion_cb("pool", complete_pool_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"rewind",
|
"rewind",
|
||||||
CliCommand::new(&API_METHOD_REWIND)
|
CliCommand::new(&API_METHOD_REWIND).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"scan",
|
"scan",
|
||||||
CliCommand::new(&API_METHOD_DEBUG_SCAN)
|
CliCommand::new(&API_METHOD_DEBUG_SCAN).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"status",
|
"status",
|
||||||
CliCommand::new(&API_METHOD_STATUS)
|
CliCommand::new(&API_METHOD_STATUS).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"eod",
|
"eod",
|
||||||
CliCommand::new(&API_METHOD_MOVE_TO_EOM)
|
CliCommand::new(&API_METHOD_MOVE_TO_EOM).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"format",
|
"format",
|
||||||
CliCommand::new(&API_METHOD_FORMAT_MEDIA)
|
CliCommand::new(&API_METHOD_FORMAT_MEDIA).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"eject",
|
"eject",
|
||||||
CliCommand::new(&API_METHOD_EJECT_MEDIA)
|
CliCommand::new(&API_METHOD_EJECT_MEDIA).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"inventory",
|
"inventory",
|
||||||
CliCommand::new(&API_METHOD_INVENTORY)
|
CliCommand::new(&API_METHOD_INVENTORY).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"read-label",
|
"read-label",
|
||||||
CliCommand::new(&API_METHOD_READ_LABEL)
|
CliCommand::new(&API_METHOD_READ_LABEL).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"catalog",
|
"catalog",
|
||||||
CliCommand::new(&API_METHOD_CATALOG_MEDIA)
|
CliCommand::new(&API_METHOD_CATALOG_MEDIA).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"cartridge-memory",
|
"cartridge-memory",
|
||||||
CliCommand::new(&API_METHOD_CARTRIDGE_MEMORY)
|
CliCommand::new(&API_METHOD_CARTRIDGE_MEMORY)
|
||||||
.completion_cb("drive", complete_drive_name)
|
.completion_cb("drive", complete_drive_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"volume-statistics",
|
"volume-statistics",
|
||||||
CliCommand::new(&API_METHOD_VOLUME_STATISTICS)
|
CliCommand::new(&API_METHOD_VOLUME_STATISTICS)
|
||||||
.completion_cb("drive", complete_drive_name)
|
.completion_cb("drive", complete_drive_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"clean",
|
"clean",
|
||||||
CliCommand::new(&API_METHOD_CLEAN_DRIVE)
|
CliCommand::new(&API_METHOD_CLEAN_DRIVE).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"label",
|
"label",
|
||||||
CliCommand::new(&API_METHOD_LABEL_MEDIA)
|
CliCommand::new(&API_METHOD_LABEL_MEDIA)
|
||||||
.completion_cb("drive", complete_drive_name)
|
.completion_cb("drive", complete_drive_name)
|
||||||
.completion_cb("pool", complete_pool_name)
|
.completion_cb("pool", complete_pool_name),
|
||||||
|
|
||||||
)
|
)
|
||||||
.insert("changer", changer_commands())
|
.insert("changer", changer_commands())
|
||||||
.insert("drive", drive_commands())
|
.insert("drive", drive_commands())
|
||||||
|
@ -1110,27 +1063,25 @@ fn main() {
|
||||||
CliCommand::new(&API_METHOD_LOAD_MEDIA)
|
CliCommand::new(&API_METHOD_LOAD_MEDIA)
|
||||||
.arg_param(&["label-text"])
|
.arg_param(&["label-text"])
|
||||||
.completion_cb("drive", complete_drive_name)
|
.completion_cb("drive", complete_drive_name)
|
||||||
.completion_cb("label-text", complete_media_label_text)
|
.completion_cb("label-text", complete_media_label_text),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"load-media-from-slot",
|
"load-media-from-slot",
|
||||||
CliCommand::new(&API_METHOD_LOAD_MEDIA_FROM_SLOT)
|
CliCommand::new(&API_METHOD_LOAD_MEDIA_FROM_SLOT)
|
||||||
.arg_param(&["source-slot"])
|
.arg_param(&["source-slot"])
|
||||||
.completion_cb("drive", complete_drive_name)
|
.completion_cb("drive", complete_drive_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"unload",
|
"unload",
|
||||||
CliCommand::new(&API_METHOD_UNLOAD_MEDIA)
|
CliCommand::new(&API_METHOD_UNLOAD_MEDIA).completion_cb("drive", complete_drive_name),
|
||||||
.completion_cb("drive", complete_drive_name)
|
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"export-media",
|
"export-media",
|
||||||
CliCommand::new(&API_METHOD_EXPORT_MEDIA)
|
CliCommand::new(&API_METHOD_EXPORT_MEDIA)
|
||||||
.arg_param(&["label-text"])
|
.arg_param(&["label-text"])
|
||||||
.completion_cb("drive", complete_drive_name)
|
.completion_cb("drive", complete_drive_name)
|
||||||
.completion_cb("label-text", complete_media_label_text)
|
.completion_cb("label-text", complete_media_label_text),
|
||||||
)
|
);
|
||||||
;
|
|
||||||
|
|
||||||
let mut rpcenv = CliEnvironment::new();
|
let mut rpcenv = CliEnvironment::new();
|
||||||
rpcenv.set_auth_id(Some(String::from("root@pam")));
|
rpcenv.set_auth_id(Some(String::from("root@pam")));
|
||||||
|
|
|
@ -22,7 +22,6 @@ use proxmox_backup::client_helpers::connect_to_localhost;
|
||||||
)]
|
)]
|
||||||
/// Tape backup job list.
|
/// Tape backup job list.
|
||||||
fn list_tape_backup_jobs(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> {
|
fn list_tape_backup_jobs(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> {
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
|
|
||||||
//let info = &api2::config::tape_backup_job::API_METHOD_LIST_TAPE_BACKUP_JOBS;
|
//let info = &api2::config::tape_backup_job::API_METHOD_LIST_TAPE_BACKUP_JOBS;
|
||||||
|
@ -62,7 +61,6 @@ fn list_tape_backup_jobs(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Resul
|
||||||
)]
|
)]
|
||||||
/// Show tape backup job configuration
|
/// Show tape backup job configuration
|
||||||
fn show_tape_backup_job(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> {
|
fn show_tape_backup_job(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> {
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
|
|
||||||
let info = &api2::config::tape_backup_job::API_METHOD_READ_TAPE_BACKUP_JOB;
|
let info = &api2::config::tape_backup_job::API_METHOD_READ_TAPE_BACKUP_JOB;
|
||||||
|
@ -88,14 +86,15 @@ fn show_tape_backup_job(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result
|
||||||
)]
|
)]
|
||||||
/// Run THape Backup Job
|
/// Run THape Backup Job
|
||||||
async fn run_tape_backup_job(mut param: Value) -> Result<(), Error> {
|
async fn run_tape_backup_job(mut param: Value) -> Result<(), Error> {
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
|
|
||||||
let id = param["id"].take().as_str().unwrap().to_string();
|
let id = param["id"].take().as_str().unwrap().to_string();
|
||||||
|
|
||||||
let client = connect_to_localhost()?;
|
let client = connect_to_localhost()?;
|
||||||
|
|
||||||
let result = client.post(&format!("api2/json/tape/backup/{}", id), Some(param)).await?;
|
let result = client
|
||||||
|
.post(&format!("api2/json/tape/backup/{}", id), Some(param))
|
||||||
|
.await?;
|
||||||
|
|
||||||
view_task_result(&client, result, &output_format).await?;
|
view_task_result(&client, result, &output_format).await?;
|
||||||
|
|
||||||
|
@ -103,41 +102,45 @@ async fn run_tape_backup_job(mut param: Value) -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn backup_job_commands() -> CommandLineInterface {
|
pub fn backup_job_commands() -> CommandLineInterface {
|
||||||
|
|
||||||
let cmd_def = CliCommandMap::new()
|
let cmd_def = CliCommandMap::new()
|
||||||
.insert("list", CliCommand::new(&API_METHOD_LIST_TAPE_BACKUP_JOBS))
|
.insert("list", CliCommand::new(&API_METHOD_LIST_TAPE_BACKUP_JOBS))
|
||||||
.insert("show",
|
.insert(
|
||||||
CliCommand::new(&API_METHOD_SHOW_TAPE_BACKUP_JOB)
|
"show",
|
||||||
|
CliCommand::new(&API_METHOD_SHOW_TAPE_BACKUP_JOB)
|
||||||
.arg_param(&["id"])
|
.arg_param(&["id"])
|
||||||
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id)
|
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id),
|
||||||
)
|
)
|
||||||
.insert("run",
|
.insert(
|
||||||
CliCommand::new(&API_METHOD_RUN_TAPE_BACKUP_JOB)
|
"run",
|
||||||
|
CliCommand::new(&API_METHOD_RUN_TAPE_BACKUP_JOB)
|
||||||
.arg_param(&["id"])
|
.arg_param(&["id"])
|
||||||
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id)
|
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id),
|
||||||
)
|
)
|
||||||
.insert("create",
|
.insert(
|
||||||
CliCommand::new(&api2::config::tape_backup_job::API_METHOD_CREATE_TAPE_BACKUP_JOB)
|
"create",
|
||||||
|
CliCommand::new(&api2::config::tape_backup_job::API_METHOD_CREATE_TAPE_BACKUP_JOB)
|
||||||
.arg_param(&["id"])
|
.arg_param(&["id"])
|
||||||
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id)
|
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id)
|
||||||
.completion_cb("schedule", pbs_config::datastore::complete_calendar_event)
|
.completion_cb("schedule", pbs_config::datastore::complete_calendar_event)
|
||||||
.completion_cb("store", pbs_config::datastore::complete_datastore_name)
|
.completion_cb("store", pbs_config::datastore::complete_datastore_name)
|
||||||
.completion_cb("pool", pbs_config::media_pool::complete_pool_name)
|
.completion_cb("pool", pbs_config::media_pool::complete_pool_name)
|
||||||
.completion_cb("drive", crate::complete_drive_name)
|
.completion_cb("drive", crate::complete_drive_name),
|
||||||
)
|
)
|
||||||
.insert("update",
|
.insert(
|
||||||
CliCommand::new(&api2::config::tape_backup_job::API_METHOD_UPDATE_TAPE_BACKUP_JOB)
|
"update",
|
||||||
|
CliCommand::new(&api2::config::tape_backup_job::API_METHOD_UPDATE_TAPE_BACKUP_JOB)
|
||||||
.arg_param(&["id"])
|
.arg_param(&["id"])
|
||||||
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id)
|
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id)
|
||||||
.completion_cb("schedule", pbs_config::datastore::complete_calendar_event)
|
.completion_cb("schedule", pbs_config::datastore::complete_calendar_event)
|
||||||
.completion_cb("store", pbs_config::datastore::complete_datastore_name)
|
.completion_cb("store", pbs_config::datastore::complete_datastore_name)
|
||||||
.completion_cb("pool", pbs_config::media_pool::complete_pool_name)
|
.completion_cb("pool", pbs_config::media_pool::complete_pool_name)
|
||||||
.completion_cb("drive", crate::complete_drive_name)
|
.completion_cb("drive", crate::complete_drive_name),
|
||||||
)
|
)
|
||||||
.insert("remove",
|
.insert(
|
||||||
CliCommand::new(&api2::config::tape_backup_job::API_METHOD_DELETE_TAPE_BACKUP_JOB)
|
"remove",
|
||||||
|
CliCommand::new(&api2::config::tape_backup_job::API_METHOD_DELETE_TAPE_BACKUP_JOB)
|
||||||
.arg_param(&["id"])
|
.arg_param(&["id"])
|
||||||
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id)
|
.completion_cb("id", pbs_config::tape_job::complete_tape_job_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
cmd_def.into()
|
cmd_def.into()
|
||||||
|
|
|
@ -5,22 +5,15 @@ use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
|
||||||
use proxmox_schema::api;
|
use proxmox_schema::api;
|
||||||
use proxmox_section_config::SectionConfigData;
|
use proxmox_section_config::SectionConfigData;
|
||||||
|
|
||||||
use pbs_config::drive::{
|
use pbs_config::drive::{complete_changer_name, complete_drive_name};
|
||||||
complete_drive_name,
|
|
||||||
complete_changer_name,
|
|
||||||
};
|
|
||||||
|
|
||||||
use pbs_api_types::CHANGER_NAME_SCHEMA;
|
use pbs_api_types::CHANGER_NAME_SCHEMA;
|
||||||
|
|
||||||
use pbs_tape::linux_list_drives::{complete_changer_path};
|
use pbs_tape::linux_list_drives::complete_changer_path;
|
||||||
|
|
||||||
use proxmox_backup::{api2, tape::drive::media_changer};
|
use proxmox_backup::{api2, tape::drive::media_changer};
|
||||||
|
|
||||||
pub fn lookup_changer_name(
|
pub fn lookup_changer_name(param: &Value, config: &SectionConfigData) -> Result<String, Error> {
|
||||||
param: &Value,
|
|
||||||
config: &SectionConfigData,
|
|
||||||
) -> Result<String, Error> {
|
|
||||||
|
|
||||||
if let Some(name) = param["name"].as_str() {
|
if let Some(name) = param["name"].as_str() {
|
||||||
return Ok(String::from(name));
|
return Ok(String::from(name));
|
||||||
}
|
}
|
||||||
|
@ -37,46 +30,47 @@ pub fn lookup_changer_name(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn changer_commands() -> CommandLineInterface {
|
pub fn changer_commands() -> CommandLineInterface {
|
||||||
|
|
||||||
let cmd_def = CliCommandMap::new()
|
let cmd_def = CliCommandMap::new()
|
||||||
.insert("scan", CliCommand::new(&API_METHOD_SCAN_FOR_CHANGERS))
|
.insert("scan", CliCommand::new(&API_METHOD_SCAN_FOR_CHANGERS))
|
||||||
.insert("list", CliCommand::new(&API_METHOD_LIST_CHANGERS))
|
.insert("list", CliCommand::new(&API_METHOD_LIST_CHANGERS))
|
||||||
.insert("config",
|
.insert(
|
||||||
CliCommand::new(&API_METHOD_GET_CONFIG)
|
"config",
|
||||||
|
CliCommand::new(&API_METHOD_GET_CONFIG)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_changer_name)
|
.completion_cb("name", complete_changer_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"remove",
|
"remove",
|
||||||
CliCommand::new(&api2::config::changer::API_METHOD_DELETE_CHANGER)
|
CliCommand::new(&api2::config::changer::API_METHOD_DELETE_CHANGER)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_changer_name)
|
.completion_cb("name", complete_changer_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"create",
|
"create",
|
||||||
CliCommand::new(&api2::config::changer::API_METHOD_CREATE_CHANGER)
|
CliCommand::new(&api2::config::changer::API_METHOD_CREATE_CHANGER)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_drive_name)
|
.completion_cb("name", complete_drive_name)
|
||||||
.completion_cb("path", complete_changer_path)
|
.completion_cb("path", complete_changer_path),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"update",
|
"update",
|
||||||
CliCommand::new(&api2::config::changer::API_METHOD_UPDATE_CHANGER)
|
CliCommand::new(&api2::config::changer::API_METHOD_UPDATE_CHANGER)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_changer_name)
|
.completion_cb("name", complete_changer_name)
|
||||||
.completion_cb("path", complete_changer_path)
|
.completion_cb("path", complete_changer_path),
|
||||||
)
|
)
|
||||||
.insert("status",
|
.insert(
|
||||||
CliCommand::new(&API_METHOD_GET_STATUS)
|
"status",
|
||||||
|
CliCommand::new(&API_METHOD_GET_STATUS)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_changer_name)
|
.completion_cb("name", complete_changer_name),
|
||||||
)
|
)
|
||||||
.insert("transfer",
|
.insert(
|
||||||
CliCommand::new(&API_METHOD_TRANSFER)
|
"transfer",
|
||||||
|
CliCommand::new(&API_METHOD_TRANSFER)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_changer_name)
|
.completion_cb("name", complete_changer_name),
|
||||||
)
|
);
|
||||||
;
|
|
||||||
|
|
||||||
cmd_def.into()
|
cmd_def.into()
|
||||||
}
|
}
|
||||||
|
@ -92,11 +86,7 @@ pub fn changer_commands() -> CommandLineInterface {
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// List changers
|
/// List changers
|
||||||
fn list_changers(
|
fn list_changers(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::tape::changer::API_METHOD_LIST_CHANGERS;
|
let info = &api2::tape::changer::API_METHOD_LIST_CHANGERS;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -109,8 +99,7 @@ fn list_changers(
|
||||||
.column(ColumnConfig::new("path"))
|
.column(ColumnConfig::new("path"))
|
||||||
.column(ColumnConfig::new("vendor"))
|
.column(ColumnConfig::new("vendor"))
|
||||||
.column(ColumnConfig::new("model"))
|
.column(ColumnConfig::new("model"))
|
||||||
.column(ColumnConfig::new("serial"))
|
.column(ColumnConfig::new("serial"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -128,11 +117,7 @@ fn list_changers(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Scan for SCSI tape changers
|
/// Scan for SCSI tape changers
|
||||||
fn scan_for_changers(
|
fn scan_for_changers(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::tape::API_METHOD_SCAN_CHANGERS;
|
let info = &api2::tape::API_METHOD_SCAN_CHANGERS;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -144,8 +129,7 @@ fn scan_for_changers(
|
||||||
.column(ColumnConfig::new("path"))
|
.column(ColumnConfig::new("path"))
|
||||||
.column(ColumnConfig::new("vendor"))
|
.column(ColumnConfig::new("vendor"))
|
||||||
.column(ColumnConfig::new("model"))
|
.column(ColumnConfig::new("model"))
|
||||||
.column(ColumnConfig::new("serial"))
|
.column(ColumnConfig::new("serial"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -166,11 +150,7 @@ fn scan_for_changers(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Get tape changer configuration
|
/// Get tape changer configuration
|
||||||
fn get_config(
|
fn get_config(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::config::changer::API_METHOD_GET_CONFIG;
|
let info = &api2::config::changer::API_METHOD_GET_CONFIG;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -181,8 +161,7 @@ fn get_config(
|
||||||
let options = default_table_format_options()
|
let options = default_table_format_options()
|
||||||
.column(ColumnConfig::new("name"))
|
.column(ColumnConfig::new("name"))
|
||||||
.column(ColumnConfig::new("path"))
|
.column(ColumnConfig::new("path"))
|
||||||
.column(ColumnConfig::new("export-slots"))
|
.column(ColumnConfig::new("export-slots"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -210,11 +189,7 @@ fn get_config(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Get tape changer status
|
/// Get tape changer status
|
||||||
async fn get_status(
|
async fn get_status(mut param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
mut param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
|
||||||
param["name"] = lookup_changer_name(¶m, &config)?.into();
|
param["name"] = lookup_changer_name(¶m, &config)?.into();
|
||||||
|
@ -244,8 +219,7 @@ async fn get_status(
|
||||||
.column(ColumnConfig::new("entry-kind"))
|
.column(ColumnConfig::new("entry-kind"))
|
||||||
.column(ColumnConfig::new("entry-id"))
|
.column(ColumnConfig::new("entry-id"))
|
||||||
.column(ColumnConfig::new("label-text").renderer(render_label_text))
|
.column(ColumnConfig::new("label-text").renderer(render_label_text))
|
||||||
.column(ColumnConfig::new("loaded-slot"))
|
.column(ColumnConfig::new("loaded-slot"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -273,11 +247,7 @@ async fn get_status(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Transfers media from one slot to another
|
/// Transfers media from one slot to another
|
||||||
pub async fn transfer(
|
pub async fn transfer(mut param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
mut param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let (config, _digest) = pbs_config::drive::config()?;
|
let (config, _digest) = pbs_config::drive::config()?;
|
||||||
|
|
||||||
param["name"] = lookup_changer_name(¶m, &config)?.into();
|
param["name"] = lookup_changer_name(¶m, &config)?.into();
|
||||||
|
|
|
@ -6,31 +6,27 @@ use proxmox_schema::api;
|
||||||
|
|
||||||
use pbs_api_types::DRIVE_NAME_SCHEMA;
|
use pbs_api_types::DRIVE_NAME_SCHEMA;
|
||||||
|
|
||||||
use pbs_config::drive::{
|
use pbs_config::drive::{complete_changer_name, complete_drive_name, complete_lto_drive_name};
|
||||||
complete_drive_name,
|
|
||||||
complete_changer_name,
|
|
||||||
complete_lto_drive_name,
|
|
||||||
};
|
|
||||||
|
|
||||||
use pbs_tape::linux_list_drives::{complete_drive_path};
|
use pbs_tape::linux_list_drives::complete_drive_path;
|
||||||
|
|
||||||
use proxmox_backup::api2;
|
use proxmox_backup::api2;
|
||||||
|
|
||||||
pub fn drive_commands() -> CommandLineInterface {
|
pub fn drive_commands() -> CommandLineInterface {
|
||||||
|
|
||||||
let cmd_def = CliCommandMap::new()
|
let cmd_def = CliCommandMap::new()
|
||||||
.insert("scan", CliCommand::new(&API_METHOD_SCAN_FOR_DRIVES))
|
.insert("scan", CliCommand::new(&API_METHOD_SCAN_FOR_DRIVES))
|
||||||
.insert("list", CliCommand::new(&API_METHOD_LIST_DRIVES))
|
.insert("list", CliCommand::new(&API_METHOD_LIST_DRIVES))
|
||||||
.insert("config",
|
.insert(
|
||||||
CliCommand::new(&API_METHOD_GET_CONFIG)
|
"config",
|
||||||
|
CliCommand::new(&API_METHOD_GET_CONFIG)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_lto_drive_name)
|
.completion_cb("name", complete_lto_drive_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"remove",
|
"remove",
|
||||||
CliCommand::new(&api2::config::drive::API_METHOD_DELETE_DRIVE)
|
CliCommand::new(&api2::config::drive::API_METHOD_DELETE_DRIVE)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_lto_drive_name)
|
.completion_cb("name", complete_lto_drive_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"create",
|
"create",
|
||||||
|
@ -38,7 +34,7 @@ pub fn drive_commands() -> CommandLineInterface {
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_drive_name)
|
.completion_cb("name", complete_drive_name)
|
||||||
.completion_cb("path", complete_drive_path)
|
.completion_cb("path", complete_drive_path)
|
||||||
.completion_cb("changer", complete_changer_name)
|
.completion_cb("changer", complete_changer_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"update",
|
"update",
|
||||||
|
@ -46,9 +42,8 @@ pub fn drive_commands() -> CommandLineInterface {
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_lto_drive_name)
|
.completion_cb("name", complete_lto_drive_name)
|
||||||
.completion_cb("path", complete_drive_path)
|
.completion_cb("path", complete_drive_path)
|
||||||
.completion_cb("changer", complete_changer_name)
|
.completion_cb("changer", complete_changer_name),
|
||||||
)
|
);
|
||||||
;
|
|
||||||
|
|
||||||
cmd_def.into()
|
cmd_def.into()
|
||||||
}
|
}
|
||||||
|
@ -64,11 +59,7 @@ pub fn drive_commands() -> CommandLineInterface {
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// List drives
|
/// List drives
|
||||||
fn list_drives(
|
fn list_drives(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::tape::drive::API_METHOD_LIST_DRIVES;
|
let info = &api2::tape::drive::API_METHOD_LIST_DRIVES;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -82,8 +73,7 @@ fn list_drives(
|
||||||
.column(ColumnConfig::new("changer"))
|
.column(ColumnConfig::new("changer"))
|
||||||
.column(ColumnConfig::new("vendor"))
|
.column(ColumnConfig::new("vendor"))
|
||||||
.column(ColumnConfig::new("model"))
|
.column(ColumnConfig::new("model"))
|
||||||
.column(ColumnConfig::new("serial"))
|
.column(ColumnConfig::new("serial"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -101,11 +91,7 @@ fn list_drives(
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
/// Scan for drives
|
/// Scan for drives
|
||||||
fn scan_for_drives(
|
fn scan_for_drives(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::tape::API_METHOD_SCAN_DRIVES;
|
let info = &api2::tape::API_METHOD_SCAN_DRIVES;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -117,15 +103,13 @@ fn scan_for_drives(
|
||||||
.column(ColumnConfig::new("path"))
|
.column(ColumnConfig::new("path"))
|
||||||
.column(ColumnConfig::new("vendor"))
|
.column(ColumnConfig::new("vendor"))
|
||||||
.column(ColumnConfig::new("model"))
|
.column(ColumnConfig::new("model"))
|
||||||
.column(ColumnConfig::new("serial"))
|
.column(ColumnConfig::new("serial"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
input: {
|
input: {
|
||||||
properties: {
|
properties: {
|
||||||
|
@ -140,11 +124,7 @@ fn scan_for_drives(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Get pool configuration
|
/// Get pool configuration
|
||||||
fn get_config(
|
fn get_config(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::config::drive::API_METHOD_GET_CONFIG;
|
let info = &api2::config::drive::API_METHOD_GET_CONFIG;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -156,8 +136,7 @@ fn get_config(
|
||||||
.column(ColumnConfig::new("name"))
|
.column(ColumnConfig::new("name"))
|
||||||
.column(ColumnConfig::new("path"))
|
.column(ColumnConfig::new("path"))
|
||||||
.column(ColumnConfig::new("changer"))
|
.column(ColumnConfig::new("changer"))
|
||||||
.column(ColumnConfig::new("changer-drivenum"))
|
.column(ColumnConfig::new("changer-drivenum"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
|
|
@ -6,53 +6,45 @@ use proxmox_schema::{api, param_bail};
|
||||||
use proxmox_sys::linux::tty;
|
use proxmox_sys::linux::tty;
|
||||||
|
|
||||||
use pbs_api_types::{
|
use pbs_api_types::{
|
||||||
Fingerprint, Kdf, DRIVE_NAME_SCHEMA, TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
|
Fingerprint, Kdf, DRIVE_NAME_SCHEMA, PASSWORD_HINT_SCHEMA,
|
||||||
PASSWORD_HINT_SCHEMA,
|
TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
|
||||||
};
|
};
|
||||||
|
|
||||||
use pbs_datastore::paperkey::{PaperkeyFormat, generate_paper_key};
|
|
||||||
use pbs_config::tape_encryption_keys::{load_key_configs,complete_key_fingerprint};
|
|
||||||
use pbs_config::key_config::KeyConfig;
|
use pbs_config::key_config::KeyConfig;
|
||||||
|
use pbs_config::tape_encryption_keys::{complete_key_fingerprint, load_key_configs};
|
||||||
|
use pbs_datastore::paperkey::{generate_paper_key, PaperkeyFormat};
|
||||||
|
|
||||||
use proxmox_backup::api2;
|
use proxmox_backup::api2;
|
||||||
|
|
||||||
pub fn encryption_key_commands() -> CommandLineInterface {
|
pub fn encryption_key_commands() -> CommandLineInterface {
|
||||||
|
|
||||||
let cmd_def = CliCommandMap::new()
|
let cmd_def = CliCommandMap::new()
|
||||||
.insert("list", CliCommand::new(&API_METHOD_LIST_KEYS))
|
.insert("list", CliCommand::new(&API_METHOD_LIST_KEYS))
|
||||||
.insert(
|
.insert("create", CliCommand::new(&API_METHOD_CREATE_KEY))
|
||||||
"create",
|
|
||||||
CliCommand::new(&API_METHOD_CREATE_KEY)
|
|
||||||
)
|
|
||||||
.insert(
|
.insert(
|
||||||
"change-passphrase",
|
"change-passphrase",
|
||||||
CliCommand::new(&API_METHOD_CHANGE_PASSPHRASE)
|
CliCommand::new(&API_METHOD_CHANGE_PASSPHRASE)
|
||||||
.arg_param(&["fingerprint"])
|
.arg_param(&["fingerprint"])
|
||||||
.completion_cb("fingerprint", complete_key_fingerprint)
|
.completion_cb("fingerprint", complete_key_fingerprint),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"show",
|
"show",
|
||||||
CliCommand::new(&API_METHOD_SHOW_KEY)
|
CliCommand::new(&API_METHOD_SHOW_KEY)
|
||||||
.arg_param(&["fingerprint"])
|
.arg_param(&["fingerprint"])
|
||||||
.completion_cb("fingerprint", complete_key_fingerprint)
|
.completion_cb("fingerprint", complete_key_fingerprint),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"paperkey",
|
"paperkey",
|
||||||
CliCommand::new(&API_METHOD_PAPER_KEY)
|
CliCommand::new(&API_METHOD_PAPER_KEY)
|
||||||
.arg_param(&["fingerprint"])
|
.arg_param(&["fingerprint"])
|
||||||
.completion_cb("fingerprint", complete_key_fingerprint)
|
.completion_cb("fingerprint", complete_key_fingerprint),
|
||||||
)
|
|
||||||
.insert(
|
|
||||||
"restore",
|
|
||||||
CliCommand::new(&API_METHOD_RESTORE_KEY)
|
|
||||||
)
|
)
|
||||||
|
.insert("restore", CliCommand::new(&API_METHOD_RESTORE_KEY))
|
||||||
.insert(
|
.insert(
|
||||||
"remove",
|
"remove",
|
||||||
CliCommand::new(&api2::config::tape_encryption_keys::API_METHOD_DELETE_KEY)
|
CliCommand::new(&api2::config::tape_encryption_keys::API_METHOD_DELETE_KEY)
|
||||||
.arg_param(&["fingerprint"])
|
.arg_param(&["fingerprint"])
|
||||||
.completion_cb("fingerprint", complete_key_fingerprint)
|
.completion_cb("fingerprint", complete_key_fingerprint),
|
||||||
)
|
);
|
||||||
;
|
|
||||||
|
|
||||||
cmd_def.into()
|
cmd_def.into()
|
||||||
}
|
}
|
||||||
|
@ -82,7 +74,6 @@ fn paper_key(
|
||||||
subject: Option<String>,
|
subject: Option<String>,
|
||||||
output_format: Option<PaperkeyFormat>,
|
output_format: Option<PaperkeyFormat>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let (config_map, _digest) = load_key_configs()?;
|
let (config_map, _digest) = load_key_configs()?;
|
||||||
|
|
||||||
let key_config = match config_map.get(&fingerprint) {
|
let key_config = match config_map.get(&fingerprint) {
|
||||||
|
@ -109,11 +100,7 @@ fn paper_key(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Print the encryption key's metadata.
|
/// Print the encryption key's metadata.
|
||||||
fn show_key(
|
fn show_key(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
|
|
||||||
let info = &api2::config::tape_encryption_keys::API_METHOD_READ_KEY;
|
let info = &api2::config::tape_encryption_keys::API_METHOD_READ_KEY;
|
||||||
|
@ -162,7 +149,6 @@ fn change_passphrase(
|
||||||
mut param: Value,
|
mut param: Value,
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
rpcenv: &mut dyn RpcEnvironment,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
if !tty::stdin_isatty() {
|
if !tty::stdin_isatty() {
|
||||||
bail!("unable to change passphrase - no tty");
|
bail!("unable to change passphrase - no tty");
|
||||||
}
|
}
|
||||||
|
@ -288,11 +274,7 @@ async fn restore_key(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Create key (read password from stdin)
|
/// Create key (read password from stdin)
|
||||||
fn create_key(
|
fn create_key(mut param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
mut param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
if !tty::stdin_isatty() {
|
if !tty::stdin_isatty() {
|
||||||
bail!("no password input mechanism available");
|
bail!("no password input mechanism available");
|
||||||
}
|
}
|
||||||
|
@ -312,7 +294,6 @@ fn create_key(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
input: {
|
input: {
|
||||||
properties: {
|
properties: {
|
||||||
|
@ -324,11 +305,7 @@ fn create_key(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// List keys
|
/// List keys
|
||||||
fn list_keys(
|
fn list_keys(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::config::tape_encryption_keys::API_METHOD_LIST_KEYS;
|
let info = &api2::config::tape_encryption_keys::API_METHOD_LIST_KEYS;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -338,8 +315,7 @@ fn list_keys(
|
||||||
|
|
||||||
let options = default_table_format_options()
|
let options = default_table_format_options()
|
||||||
.column(ColumnConfig::new("fingerprint"))
|
.column(ColumnConfig::new("fingerprint"))
|
||||||
.column(ColumnConfig::new("hint"))
|
.column(ColumnConfig::new("hint"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
|
|
@ -1,39 +1,34 @@
|
||||||
use anyhow::{Error};
|
use anyhow::Error;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
|
use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
|
||||||
use proxmox_schema::api;
|
use proxmox_schema::api;
|
||||||
|
|
||||||
use pbs_api_types::{
|
use pbs_api_types::{
|
||||||
MEDIA_POOL_NAME_SCHEMA, CHANGER_NAME_SCHEMA, MediaStatus, MediaListEntry,
|
MediaContentListFilter, MediaListEntry, MediaStatus, CHANGER_NAME_SCHEMA,
|
||||||
MediaContentListFilter,
|
MEDIA_POOL_NAME_SCHEMA,
|
||||||
};
|
};
|
||||||
use pbs_config::drive::complete_changer_name;
|
use pbs_config::drive::complete_changer_name;
|
||||||
use pbs_config::media_pool::complete_pool_name;
|
use pbs_config::media_pool::complete_pool_name;
|
||||||
|
|
||||||
use proxmox_backup::{
|
use proxmox_backup::{
|
||||||
api2,
|
api2,
|
||||||
tape::{
|
tape::{complete_media_label_text, complete_media_set_uuid, complete_media_uuid},
|
||||||
complete_media_label_text,
|
|
||||||
complete_media_uuid,
|
|
||||||
complete_media_set_uuid,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn media_commands() -> CommandLineInterface {
|
pub fn media_commands() -> CommandLineInterface {
|
||||||
|
|
||||||
let cmd_def = CliCommandMap::new()
|
let cmd_def = CliCommandMap::new()
|
||||||
.insert(
|
.insert(
|
||||||
"list",
|
"list",
|
||||||
CliCommand::new(&API_METHOD_LIST_MEDIA)
|
CliCommand::new(&API_METHOD_LIST_MEDIA)
|
||||||
.completion_cb("pool", complete_pool_name)
|
.completion_cb("pool", complete_pool_name)
|
||||||
.completion_cb("update-status-changer", complete_changer_name)
|
.completion_cb("update-status-changer", complete_changer_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"destroy",
|
"destroy",
|
||||||
CliCommand::new(&api2::tape::media::API_METHOD_DESTROY_MEDIA)
|
CliCommand::new(&api2::tape::media::API_METHOD_DESTROY_MEDIA)
|
||||||
.arg_param(&["label-text"])
|
.arg_param(&["label-text"])
|
||||||
.completion_cb("label-text", complete_media_label_text)
|
.completion_cb("label-text", complete_media_label_text),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"content",
|
"content",
|
||||||
|
@ -41,9 +36,8 @@ pub fn media_commands() -> CommandLineInterface {
|
||||||
.completion_cb("pool", complete_pool_name)
|
.completion_cb("pool", complete_pool_name)
|
||||||
.completion_cb("label-text", complete_media_label_text)
|
.completion_cb("label-text", complete_media_label_text)
|
||||||
.completion_cb("media", complete_media_uuid)
|
.completion_cb("media", complete_media_uuid)
|
||||||
.completion_cb("media-set", complete_media_set_uuid)
|
.completion_cb("media-set", complete_media_set_uuid),
|
||||||
)
|
);
|
||||||
;
|
|
||||||
|
|
||||||
cmd_def.into()
|
cmd_def.into()
|
||||||
}
|
}
|
||||||
|
@ -74,11 +68,7 @@ pub fn media_commands() -> CommandLineInterface {
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// List pool media
|
/// List pool media
|
||||||
async fn list_media(
|
async fn list_media(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::tape::media::API_METHOD_LIST_MEDIA;
|
let info = &api2::tape::media::API_METHOD_LIST_MEDIA;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -89,17 +79,17 @@ async fn list_media(
|
||||||
fn render_status(_value: &Value, record: &Value) -> Result<String, Error> {
|
fn render_status(_value: &Value, record: &Value) -> Result<String, Error> {
|
||||||
let record: MediaListEntry = serde_json::from_value(record.clone())?;
|
let record: MediaListEntry = serde_json::from_value(record.clone())?;
|
||||||
Ok(match record.status {
|
Ok(match record.status {
|
||||||
MediaStatus::Damaged | MediaStatus::Retired => {
|
MediaStatus::Damaged | MediaStatus::Retired => serde_json::to_value(&record.status)?
|
||||||
serde_json::to_value(&record.status)?
|
.as_str()
|
||||||
.as_str().unwrap()
|
.unwrap()
|
||||||
.to_string()
|
.to_string(),
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
if record.expired {
|
if record.expired {
|
||||||
String::from("expired")
|
String::from("expired")
|
||||||
} else {
|
} else {
|
||||||
serde_json::to_value(&record.status)?
|
serde_json::to_value(&record.status)?
|
||||||
.as_str().unwrap()
|
.as_str()
|
||||||
|
.unwrap()
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,8 +117,7 @@ async fn list_media(
|
||||||
.column(ColumnConfig::new("location"))
|
.column(ColumnConfig::new("location"))
|
||||||
.column(ColumnConfig::new("catalog").renderer(catalog_status))
|
.column(ColumnConfig::new("catalog").renderer(catalog_status))
|
||||||
.column(ColumnConfig::new("uuid"))
|
.column(ColumnConfig::new("uuid"))
|
||||||
.column(ColumnConfig::new("media-set-uuid"))
|
.column(ColumnConfig::new("media-set-uuid"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -150,11 +139,7 @@ async fn list_media(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// List media content
|
/// List media content
|
||||||
fn list_content(
|
fn list_content(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::tape::media::API_METHOD_LIST_CONTENT;
|
let info = &api2::tape::media::API_METHOD_LIST_CONTENT;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -174,11 +159,9 @@ fn list_content(
|
||||||
.column(ColumnConfig::new("seq-nr"))
|
.column(ColumnConfig::new("seq-nr"))
|
||||||
.column(ColumnConfig::new("store"))
|
.column(ColumnConfig::new("store"))
|
||||||
.column(ColumnConfig::new("snapshot"))
|
.column(ColumnConfig::new("snapshot"))
|
||||||
.column(ColumnConfig::new("media-set-uuid"))
|
.column(ColumnConfig::new("media-set-uuid"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use anyhow::{Error};
|
use anyhow::Error;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
|
use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
|
||||||
|
@ -11,35 +11,34 @@ use pbs_config::tape_encryption_keys::complete_key_fingerprint;
|
||||||
use proxmox_backup::api2;
|
use proxmox_backup::api2;
|
||||||
|
|
||||||
pub fn pool_commands() -> CommandLineInterface {
|
pub fn pool_commands() -> CommandLineInterface {
|
||||||
|
|
||||||
let cmd_def = CliCommandMap::new()
|
let cmd_def = CliCommandMap::new()
|
||||||
.insert("list", CliCommand::new(&API_METHOD_LIST_POOLS))
|
.insert("list", CliCommand::new(&API_METHOD_LIST_POOLS))
|
||||||
.insert("config",
|
.insert(
|
||||||
CliCommand::new(&API_METHOD_GET_CONFIG)
|
"config",
|
||||||
|
CliCommand::new(&API_METHOD_GET_CONFIG)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_pool_name)
|
.completion_cb("name", complete_pool_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"remove",
|
"remove",
|
||||||
CliCommand::new(&api2::config::media_pool::API_METHOD_DELETE_POOL)
|
CliCommand::new(&api2::config::media_pool::API_METHOD_DELETE_POOL)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_pool_name)
|
.completion_cb("name", complete_pool_name),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"create",
|
"create",
|
||||||
CliCommand::new(&api2::config::media_pool::API_METHOD_CREATE_POOL)
|
CliCommand::new(&api2::config::media_pool::API_METHOD_CREATE_POOL)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_pool_name)
|
.completion_cb("name", complete_pool_name)
|
||||||
.completion_cb("encrypt", complete_key_fingerprint)
|
.completion_cb("encrypt", complete_key_fingerprint),
|
||||||
)
|
)
|
||||||
.insert(
|
.insert(
|
||||||
"update",
|
"update",
|
||||||
CliCommand::new(&api2::config::media_pool::API_METHOD_UPDATE_POOL)
|
CliCommand::new(&api2::config::media_pool::API_METHOD_UPDATE_POOL)
|
||||||
.arg_param(&["name"])
|
.arg_param(&["name"])
|
||||||
.completion_cb("name", complete_pool_name)
|
.completion_cb("name", complete_pool_name)
|
||||||
.completion_cb("encrypt", complete_key_fingerprint)
|
.completion_cb("encrypt", complete_key_fingerprint),
|
||||||
)
|
);
|
||||||
;
|
|
||||||
|
|
||||||
cmd_def.into()
|
cmd_def.into()
|
||||||
}
|
}
|
||||||
|
@ -55,11 +54,7 @@ pub fn pool_commands() -> CommandLineInterface {
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// List media pool
|
/// List media pool
|
||||||
fn list_pools(
|
fn list_pools(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::config::media_pool::API_METHOD_LIST_POOLS;
|
let info = &api2::config::media_pool::API_METHOD_LIST_POOLS;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -80,8 +75,7 @@ fn list_pools(
|
||||||
.column(ColumnConfig::new("allocation"))
|
.column(ColumnConfig::new("allocation"))
|
||||||
.column(ColumnConfig::new("retention"))
|
.column(ColumnConfig::new("retention"))
|
||||||
.column(ColumnConfig::new("template"))
|
.column(ColumnConfig::new("template"))
|
||||||
.column(ColumnConfig::new("encrypt").renderer(render_encryption))
|
.column(ColumnConfig::new("encrypt").renderer(render_encryption));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
@ -102,11 +96,7 @@ fn list_pools(
|
||||||
},
|
},
|
||||||
)]
|
)]
|
||||||
/// Get media pool configuration
|
/// Get media pool configuration
|
||||||
fn get_config(
|
fn get_config(param: Value, rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
|
||||||
param: Value,
|
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
|
|
||||||
let output_format = get_output_format(¶m);
|
let output_format = get_output_format(¶m);
|
||||||
let info = &api2::config::media_pool::API_METHOD_GET_CONFIG;
|
let info = &api2::config::media_pool::API_METHOD_GET_CONFIG;
|
||||||
let mut data = match info.handler {
|
let mut data = match info.handler {
|
||||||
|
@ -119,8 +109,7 @@ fn get_config(
|
||||||
.column(ColumnConfig::new("allocation"))
|
.column(ColumnConfig::new("allocation"))
|
||||||
.column(ColumnConfig::new("retention"))
|
.column(ColumnConfig::new("retention"))
|
||||||
.column(ColumnConfig::new("template"))
|
.column(ColumnConfig::new("template"))
|
||||||
.column(ColumnConfig::new("encrypt"))
|
.column(ColumnConfig::new("encrypt"));
|
||||||
;
|
|
||||||
|
|
||||||
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue