From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 60C4169F5E for ; Wed, 15 Sep 2021 15:42:28 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 5D8A019C2A for ; Wed, 15 Sep 2021 15:42:28 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 7AB8A19C1D for ; Wed, 15 Sep 2021 15:42:27 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 509FC448A1 for ; Wed, 15 Sep 2021 15:42:27 +0200 (CEST) From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= To: pve-devel@lists.proxmox.com Date: Wed, 15 Sep 2021 15:41:55 +0200 Message-Id: <20210915134157.19762-9-f.gruenbichler@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210915134157.19762-1-f.gruenbichler@proxmox.com> References: <20210915134157.19762-1-f.gruenbichler@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.380 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [proxmox-backup-manager.rs, sync.rs] Subject: [pve-devel] [PATCH v2 proxmox-backup 08/10] manager: extend sync/pull completion X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Sep 2021 13:42:28 -0000 complete groups by scanning the remote store if available, and query the sync job config if remote or remote-store is not given on the current command-line (e.g., when updating a job config). unfortunately groups already given on the current command line are not passed to the completion helper, so we can't filter those out.. other filter types are completed statically. Signed-off-by: Fabian Grünbichler --- src/bin/proxmox-backup-manager.rs | 105 ++++++++++++++++++++++--- src/bin/proxmox_backup_manager/sync.rs | 2 + 2 files changed, 96 insertions(+), 11 deletions(-) diff --git a/src/bin/proxmox-backup-manager.rs b/src/bin/proxmox-backup-manager.rs index 479ecf03..0c8f2dc7 100644 --- a/src/bin/proxmox-backup-manager.rs +++ b/src/bin/proxmox-backup-manager.rs @@ -1,18 +1,19 @@ use std::collections::HashMap; use std::io::{self, Write}; -use anyhow::{format_err, Error}; +use anyhow::Error; use serde_json::{json, Value}; use proxmox::api::{api, cli::*, RpcEnvironment}; use pbs_client::{connect_to_localhost, display_task_log, view_task_result}; +use pbs_config::sync; use pbs_tools::percent_encoding::percent_encode_component; use pbs_tools::json::required_string_param; use pbs_api_types::{ DATASTORE_SCHEMA, UPID_SCHEMA, REMOTE_ID_SCHEMA, REMOVE_VANISHED_BACKUPS_SCHEMA, IGNORE_VERIFIED_BACKUPS_SCHEMA, VERIFICATION_OUTDATED_AFTER_SCHEMA, - GroupFilterList, + GroupFilterList, SyncJobConfig, }; use proxmox_backup::config; @@ -396,6 +397,7 @@ fn main() { .completion_cb("local-store", pbs_config::datastore::complete_datastore_name) .completion_cb("remote", pbs_config::remote::complete_remote_name) .completion_cb("remote-store", complete_remote_datastore_name) + .completion_cb("groups", complete_remote_datastore_group_filter) ) .insert( "verify", @@ -418,24 +420,105 @@ fn main() { pbs_runtime::main(run_async_cli_command(cmd_def, rpcenv)); } +fn get_sync_job(id: &String) -> Result { + let (config, _digest) = sync::config()?; + + config.lookup("sync", id) +} + +fn get_remote(param: &HashMap) -> Option { + param + .get("remote") + .map(|r| r.to_owned()) + .or_else(|| { + if let Some(id) = param.get("id") { + if let Ok(job) = get_sync_job(id) { + return Some(job.remote.clone()); + } + } + None + }) +} + +fn get_remote_store(param: &HashMap) -> Option<(String, String)> { + let mut job: Option = None; + + let remote = param + .get("remote") + .map(|r| r.to_owned()) + .or_else(|| { + if let Some(id) = param.get("id") { + job = get_sync_job(id).ok(); + if let Some(ref job) = job { + return Some(job.remote.clone()); + } + } + None + }); + + if let Some(remote) = remote { + let store = param + .get("remote-store") + .map(|r| r.to_owned()) + .or_else(|| job.map(|job| job.remote_store.clone())); + + if let Some(store) = store { + return Some((remote, store)) + } + } + + None +} + // shell completion helper pub fn complete_remote_datastore_name(_arg: &str, param: &HashMap) -> Vec { let mut list = Vec::new(); - let _ = proxmox::try_block!({ - let remote = param.get("remote").ok_or_else(|| format_err!("no remote"))?; + if let Some(remote) = get_remote(param) { + if let Ok(data) = pbs_runtime::block_on(async move { + crate::api2::config::remote::scan_remote_datastores(remote).await + }) { - let data = pbs_runtime::block_on(async move { - crate::api2::config::remote::scan_remote_datastores(remote.clone()).await - })?; + for item in data { + list.push(item.store); + } + } + } - for item in data { - list.push(item.store); + list +} + +// shell completion helper +pub fn complete_remote_datastore_group(_arg: &str, param: &HashMap) -> Vec { + + let mut list = Vec::new(); + + if let Some((remote, remote_store)) = get_remote_store(param) { + if let Ok(data) = pbs_runtime::block_on(async move { + crate::api2::config::remote::scan_remote_groups(remote.clone(), remote_store.clone()).await + }) { + + for item in data { + list.push(format!("{}/{}", item.backup_type, item.backup_id)); + } } + } + + list +} + +// shell completion helper +pub fn complete_remote_datastore_group_filter(_arg: &str, param: &HashMap) -> Vec { + + let mut list = Vec::new(); + + list.push("regex:".to_string()); + list.push("type:ct".to_string()); + list.push("type:host".to_string()); + list.push("type:vm".to_string()); - Ok(()) - }).map_err(|_err: Error| { /* ignore */ }); + list.extend(complete_remote_datastore_group(_arg, param).iter().map(|group| format!("group:{}", group))); list } diff --git a/src/bin/proxmox_backup_manager/sync.rs b/src/bin/proxmox_backup_manager/sync.rs index 7a1e8718..2dbef119 100644 --- a/src/bin/proxmox_backup_manager/sync.rs +++ b/src/bin/proxmox_backup_manager/sync.rs @@ -88,6 +88,7 @@ pub fn sync_job_commands() -> CommandLineInterface { .completion_cb("store", pbs_config::datastore::complete_datastore_name) .completion_cb("remote", pbs_config::remote::complete_remote_name) .completion_cb("remote-store", crate::complete_remote_datastore_name) + .completion_cb("groups", crate::complete_remote_datastore_group_filter) ) .insert("update", CliCommand::new(&api2::config::sync::API_METHOD_UPDATE_SYNC_JOB) @@ -96,6 +97,7 @@ pub fn sync_job_commands() -> CommandLineInterface { .completion_cb("schedule", pbs_config::datastore::complete_calendar_event) .completion_cb("store", pbs_config::datastore::complete_datastore_name) .completion_cb("remote-store", crate::complete_remote_datastore_name) + .completion_cb("groups", crate::complete_remote_datastore_group_filter) ) .insert("remove", CliCommand::new(&api2::config::sync::API_METHOD_DELETE_SYNC_JOB) -- 2.30.2