]>
Commit | Line | Data |
---|---|---|
e6604cf3 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 | ||
13 | use proxmox_backup::{ | |
14 | api2::{ | |
15 | self, | |
16 | types::{ | |
17 | DRIVE_ID_SCHEMA, | |
18 | CHANGER_ID_SCHEMA, | |
19 | LINUX_DRIVE_PATH_SCHEMA, | |
20 | }, | |
21 | }, | |
22 | tape::{ | |
23 | complete_drive_path, | |
24 | }, | |
25 | config::drive::{ | |
26 | complete_drive_name, | |
27 | complete_changer_name, | |
28 | complete_linux_drive_name, | |
29 | }, | |
30 | }; | |
31 | ||
32 | pub fn drive_commands() -> CommandLineInterface { | |
33 | ||
34 | let cmd_def = CliCommandMap::new() | |
35 | .insert("scan-for-drives", CliCommand::new(&API_METHOD_SCAN_FOR_DRIVES)) | |
36 | .insert("list", CliCommand::new(&API_METHOD_LIST_DRIVES)) | |
37 | .insert("config", | |
38 | CliCommand::new(&API_METHOD_GET_CONFIG) | |
39 | .arg_param(&["name"]) | |
40 | .completion_cb("name", complete_linux_drive_name) | |
41 | ) | |
42 | .insert( | |
43 | "remove", | |
44 | CliCommand::new(&API_METHOD_DELETE_DRIVE) | |
45 | .arg_param(&["name"]) | |
46 | .completion_cb("name", complete_linux_drive_name) | |
47 | ) | |
48 | .insert( | |
49 | "create", | |
50 | CliCommand::new(&API_METHOD_CREATE_LINUX_DRIVE) | |
51 | .arg_param(&["name"]) | |
52 | .completion_cb("name", complete_drive_name) | |
53 | .completion_cb("path", complete_drive_path) | |
54 | .completion_cb("changer", complete_changer_name) | |
55 | ) | |
56 | .insert( | |
57 | "update", | |
58 | CliCommand::new(&API_METHOD_UPDATE_LINUX_DRIVE) | |
59 | .arg_param(&["name"]) | |
60 | .completion_cb("name", complete_linux_drive_name) | |
61 | .completion_cb("path", complete_drive_path) | |
62 | .completion_cb("changer", complete_changer_name) | |
63 | ) | |
64 | .insert( | |
65 | "load", | |
66 | CliCommand::new(&API_METHOD_LOAD_SLOT) | |
67 | .arg_param(&["name"]) | |
68 | .completion_cb("name", complete_linux_drive_name) | |
69 | ) | |
70 | .insert( | |
71 | "unload", | |
72 | CliCommand::new(&API_METHOD_UNLOAD) | |
73 | .arg_param(&["name"]) | |
74 | .completion_cb("name", complete_linux_drive_name) | |
75 | ) | |
76 | ; | |
77 | ||
78 | cmd_def.into() | |
79 | } | |
80 | ||
81 | #[api( | |
82 | input: { | |
83 | properties: { | |
84 | name: { | |
85 | schema: DRIVE_ID_SCHEMA, | |
86 | }, | |
87 | path: { | |
88 | schema: LINUX_DRIVE_PATH_SCHEMA, | |
89 | }, | |
90 | changer: { | |
91 | schema: CHANGER_ID_SCHEMA, | |
92 | optional: true, | |
93 | }, | |
94 | }, | |
95 | }, | |
96 | )] | |
97 | /// Create a new drive | |
98 | fn create_linux_drive( | |
99 | param: Value, | |
100 | rpcenv: &mut dyn RpcEnvironment, | |
101 | ) -> Result<(), Error> { | |
102 | ||
103 | let info = &api2::config::drive::API_METHOD_CREATE_DRIVE; | |
104 | match info.handler { | |
105 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
106 | _ => unreachable!(), | |
107 | }; | |
108 | ||
109 | Ok(()) | |
110 | } | |
111 | ||
112 | #[api( | |
113 | input: { | |
114 | properties: { | |
115 | "output-format": { | |
116 | schema: OUTPUT_FORMAT, | |
117 | optional: true, | |
118 | }, | |
119 | }, | |
120 | }, | |
121 | )] | |
122 | /// List drives | |
123 | fn list_drives( | |
124 | param: Value, | |
125 | rpcenv: &mut dyn RpcEnvironment, | |
126 | ) -> Result<(), Error> { | |
127 | ||
128 | let output_format = get_output_format(¶m); | |
129 | let info = &api2::config::drive::API_METHOD_LIST_DRIVES; | |
130 | let mut data = match info.handler { | |
131 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
132 | _ => unreachable!(), | |
133 | }; | |
134 | ||
135 | let options = default_table_format_options() | |
136 | .column(ColumnConfig::new("name")) | |
137 | .column(ColumnConfig::new("path")) | |
138 | .column(ColumnConfig::new("changer")) | |
139 | .column(ColumnConfig::new("vendor")) | |
140 | .column(ColumnConfig::new("model")) | |
141 | .column(ColumnConfig::new("serial")) | |
142 | ; | |
143 | ||
144 | format_and_print_result_full(&mut data, info.returns, &output_format, &options); | |
145 | ||
146 | Ok(()) | |
147 | } | |
148 | ||
149 | #[api( | |
150 | input: { | |
151 | properties: { | |
152 | "output-format": { | |
153 | schema: OUTPUT_FORMAT, | |
154 | optional: true, | |
155 | }, | |
156 | }, | |
157 | } | |
158 | )] | |
159 | /// Scan for drives | |
160 | fn scan_for_drives( | |
161 | param: Value, | |
162 | rpcenv: &mut dyn RpcEnvironment, | |
163 | ) -> Result<(), Error> { | |
164 | ||
165 | let output_format = get_output_format(¶m); | |
166 | let info = &api2::tape::drive::API_METHOD_SCAN_DRIVES; | |
167 | let mut data = match info.handler { | |
168 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
169 | _ => unreachable!(), | |
170 | }; | |
171 | ||
172 | let options = default_table_format_options() | |
173 | .column(ColumnConfig::new("path")) | |
174 | .column(ColumnConfig::new("vendor")) | |
175 | .column(ColumnConfig::new("model")) | |
176 | .column(ColumnConfig::new("serial")) | |
177 | ; | |
178 | ||
179 | format_and_print_result_full(&mut data, info.returns, &output_format, &options); | |
180 | ||
181 | Ok(()) | |
182 | } | |
183 | ||
184 | ||
185 | #[api( | |
186 | input: { | |
187 | properties: { | |
188 | "output-format": { | |
189 | schema: OUTPUT_FORMAT, | |
190 | optional: true, | |
191 | }, | |
192 | name: { | |
193 | schema: DRIVE_ID_SCHEMA, | |
194 | }, | |
195 | }, | |
196 | }, | |
197 | )] | |
198 | /// Get pool configuration | |
199 | fn get_config( | |
200 | param: Value, | |
201 | rpcenv: &mut dyn RpcEnvironment, | |
202 | ) -> Result<(), Error> { | |
203 | ||
204 | let output_format = get_output_format(¶m); | |
205 | let info = &api2::config::drive::API_METHOD_GET_CONFIG; | |
206 | let mut data = match info.handler { | |
207 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
208 | _ => unreachable!(), | |
209 | }; | |
210 | ||
211 | let options = default_table_format_options() | |
212 | .column(ColumnConfig::new("name")) | |
213 | .column(ColumnConfig::new("path")) | |
214 | .column(ColumnConfig::new("changer")) | |
215 | ; | |
216 | ||
217 | format_and_print_result_full(&mut data, info.returns, &output_format, &options); | |
218 | ||
219 | Ok(()) | |
220 | } | |
221 | ||
222 | #[api( | |
223 | input: { | |
224 | properties: { | |
225 | name: { | |
226 | schema: DRIVE_ID_SCHEMA, | |
227 | }, | |
228 | }, | |
229 | }, | |
230 | )] | |
231 | /// Delete a drive configuration | |
232 | fn delete_drive( | |
233 | param: Value, | |
234 | rpcenv: &mut dyn RpcEnvironment, | |
235 | ) -> Result<(), Error> { | |
236 | ||
237 | let info = &api2::config::drive::API_METHOD_DELETE_DRIVE; | |
238 | ||
239 | match info.handler { | |
240 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
241 | _ => unreachable!(), | |
242 | }; | |
243 | ||
244 | Ok(()) | |
245 | } | |
246 | ||
247 | #[api( | |
248 | input: { | |
249 | properties: { | |
250 | name: { | |
251 | schema: DRIVE_ID_SCHEMA, | |
252 | }, | |
253 | path: { | |
254 | schema: LINUX_DRIVE_PATH_SCHEMA, | |
255 | optional: true, | |
256 | }, | |
257 | changer: { | |
258 | schema: CHANGER_ID_SCHEMA, | |
259 | optional: true, | |
260 | }, | |
261 | }, | |
262 | }, | |
263 | )] | |
264 | /// Update a drive configuration | |
265 | fn update_linux_drive( | |
266 | param: Value, | |
267 | rpcenv: &mut dyn RpcEnvironment, | |
268 | ) -> Result<(), Error> { | |
269 | ||
270 | let info = &api2::config::drive::API_METHOD_UPDATE_DRIVE; | |
271 | ||
272 | match info.handler { | |
273 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
274 | _ => unreachable!(), | |
275 | }; | |
276 | ||
277 | Ok(()) | |
278 | } | |
279 | ||
280 | #[api( | |
281 | input: { | |
282 | properties: { | |
283 | name: { | |
284 | schema: DRIVE_ID_SCHEMA, | |
285 | }, | |
286 | slot: { | |
287 | type: u64, | |
288 | description: "Source slot number", | |
289 | minimum: 1, | |
290 | }, | |
291 | }, | |
292 | }, | |
293 | )] | |
294 | /// Load media via changer from slot | |
295 | fn load_slot( | |
296 | param: Value, | |
297 | rpcenv: &mut dyn RpcEnvironment, | |
298 | ) -> Result<(), Error> { | |
299 | ||
300 | let info = &api2::tape::drive::API_METHOD_LOAD_SLOT; | |
301 | ||
302 | match info.handler { | |
303 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
304 | _ => unreachable!(), | |
305 | }; | |
306 | ||
307 | Ok(()) | |
308 | } | |
309 | ||
310 | #[api( | |
311 | input: { | |
312 | properties: { | |
313 | name: { | |
314 | schema: DRIVE_ID_SCHEMA, | |
315 | }, | |
316 | slot: { | |
317 | description: "Target slot number. If omitted, defaults to the slot that the drive was loaded from.", | |
318 | type: u64, | |
319 | minimum: 1, | |
320 | optional: true, | |
321 | }, | |
322 | }, | |
323 | }, | |
324 | )] | |
325 | /// Unload media via changer | |
326 | fn unload( | |
327 | param: Value, | |
328 | rpcenv: &mut dyn RpcEnvironment, | |
329 | ) -> Result<(), Error> { | |
330 | ||
331 | let info = &api2::tape::drive::API_METHOD_UNLOAD; | |
332 | ||
333 | match info.handler { | |
334 | ApiHandler::Sync(handler) => (handler)(param, info, rpcenv)?, | |
335 | _ => unreachable!(), | |
336 | }; | |
337 | ||
338 | Ok(()) | |
339 | } |