]>
Commit | Line | Data |
---|---|---|
a65e3e4b DC |
1 | use anyhow::Error; |
2 | use serde_json::{json, Value}; | |
3 | ||
4 | use proxmox::api::{api, cli::*}; | |
731eeef2 DM |
5 | use proxmox_backup::{ |
6 | tools, | |
7 | api2::types::*, | |
8 | backup::{ | |
9 | BackupGroup, | |
10 | } | |
11 | }; | |
a65e3e4b DC |
12 | |
13 | use crate::{ | |
731eeef2 DM |
14 | REPO_URL_SCHEMA, |
15 | BackupDir, | |
16 | api_datastore_list_snapshots, | |
17 | complete_backup_snapshot, | |
18 | complete_backup_group, | |
19 | complete_repository, | |
20 | connect, | |
21 | extract_repository_from_value, | |
22 | record_repository, | |
a65e3e4b DC |
23 | }; |
24 | ||
731eeef2 DM |
25 | #[api( |
26 | input: { | |
27 | properties: { | |
28 | repository: { | |
29 | schema: REPO_URL_SCHEMA, | |
30 | optional: true, | |
31 | }, | |
32 | group: { | |
33 | type: String, | |
34 | description: "Backup group.", | |
35 | optional: true, | |
36 | }, | |
37 | "output-format": { | |
38 | schema: OUTPUT_FORMAT, | |
39 | optional: true, | |
40 | }, | |
41 | } | |
42 | } | |
43 | )] | |
44 | /// List backup snapshots. | |
45 | async fn list_snapshots(param: Value) -> Result<Value, Error> { | |
46 | ||
47 | let repo = extract_repository_from_value(¶m)?; | |
48 | ||
49 | let output_format = get_output_format(¶m); | |
50 | ||
51 | let client = connect(&repo)?; | |
52 | ||
53 | let group: Option<BackupGroup> = if let Some(path) = param["group"].as_str() { | |
54 | Some(path.parse()?) | |
55 | } else { | |
56 | None | |
57 | }; | |
58 | ||
59 | let mut data = api_datastore_list_snapshots(&client, repo.store(), group).await?; | |
60 | ||
61 | record_repository(&repo); | |
62 | ||
63 | let render_snapshot_path = |_v: &Value, record: &Value| -> Result<String, Error> { | |
64 | let item: SnapshotListItem = serde_json::from_value(record.to_owned())?; | |
65 | let snapshot = BackupDir::new(item.backup_type, item.backup_id, item.backup_time)?; | |
66 | Ok(snapshot.relative_path().to_str().unwrap().to_owned()) | |
67 | }; | |
68 | ||
69 | let render_files = |_v: &Value, record: &Value| -> Result<String, Error> { | |
70 | let item: SnapshotListItem = serde_json::from_value(record.to_owned())?; | |
71 | let mut filenames = Vec::new(); | |
72 | for file in &item.files { | |
73 | filenames.push(file.filename.to_string()); | |
74 | } | |
75 | Ok(tools::format::render_backup_file_list(&filenames[..])) | |
76 | }; | |
77 | ||
78 | let options = default_table_format_options() | |
79 | .sortby("backup-type", false) | |
80 | .sortby("backup-id", false) | |
81 | .sortby("backup-time", false) | |
82 | .column(ColumnConfig::new("backup-id").renderer(render_snapshot_path).header("snapshot")) | |
83 | .column(ColumnConfig::new("size").renderer(tools::format::render_bytes_human_readable)) | |
84 | .column(ColumnConfig::new("files").renderer(render_files)) | |
85 | ; | |
86 | ||
87 | let info = &proxmox_backup::api2::admin::datastore::API_RETURN_SCHEMA_LIST_SNAPSHOTS; | |
88 | ||
89 | format_and_print_result_full(&mut data, info, &output_format, &options); | |
90 | ||
91 | Ok(Value::Null) | |
92 | } | |
93 | ||
a65e3e4b DC |
94 | #[api( |
95 | input: { | |
96 | properties: { | |
97 | repository: { | |
98 | schema: REPO_URL_SCHEMA, | |
99 | optional: true, | |
100 | }, | |
101 | snapshot: { | |
102 | type: String, | |
103 | description: "Snapshot path.", | |
104 | }, | |
105 | "output-format": { | |
106 | schema: OUTPUT_FORMAT, | |
107 | optional: true, | |
108 | }, | |
109 | } | |
110 | } | |
111 | )] | |
112 | /// Show notes | |
113 | async fn show_notes(param: Value) -> Result<Value, Error> { | |
114 | let repo = extract_repository_from_value(¶m)?; | |
115 | let path = tools::required_string_param(¶m, "snapshot")?; | |
116 | ||
117 | let snapshot: BackupDir = path.parse()?; | |
118 | let client = connect(&repo)?; | |
119 | ||
120 | let path = format!("api2/json/admin/datastore/{}/notes", repo.store()); | |
121 | ||
122 | let args = json!({ | |
123 | "backup-type": snapshot.group().backup_type(), | |
124 | "backup-id": snapshot.group().backup_id(), | |
125 | "backup-time": snapshot.backup_time(), | |
126 | }); | |
127 | ||
128 | let output_format = get_output_format(¶m); | |
129 | ||
130 | let mut result = client.get(&path, Some(args)).await?; | |
131 | ||
132 | let notes = result["data"].take(); | |
133 | ||
134 | if output_format == "text" { | |
135 | if let Some(notes) = notes.as_str() { | |
136 | println!("{}", notes); | |
137 | } | |
138 | } else { | |
139 | format_and_print_result( | |
140 | &json!({ | |
141 | "notes": notes, | |
142 | }), | |
143 | &output_format, | |
144 | ); | |
145 | } | |
146 | ||
147 | Ok(Value::Null) | |
148 | } | |
149 | ||
150 | #[api( | |
151 | input: { | |
152 | properties: { | |
153 | repository: { | |
154 | schema: REPO_URL_SCHEMA, | |
155 | optional: true, | |
156 | }, | |
157 | snapshot: { | |
158 | type: String, | |
159 | description: "Snapshot path.", | |
160 | }, | |
161 | notes: { | |
162 | type: String, | |
163 | description: "The Notes.", | |
164 | }, | |
165 | } | |
166 | } | |
167 | )] | |
168 | /// Update Notes | |
169 | async fn update_notes(param: Value) -> Result<Value, Error> { | |
170 | let repo = extract_repository_from_value(¶m)?; | |
171 | let path = tools::required_string_param(¶m, "snapshot")?; | |
172 | let notes = tools::required_string_param(¶m, "notes")?; | |
173 | ||
174 | let snapshot: BackupDir = path.parse()?; | |
175 | let mut client = connect(&repo)?; | |
176 | ||
177 | let path = format!("api2/json/admin/datastore/{}/notes", repo.store()); | |
178 | ||
179 | let args = json!({ | |
180 | "backup-type": snapshot.group().backup_type(), | |
181 | "backup-id": snapshot.group().backup_id(), | |
182 | "backup-time": snapshot.backup_time(), | |
183 | "notes": notes, | |
184 | }); | |
185 | ||
186 | client.put(&path, Some(args)).await?; | |
187 | ||
188 | Ok(Value::Null) | |
189 | } | |
190 | ||
191 | fn notes_cli() -> CliCommandMap { | |
192 | CliCommandMap::new() | |
193 | .insert( | |
194 | "show", | |
195 | CliCommand::new(&API_METHOD_SHOW_NOTES) | |
196 | .arg_param(&["snapshot"]) | |
197 | .completion_cb("snapshot", complete_backup_snapshot), | |
198 | ) | |
199 | .insert( | |
200 | "update", | |
201 | CliCommand::new(&API_METHOD_UPDATE_NOTES) | |
202 | .arg_param(&["snapshot", "notes"]) | |
203 | .completion_cb("snapshot", complete_backup_snapshot), | |
204 | ) | |
205 | } | |
206 | ||
207 | pub fn snapshot_mgtm_cli() -> CliCommandMap { | |
731eeef2 DM |
208 | CliCommandMap::new() |
209 | .insert("notes", notes_cli()) | |
210 | .insert( | |
211 | "list", CliCommand::new(&API_METHOD_LIST_SNAPSHOTS) | |
212 | .arg_param(&["group"]) | |
213 | .completion_cb("group", complete_backup_group) | |
214 | .completion_cb("repository", complete_repository) | |
215 | ) | |
a65e3e4b | 216 | } |