expose previous backup time in backup env

and use this information to add more information to client backup log
and guide the download manifest decision.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
Fabian Grünbichler 2020-11-20 17:38:40 +01:00 committed by Dietmar Maurer
parent 866c859a1e
commit 8b7f8d3f3d
3 changed files with 68 additions and 16 deletions

View File

@ -311,6 +311,10 @@ pub const BACKUP_API_SUBDIRS: SubdirMap = &[
"previous", &Router::new() "previous", &Router::new()
.download(&API_METHOD_DOWNLOAD_PREVIOUS) .download(&API_METHOD_DOWNLOAD_PREVIOUS)
), ),
(
"previous_backup_time", &Router::new()
.get(&API_METHOD_GET_PREVIOUS_BACKUP_TIME)
),
( (
"speedtest", &Router::new() "speedtest", &Router::new()
.upload(&API_METHOD_UPLOAD_SPEEDTEST) .upload(&API_METHOD_UPLOAD_SPEEDTEST)
@ -694,6 +698,28 @@ fn finish_backup (
Ok(Value::Null) 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<Value, Error> {
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] #[sortable]
pub const API_METHOD_DOWNLOAD_PREVIOUS: ApiMethod = ApiMethod::new( pub const API_METHOD_DOWNLOAD_PREVIOUS: ApiMethod = ApiMethod::new(
&ApiHandler::AsyncHttp(&download_previous), &ApiHandler::AsyncHttp(&download_previous),

View File

@ -1099,23 +1099,42 @@ async fn create_backup(
false false
).await?; ).await?;
let previous_manifest = match client.download_previous_manifest().await { let download_previous_manifest = match client.previous_backup_time().await {
Ok(previous_manifest) => { Ok(Some(backup_time)) => {
match previous_manifest.check_fingerprint(crypt_config.as_ref().map(Arc::as_ref)) { println!(
Ok(()) => { "Downloading previous manifest ({})",
println!("Successfully downloaded previous manifest."); strftime_local("%c", backup_time)?
Some(Arc::new(previous_manifest)) );
}, true
Err(err) => { }
println!("Couldn't re-use pevious manifest - {}", err); Ok(None) => {
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) => {
Err(err) => { println!("Couldn't download previous manifest - {}", err);
println!("Couldn't download pevious manifest - {}", err); None
None }
}, }
} else {
None
}; };
let snapshot = BackupDir::new(backup_type, backup_id, backup_time)?; let snapshot = BackupDir::new(backup_type, backup_id, backup_time)?;

View File

@ -475,6 +475,13 @@ impl BackupWriter {
Ok(index) Ok(index)
} }
/// Retrieve backup time of last backup
pub async fn previous_backup_time(&self) -> Result<Option<i64>, 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 /// Download backup manifest (index.json) of last backup
pub async fn download_previous_manifest(&self) -> Result<BackupManifest, Error> { pub async fn download_previous_manifest(&self) -> Result<BackupManifest, Error> {