public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Christian Ebner <c.ebner@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup 1/3] api-types: client: add type to specify progress log interval
Date: Mon, 21 Oct 2024 14:55:20 +0200	[thread overview]
Message-ID: <20241021125522.237273-2-c.ebner@proxmox.com> (raw)
In-Reply-To: <20241021125522.237273-1-c.ebner@proxmox.com>

Implements the `LogInterval` api type, which will be used to specify
the log progress output interval for the proxmox backup client's
backup command.

Currently, 3 variants of progress log output are allowed:
- none
- time based
- size based

Further, implements the methods to parse the string given as API
parameter into the corresponding variant and value.

The time based variant allows to specify an interval given by a
`TimeSpan` compatible value, the size based variant allows to specify
`HumanByte` compatible interval.
If no explicit variant is specified, the time based variant is used.

Possible parameter values are therefore, e.g.:
- `none` to set no interval (disable logging)
- `1m 30s` to set a time based interval, alternatively the variant
  might be declared explicitly as `time:1m 30s`.
- `size:512MiB` to set a size based log interval

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
 pbs-api-types/src/client.rs | 73 +++++++++++++++++++++++++++++++++++++
 pbs-api-types/src/lib.rs    |  3 ++
 2 files changed, 76 insertions(+)
 create mode 100644 pbs-api-types/src/client.rs

diff --git a/pbs-api-types/src/client.rs b/pbs-api-types/src/client.rs
new file mode 100644
index 000000000..ecc4ad692
--- /dev/null
+++ b/pbs-api-types/src/client.rs
@@ -0,0 +1,73 @@
+use std::str::FromStr;
+
+use anyhow::{bail, Error};
+
+use proxmox_human_byte::HumanByte;
+use proxmox_schema::{const_regex, ApiStringFormat, ApiType, Schema, StringSchema};
+use proxmox_time::TimeSpan;
+
+const_regex! {
+    pub LOG_INTERVAL_REGEX = r"^((none|(size|time):)?[0-9a-z\.\s]*)$";
+}
+
+pub const LOG_INTERVAL_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&LOG_INTERVAL_REGEX);
+pub const LOG_INTERVAL_SCHEMA: Schema = StringSchema::new("Log interval")
+    .format(&ApiStringFormat::VerifyFn(verify_log_interval))
+    .type_text("(none|[(size|time):]value) (default 'time:60s')")
+    .schema();
+
+#[derive(Clone)]
+pub enum LogInterval {
+    None,
+    Size(HumanByte),
+    Time(TimeSpan),
+}
+
+impl Default for LogInterval {
+    fn default() -> Self {
+        Self::Time(TimeSpan::from_str("60s").unwrap())
+    }
+}
+
+impl ApiType for LogInterval {
+    const API_SCHEMA: Schema = LOG_INTERVAL_SCHEMA;
+}
+
+pub fn verify_log_interval(value: &str) -> Result<(), Error> {
+    let _: LogInterval = value.parse()?;
+    Ok(())
+}
+
+impl FromStr for LogInterval {
+    type Err = Error;
+
+    fn from_str(v: &str) -> Result<Self, Self::Err> {
+        let mut split = v.split(':');
+        let interval = match (split.next(), split.next()) {
+            (Some("none"), None) => LogInterval::None,
+            // Default to time if no explicit variant set
+            (Some(value), None) => LogInterval::Time(TimeSpan::from_str(value)?),
+            (Some(variant), Some(value)) => match variant {
+                "size" => LogInterval::Size(HumanByte::from_str(value)?),
+                "time" => LogInterval::Time(TimeSpan::from_str(value)?),
+                variant => bail!(format!("unexpected log interval variant '{variant}'")),
+            },
+            _ => bail!("expected '(none|[variant:]value)'"),
+        };
+
+        Ok(interval)
+    }
+}
+
+impl std::fmt::Display for LogInterval {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            LogInterval::None => write!(f, "none"),
+            LogInterval::Size(value) => write!(f, "size:{value}"),
+            LogInterval::Time(value) => write!(f, "time:{value}"),
+        }
+    }
+}
+
+proxmox_serde::forward_serialize_to_display!(LogInterval);
+proxmox_serde::forward_deserialize_to_from_str!(LogInterval);
diff --git a/pbs-api-types/src/lib.rs b/pbs-api-types/src/lib.rs
index 635292a54..e2eb2f5c6 100644
--- a/pbs-api-types/src/lib.rs
+++ b/pbs-api-types/src/lib.rs
@@ -93,6 +93,9 @@ pub const GROUP_OR_SNAPSHOT_PATH_REGEX_STR: &str =
 mod acl;
 pub use acl::*;
 
+mod client;
+pub use client::*;
+
 mod datastore;
 pub use datastore::*;
 
-- 
2.39.5



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


  reply	other threads:[~2024-10-21 12:55 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-21 12:55 [pbs-devel] [PATCH proxmox-backup 0/3] backup client " Christian Ebner
2024-10-21 12:55 ` Christian Ebner [this message]
2024-10-21 12:55 ` [pbs-devel] [PATCH proxmox-backup 2/3] client: progress log: factor out log message generation Christian Ebner
2024-10-21 12:55 ` [pbs-devel] [PATCH proxmox-backup 3/3] client: progress log: allow to specify backup log interval Christian Ebner
2024-10-21 15:08 ` [pbs-devel] [PATCH proxmox-backup 0/3] backup client progress " Thomas Lamprecht
2024-10-21 16:06   ` Christian Ebner
2024-10-22  5:35     ` Thomas Lamprecht
2024-10-23  9:12 ` Christian Ebner

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=20241021125522.237273-2-c.ebner@proxmox.com \
    --to=c.ebner@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