]>
Commit | Line | Data |
---|---|---|
fba0b774 DM |
1 | use anyhow::{Error}; |
2 | use serde_json::Value; | |
3 | ||
6ef1b649 WB |
4 | use proxmox_router::{cli::*, ApiHandler, RpcEnvironment}; |
5 | use proxmox_schema::api; | |
fba0b774 | 6 | |
1ce8e905 DM |
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; | |
aad2d162 | 12 | use pbs_config::media_pool::complete_pool_name; |
1ce8e905 | 13 | |
fba0b774 | 14 | use proxmox_backup::{ |
1ce8e905 | 15 | api2, |
a33389c3 | 16 | tape::{ |
8446fbca | 17 | complete_media_label_text, |
a33389c3 DM |
18 | complete_media_uuid, |
19 | complete_media_set_uuid, | |
fba0b774 | 20 | }, |
fba0b774 DM |
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) | |
9bbd83b1 | 30 | .completion_cb("update-status-changer", complete_changer_name) |
fba0b774 | 31 | ) |
fb657d8e | 32 | .insert( |
e20d008c | 33 | "destroy", |
fb657d8e | 34 | CliCommand::new(&api2::tape::media::API_METHOD_DESTROY_MEDIA) |
8446fbca DM |
35 | .arg_param(&["label-text"]) |
36 | .completion_cb("label-text", complete_media_label_text) | |
fb657d8e | 37 | ) |
a33389c3 DM |
38 | .insert( |
39 | "content", | |
40 | CliCommand::new(&API_METHOD_LIST_CONTENT) | |
41 | .completion_cb("pool", complete_pool_name) | |
8446fbca | 42 | .completion_cb("label-text", complete_media_label_text) |
a33389c3 DM |
43 | .completion_cb("media", complete_media_uuid) |
44 | .completion_cb("media-set", complete_media_set_uuid) | |
45 | ) | |
fba0b774 DM |
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 | }, | |
9bbd83b1 DM |
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 | }, | |
fba0b774 DM |
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(¶m); | |
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 | ||
fba0b774 DM |
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 | ||
0bf1c314 DM |
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 | } | |
fba0b774 DM |
117 | let options = default_table_format_options() |
118 | .sortby("pool", false) | |
119 | .sortby("media-set-uuid", false) | |
120 | .sortby("seq-nr", false) | |
8446fbca DM |
121 | .sortby("label-text", false) |
122 | .column(ColumnConfig::new("label-text")) | |
fba0b774 DM |
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)) | |
c1c2c8f6 | 127 | .column(ColumnConfig::new("location")) |
0bf1c314 | 128 | .column(ColumnConfig::new("catalog").renderer(catalog_status)) |
fba0b774 DM |
129 | .column(ColumnConfig::new("uuid")) |
130 | .column(ColumnConfig::new("media-set-uuid")) | |
131 | ; | |
132 | ||
b2362a12 | 133 | format_and_print_result_full(&mut data, &info.returns, &output_format, &options); |
fba0b774 DM |
134 | |
135 | Ok(()) | |
136 | } | |
a33389c3 DM |
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(¶m); | |
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) | |
ef4bdf6b | 168 | .sortby("store", false) |
a33389c3 DM |
169 | .sortby("snapshot", false) |
170 | .sortby("backup-time", false) | |
8446fbca | 171 | .column(ColumnConfig::new("label-text")) |
a33389c3 DM |
172 | .column(ColumnConfig::new("pool")) |
173 | .column(ColumnConfig::new("media-set-name")) | |
174 | .column(ColumnConfig::new("seq-nr")) | |
ef4bdf6b | 175 | .column(ColumnConfig::new("store")) |
a33389c3 DM |
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 | } |