src/api2/types.rs: define and use GroupListItem
This commit is contained in:
parent
2bbbade367
commit
b31c8019d7
|
@ -60,21 +60,34 @@ fn group_backups(backup_list: Vec<BackupInfo>) -> HashMap<String, Vec<BackupInfo
|
||||||
group_hash
|
group_hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
input: {
|
||||||
|
properties: {
|
||||||
|
store: {
|
||||||
|
schema: DATASTORE_SCHEMA,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
type: Array,
|
||||||
|
description: "Returns the list of backup groups.",
|
||||||
|
items: {
|
||||||
|
type: GroupListItem,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
/// List backup groups.
|
||||||
fn list_groups(
|
fn list_groups(
|
||||||
param: Value,
|
store: String,
|
||||||
_info: &ApiMethod,
|
) -> Result<Vec<GroupListItem>, Error> {
|
||||||
_rpcenv: &mut dyn RpcEnvironment,
|
|
||||||
) -> Result<Value, Error> {
|
|
||||||
|
|
||||||
let store = param["store"].as_str().unwrap();
|
let datastore = DataStore::lookup_datastore(&store)?;
|
||||||
|
|
||||||
let datastore = DataStore::lookup_datastore(store)?;
|
|
||||||
|
|
||||||
let backup_list = BackupInfo::list_backups(&datastore.base_path())?;
|
let backup_list = BackupInfo::list_backups(&datastore.base_path())?;
|
||||||
|
|
||||||
let group_hash = group_backups(backup_list);
|
let group_hash = group_backups(backup_list);
|
||||||
|
|
||||||
let mut groups = vec![];
|
let mut groups = Vec::new();
|
||||||
|
|
||||||
for (_group_id, mut list) in group_hash {
|
for (_group_id, mut list) in group_hash {
|
||||||
|
|
||||||
|
@ -83,16 +96,17 @@ fn list_groups(
|
||||||
let info = &list[0];
|
let info = &list[0];
|
||||||
let group = info.backup_dir.group();
|
let group = info.backup_dir.group();
|
||||||
|
|
||||||
groups.push(json!({
|
let result_item = GroupListItem {
|
||||||
"backup-type": group.backup_type(),
|
backup_type: group.backup_type().to_string(),
|
||||||
"backup-id": group.backup_id(),
|
backup_id: group.backup_id().to_string(),
|
||||||
"last-backup": info.backup_dir.backup_time().timestamp(),
|
last_backup: info.backup_dir.backup_time().timestamp(),
|
||||||
"backup-count": list.len() as u64,
|
backup_count: list.len() as u64,
|
||||||
"files": info.files,
|
files: info.files.clone(),
|
||||||
}));
|
};
|
||||||
|
groups.push(result_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(json!(groups))
|
Ok(groups)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_snapshot_files (
|
fn list_snapshot_files (
|
||||||
|
@ -652,15 +666,7 @@ const DATASTORE_INFO_SUBDIRS: SubdirMap = &[
|
||||||
(
|
(
|
||||||
"groups",
|
"groups",
|
||||||
&Router::new()
|
&Router::new()
|
||||||
.get(
|
.get(&API_METHOD_LIST_GROUPS)
|
||||||
&ApiMethod::new(
|
|
||||||
&ApiHandler::Sync(&list_groups),
|
|
||||||
&ObjectSchema::new(
|
|
||||||
"List backup groups.",
|
|
||||||
&sorted!([ ("store", false, &DATASTORE_SCHEMA) ]),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"prune",
|
"prune",
|
||||||
|
|
|
@ -299,17 +299,12 @@ pub async fn pull_store(
|
||||||
|
|
||||||
let mut result = client.get(&path, None).await?;
|
let mut result = client.get(&path, None).await?;
|
||||||
|
|
||||||
let list = result["data"].as_array_mut().unwrap();
|
let mut list: Vec<GroupListItem> = serde_json::from_value(result["data"].take())?;
|
||||||
|
|
||||||
list.sort_unstable_by(|a, b| {
|
list.sort_unstable_by(|a, b| {
|
||||||
let a_id = a["backup-id"].as_str().unwrap();
|
let type_order = a.backup_type.cmp(&b.backup_type);
|
||||||
let a_backup_type = a["backup-type"].as_str().unwrap();
|
|
||||||
let b_id = b["backup-id"].as_str().unwrap();
|
|
||||||
let b_backup_type = b["backup-type"].as_str().unwrap();
|
|
||||||
|
|
||||||
let type_order = a_backup_type.cmp(b_backup_type);
|
|
||||||
if type_order == std::cmp::Ordering::Equal {
|
if type_order == std::cmp::Ordering::Equal {
|
||||||
a_id.cmp(b_id)
|
a.backup_id.cmp(&b.backup_id)
|
||||||
} else {
|
} else {
|
||||||
type_order
|
type_order
|
||||||
}
|
}
|
||||||
|
@ -318,13 +313,9 @@ pub async fn pull_store(
|
||||||
let mut errors = false;
|
let mut errors = false;
|
||||||
|
|
||||||
for item in list {
|
for item in list {
|
||||||
|
let group = BackupGroup::new(&item.backup_type, &item.backup_id);
|
||||||
let id = item["backup-id"].as_str().unwrap();
|
|
||||||
let btype = item["backup-type"].as_str().unwrap();
|
|
||||||
|
|
||||||
let group = BackupGroup::new(btype, id);
|
|
||||||
if let Err(err) = pull_group(worker, client, src_repo, tgt_store.clone(), &group).await {
|
if let Err(err) = pull_group(worker, client, src_repo, tgt_store.clone(), &group).await {
|
||||||
worker.log(format!("sync group {}/{} failed - {}", btype, id, err));
|
worker.log(format!("sync group {}/{} failed - {}", item.backup_type, item.backup_id, err));
|
||||||
errors = true;
|
errors = true;
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,6 +192,40 @@ pub const PROXMOX_USER_ID_SCHEMA: Schema = StringSchema::new("User ID")
|
||||||
|
|
||||||
// Complex type definitions
|
// Complex type definitions
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
properties: {
|
||||||
|
"backup-type": {
|
||||||
|
schema: BACKUP_TYPE_SCHEMA,
|
||||||
|
},
|
||||||
|
"backup-id": {
|
||||||
|
schema: BACKUP_ID_SCHEMA,
|
||||||
|
},
|
||||||
|
"last-backup": {
|
||||||
|
schema: BACKUP_TIME_SCHEMA,
|
||||||
|
},
|
||||||
|
"backup-count": {
|
||||||
|
type: Integer,
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
items: {
|
||||||
|
schema: BACKUP_ARCHIVE_NAME_SCHEMA
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all="kebab-case")]
|
||||||
|
/// Basic information about a backup group.
|
||||||
|
pub struct GroupListItem {
|
||||||
|
pub backup_type: String, // enum
|
||||||
|
pub backup_id: String,
|
||||||
|
pub last_backup: i64,
|
||||||
|
/// Number of contained snapshots
|
||||||
|
pub backup_count: u64,
|
||||||
|
/// List of contained archive files.
|
||||||
|
pub files: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
properties: {
|
properties: {
|
||||||
"backup-type": {
|
"backup-type": {
|
||||||
|
|
Loading…
Reference in New Issue