api2/tape/backup: include a summary on notification e-mails
for now only contains the list of included snapshots (if any), as well as the backup duration Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
eac1beef3c
commit
4abd4dbe38
@ -33,6 +33,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
server::{
|
server::{
|
||||||
lookup_user_email,
|
lookup_user_email,
|
||||||
|
TapeBackupJobSummary,
|
||||||
jobstate::{
|
jobstate::{
|
||||||
Job,
|
Job,
|
||||||
JobState,
|
JobState,
|
||||||
@ -198,13 +199,16 @@ pub fn do_tape_backup_job(
|
|||||||
let notify_user = setup.notify_user.as_ref().unwrap_or_else(|| &Userid::root_userid());
|
let notify_user = setup.notify_user.as_ref().unwrap_or_else(|| &Userid::root_userid());
|
||||||
let email = lookup_user_email(notify_user);
|
let email = lookup_user_email(notify_user);
|
||||||
|
|
||||||
let job_result = backup_worker(
|
let (job_result, summary) = match backup_worker(
|
||||||
&worker,
|
&worker,
|
||||||
datastore,
|
datastore,
|
||||||
&pool_config,
|
&pool_config,
|
||||||
&setup,
|
&setup,
|
||||||
email.clone(),
|
email.clone(),
|
||||||
);
|
) {
|
||||||
|
Ok(summary) => (Ok(()), summary),
|
||||||
|
Err(err) => (Err(err), Default::default()),
|
||||||
|
};
|
||||||
|
|
||||||
let status = worker.create_state(&job_result);
|
let status = worker.create_state(&job_result);
|
||||||
|
|
||||||
@ -214,6 +218,7 @@ pub fn do_tape_backup_job(
|
|||||||
Some(job.jobname()),
|
Some(job.jobname()),
|
||||||
&setup,
|
&setup,
|
||||||
&job_result,
|
&job_result,
|
||||||
|
summary,
|
||||||
) {
|
) {
|
||||||
eprintln!("send tape backup notification failed: {}", err);
|
eprintln!("send tape backup notification failed: {}", err);
|
||||||
}
|
}
|
||||||
@ -340,13 +345,17 @@ pub fn backup(
|
|||||||
move |worker| {
|
move |worker| {
|
||||||
let _drive_lock = drive_lock; // keep lock guard
|
let _drive_lock = drive_lock; // keep lock guard
|
||||||
set_tape_device_state(&setup.drive, &worker.upid().to_string())?;
|
set_tape_device_state(&setup.drive, &worker.upid().to_string())?;
|
||||||
let job_result = backup_worker(
|
|
||||||
|
let (job_result, summary) = match backup_worker(
|
||||||
&worker,
|
&worker,
|
||||||
datastore,
|
datastore,
|
||||||
&pool_config,
|
&pool_config,
|
||||||
&setup,
|
&setup,
|
||||||
email.clone(),
|
email.clone(),
|
||||||
);
|
) {
|
||||||
|
Ok(summary) => (Ok(()), summary),
|
||||||
|
Err(err) => (Err(err), Default::default()),
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(email) = email {
|
if let Some(email) = email {
|
||||||
if let Err(err) = crate::server::send_tape_backup_status(
|
if let Err(err) = crate::server::send_tape_backup_status(
|
||||||
@ -354,6 +363,7 @@ pub fn backup(
|
|||||||
None,
|
None,
|
||||||
&setup,
|
&setup,
|
||||||
&job_result,
|
&job_result,
|
||||||
|
summary,
|
||||||
) {
|
) {
|
||||||
eprintln!("send tape backup notification failed: {}", err);
|
eprintln!("send tape backup notification failed: {}", err);
|
||||||
}
|
}
|
||||||
@ -374,9 +384,11 @@ fn backup_worker(
|
|||||||
pool_config: &MediaPoolConfig,
|
pool_config: &MediaPoolConfig,
|
||||||
setup: &TapeBackupJobSetup,
|
setup: &TapeBackupJobSetup,
|
||||||
email: Option<String>,
|
email: Option<String>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<TapeBackupJobSummary, Error> {
|
||||||
|
|
||||||
let status_path = Path::new(TAPE_STATUS_DIR);
|
let status_path = Path::new(TAPE_STATUS_DIR);
|
||||||
|
let start = std::time::Instant::now();
|
||||||
|
let mut summary: TapeBackupJobSummary = Default::default();
|
||||||
|
|
||||||
let _lock = MediaPool::lock(status_path, &pool_config.name)?;
|
let _lock = MediaPool::lock(status_path, &pool_config.name)?;
|
||||||
|
|
||||||
@ -422,8 +434,11 @@ fn backup_worker(
|
|||||||
task_log!(worker, "skip snapshot {}", info.backup_dir);
|
task_log!(worker, "skip snapshot {}", info.backup_dir);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
let snapshot_name = info.backup_dir.to_string();
|
||||||
if !backup_snapshot(worker, &mut pool_writer, datastore.clone(), info.backup_dir)? {
|
if !backup_snapshot(worker, &mut pool_writer, datastore.clone(), info.backup_dir)? {
|
||||||
errors = true;
|
errors = true;
|
||||||
|
} else {
|
||||||
|
summary.snapshot_list.push(snapshot_name);
|
||||||
}
|
}
|
||||||
progress.done_snapshots = 1;
|
progress.done_snapshots = 1;
|
||||||
task_log!(
|
task_log!(
|
||||||
@ -439,8 +454,11 @@ fn backup_worker(
|
|||||||
task_log!(worker, "skip snapshot {}", info.backup_dir);
|
task_log!(worker, "skip snapshot {}", info.backup_dir);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
let snapshot_name = info.backup_dir.to_string();
|
||||||
if !backup_snapshot(worker, &mut pool_writer, datastore.clone(), info.backup_dir)? {
|
if !backup_snapshot(worker, &mut pool_writer, datastore.clone(), info.backup_dir)? {
|
||||||
errors = true;
|
errors = true;
|
||||||
|
} else {
|
||||||
|
summary.snapshot_list.push(snapshot_name);
|
||||||
}
|
}
|
||||||
progress.done_snapshots = snapshot_number as u64 + 1;
|
progress.done_snapshots = snapshot_number as u64 + 1;
|
||||||
task_log!(
|
task_log!(
|
||||||
@ -478,7 +496,9 @@ fn backup_worker(
|
|||||||
bail!("Tape backup finished with some errors. Please check the task log.");
|
bail!("Tape backup finished with some errors. Please check the task log.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
summary.duration = start.elapsed();
|
||||||
|
|
||||||
|
Ok(summary)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to update the the media online status
|
// Try to update the the media online status
|
||||||
|
@ -149,6 +149,14 @@ Datastore: {{job.store}}
|
|||||||
Tape Pool: {{job.pool}}
|
Tape Pool: {{job.pool}}
|
||||||
Tape Drive: {{job.drive}}
|
Tape Drive: {{job.drive}}
|
||||||
|
|
||||||
|
{{#if snapshot-list ~}}
|
||||||
|
Snapshots included:
|
||||||
|
|
||||||
|
{{#each snapshot-list~}}
|
||||||
|
{{this}}
|
||||||
|
{{/each~}}
|
||||||
|
{{/if}}
|
||||||
|
Duration: {{duration}}
|
||||||
|
|
||||||
Tape Backup successful.
|
Tape Backup successful.
|
||||||
|
|
||||||
@ -215,6 +223,15 @@ lazy_static::lazy_static!{
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Summary of a successful Tape Job
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct TapeBackupJobSummary {
|
||||||
|
/// The list of snaphots backed up
|
||||||
|
pub snapshot_list: Vec<String>,
|
||||||
|
/// The total time of the backup job
|
||||||
|
pub duration: std::time::Duration,
|
||||||
|
}
|
||||||
|
|
||||||
fn send_job_status_mail(
|
fn send_job_status_mail(
|
||||||
email: &str,
|
email: &str,
|
||||||
subject: &str,
|
subject: &str,
|
||||||
@ -412,14 +429,18 @@ pub fn send_tape_backup_status(
|
|||||||
id: Option<&str>,
|
id: Option<&str>,
|
||||||
job: &TapeBackupJobSetup,
|
job: &TapeBackupJobSetup,
|
||||||
result: &Result<(), Error>,
|
result: &Result<(), Error>,
|
||||||
|
summary: TapeBackupJobSummary,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let (fqdn, port) = get_server_url();
|
let (fqdn, port) = get_server_url();
|
||||||
|
let duration: crate::tools::systemd::time::TimeSpan = summary.duration.into();
|
||||||
let mut data = json!({
|
let mut data = json!({
|
||||||
"job": job,
|
"job": job,
|
||||||
"fqdn": fqdn,
|
"fqdn": fqdn,
|
||||||
"port": port,
|
"port": port,
|
||||||
"id": id,
|
"id": id,
|
||||||
|
"snapshot-list": summary.snapshot_list,
|
||||||
|
"duration": duration.to_string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let text = match result {
|
let text = match result {
|
||||||
|
Loading…
Reference in New Issue
Block a user