From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 97E591FF16B for ; Thu, 17 Oct 2024 15:28:10 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8B22710694; Thu, 17 Oct 2024 15:28:40 +0200 (CEST) From: Christian Ebner To: pbs-devel@lists.proxmox.com Date: Thu, 17 Oct 2024 15:26:57 +0200 Message-Id: <20241017132716.385234-13-c.ebner@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241017132716.385234-1-c.ebner@proxmox.com> References: <20241017132716.385234-1-c.ebner@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.025 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH v4 proxmox 12/31] api: sync jobs: expose optional `sync-direction` parameter 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: , Reply-To: Proxmox Backup Server development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" Exposes and switch the config type for sync job operations based on the `sync-direction` parameter. If not set, the default config type is `sync` and the default sync direction is `pull` for full backwards compatibility. Signed-off-by: Christian Ebner --- changes since version 3: - Use `SyncDirection` api type directly - Deduplicate code by iterating over sync direction enum variants src/api2/admin/sync.rs | 27 +++++++++------ src/api2/config/datastore.rs | 11 +++--- src/api2/config/notifications/mod.rs | 19 ++++++----- src/api2/config/sync.rs | 51 +++++++++++++++++++++++----- src/bin/proxmox-backup-proxy.rs | 11 ++++-- 5 files changed, 86 insertions(+), 33 deletions(-) diff --git a/src/api2/admin/sync.rs b/src/api2/admin/sync.rs index be324564c..c6b309859 100644 --- a/src/api2/admin/sync.rs +++ b/src/api2/admin/sync.rs @@ -29,6 +29,10 @@ use crate::{ schema: DATASTORE_SCHEMA, optional: true, }, + "sync-direction": { + type: SyncDirection, + optional: true, + }, }, }, returns: { @@ -44,6 +48,7 @@ use crate::{ /// List all sync jobs pub fn list_sync_jobs( store: Option, + sync_direction: Option, _param: Value, rpcenv: &mut dyn RpcEnvironment, ) -> Result, Error> { @@ -52,8 +57,9 @@ pub fn list_sync_jobs( let (config, digest) = sync::config()?; + let sync_direction = sync_direction.unwrap_or_default(); let job_config_iter = config - .convert_to_typed_array("sync")? + .convert_to_typed_array(sync_direction.as_config_type_str())? .into_iter() .filter(|job: &SyncJobConfig| { if let Some(store) = &store { @@ -88,7 +94,11 @@ pub fn list_sync_jobs( properties: { id: { schema: JOB_ID_SCHEMA, - } + }, + "sync-direction": { + type: SyncDirection, + optional: true, + }, } }, access: { @@ -99,6 +109,7 @@ pub fn list_sync_jobs( /// Runs the sync jobs manually. pub fn run_sync_job( id: String, + sync_direction: Option, _info: &ApiMethod, rpcenv: &mut dyn RpcEnvironment, ) -> Result { @@ -106,7 +117,8 @@ pub fn run_sync_job( let user_info = CachedUserInfo::new()?; let (config, _digest) = sync::config()?; - let sync_job: SyncJobConfig = config.lookup("sync", &id)?; + let sync_direction = sync_direction.unwrap_or_default(); + let sync_job: SyncJobConfig = config.lookup(sync_direction.as_config_type_str(), &id)?; if !check_sync_job_modify_access(&user_info, &auth_id, &sync_job) { bail!("permission check failed"); @@ -116,14 +128,7 @@ pub fn run_sync_job( let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI; - let upid_str = do_sync_job( - job, - sync_job, - &auth_id, - None, - SyncDirection::Pull, - to_stdout, - )?; + let upid_str = do_sync_job(job, sync_job, &auth_id, None, sync_direction, to_stdout)?; Ok(upid_str) } diff --git a/src/api2/config/datastore.rs b/src/api2/config/datastore.rs index ca6edf05a..e2d876555 100644 --- a/src/api2/config/datastore.rs +++ b/src/api2/config/datastore.rs @@ -13,8 +13,9 @@ use proxmox_uuid::Uuid; use pbs_api_types::{ Authid, DataStoreConfig, DataStoreConfigUpdater, DatastoreNotify, DatastoreTuning, KeepOptions, - MaintenanceMode, PruneJobConfig, PruneJobOptions, DATASTORE_SCHEMA, PRIV_DATASTORE_ALLOCATE, - PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_MODIFY, PROXMOX_CONFIG_DIGEST_SCHEMA, UPID_SCHEMA, + MaintenanceMode, PruneJobConfig, PruneJobOptions, SyncDirection, DATASTORE_SCHEMA, + PRIV_DATASTORE_ALLOCATE, PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_MODIFY, + PROXMOX_CONFIG_DIGEST_SCHEMA, UPID_SCHEMA, }; use pbs_config::BackupLockGuard; use pbs_datastore::chunk_store::ChunkStore; @@ -498,8 +499,10 @@ pub async fn delete_datastore( for job in list_verification_jobs(Some(name.clone()), Value::Null, rpcenv)? { delete_verification_job(job.config.id, None, rpcenv)? } - for job in list_sync_jobs(Some(name.clone()), Value::Null, rpcenv)? { - delete_sync_job(job.config.id, None, rpcenv)? + for direction in [SyncDirection::Pull, SyncDirection::Push] { + for job in list_sync_jobs(Some(name.clone()), Some(direction), Value::Null, rpcenv)? { + delete_sync_job(job.config.id, Some(direction), None, rpcenv)? + } } for job in list_prune_jobs(Some(name.clone()), Value::Null, rpcenv)? { delete_prune_job(job.config.id, None, rpcenv)? diff --git a/src/api2/config/notifications/mod.rs b/src/api2/config/notifications/mod.rs index dfe82ed03..31c4851c1 100644 --- a/src/api2/config/notifications/mod.rs +++ b/src/api2/config/notifications/mod.rs @@ -9,7 +9,7 @@ use proxmox_schema::api; use proxmox_sortable_macro::sortable; use crate::api2::admin::datastore::get_datastore_list; -use pbs_api_types::PRIV_SYS_AUDIT; +use pbs_api_types::{SyncDirection, PRIV_SYS_AUDIT}; use crate::api2::admin::prune::list_prune_jobs; use crate::api2::admin::sync::list_sync_jobs; @@ -154,13 +154,15 @@ pub fn get_values( }); } - let sync_jobs = list_sync_jobs(None, param.clone(), rpcenv)?; - for job in sync_jobs { - values.push(MatchableValue { - field: "job-id".into(), - value: job.config.id, - comment: job.config.comment, - }); + for direction in [SyncDirection::Pull, SyncDirection::Push] { + let sync_jobs = list_sync_jobs(None, Some(direction), param.clone(), rpcenv)?; + for job in sync_jobs { + values.push(MatchableValue { + field: "job-id".into(), + value: job.config.id, + comment: job.config.comment, + }); + } } let verify_jobs = list_verification_jobs(None, param.clone(), rpcenv)?; @@ -184,6 +186,7 @@ pub fn get_values( "package-updates", "prune", "sync", + "sync-push", "system-mail", "tape-backup", "tape-load", diff --git a/src/api2/config/sync.rs b/src/api2/config/sync.rs index 6fdc69a9e..b78267025 100644 --- a/src/api2/config/sync.rs +++ b/src/api2/config/sync.rs @@ -1,6 +1,7 @@ use ::serde::{Deserialize, Serialize}; use anyhow::{bail, Error}; use hex::FromHex; +use pbs_api_types::SyncDirection; use serde_json::Value; use proxmox_router::{http_bail, Permission, Router, RpcEnvironment}; @@ -77,7 +78,12 @@ pub fn check_sync_job_modify_access( #[api( input: { - properties: {}, + properties: { + "sync-direction": { + type: SyncDirection, + optional: true, + }, + }, }, returns: { description: "List configured jobs.", @@ -92,6 +98,7 @@ pub fn check_sync_job_modify_access( /// List all sync jobs pub fn list_sync_jobs( _param: Value, + sync_direction: Option, rpcenv: &mut dyn RpcEnvironment, ) -> Result, Error> { let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; @@ -99,7 +106,8 @@ pub fn list_sync_jobs( let (config, digest) = sync::config()?; - let list = config.convert_to_typed_array("sync")?; + let sync_direction = sync_direction.unwrap_or_default(); + let list = config.convert_to_typed_array(sync_direction.as_config_type_str())?; rpcenv["digest"] = hex::encode(digest).into(); @@ -118,6 +126,10 @@ pub fn list_sync_jobs( type: SyncJobConfig, flatten: true, }, + "sync-direction": { + type: SyncDirection, + optional: true, + }, }, }, access: { @@ -128,6 +140,7 @@ pub fn list_sync_jobs( /// Create a new sync job. pub fn create_sync_job( config: SyncJobConfig, + sync_direction: Option, rpcenv: &mut dyn RpcEnvironment, ) -> Result<(), Error> { let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; @@ -158,7 +171,8 @@ pub fn create_sync_job( param_bail!("id", "job '{}' already exists.", config.id); } - section_config.set_data(&config.id, "sync", &config)?; + let sync_direction = sync_direction.unwrap_or_default(); + section_config.set_data(&config.id, sync_direction.as_config_type_str(), &config)?; sync::save_config(§ion_config)?; @@ -173,6 +187,10 @@ pub fn create_sync_job( id: { schema: JOB_ID_SCHEMA, }, + "sync-direction": { + type: SyncDirection, + optional: true, + }, }, }, returns: { type: SyncJobConfig }, @@ -182,13 +200,18 @@ pub fn create_sync_job( }, )] /// Read a sync job configuration. -pub fn read_sync_job(id: String, rpcenv: &mut dyn RpcEnvironment) -> Result { +pub fn read_sync_job( + id: String, + sync_direction: Option, + rpcenv: &mut dyn RpcEnvironment, +) -> Result { let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; let user_info = CachedUserInfo::new()?; let (config, digest) = sync::config()?; - let sync_job = config.lookup("sync", &id)?; + let sync_direction = sync_direction.unwrap_or_default(); + let sync_job = config.lookup(sync_direction.as_config_type_str(), &id)?; if !check_sync_job_read_access(&user_info, &auth_id, &sync_job) { bail!("permission check failed"); } @@ -252,6 +275,10 @@ pub enum DeletableProperty { type: DeletableProperty, } }, + "sync-direction": { + type: SyncDirection, + optional: true, + }, digest: { optional: true, schema: PROXMOX_CONFIG_DIGEST_SCHEMA, @@ -269,6 +296,7 @@ pub fn update_sync_job( id: String, update: SyncJobConfigUpdater, delete: Option>, + sync_direction: Option, digest: Option, rpcenv: &mut dyn RpcEnvironment, ) -> Result<(), Error> { @@ -284,7 +312,8 @@ pub fn update_sync_job( crate::tools::detect_modified_configuration_file(&digest, &expected_digest)?; } - let mut data: SyncJobConfig = config.lookup("sync", &id)?; + let sync_direction = sync_direction.unwrap_or_default(); + let mut data: SyncJobConfig = config.lookup(sync_direction.as_config_type_str(), &id)?; if let Some(delete) = delete { for delete_prop in delete { @@ -409,7 +438,7 @@ pub fn update_sync_job( bail!("permission check failed"); } - config.set_data(&id, "sync", &data)?; + config.set_data(&id, sync_direction.as_config_type_str(), &data)?; sync::save_config(&config)?; @@ -427,6 +456,10 @@ pub fn update_sync_job( id: { schema: JOB_ID_SCHEMA, }, + "sync-direction": { + type: SyncDirection, + optional: true, + }, digest: { optional: true, schema: PROXMOX_CONFIG_DIGEST_SCHEMA, @@ -441,6 +474,7 @@ pub fn update_sync_job( /// Remove a sync job configuration pub fn delete_sync_job( id: String, + sync_direction: Option, digest: Option, rpcenv: &mut dyn RpcEnvironment, ) -> Result<(), Error> { @@ -456,7 +490,8 @@ pub fn delete_sync_job( crate::tools::detect_modified_configuration_file(&digest, &expected_digest)?; } - match config.lookup("sync", &id) { + let sync_direction = sync_direction.unwrap_or_default(); + match config.lookup(sync_direction.as_config_type_str(), &id) { Ok(job) => { if !check_sync_job_modify_access(&user_info, &auth_id, &job) { bail!("permission check failed"); diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs index 6f19a3fbd..70283510d 100644 --- a/src/bin/proxmox-backup-proxy.rs +++ b/src/bin/proxmox-backup-proxy.rs @@ -589,7 +589,14 @@ async fn schedule_datastore_sync_jobs() { Ok((config, _digest)) => config, }; - for (job_id, (_, job_config)) in config.sections { + for (job_id, (job_type, job_config)) in config.sections { + let sync_direction = match SyncDirection::from_config_type_str(&job_type) { + Ok(direction) => direction, + Err(err) => { + eprintln!("unexpected config type in sync job config - {err}"); + continue; + } + }; let job_config: SyncJobConfig = match serde_json::from_value(job_config) { Ok(c) => c, Err(err) => { @@ -616,7 +623,7 @@ async fn schedule_datastore_sync_jobs() { job_config, &auth_id, Some(event_str), - SyncDirection::Pull, + sync_direction, false, ) { eprintln!("unable to start datastore sync job {job_id} - {err}"); -- 2.39.5 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel