diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs index 05c7a58c..9befcaae 100644 --- a/src/api2/admin/datastore.rs +++ b/src/api2/admin/datastore.rs @@ -214,6 +214,11 @@ fn prune( let store = param["store"].as_str().unwrap(); + let backup_type = tools::required_string_param(¶m, "backup-type")?; + let backup_id = tools::required_string_param(¶m, "backup-id")?; + + let group = BackupGroup::new(backup_type, backup_id); + let datastore = DataStore::lookup_datastore(store)?; let mut keep_all = true; @@ -228,61 +233,56 @@ fn prune( let worker = WorkerTask::new("prune", Some(store.to_owned()), "root@pam", true)?; let result = try_block! { if keep_all { - worker.log("No selection - keeping all files."); + worker.log("No prune selection - keeping all files."); return Ok(()); } else { worker.log(format!("Starting prune on store {}", store)); } - let backup_list = BackupInfo::list_backups(&datastore.base_path())?; + let mut list = group.list_backups(&datastore.base_path())?; - let group_hash = group_backups(backup_list); + let mut mark = HashSet::new(); - for (_group_id, mut list) in group_hash { + BackupInfo::sort_list(&mut list, false); - let mut mark = HashSet::new(); + if let Some(keep_last) = param["keep-last"].as_u64() { + list.iter().take(keep_last as usize).for_each(|info| { + mark.insert(info.backup_dir.relative_path()); + }); + } - BackupInfo::sort_list(&mut list, false); + if let Some(keep_daily) = param["keep-daily"].as_u64() { + mark_selections(&mut mark, &list, keep_daily as usize, |local_time, _info| { + format!("{}/{}/{}", local_time.year(), local_time.month(), local_time.day()) + }); + } - if let Some(keep_last) = param["keep-last"].as_u64() { - list.iter().take(keep_last as usize).for_each(|info| { - mark.insert(info.backup_dir.relative_path()); - }); - } + if let Some(keep_weekly) = param["keep-weekly"].as_u64() { + mark_selections(&mut mark, &list, keep_weekly as usize, |local_time, _info| { + format!("{}/{}", local_time.year(), local_time.iso_week().week()) + }); + } - if let Some(keep_daily) = param["keep-daily"].as_u64() { - mark_selections(&mut mark, &list, keep_daily as usize, |local_time, _info| { - format!("{}/{}/{}", local_time.year(), local_time.month(), local_time.day()) - }); - } + if let Some(keep_monthly) = param["keep-monthly"].as_u64() { + mark_selections(&mut mark, &list, keep_monthly as usize, |local_time, _info| { + format!("{}/{}", local_time.year(), local_time.month()) + }); + } - if let Some(keep_weekly) = param["keep-weekly"].as_u64() { - mark_selections(&mut mark, &list, keep_weekly as usize, |local_time, _info| { - format!("{}/{}", local_time.year(), local_time.iso_week().week()) - }); - } + if let Some(keep_yearly) = param["keep-yearly"].as_u64() { + mark_selections(&mut mark, &list, keep_yearly as usize, |local_time, _info| { + format!("{}/{}", local_time.year(), local_time.year()) + }); + } - if let Some(keep_monthly) = param["keep-monthly"].as_u64() { - mark_selections(&mut mark, &list, keep_monthly as usize, |local_time, _info| { - format!("{}/{}", local_time.year(), local_time.month()) - }); - } + let mut remove_list: Vec = list.into_iter() + .filter(|info| !mark.contains(&info.backup_dir.relative_path())).collect(); - if let Some(keep_yearly) = param["keep-yearly"].as_u64() { - mark_selections(&mut mark, &list, keep_yearly as usize, |local_time, _info| { - format!("{}/{}", local_time.year(), local_time.year()) - }); - } + BackupInfo::sort_list(&mut remove_list, true); - let mut remove_list: Vec = list.into_iter() - .filter(|info| !mark.contains(&info.backup_dir.relative_path())).collect(); - - BackupInfo::sort_list(&mut remove_list, true); - - for info in remove_list { - worker.log(format!("remove {:?}", info.backup_dir)); - datastore.remove_backup_dir(&info.backup_dir)?; - } + for info in remove_list { + worker.log(format!("remove {:?}", info.backup_dir)); + datastore.remove_backup_dir(&info.backup_dir)?; } Ok(()) @@ -336,6 +336,8 @@ fn api_method_prune() -> ApiMethod { "store", StringSchema::new("Datastore name.") ) + .required("backup-type", BACKUP_TYPE_SCHEMA.clone()) + .required("backup-id", BACKUP_ID_SCHEMA.clone()) ) ) } diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index 1ac40a16..50077260 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -840,7 +840,7 @@ fn upload_log( } fn prune( - mut param: Value, + param: Value, _info: &ApiMethod, _rpcenv: &mut dyn RpcEnvironment, ) -> Result { @@ -851,9 +851,14 @@ fn prune( let path = format!("api2/json/admin/datastore/{}/prune", repo.store()); - param.as_object_mut().unwrap().remove("repository"); + let group = tools::required_string_param(¶m, "group")?; + let group = BackupGroup::parse(group)?; - let result = client.post(&path, Some(param)).wait()?; + let mut args = json!({}); + args["backup-type"] = group.backup_type().into(); + args["backup-id"] = group.backup_id().into(); + + let result = client.post(&path, Some(args)).wait()?; record_repository(&repo); @@ -1440,9 +1445,12 @@ We do not extraxt '.pxar' archives when writing to stdandard output. prune, proxmox_backup::api2::admin::datastore::add_common_prune_prameters( ObjectSchema::new("Prune backup repository.") + .required("group", StringSchema::new("Backup group.")) .optional("repository", REPO_URL_SCHEMA.clone()) ) )) + .arg_param(vec!["group"]) + .completion_cb("group", complete_backup_group) .completion_cb("repository", complete_repository); let status_cmd_def = CliCommand::new(