pxar: add optional payload input to mount archive

Allow to pass an optional input path to mount a split pxar archive
with dedicated payload data file.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
Christian Ebner 2024-06-03 16:46:07 +02:00 committed by Fabian Grünbichler
parent 108764f95b
commit a43399da06
2 changed files with 35 additions and 6 deletions

View File

@ -61,12 +61,24 @@ impl Session {
options: &OsStr, options: &OsStr,
verbose: bool, verbose: bool,
mountpoint: &Path, mountpoint: &Path,
payload_input_path: Option<&Path>,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
// TODO: Add a buffered/caching ReadAt layer? // TODO: Add a buffered/caching ReadAt layer?
let file = std::fs::File::open(archive_path)?; let file = std::fs::File::open(archive_path)?;
let file_size = file.metadata()?.len(); let file_size = file.metadata()?.len();
let reader: Reader = Arc::new(accessor::sync::FileReader::new(file)); let reader: Reader = Arc::new(accessor::sync::FileReader::new(file));
let accessor = Accessor::new(pxar::PxarVariant::Unified(reader), file_size).await?; let accessor = if let Some(payload_input) = payload_input_path {
let payload_file = std::fs::File::open(payload_input)?;
let payload_size = payload_file.metadata()?.len();
let payload_reader: Reader = Arc::new(accessor::sync::FileReader::new(payload_file));
Accessor::new(
pxar::PxarVariant::Split(reader, (payload_reader, payload_size)),
file_size,
)
.await?
} else {
Accessor::new(pxar::PxarVariant::Unified(reader), file_size).await?
};
Self::mount(accessor, options, verbose, mountpoint) Self::mount(accessor, options, verbose, mountpoint)
} }

View File

@ -458,18 +458,34 @@ async fn create_archive(
optional: true, optional: true,
default: false, default: false,
}, },
"payload-input": {
description: "'ppxar' payload input data file to restore split archive.",
optional: true,
},
}, },
}, },
)] )]
/// Mount the archive to the provided mountpoint via FUSE. /// Mount the archive to the provided mountpoint via FUSE.
async fn mount_archive(archive: String, mountpoint: String, verbose: bool) -> Result<(), Error> { async fn mount_archive(
archive: String,
mountpoint: String,
verbose: bool,
payload_input: Option<String>,
) -> Result<(), Error> {
let archive = Path::new(&archive); let archive = Path::new(&archive);
let mountpoint = Path::new(&mountpoint); let mountpoint = Path::new(&mountpoint);
let options = OsStr::new("ro,default_permissions"); let options = OsStr::new("ro,default_permissions");
let payload_input = payload_input.map(|payload_input| PathBuf::from(payload_input));
let session = pbs_pxar_fuse::Session::mount_path(archive, options, verbose, mountpoint) let session = pbs_pxar_fuse::Session::mount_path(
.await archive,
.map_err(|err| format_err!("pxar mount failed: {}", err))?; options,
verbose,
mountpoint,
payload_input.as_deref(),
)
.await
.map_err(|err| format_err!("pxar mount failed: {}", err))?;
let mut interrupt = signal(SignalKind::interrupt())?; let mut interrupt = signal(SignalKind::interrupt())?;
@ -576,7 +592,8 @@ fn main() {
CliCommand::new(&API_METHOD_MOUNT_ARCHIVE) CliCommand::new(&API_METHOD_MOUNT_ARCHIVE)
.arg_param(&["archive", "mountpoint"]) .arg_param(&["archive", "mountpoint"])
.completion_cb("archive", complete_file_name) .completion_cb("archive", complete_file_name)
.completion_cb("mountpoint", complete_file_name), .completion_cb("mountpoint", complete_file_name)
.completion_cb("payload-input", complete_file_name),
) )
.insert( .insert(
"list", "list",