[pbs-devel] [PATCH proxmox-backup 3/7] sync: add group filtering
Fabian Grünbichler
f.gruenbichler at proxmox.com
Thu Jul 22 16:35:06 CEST 2021
like for manual pulls, but persisted in the sync job config and visible
in the relevant GUI parts.
Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
Notes:
if we want to make this configurable over the GUI, we probably want to switch
the job edit window to a tabpanel and add a second grid tab for selecting
the groups.
src/api2/config/sync.rs | 22 ++++++++++++++++++++++
src/api2/pull.rs | 31 +++++++++++++++++++------------
src/config/sync.rs | 10 ++++++++++
www/config/SyncView.js | 13 ++++++++++++-
www/window/SyncJobEdit.js | 12 ++++++++++++
5 files changed, 75 insertions(+), 13 deletions(-)
diff --git a/src/api2/config/sync.rs b/src/api2/config/sync.rs
index bc7b9f24..28c04179 100644
--- a/src/api2/config/sync.rs
+++ b/src/api2/config/sync.rs
@@ -137,6 +137,14 @@ pub fn list_sync_jobs(
optional: true,
schema: SYNC_SCHEDULE_SCHEMA,
},
+ groups: {
+ type: Array,
+ description: "List of group identifiers to filter for. All if unspecified.",
+ items: {
+ schema: BACKUP_GROUP_SCHEMA,
+ },
+ optional: true,
+ },
},
},
access: {
@@ -222,6 +230,8 @@ pub enum DeletableProperty {
schedule,
/// Delete the remove-vanished flag.
remove_vanished,
+ /// Delete the groups property.
+ groups,
}
#[api(
@@ -259,6 +269,14 @@ pub enum DeletableProperty {
optional: true,
schema: SYNC_SCHEDULE_SCHEMA,
},
+ groups: {
+ type: Array,
+ description: "List of group identifiers to filter for. All if unspecified.",
+ items: {
+ schema: BACKUP_GROUP_SCHEMA,
+ },
+ optional: true,
+ },
delete: {
description: "List of properties to delete.",
type: Array,
@@ -289,6 +307,7 @@ pub fn update_sync_job(
remove_vanished: Option<bool>,
comment: Option<String>,
schedule: Option<String>,
+ groups: Option<Vec<String>>,
delete: Option<Vec<DeletableProperty>>,
digest: Option<String>,
rpcenv: &mut dyn RpcEnvironment,
@@ -315,6 +334,7 @@ pub fn update_sync_job(
DeletableProperty::comment => { data.comment = None; },
DeletableProperty::schedule => { data.schedule = None; },
DeletableProperty::remove_vanished => { data.remove_vanished = None; },
+ DeletableProperty::groups => { data.groups = None; },
}
}
}
@@ -332,6 +352,7 @@ pub fn update_sync_job(
if let Some(remote) = remote { data.remote = remote; }
if let Some(remote_store) = remote_store { data.remote_store = remote_store; }
if let Some(owner) = owner { data.owner = Some(owner); }
+ if let Some(groups) = groups { data.groups = Some(groups); }
let schedule_changed = data.schedule != schedule;
if schedule.is_some() { data.schedule = schedule; }
@@ -451,6 +472,7 @@ acl:1:/remote/remote1/remotestore1:write at pbs:RemoteSyncOperator
owner: Some(write_auth_id.clone()),
comment: None,
remove_vanished: None,
+ groups: None,
schedule: None,
};
diff --git a/src/api2/pull.rs b/src/api2/pull.rs
index 36149761..fbcabb11 100644
--- a/src/api2/pull.rs
+++ b/src/api2/pull.rs
@@ -1,4 +1,5 @@
//! Sync datastore from remote server
+use std::collections::HashSet;
use std::sync::{Arc};
use std::str::FromStr;
@@ -61,6 +62,20 @@ pub async fn get_pull_parameters(
Ok((client, src_repo, tgt_store))
}
+fn convert_group_filter(groups: Option<Vec<String>>) -> Result<Option<HashSet<BackupGroup>>, Error> {
+ match groups {
+ Some(filter) => {
+ let mut groups = std::collections::HashSet::with_capacity(filter.len());
+ for group in filter {
+ let group = BackupGroup::from_str(&group)?;
+ groups.insert(group);
+ }
+ Ok(Some(groups))
+ },
+ None => Ok(None)
+ }
+}
+
pub fn do_sync_job(
mut job: Job,
sync_job: SyncJobConfig,
@@ -102,7 +117,9 @@ pub fn do_sync_job(
worker.log(format!("Sync datastore '{}' from '{}/{}'",
sync_job.store, sync_job.remote, sync_job.remote_store));
- pull_store(&worker, &client, &src_repo, tgt_store.clone(), delete, sync_owner, None).await?;
+ let sync_group_filter = convert_group_filter(sync_job.groups)?;
+
+ pull_store(&worker, &client, &src_repo, tgt_store.clone(), delete, sync_owner, sync_group_filter).await?;
worker.log(format!("sync job '{}' end", &job_id));
@@ -195,17 +212,7 @@ async fn pull (
worker.log(format!("sync datastore '{}' start", store));
- let groups = match groups {
- Some(filter) => {
- let mut groups = std::collections::HashSet::with_capacity(filter.len());
- for group in filter {
- let group = BackupGroup::from_str(&group)?;
- groups.insert(group);
- }
- Some(groups)
- },
- None => None,
- };
+ let groups = convert_group_filter(groups)?;
let pull_future = pull_store(&worker, &client, &src_repo, tgt_store.clone(), delete, auth_id, groups);
let future = select!{
success = pull_future.fuse() => success,
diff --git a/src/config/sync.rs b/src/config/sync.rs
index 5d5b2060..c088e08a 100644
--- a/src/config/sync.rs
+++ b/src/config/sync.rs
@@ -49,6 +49,14 @@ lazy_static! {
optional: true,
schema: SYNC_SCHEDULE_SCHEMA,
},
+ groups: {
+ type: Array,
+ description: "List of group identifiers to filter for. All if unspecified.",
+ items: {
+ schema: BACKUP_GROUP_SCHEMA,
+ },
+ optional: true,
+ },
}
)]
#[derive(Serialize,Deserialize,Clone)]
@@ -67,6 +75,8 @@ pub struct SyncJobConfig {
pub comment: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
pub schedule: Option<String>,
+ #[serde(skip_serializing_if="Option::is_none")]
+ pub groups: Option<Vec<String>>,
}
#[api(
diff --git a/www/config/SyncView.js b/www/config/SyncView.js
index 7d7e751c..d2a3954f 100644
--- a/www/config/SyncView.js
+++ b/www/config/SyncView.js
@@ -1,7 +1,7 @@
Ext.define('pbs-sync-jobs-status', {
extend: 'Ext.data.Model',
fields: [
- 'id', 'owner', 'remote', 'remote-store', 'store', 'schedule',
+ 'id', 'owner', 'remote', 'remote-store', 'store', 'schedule', 'groups',
'next-run', 'last-run-upid', 'last-run-state', 'last-run-endtime',
{
name: 'duration',
@@ -106,6 +106,11 @@ Ext.define('PBS.config.SyncJobView', {
return Ext.String.htmlEncode(value, metadata, record);
},
+ render_optional_groups: function(value, metadata, record) {
+ if (!value) return gettext('All');
+ return Ext.String.htmlEncode(value, metadata, record);
+ },
+
startStore: function() { this.getView().getStore().rstore.startUpdate(); },
stopStore: function() { this.getView().getStore().rstore.stopUpdate(); },
@@ -214,6 +219,12 @@ Ext.define('PBS.config.SyncJobView', {
flex: 2,
sortable: true,
},
+ {
+ header: gettext('Backup Groups'),
+ dataIndex: 'groups',
+ renderer: 'render_optional_groups',
+ width: 80,
+ },
{
header: gettext('Schedule'),
dataIndex: 'schedule',
diff --git a/www/window/SyncJobEdit.js b/www/window/SyncJobEdit.js
index 47e65ae3..2399f11f 100644
--- a/www/window/SyncJobEdit.js
+++ b/www/window/SyncJobEdit.js
@@ -199,6 +199,18 @@ Ext.define('PBS.window.SyncJobEdit', {
],
columnB: [
+ {
+ fieldLabel: gettext('Backup Groups'),
+ xtype: 'displayfield',
+ name: 'groups',
+ renderer: function(value, metadata, record) {
+ if (!value) return gettext('All');
+ return Ext.String.htmlEncode(value, metadata, record);
+ },
+ cbind: {
+ hidden: '{isCreate}',
+ },
+ },
{
fieldLabel: gettext('Comment'),
xtype: 'proxmoxtextfield',
--
2.30.2
More information about the pbs-devel
mailing list