cleanup: use serde(flatten) for VerificationJobStatus, improve code reuse
This commit is contained in:
parent
70842b9ef2
commit
1917ea3ce1
|
@ -1,24 +1,40 @@
|
||||||
//! Datastore Verify Job Management
|
//! Datastore Verify Job Management
|
||||||
|
|
||||||
use anyhow::{format_err, Error};
|
use anyhow::{format_err, Error};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
use proxmox::api::router::SubdirMap;
|
use proxmox::api::router::SubdirMap;
|
||||||
use proxmox::{list_subdirs_api_method, sortable};
|
use proxmox::{list_subdirs_api_method, sortable};
|
||||||
use proxmox::api::{api, ApiMethod, Permission, Router, RpcEnvironment};
|
use proxmox::api::{api, ApiMethod, Permission, Router, RpcEnvironment};
|
||||||
|
|
||||||
use crate::api2::types::*;
|
use crate::{
|
||||||
use crate::server::do_verification_job;
|
api2::types::{
|
||||||
use crate::server::jobstate::{Job, JobState};
|
DATASTORE_SCHEMA,
|
||||||
use crate::config::acl::{
|
JOB_ID_SCHEMA,
|
||||||
PRIV_DATASTORE_AUDIT,
|
Authid,
|
||||||
PRIV_DATASTORE_VERIFY,
|
},
|
||||||
|
server::{
|
||||||
|
do_verification_job,
|
||||||
|
jobstate::{
|
||||||
|
Job,
|
||||||
|
JobState,
|
||||||
|
compute_schedule_status,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config::{
|
||||||
|
acl::{
|
||||||
|
PRIV_DATASTORE_AUDIT,
|
||||||
|
PRIV_DATASTORE_VERIFY,
|
||||||
|
},
|
||||||
|
cached_user_info::CachedUserInfo,
|
||||||
|
verify::{
|
||||||
|
self,
|
||||||
|
VerificationJobConfig,
|
||||||
|
VerificationJobStatus,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use crate::config::cached_user_info::CachedUserInfo;
|
|
||||||
use crate::config::verify;
|
|
||||||
use crate::config::verify::{VerificationJobConfig, VerificationJobStatus};
|
|
||||||
use serde_json::Value;
|
|
||||||
use crate::tools::systemd::time::{parse_calendar_event, compute_next_event};
|
|
||||||
use crate::server::UPID;
|
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
input: {
|
input: {
|
||||||
|
@ -52,10 +68,10 @@ pub fn list_verification_jobs(
|
||||||
|
|
||||||
let (config, digest) = verify::config()?;
|
let (config, digest) = verify::config()?;
|
||||||
|
|
||||||
let mut list: Vec<VerificationJobStatus> = config
|
let job_config_iter = config
|
||||||
.convert_to_typed_array("verification")?
|
.convert_to_typed_array("verification")?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|job: &VerificationJobStatus| {
|
.filter(|job: &VerificationJobConfig| {
|
||||||
let privs = user_info.lookup_privs(&auth_id, &["datastore", &job.store]);
|
let privs = user_info.lookup_privs(&auth_id, &["datastore", &job.store]);
|
||||||
if privs & required_privs == 0 {
|
if privs & required_privs == 0 {
|
||||||
return false;
|
return false;
|
||||||
|
@ -66,36 +82,17 @@ pub fn list_verification_jobs(
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}).collect();
|
});
|
||||||
|
|
||||||
for job in &mut list {
|
let mut list = Vec::new();
|
||||||
|
|
||||||
|
for job in job_config_iter {
|
||||||
let last_state = JobState::load("verificationjob", &job.id)
|
let last_state = JobState::load("verificationjob", &job.id)
|
||||||
.map_err(|err| format_err!("could not open statefile for {}: {}", &job.id, err))?;
|
.map_err(|err| format_err!("could not open statefile for {}: {}", &job.id, err))?;
|
||||||
|
|
||||||
let (upid, endtime, state, starttime) = match last_state {
|
let status = compute_schedule_status(&last_state, job.schedule.as_deref())?;
|
||||||
JobState::Created { time } => (None, None, None, time),
|
|
||||||
JobState::Started { upid } => {
|
|
||||||
let parsed_upid: UPID = upid.parse()?;
|
|
||||||
(Some(upid), None, None, parsed_upid.starttime)
|
|
||||||
},
|
|
||||||
JobState::Finished { upid, state } => {
|
|
||||||
let parsed_upid: UPID = upid.parse()?;
|
|
||||||
(Some(upid), Some(state.endtime()), Some(state.to_string()), parsed_upid.starttime)
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
job.last_run_upid = upid;
|
list.push(VerificationJobStatus { config: job, status });
|
||||||
job.last_run_state = state;
|
|
||||||
job.last_run_endtime = endtime;
|
|
||||||
|
|
||||||
let last = job.last_run_endtime.unwrap_or(starttime);
|
|
||||||
|
|
||||||
job.next_run = (|| -> Option<i64> {
|
|
||||||
let schedule = job.schedule.as_ref()?;
|
|
||||||
let event = parse_calendar_event(&schedule).ok()?;
|
|
||||||
// ignore errors
|
|
||||||
compute_next_event(&event, last, false).unwrap_or(None)
|
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into();
|
rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into();
|
||||||
|
|
|
@ -70,88 +70,26 @@ pub struct VerificationJobConfig {
|
||||||
pub schedule: Option<String>,
|
pub schedule: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
properties: {
|
properties: {
|
||||||
id: {
|
config: {
|
||||||
schema: JOB_ID_SCHEMA,
|
type: VerificationJobConfig,
|
||||||
},
|
},
|
||||||
store: {
|
status: {
|
||||||
schema: DATASTORE_SCHEMA,
|
type: JobScheduleStatus,
|
||||||
},
|
},
|
||||||
"ignore-verified": {
|
},
|
||||||
optional: true,
|
|
||||||
schema: IGNORE_VERIFIED_BACKUPS_SCHEMA,
|
|
||||||
},
|
|
||||||
"outdated-after": {
|
|
||||||
optional: true,
|
|
||||||
schema: VERIFICATION_OUTDATED_AFTER_SCHEMA,
|
|
||||||
},
|
|
||||||
comment: {
|
|
||||||
optional: true,
|
|
||||||
schema: SINGLE_LINE_COMMENT_SCHEMA,
|
|
||||||
},
|
|
||||||
schedule: {
|
|
||||||
optional: true,
|
|
||||||
schema: VERIFICATION_SCHEDULE_SCHEMA,
|
|
||||||
},
|
|
||||||
"next-run": {
|
|
||||||
description: "Estimated time of the next run (UNIX epoch).",
|
|
||||||
optional: true,
|
|
||||||
type: Integer,
|
|
||||||
},
|
|
||||||
"last-run-state": {
|
|
||||||
description: "Result of the last run.",
|
|
||||||
optional: true,
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
"last-run-upid": {
|
|
||||||
description: "Task UPID of the last run.",
|
|
||||||
optional: true,
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
"last-run-endtime": {
|
|
||||||
description: "Endtime of the last run.",
|
|
||||||
optional: true,
|
|
||||||
type: Integer,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)]
|
)]
|
||||||
#[serde(rename_all="kebab-case")]
|
#[serde(rename_all="kebab-case")]
|
||||||
#[derive(Serialize,Deserialize)]
|
#[derive(Serialize,Deserialize)]
|
||||||
/// Status of Verification Job
|
/// Status of Verification Job
|
||||||
pub struct VerificationJobStatus {
|
pub struct VerificationJobStatus {
|
||||||
/// unique ID to address this job
|
#[serde(flatten)]
|
||||||
pub id: String,
|
pub config: VerificationJobConfig,
|
||||||
/// the datastore ID this verificaiton job affects
|
#[serde(flatten)]
|
||||||
pub store: String,
|
pub status: JobScheduleStatus,
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
/// if not set to false, check the age of the last snapshot verification to filter
|
|
||||||
/// out recent ones, depending on 'outdated_after' configuration.
|
|
||||||
pub ignore_verified: Option<bool>,
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
/// Reverify snapshots after X days, never if 0. Ignored if 'ignore_verified' is false.
|
|
||||||
pub outdated_after: Option<i64>,
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
pub comment: Option<String>,
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
/// when to schedule this job in calendar event notation
|
|
||||||
pub schedule: Option<String>,
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
/// The timestamp when this job runs the next time.
|
|
||||||
pub next_run: Option<i64>,
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
/// The state of the last scheduled run, if any
|
|
||||||
pub last_run_state: Option<String>,
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
/// The task UPID of the last scheduled run, if any
|
|
||||||
pub last_run_upid: Option<String>,
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
|
||||||
/// When the last run was finished, combined with UPID.starttime one can calculate the duration
|
|
||||||
pub last_run_endtime: Option<i64>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn init() -> SectionConfig {
|
fn init() -> SectionConfig {
|
||||||
let obj_schema = match VerificationJobConfig::API_SCHEMA {
|
let obj_schema = match VerificationJobConfig::API_SCHEMA {
|
||||||
Schema::Object(ref obj_schema) => obj_schema,
|
Schema::Object(ref obj_schema) => obj_schema,
|
||||||
|
|
Loading…
Reference in New Issue