diff --git a/src/api2/tape/backup.rs b/src/api2/tape/backup.rs index 66a89d51..06f75f92 100644 --- a/src/api2/tape/backup.rs +++ b/src/api2/tape/backup.rs @@ -31,6 +31,7 @@ use crate::{ }, }, server::{ + lookup_user_email, jobstate::{ Job, JobState, @@ -47,6 +48,7 @@ use crate::{ UPID_SCHEMA, JOB_ID_SCHEMA, MediaPoolConfig, + Userid, }, server::WorkerTask, task::TaskState, @@ -350,7 +352,10 @@ fn backup_worker( let pool = MediaPool::with_config(status_path, &pool_config, changer_name)?; - let mut pool_writer = PoolWriter::new(pool, &setup.drive, worker)?; + let notify_user = setup.notify_user.as_ref().unwrap_or_else(|| &Userid::root_userid()); + let email = lookup_user_email(notify_user); + + let mut pool_writer = PoolWriter::new(pool, &setup.drive, worker, email)?; let mut group_list = BackupInfo::list_backup_groups(&datastore.base_path())?; diff --git a/src/api2/tape/restore.rs b/src/api2/tape/restore.rs index 22da07b8..504bc296 100644 --- a/src/api2/tape/restore.rs +++ b/src/api2/tape/restore.rs @@ -33,6 +33,7 @@ use crate::{ DRIVE_NAME_SCHEMA, UPID_SCHEMA, Authid, + Userid, }, config::{ self, @@ -55,7 +56,10 @@ use crate::{ DynamicIndexReader, FixedIndexReader, }, - server::WorkerTask, + server::{ + lookup_user_email, + WorkerTask, + }, tape::{ TAPE_STATUS_DIR, TapeRead, @@ -97,6 +101,10 @@ pub const ROUTER: Router = Router::new() description: "Media set UUID.", type: String, }, + "notify-user": { + type: Userid, + optional: true, + }, }, }, returns: { @@ -114,6 +122,7 @@ pub fn restore( store: String, drive: String, media_set: String, + notify_user: Option, rpcenv: &mut dyn RpcEnvironment, ) -> Result { @@ -212,6 +221,7 @@ pub fn restore( &drive, &datastore, &auth_id, + ¬ify_user, )?; } @@ -241,6 +251,7 @@ pub fn request_and_restore_media( drive_name: &str, datastore: &DataStore, authid: &Authid, + notify_user: &Option, ) -> Result<(), Error> { let media_set_uuid = match media_id.media_set_label { @@ -248,7 +259,12 @@ pub fn request_and_restore_media( Some(ref set) => &set.uuid, }; - let (mut drive, info) = request_and_load_media(worker, &drive_config, &drive_name, &media_id.label)?; + let email = notify_user + .as_ref() + .and_then(|userid| lookup_user_email(userid)) + .or_else(|| lookup_user_email(&authid.clone().into())); + + let (mut drive, info) = request_and_load_media(worker, &drive_config, &drive_name, &media_id.label, &email)?; match info.media_set_label { None => { diff --git a/src/server/email_notifications.rs b/src/server/email_notifications.rs index 6af6bd38..3ff1be7c 100644 --- a/src/server/email_notifications.rs +++ b/src/server/email_notifications.rs @@ -397,7 +397,7 @@ pub fn send_updates_available( } /// Lookup users email address -fn lookup_user_email(userid: &Userid) -> Option { +pub fn lookup_user_email(userid: &Userid) -> Option { use crate::config::user::{self, User}; diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs index 8bbca98c..c3021dc3 100644 --- a/src/tape/drive/mod.rs +++ b/src/tape/drive/mod.rs @@ -319,6 +319,7 @@ pub fn request_and_load_media( config: &SectionConfigData, drive: &str, label: &MediaLabel, + notify_email: &Option, ) -> Result<( Box, MediaId, @@ -375,9 +376,6 @@ pub fn request_and_load_media( return Ok((handle, media_id)); } - - let to = "root@localhost"; // fixme - let mut last_media_uuid = None; let mut last_error = None; @@ -390,7 +388,9 @@ pub fn request_and_load_media( if tried { if let Some(reason) = failure_reason { task_log!(worker, "Please insert media '{}' into drive '{}'", label_text, drive); - send_load_media_email(drive, &label_text, to, Some(reason))?; + if let Some(to) = notify_email { + send_load_media_email(drive, &label_text, to, Some(reason))?; + } } failure_reason = None; diff --git a/src/tape/pool_writer.rs b/src/tape/pool_writer.rs index a0a54576..2f07699a 100644 --- a/src/tape/pool_writer.rs +++ b/src/tape/pool_writer.rs @@ -64,11 +64,12 @@ pub struct PoolWriter { drive_name: String, status: Option, media_set_catalog: MediaSetCatalog, + notify_email: Option, } impl PoolWriter { - pub fn new(mut pool: MediaPool, drive_name: &str, worker: &WorkerTask) -> Result { + pub fn new(mut pool: MediaPool, drive_name: &str, worker: &WorkerTask, notify_email: Option) -> Result { let current_time = proxmox::tools::time::epoch_i64(); @@ -101,6 +102,7 @@ impl PoolWriter { drive_name: drive_name.to_string(), status: None, media_set_catalog, + notify_email, }) } @@ -227,7 +229,7 @@ impl PoolWriter { let (drive_config, _digest) = crate::config::drive::config()?; let (mut drive, old_media_id) = - request_and_load_media(worker, &drive_config, &self.drive_name, media.label())?; + request_and_load_media(worker, &drive_config, &self.drive_name, media.label(), &self.notify_email)?; // test for critical tape alert flags if let Ok(alert_flags) = drive.tape_alert_flags() {