]> git.proxmox.com Git - proxmox-backup.git/blob - src/bin/proxmox_tape/media.rs
update to first proxmox crate split
[proxmox-backup.git] / src / bin / proxmox_tape / media.rs
1 use anyhow::{Error};
2 use serde_json::Value;
3
4 use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
5 use proxmox_schema::api;
6
7 use pbs_api_types::{
8 MEDIA_POOL_NAME_SCHEMA, CHANGER_NAME_SCHEMA, MediaStatus, MediaListEntry,
9 MediaContentListFilter,
10 };
11 use pbs_config::drive::complete_changer_name;
12 use pbs_config::media_pool::complete_pool_name;
13
14 use proxmox_backup::{
15 api2,
16 tape::{
17 complete_media_label_text,
18 complete_media_uuid,
19 complete_media_set_uuid,
20 },
21 };
22
23 pub fn media_commands() -> CommandLineInterface {
24
25 let cmd_def = CliCommandMap::new()
26 .insert(
27 "list",
28 CliCommand::new(&API_METHOD_LIST_MEDIA)
29 .completion_cb("pool", complete_pool_name)
30 .completion_cb("update-status-changer", complete_changer_name)
31 )
32 .insert(
33 "destroy",
34 CliCommand::new(&api2::tape::media::API_METHOD_DESTROY_MEDIA)
35 .arg_param(&["label-text"])
36 .completion_cb("label-text", complete_media_label_text)
37 )
38 .insert(
39 "content",
40 CliCommand::new(&API_METHOD_LIST_CONTENT)
41 .completion_cb("pool", complete_pool_name)
42 .completion_cb("label-text", complete_media_label_text)
43 .completion_cb("media", complete_media_uuid)
44 .completion_cb("media-set", complete_media_set_uuid)
45 )
46 ;
47
48 cmd_def.into()
49 }
50
51 #[api(
52 input: {
53 properties: {
54 pool: {
55 schema: MEDIA_POOL_NAME_SCHEMA,
56 optional: true,
57 },
58 "update-status": {
59 description: "Try to update tape library status (check what tapes are online).",
60 type: bool,
61 optional: true,
62 default: true,
63 },
64 "update-status-changer": {
65 // only update status for a single changer
66 schema: CHANGER_NAME_SCHEMA,
67 optional: true,
68 },
69 "output-format": {
70 schema: OUTPUT_FORMAT,
71 optional: true,
72 },
73 },
74 },
75 )]
76 /// List pool media
77 async fn list_media(
78 param: Value,
79 rpcenv: &mut dyn RpcEnvironment,
80 ) -> Result<(), Error> {
81
82 let output_format = get_output_format(&param);
83 let info = &api2::tape::media::API_METHOD_LIST_MEDIA;
84 let mut data = match info.handler {
85 ApiHandler::Async(handler) => (handler)(param, info, rpcenv).await?,
86 _ => unreachable!(),
87 };
88
89 fn render_status(_value: &Value, record: &Value) -> Result<String, Error> {
90 let record: MediaListEntry = serde_json::from_value(record.clone())?;
91 Ok(match record.status {
92 MediaStatus::Damaged | MediaStatus::Retired => {
93 serde_json::to_value(&record.status)?
94 .as_str().unwrap()
95 .to_string()
96 }
97 _ => {
98 if record.expired {
99 String::from("expired")
100 } else {
101 serde_json::to_value(&record.status)?
102 .as_str().unwrap()
103 .to_string()
104 }
105 }
106 })
107 }
108
109 fn catalog_status(value: &Value, _record: &Value) -> Result<String, Error> {
110 let catalog_ok = value.as_bool().unwrap();
111 if catalog_ok {
112 Ok(String::from("ok"))
113 } else {
114 Ok(String::from("missing"))
115 }
116 }
117 let options = default_table_format_options()
118 .sortby("pool", false)
119 .sortby("media-set-uuid", false)
120 .sortby("seq-nr", false)
121 .sortby("label-text", false)
122 .column(ColumnConfig::new("label-text"))
123 .column(ColumnConfig::new("pool"))
124 .column(ColumnConfig::new("media-set-name"))
125 .column(ColumnConfig::new("seq-nr"))
126 .column(ColumnConfig::new("status").renderer(render_status))
127 .column(ColumnConfig::new("location"))
128 .column(ColumnConfig::new("catalog").renderer(catalog_status))
129 .column(ColumnConfig::new("uuid"))
130 .column(ColumnConfig::new("media-set-uuid"))
131 ;
132
133 format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
134
135 Ok(())
136 }
137
138 #[api(
139 input: {
140 properties: {
141 "filter": {
142 type: MediaContentListFilter,
143 flatten: true,
144 },
145 "output-format": {
146 schema: OUTPUT_FORMAT,
147 optional: true,
148 },
149 },
150 },
151 )]
152 /// List media content
153 fn list_content(
154 param: Value,
155 rpcenv: &mut dyn RpcEnvironment,
156 ) -> Result<(), Error> {
157
158 let output_format = get_output_format(&param);
159 let info = &api2::tape::media::API_METHOD_LIST_CONTENT;
160 let mut data = match info.handler {
161 ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?,
162 _ => unreachable!(),
163 };
164
165 let options = default_table_format_options()
166 .sortby("media-set-uuid", false)
167 .sortby("seq-nr", false)
168 .sortby("store", false)
169 .sortby("snapshot", false)
170 .sortby("backup-time", false)
171 .column(ColumnConfig::new("label-text"))
172 .column(ColumnConfig::new("pool"))
173 .column(ColumnConfig::new("media-set-name"))
174 .column(ColumnConfig::new("seq-nr"))
175 .column(ColumnConfig::new("store"))
176 .column(ColumnConfig::new("snapshot"))
177 .column(ColumnConfig::new("media-set-uuid"))
178 ;
179
180 format_and_print_result_full(&mut data, &info.returns, &output_format, &options);
181
182 Ok(())
183
184 }