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 331DD1FF179 for ; Thu, 22 Jan 2026 16:11:25 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 17D2E19C79; Thu, 22 Jan 2026 16:11:44 +0100 (CET) From: Christian Ebner To: pbs-devel@lists.proxmox.com Date: Thu, 22 Jan 2026 16:11:24 +0100 Message-ID: <20260122151125.832787-6-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260122151125.832787-1-c.ebner@proxmox.com> References: <20260122151125.832787-1-c.ebner@proxmox.com> MIME-Version: 1.0 X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1769094638847 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.048 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 proxmox-backup 3/4] datastore: refactor datastore lookup parameters into dedicated type 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" This will allow to easily extend the lookup by a callback method to allow lookup of the nodes proxy config whenever that is required for the backend implementation. Move this to a central helper so individual DataStore::lookup_datastore() calls do not need to individually set common future parameters. Signed-off-by: Christian Ebner --- pbs-datastore/src/datastore.rs | 36 ++++++++++++++++++---------- pbs-datastore/src/lib.rs | 2 +- pbs-datastore/src/snapshot_reader.rs | 6 +++-- src/api2/admin/datastore.rs | 26 ++++++++++---------- src/api2/admin/namespace.rs | 9 ++++--- src/api2/backup/mod.rs | 3 ++- src/api2/reader/mod.rs | 3 ++- src/api2/status/mod.rs | 6 +++-- src/api2/tape/backup.rs | 6 +++-- src/api2/tape/restore.rs | 6 +++-- src/bin/proxmox-backup-proxy.rs | 8 ++++--- src/server/prune_job.rs | 3 ++- src/server/pull.rs | 7 ++++-- src/server/push.rs | 3 ++- src/server/verify_job.rs | 3 ++- src/tools/mod.rs | 10 +++++++- 16 files changed, 90 insertions(+), 47 deletions(-) diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs index b77567e51..6fa533e2f 100644 --- a/pbs-datastore/src/datastore.rs +++ b/pbs-datastore/src/datastore.rs @@ -195,6 +195,17 @@ impl DataStoreImpl { } } +pub struct DataStoreLookup<'a> { + name: &'a str, + operation: Operation, +} + +impl<'a> DataStoreLookup<'a> { + pub fn with(name: &'a str, operation: Operation) -> Self { + Self { name, operation } + } +} + pub struct DataStore { inner: Arc, operation: Option, @@ -464,18 +475,18 @@ impl DataStore { Ok(()) } - pub fn lookup_datastore(name: &str, operation: Operation) -> Result, Error> { + pub fn lookup_datastore(lookup: DataStoreLookup) -> Result, Error> { // Avoid TOCTOU between checking maintenance mode and updating active operation counter, as // we use it to decide whether it is okay to delete the datastore. let _config_lock = pbs_config::datastore::lock_config()?; // Get the current datastore.cfg generation number and cached config let (section_config, gen_num) = datastore_section_config_cached(true)?; - let config: DataStoreConfig = section_config.lookup("datastore", name)?; + let config: DataStoreConfig = section_config.lookup("datastore", lookup.name)?; if let Some(maintenance_mode) = config.get_maintenance_mode() { - if let Err(error) = maintenance_mode.check(operation) { - bail!("datastore '{name}' is unavailable: {error}"); + if let Err(error) = maintenance_mode.check(lookup.operation) { + bail!("datastore '{}' is unavailable: {error}", lookup.name); } } @@ -486,16 +497,16 @@ impl DataStore { bail!("datastore '{}' is not mounted", config.name); } - let entry = datastore_cache.get(name); + let entry = datastore_cache.get(lookup.name); // reuse chunk store so that we keep using the same process locker instance! let chunk_store = if let Some(datastore) = &entry { // Re-use DataStoreImpl if datastore.config_generation == gen_num && gen_num.is_some() { - update_active_operations(name, operation, 1)?; + update_active_operations(lookup.name, lookup.operation, 1)?; return Ok(Arc::new(Self { inner: Arc::clone(datastore), - operation: Some(operation), + operation: Some(lookup.operation), })); } Arc::clone(&datastore.chunk_store) @@ -505,7 +516,7 @@ impl DataStore { .parse_property_string(config.tuning.as_deref().unwrap_or(""))?, )?; Arc::new(ChunkStore::open( - name, + lookup.name, config.absolute_path(), tuning.sync_level.unwrap_or_default(), )?) @@ -514,13 +525,13 @@ impl DataStore { let datastore = DataStore::with_store_and_config(chunk_store, config, gen_num)?; let datastore = Arc::new(datastore); - datastore_cache.insert(name.to_string(), datastore.clone()); + datastore_cache.insert(lookup.name.to_string(), datastore.clone()); - update_active_operations(name, operation, 1)?; + update_active_operations(lookup.name, lookup.operation, 1)?; Ok(Arc::new(Self { inner: datastore, - operation: Some(operation), + operation: Some(lookup.operation), })) } @@ -546,7 +557,8 @@ impl DataStore { { // the datastore drop handler does the checking if tasks are running and clears the // cache entry, so we just have to trigger it here - let _ = DataStore::lookup_datastore(name, Operation::Lookup); + let lookup = DataStoreLookup::with(name, Operation::Lookup); + let _ = DataStore::lookup_datastore(lookup); } Ok(()) diff --git a/pbs-datastore/src/lib.rs b/pbs-datastore/src/lib.rs index 1f7c54ae8..8770a09ca 100644 --- a/pbs-datastore/src/lib.rs +++ b/pbs-datastore/src/lib.rs @@ -217,7 +217,7 @@ pub use store_progress::StoreProgress; mod datastore; pub use datastore::{ check_backup_owner, ensure_datastore_is_mounted, get_datastore_mount_status, DataStore, - DatastoreBackend, S3_DATASTORE_IN_USE_MARKER, + DataStoreLookup, DatastoreBackend, S3_DATASTORE_IN_USE_MARKER, }; mod hierarchy; diff --git a/pbs-datastore/src/snapshot_reader.rs b/pbs-datastore/src/snapshot_reader.rs index 231b1f493..d522a02d7 100644 --- a/pbs-datastore/src/snapshot_reader.rs +++ b/pbs-datastore/src/snapshot_reader.rs @@ -16,6 +16,7 @@ use pbs_api_types::{ }; use crate::backup_info::BackupDir; +use crate::datastore::DataStoreLookup; use crate::dynamic_index::DynamicIndexReader; use crate::fixed_index::FixedIndexReader; use crate::index::IndexFile; @@ -162,10 +163,11 @@ impl bool> Iterator for SnapshotChunkIterator<'_, F> { ), }; - let datastore = DataStore::lookup_datastore( + let lookup = DataStoreLookup::with( self.snapshot_reader.datastore_name(), Operation::Read, - )?; + ); + let datastore = DataStore::lookup_datastore(lookup)?; let order = datastore.get_chunks_in_order(&*index, &self.skip_fn, |_| Ok(()))?; diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs index a307e1488..f5bd3f0f4 100644 --- a/src/api2/admin/datastore.rs +++ b/src/api2/admin/datastore.rs @@ -71,7 +71,9 @@ use crate::api2::backup::optional_ns_param; use crate::api2::node::rrd::create_value_from_rrd; use crate::backup::{check_ns_privs_full, ListAccessibleBackupGroups, VerifyWorker, NS_PRIVS_OK}; use crate::server::jobstate::{compute_schedule_status, Job, JobState}; -use crate::tools::{backup_info_to_snapshot_list_item, get_all_snapshot_files, read_backup_index}; +use crate::tools::{ + backup_info_to_snapshot_list_item, get_all_snapshot_files, lookup_with, read_backup_index, +}; // helper to unify common sequence of checks: // 1. check privs on NS (full or limited access) @@ -88,7 +90,7 @@ fn check_privs_and_load_store( ) -> Result, Error> { let limited = check_ns_privs_full(store, ns, auth_id, full_access_privs, partial_access_privs)?; - let datastore = DataStore::lookup_datastore(store, operation)?; + let datastore = DataStore::lookup_datastore(lookup_with(store, operation))?; if limited { let owner = datastore.get_owner(ns, backup_group)?; @@ -134,7 +136,7 @@ pub fn list_groups( PRIV_DATASTORE_BACKUP, )?; - let datastore = DataStore::lookup_datastore(&store, Operation::Read)?; + let datastore = DataStore::lookup_datastore(lookup_with(&store, Operation::Read))?; datastore .iter_backup_groups(ns.clone())? // FIXME: Namespaces and recursion parameters! @@ -467,7 +469,7 @@ unsafe fn list_snapshots_blocking( PRIV_DATASTORE_BACKUP, )?; - let datastore = DataStore::lookup_datastore(&store, Operation::Read)?; + let datastore = DataStore::lookup_datastore(lookup_with(&store, Operation::Read))?; // FIXME: filter also owner before collecting, for doing that nicely the owner should move into // backup group and provide an error free (Err -> None) accessor @@ -601,7 +603,7 @@ pub async fn status( } }; - let datastore = DataStore::lookup_datastore(&store, Operation::Read)?; + let datastore = DataStore::lookup_datastore(lookup_with(&store, Operation::Read))?; let (counts, gc_status) = if verbose { let filter_owner = if store_privs & PRIV_DATASTORE_AUDIT != 0 { @@ -724,7 +726,7 @@ pub fn verify( PRIV_DATASTORE_BACKUP, )?; - let datastore = DataStore::lookup_datastore(&store, Operation::Read)?; + let datastore = DataStore::lookup_datastore(lookup_with(&store, Operation::Read))?; let ignore_verified = ignore_verified.unwrap_or(true); let worker_id; @@ -1076,7 +1078,7 @@ pub fn prune_datastore( true, )?; - let datastore = DataStore::lookup_datastore(&store, Operation::Write)?; + let datastore = DataStore::lookup_datastore(lookup_with(&store, Operation::Write))?; let ns = prune_options.ns.clone().unwrap_or_default(); let worker_id = format!("{store}:{ns}"); @@ -1114,7 +1116,7 @@ pub fn start_garbage_collection( _info: &ApiMethod, rpcenv: &mut dyn RpcEnvironment, ) -> Result { - let datastore = DataStore::lookup_datastore(&store, Operation::Write)?; + let datastore = DataStore::lookup_datastore(lookup_with(&store, Operation::Write))?; let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; let job = Job::new("garbage_collection", &store) @@ -1161,7 +1163,7 @@ pub fn garbage_collection_status( ..Default::default() }; - let datastore = DataStore::lookup_datastore(&store, Operation::Read)?; + let datastore = DataStore::lookup_datastore(lookup_with(&store, Operation::Read))?; let status_in_memory = datastore.last_gc_status(); let state_file = JobState::load("garbage_collection", &store) .map_err(|err| log::error!("could not open GC statefile for {store}: {err}")) @@ -1873,7 +1875,7 @@ pub fn get_rrd_stats( cf: RrdMode, _param: Value, ) -> Result { - let datastore = DataStore::lookup_datastore(&store, Operation::Read)?; + let datastore = DataStore::lookup_datastore(lookup_with(&store, Operation::Read))?; let disk_manager = crate::tools::disks::DiskManage::new(); let mut rrd_fields = vec![ @@ -2249,7 +2251,7 @@ pub async fn set_backup_owner( PRIV_DATASTORE_BACKUP, )?; - let datastore = DataStore::lookup_datastore(&store, Operation::Write)?; + let datastore = DataStore::lookup_datastore(lookup_with(&store, Operation::Write))?; let backup_group = datastore.backup_group(ns, backup_group); let owner = backup_group.get_owner()?; @@ -2734,7 +2736,7 @@ pub fn s3_refresh(store: String, rpcenv: &mut dyn RpcEnvironment) -> Result Result<(), Error> { - let datastore = DataStore::lookup_datastore(store, Operation::Lookup)?; + let datastore = DataStore::lookup_datastore(lookup_with(store, Operation::Lookup))?; run_maintenance_locked(store, MaintenanceType::S3Refresh, worker, || { proxmox_async::runtime::block_on(datastore.s3_refresh()) }) diff --git a/src/api2/admin/namespace.rs b/src/api2/admin/namespace.rs index 30e24d8db..c885ab540 100644 --- a/src/api2/admin/namespace.rs +++ b/src/api2/admin/namespace.rs @@ -54,7 +54,8 @@ pub fn create_namespace( check_ns_modification_privs(&store, &ns, &auth_id)?; - let datastore = DataStore::lookup_datastore(&store, Operation::Write)?; + let lookup = crate::tools::lookup_with(&store, Operation::Write); + let datastore = DataStore::lookup_datastore(lookup)?; datastore.create_namespace(&parent, name) } @@ -97,7 +98,8 @@ pub fn list_namespaces( // get result up-front to avoid cloning NS, it's relatively cheap anyway (no IO normally) let parent_access = check_ns_privs(&store, &parent, &auth_id, NS_PRIVS_OK); - let datastore = DataStore::lookup_datastore(&store, Operation::Read)?; + let lookup = crate::tools::lookup_with(&store, Operation::Read); + let datastore = DataStore::lookup_datastore(lookup)?; let iter = match datastore.recursive_iter_backup_ns_ok(parent, max_depth) { Ok(iter) => iter, @@ -162,7 +164,8 @@ pub fn delete_namespace( check_ns_modification_privs(&store, &ns, &auth_id)?; - let datastore = DataStore::lookup_datastore(&store, Operation::Write)?; + let lookup = crate::tools::lookup_with(&store, Operation::Write); + let datastore = DataStore::lookup_datastore(lookup)?; let (removed_all, stats) = datastore.remove_namespace_recursive(&ns, delete_groups)?; if !removed_all { diff --git a/src/api2/backup/mod.rs b/src/api2/backup/mod.rs index 946510e85..6708f3da3 100644 --- a/src/api2/backup/mod.rs +++ b/src/api2/backup/mod.rs @@ -99,7 +99,8 @@ fn upgrade_to_backup_protocol( ) .map_err(|err| http_err!(FORBIDDEN, "{err}"))?; - let datastore = DataStore::lookup_datastore(&store, Operation::Write)?; + let lookup = crate::tools::lookup_with(&store, Operation::Write); + let datastore = DataStore::lookup_datastore(lookup)?; let protocols = parts .headers diff --git a/src/api2/reader/mod.rs b/src/api2/reader/mod.rs index 9262eb6cb..a814ba5f7 100644 --- a/src/api2/reader/mod.rs +++ b/src/api2/reader/mod.rs @@ -96,7 +96,8 @@ fn upgrade_to_backup_reader_protocol( bail!("no permissions on /{}", acl_path.join("/")); } - let datastore = DataStore::lookup_datastore(&store, Operation::Read)?; + let lookup = crate::tools::lookup_with(&store, Operation::Read); + let datastore = DataStore::lookup_datastore(lookup)?; let backup_dir = pbs_api_types::BackupDir::deserialize(¶m)?; diff --git a/src/api2/status/mod.rs b/src/api2/status/mod.rs index 885fdb0cc..43bb95d19 100644 --- a/src/api2/status/mod.rs +++ b/src/api2/status/mod.rs @@ -69,7 +69,8 @@ pub async fn datastore_status( }; if !allowed { - if let Ok(datastore) = DataStore::lookup_datastore(store, Operation::Lookup) { + let lookup = crate::tools::lookup_with(store, Operation::Lookup); + if let Ok(datastore) = DataStore::lookup_datastore(lookup) { if can_access_any_namespace(datastore, &auth_id, &user_info) { list.push(DataStoreStatusListItem::empty(store, None, mount_status)); } @@ -77,7 +78,8 @@ pub async fn datastore_status( continue; } - let datastore = match DataStore::lookup_datastore(store, Operation::Read) { + let lookup = crate::tools::lookup_with(store, Operation::Read); + let datastore = match DataStore::lookup_datastore(lookup) { Ok(datastore) => datastore, Err(err) => { list.push(DataStoreStatusListItem::empty( diff --git a/src/api2/tape/backup.rs b/src/api2/tape/backup.rs index 47e8d0209..c254c6d8b 100644 --- a/src/api2/tape/backup.rs +++ b/src/api2/tape/backup.rs @@ -152,7 +152,8 @@ pub fn do_tape_backup_job( let worker_type = job.jobtype().to_string(); - let datastore = DataStore::lookup_datastore(&setup.store, Operation::Read)?; + let lookup = crate::tools::lookup_with(&setup.store, Operation::Read); + let datastore = DataStore::lookup_datastore(lookup)?; let (config, _digest) = pbs_config::media_pool::config()?; let pool_config: MediaPoolConfig = config.lookup("pool", &setup.pool)?; @@ -310,7 +311,8 @@ pub fn backup( check_backup_permission(&auth_id, &setup.store, &setup.pool, &setup.drive)?; - let datastore = DataStore::lookup_datastore(&setup.store, Operation::Read)?; + let lookup = crate::tools::lookup_with(&setup.store, Operation::Read); + let datastore = DataStore::lookup_datastore(lookup)?; let (config, _digest) = pbs_config::media_pool::config()?; let pool_config: MediaPoolConfig = config.lookup("pool", &setup.pool)?; diff --git a/src/api2/tape/restore.rs b/src/api2/tape/restore.rs index 92529a76d..4356cf748 100644 --- a/src/api2/tape/restore.rs +++ b/src/api2/tape/restore.rs @@ -144,10 +144,12 @@ impl TryFrom for DataStoreMap { if let Some(index) = store.find('=') { let mut target = store.split_off(index); target.remove(0); // remove '=' - let datastore = DataStore::lookup_datastore(&target, Operation::Write)?; + let lookup = crate::tools::lookup_with(&target, Operation::Write); + let datastore = DataStore::lookup_datastore(lookup)?; map.insert(store, datastore); } else if default.is_none() { - default = Some(DataStore::lookup_datastore(&store, Operation::Write)?); + let lookup = crate::tools::lookup_with(&store, Operation::Write); + default = Some(DataStore::lookup_datastore(lookup)?); } else { bail!("multiple default stores given"); } diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs index 3be8e8dcf..3014d3092 100644 --- a/src/bin/proxmox-backup-proxy.rs +++ b/src/bin/proxmox-backup-proxy.rs @@ -47,7 +47,7 @@ use pbs_api_types::{ use proxmox_backup::auth_helpers::*; use proxmox_backup::config; use proxmox_backup::server::{self, metric_collection}; -use proxmox_backup::tools::PROXMOX_BACKUP_TCP_KEEPALIVE_TIME; +use proxmox_backup::tools::{lookup_with, PROXMOX_BACKUP_TCP_KEEPALIVE_TIME}; use proxmox_backup::api2::tape::backup::do_tape_backup_job; use proxmox_backup::server::do_prune_job; @@ -530,7 +530,8 @@ async fn schedule_datastore_garbage_collection() { { // limit datastore scope due to Op::Lookup - let datastore = match DataStore::lookup_datastore(&store, Operation::Lookup) { + let lookup = lookup_with(&store, Operation::Lookup); + let datastore = match DataStore::lookup_datastore(lookup) { Ok(datastore) => datastore, Err(err) => { eprintln!("lookup_datastore failed - {err}"); @@ -573,7 +574,8 @@ async fn schedule_datastore_garbage_collection() { Err(_) => continue, // could not get lock }; - let datastore = match DataStore::lookup_datastore(&store, Operation::Write) { + let lookup = lookup_with(&store, Operation::Write); + let datastore = match DataStore::lookup_datastore(lookup) { Ok(datastore) => datastore, Err(err) => { log::warn!("skipping scheduled GC on {store}, could look it up - {err}"); diff --git a/src/server/prune_job.rs b/src/server/prune_job.rs index bb86a323e..ca5c67541 100644 --- a/src/server/prune_job.rs +++ b/src/server/prune_job.rs @@ -133,7 +133,8 @@ pub fn do_prune_job( auth_id: &Authid, schedule: Option, ) -> Result { - let datastore = DataStore::lookup_datastore(&store, Operation::Write)?; + let lookup = crate::tools::lookup_with(&store, Operation::Write); + let datastore = DataStore::lookup_datastore(lookup)?; let worker_type = job.jobtype().to_string(); let auth_id = auth_id.clone(); diff --git a/src/server/pull.rs b/src/server/pull.rs index 412a59e66..dece52f34 100644 --- a/src/server/pull.rs +++ b/src/server/pull.rs @@ -112,12 +112,15 @@ impl PullParameters { client, }) } else { + let lookup = crate::tools::lookup_with(remote_store, Operation::Read); + let store = DataStore::lookup_datastore(lookup)?; Arc::new(LocalSource { - store: DataStore::lookup_datastore(remote_store, Operation::Read)?, + store, ns: remote_ns, }) }; - let store = DataStore::lookup_datastore(store, Operation::Write)?; + let lookup = crate::tools::lookup_with(store, Operation::Write); + let store = DataStore::lookup_datastore(lookup)?; let backend = store.backend()?; let target = PullTarget { store, ns, backend }; diff --git a/src/server/push.rs b/src/server/push.rs index 92bbbb9fc..2d335f559 100644 --- a/src/server/push.rs +++ b/src/server/push.rs @@ -109,7 +109,8 @@ impl PushParameters { let remove_vanished = remove_vanished.unwrap_or(false); let encrypted_only = encrypted_only.unwrap_or(false); let verified_only = verified_only.unwrap_or(false); - let store = DataStore::lookup_datastore(store, Operation::Read)?; + let lookup = crate::tools::lookup_with(store, Operation::Read); + let store = DataStore::lookup_datastore(lookup)?; if !store.namespace_exists(&ns) { bail!( diff --git a/src/server/verify_job.rs b/src/server/verify_job.rs index 2ec8c5138..ab14c7389 100644 --- a/src/server/verify_job.rs +++ b/src/server/verify_job.rs @@ -15,7 +15,8 @@ pub fn do_verification_job( schedule: Option, to_stdout: bool, ) -> Result { - let datastore = DataStore::lookup_datastore(&verification_job.store, Operation::Read)?; + let lookup = crate::tools::lookup_with(&verification_job.store, Operation::Read); + let datastore = DataStore::lookup_datastore(lookup)?; let outdated_after = verification_job.outdated_after; let ignore_verified_snapshots = verification_job.ignore_verified.unwrap_or(true); diff --git a/src/tools/mod.rs b/src/tools/mod.rs index 93b4d8ea4..4e9f9928c 100644 --- a/src/tools/mod.rs +++ b/src/tools/mod.rs @@ -6,12 +6,14 @@ use anyhow::{bail, Error}; use std::collections::HashSet; use pbs_api_types::{ - Authid, BackupContent, CryptMode, SnapshotListItem, SnapshotVerifyState, MANIFEST_BLOB_NAME, + Authid, BackupContent, CryptMode, Operation, SnapshotListItem, SnapshotVerifyState, + MANIFEST_BLOB_NAME, }; use proxmox_http::{client::Client, HttpOptions, ProxyConfig}; use pbs_datastore::backup_info::{BackupDir, BackupInfo}; use pbs_datastore::manifest::BackupManifest; +use pbs_datastore::DataStoreLookup; use crate::config::node; @@ -197,3 +199,9 @@ pub(super) fn node_proxy_config() -> Option { None } } + +/// Read the nodes http proxy config from the node config. +#[inline(always)] +pub fn lookup_with<'a>(name: &'a str, operation: Operation) -> DataStoreLookup<'a> { + DataStoreLookup::with(name, operation) +} -- 2.47.3 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel