1 //! Datastore Verify Job Management
3 use anyhow
::{format_err, Error}
;
6 use proxmox
::api
::router
::SubdirMap
;
7 use proxmox
::{list_subdirs_api_method, sortable}
;
8 use proxmox
::api
::{api, ApiMethod, Permission, Router, RpcEnvironment, RpcEnvironmentType}
;
11 VerificationJobConfig
, VerificationJobStatus
, JOB_ID_SCHEMA
, Authid
,
12 PRIV_DATASTORE_AUDIT
, PRIV_DATASTORE_VERIFY
, DATASTORE_SCHEMA
,
14 use pbs_config
::verify
;
15 use pbs_config
::CachedUserInfo
;
23 compute_schedule_status
,
32 schema
: DATASTORE_SCHEMA
,
38 description
: "List configured jobs and their status (filtered by access)",
40 items
: { type: VerificationJobStatus }
,
43 permission
: &Permission
::Anybody
,
44 description
: "Requires Datastore.Audit or Datastore.Verify on datastore.",
47 /// List all verification jobs
48 pub fn list_verification_jobs(
49 store
: Option
<String
>,
51 mut rpcenv
: &mut dyn RpcEnvironment
,
52 ) -> Result
<Vec
<VerificationJobStatus
>, Error
> {
53 let auth_id
: Authid
= rpcenv
.get_auth_id().unwrap().parse()?
;
54 let user_info
= CachedUserInfo
::new()?
;
56 let required_privs
= PRIV_DATASTORE_AUDIT
| PRIV_DATASTORE_VERIFY
;
58 let (config
, digest
) = verify
::config()?
;
60 let job_config_iter
= config
61 .convert_to_typed_array("verification")?
63 .filter(|job
: &VerificationJobConfig
| {
64 let privs
= user_info
.lookup_privs(&auth_id
, &["datastore", &job
.store
]);
65 if privs
& required_privs
== 0 {
69 if let Some(store
) = &store
{
76 let mut list
= Vec
::new();
78 for job
in job_config_iter
{
79 let last_state
= JobState
::load("verificationjob", &job
.id
)
80 .map_err(|err
| format_err
!("could not open statefile for {}: {}", &job
.id
, err
))?
;
82 let status
= compute_schedule_status(&last_state
, job
.schedule
.as_deref())?
;
84 list
.push(VerificationJobStatus { config: job, status }
);
87 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
96 schema
: JOB_ID_SCHEMA
,
101 permission
: &Permission
::Anybody
,
102 description
: "Requires Datastore.Verify on job's datastore.",
105 /// Runs a verification job manually.
106 pub fn run_verification_job(
109 rpcenv
: &mut dyn RpcEnvironment
,
110 ) -> Result
<String
, Error
> {
111 let auth_id
: Authid
= rpcenv
.get_auth_id().unwrap().parse()?
;
112 let user_info
= CachedUserInfo
::new()?
;
114 let (config
, _digest
) = verify
::config()?
;
115 let verification_job
: VerificationJobConfig
= config
.lookup("verification", &id
)?
;
117 user_info
.check_privs(&auth_id
, &["datastore", &verification_job
.store
], PRIV_DATASTORE_VERIFY
, true)?
;
119 let job
= Job
::new("verificationjob", &id
)?
;
120 let to_stdout
= rpcenv
.env_type() == RpcEnvironmentType
::CLI
;
122 let upid_str
= do_verification_job(job
, verification_job
, &auth_id
, None
, to_stdout
)?
;
128 const VERIFICATION_INFO_SUBDIRS
: SubdirMap
= &[("run", &Router
::new().post(&API_METHOD_RUN_VERIFICATION_JOB
))];
130 const VERIFICATION_INFO_ROUTER
: Router
= Router
::new()
131 .get(&list_subdirs_api_method
!(VERIFICATION_INFO_SUBDIRS
))
132 .subdirs(VERIFICATION_INFO_SUBDIRS
);
134 pub const ROUTER
: Router
= Router
::new()
135 .get(&API_METHOD_LIST_VERIFICATION_JOBS
)
136 .match_all("id", &VERIFICATION_INFO_ROUTER
);