[pbs-devel] [PATCH proxmox-backup v8 06/45] datastore: allow to get the backend for a datastore

Christian Ebner c.ebner at proxmox.com
Fri Jul 18 11:10:02 CEST 2025


On 7/18/25 9:52 AM, Lukas Wagner wrote:
> With my feedback addressed:
> 
> Reviewed-by: Lukas Wagner <l.wagner at proxmox.com>
> 
> 
> On  2025-07-15 14:52, Christian Ebner wrote:
>> Implements an enum with variants Filesystem and S3 to distinguish
>> between available backends. Filesystem will be used as default, if no
>> backend is configured in the datastores configuration. If the
>> datastore has an s3 backend configured, the backend method will
>> instantiate and s3 client and return it with the S3 variant.
>>
>> This allows to instantiate the client once, keeping and reusing the
>> same open connection to the api for the lifetime of task or job, e.g.
>> in the backup writer/readers runtime environment.
>>
>> Signed-off-by: Christian Ebner <c.ebner at proxmox.com>
>> ---
>> changes since version 7:
>> - no changes
>>
>>   pbs-datastore/src/datastore.rs | 52 ++++++++++++++++++++++++++++++++--
>>   pbs-datastore/src/lib.rs       |  1 +
>>   2 files changed, 51 insertions(+), 2 deletions(-)
>>
>> diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs
>> index 924d8cf9c..90ab80005 100644
>> --- a/pbs-datastore/src/datastore.rs
>> +++ b/pbs-datastore/src/datastore.rs
>> @@ -12,6 +12,7 @@ use pbs_tools::lru_cache::LruCache;
>>   use tracing::{info, warn};
>>   
>>   use proxmox_human_byte::HumanByte;
>> +use proxmox_s3_client::{S3Client, S3ClientConfig, S3ClientOptions, S3ClientSecretsConfig};
>>   use proxmox_schema::ApiType;
>>   
>>   use proxmox_sys::error::SysError;
>> @@ -23,8 +24,8 @@ use proxmox_worker_task::WorkerTaskContext;
>>   
>>   use pbs_api_types::{
>>       ArchiveType, Authid, BackupGroupDeleteStats, BackupNamespace, BackupType, ChunkOrder,
>> -    DataStoreConfig, DatastoreFSyncLevel, DatastoreTuning, GarbageCollectionStatus,
>> -    MaintenanceMode, MaintenanceType, Operation, UPID,
>> +    DataStoreConfig, DatastoreBackendConfig, DatastoreBackendType, DatastoreFSyncLevel,
>> +    DatastoreTuning, GarbageCollectionStatus, MaintenanceMode, MaintenanceType, Operation, UPID,
>>   };
>>   use pbs_config::BackupLockGuard;
>>   
>> @@ -127,6 +128,7 @@ pub struct DataStoreImpl {
>>       chunk_order: ChunkOrder,
>>       last_digest: Option<[u8; 32]>,
>>       sync_level: DatastoreFSyncLevel,
>> +    backend_config: DatastoreBackendConfig,
>>   }
>>   
>>   impl DataStoreImpl {
>> @@ -141,6 +143,7 @@ impl DataStoreImpl {
>>               chunk_order: Default::default(),
>>               last_digest: None,
>>               sync_level: Default::default(),
>> +            backend_config: Default::default(),
>>           })
>>       }
>>   }
>> @@ -196,6 +199,12 @@ impl Drop for DataStore {
>>       }
>>   }
>>   
>> +#[derive(Clone)]
>> +pub enum DatastoreBackend {
>> +    Filesystem,
>> +    S3(Arc<S3Client>),
>> +}
>> +
> 
> Missing doc comments for this public enum

Added docs for both, the enum and the individual variants.

>>   impl DataStore {
>>       // This one just panics on everything
>>       #[doc(hidden)]
>> @@ -206,6 +215,39 @@ impl DataStore {
>>           })
>>       }
>>   
>> +    /// Get the backend for this datastore based on it's configuration
>> +    pub fn backend(&self) -> Result<DatastoreBackend, Error> {
>> +        let backend_type = match self.inner.backend_config.ty.unwrap_or_default() {
>> +            DatastoreBackendType::Filesystem => DatastoreBackend::Filesystem,
>> +            DatastoreBackendType::S3 => {
>> +                let s3_client_id = self
>> +                    .inner
>> +                    .backend_config
>> +                    .client
>> +                    .as_ref()
>> +                    .ok_or_else(|| format_err!("missing client for s3 backend"))?;
>> +                let bucket = self
>> +                    .inner
>> +                    .backend_config
>> +                    .bucket
>> +                    .clone()
>> +                    .ok_or_else(|| format_err!("missing bucket for s3 backend"))?;
>> +
>> +                let (config, _config_digest) = pbs_config::s3::config()?;
>> +                let (secrets, _secrets_digest) = pbs_config::s3::secrets_config()?;
>> +                let config: S3ClientConfig = config.lookup("s3client", s3_client_id)?;
>> +                let secrets: S3ClientSecretsConfig = secrets.lookup("s3secrets", s3_client_id)?;
> 
> Same thing here with regards to the hard-coded section type names.

Adapted as well, thx for pointing them out!

> 
>> +
>> +                let options =
>> +                    S3ClientOptions::from_config(config, secrets, bucket, self.name().to_owned());
>> +                let s3_client = S3Client::new(options)?;
>> +                DatastoreBackend::S3(Arc::new(s3_client))
>> +            }
>> +        };
>> +
>> +        Ok(backend_type)
>> +    }
>> +
>>       pub fn lookup_datastore(
>>           name: &str,
>>           operation: Option<Operation>,
>> @@ -383,6 +425,11 @@ impl DataStore {
>>                   .parse_property_string(config.tuning.as_deref().unwrap_or(""))?,
>>           )?;
>>   
>> +        let backend_config: DatastoreBackendConfig = serde_json::from_value(
>> +            DatastoreBackendConfig::API_SCHEMA
>> +                .parse_property_string(config.backend.as_deref().unwrap_or(""))?,
>> +        )?;
>> +
>>           Ok(DataStoreImpl {
>>               chunk_store,
>>               gc_mutex: Mutex::new(()),
>> @@ -391,6 +438,7 @@ impl DataStore {
>>               chunk_order: tuning.chunk_order.unwrap_or_default(),
>>               last_digest,
>>               sync_level: tuning.sync_level.unwrap_or_default(),
>> +            backend_config,
>>           })
>>       }
>>   
>> diff --git a/pbs-datastore/src/lib.rs b/pbs-datastore/src/lib.rs
>> index ffd0d91b2..ca6fdb7d8 100644
>> --- a/pbs-datastore/src/lib.rs
>> +++ b/pbs-datastore/src/lib.rs
>> @@ -204,6 +204,7 @@ pub use store_progress::StoreProgress;
>>   mod datastore;
>>   pub use datastore::{
>>       check_backup_owner, ensure_datastore_is_mounted, get_datastore_mount_status, DataStore,
>> +    DatastoreBackend,
>>   };
>>   
>>   mod hierarchy;
> 





More information about the pbs-devel mailing list