public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: Hannes Laimer <h.laimer@proxmox.com>
Cc: pbs-devel@lists.proxmox.com
Subject: Re: [pbs-devel] [PATCH v2 proxmox-backup 03/15] api2: add verify job config endpoint
Date: Thu, 8 Oct 2020 10:22:55 +0200	[thread overview]
Message-ID: <20201008082255.x73lsqkt6r7payt4@olga.proxmox.com> (raw)
In-Reply-To: <20201007090324.42928-4-h.laimer@proxmox.com>

On Wed, Oct 07, 2020 at 11:03:12AM +0200, Hannes Laimer wrote:
> Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
> ---
>  src/api2/config.rs        |   2 +
>  src/api2/config/verify.rs | 275 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 277 insertions(+)
>  create mode 100644 src/api2/config/verify.rs
> 
> diff --git a/src/api2/config.rs b/src/api2/config.rs
> index be7397c8..7a5129c7 100644
> --- a/src/api2/config.rs
> +++ b/src/api2/config.rs
> @@ -4,11 +4,13 @@ use proxmox::list_subdirs_api_method;
>  pub mod datastore;
>  pub mod remote;
>  pub mod sync;
> +pub mod verify;
>  
>  const SUBDIRS: SubdirMap = &[
>      ("datastore", &datastore::ROUTER),
>      ("remote", &remote::ROUTER),
>      ("sync", &sync::ROUTER),
> +    ("verify", &verify::ROUTER)
>  ];
>  
>  pub const ROUTER: Router = Router::new()
> diff --git a/src/api2/config/verify.rs b/src/api2/config/verify.rs
> new file mode 100644
> index 00000000..9897aaf9
> --- /dev/null
> +++ b/src/api2/config/verify.rs
> @@ -0,0 +1,275 @@
> +use anyhow::{bail, Error};
> +use serde_json::Value;
> +use ::serde::{Deserialize, Serialize};
> +
> +use proxmox::api::{api, Router, RpcEnvironment};
> +use proxmox::tools::fs::open_file_locked;
> +
> +use crate::api2::types::*;
> +use crate::config::verify::{self, VerifyJobConfig};
> +
> +#[api(
> +    input: {
> +        properties: {},
> +    },
> +    returns: {
> +        description: "List configured jobs.",
> +        type: Array,
> +        items: { type: verify::VerifyJobConfig },
> +    },
> +)]
> +/// List all verify jobs
> +pub fn list_verify_jobs(
> +    _param: Value,
> +    mut rpcenv: &mut dyn RpcEnvironment,
> +) -> Result<Vec<VerifyJobConfig>, Error> {
> +
> +    let (config, digest) = verify::config()?;
> +
> +    let list = config.convert_to_typed_array("verify")?;
> +
> +    rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into();
> +
> +    Ok(list)
> +}
> +
> +
> +#[api(
> +    protected: true,
> +    input: {
> +        properties: {
> +            id: {
> +                schema: JOB_ID_SCHEMA,
> +            },
> +            store: {
> +                schema: DATASTORE_SCHEMA,
> +            },
> +            "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: VERIFY_SCHEDULE_SCHEMA,
> +            },
> +        }
> +    }
> +)]
> +/// Create a new verify job.
> +pub fn create_verify_job(param: Value) -> Result<(), Error> {
> +
> +    let _lock = open_file_locked(verify::VERIFY_CFG_LOCKFILE, std::time::Duration::new(10, 0), true)?;
> +
> +    let verify_job: verify::VerifyJobConfig = serde_json::from_value(param.clone())?;
> +
> +    let (mut config, _digest) = verify::config()?;
> +
> +    if let Some(_) = config.sections.get(&verify_job.id) {
> +        bail!("job '{}' already exists.", verify_job.id);
> +    }
> +
> +    config.set_data(&verify_job.id, "verify", &verify_job)?;
> +
> +    verify::save_config(&config)?;
> +
> +    crate::config::jobstate::create_state_file("verifyjob", &verify_job.id)?;
> +
> +    Ok(())
> +}
> +
> +#[api(
> +   input: {
> +        properties: {
> +            id: {
> +                schema: JOB_ID_SCHEMA,
> +            },
> +        },
> +    },
> +    returns: {
> +        description: "The verify job configuration.",
> +        type: verify::VerifyJobConfig,
> +    },
> +)]
> +/// Read a verify job configuration.
> +pub fn read_verify_job(
> +    id: String,
> +    mut rpcenv: &mut dyn RpcEnvironment,
> +) -> Result<VerifyJobConfig, Error> {
> +    let (config, digest) = verify::config()?;
> +
> +    let verify_job = config.lookup("verify", &id)?;
> +    rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into();
> +
> +    Ok(verify_job)
> +}
> +
> +#[api()]
> +#[derive(Serialize, Deserialize)]
> +#[serde(rename_all="kebab-case")]
> +#[allow(non_camel_case_types)]

You already `rename-all`, please drop the non-camel-case-types and just
use standard style.

> +/// Deletable property name
> +pub enum DeletableProperty {
> +    /// Delete ignore verified
> +    ignore_verified,
> +    /// Delete the comment property.
> +    comment,
> +    /// Delete the job schedule.
> +    schedule,
> +    /// Delete outdated_after.
> +    outdated_after
> +}
> +
> +#[api(
> +    protected: true,
> +    input: {
> +        properties: {
> +            id: {
> +                schema: JOB_ID_SCHEMA,
> +            },
> +            store: {
> +                optional: true,
> +                schema: DATASTORE_SCHEMA,
> +            },
> +            "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: VERIFY_SCHEDULE_SCHEMA,
> +            },

^ This is the part that needs actual fixing in the schema, because this
is where all the properties become optional. (That wouldn't striclty be
necessary, though, I mean most of the time we have the complete data
available already anyway before doing the call...)
But before this can be fixed in the `#[api]` macro it needs to be fixed
in the schema code itself.

> +            delete: {
> +                description: "List of properties to delete.",
> +                type: Array,
> +                optional: true,
> +                items: {
> +                    type: DeletableProperty,
> +                }
> +            },
> +            digest: {
> +                optional: true,
> +                schema: PROXMOX_CONFIG_DIGEST_SCHEMA,
> +            },
> +        },
> +    },
> +)]
> +/// Update verify job config.
> +pub fn update_verify_job(
> +    id: String,
> +    store: Option<String>,
> +    ignore_verified: Option<bool>,
> +    outdated_after: Option<i64>,
> +    comment: Option<String>,
> +    schedule: Option<String>,
> +    delete: Option<Vec<DeletableProperty>>,
> +    digest: Option<String>,
> +) -> Result<(), Error> {
> +
> +    let _lock = open_file_locked(verify::VERIFY_CFG_LOCKFILE, std::time::Duration::new(10, 0), true)?;
> +
> +    // pass/compare digest
> +    let (mut config, expected_digest) = verify::config()?;
> +
> +    if let Some(ref digest) = digest {
> +        let digest = proxmox::tools::hex_to_digest(digest)?;
> +        crate::tools::detect_modified_configuration_file(&digest, &expected_digest)?;
> +    }
> +
> +    let mut data: verify::VerifyJobConfig = config.lookup("verify", &id)?;
> +
> +     if let Some(delete) = delete {
> +        for delete_prop in delete {
> +            match delete_prop {
> +                DeletableProperty::ignore_verified => { data.ignore_verified = None; },
> +                DeletableProperty::outdated_after => { data.outdated_after = None; },
> +                DeletableProperty::comment => { data.comment = None; },
> +                DeletableProperty::schedule => { data.schedule = None; },
> +            }
> +        }
> +    }
> +
> +    if let Some(comment) = comment {
> +        let comment = comment.trim().to_string();
> +        if comment.is_empty() {
> +            data.comment = None;
> +        } else {
> +            data.comment = Some(comment);
> +        }
> +    }
> +
> +    if let Some(store) = store { data.store = store; }
> +
> +    if ignore_verified.is_some() { data.ignore_verified = ignore_verified; }
> +    if outdated_after.is_some() { data.outdated_after = outdated_after; }
> +    if schedule.is_some() { data.schedule = schedule; }
> +
> +    config.set_data(&id, "verify", &data)?;
> +
> +    verify::save_config(&config)?;
> +
> +    Ok(())
> +}
> +
> +#[api(
> +    protected: true,
> +    input: {
> +        properties: {
> +            id: {
> +                schema: JOB_ID_SCHEMA,
> +            },
> +            digest: {
> +                optional: true,
> +                schema: PROXMOX_CONFIG_DIGEST_SCHEMA,
> +            },
> +        },
> +    },
> +)]
> +/// Remove a verify job configuration
> +pub fn delete_verify_job(id: String, digest: Option<String>) -> Result<(), Error> {
> +
> +    let _lock = open_file_locked(verify::VERIFY_CFG_LOCKFILE, std::time::Duration::new(10, 0), true)?;
> +
> +    let (mut config, expected_digest) = verify::config()?;
> +
> +    if let Some(ref digest) = digest {
> +        let digest = proxmox::tools::hex_to_digest(digest)?;
> +        crate::tools::detect_modified_configuration_file(&digest, &expected_digest)?;
> +    }
> +
> +    match config.sections.get(&id) {
> +        Some(_) => { config.sections.remove(&id); },
> +        None => bail!("job '{}' does not exist.", id),
> +    }
> +
> +    verify::save_config(&config)?;
> +
> +    crate::config::jobstate::remove_state_file("verifyjob", &id)?;
> +
> +    Ok(())
> +}
> +
> +const ITEM_ROUTER: Router = Router::new()
> +    .get(&API_METHOD_READ_VERIFY_JOB)
> +    .put(&API_METHOD_UPDATE_VERIFY_JOB)
> +    .delete(&API_METHOD_DELETE_VERIFY_JOB);
> +
> +pub const ROUTER: Router = Router::new()
> +    .get(&API_METHOD_LIST_VERIFY_JOBS)
> +    .post(&API_METHOD_CREATE_VERIFY_JOB)
> +    .match_all("id", &ITEM_ROUTER);
> \ No newline at end of file
> -- 
> 2.20.1




  reply	other threads:[~2020-10-08  8:23 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-07  9:03 [pbs-devel] [PATCH v2 proxmox-backup 00/15] add job based verify scheduling Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 01/15] add two new schemas for verify jobs Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 02/15] add verify job config Hannes Laimer
2020-10-08  7:50   ` Wolfgang Bumiller
2020-10-08  8:15     ` Dominik Csapak
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 03/15] api2: add verify job config endpoint Hannes Laimer
2020-10-08  8:22   ` Wolfgang Bumiller [this message]
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 04/15] add do_verification_job function to verify.rs Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 05/15] api2: add verify job admin endpoint Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 06/15] add scheduling for verify jobs Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 07/15] set a diffrent worker_type based on what is going to be verified(snapshot, group, ds) Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 08/15] ui: add verify job view Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 09/15] ui: add verify job edit window Hannes Laimer
2020-10-08  9:58   ` Dominik Csapak
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 10/15] ui: add task descriptions for the different types of verify(job, snapshot, group, ds) Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 11/15] remove verify_schedule field from DatastoreConfig Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 12/15] remove verify_schedule field from datastore config endpoint Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 13/15] remove verify-schedule field from DataStoreEdit and DataStoreConfig Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 14/15] remove old verification scheduling from proxmox-backup-proxy.rs Hannes Laimer
2020-10-07  9:03 ` [pbs-devel] [PATCH v2 proxmox-backup 15/15] verify job: log number of planned verifications Hannes Laimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201008082255.x73lsqkt6r7payt4@olga.proxmox.com \
    --to=w.bumiller@proxmox.com \
    --cc=h.laimer@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal