mirror of
https://git.proxmox.com/git/proxmox-backup
synced 2025-04-29 13:35:34 +00:00
client: catalog: fallback to metadata archives for catalog dump
Commit c0302805c
"client: backup: conditionally write catalog for
file level backups" drops encoding of the dedicated catalog when
archives are encoded as split metadata/data archives with the
`change-detection-mode` set to `data` or `metadata`.
Since the catalog is not present anymore, fallback to use the pxar
metadata archives in the manifest (if present) for generating the
listing of contents in a compatible manner.
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
parent
d530ba080d
commit
8b9bae1ef1
@ -8,11 +8,13 @@ use proxmox_router::cli::*;
|
|||||||
use proxmox_schema::api;
|
use proxmox_schema::api;
|
||||||
|
|
||||||
use pbs_api_types::BackupNamespace;
|
use pbs_api_types::BackupNamespace;
|
||||||
|
use pbs_client::pxar::tools::get_remote_pxar_reader;
|
||||||
use pbs_client::tools::has_pxar_filename_extension;
|
use pbs_client::tools::has_pxar_filename_extension;
|
||||||
use pbs_client::tools::key_source::get_encryption_key_password;
|
use pbs_client::tools::key_source::get_encryption_key_password;
|
||||||
use pbs_client::{BackupReader, RemoteChunkReader};
|
use pbs_client::{BackupReader, RemoteChunkReader};
|
||||||
use pbs_tools::crypt_config::CryptConfig;
|
use pbs_tools::crypt_config::CryptConfig;
|
||||||
use pbs_tools::json::required_string_param;
|
use pbs_tools::json::required_string_param;
|
||||||
|
use pxar::accessor::aio::Accessor;
|
||||||
|
|
||||||
use crate::helper;
|
use crate::helper;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -88,14 +90,49 @@ async fn dump_catalog(param: Value) -> Result<Value, Error> {
|
|||||||
let (manifest, _) = client.download_manifest().await?;
|
let (manifest, _) = client.download_manifest().await?;
|
||||||
manifest.check_fingerprint(crypt_config.as_ref().map(Arc::as_ref))?;
|
manifest.check_fingerprint(crypt_config.as_ref().map(Arc::as_ref))?;
|
||||||
|
|
||||||
|
let file_info = match manifest.lookup_file_info(CATALOG_NAME) {
|
||||||
|
Ok(file_info) => file_info,
|
||||||
|
Err(err) => {
|
||||||
|
let mut metadata_archives = Vec::new();
|
||||||
|
// No catalog, fallback to metadata archives if present
|
||||||
|
for archive in manifest.files() {
|
||||||
|
if archive.filename.ends_with(".mpxar.didx") {
|
||||||
|
metadata_archives.push(archive.filename.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
metadata_archives.sort_unstable_by(|a, b| a.cmp(b));
|
||||||
|
|
||||||
|
for archive in &metadata_archives {
|
||||||
|
let (reader, archive_size) = get_remote_pxar_reader(
|
||||||
|
&archive,
|
||||||
|
client.clone(),
|
||||||
|
&manifest,
|
||||||
|
crypt_config.clone(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
// only care about the metadata, don't attach a payload reader
|
||||||
|
let reader = pxar::PxarVariant::Unified(reader);
|
||||||
|
let accessor = Accessor::new(reader, archive_size).await?;
|
||||||
|
let root_dir = accessor.open_root().await?;
|
||||||
|
let prefix = format!("./{archive}");
|
||||||
|
pbs_client::pxar::tools::pxar_metadata_catalog_dump_dir(root_dir, Some(&prefix))
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !metadata_archives.is_empty() {
|
||||||
|
return Ok(Value::Null);
|
||||||
|
}
|
||||||
|
|
||||||
|
bail!(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let index = client
|
let index = client
|
||||||
.download_dynamic_index(&manifest, CATALOG_NAME)
|
.download_dynamic_index(&manifest, CATALOG_NAME)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let most_used = index.find_most_used_chunks(8);
|
let most_used = index.find_most_used_chunks(8);
|
||||||
|
|
||||||
let file_info = manifest.lookup_file_info(CATALOG_NAME)?;
|
|
||||||
|
|
||||||
let chunk_reader = RemoteChunkReader::new(
|
let chunk_reader = RemoteChunkReader::new(
|
||||||
client.clone(),
|
client.clone(),
|
||||||
crypt_config,
|
crypt_config,
|
||||||
|
Loading…
Reference in New Issue
Block a user