we'll want to reuse that in a later patch Signed-off-by: Dominik Csapak <d.csa...@proxmox.com> --- proxmox-file-restore/src/main.rs | 153 +++++++++++++++++-------------- 1 file changed, 85 insertions(+), 68 deletions(-)
diff --git a/proxmox-file-restore/src/main.rs b/proxmox-file-restore/src/main.rs index 0ada15e6..cbf79802 100644 --- a/proxmox-file-restore/src/main.rs +++ b/proxmox-file-restore/src/main.rs @@ -25,7 +25,7 @@ use pbs_datastore::catalog::{ArchiveEntry, CatalogReader, DirEntryAttribute}; use pbs_datastore::dynamic_index::{BufferedDynamicReader, LocalDynamicReadAt}; use pbs_datastore::index::IndexFile; use pbs_config::key_config::decrypt_key; -use pbs_client::{BackupReader, RemoteChunkReader}; +use pbs_client::{BackupReader, BackupRepository, RemoteChunkReader}; use pbs_client::pxar::{create_zip, extract_sub_dir, extract_sub_dir_seq}; use pbs_client::tools::{ complete_group_or_snapshot, complete_repository, connect, extract_repository_from_value, @@ -94,6 +94,84 @@ fn keyfile_path(param: &Value) -> Option<String> { None } +async fn list_files( + repo: BackupRepository, + snapshot: BackupDir, + path: ExtractPath, + crypt_config: Option<Arc<CryptConfig>>, + keyfile: Option<String>, + driver: Option<BlockDriverType>, +) -> Result<Vec<ArchiveEntry>, Error> { + let client = connect(&repo)?; + let client = BackupReader::start( + client, + crypt_config.clone(), + repo.store(), + snapshot.group().backup_type(), + snapshot.group().backup_id(), + snapshot.backup_time(), + true, + ) + .await?; + + let (manifest, _) = client.download_manifest().await?; + manifest.check_fingerprint(crypt_config.as_ref().map(Arc::as_ref))?; + + match path { + ExtractPath::ListArchives => { + let mut entries = vec![]; + for file in manifest.files() { + if !file.filename.ends_with(".pxar.didx") && !file.filename.ends_with(".img.fidx") { + continue; + } + let path = format!("/{}", file.filename); + let attr = if file.filename.ends_with(".pxar.didx") { + // a pxar file is a file archive, so it's root is also a directory root + Some(&DirEntryAttribute::Directory { start: 0 }) + } else { + None + }; + entries.push(ArchiveEntry::new_with_size( + path.as_bytes(), + attr, + Some(file.size), + )); + } + + Ok(entries) + } + ExtractPath::Pxar(file, mut path) => { + let index = client + .download_dynamic_index(&manifest, CATALOG_NAME) + .await?; + let most_used = index.find_most_used_chunks(8); + let file_info = manifest.lookup_file_info(CATALOG_NAME)?; + let chunk_reader = RemoteChunkReader::new( + client.clone(), + crypt_config, + file_info.chunk_crypt_mode(), + most_used, + ); + let reader = BufferedDynamicReader::new(index, chunk_reader); + let mut catalog_reader = CatalogReader::new(reader); + + let mut fullpath = file.into_bytes(); + fullpath.append(&mut path); + + catalog_reader.list_dir_contents(&fullpath) + } + ExtractPath::VM(file, path) => { + let details = SnapRestoreDetails { + manifest, + repo, + snapshot, + keyfile, + }; + data_list(driver, details, file, path).await + } + } +} + #[api( input: { properties: { @@ -170,74 +248,14 @@ async fn list( } }; - let client = connect(&repo)?; - let client = BackupReader::start( - client, - crypt_config.clone(), - repo.store(), - snapshot.group().backup_type(), - snapshot.group().backup_id(), - snapshot.backup_time(), - true, - ) - .await?; - - let (manifest, _) = client.download_manifest().await?; - manifest.check_fingerprint(crypt_config.as_ref().map(Arc::as_ref))?; - - let result = match path { - ExtractPath::ListArchives => { - let mut entries = vec![]; - for file in manifest.files() { - if !file.filename.ends_with(".pxar.didx") && !file.filename.ends_with(".img.fidx") { - continue; - } - let path = format!("/{}", file.filename); - let attr = if file.filename.ends_with(".pxar.didx") { - // a pxar file is a file archive, so it's root is also a directory root - Some(&DirEntryAttribute::Directory { start: 0 }) - } else { - None - }; - entries.push(ArchiveEntry::new_with_size(path.as_bytes(), attr, Some(file.size))); - } - - Ok(entries) - } - ExtractPath::Pxar(file, mut path) => { - let index = client - .download_dynamic_index(&manifest, CATALOG_NAME) - .await?; - let most_used = index.find_most_used_chunks(8); - let file_info = manifest.lookup_file_info(CATALOG_NAME)?; - let chunk_reader = RemoteChunkReader::new( - client.clone(), - crypt_config, - file_info.chunk_crypt_mode(), - most_used, - ); - let reader = BufferedDynamicReader::new(index, chunk_reader); - let mut catalog_reader = CatalogReader::new(reader); + let driver: Option<BlockDriverType> = match param.get("driver") { + Some(drv) => Some(serde_json::from_value(drv.clone())?), + None => None, + }; - let mut fullpath = file.into_bytes(); - fullpath.append(&mut path); + let result = list_files(repo, snapshot, path, crypt_config, keyfile, driver).await?; - catalog_reader.list_dir_contents(&fullpath) - } - ExtractPath::VM(file, path) => { - let details = SnapRestoreDetails { - manifest, - repo, - snapshot, - keyfile, - }; - let driver: Option<BlockDriverType> = match param.get("driver") { - Some(drv) => Some(serde_json::from_value(drv.clone())?), - None => None, - }; - data_list(driver, details, file, path).await - } - }?; + let output_format = get_output_format(¶m); let options = default_table_format_options() .sortby("type", false) @@ -247,7 +265,6 @@ async fn list( .column(ColumnConfig::new("mtime").header("last modified")) .column(ColumnConfig::new("size")); - let output_format = get_output_format(¶m); format_and_print_result_full( &mut json!(result), &API_METHOD_LIST.returns, -- 2.30.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel