diff --git a/src/bin/download-speed.rs b/src/bin/download-speed.rs index da4257b5..3e4010a2 100644 --- a/src/bin/download-speed.rs +++ b/src/bin/download-speed.rs @@ -33,7 +33,7 @@ async fn run() -> Result<(), Error> { let backup_time = "2019-06-28T10:49:48Z".parse::>()?; - let client = BackupReader::start(client, "store2", "host", "elsa", backup_time, true) + let client = BackupReader::start(client, None, "store2", "host", "elsa", backup_time, true) .await?; let start = std::time::SystemTime::now(); diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index dffdd989..b16e74f3 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -481,6 +481,7 @@ fn dump_catalog( async_main(async move { let client = BackupReader::start( client, + crypt_config.clone(), repo.store(), &snapshot.group().backup_type(), &snapshot.group().backup_id(), @@ -488,8 +489,7 @@ fn dump_catalog( true, ).await?; - let backup_index_data = download_index_blob(client.clone(), crypt_config.clone()).await?; - let backup_index: Value = serde_json::from_slice(&backup_index_data[..])?; + let backup_index = client.download_manifest().await?; let blob_file = std::fs::OpenOptions::new() .read(true) @@ -891,14 +891,6 @@ fn restore( async_main(restore_do(param)) } -async fn download_index_blob(client: Arc, crypt_config: Option>) -> Result, Error> { - - let index_data = client.download(INDEX_BLOB_NAME, Vec::with_capacity(64*1024)).await?; - let blob = DataBlob::from_raw(index_data)?; - blob.verify_crc()?; - blob.decode(crypt_config.as_ref().map(Arc::as_ref)) -} - fn verify_index_file(backup_index: &Value, name: &str, csum: &[u8; 32], size: u64) -> Result<(), Error> { let files = backup_index["files"] @@ -1042,7 +1034,15 @@ async fn restore_do(param: Value) -> Result { format!("{}.blob", archive_name) }; - let client = BackupReader::start(client, repo.store(), &backup_type, &backup_id, backup_time, true).await?; + let client = BackupReader::start( + client, + crypt_config.clone(), + repo.store(), + &backup_type, + &backup_id, + backup_time, + true, + ).await?; let tmpfile = std::fs::OpenOptions::new() .write(true) @@ -1050,17 +1050,16 @@ async fn restore_do(param: Value) -> Result { .custom_flags(libc::O_TMPFILE) .open("/tmp")?; - - let backup_index_data = download_index_blob(client.clone(), crypt_config.clone()).await?; - let backup_index: Value = serde_json::from_slice(&backup_index_data[..])?; + let backup_index = client.download_manifest().await?; if server_archive_name == INDEX_BLOB_NAME { + let backup_index_data = backup_index.to_string(); if let Some(target) = target { - file_set_contents(target, &backup_index_data, None)?; + file_set_contents(target, backup_index_data.as_bytes(), None)?; } else { let stdout = std::io::stdout(); let mut writer = stdout.lock(); - writer.write_all(&backup_index_data) + writer.write_all(backup_index_data.as_bytes()) .map_err(|err| format_err!("unable to pipe data - {}", err))?; } @@ -1759,7 +1758,15 @@ async fn mount_do(param: Value, pipe: Option) -> Result { bail!("Can only mount pxar archives."); }; - let client = BackupReader::start(client, repo.store(), &backup_type, &backup_id, backup_time, true).await?; + let client = BackupReader::start( + client, + crypt_config.clone(), + repo.store(), + &backup_type, + &backup_id, + backup_time, + true, + ).await?; let tmpfile = std::fs::OpenOptions::new() .write(true) @@ -1767,8 +1774,8 @@ async fn mount_do(param: Value, pipe: Option) -> Result { .custom_flags(libc::O_TMPFILE) .open("/tmp")?; - let backup_index_data = download_index_blob(client.clone(), crypt_config.clone()).await?; - let backup_index: Value = serde_json::from_slice(&backup_index_data[..])?; + let backup_index = client.download_manifest().await?; + if server_archive_name.ends_with(".didx") { let tmpfile = client.download(&server_archive_name, tmpfile).await?; let index = DynamicIndexReader::new(tmpfile) diff --git a/src/client/backup_reader.rs b/src/client/backup_reader.rs index 226340fe..7795e928 100644 --- a/src/client/backup_reader.rs +++ b/src/client/backup_reader.rs @@ -8,6 +8,7 @@ use serde_json::{json, Value}; use proxmox::tools::digest_to_hex; use crate::tools::futures::Canceller; +use crate::backup::*; use super::{HttpClient, H2Client}; @@ -15,6 +16,7 @@ use super::{HttpClient, H2Client}; pub struct BackupReader { h2: H2Client, canceller: Canceller, + crypt_config: Option>, } impl Drop for BackupReader { @@ -26,13 +28,14 @@ impl Drop for BackupReader { impl BackupReader { - fn new(h2: H2Client, canceller: Canceller) -> Arc { - Arc::new(Self { h2, canceller }) + fn new(h2: H2Client, canceller: Canceller, crypt_config: Option>) -> Arc { + Arc::new(Self { h2, canceller, crypt_config}) } /// Create a new instance by upgrading the connection at '/api2/json/reader' pub async fn start( client: HttpClient, + crypt_config: Option>, datastore: &str, backup_type: &str, backup_id: &str, @@ -51,7 +54,7 @@ impl BackupReader { let (h2, canceller) = client.start_h2_connection(req, String::from(PROXMOX_BACKUP_READER_PROTOCOL_ID_V1!())).await?; - Ok(BackupReader::new(h2, canceller)) + Ok(BackupReader::new(h2, canceller, crypt_config)) } /// Execute a GET request @@ -116,4 +119,15 @@ impl BackupReader { pub fn force_close(self) { self.canceller.cancel(); } + + /// Download backup manifest (index.json) + pub async fn download_manifest(&self) -> Result { + + let raw_data = self.download(INDEX_BLOB_NAME, Vec::with_capacity(64*1024)).await?; + let blob = DataBlob::from_raw(raw_data)?; + blob.verify_crc()?; + let data = blob.decode(self.crypt_config.as_ref().map(Arc::as_ref))?; + let result: Value = serde_json::from_slice(&data[..])?; + Ok(result) + } }