[pbs-devel] [PATCH v5 proxmox-backup 59/62] client: pxar: allow to restore prelude to optional path

Christian Ebner c.ebner at proxmox.com
Tue May 7 17:52:41 CEST 2024


Pxar archives allow to store additional information in a prelude
entry since pxar format version 2.

Add an optional parameter to `pxar` and `proxmox-backup-client` to
specify the path to restore the prelude to and pass this to the
archive extraction by extending the `PxarExtractOptions` by a
corresponding field. If none is given, the prelude is simply skipped
during restore.

Signed-off-by: Christian Ebner <c.ebner at proxmox.com>
---
changes since version 4:
- not present in previous version

 pbs-client/src/pxar/extract.rs    | 26 +++++++++++++++++++++++---
 proxmox-backup-client/src/main.rs | 12 +++++++++++-
 pxar-bin/src/main.rs              |  6 ++++++
 3 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/pbs-client/src/pxar/extract.rs b/pbs-client/src/pxar/extract.rs
index 23b2f6ba5..0fa3d48d7 100644
--- a/pbs-client/src/pxar/extract.rs
+++ b/pbs-client/src/pxar/extract.rs
@@ -2,7 +2,8 @@
 
 use std::collections::HashMap;
 use std::ffi::{CStr, CString, OsStr, OsString};
-use std::io;
+use std::fs::OpenOptions;
+use std::io::{self, Write};
 use std::os::unix::ffi::OsStrExt;
 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
 use std::path::{Path, PathBuf};
@@ -37,6 +38,7 @@ pub struct PxarExtractOptions<'a> {
     pub allow_existing_dirs: bool,
     pub overwrite_flags: OverwriteFlags,
     pub on_error: Option<ErrorHandler>,
+    pub prelude_path: Option<PathBuf>,
 }
 
 bitflags! {
@@ -125,8 +127,26 @@ where
         // we use this to keep track of our directory-traversal
         decoder.enable_goodbye_entries(true);
 
-        let (root, _, _) = handle_root_with_optional_format_version_prelude(&mut decoder)
-            .context("error reading pxar archive")?;
+        let (root, _version, prelude) =
+            handle_root_with_optional_format_version_prelude(&mut decoder)
+                .context("error reading pxar archive")?;
+
+        if let Some(ref path) = options.prelude_path {
+            if let Some(entry) = prelude {
+                let mut prelude_file = OpenOptions::new()
+                    .create(true)
+                    .write(true)
+                    .open(path)
+                    .with_context(|| format!("error creating prelude file '{path:?}'"))?;
+                if let pxar::EntryKind::Prelude(ref prelude) = entry.kind() {
+                    prelude_file.write_all(prelude.as_os_str().as_bytes())?;
+                } else {
+                    log::info!("unexpected entry kind for prelude");
+                }
+            } else {
+                log::info!("No prelude entry found, skip prelude restore.");
+            }
+        }
 
         if !root.is_dir() {
             bail!("pxar archive does not start with a directory entry!");
diff --git a/proxmox-backup-client/src/main.rs b/proxmox-backup-client/src/main.rs
index dccea230e..1423e6f0f 100644
--- a/proxmox-backup-client/src/main.rs
+++ b/proxmox-backup-client/src/main.rs
@@ -1432,7 +1432,12 @@ We do not extract '.pxar' archives when writing to standard output.
                 description: "ignore errors that occur during device node extraction",
                 optional: true,
                 default: false,
-            }
+            },
+            "restore-prelude-to": {
+                description: "Path to restore prelude to, (pxar v2 archives only).",
+                type: String,
+                optional: true,
+            },
         }
     }
 )]
@@ -1593,12 +1598,17 @@ async fn restore(
             overwrite_flags.insert(pbs_client::pxar::OverwriteFlags::all());
         }
 
+        let prelude_path = param["restore-prelude-to"]
+            .as_str()
+            .map(|path| PathBuf::from(path));
+
         let options = pbs_client::pxar::PxarExtractOptions {
             match_list: &[],
             extract_match_default: true,
             allow_existing_dirs,
             overwrite_flags,
             on_error,
+            prelude_path,
         };
 
         let mut feature_flags = pbs_client::pxar::Flags::DEFAULT;
diff --git a/pxar-bin/src/main.rs b/pxar-bin/src/main.rs
index 85f96ad2c..2a5403467 100644
--- a/pxar-bin/src/main.rs
+++ b/pxar-bin/src/main.rs
@@ -126,6 +126,10 @@ fn extract_archive_from_reader<R: std::io::Read>(
                 description: "'ppxar' payload input data file to restore split archive.",
                 optional: true,
             },
+            "restore-prelude-to": {
+                description: "Path to restore pxar archive prelude to.",
+                optional: true,
+            },
         },
     },
 )]
@@ -149,6 +153,7 @@ fn extract_archive(
     no_sockets: bool,
     strict: bool,
     payload_input: Option<String>,
+    restore_prelude_to: Option<String>,
 ) -> Result<(), Error> {
     let mut feature_flags = Flags::DEFAULT;
     if no_xattrs {
@@ -222,6 +227,7 @@ fn extract_archive(
         overwrite_flags,
         extract_match_default,
         on_error,
+        prelude_path: restore_prelude_to.map(|path| PathBuf::from(path)),
     };
 
     if archive == "-" {
-- 
2.39.2





More information about the pbs-devel mailing list