[pbs-devel] [PATCH proxmox-backup v9 2/6] datastore: add check for maintenance in lookup

Dylan Whyte d.whyte at proxmox.com
Wed Apr 6 15:08:27 CEST 2022


Minor comment inline:

On 2/17/22 18:14, Hannes Laimer wrote:
> Signed-off-by: Hannes Laimer <h.laimer at proxmox.com>
> ---
>   pbs-api-types/src/maintenance.rs     | 23 +++++++++++--
>   pbs-datastore/src/datastore.rs       | 17 +++++++---
>   pbs-datastore/src/snapshot_reader.rs |  6 +++-
>   src/api2/admin/datastore.rs          | 50 ++++++++++++++--------------
>   src/api2/backup/mod.rs               |  4 +--
>   src/api2/reader/mod.rs               |  6 ++--
>   src/api2/status.rs                   |  4 +--
>   src/api2/tape/backup.rs              |  6 ++--
>   src/api2/tape/restore.rs             |  6 ++--
>   src/bin/proxmox-backup-proxy.rs      |  4 +--
>   src/server/prune_job.rs              |  4 +--
>   src/server/pull.rs                   |  4 +--
>   src/server/verify_job.rs             |  4 +--
>   13 files changed, 85 insertions(+), 53 deletions(-)
>
> diff --git a/pbs-api-types/src/maintenance.rs b/pbs-api-types/src/maintenance.rs
> index 19883e46..55d66964 100644
> --- a/pbs-api-types/src/maintenance.rs
> +++ b/pbs-api-types/src/maintenance.rs
> @@ -1,3 +1,5 @@
> +use std::borrow::Cow;
> +use anyhow::{bail, Error};
>   use serde::{Deserialize, Serialize};
>   
>   use proxmox_schema::{api, ApiStringFormat, const_regex, Schema, StringSchema};
> @@ -24,7 +26,7 @@ pub enum Operation {
>   }
>   
>   #[api]
> -#[derive(Deserialize, Serialize)]
> +#[derive(Deserialize, Serialize, PartialEq)]
>   #[serde(rename_all="kebab-case")]
>   /// Maintenance type.
>   pub enum MaintenanceType {
> @@ -49,7 +51,7 @@ pub enum MaintenanceType {
>   #[derive(Deserialize, Serialize)]
>   /// Maintenance mode
>   pub struct MaintenanceMode {
> -    /// Type of the maintenance
> +    /// Type of the maintenance.
>       #[serde(rename = "type")]
>       ty: MaintenanceType,
>   
> @@ -57,3 +59,20 @@ pub struct MaintenanceMode {
>       #[serde(skip_serializing_if = "Option::is_none")]
>       message: Option<String>,
>   }
> +
> +impl MaintenanceMode {
> +    pub fn check(&self, operation: Option<Operation>) -> Result<(), Error> {
> +        let message = percent_encoding::percent_decode_str(self.message.as_deref().unwrap_or(""))
> +            .decode_utf8()
> +            .unwrap_or(Cow::Borrowed(""));

You could possibly add a more generic default/fallback message here, 
such as "contact the administrator for more info". This adds less 
confusion, given the trailing semi-colon below, but is really not a big 
deal in any case.

> +
> +        if self.ty == MaintenanceType::Offline {
> +            bail!("offline maintenance mode: {}", message);
> +        } else if self.ty == MaintenanceType::ReadOnly {
> +            if let Some(Operation::Write) = operation {
> +                bail!("read-only maintenance mode: {}", message);
> +            }
> +        }
> +        Ok(())
> +    }
> +}
> diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs
> index 7044e074..902848d6 100644
> --- a/pbs-datastore/src/datastore.rs
> +++ b/pbs-datastore/src/datastore.rs
> @@ -15,7 +15,9 @@ use proxmox_sys::WorkerTaskContext;
>   use proxmox_sys::{task_log, task_warn};
>   use proxmox_sys::fs::{lock_dir_noblock, DirLockGuard};
>   
> -use pbs_api_types::{UPID, DataStoreConfig, Authid, GarbageCollectionStatus, HumanByte};
> +use pbs_api_types::{
> +    UPID, DataStoreConfig, Authid, Operation, GarbageCollectionStatus, HumanByte
> +};
>   use pbs_config::{open_backup_lockfile, BackupLockGuard};
>   
>   use crate::DataBlob;
> @@ -60,13 +62,20 @@ pub struct DataStore {
>   }
>   
>   impl DataStore {
> -
> -    pub fn lookup_datastore(name: &str) -> Result<Arc<DataStore>, Error> {
> -
> +    pub fn lookup_datastore(
> +        name: &str,
> +        operation: Option<Operation>,
> +    ) -> Result<Arc<DataStore>, Error> {
>           let (config, _digest) = pbs_config::datastore::config()?;
>           let config: DataStoreConfig = config.lookup("datastore", name)?;
>           let path = PathBuf::from(&config.path);
>   
> +        if let Some(maintenance_mode) = config.get_maintenance_mode() {
> +            if let Err(error) = maintenance_mode.check(operation) {
> +                bail!("datastore '{}' is in {}", name, error);
> +            }
> +        }
> +
>           let mut map = DATASTORE_MAP.lock().unwrap();
>   
>           if let Some(datastore) = map.get(name) {
> diff --git a/pbs-datastore/src/snapshot_reader.rs b/pbs-datastore/src/snapshot_reader.rs
> index 18bc0d83..65abac7d 100644
> --- a/pbs-datastore/src/snapshot_reader.rs
> +++ b/pbs-datastore/src/snapshot_reader.rs
> @@ -14,6 +14,7 @@ use crate::fixed_index::FixedIndexReader;
>   use crate::dynamic_index::DynamicIndexReader;
>   use crate::manifest::{archive_type, ArchiveType, CLIENT_LOG_BLOB_NAME, MANIFEST_BLOB_NAME};
>   use crate::DataStore;
> +use pbs_api_types::Operation;
>   
>   /// Helper to access the contents of a datastore backup snapshot
>   ///
> @@ -120,7 +121,10 @@ impl <'a> Iterator for SnapshotChunkIterator<'a> {
>                           };
>   
>                           let datastore =
> -                            DataStore::lookup_datastore(self.snapshot_reader.datastore_name())?;
> +                            DataStore::lookup_datastore(
> +                                self.snapshot_reader.datastore_name(),
> +                                Some(Operation::Read)
> +                            )?;
>                           let order = datastore.get_chunks_in_order(&index, |_| false, |_| Ok(()))?;
>   
>                           self.current_index = Some((Arc::new(index), 0, order));
> diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs
> index 263ea96f..ce710938 100644
> --- a/src/api2/admin/datastore.rs
> +++ b/src/api2/admin/datastore.rs
> @@ -30,7 +30,7 @@ use pxar::EntryKind;
>   
>   use pbs_api_types::{ Authid, BackupContent, Counts, CryptMode,
>       DataStoreListItem, GarbageCollectionStatus, GroupListItem,
> -    SnapshotListItem, SnapshotVerifyState, PruneOptions,
> +    Operation, SnapshotListItem, SnapshotVerifyState, PruneOptions,
>       DataStoreStatus, RRDMode, RRDTimeFrame,
>       BACKUP_ARCHIVE_NAME_SCHEMA, BACKUP_ID_SCHEMA, BACKUP_TIME_SCHEMA,
>       BACKUP_TYPE_SCHEMA, DATASTORE_SCHEMA,
> @@ -170,7 +170,7 @@ pub fn list_groups(
>       let user_info = CachedUserInfo::new()?;
>       let user_privs = user_info.lookup_privs(&auth_id, &["datastore", &store]);
>   
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>       let list_all = (user_privs & PRIV_DATASTORE_AUDIT) != 0;
>   
>       let backup_groups = BackupInfo::list_backup_groups(&datastore.base_path())?;
> @@ -268,7 +268,7 @@ pub fn delete_group(
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>   
>       let group = BackupGroup::new(backup_type, backup_id);
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       check_priv_or_backup_owner(&datastore, &group, &auth_id, PRIV_DATASTORE_MODIFY)?;
>   
> @@ -315,7 +315,7 @@ pub fn list_snapshot_files(
>   ) -> Result<Vec<BackupContent>, Error> {
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>   
>       let snapshot = BackupDir::new(backup_type, backup_id, backup_time)?;
>   
> @@ -365,7 +365,7 @@ pub fn delete_snapshot(
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>   
>       let snapshot = BackupDir::new(backup_type, backup_id, backup_time)?;
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       check_priv_or_backup_owner(&datastore, snapshot.group(), &auth_id, PRIV_DATASTORE_MODIFY)?;
>   
> @@ -414,7 +414,7 @@ pub fn list_snapshots (
>   
>       let list_all = (user_privs & PRIV_DATASTORE_AUDIT) != 0;
>   
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>   
>       let base_path = datastore.base_path();
>   
> @@ -615,7 +615,7 @@ pub fn status(
>       _info: &ApiMethod,
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<DataStoreStatus, Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>       let storage = crate::tools::disks::disk_usage(&datastore.base_path())?;
>       let (counts, gc_status) = if verbose {
>           let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
> @@ -693,7 +693,7 @@ pub fn verify(
>       outdated_after: Option<i64>,
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<Value, Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>       let ignore_verified = ignore_verified.unwrap_or(true);
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
> @@ -838,7 +838,7 @@ pub fn prune(
>   
>       let group = BackupGroup::new(&backup_type, &backup_id);
>   
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       check_priv_or_backup_owner(&datastore, &group, &auth_id, PRIV_DATASTORE_MODIFY)?;
>   
> @@ -963,7 +963,7 @@ pub fn prune_datastore(
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>   
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
>   
> @@ -1007,7 +1007,7 @@ pub fn start_garbage_collection(
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<Value, Error> {
>   
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>   
>       let job =  Job::new("garbage_collection", &store)
> @@ -1043,7 +1043,7 @@ pub fn garbage_collection_status(
>       _rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<GarbageCollectionStatus, Error> {
>   
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>   
>       let status = datastore.last_gc_status();
>   
> @@ -1119,7 +1119,7 @@ pub fn download_file(
>   
>       async move {
>           let store = required_string_param(&param, "store")?;
> -        let datastore = DataStore::lookup_datastore(store)?;
> +        let datastore = DataStore::lookup_datastore(store, Some(Operation::Read))?;
>   
>           let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>   
> @@ -1189,7 +1189,7 @@ pub fn download_file_decoded(
>   
>       async move {
>           let store = required_string_param(&param, "store")?;
> -        let datastore = DataStore::lookup_datastore(store)?;
> +        let datastore = DataStore::lookup_datastore(store, Some(Operation::Read))?;
>   
>           let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>   
> @@ -1303,7 +1303,7 @@ pub fn upload_backup_log(
>   
>       async move {
>           let store = required_string_param(&param, "store")?;
> -        let datastore = DataStore::lookup_datastore(store)?;
> +        let datastore = DataStore::lookup_datastore(store, Some(Operation::Write))?;
>   
>           let file_name =  CLIENT_LOG_BLOB_NAME;
>   
> @@ -1380,7 +1380,7 @@ pub fn catalog(
>       filepath: String,
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<Vec<ArchiveEntry>, Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>   
> @@ -1450,7 +1450,7 @@ pub fn pxar_file_download(
>   
>       async move {
>           let store = required_string_param(&param, "store")?;
> -        let datastore = DataStore::lookup_datastore(store)?;
> +        let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>   
>           let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>   
> @@ -1567,7 +1567,7 @@ pub fn get_rrd_stats(
>       _param: Value,
>   ) -> Result<Value, Error> {
>   
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>       let disk_manager = crate::tools::disks::DiskManage::new();
>   
>       let mut rrd_fields = vec![
> @@ -1615,7 +1615,7 @@ pub fn get_group_notes(
>       backup_id: String,
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<String, Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>       let backup_group = BackupGroup::new(backup_type, backup_id);
> @@ -1657,7 +1657,7 @@ pub fn set_group_notes(
>       notes: String,
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<(), Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>       let backup_group = BackupGroup::new(backup_type, backup_id);
> @@ -1699,7 +1699,7 @@ pub fn get_notes(
>       backup_time: i64,
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<String, Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>       let backup_dir = BackupDir::new(backup_type, backup_id, backup_time)?;
> @@ -1750,7 +1750,7 @@ pub fn set_notes(
>       notes: String,
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<(), Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>       let backup_dir = BackupDir::new(backup_type, backup_id, backup_time)?;
> @@ -1793,7 +1793,7 @@ pub fn get_protection(
>       backup_time: i64,
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<bool, Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>       let backup_dir = BackupDir::new(backup_type, backup_id, backup_time)?;
> @@ -1838,7 +1838,7 @@ pub fn set_protection(
>       protected: bool,
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<(), Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
>       let backup_dir = BackupDir::new(backup_type, backup_id, backup_time)?;
> @@ -1879,7 +1879,7 @@ pub fn set_backup_owner(
>       rpcenv: &mut dyn RpcEnvironment,
>   ) -> Result<(), Error> {
>   
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       let backup_group = BackupGroup::new(backup_type, backup_id);
>   
> diff --git a/src/api2/backup/mod.rs b/src/api2/backup/mod.rs
> index 395edd3d..9d62dc52 100644
> --- a/src/api2/backup/mod.rs
> +++ b/src/api2/backup/mod.rs
> @@ -16,7 +16,7 @@ use proxmox_router::{
>   use proxmox_schema::*;
>   
>   use pbs_api_types::{
> -    Authid, VerifyState, SnapshotVerifyState,
> +    Authid, Operation, VerifyState, SnapshotVerifyState,
>       BACKUP_ID_SCHEMA, BACKUP_TIME_SCHEMA, BACKUP_TYPE_SCHEMA, DATASTORE_SCHEMA,
>       CHUNK_DIGEST_SCHEMA, PRIV_DATASTORE_BACKUP, BACKUP_ARCHIVE_NAME_SCHEMA,
>   };
> @@ -77,7 +77,7 @@ async move {
>       let user_info = CachedUserInfo::new()?;
>       user_info.check_privs(&auth_id, &["datastore", &store], PRIV_DATASTORE_BACKUP, false)?;
>   
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       let backup_type = required_string_param(&param, "backup-type")?;
>       let backup_id = required_string_param(&param, "backup-id")?;
> diff --git a/src/api2/reader/mod.rs b/src/api2/reader/mod.rs
> index 2b11d1b1..45cefe5d 100644
> --- a/src/api2/reader/mod.rs
> +++ b/src/api2/reader/mod.rs
> @@ -16,8 +16,8 @@ use proxmox_router::{
>   use proxmox_schema::{BooleanSchema, ObjectSchema};
>   
>   use pbs_api_types::{
> -    Authid, DATASTORE_SCHEMA, BACKUP_TYPE_SCHEMA, BACKUP_TIME_SCHEMA, BACKUP_ID_SCHEMA,
> -    CHUNK_DIGEST_SCHEMA, PRIV_DATASTORE_READ, PRIV_DATASTORE_BACKUP,
> +    Authid, Operation, DATASTORE_SCHEMA, BACKUP_TYPE_SCHEMA, BACKUP_TIME_SCHEMA,
> +    BACKUP_ID_SCHEMA, CHUNK_DIGEST_SCHEMA, PRIV_DATASTORE_READ, PRIV_DATASTORE_BACKUP,
>       BACKUP_ARCHIVE_NAME_SCHEMA,
>   };
>   use proxmox_sys::fs::lock_dir_noblock_shared;
> @@ -81,7 +81,7 @@ fn upgrade_to_backup_reader_protocol(
>               bail!("no permissions on /datastore/{}", store);
>           }
>   
> -        let datastore = DataStore::lookup_datastore(&store)?;
> +        let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
>   
>           let backup_type = required_string_param(&param, "backup-type")?;
>           let backup_id = required_string_param(&param, "backup-id")?;
> diff --git a/src/api2/status.rs b/src/api2/status.rs
> index 029529ac..b589951d 100644
> --- a/src/api2/status.rs
> +++ b/src/api2/status.rs
> @@ -14,7 +14,7 @@ use proxmox_router::{
>   use proxmox_router::list_subdirs_api_method;
>   
>   use pbs_api_types::{
> -    Authid, DATASTORE_SCHEMA, RRDMode, RRDTimeFrame,
> +    Authid, Operation, DATASTORE_SCHEMA, RRDMode, RRDTimeFrame,
>       PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_BACKUP,
>   };
>   
> @@ -97,7 +97,7 @@ pub fn datastore_status(
>               continue;
>           }
>   
> -        let datastore = match DataStore::lookup_datastore(store) {
> +        let datastore = match DataStore::lookup_datastore(&store, Some(Operation::Read)) {
>               Ok(datastore) => datastore,
>               Err(err) => {
>                   list.push(json!({
> diff --git a/src/api2/tape/backup.rs b/src/api2/tape/backup.rs
> index 1462f200..28b24168 100644
> --- a/src/api2/tape/backup.rs
> +++ b/src/api2/tape/backup.rs
> @@ -10,7 +10,7 @@ use proxmox_schema::api;
>   use proxmox_sys::{task_log, task_warn, WorkerTaskContext};
>   
>   use pbs_api_types::{
> -    Authid, Userid, TapeBackupJobConfig, TapeBackupJobSetup, TapeBackupJobStatus, MediaPoolConfig,
> +    Authid, Userid, Operation, TapeBackupJobConfig, TapeBackupJobSetup, TapeBackupJobStatus, MediaPoolConfig,
>       UPID_SCHEMA, JOB_ID_SCHEMA, PRIV_DATASTORE_READ, PRIV_TAPE_AUDIT, PRIV_TAPE_WRITE,
>       GroupFilter,
>   };
> @@ -168,7 +168,7 @@ pub fn do_tape_backup_job(
>   
>       let worker_type = job.jobtype().to_string();
>   
> -    let datastore = DataStore::lookup_datastore(&setup.store)?;
> +    let datastore = DataStore::lookup_datastore(&setup.store, Some(Operation::Read))?;
>   
>       let (config, _digest) = pbs_config::media_pool::config()?;
>       let pool_config: MediaPoolConfig = config.lookup("pool", &setup.pool)?;
> @@ -349,7 +349,7 @@ pub fn backup(
>           &setup.drive,
>       )?;
>   
> -    let datastore = DataStore::lookup_datastore(&setup.store)?;
> +    let datastore = DataStore::lookup_datastore(&setup.store, Some(Operation::Read))?;
>   
>       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 2ce16c9d..59f098d9 100644
> --- a/src/api2/tape/restore.rs
> +++ b/src/api2/tape/restore.rs
> @@ -17,7 +17,7 @@ use proxmox_uuid::Uuid;
>   use proxmox_sys::{task_log, task_warn, WorkerTaskContext};
>   
>   use pbs_api_types::{
> -    Authid, Userid, CryptMode,
> +    Authid, Operation, Userid, CryptMode,
>       DATASTORE_MAP_ARRAY_SCHEMA, DATASTORE_MAP_LIST_SCHEMA, DRIVE_NAME_SCHEMA,
>       UPID_SCHEMA, TAPE_RESTORE_SNAPSHOT_SCHEMA,
>       PRIV_DATASTORE_BACKUP, PRIV_DATASTORE_MODIFY, PRIV_TAPE_READ,
> @@ -93,10 +93,10 @@ impl TryFrom<String> 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)?;
> +                let datastore = DataStore::lookup_datastore(&target, Some(Operation::Write))?;
>                   map.insert(store, datastore);
>               } else if default.is_none() {
> -                default = Some(DataStore::lookup_datastore(&store)?);
> +                default = Some(DataStore::lookup_datastore(&store, Some(Operation::Write))?);
>               } else {
>                   bail!("multiple default stores given");
>               }
> diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs
> index a4f20af1..e8315e5f 100644
> --- a/src/bin/proxmox-backup-proxy.rs
> +++ b/src/bin/proxmox-backup-proxy.rs
> @@ -48,7 +48,7 @@ use proxmox_time::CalendarEvent;
>   
>   use pbs_api_types::{
>       Authid, DataStoreConfig, PruneOptions, SyncJobConfig, TapeBackupJobConfig,
> -    VerificationJobConfig,
> +    VerificationJobConfig, Operation
>   };
>   
>   use proxmox_rest_server::daemon;
> @@ -560,7 +560,7 @@ async fn schedule_datastore_garbage_collection() {
>       };
>   
>       for (store, (_, store_config)) in config.sections {
> -        let datastore = match DataStore::lookup_datastore(&store) {
> +        let datastore = match DataStore::lookup_datastore(&store, Some(Operation::Write)) {
>               Ok(datastore) => datastore,
>               Err(err) => {
>                   eprintln!("lookup_datastore failed - {}", err);
> diff --git a/src/server/prune_job.rs b/src/server/prune_job.rs
> index 825fd60d..d9a6651e 100644
> --- a/src/server/prune_job.rs
> +++ b/src/server/prune_job.rs
> @@ -7,7 +7,7 @@ use proxmox_sys::{task_log, task_warn};
>   use pbs_datastore::backup_info::BackupInfo;
>   use pbs_datastore::prune::compute_prune_info;
>   use pbs_datastore::DataStore;
> -use pbs_api_types::{Authid, PRIV_DATASTORE_MODIFY, PruneOptions};
> +use pbs_api_types::{Authid, Operation, PRIV_DATASTORE_MODIFY, PruneOptions};
>   use pbs_config::CachedUserInfo;
>   use proxmox_rest_server::WorkerTask;
>   
> @@ -97,7 +97,7 @@ pub fn do_prune_job(
>       auth_id: &Authid,
>       schedule: Option<String>,
>   ) -> Result<String, Error> {
> -    let datastore = DataStore::lookup_datastore(&store)?;
> +    let datastore = DataStore::lookup_datastore(&store, Some(Operation::Write))?;
>   
>       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 a2a5f1f1..559533a6 100644
> --- a/src/server/pull.rs
> +++ b/src/server/pull.rs
> @@ -16,7 +16,7 @@ use proxmox_sys::task_log;
>   
>   use pbs_api_types::{
>       Authid, GroupFilter, GroupListItem, RateLimitConfig, Remote,
> -    SnapshotListItem,
> +    Operation, SnapshotListItem,
>   };
>   
>   use pbs_datastore::{BackupDir, BackupInfo, BackupGroup, DataStore, StoreProgress};
> @@ -57,7 +57,7 @@ impl PullParameters {
>           group_filter: Option<Vec<GroupFilter>>,
>           limit: RateLimitConfig,
>       ) -> Result<Self, Error> {
> -        let store = DataStore::lookup_datastore(store)?;
> +        let store = DataStore::lookup_datastore(store, Some(Operation::Write))?;
>   
>           let (remote_config, _digest) = pbs_config::remote::config()?;
>           let remote: Remote = remote_config.lookup("remote", remote)?;
> diff --git a/src/server/verify_job.rs b/src/server/verify_job.rs
> index a23eb04e..e472ed91 100644
> --- a/src/server/verify_job.rs
> +++ b/src/server/verify_job.rs
> @@ -1,7 +1,7 @@
>   use anyhow::{format_err, Error};
>   
>   use proxmox_sys::task_log;
> -use pbs_api_types::{Authid, VerificationJobConfig};
> +use pbs_api_types::{Authid, Operation, VerificationJobConfig};
>   use proxmox_rest_server::WorkerTask;
>   use pbs_datastore::DataStore;
>   
> @@ -22,7 +22,7 @@ pub fn do_verification_job(
>       to_stdout: bool,
>   ) -> Result<String, Error> {
>   
> -    let datastore = DataStore::lookup_datastore(&verification_job.store)?;
> +    let datastore = DataStore::lookup_datastore(&verification_job.store, Some(Operation::Read))?;
>   
>       let outdated_after = verification_job.outdated_after;
>       let ignore_verified_snapshots = verification_job.ignore_verified.unwrap_or(true);





More information about the pbs-devel mailing list