diff --git a/Cargo.toml b/Cargo.toml index 14bf8dc..9e27800 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,8 @@ cbindgen = "0.14.2" libc = "0.2" bytes = "0.5" proxmox = { version = "0.1.42", features = [ "sortable-macro", "api-macro" ] } -proxmox-backup = { git = "git://git.proxmox.com/git/proxmox-backup.git", tag = "v0.8.0" } +proxmox-backup = { git = "git://git.proxmox.com/git/proxmox-backup.git", commit = "8b2ad84a251bd4af33d8c2cddd4f40e26a99e84b" } +#proxmox-backup = { git = "git://git.proxmox.com/git/proxmox-backup.git", tag = "v0.8.0" } #proxmox-backup = { path = "../proxmox-backup" } chrono = "0.4" # Date and time library for Rust anyhow = "1.0" diff --git a/current-api.h b/current-api.h index 4462b88..15bb275 100644 --- a/current-api.h +++ b/current-api.h @@ -176,6 +176,8 @@ ProxmoxBackupHandle *proxmox_backup_new(const char *repo, const char *password, const char *keyfile, const char *key_password, + bool compress, + bool encrypt, const char *fingerprint, char **error); diff --git a/src/backup.rs b/src/backup.rs index 9c086e2..77fb611 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -8,7 +8,7 @@ use futures::future::{Future, Either, FutureExt}; use tokio::runtime::Runtime; use proxmox_backup::tools::runtime::get_runtime_with_builder; -use proxmox_backup::backup::{CryptConfig, BackupManifest, load_and_decrypt_key}; +use proxmox_backup::backup::{CryptConfig, CryptMode, BackupManifest, load_and_decrypt_key}; use proxmox_backup::client::{HttpClient, HttpClientOptions, BackupWriter}; use super::BackupSetup; @@ -19,6 +19,8 @@ use crate::commands::*; pub(crate) struct BackupTask { setup: BackupSetup, runtime: Arc, + compress: bool, + crypt_mode: CryptMode, crypt_config: Option>, writer: OnceCell>, last_manifest: OnceCell>, @@ -34,7 +36,12 @@ impl BackupTask { /// /// We keep a reference to the runtime - else the runtime can be /// dropped and further connections fails. - pub fn with_runtime(setup: BackupSetup, runtime: Arc) -> Result { + pub fn with_runtime( + setup: BackupSetup, + compress: bool, + crypt_mode: CryptMode, + runtime: Arc + ) -> Result { let crypt_config = match setup.keyfile { None => None, @@ -54,12 +61,12 @@ impl BackupTask { let registry = Arc::new(Mutex::new(Registry::::new())); let known_chunks = Arc::new(Mutex::new(HashSet::new())); - Ok(Self { runtime, setup, crypt_config, abort, registry, known_chunks, + Ok(Self { runtime, setup, compress, crypt_mode, crypt_config, abort, registry, known_chunks, writer: OnceCell::new(), last_manifest: OnceCell::new(), aborted: OnceCell::new() }) } - pub fn new(setup: BackupSetup) -> Result { + pub fn new(setup: BackupSetup, compress: bool, crypt_mode: CryptMode) -> Result { let runtime = get_runtime_with_builder(|| { let mut builder = tokio::runtime::Builder::new(); builder.threaded_scheduler(); @@ -69,7 +76,7 @@ impl BackupTask { builder.thread_name("proxmox-backup-worker"); builder }); - Self::with_runtime(setup, runtime) + Self::with_runtime(setup, compress, crypt_mode, runtime) } pub fn runtime(&self) -> tokio::runtime::Handle { @@ -140,7 +147,10 @@ impl BackupTask { writer, self.registry.clone(), name, - data); + data, + self.compress, + self.crypt_mode == CryptMode::Encrypt, + ); let mut abort_rx = self.abort.subscribe(); abortable_command(command_future, abort_rx.recv()).await @@ -163,7 +173,7 @@ impl BackupTask { let command_future = write_data( writer, - self.crypt_config.clone(), + if self.crypt_mode == CryptMode::Encrypt { self.crypt_config.clone() } else { None }, self.registry.clone(), self.known_chunks.clone(), dev_id, @@ -171,6 +181,7 @@ impl BackupTask { offset, size, self.setup.chunk_size, + self.compress, ); let mut abort_rx = self.abort.subscribe(); @@ -206,6 +217,7 @@ impl BackupTask { let command_future = register_image( writer, self.crypt_config.clone(), + self.crypt_mode, self.last_manifest.get().map(|m| m.clone()), self.registry.clone(), self.known_chunks.clone(), @@ -244,6 +256,7 @@ impl BackupTask { let command_future = finish_backup( writer, + self.crypt_mode, self.registry.clone(), self.setup.clone(), ); diff --git a/src/commands.rs b/src/commands.rs index b3b2da0..bf8b8a0 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -64,12 +64,14 @@ pub(crate) async fn add_config( registry: Arc>>, name: String, data: Vec, + compress: bool, + encrypt: bool, ) -> Result { //println!("add config {} size {}", name, size); let blob_name = format!("{}.blob", name); - let stats = client.upload_blob_from_data(data, &blob_name, true, Some(false)).await?; + let stats = client.upload_blob_from_data(data, &blob_name, compress, encrypt).await?; let mut guard = registry.lock().unwrap(); guard.add_file_info(json!({ @@ -103,6 +105,7 @@ pub(crate) fn check_last_incremental_csum( pub(crate) async fn register_image( client: Arc, crypt_config: Option>, + crypt_mode: CryptMode, manifest: Option>, registry: Arc>>, known_chunks: Arc>>, @@ -158,8 +161,12 @@ pub(crate) async fn register_image( let wid = client.post("fixed_index", Some(param)).await?.as_u64().unwrap(); - let zero_chunk_digest = - register_zero_chunk(client.clone(), crypt_config, chunk_size as usize, wid).await?; + let zero_chunk_digest = register_zero_chunk( + client.clone(), + if crypt_mode == CryptMode::Encrypt { crypt_config } else { None }, + chunk_size as usize, + wid, + ).await?; let (upload_queue, upload_result) = create_upload_queue( client.clone(), @@ -248,6 +255,7 @@ pub(crate) async fn write_data( offset: u64, size: u64, // actual data size chunk_size: u64, // expected data size + compress: bool, ) -> Result { //println!("dev {}: write {} {}", dev_id, offset, size); @@ -273,7 +281,7 @@ pub(crate) async fn write_data( } else { let data: &[u8] = unsafe { std::slice::from_raw_parts(data.0, size as usize) }; - let mut chunk_builder = DataChunkBuilder::new(data).compress(true); + let mut chunk_builder = DataChunkBuilder::new(data).compress(compress); if let Some(ref crypt_config) = crypt_config { chunk_builder = chunk_builder.crypt_config(crypt_config); @@ -358,6 +366,7 @@ pub(crate) async fn write_data( pub(crate) async fn finish_backup( client: Arc, + crypt_mode: CryptMode, registry: Arc>>, setup: BackupSetup, ) -> Result { @@ -379,7 +388,7 @@ pub(crate) async fn finish_backup( }; client - .upload_blob_from_data(index_data, "index.json.blob", true, Some(true)) + .upload_blob_from_data(index_data, "index.json.blob", true, crypt_mode == CryptMode::Encrypt) .await?; client.finish().await?; diff --git a/src/lib.rs b/src/lib.rs index 09ddd99..d4b9370 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ use std::os::raw::{c_uchar, c_char, c_int, c_void, c_long}; use std::sync::{Arc, Mutex, Condvar}; use proxmox::try_block; -use proxmox_backup::backup::BackupDir; +use proxmox_backup::backup::{CryptMode, BackupDir}; use proxmox_backup::client::BackupRepository; use chrono::{DateTime, Utc, TimeZone}; @@ -189,6 +189,8 @@ pub extern "C" fn proxmox_backup_new( password: *const c_char, keyfile: *const c_char, key_password: *const c_char, + compress: bool, + encrypt: bool, fingerprint: *const c_char, error: * mut * mut c_char, ) -> *mut ProxmoxBackupHandle { @@ -208,6 +210,12 @@ pub extern "C" fn proxmox_backup_new( let key_password = tools::utf8_c_string(key_password)?; let fingerprint = tools::utf8_c_string(fingerprint)?; + let crypt_mode = if keyfile.is_some() { + if encrypt { CryptMode::Encrypt } else { CryptMode::SignOnly } + } else { + CryptMode::None + }; + let setup = BackupSetup { host: repo.host().to_owned(), user: repo.user().to_owned(), @@ -222,7 +230,7 @@ pub extern "C" fn proxmox_backup_new( fingerprint, }; - BackupTask::new(setup) + BackupTask::new(setup, compress, crypt_mode) }); match task { diff --git a/src/restore.rs b/src/restore.rs index 5a5667d..3e37066 100644 --- a/src/restore.rs +++ b/src/restore.rs @@ -102,7 +102,7 @@ impl RestoreTask { self.chunk_reader.set(chunk_reader) .map_err(|_| format_err!("already connected!"))?; - let manifest = client.download_manifest().await?; + let (manifest, _) = client.download_manifest().await?; self.manifest.set(Arc::new(manifest)) .map_err(|_| format_err!("already connected!"))?;