proxmox-backup/src/bin/proxmox_tape/media.rs

197 lines
5.6 KiB
Rust
Raw Normal View History

2020-12-14 06:55:57 +00:00
use anyhow::{Error};
use serde_json::Value;
use proxmox::{
api::{
api,
cli::*,
RpcEnvironment,
ApiHandler,
},
};
use proxmox_backup::{
api2::{
self,
types::{
MEDIA_POOL_NAME_SCHEMA,
CHANGER_NAME_SCHEMA,
2020-12-14 06:55:57 +00:00
MediaStatus,
MediaListEntry,
},
2020-12-29 10:58:26 +00:00
tape::media::MediaContentListFilter,
},
config::drive::complete_changer_name,
2020-12-29 10:58:26 +00:00
tape::{
2021-01-13 12:26:59 +00:00
complete_media_label_text,
2020-12-29 10:58:26 +00:00
complete_media_uuid,
complete_media_set_uuid,
2020-12-14 06:55:57 +00:00
},
config::{
media_pool::complete_pool_name,
},
};
pub fn media_commands() -> CommandLineInterface {
let cmd_def = CliCommandMap::new()
.insert(
"list",
CliCommand::new(&API_METHOD_LIST_MEDIA)
.completion_cb("pool", complete_pool_name)
.completion_cb("update-status-changer", complete_changer_name)
2020-12-14 06:55:57 +00:00
)
2020-12-14 07:58:40 +00:00
.insert(
"destroy",
2020-12-14 07:58:40 +00:00
CliCommand::new(&api2::tape::media::API_METHOD_DESTROY_MEDIA)
2021-01-13 12:26:59 +00:00
.arg_param(&["label-text"])
.completion_cb("label-text", complete_media_label_text)
2020-12-14 07:58:40 +00:00
)
2020-12-29 10:58:26 +00:00
.insert(
"content",
CliCommand::new(&API_METHOD_LIST_CONTENT)
.completion_cb("pool", complete_pool_name)
2021-01-13 12:26:59 +00:00
.completion_cb("label-text", complete_media_label_text)
2020-12-29 10:58:26 +00:00
.completion_cb("media", complete_media_uuid)
.completion_cb("media-set", complete_media_set_uuid)
)
2020-12-14 06:55:57 +00:00
;
cmd_def.into()
}
#[api(
input: {
properties: {
pool: {
schema: MEDIA_POOL_NAME_SCHEMA,
optional: true,
},
"update-status": {
description: "Try to update tape library status (check what tapes are online).",
type: bool,
optional: true,
default: true,
},
"update-status-changer": {
// only update status for a single changer
schema: CHANGER_NAME_SCHEMA,
optional: true,
},
2020-12-14 06:55:57 +00:00
"output-format": {
schema: OUTPUT_FORMAT,
optional: true,
},
},
},
)]
/// List pool media
async fn list_media(
param: Value,
rpcenv: &mut dyn RpcEnvironment,
) -> Result<(), Error> {
let output_format = get_output_format(&param);
let info = &api2::tape::media::API_METHOD_LIST_MEDIA;
let mut data = match info.handler {
ApiHandler::Async(handler) => (handler)(param, info, rpcenv).await?,
_ => unreachable!(),
};
fn render_status(_value: &Value, record: &Value) -> Result<String, Error> {
let record: MediaListEntry = serde_json::from_value(record.clone())?;
Ok(match record.status {
MediaStatus::Damaged | MediaStatus::Retired => {
serde_json::to_value(&record.status)?
.as_str().unwrap()
.to_string()
}
_ => {
if record.expired {
String::from("expired")
} else {
serde_json::to_value(&record.status)?
.as_str().unwrap()
.to_string()
}
}
})
}
fn catalog_status(value: &Value, _record: &Value) -> Result<String, Error> {
let catalog_ok = value.as_bool().unwrap();
if catalog_ok {
Ok(String::from("ok"))
} else {
Ok(String::from("missing"))
}
}
2020-12-14 06:55:57 +00:00
let options = default_table_format_options()
.sortby("pool", false)
.sortby("media-set-uuid", false)
.sortby("seq-nr", false)
2021-01-13 12:26:59 +00:00
.sortby("label-text", false)
.column(ColumnConfig::new("label-text"))
2020-12-14 06:55:57 +00:00
.column(ColumnConfig::new("pool"))
.column(ColumnConfig::new("media-set-name"))
.column(ColumnConfig::new("seq-nr"))
.column(ColumnConfig::new("status").renderer(render_status))
.column(ColumnConfig::new("location"))
.column(ColumnConfig::new("catalog").renderer(catalog_status))
2020-12-14 06:55:57 +00:00
.column(ColumnConfig::new("uuid"))
.column(ColumnConfig::new("media-set-uuid"))
;
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
2020-12-14 06:55:57 +00:00
Ok(())
}
2020-12-29 10:58:26 +00:00
#[api(
input: {
properties: {
"filter": {
type: MediaContentListFilter,
flatten: true,
},
"output-format": {
schema: OUTPUT_FORMAT,
optional: true,
},
},
},
)]
/// List media content
fn list_content(
param: Value,
rpcenv: &mut dyn RpcEnvironment,
) -> Result<(), Error> {
let output_format = get_output_format(&param);
let info = &api2::tape::media::API_METHOD_LIST_CONTENT;
let mut data = match info.handler {
ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?,
_ => unreachable!(),
};
let options = default_table_format_options()
.sortby("media-set-uuid", false)
.sortby("seq-nr", false)
.sortby("store", false)
2020-12-29 10:58:26 +00:00
.sortby("snapshot", false)
.sortby("backup-time", false)
2021-01-13 12:26:59 +00:00
.column(ColumnConfig::new("label-text"))
2020-12-29 10:58:26 +00:00
.column(ColumnConfig::new("pool"))
.column(ColumnConfig::new("media-set-name"))
.column(ColumnConfig::new("seq-nr"))
.column(ColumnConfig::new("store"))
2020-12-29 10:58:26 +00:00
.column(ColumnConfig::new("snapshot"))
.column(ColumnConfig::new("media-set-uuid"))
;
format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
Ok(())
}