src/api2/types.rs: define and use GroupListItem
This commit is contained in:
		@ -60,21 +60,34 @@ fn group_backups(backup_list: Vec<BackupInfo>) -> HashMap<String, Vec<BackupInfo
 | 
			
		||||
    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(
 | 
			
		||||
    param: Value,
 | 
			
		||||
    _info: &ApiMethod,
 | 
			
		||||
    _rpcenv: &mut dyn RpcEnvironment,
 | 
			
		||||
) -> Result<Value, Error> {
 | 
			
		||||
    store: String,
 | 
			
		||||
) -> Result<Vec<GroupListItem>, 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 group_hash = group_backups(backup_list);
 | 
			
		||||
 | 
			
		||||
    let mut groups = vec![];
 | 
			
		||||
    let mut groups = Vec::new();
 | 
			
		||||
 | 
			
		||||
    for (_group_id, mut list) in group_hash {
 | 
			
		||||
 | 
			
		||||
@ -83,16 +96,17 @@ fn list_groups(
 | 
			
		||||
        let info = &list[0];
 | 
			
		||||
        let group = info.backup_dir.group();
 | 
			
		||||
 | 
			
		||||
        groups.push(json!({
 | 
			
		||||
            "backup-type": group.backup_type(),
 | 
			
		||||
            "backup-id": group.backup_id(),
 | 
			
		||||
            "last-backup": info.backup_dir.backup_time().timestamp(),
 | 
			
		||||
            "backup-count": list.len() as u64,
 | 
			
		||||
            "files": info.files,
 | 
			
		||||
        }));
 | 
			
		||||
        let result_item = GroupListItem {
 | 
			
		||||
            backup_type: group.backup_type().to_string(),
 | 
			
		||||
            backup_id: group.backup_id().to_string(),
 | 
			
		||||
            last_backup: info.backup_dir.backup_time().timestamp(),
 | 
			
		||||
            backup_count: list.len() as u64,
 | 
			
		||||
            files: info.files.clone(),
 | 
			
		||||
        };
 | 
			
		||||
        groups.push(result_item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(json!(groups))
 | 
			
		||||
    Ok(groups)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn list_snapshot_files (
 | 
			
		||||
@ -652,15 +666,7 @@ const DATASTORE_INFO_SUBDIRS: SubdirMap = &[
 | 
			
		||||
    (
 | 
			
		||||
        "groups",
 | 
			
		||||
        &Router::new()
 | 
			
		||||
            .get(
 | 
			
		||||
                &ApiMethod::new(
 | 
			
		||||
                    &ApiHandler::Sync(&list_groups),
 | 
			
		||||
                    &ObjectSchema::new(
 | 
			
		||||
                        "List backup groups.",
 | 
			
		||||
                        &sorted!([ ("store", false, &DATASTORE_SCHEMA) ]),
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            .get(&API_METHOD_LIST_GROUPS)
 | 
			
		||||
    ),
 | 
			
		||||
    (
 | 
			
		||||
        "prune",
 | 
			
		||||
 | 
			
		||||
@ -299,17 +299,12 @@ pub async fn pull_store(
 | 
			
		||||
 | 
			
		||||
    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| {
 | 
			
		||||
        let a_id = a["backup-id"].as_str().unwrap();
 | 
			
		||||
        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);
 | 
			
		||||
        let type_order = a.backup_type.cmp(&b.backup_type);
 | 
			
		||||
        if type_order == std::cmp::Ordering::Equal {
 | 
			
		||||
            a_id.cmp(b_id)
 | 
			
		||||
            a.backup_id.cmp(&b.backup_id)
 | 
			
		||||
        } else {
 | 
			
		||||
            type_order
 | 
			
		||||
        }
 | 
			
		||||
@ -318,13 +313,9 @@ pub async fn pull_store(
 | 
			
		||||
    let mut errors = false;
 | 
			
		||||
 | 
			
		||||
    for item in list {
 | 
			
		||||
 | 
			
		||||
        let id = item["backup-id"].as_str().unwrap();
 | 
			
		||||
        let btype = item["backup-type"].as_str().unwrap();
 | 
			
		||||
 | 
			
		||||
        let group = BackupGroup::new(btype, id);
 | 
			
		||||
        let group = BackupGroup::new(&item.backup_type, &item.backup_id);
 | 
			
		||||
        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;
 | 
			
		||||
            // continue
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -192,6 +192,40 @@ pub const PROXMOX_USER_ID_SCHEMA: Schema = StringSchema::new("User ID")
 | 
			
		||||
 | 
			
		||||
// 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(
 | 
			
		||||
    properties: {
 | 
			
		||||
        "backup-type": {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user