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