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 BBB147B9BF for ; Tue, 12 Jul 2022 12:23:02 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id B223C26CFD for ; Tue, 12 Jul 2022 12:23:02 +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) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Tue, 12 Jul 2022 12:23:01 +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 6CE7F41F9E for ; Tue, 12 Jul 2022 12:23:01 +0200 (CEST) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Tue, 12 Jul 2022 12:22:59 +0200 Message-Id: <20220712102259.2325389-1-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.099 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 T_SCC_BODY_TEXT_LINE -0.01 - URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [datastore.rs, jobs.rs] Subject: [pbs-devel] [PATCH proxmox-backup] implement prune notifications X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jul 2022 10:23:02 -0000 we converted the prune settings of datastores to prune-jobs, but did not actually implement the notifications for them, even though we had the notification options in the gui (they did not work). implement the basic ok/error notification for prune jobs Signed-off-by: Dominik Csapak --- if we want we could collect some basic info about the pruning, like how many snapshots we removed/kept adding the whole list of which snapshots were kept/deleted does not really make sense to me though, thats the purpose of the task log pbs-api-types/src/jobs.rs | 6 +++ src/api2/config/datastore.rs | 1 + src/server/email_notifications.rs | 74 +++++++++++++++++++++++++++++++ src/server/prune_job.rs | 9 ++++ www/window/NotifyOptions.js | 2 +- 5 files changed, 91 insertions(+), 1 deletion(-) diff --git a/pbs-api-types/src/jobs.rs b/pbs-api-types/src/jobs.rs index 925a1829..3ed964a8 100644 --- a/pbs-api-types/src/jobs.rs +++ b/pbs-api-types/src/jobs.rs @@ -128,6 +128,10 @@ pub enum Notify { type: Notify, optional: true, }, + prune: { + type: Notify, + optional: true, + }, }, )] #[derive(Debug, Serialize, Deserialize)] @@ -139,6 +143,8 @@ pub struct DatastoreNotify { pub verify: Option, /// Sync job setting pub sync: Option, + /// Prune job setting + pub prune: Option, } pub const DATASTORE_NOTIFY_STRING_SCHEMA: Schema = diff --git a/src/api2/config/datastore.rs b/src/api2/config/datastore.rs index 2d769722..08adf7c9 100644 --- a/src/api2/config/datastore.rs +++ b/src/api2/config/datastore.rs @@ -331,6 +331,7 @@ pub fn update_datastore( gc: None, verify: None, sync: None, + prune: None, } = notify { data.notify = None; diff --git a/src/server/email_notifications.rs b/src/server/email_notifications.rs index 6fca4133..e6281e6d 100644 --- a/src/server/email_notifications.rs +++ b/src/server/email_notifications.rs @@ -113,6 +113,34 @@ Remote Store: {{job.remote-store}} Synchronization failed: {{error}} +Please visit the web interface for further details: + + + +"###; + +const PRUNE_OK_TEMPLATE: &str = r###" + +Job ID: {{jobname}} +Datastore: {{store}} + +Pruning successful. + + +Please visit the web interface for further details: + + + +"###; + +const PRUNE_ERR_TEMPLATE: &str = r###" + +Job ID: {{jobname}} +Datastore: {{store}} + +Pruning failed: {{error}} + + Please visit the web interface for further details: @@ -227,6 +255,9 @@ lazy_static::lazy_static! { hb.register_template_string("sync_ok_template", SYNC_OK_TEMPLATE)?; hb.register_template_string("sync_err_template", SYNC_ERR_TEMPLATE)?; + hb.register_template_string("prune_ok_template", PRUNE_OK_TEMPLATE)?; + hb.register_template_string("prune_err_template", PRUNE_ERR_TEMPLATE)?; + hb.register_template_string("tape_backup_ok_template", TAPE_BACKUP_OK_TEMPLATE)?; hb.register_template_string("tape_backup_err_template", TAPE_BACKUP_ERR_TEMPLATE)?; @@ -384,6 +415,48 @@ pub fn send_verify_status( Ok(()) } +pub fn send_prune_status( + email: &str, + notify: DatastoreNotify, + store: &str, + jobname: &str, + result: &Result<(), Error>, +) -> Result<(), Error> { + match notify.prune { + None => { /* send notifications by default */ } + Some(notify) => { + if notify == Notify::Never || (result.is_ok() && notify == Notify::Error) { + return Ok(()); + } + } + } + + let (fqdn, port) = get_server_url(); + let mut data = json!({ + "jobname": jobname, + "store": store, + "fqdn": fqdn, + "port": port, + }); + + let text = match result { + Ok(()) => HANDLEBARS.render("prune_ok_template", &data)?, + Err(err) => { + data["error"] = err.to_string().into(); + HANDLEBARS.render("prune_err_template", &data)? + } + }; + + let subject = match result { + Ok(()) => format!("Pruning datastore '{}' successful", store,), + Err(_) => format!("Pruning datastore '{}' failed", store,), + }; + + send_job_status_mail(email, &subject, &text)?; + + Ok(()) +} + pub fn send_sync_status( email: &str, notify: DatastoreNotify, @@ -581,6 +654,7 @@ pub fn lookup_datastore_notify_settings(store: &str) -> (Option, Datasto gc: None, verify: None, sync: None, + prune: None, }; let (config, _digest) = match pbs_config::datastore::config() { diff --git a/src/server/prune_job.rs b/src/server/prune_job.rs index a62177e4..e9631183 100644 --- a/src/server/prune_job.rs +++ b/src/server/prune_job.rs @@ -169,6 +169,8 @@ pub fn do_prune_job( None => format!("{store}"), }; + let (email, notify) = crate::server::lookup_datastore_notify_settings(&store); + let upid_str = WorkerTask::new_thread( &worker_type, Some(worker_id), @@ -191,6 +193,13 @@ pub fn do_prune_job( eprintln!("could not finish job state for {}: {}", job.jobtype(), err); } + if let Some(email) = email { + if let Err(err) = + crate::server::send_prune_status(&email, notify, &store, job.jobname(), &result) + { + eprintln!("send prune notification failed: {}", err); + } + } result }, )?; diff --git a/www/window/NotifyOptions.js b/www/window/NotifyOptions.js index 924bbb8b..7c7e6489 100644 --- a/www/window/NotifyOptions.js +++ b/www/window/NotifyOptions.js @@ -36,7 +36,7 @@ Ext.define('PBS.window.NotifyOptions', { xtype: 'inputpanel', onGetValues: function(values) { let notify = {}; - for (const k of ['verify', 'sync', 'gc']) { + for (const k of ['verify', 'sync', 'gc', 'prune']) { notify[k] = values[k]; delete values[k]; } -- 2.30.2