From: Dominik Csapak <d.csapak@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup v2 2/9] config: add JobState helper
Date: Tue, 11 Aug 2020 11:57:17 +0200 [thread overview]
Message-ID: <20200811095724.26896-3-d.csapak@proxmox.com> (raw)
In-Reply-To: <20200811095724.26896-1-d.csapak@proxmox.com>
this is intended to be a generic helper to (de)serialize job states
(e.g., sync, verify, and so on)
writes a json file into '/var/lib/proxmox-backup/jobstates/TYPE-ID.json'
the api creates the directory with the correct permissions, like
the rrd directory
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes from v1:
* JobState is now an enum
* use dietmars suggestions
src/bin/proxmox-backup-api.rs | 1 +
src/config.rs | 1 +
src/config/jobstate.rs | 125 ++++++++++++++++++++++++++++++++++
3 files changed, 127 insertions(+)
create mode 100644 src/config/jobstate.rs
diff --git a/src/bin/proxmox-backup-api.rs b/src/bin/proxmox-backup-api.rs
index 9dde46c0..ea306cf0 100644
--- a/src/bin/proxmox-backup-api.rs
+++ b/src/bin/proxmox-backup-api.rs
@@ -37,6 +37,7 @@ async fn run() -> Result<(), Error> {
config::update_self_signed_cert(false)?;
proxmox_backup::rrd::create_rrdb_dir()?;
+ proxmox_backup::config::jobstate::create_jobstate_dir()?;
if let Err(err) = generate_auth_key() {
bail!("unable to generate auth key - {}", err);
diff --git a/src/config.rs b/src/config.rs
index 2aeccaec..c2ac6da1 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -18,6 +18,7 @@ use crate::buildcfg;
pub mod acl;
pub mod cached_user_info;
pub mod datastore;
+pub mod jobstate;
pub mod network;
pub mod remote;
pub mod sync;
diff --git a/src/config/jobstate.rs b/src/config/jobstate.rs
new file mode 100644
index 00000000..0e8a3115
--- /dev/null
+++ b/src/config/jobstate.rs
@@ -0,0 +1,125 @@
+use std::fs::File;
+use std::path::{Path, PathBuf};
+use std::time::Duration;
+
+use serde::{Serialize, Deserialize};
+use anyhow::{bail, Error, format_err};
+use proxmox::tools::fs::{file_read_optional_string, replace_file, create_path, CreateOptions, open_file_locked};
+
+use crate::tools::epoch_now_u64;
+use crate::server::TaskState;
+
+#[serde(rename_all="kebab-case")]
+#[derive(Serialize,Deserialize)]
+pub enum JobState {
+ Created { time: i64 },
+ Started { upid: String },
+ Finished { upid: String, endtime: i64, state: TaskState }
+}
+
+const JOB_STATE_BASEDIR: &str = "/var/lib/proxmox-backup/jobstates";
+
+/// Create jobstate stat dir with correct permission
+pub fn create_jobstate_dir() -> Result<(), Error> {
+
+ let backup_user = crate::backup::backup_user()?;
+ let opts = CreateOptions::new()
+ .owner(backup_user.uid)
+ .group(backup_user.gid);
+
+ create_path(JOB_STATE_BASEDIR, None, Some(opts))
+ .map_err(|err: Error| format_err!("unable to create rrdb stat dir - {}", err))?;
+
+ Ok(())
+}
+
+fn get_path(jobtype: &str, jobname: &str) -> Result<PathBuf, Error> {
+ let mut path = PathBuf::from(JOB_STATE_BASEDIR);
+ path.push(format!("{}-{}.json", jobtype, jobname));
+ Ok(path)
+}
+
+fn get_lock<P>(path: P) -> Result<File, Error>
+where
+ P: AsRef<Path>
+{
+ let mut path = path.as_ref().to_path_buf();
+ path.set_extension("lck");
+ open_file_locked(path, Duration::new(10, 0))
+}
+
+pub fn remove_state_file(jobtype: &str, jobname: &str) -> Result<(), Error> {
+ let path = get_path(jobtype, jobname)?;
+ let _lock = get_lock(&path)?;
+ std::fs::remove_file(&path).map_err(|err|
+ format_err!("cannot remove statefile for {} - {}: {}", jobtype, jobname, err)
+ )
+}
+
+impl JobState {
+ pub fn new(upid: &str) -> Self {
+ JobState::Started{
+ upid: upid.to_string(),
+ }
+ }
+
+ pub fn finish(&mut self, state: TaskState) -> Result<(), Error> {
+ let upid = match self {
+ JobState::Created { .. } => bail!("cannot finish when not started"),
+ JobState::Started { upid } => upid,
+ JobState::Finished { upid, .. } => upid,
+ }.to_string();
+
+ let endtime: i64 = epoch_now_u64()? as i64;
+
+ *self = JobState::Finished {
+ upid,
+ endtime,
+ state,
+ };
+
+ Ok(())
+ }
+
+ pub fn try_read_or_create(jobtype: &str, jobname: &str) -> Result<Self, Error> {
+ let path = get_path(jobtype, jobname)?;
+
+ let lock = get_lock(&path)?;
+
+ if let Some(state) = file_read_optional_string(path)? {
+ Ok(serde_json::from_str(&state)?)
+ } else {
+ let state = JobState::Created {
+ time: epoch_now_u64()? as i64
+ };
+ state.write_state(jobtype, jobname, Some(lock))?;
+ Ok(state)
+ }
+ }
+
+ pub fn write_state(&self, jobtype: &str, jobname: &str, lock: Option<File>) -> Result<(), Error> {
+ let serialized = serde_json::to_string(&self)?;
+ let path = get_path(jobtype, jobname)?;
+
+ let _lock = if let Some(lock) = lock {
+ lock
+ } else {
+ get_lock(&path)?
+ };
+
+ let backup_user = crate::backup::backup_user()?;
+ let mode = nix::sys::stat::Mode::from_bits_truncate(0o0644);
+ // set the correct owner/group/permissions while saving file
+ // owner(rw) = backup, group(r)= backup
+ let options = CreateOptions::new()
+ .perm(mode)
+ .owner(backup_user.uid)
+ .group(backup_user.gid);
+
+ replace_file(
+ path,
+ serialized.as_bytes(),
+ options,
+ )
+ }
+}
--
2.20.1
next prev parent reply other threads:[~2020-08-11 9:57 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-11 9:57 [pbs-devel] [PATCH proxmox-backup v2 0/9] improve syncjob handling Dominik Csapak
2020-08-11 9:57 ` [pbs-devel] [PATCH proxmox-backup v2 1/9] server: change status of a task from a string to an enum Dominik Csapak
2020-08-11 9:57 ` Dominik Csapak [this message]
2020-08-17 8:33 ` [pbs-devel] [PATCH proxmox-backup v2 2/9] config: add JobState helper Wolfgang Bumiller
2020-08-11 9:57 ` [pbs-devel] [PATCH proxmox-backup v2 3/9] api/{pull, sync}: refactor to do_sync_job Dominik Csapak
2020-08-11 9:57 ` [pbs-devel] [PATCH proxmox-backup v2 4/9] api2/pull: extend do_sync_job to also handle schedule and jobstate Dominik Csapak
2020-08-11 9:57 ` [pbs-devel] [PATCH proxmox-backup v2 5/9] syncjob: use do_sync_job also for scheduled sync jobs Dominik Csapak
2020-08-11 9:57 ` [pbs-devel] [PATCH proxmox-backup v2 6/9] syncjob: use JobState for determining when to run next scheduled sync Dominik Csapak
2020-08-11 9:57 ` [pbs-devel] [PATCH proxmox-backup v2 7/9] api2/admin/sync: use JobState for faster access to state info Dominik Csapak
2020-08-11 9:57 ` [pbs-devel] [PATCH proxmox-backup v2 8/9] ui: syncjob: improve task text rendering Dominik Csapak
2020-08-11 9:57 ` [pbs-devel] [PATCH proxmox-backup v2 9/9] ui: syncjob: make some columns smaller Dominik Csapak
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=20200811095724.26896-3-d.csapak@proxmox.com \
--to=d.csapak@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal