From 8b7f8d3f3d28d1e6e7a5d9ab55ddb44d0d14f5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Fri, 20 Nov 2020 17:38:40 +0100 Subject: [PATCH] expose previous backup time in backup env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and use this information to add more information to client backup log and guide the download manifest decision. Signed-off-by: Fabian Grünbichler --- src/api2/backup.rs | 26 ++++++++++++++++ src/bin/proxmox-backup-client.rs | 51 ++++++++++++++++++++++---------- src/client/backup_writer.rs | 7 +++++ 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/src/api2/backup.rs b/src/api2/backup.rs index ce9a34ae..f4eed074 100644 --- a/src/api2/backup.rs +++ b/src/api2/backup.rs @@ -311,6 +311,10 @@ pub const BACKUP_API_SUBDIRS: SubdirMap = &[ "previous", &Router::new() .download(&API_METHOD_DOWNLOAD_PREVIOUS) ), + ( + "previous_backup_time", &Router::new() + .get(&API_METHOD_GET_PREVIOUS_BACKUP_TIME) + ), ( "speedtest", &Router::new() .upload(&API_METHOD_UPLOAD_SPEEDTEST) @@ -694,6 +698,28 @@ fn finish_backup ( Ok(Value::Null) } +#[sortable] +pub const API_METHOD_GET_PREVIOUS_BACKUP_TIME: ApiMethod = ApiMethod::new( + &ApiHandler::Sync(&get_previous_backup_time), + &ObjectSchema::new( + "Get previous backup time.", + &[], + ) +); + +fn get_previous_backup_time( + _param: Value, + _info: &ApiMethod, + rpcenv: &mut dyn RpcEnvironment, +) -> Result { + + let env: &BackupEnvironment = rpcenv.as_ref(); + + let backup_time = env.last_backup.as_ref().map(|info| info.backup_dir.backup_time()); + + Ok(json!(backup_time)) +} + #[sortable] pub const API_METHOD_DOWNLOAD_PREVIOUS: ApiMethod = ApiMethod::new( &ApiHandler::AsyncHttp(&download_previous), diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index 4d5f2d08..c961e390 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -1099,23 +1099,42 @@ async fn create_backup( false ).await?; - let previous_manifest = match client.download_previous_manifest().await { - Ok(previous_manifest) => { - match previous_manifest.check_fingerprint(crypt_config.as_ref().map(Arc::as_ref)) { - Ok(()) => { - println!("Successfully downloaded previous manifest."); - Some(Arc::new(previous_manifest)) - }, - Err(err) => { - println!("Couldn't re-use pevious manifest - {}", err); - None - }, + let download_previous_manifest = match client.previous_backup_time().await { + Ok(Some(backup_time)) => { + println!( + "Downloading previous manifest ({})", + strftime_local("%c", backup_time)? + ); + true + } + Ok(None) => { + println!("No previous manifest available."); + false + } + Err(_) => { + // Fallback for outdated server, TODO remove/bubble up with 2.0 + true + } + }; + + let previous_manifest = if download_previous_manifest { + match client.download_previous_manifest().await { + Ok(previous_manifest) => { + match previous_manifest.check_fingerprint(crypt_config.as_ref().map(Arc::as_ref)) { + Ok(()) => Some(Arc::new(previous_manifest)), + Err(err) => { + println!("Couldn't re-use previous manifest - {}", err); + None + } + } } - }, - Err(err) => { - println!("Couldn't download pevious manifest - {}", err); - None - }, + Err(err) => { + println!("Couldn't download previous manifest - {}", err); + None + } + } + } else { + None }; let snapshot = BackupDir::new(backup_type, backup_id, backup_time)?; diff --git a/src/client/backup_writer.rs b/src/client/backup_writer.rs index c5ce5b42..39cd574d 100644 --- a/src/client/backup_writer.rs +++ b/src/client/backup_writer.rs @@ -475,6 +475,13 @@ impl BackupWriter { Ok(index) } + /// Retrieve backup time of last backup + pub async fn previous_backup_time(&self) -> Result, Error> { + let data = self.h2.get("previous_backup_time", None).await?; + serde_json::from_value(data) + .map_err(|err| format_err!("Failed to parse backup time value returned by server - {}", err)) + } + /// Download backup manifest (index.json) of last backup pub async fn download_previous_manifest(&self) -> Result {