src/client/backup_reader.rs: add download_manifest
Also add crypt_config as member variable.
This commit is contained in:
		@ -33,7 +33,7 @@ async fn run() -> Result<(), Error> {
 | 
			
		||||
 | 
			
		||||
    let backup_time = "2019-06-28T10:49:48Z".parse::<DateTime<Utc>>()?;
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
 | 
			
		||||
@ -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<BackupReader>, crypt_config: Option<Arc<CryptConfig>>) -> Result<Vec<u8>, 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<Value, Error> {
 | 
			
		||||
        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<Value, Error> {
 | 
			
		||||
        .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<RawFd>) -> Result<Value, Error> {
 | 
			
		||||
        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<RawFd>) -> Result<Value, Error> {
 | 
			
		||||
        .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)
 | 
			
		||||
 | 
			
		||||
@ -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<Arc<CryptConfig>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Drop for BackupReader {
 | 
			
		||||
@ -26,13 +28,14 @@ impl Drop for BackupReader {
 | 
			
		||||
 | 
			
		||||
impl BackupReader {
 | 
			
		||||
 | 
			
		||||
    fn new(h2: H2Client, canceller: Canceller) -> Arc<Self> {
 | 
			
		||||
        Arc::new(Self { h2, canceller })
 | 
			
		||||
    fn new(h2: H2Client, canceller: Canceller, crypt_config: Option<Arc<CryptConfig>>) -> Arc<Self> {
 | 
			
		||||
        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<Arc<CryptConfig>>,
 | 
			
		||||
        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<Value, Error> {
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user