From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 4A7636C6C4 for ; Thu, 23 Sep 2021 12:14:13 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 2BB8C23EAF for ; Thu, 23 Sep 2021 12:13:43 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id C205F23E4F for ; Thu, 23 Sep 2021 12:13:35 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 8F30844A5A; Thu, 23 Sep 2021 12:13:35 +0200 (CEST) From: Dietmar Maurer To: pbs-devel@lists.proxmox.com Date: Thu, 23 Sep 2021 12:13:26 +0200 Message-Id: <20210923101329.950146-3-dietmar@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210923101329.950146-1-dietmar@proxmox.com> References: <20210923101329.950146-1-dietmar@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.328 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_NUMSUBJECT 0.5 Subject ends in numbers excluding current years SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox-backup 3/6] use UPID and systemd helpers from proxmox 0.13.4 X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Sep 2021 10:14:13 -0000 --- Cargo.toml | 2 +- pbs-api-types/Cargo.toml | 2 +- pbs-api-types/src/lib.rs | 59 ++++- pbs-api-types/src/upid.rs | 204 ------------------ pbs-client/Cargo.toml | 2 +- pbs-config/Cargo.toml | 2 +- pbs-datastore/Cargo.toml | 2 +- pbs-fuse-loop/Cargo.toml | 2 +- pbs-tape/Cargo.toml | 2 +- pbs-tools/Cargo.toml | 2 +- proxmox-backup-client/Cargo.toml | 3 +- proxmox-backup-client/src/mount.rs | 8 +- proxmox-file-restore/Cargo.toml | 3 +- proxmox-file-restore/src/block_driver_qemu.rs | 8 +- proxmox-rest-server/Cargo.toml | 2 +- proxmox-restore-daemon/Cargo.toml | 2 +- proxmox-systemd/Cargo.toml | 2 +- proxmox-systemd/src/unit.rs | 85 +------- pxar-bin/Cargo.toml | 2 +- src/api2/node/disks/directory.rs | 4 +- src/api2/node/disks/zfs.rs | 2 +- src/server/worker_task.rs | 2 +- src/tape/drive/mod.rs | 2 +- 23 files changed, 86 insertions(+), 318 deletions(-) delete mode 100644 pbs-api-types/src/upid.rs diff --git a/Cargo.toml b/Cargo.toml index 99c56f04..88e8fbd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,7 +94,7 @@ zstd = { version = "0.6", features = [ "bindgen" ] } pathpatterns = "0.1.2" pxar = { version = "0.10.1", features = [ "tokio-io" ] } -proxmox = { version = "0.13.3", features = [ "sortable-macro", "api-macro", "cli", "router", "tfa" ] } +proxmox = { version = "0.13.4", features = [ "sortable-macro", "api-macro", "cli", "router", "tfa" ] } proxmox-acme-rs = "0.2.1" proxmox-apt = "0.7.0" proxmox-http = { version = "0.4.0", features = [ "client", "http-helpers", "websocket" ] } diff --git a/pbs-api-types/Cargo.toml b/pbs-api-types/Cargo.toml index a64d7f0a..878d6417 100644 --- a/pbs-api-types/Cargo.toml +++ b/pbs-api-types/Cargo.toml @@ -14,7 +14,7 @@ openssl = "0.10" regex = "1.2" serde = { version = "1.0", features = ["derive"] } -proxmox = { version = "0.13.3", default-features = false, features = [ "api-macro" ] } +proxmox = { version = "0.13.4", default-features = false, features = [ "api-macro" ] } proxmox-systemd = { path = "../proxmox-systemd" } pbs-tools = { path = "../pbs-tools" } diff --git a/pbs-api-types/src/lib.rs b/pbs-api-types/src/lib.rs index 6b0246f5..f7521b02 100644 --- a/pbs-api-types/src/lib.rs +++ b/pbs-api-types/src/lib.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use anyhow::bail; use proxmox::api::api; -use proxmox::api::schema::{ApiStringFormat, ArraySchema, Schema, StringSchema}; +use proxmox::api::schema::{ApiStringFormat, ApiType, ArraySchema, Schema, StringSchema, ReturnType}; use proxmox::const_regex; use proxmox::{IPRE, IPRE_BRACKET, IPV4OCTET, IPV4RE, IPV6H16, IPV6LS32, IPV6RE}; @@ -60,8 +60,7 @@ pub use userid::{PROXMOX_GROUP_ID_SCHEMA, PROXMOX_TOKEN_ID_SCHEMA, PROXMOX_TOKEN mod user; pub use user::*; -pub mod upid; -pub use upid::*; +pub use proxmox::api::upid::*; mod crypto; pub use crypto::{CryptMode, Fingerprint}; @@ -397,3 +396,57 @@ pub enum NodePowerCommand { /// Shutdown the server Shutdown, } + + +#[api()] +#[derive(Eq, PartialEq, Debug, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum TaskStateType { + /// Ok + OK, + /// Warning + Warning, + /// Error + Error, + /// Unknown + Unknown, +} + +#[api( + properties: { + upid: { schema: UPID::API_SCHEMA }, + }, +)] +#[derive(Serialize, Deserialize)] +/// Task properties. +pub struct TaskListItem { + pub upid: String, + /// The node name where the task is running on. + pub node: String, + /// The Unix PID + pub pid: i64, + /// The task start time (Epoch) + pub pstart: u64, + /// The task start time (Epoch) + pub starttime: i64, + /// Worker type (arbitrary ASCII string) + pub worker_type: String, + /// Worker ID (arbitrary ASCII string) + pub worker_id: Option, + /// The authenticated entity who started the task + pub user: String, + /// The task end time (Epoch) + #[serde(skip_serializing_if="Option::is_none")] + pub endtime: Option, + /// Task end status + #[serde(skip_serializing_if="Option::is_none")] + pub status: Option, +} + +pub const NODE_TASKS_LIST_TASKS_RETURN_TYPE: ReturnType = ReturnType { + optional: false, + schema: &ArraySchema::new( + "A list of tasks.", + &TaskListItem::API_SCHEMA, + ).schema(), +}; diff --git a/pbs-api-types/src/upid.rs b/pbs-api-types/src/upid.rs deleted file mode 100644 index 29135bca..00000000 --- a/pbs-api-types/src/upid.rs +++ /dev/null @@ -1,204 +0,0 @@ -use std::sync::atomic::{AtomicUsize, Ordering}; - -use anyhow::{bail, Error}; -use serde::{Deserialize, Serialize}; - -use proxmox::api::api; -use proxmox::api::schema::{ApiStringFormat, ApiType, Schema, StringSchema, ArraySchema, ReturnType}; -use proxmox::const_regex; -use proxmox::sys::linux::procfs; - -/// Unique Process/Task Identifier -/// -/// We use this to uniquely identify worker task. UPIDs have a short -/// string repesentaion, which gives additional information about the -/// type of the task. for example: -/// ```text -/// UPID:{node}:{pid}:{pstart}:{task_id}:{starttime}:{worker_type}:{worker_id}:{userid}: -/// UPID:elsa:00004F37:0039E469:00000000:5CA78B83:garbage_collection::root@pam: -/// ``` -/// Please note that we use tokio, so a single thread can run multiple -/// tasks. -// #[api] - manually implemented API type -#[derive(Debug, Clone)] -pub struct UPID { - /// The Unix PID - pub pid: libc::pid_t, - /// The Unix process start time from `/proc/pid/stat` - pub pstart: u64, - /// The task start time (Epoch) - pub starttime: i64, - /// The task ID (inside the process/thread) - pub task_id: usize, - /// Worker type (arbitrary ASCII string) - pub worker_type: String, - /// Worker ID (arbitrary ASCII string) - pub worker_id: Option, - /// The authenticated entity who started the task - pub auth_id: String, - /// The node name. - pub node: String, -} - -proxmox::forward_serialize_to_display!(UPID); -proxmox::forward_deserialize_to_from_str!(UPID); - -const_regex! { - pub PROXMOX_UPID_REGEX = concat!( - r"^UPID:(?P[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?):(?P[0-9A-Fa-f]{8}):", - r"(?P[0-9A-Fa-f]{8,9}):(?P[0-9A-Fa-f]{8,16}):(?P[0-9A-Fa-f]{8}):", - r"(?P[^:\s]+):(?P[^:\s]*):(?P[^:\s]+):$" - ); -} - -pub const PROXMOX_UPID_FORMAT: ApiStringFormat = - ApiStringFormat::Pattern(&PROXMOX_UPID_REGEX); - -pub const UPID_SCHEMA: Schema = StringSchema::new("Unique Process/Task Identifier") - .min_length("UPID:N:12345678:12345678:12345678:::".len()) - .max_length(128) // arbitrary - .format(&PROXMOX_UPID_FORMAT) - .schema(); - -impl ApiType for UPID { - const API_SCHEMA: Schema = UPID_SCHEMA; -} - -impl UPID { - /// Create a new UPID - pub fn new( - worker_type: &str, - worker_id: Option, - auth_id: String, - ) -> Result { - - let pid = unsafe { libc::getpid() }; - - let bad: &[_] = &['/', ':', ' ']; - - if worker_type.contains(bad) { - bail!("illegal characters in worker type '{}'", worker_type); - } - - if auth_id.contains(bad) { - bail!("illegal characters in auth_id '{}'", auth_id); - } - - static WORKER_TASK_NEXT_ID: AtomicUsize = AtomicUsize::new(0); - - let task_id = WORKER_TASK_NEXT_ID.fetch_add(1, Ordering::SeqCst); - - Ok(UPID { - pid, - pstart: procfs::PidStat::read_from_pid(nix::unistd::Pid::from_raw(pid))?.starttime, - starttime: proxmox::tools::time::epoch_i64(), - task_id, - worker_type: worker_type.to_owned(), - worker_id, - auth_id, - node: proxmox::tools::nodename().to_owned(), - }) - } -} - - -impl std::str::FromStr for UPID { - type Err = Error; - - fn from_str(s: &str) -> Result { - if let Some(cap) = PROXMOX_UPID_REGEX.captures(s) { - - let worker_id = if cap["wid"].is_empty() { - None - } else { - let wid = proxmox_systemd::unescape_unit(&cap["wid"])?; - Some(wid) - }; - - Ok(UPID { - pid: i32::from_str_radix(&cap["pid"], 16).unwrap(), - pstart: u64::from_str_radix(&cap["pstart"], 16).unwrap(), - starttime: i64::from_str_radix(&cap["starttime"], 16).unwrap(), - task_id: usize::from_str_radix(&cap["task_id"], 16).unwrap(), - worker_type: cap["wtype"].to_string(), - worker_id, - auth_id: cap["authid"].parse()?, - node: cap["node"].to_string(), - }) - } else { - bail!("unable to parse UPID '{}'", s); - } - - } -} - -impl std::fmt::Display for UPID { - - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - - let wid = if let Some(ref id) = self.worker_id { - proxmox_systemd::escape_unit(id, false) - } else { - String::new() - }; - - // Note: pstart can be > 32bit if uptime > 497 days, so this can result in - // more that 8 characters for pstart - - write!(f, "UPID:{}:{:08X}:{:08X}:{:08X}:{:08X}:{}:{}:{}:", - self.node, self.pid, self.pstart, self.task_id, self.starttime, self.worker_type, wid, self.auth_id) - } -} - -#[api()] -#[derive(Eq, PartialEq, Debug, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -pub enum TaskStateType { - /// Ok - OK, - /// Warning - Warning, - /// Error - Error, - /// Unknown - Unknown, -} - -#[api( - properties: { - upid: { schema: UPID::API_SCHEMA }, - }, -)] -#[derive(Serialize, Deserialize)] -/// Task properties. -pub struct TaskListItem { - pub upid: String, - /// The node name where the task is running on. - pub node: String, - /// The Unix PID - pub pid: i64, - /// The task start time (Epoch) - pub pstart: u64, - /// The task start time (Epoch) - pub starttime: i64, - /// Worker type (arbitrary ASCII string) - pub worker_type: String, - /// Worker ID (arbitrary ASCII string) - pub worker_id: Option, - /// The authenticated entity who started the task - pub user: String, - /// The task end time (Epoch) - #[serde(skip_serializing_if="Option::is_none")] - pub endtime: Option, - /// Task end status - #[serde(skip_serializing_if="Option::is_none")] - pub status: Option, -} - -pub const NODE_TASKS_LIST_TASKS_RETURN_TYPE: ReturnType = ReturnType { - optional: false, - schema: &ArraySchema::new( - "A list of tasks.", - &TaskListItem::API_SCHEMA, - ).schema(), -}; diff --git a/pbs-client/Cargo.toml b/pbs-client/Cargo.toml index 965282bc..dc5d8928 100644 --- a/pbs-client/Cargo.toml +++ b/pbs-client/Cargo.toml @@ -28,7 +28,7 @@ tower-service = "0.3.0" xdg = "2.2" pathpatterns = "0.1.2" -proxmox = { version = "0.13.3", default-features = false, features = [ "cli" ] } +proxmox = { version = "0.13.4", default-features = false, features = [ "cli" ] } proxmox-fuse = "0.1.1" proxmox-http = { version = "0.4.0", features = [ "client", "http-helpers", "websocket" ] } pxar = { version = "0.10.1", features = [ "tokio-io" ] } diff --git a/pbs-config/Cargo.toml b/pbs-config/Cargo.toml index 48830045..3249a8e9 100644 --- a/pbs-config/Cargo.toml +++ b/pbs-config/Cargo.toml @@ -16,7 +16,7 @@ nix = "0.19.1" regex = "1.2" once_cell = "1.3.1" -proxmox = { version = "0.13.3", default-features = false, features = [ "cli" ] } +proxmox = { version = "0.13.4", default-features = false, features = [ "cli" ] } pbs-api-types = { path = "../pbs-api-types" } pbs-buildcfg = { path = "../pbs-buildcfg" } diff --git a/pbs-datastore/Cargo.toml b/pbs-datastore/Cargo.toml index 5b3c7fab..578b8689 100644 --- a/pbs-datastore/Cargo.toml +++ b/pbs-datastore/Cargo.toml @@ -23,7 +23,7 @@ zstd = { version = "0.6", features = [ "bindgen" ] } pathpatterns = "0.1.2" pxar = "0.10.1" -proxmox = { version = "0.13.3", default-features = false, features = [ "api-macro" ] } +proxmox = { version = "0.13.4", default-features = false, features = [ "api-macro" ] } pbs-api-types = { path = "../pbs-api-types" } pbs-tools = { path = "../pbs-tools" } diff --git a/pbs-fuse-loop/Cargo.toml b/pbs-fuse-loop/Cargo.toml index c3220be7..aa61d006 100644 --- a/pbs-fuse-loop/Cargo.toml +++ b/pbs-fuse-loop/Cargo.toml @@ -14,7 +14,7 @@ nix = "0.19.1" regex = "1.2" tokio = { version = "1.6", features = [] } -proxmox = "0.13.3" +proxmox = "0.13.4" proxmox-fuse = "0.1.1" pbs-tools = { path = "../pbs-tools" } diff --git a/pbs-tape/Cargo.toml b/pbs-tape/Cargo.toml index 4ffae21e..3dbeb17c 100644 --- a/pbs-tape/Cargo.toml +++ b/pbs-tape/Cargo.toml @@ -18,7 +18,7 @@ bitflags = "1.2.1" regex = "1.2" udev = ">= 0.3, <0.5" -proxmox = { version = "0.13.3", default-features = false, features = [] } +proxmox = { version = "0.13.4", default-features = false, features = [] } pbs-api-types = { path = "../pbs-api-types" } pbs-tools = { path = "../pbs-tools" } diff --git a/pbs-tools/Cargo.toml b/pbs-tools/Cargo.toml index 88f6f54c..f20a315e 100644 --- a/pbs-tools/Cargo.toml +++ b/pbs-tools/Cargo.toml @@ -30,7 +30,7 @@ url = "2.1" walkdir = "2" zstd = { version = "0.6", features = [ "bindgen" ] } -proxmox = { version = "0.13.3", default-features = false, features = [ "tokio" ] } +proxmox = { version = "0.13.4", default-features = false, features = [ "tokio" ] } pbs-buildcfg = { path = "../pbs-buildcfg" } pbs-runtime = { path = "../pbs-runtime" } diff --git a/proxmox-backup-client/Cargo.toml b/proxmox-backup-client/Cargo.toml index d3c35534..42a4d09f 100644 --- a/proxmox-backup-client/Cargo.toml +++ b/proxmox-backup-client/Cargo.toml @@ -22,7 +22,7 @@ zstd = { version = "0.6", features = [ "bindgen" ] } pathpatterns = "0.1.2" pxar = { version = "0.10.1", features = [ "tokio-io" ] } -proxmox = { version = "0.13.3", features = [ "sortable-macro", "api-macro", "cli", "router" ] } +proxmox = { version = "0.13.4", features = [ "sortable-macro", "api-macro", "cli", "router" ] } pbs-api-types = { path = "../pbs-api-types" } pbs-buildcfg = { path = "../pbs-buildcfg" } @@ -31,5 +31,4 @@ pbs-client = { path = "../pbs-client" } pbs-datastore = { path = "../pbs-datastore" } pbs-fuse-loop = { path = "../pbs-fuse-loop" } pbs-runtime = { path = "../pbs-runtime" } -proxmox-systemd = { path = "../proxmox-systemd" } pbs-tools = { path = "../pbs-tools" } diff --git a/proxmox-backup-client/src/mount.rs b/proxmox-backup-client/src/mount.rs index 9ac1d9c2..7c977864 100644 --- a/proxmox-backup-client/src/mount.rs +++ b/proxmox-backup-client/src/mount.rs @@ -118,7 +118,7 @@ fn complete_mapping_names(_arg: &str, _param: &HashMap mappings .filter_map(|(name, _)| { - proxmox_systemd::unescape_unit(&name).ok() + proxmox::tools::systemd::unescape_unit(&name).ok() }).collect(), Err(_) => Vec::new() } @@ -279,7 +279,7 @@ async fn mount_do(param: Value, pipe: Option) -> Result { let reader = CachedChunkReader::new(chunk_reader, index, 8).seekable(); let name = &format!("{}:{}/{}", repo.to_string(), path, archive_name); - let name_escaped = proxmox_systemd::escape_unit(name, false); + let name_escaped = proxmox::tools::systemd::escape_unit(name, false); let mut session = pbs_fuse_loop::FuseLoopSession::map_loop(size, reader, &name_escaped, options).await?; let loopdev = session.loopdev_path.clone(); @@ -341,7 +341,7 @@ fn unmap( pbs_fuse_loop::cleanup_unused_run_files(None); let mut any = false; for (backing, loopdev) in pbs_fuse_loop::find_all_mappings()? { - let name = proxmox_systemd::unescape_unit(&backing)?; + let name = proxmox::tools::systemd::unescape_unit(&backing)?; println!("{}:\t{}", loopdev.unwrap_or_else(|| "(unmapped)".to_string()), name); any = true; } @@ -360,7 +360,7 @@ fn unmap( if name.starts_with("/dev/loop") { pbs_fuse_loop::unmap_loopdev(name)?; } else { - let name = proxmox_systemd::escape_unit(&name, false); + let name = proxmox::tools::systemd::escape_unit(&name, false); pbs_fuse_loop::unmap_name(name)?; } diff --git a/proxmox-file-restore/Cargo.toml b/proxmox-file-restore/Cargo.toml index 1e13fb46..899fc984 100644 --- a/proxmox-file-restore/Cargo.toml +++ b/proxmox-file-restore/Cargo.toml @@ -16,7 +16,7 @@ tokio = { version = "1.6", features = [ "io-std", "rt", "rt-multi-thread", "time pxar = { version = "0.10.1", features = [ "tokio-io" ] } -proxmox = { version = "0.13.3", features = [ "api-macro", "cli" ] } +proxmox = { version = "0.13.4", features = [ "api-macro", "cli" ] } pbs-api-types = { path = "../pbs-api-types" } pbs-buildcfg = { path = "../pbs-buildcfg" } @@ -24,5 +24,4 @@ pbs-config = { path = "../pbs-config" } pbs-client = { path = "../pbs-client" } pbs-datastore = { path = "../pbs-datastore" } pbs-runtime = { path = "../pbs-runtime" } -proxmox-systemd = { path = "../proxmox-systemd" } pbs-tools = { path = "../pbs-tools" } diff --git a/proxmox-file-restore/src/block_driver_qemu.rs b/proxmox-file-restore/src/block_driver_qemu.rs index 2f73e669..b6eaf83a 100644 --- a/proxmox-file-restore/src/block_driver_qemu.rs +++ b/proxmox-file-restore/src/block_driver_qemu.rs @@ -80,7 +80,7 @@ impl VMStateMap { fn make_name(repo: &BackupRepository, snap: &BackupDir) -> String { let full = format!("qemu_{}/{}", repo, snap); - proxmox_systemd::escape_unit(&full, false) + proxmox::tools::systemd::escape_unit(&full, false) } /// remove non-responsive VMs from given map, returns 'true' if map was modified @@ -257,7 +257,7 @@ impl BlockRestoreDriver for QemuBlockDriver { let resp = client .get("api2/json/status", Some(json!({"keep-timeout": true}))) .await; - let name = proxmox_systemd::unescape_unit(n) + let name = proxmox::tools::systemd::unescape_unit(n) .unwrap_or_else(|_| "".to_owned()); let mut extra = json!({"pid": s.pid, "cid": s.cid}); @@ -295,7 +295,7 @@ impl BlockRestoreDriver for QemuBlockDriver { fn stop(&self, id: String) -> Async> { async move { - let name = proxmox_systemd::escape_unit(&id, false); + let name = proxmox::tools::systemd::escape_unit(&id, false); let mut map = VMStateMap::load()?; let map_mod = cleanup_map(&mut map.map).await; match map.map.get(&name) { @@ -325,7 +325,7 @@ impl BlockRestoreDriver for QemuBlockDriver { match VMStateMap::load_read_only() { Ok(state) => state .iter() - .filter_map(|(name, _)| proxmox_systemd::unescape_unit(&name).ok()) + .filter_map(|(name, _)| proxmox::tools::systemd::unescape_unit(&name).ok()) .collect(), Err(_) => Vec::new(), } diff --git a/proxmox-rest-server/Cargo.toml b/proxmox-rest-server/Cargo.toml index 2f740e67..b02c20db 100644 --- a/proxmox-rest-server/Cargo.toml +++ b/proxmox-rest-server/Cargo.toml @@ -24,7 +24,7 @@ tokio-openssl = "0.6.1" tower-service = "0.3.0" url = "2.1" -proxmox = { version = "0.13.3", features = [ "router"] } +proxmox = { version = "0.13.4", features = [ "router"] } # fixme: remove this dependency (pbs_tools::broadcast_future) pbs-tools = { path = "../pbs-tools" } diff --git a/proxmox-restore-daemon/Cargo.toml b/proxmox-restore-daemon/Cargo.toml index c525dc99..871af5f9 100644 --- a/proxmox-restore-daemon/Cargo.toml +++ b/proxmox-restore-daemon/Cargo.toml @@ -26,7 +26,7 @@ tokio-util = { version = "0.6", features = [ "codec", "io" ] } pathpatterns = "0.1.2" pxar = { version = "0.10.1", features = [ "tokio-io" ] } -proxmox = { version = "0.13.3", features = [ "router", "sortable-macro" ] } +proxmox = { version = "0.13.4", features = [ "router", "sortable-macro" ] } pbs-api-types = { path = "../pbs-api-types" } pbs-runtime = { path = "../pbs-runtime" } diff --git a/proxmox-systemd/Cargo.toml b/proxmox-systemd/Cargo.toml index c6caa7ec..017a281c 100644 --- a/proxmox-systemd/Cargo.toml +++ b/proxmox-systemd/Cargo.toml @@ -11,6 +11,6 @@ bitflags = "1.2.1" lazy_static = "1.4" nom = "5.1" -proxmox = { version = "0.13.3", default-features = false } +proxmox = { version = "0.13.4", default-features = false } #pbs-tools = { path = "../pbs-tools" } diff --git a/proxmox-systemd/src/unit.rs b/proxmox-systemd/src/unit.rs index af3db1a6..15be61fd 100644 --- a/proxmox-systemd/src/unit.rs +++ b/proxmox-systemd/src/unit.rs @@ -34,88 +34,6 @@ fn run_command(mut command: Command) -> Result<(), Error> { Ok(()) } -/// Escape strings for usage in systemd unit names -pub fn escape_unit(mut unit: &str, is_path: bool) -> String { - if is_path { - unit = unit.trim_matches('/'); - if unit.is_empty() { - return String::from("-"); - } - } - - let unit = unit.as_bytes(); - - let mut escaped = String::new(); - - for (i, c) in unit.iter().enumerate() { - if *c == b'/' { - escaped.push('-'); - continue; - } - if (i == 0 && *c == b'.') - || !(*c == b'_' - || *c == b'.' - || (*c >= b'0' && *c <= b'9') - || (*c >= b'A' && *c <= b'Z') - || (*c >= b'a' && *c <= b'z')) - { - escaped.push_str(&format!("\\x{:0x}", c)); - } else { - escaped.push(*c as char); - } - } - escaped -} - -fn parse_hex_digit(d: u8) -> Result { - if d >= b'0' && d <= b'9' { - return Ok(d - b'0'); - } - if d >= b'A' && d <= b'F' { - return Ok(d - b'A' + 10); - } - if d >= b'a' && d <= b'f' { - return Ok(d - b'a' + 10); - } - bail!("got invalid hex digit"); -} - -/// Unescape strings used in systemd unit names -pub fn unescape_unit(text: &str) -> Result { - let mut i = text.as_bytes(); - - let mut data: Vec = Vec::new(); - - loop { - if i.is_empty() { - break; - } - let next = i[0]; - if next == b'\\' { - if i.len() < 4 { - bail!("short input"); - } - if i[1] != b'x' { - bail!("unkwnown escape sequence"); - } - let h1 = parse_hex_digit(i[2])?; - let h0 = parse_hex_digit(i[3])?; - data.push(h1 << 4 | h0); - i = &i[4..] - } else if next == b'-' { - data.push(b'/'); - i = &i[1..] - } else { - data.push(next); - i = &i[1..] - } - } - - let text = String::from_utf8(data)?; - - Ok(text) -} - pub fn reload_daemon() -> Result<(), Error> { let mut command = std::process::Command::new("systemctl"); command.arg("daemon-reload"); @@ -178,6 +96,9 @@ pub fn reload_unit(unit: &str) -> Result<(), Error> { #[test] fn test_escape_unit() -> Result<(), Error> { fn test_escape(i: &str, expected: &str, is_path: bool) { + + use proxmox::tools::systemd::{escape_unit, unescape_unit}; + let escaped = escape_unit(i, is_path); assert_eq!(escaped, expected); let unescaped = unescape_unit(&escaped).unwrap(); diff --git a/pxar-bin/Cargo.toml b/pxar-bin/Cargo.toml index e322e654..6121f7bc 100644 --- a/pxar-bin/Cargo.toml +++ b/pxar-bin/Cargo.toml @@ -16,7 +16,7 @@ serde_json = "1.0" tokio = { version = "1.6", features = [ "rt", "rt-multi-thread" ] } pathpatterns = "0.1.2" -proxmox = { version = "0.13.3", default-features = false, features = [] } +proxmox = { version = "0.13.4", default-features = false, features = [] } pxar = { version = "0.10.1", features = [ "tokio-io" ] } pbs-client = { path = "../pbs-client" } diff --git a/src/api2/node/disks/directory.rs b/src/api2/node/disks/directory.rs index 2f4a738d..49127586 100644 --- a/src/api2/node/disks/directory.rs +++ b/src/api2/node/disks/directory.rs @@ -242,7 +242,7 @@ pub fn delete_datastore_disk(name: String) -> Result<(), Error> { } // disable systemd mount-unit - let mut mount_unit_name = proxmox_systemd::escape_unit(&path, true); + let mut mount_unit_name = proxmox::tools::systemd::escape_unit(&path, true); mount_unit_name.push_str(".mount"); proxmox_systemd::disable_unit(&mount_unit_name)?; @@ -281,7 +281,7 @@ fn create_datastore_mount_unit( what: &str, ) -> Result { - let mut mount_unit_name = proxmox_systemd::escape_unit(&mount_point, true); + let mut mount_unit_name = proxmox::tools::systemd::escape_unit(&mount_point, true); mount_unit_name.push_str(".mount"); let mount_unit_path = format!("/etc/systemd/system/{}", mount_unit_name); diff --git a/src/api2/node/disks/zfs.rs b/src/api2/node/disks/zfs.rs index 9fe0dac4..8a6cb708 100644 --- a/src/api2/node/disks/zfs.rs +++ b/src/api2/node/disks/zfs.rs @@ -271,7 +271,7 @@ pub fn create_zpool( worker.log(output); if std::path::Path::new("/lib/systemd/system/zfs-import@.service").exists() { - let import_unit = format!("zfs-import@{}.service", proxmox_systemd::escape_unit(&name, false)); + let import_unit = format!("zfs-import@{}.service", proxmox::tools::systemd::escape_unit(&name, false)); proxmox_systemd::enable_unit(&import_unit)?; } diff --git a/src/server/worker_task.rs b/src/server/worker_task.rs index 191d8a44..94ffbeb0 100644 --- a/src/server/worker_task.rs +++ b/src/server/worker_task.rs @@ -18,9 +18,9 @@ use once_cell::sync::OnceCell; use proxmox::sys::linux::procfs; use proxmox::try_block; use proxmox::tools::fs::{create_path, replace_file, atomic_open_or_create_file, CreateOptions}; +use proxmox::api::upid::UPID; use pbs_tools::logrotate::{LogRotate, LogRotateFiles}; -use pbs_api_types::UPID; use proxmox_rest_server::{CommandoSocket, FileLogger, FileLogOptions}; struct TaskListLockGuard(File); diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs index f477acc7..ef5ffdbf 100644 --- a/src/tape/drive/mod.rs +++ b/src/tape/drive/mod.rs @@ -606,7 +606,7 @@ pub struct DeviceLockGuard(std::fs::File); // Uses systemd escape_unit to compute a file name from `device_path`, the try // to lock `/var/lock/`. fn open_device_lock(device_path: &str) -> Result { - let lock_name = proxmox_systemd::escape_unit(device_path, true); + let lock_name = proxmox::tools::systemd::escape_unit(device_path, true); let mut path = std::path::PathBuf::from(crate::tape::DRIVE_LOCK_DIR); path.push(lock_name); -- 2.30.2