]> git.proxmox.com Git - proxmox-backup.git/blob - src/server/verify_job.rs
verify: improve code reuse, fix filter function
[proxmox-backup.git] / src / server / verify_job.rs
1 use anyhow::{format_err, Error};
2
3 use crate::{
4 server::WorkerTask,
5 api2::types::*,
6 server::jobstate::Job,
7 config::verify::VerificationJobConfig,
8 backup::{
9 DataStore,
10 BackupInfo,
11 verify_all_backups,
12 },
13 task_log,
14 };
15
16 /// Runs a verification job.
17 pub fn do_verification_job(
18 mut job: Job,
19 verification_job: VerificationJobConfig,
20 userid: &Userid,
21 schedule: Option<String>,
22 ) -> Result<String, Error> {
23
24 let datastore = DataStore::lookup_datastore(&verification_job.store)?;
25
26 let datastore2 = datastore.clone();
27
28 let outdated_after = verification_job.outdated_after.clone();
29 let ignore_verified = verification_job.ignore_verified.unwrap_or(true);
30
31 let filter = move |backup_info: &BackupInfo| {
32 if !ignore_verified {
33 return true;
34 }
35 let manifest = match datastore2.load_manifest(&backup_info.backup_dir) {
36 Ok((manifest, _)) => manifest,
37 Err(_) => return false,
38 };
39
40 let raw_verify_state = manifest.unprotected["verify_state"].clone();
41 let last_state = match serde_json::from_value::<SnapshotVerifyState>(raw_verify_state) {
42 Ok(last_state) => last_state,
43 Err(_) => return true,
44 };
45
46 let now = proxmox::tools::time::epoch_i64();
47 let days_since_last_verify = (now - last_state.upid.starttime) / 86400;
48
49 outdated_after
50 .map(|v| days_since_last_verify > v)
51 .unwrap_or(true)
52 };
53
54 let email = crate::server::lookup_user_email(userid);
55
56 let job_id = job.jobname().to_string();
57 let worker_type = job.jobtype().to_string();
58 let upid_str = WorkerTask::new_thread(
59 &worker_type,
60 Some(job.jobname().to_string()),
61 userid.clone(),
62 false,
63 move |worker| {
64 job.start(&worker.upid().to_string())?;
65
66 task_log!(worker,"Starting datastore verify job '{}'", job_id);
67 if let Some(event_str) = schedule {
68 task_log!(worker,"task triggered by schedule '{}'", event_str);
69 }
70
71 let result = verify_all_backups(datastore, worker.clone(), worker.upid(), &filter);
72 let job_result = match result {
73 Ok(ref errors) if errors.is_empty() => Ok(()),
74 Ok(_) => Err(format_err!("verification failed - please check the log for details")),
75 Err(_) => Err(format_err!("verification failed - job aborted")),
76 };
77
78 let status = worker.create_state(&job_result);
79
80 match job.finish(status) {
81 Err(err) => eprintln!(
82 "could not finish job state for {}: {}",
83 job.jobtype().to_string(),
84 err
85 ),
86 Ok(_) => (),
87 }
88
89 if let Some(email) = email {
90 if let Err(err) = crate::server::send_verify_status(&email, verification_job, &result) {
91 eprintln!("send verify notification failed: {}", err);
92 }
93 }
94
95 job_result
96 },
97 )?;
98 Ok(upid_str)
99 }