sync/pull: make namespace aware

Allow pulling all groups from a certain source namespace, and
possibly sub namespaces until max-depth, into a target namespace.

If any sub-namespaces get pulled, they will be mapped relatively from
the source parent namespace to the target parent namespace.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Fabian Grünbichler
2022-04-29 13:46:14 +02:00
committed by Thomas Lamprecht
parent 31aa38b684
commit c06c1b4bd7
8 changed files with 582 additions and 116 deletions

View File

@ -12,8 +12,9 @@ use proxmox_sys::fs::CreateOptions;
use pbs_api_types::percent_encoding::percent_encode_component;
use pbs_api_types::{
BackupNamespace, GroupFilter, RateLimitConfig, SyncJobConfig, DATASTORE_SCHEMA,
GROUP_FILTER_LIST_SCHEMA, IGNORE_VERIFIED_BACKUPS_SCHEMA, REMOTE_ID_SCHEMA,
REMOVE_VANISHED_BACKUPS_SCHEMA, UPID_SCHEMA, VERIFICATION_OUTDATED_AFTER_SCHEMA,
GROUP_FILTER_LIST_SCHEMA, IGNORE_VERIFIED_BACKUPS_SCHEMA, NS_MAX_DEPTH_SCHEMA,
REMOTE_ID_SCHEMA, REMOVE_VANISHED_BACKUPS_SCHEMA, UPID_SCHEMA,
VERIFICATION_OUTDATED_AFTER_SCHEMA,
};
use pbs_client::{display_task_log, view_task_result};
use pbs_config::sync;
@ -234,19 +235,31 @@ fn task_mgmt_cli() -> CommandLineInterface {
#[api(
input: {
properties: {
"local-store": {
"store": {
schema: DATASTORE_SCHEMA,
},
"ns": {
type: BackupNamespace,
optional: true,
},
remote: {
schema: REMOTE_ID_SCHEMA,
},
"remote-store": {
schema: DATASTORE_SCHEMA,
},
"remote-ns": {
type: BackupNamespace,
optional: true,
},
"remove-vanished": {
schema: REMOVE_VANISHED_BACKUPS_SCHEMA,
optional: true,
},
"max-depth": {
schema: NS_MAX_DEPTH_SCHEMA,
optional: true,
},
"group-filter": {
schema: GROUP_FILTER_LIST_SCHEMA,
optional: true,
@ -266,8 +279,11 @@ fn task_mgmt_cli() -> CommandLineInterface {
async fn pull_datastore(
remote: String,
remote_store: String,
local_store: String,
remote_ns: Option<BackupNamespace>,
store: String,
ns: Option<BackupNamespace>,
remove_vanished: Option<bool>,
max_depth: Option<usize>,
group_filter: Option<Vec<GroupFilter>>,
limit: RateLimitConfig,
param: Value,
@ -277,12 +293,24 @@ async fn pull_datastore(
let client = connect_to_localhost()?;
let mut args = json!({
"store": local_store,
"store": store,
"remote": remote,
"remote-store": remote_store,
"limit": limit,
});
if remote_ns.is_some() {
args["remote-ns"] = json!(remote_ns);
}
if ns.is_some() {
args["local-ns"] = json!(ns);
}
if max_depth.is_some() {
args["max-depth"] = json!(max_depth);
}
if group_filter.is_some() {
args["group-filter"] = json!(group_filter);
}
@ -406,14 +434,13 @@ async fn run() -> Result<(), Error> {
.insert(
"pull",
CliCommand::new(&API_METHOD_PULL_DATASTORE)
.arg_param(&["remote", "remote-store", "local-store"])
.completion_cb(
"local-store",
pbs_config::datastore::complete_datastore_name,
)
.arg_param(&["remote", "remote-store", "store"])
.completion_cb("store", pbs_config::datastore::complete_datastore_name)
.completion_cb("ns", complete_sync_local_datastore_namespace)
.completion_cb("remote", pbs_config::remote::complete_remote_name)
.completion_cb("remote-store", complete_remote_datastore_name)
.completion_cb("group-filter", complete_remote_datastore_group_filter),
.completion_cb("group-filter", complete_remote_datastore_group_filter)
.completion_cb("remote-ns", complete_remote_datastore_namespace),
)
.insert(
"verify",
@ -507,6 +534,12 @@ fn get_remote_ns(param: &HashMap<String, String>) -> Option<BackupNamespace> {
if let Some(ns_str) = param.get("remote-ns") {
BackupNamespace::from_str(ns_str).ok()
} else {
if let Some(id) = param.get("id") {
let job = get_sync_job(id).ok();
if let Some(ref job) = job {
return job.remote_ns.clone();
}
}
None
}
}

View File

@ -103,12 +103,14 @@ pub fn sync_job_commands() -> CommandLineInterface {
.completion_cb("id", pbs_config::sync::complete_sync_job_id)
.completion_cb("schedule", pbs_config::datastore::complete_calendar_event)
.completion_cb("store", pbs_config::datastore::complete_datastore_name)
.completion_cb("ns", crate::complete_sync_local_datastore_namespace)
.completion_cb("remote", pbs_config::remote::complete_remote_name)
.completion_cb("remote-store", crate::complete_remote_datastore_name)
.completion_cb(
"group-filter",
crate::complete_remote_datastore_group_filter,
),
)
.completion_cb("remote-ns", crate::complete_remote_datastore_namespace),
)
.insert(
"update",
@ -117,11 +119,13 @@ pub fn sync_job_commands() -> CommandLineInterface {
.completion_cb("id", pbs_config::sync::complete_sync_job_id)
.completion_cb("schedule", pbs_config::datastore::complete_calendar_event)
.completion_cb("store", pbs_config::datastore::complete_datastore_name)
.completion_cb("ns", crate::complete_sync_local_datastore_namespace)
.completion_cb("remote-store", crate::complete_remote_datastore_name)
.completion_cb(
"group-filter",
crate::complete_remote_datastore_group_filter,
),
)
.completion_cb("remote-ns", crate::complete_remote_datastore_namespace),
)
.insert(
"remove",