From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 729CBD3C3 for ; Wed, 30 Nov 2022 16:01:29 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 569002018E for ; Wed, 30 Nov 2022 16:01:29 +0100 (CET) Received: from lana.proxmox.com (unknown [94.136.29.99]) by firstgate.proxmox.com (Proxmox) with ESMTP for ; Wed, 30 Nov 2022 16:01:26 +0100 (CET) Received: by lana.proxmox.com (Postfix, from userid 10043) id C0C3F2C2780; Wed, 30 Nov 2022 16:01:26 +0100 (CET) From: Stefan Hanreich To: pbs-devel@lists.proxmox.com Date: Wed, 30 Nov 2022 16:00:56 +0100 Message-Id: <20221130150102.242374-2-s.hanreich@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221130150102.242374-1-s.hanreich@proxmox.com> References: <20221130150102.242374-1-s.hanreich@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.312 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods NO_DNS_FOR_FROM 0.001 Envelope sender has no MX or A DNS records RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pbs-devel] [PATCH proxmox-backup v2 1/7] Add KeepOptions parameters to pull & sync-job X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Nov 2022 15:01:29 -0000 Do nothing with this information for now, just prepare the API and client to accept the parameters so we can handle them in a later commit. Signed-off-by: Stefan Hanreich --- pbs-api-types/src/jobs.rs | 7 ++++- src/api2/config/sync.rs | 52 +++++++++++++++++++++++++++++++ src/api2/pull.rs | 13 ++++++-- src/bin/proxmox-backup-manager.rs | 17 ++++++++-- src/server/pull.rs | 8 +++-- 5 files changed, 89 insertions(+), 8 deletions(-) diff --git a/pbs-api-types/src/jobs.rs b/pbs-api-types/src/jobs.rs index 7f029af7..c778039c 100644 --- a/pbs-api-types/src/jobs.rs +++ b/pbs-api-types/src/jobs.rs @@ -474,6 +474,9 @@ pub const GROUP_FILTER_LIST_SCHEMA: Schema = limit: { type: RateLimitConfig, }, + keep: { + type: KeepOptions, + }, schedule: { optional: true, schema: SYNC_SCHEDULE_SCHEMA, @@ -511,6 +514,8 @@ pub struct SyncJobConfig { pub group_filter: Option>, #[serde(flatten)] pub limit: RateLimitConfig, + #[serde(flatten)] + pub keep: KeepOptions, } impl SyncJobConfig { @@ -572,7 +577,7 @@ pub struct SyncJobStatus { }, } )] -#[derive(Serialize, Deserialize, Default, Updater)] +#[derive(Serialize, Deserialize, Default, Updater, Clone)] #[serde(rename_all = "kebab-case")] /// Common pruning options pub struct KeepOptions { diff --git a/src/api2/config/sync.rs b/src/api2/config/sync.rs index 6f39b239..cafbf102 100644 --- a/src/api2/config/sync.rs +++ b/src/api2/config/sync.rs @@ -216,6 +216,18 @@ pub enum DeletableProperty { remote_ns, /// Delete the max_depth property, max_depth, + /// Delete keep_last prune option. + keep_last, + /// Delete keep_hourly prune option. + keep_hourly, + /// Delete keep_daily prune option. + keep_daily, + /// Delete keep_weekly prune option. + keep_weekly, + /// Delete keep_monthly prune option. + keep_monthly, + /// Delete keep_yearly prune option. + keep_yearly, } #[api( @@ -310,6 +322,24 @@ pub fn update_sync_job( DeletableProperty::max_depth => { data.max_depth = None; } + DeletableProperty::keep_last => { + data.keep.keep_last = None; + } + DeletableProperty::keep_hourly => { + data.keep.keep_hourly = None; + } + DeletableProperty::keep_daily => { + data.keep.keep_daily = None; + } + DeletableProperty::keep_weekly => { + data.keep.keep_weekly = None; + } + DeletableProperty::keep_monthly => { + data.keep.keep_monthly = None; + } + DeletableProperty::keep_yearly => { + data.keep.keep_yearly = None; + } } } } @@ -381,6 +411,25 @@ pub fn update_sync_job( } } + if update.keep.keep_last.is_some() { + data.keep.keep_last = update.keep.keep_last; + } + if update.keep.keep_hourly.is_some() { + data.keep.keep_hourly = update.keep.keep_hourly; + } + if update.keep.keep_daily.is_some() { + data.keep.keep_daily = update.keep.keep_daily; + } + if update.keep.keep_weekly.is_some() { + data.keep.keep_weekly = update.keep.keep_weekly; + } + if update.keep.keep_monthly.is_some() { + data.keep.keep_monthly = update.keep.keep_monthly; + } + if update.keep.keep_yearly.is_some() { + data.keep.keep_yearly = update.keep.keep_yearly; + } + if !check_sync_job_modify_access(&user_info, &auth_id, &data) { bail!("permission check failed"); } @@ -463,6 +512,8 @@ pub const ROUTER: Router = Router::new() #[test] fn sync_job_access_test() -> Result<(), Error> { + use pbs_api_types::KeepOptions; + let (user_cfg, _) = pbs_config::user::test_cfg_from_str( r###" user: noperm@pbs @@ -508,6 +559,7 @@ acl:1:/remote/remote1/remotestore1:write@pbs:RemoteSyncOperator group_filter: None, schedule: None, limit: pbs_api_types::RateLimitConfig::default(), // no limit + keep: KeepOptions::default(), }; // should work without ACLs diff --git a/src/api2/pull.rs b/src/api2/pull.rs index 193f28fe..f3b31e05 100644 --- a/src/api2/pull.rs +++ b/src/api2/pull.rs @@ -9,8 +9,8 @@ use proxmox_schema::api; use proxmox_sys::task_log; use pbs_api_types::{ - Authid, BackupNamespace, GroupFilter, RateLimitConfig, SyncJobConfig, DATASTORE_SCHEMA, - GROUP_FILTER_LIST_SCHEMA, NS_MAX_DEPTH_REDUCED_SCHEMA, PRIV_DATASTORE_BACKUP, + Authid, BackupNamespace, GroupFilter, KeepOptions, RateLimitConfig, SyncJobConfig, + DATASTORE_SCHEMA, GROUP_FILTER_LIST_SCHEMA, NS_MAX_DEPTH_REDUCED_SCHEMA, PRIV_DATASTORE_BACKUP, PRIV_DATASTORE_PRUNE, PRIV_REMOTE_READ, REMOTE_ID_SCHEMA, REMOVE_VANISHED_BACKUPS_SCHEMA, }; use pbs_config::CachedUserInfo; @@ -78,6 +78,7 @@ impl TryFrom<&SyncJobConfig> for PullParameters { sync_job.max_depth, sync_job.group_filter.clone(), sync_job.limit.clone(), + sync_job.keep.clone(), ) } } @@ -203,7 +204,11 @@ pub fn do_sync_job( limit: { type: RateLimitConfig, flatten: true, - } + }, + "keep-options": { + type: KeepOptions, + flatten: true, + }, }, }, access: { @@ -227,6 +232,7 @@ async fn pull( max_depth: Option, group_filter: Option>, limit: RateLimitConfig, + keep_options: KeepOptions, rpcenv: &mut dyn RpcEnvironment, ) -> Result { let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; @@ -259,6 +265,7 @@ async fn pull( max_depth, group_filter, limit, + keep_options, )?; let client = pull_params.client().await?; diff --git a/src/bin/proxmox-backup-manager.rs b/src/bin/proxmox-backup-manager.rs index 06330c78..0d6680b2 100644 --- a/src/bin/proxmox-backup-manager.rs +++ b/src/bin/proxmox-backup-manager.rs @@ -11,7 +11,7 @@ use proxmox_sys::fs::CreateOptions; use pbs_api_types::percent_encoding::percent_encode_component; use pbs_api_types::{ - BackupNamespace, GroupFilter, RateLimitConfig, SyncJobConfig, DATASTORE_SCHEMA, + BackupNamespace, GroupFilter, KeepOptions, RateLimitConfig, SyncJobConfig, DATASTORE_SCHEMA, GROUP_FILTER_LIST_SCHEMA, IGNORE_VERIFIED_BACKUPS_SCHEMA, NS_MAX_DEPTH_SCHEMA, REMOTE_ID_SCHEMA, REMOVE_VANISHED_BACKUPS_SCHEMA, UPID_SCHEMA, VERIFICATION_OUTDATED_AFTER_SCHEMA, @@ -268,6 +268,10 @@ fn task_mgmt_cli() -> CommandLineInterface { type: RateLimitConfig, flatten: true, }, + "keep-options": { + type: KeepOptions, + flatten: true, + }, "output-format": { schema: OUTPUT_FORMAT, optional: true, @@ -287,6 +291,7 @@ async fn pull_datastore( max_depth: Option, group_filter: Option>, limit: RateLimitConfig, + keep_options: KeepOptions, param: Value, ) -> Result { let output_format = get_output_format(¶m); @@ -324,7 +329,15 @@ async fn pull_datastore( .as_object_mut() .ok_or_else(|| format_err!("limit is not an Object"))?; - args.as_object_mut().unwrap().append(limit_map); + let mut keep_json = json!(keep_options); + let keep_map = keep_json + .as_object_mut() + .ok_or_else(|| format_err!("keep_options is not an Object"))?; + + let args_map = args.as_object_mut().unwrap(); + + args_map.append(limit_map); + args_map.append(keep_map); let result = client.post("api2/json/pull", Some(args)).await?; diff --git a/src/server/pull.rs b/src/server/pull.rs index 77caf327..634a0b70 100644 --- a/src/server/pull.rs +++ b/src/server/pull.rs @@ -16,8 +16,8 @@ use proxmox_router::HttpError; use proxmox_sys::task_log; use pbs_api_types::{ - print_store_and_ns, Authid, BackupNamespace, GroupFilter, GroupListItem, NamespaceListItem, - Operation, RateLimitConfig, Remote, SnapshotListItem, MAX_NAMESPACE_DEPTH, + print_store_and_ns, Authid, BackupNamespace, GroupFilter, GroupListItem, KeepOptions, + NamespaceListItem, Operation, RateLimitConfig, Remote, SnapshotListItem, MAX_NAMESPACE_DEPTH, PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP, }; @@ -60,6 +60,8 @@ pub(crate) struct PullParameters { group_filter: Option>, /// Rate limits for all transfers from `remote` limit: RateLimitConfig, + /// Options for pruning after pulling + keep_options: KeepOptions, } impl PullParameters { @@ -79,6 +81,7 @@ impl PullParameters { max_depth: Option, group_filter: Option>, limit: RateLimitConfig, + keep_options: KeepOptions, ) -> Result { let store = DataStore::lookup_datastore(store, Some(Operation::Write))?; @@ -110,6 +113,7 @@ impl PullParameters { max_depth, group_filter, limit, + keep_options, }) } -- 2.30.2