[pbs-devel] [PATCH proxmox-backup 3/3] pxar: added creation parameters

Gabriel Goller g.goller at proxmox.com
Wed Mar 6 15:34:13 CET 2024


This adds support for the creation parameters and the
`.pxar_creation_params` file into the `pxar` binary.

Signed-off-by: Gabriel Goller <g.goller at proxmox.com>
---
 pxar-bin/Cargo.toml  |  1 +
 pxar-bin/src/main.rs | 68 +++++++++++++++++++++++++++-----------------
 2 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/pxar-bin/Cargo.toml b/pxar-bin/Cargo.toml
index d91c03d3..4ed5c29a 100644
--- a/pxar-bin/Cargo.toml
+++ b/pxar-bin/Cargo.toml
@@ -13,6 +13,7 @@ anyhow.workspace = true
 futures.workspace = true
 log.workspace = true
 nix.workspace = true
+serde.workspace = true
 serde_json.workspace = true
 tokio = { workspace = true, features = [ "rt", "rt-multi-thread" ] }
 
diff --git a/pxar-bin/src/main.rs b/pxar-bin/src/main.rs
index 277d0b46..f0db2440 100644
--- a/pxar-bin/src/main.rs
+++ b/pxar-bin/src/main.rs
@@ -9,6 +9,7 @@ use std::sync::Arc;
 use anyhow::{bail, format_err, Error};
 use futures::future::FutureExt;
 use futures::select;
+use serde_json::Value;
 use tokio::signal::unix::{signal, SignalKind};
 
 use pathpatterns::{MatchEntry, MatchType, PatternFlag};
@@ -234,46 +235,71 @@ fn extract_archive(
     Ok(())
 }
 
+#[derive(serde::Deserialize)]
+#[serde(rename_all = "kebab-case")]
+struct CreateArchiveParams {
+    archive: String,
+    source: String,
+    no_xattrs: Option<bool>,
+    no_fcaps: Option<bool>,
+    no_acls: Option<bool>,
+    all_file_systems: Option<bool>,
+    no_device_nodes: Option<bool>,
+    no_fifos: Option<bool>,
+    no_sockets: Option<bool>,
+    exclude: Option<Vec<String>>,
+    entries_max: Option<isize>,
+}
+
 #[api(
     input: {
         properties: {
             archive: {
+                type: String,
                 description: "Archive name.",
             },
             source: {
+                type: String,
                 description: "Source directory.",
             },
             "no-xattrs": {
+                type: Boolean,
                 description: "Ignore extended file attributes.",
                 optional: true,
                 default: false,
             },
             "no-fcaps": {
+                type: Boolean,
                 description: "Ignore file capabilities.",
                 optional: true,
                 default: false,
             },
             "no-acls": {
+                type: Boolean,
                 description: "Ignore access control list entries.",
                 optional: true,
                 default: false,
             },
             "all-file-systems": {
+                type: Boolean,
                 description: "Include mounted sudirs.",
                 optional: true,
                 default: false,
             },
             "no-device-nodes": {
+                type: Boolean,
                 description: "Ignore device nodes.",
                 optional: true,
                 default: false,
             },
             "no-fifos": {
+                type: Boolean,
                 description: "Ignore fifos.",
                 optional: true,
                 default: false,
             },
             "no-sockets": {
+                type: Boolean,
                 description: "Ignore sockets.",
                 optional: true,
                 default: false,
@@ -288,6 +314,7 @@ fn extract_archive(
                 },
             },
             "entries-max": {
+                type: Integer,
                 description: "Max number of entries loaded at once into memory",
                 optional: true,
                 default: ENCODER_MAX_ENTRIES as isize,
@@ -298,22 +325,11 @@ fn extract_archive(
     },
 )]
 /// Create a new .pxar archive.
-#[allow(clippy::too_many_arguments)]
-async fn create_archive(
-    archive: String,
-    source: String,
-    no_xattrs: bool,
-    no_fcaps: bool,
-    no_acls: bool,
-    all_file_systems: bool,
-    no_device_nodes: bool,
-    no_fifos: bool,
-    no_sockets: bool,
-    exclude: Option<Vec<String>>,
-    entries_max: isize,
-) -> Result<(), Error> {
+async fn create_archive(param: Value) -> Result<(), Error> {
+    let params: CreateArchiveParams = serde_json::from_value(param.clone()).unwrap();
+
     let patterns = {
-        let input = exclude.unwrap_or_default();
+        let input = params.exclude.unwrap_or_default();
         let mut patterns = Vec::with_capacity(input.len());
         for entry in input {
             patterns.push(
@@ -324,21 +340,21 @@ async fn create_archive(
         patterns
     };
 
-    let device_set = if all_file_systems {
+    let device_set = if params.all_file_systems.unwrap_or(false) {
         None
     } else {
         Some(HashSet::new())
     };
 
     let options = pbs_client::pxar::PxarCreateOptions {
-        entries_max: entries_max as usize,
+        entries_max: params.entries_max.unwrap_or(ENCODER_MAX_ENTRIES as isize) as usize,
         device_set,
         patterns,
         skip_lost_and_found: false,
         skip_e2big_xattr: false,
     };
 
-    let source = PathBuf::from(source);
+    let source = PathBuf::from(params.source);
 
     let dir = nix::dir::Dir::open(
         &source,
@@ -350,26 +366,26 @@ async fn create_archive(
         .create_new(true)
         .write(true)
         .mode(0o640)
-        .open(archive)?;
+        .open(params.archive)?;
 
     let writer = std::io::BufWriter::with_capacity(1024 * 1024, file);
     let mut feature_flags = Flags::DEFAULT;
-    if no_xattrs {
+    if params.no_xattrs.unwrap_or(false) {
         feature_flags.remove(Flags::WITH_XATTRS);
     }
-    if no_fcaps {
+    if params.no_fcaps.unwrap_or(false) {
         feature_flags.remove(Flags::WITH_FCAPS);
     }
-    if no_acls {
+    if params.no_acls.unwrap_or(false) {
         feature_flags.remove(Flags::WITH_ACL);
     }
-    if no_device_nodes {
+    if params.no_device_nodes.unwrap_or(false) {
         feature_flags.remove(Flags::WITH_DEVICE_NODES);
     }
-    if no_fifos {
+    if params.no_fifos.unwrap_or(false) {
         feature_flags.remove(Flags::WITH_FIFOS);
     }
-    if no_sockets {
+    if params.no_sockets.unwrap_or(false) {
         feature_flags.remove(Flags::WITH_SOCKETS);
     }
 
@@ -384,7 +400,7 @@ async fn create_archive(
         },
         None,
         options,
-        "".to_string(),
+        param.to_string(),
     )
     .await?;
 
-- 
2.43.0





More information about the pbs-devel mailing list