[pbs-devel] [PATCH proxmox-backup v2 08/13] api2/admin/datastore: add get/set_protection
Dominik Csapak
d.csapak at proxmox.com
Thu Sep 23 13:37:34 CEST 2021
for gettin/setting the protected flag for snapshots (akin to notes)
Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
src/api2/admin/datastore.rs | 92 +++++++++++++++++++++++++++++++++++++
src/backup/datastore.rs | 24 ++++++++++
2 files changed, 116 insertions(+)
diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs
index 04320f9c..a92efc02 100644
--- a/src/api2/admin/datastore.rs
+++ b/src/api2/admin/datastore.rs
@@ -1748,6 +1748,92 @@ pub fn set_notes(
Ok(())
}
+#[api(
+ input: {
+ properties: {
+ store: {
+ schema: DATASTORE_SCHEMA,
+ },
+ "backup-type": {
+ schema: BACKUP_TYPE_SCHEMA,
+ },
+ "backup-id": {
+ schema: BACKUP_ID_SCHEMA,
+ },
+ "backup-time": {
+ schema: BACKUP_TIME_SCHEMA,
+ },
+ },
+ },
+ access: {
+ permission: &Permission::Privilege(&["datastore", "{store}"], PRIV_DATASTORE_AUDIT | PRIV_DATASTORE_BACKUP, true),
+ },
+)]
+/// Query protection for a specific backup
+pub fn get_protection(
+ store: String,
+ backup_type: String,
+ backup_id: String,
+ backup_time: i64,
+ rpcenv: &mut dyn RpcEnvironment,
+) -> Result<bool, Error> {
+ let datastore = DataStore::lookup_datastore(&store)?;
+
+ let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+ let backup_dir = BackupDir::new(backup_type, backup_id, backup_time)?;
+
+ check_priv_or_backup_owner(&datastore, backup_dir.group(), &auth_id, PRIV_DATASTORE_AUDIT)?;
+
+ let protected_path = backup_dir.protected_file(datastore.base_path());
+
+ Ok(protected_path.exists())
+}
+
+#[api(
+ input: {
+ properties: {
+ store: {
+ schema: DATASTORE_SCHEMA,
+ },
+ "backup-type": {
+ schema: BACKUP_TYPE_SCHEMA,
+ },
+ "backup-id": {
+ schema: BACKUP_ID_SCHEMA,
+ },
+ "backup-time": {
+ schema: BACKUP_TIME_SCHEMA,
+ },
+ protected: {
+ description: "Enable/disable protection.",
+ },
+ },
+ },
+ access: {
+ permission: &Permission::Privilege(&["datastore", "{store}"],
+ PRIV_DATASTORE_MODIFY | PRIV_DATASTORE_BACKUP,
+ true),
+ },
+)]
+/// En- or disable protection for a specific backup
+pub fn set_protection(
+ store: String,
+ backup_type: String,
+ backup_id: String,
+ backup_time: i64,
+ protected: bool,
+ rpcenv: &mut dyn RpcEnvironment,
+) -> Result<(), Error> {
+ let datastore = DataStore::lookup_datastore(&store)?;
+
+ let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+ let backup_dir = BackupDir::new(backup_type, backup_id, backup_time)?;
+
+ check_priv_or_backup_owner(&datastore, backup_dir.group(), &auth_id, PRIV_DATASTORE_MODIFY)?;
+
+ datastore.update_protection(&backup_dir, protected)
+}
+
#[api(
input: {
properties: {
@@ -1896,6 +1982,12 @@ const DATASTORE_INFO_SUBDIRS: SubdirMap = &[
.get(&API_METHOD_GET_NOTES)
.put(&API_METHOD_SET_NOTES)
),
+ (
+ "protected",
+ &Router::new()
+ .get(&API_METHOD_GET_PROTECTION)
+ .put(&API_METHOD_SET_PROTECTION)
+ ),
(
"prune",
&Router::new()
diff --git a/src/backup/datastore.rs b/src/backup/datastore.rs
index a791807f..2ab0e289 100644
--- a/src/backup/datastore.rs
+++ b/src/backup/datastore.rs
@@ -860,6 +860,30 @@ impl DataStore {
Ok(())
}
+ /// Updates the protection status of the specified snapshot.
+ pub fn update_protection(
+ &self,
+ backup_dir: &BackupDir,
+ protection: bool
+ ) -> Result<(), Error> {
+ let full_path = self.snapshot_path(backup_dir);
+
+ let _guard = lock_dir_noblock(&full_path, "snapshot", "possibly running or in use")?;
+
+ let protected_path = backup_dir.protected_file(self.base_path());
+ if protection {
+ std::fs::File::create(protected_path)
+ .map_err(|err| format_err!("could not create protection file: {}", err))?;
+ } else if let Err(err) = std::fs::remove_file(protected_path) {
+ // ignore error for non-existing file
+ if err.kind() != std::io::ErrorKind::NotFound {
+ bail!("could not remove protection file: {}", err);
+ }
+ }
+
+ Ok(())
+ }
+
pub fn verify_new(&self) -> bool {
self.verify_new
}
--
2.30.2
More information about the pbs-devel
mailing list