snapshot: add helper function to retrieve verify_state

Add helper functions to retrieve the verify_state from the manifest of a
snapshot. Replaced all the manual "verify_state" parsing with the helper
function.

Suggested-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
This commit is contained in:
Gabriel Goller 2024-11-22 13:16:14 +01:00 committed by Fabian Grünbichler
parent 3dc9d2de69
commit b5be65cf8a
5 changed files with 43 additions and 21 deletions

View File

@ -8,8 +8,8 @@ use anyhow::{bail, format_err, Error};
use proxmox_sys::fs::{lock_dir_noblock, replace_file, CreateOptions};
use pbs_api_types::{
Authid, BackupGroupDeleteStats, BackupNamespace, BackupType, GroupFilter, BACKUP_DATE_REGEX,
BACKUP_FILE_REGEX, CLIENT_LOG_BLOB_NAME, MANIFEST_BLOB_NAME,
Authid, BackupGroupDeleteStats, BackupNamespace, BackupType, GroupFilter, VerifyState,
BACKUP_DATE_REGEX, BACKUP_FILE_REGEX, CLIENT_LOG_BLOB_NAME, MANIFEST_BLOB_NAME,
};
use pbs_config::{open_backup_lockfile, BackupLockGuard};
@ -553,6 +553,11 @@ impl BackupDir {
Ok(())
}
/// Load the verify state from the manifest.
pub fn verify_state(&self) -> Result<Option<VerifyState>, anyhow::Error> {
Ok(self.load_manifest()?.0.verify_state()?.map(|svs| svs.state))
}
}
impl AsRef<pbs_api_types::BackupNamespace> for BackupDir {

View File

@ -3,7 +3,7 @@ use anyhow::{bail, format_err, Error};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use pbs_api_types::{BackupArchiveName, BackupType, CryptMode, Fingerprint};
use pbs_api_types::{BackupArchiveName, BackupType, CryptMode, Fingerprint, SnapshotVerifyState};
use pbs_tools::crypt_config::CryptConfig;
pub const MANIFEST_LOCK_NAME: &str = ".index.json.lck";
@ -224,6 +224,18 @@ impl BackupManifest {
let manifest: BackupManifest = serde_json::from_value(json)?;
Ok(manifest)
}
/// Get the verify state of the snapshot
///
/// Note: New snapshots, which have not been verified yet, do not have a status and this
/// function will return `Ok(None)`.
pub fn verify_state(&self) -> Result<Option<SnapshotVerifyState>, anyhow::Error> {
let verify = self.unprotected["verify_state"].clone();
if verify.is_null() {
return Ok(None);
}
Ok(Some(serde_json::from_value::<SnapshotVerifyState>(verify)?))
}
}
impl TryFrom<super::DataBlob> for BackupManifest {

View File

@ -539,15 +539,13 @@ unsafe fn list_snapshots_blocking(
}
};
let verification = manifest.unprotected["verify_state"].clone();
let verification: Option<SnapshotVerifyState> =
match serde_json::from_value(verification) {
Ok(verify) => verify,
Err(err) => {
eprintln!("error parsing verification state : '{}'", err);
None
}
};
let verification: Option<SnapshotVerifyState> = match manifest.verify_state() {
Ok(verify) => verify,
Err(err) => {
eprintln!("error parsing verification state : '{}'", err);
None
}
};
let size = Some(files.iter().map(|x| x.size.unwrap_or(0)).sum());

View File

@ -8,6 +8,7 @@ use hyper::http::request::Parts;
use hyper::{Body, Request, Response, StatusCode};
use serde::Deserialize;
use serde_json::{json, Value};
use tracing::warn;
use proxmox_rest_server::{H2Service, WorkerTask};
use proxmox_router::{http_err, list_subdirs_api_method};
@ -158,15 +159,18 @@ fn upgrade_to_backup_protocol(
let info = backup_group.last_backup(true).unwrap_or(None);
if let Some(info) = info {
let (manifest, _) = info.backup_dir.load_manifest()?;
let verify = manifest.unprotected["verify_state"].clone();
match serde_json::from_value::<SnapshotVerifyState>(verify) {
Ok(verify) => match verify.state {
match manifest.verify_state() {
Ok(Some(verify)) => match verify.state {
VerifyState::Ok => Some(info),
VerifyState::Failed => None,
},
Err(_) => {
Ok(None) => {
// no verify state found, treat as valid
Some(info)
},
Err(err) => {
warn!("error parsing the snapshot manifest: {err:#}");
Some(info)
}
}
} else {

View File

@ -5,7 +5,7 @@ use std::time::Instant;
use anyhow::{bail, format_err, Error};
use nix::dir::Dir;
use tracing::{error, info};
use tracing::{error, info, warn};
use proxmox_sys::fs::lock_dir_noblock_shared;
use proxmox_worker_task::WorkerTaskContext;
@ -554,10 +554,13 @@ pub fn verify_filter(
return true;
}
let raw_verify_state = manifest.unprotected["verify_state"].clone();
match serde_json::from_value::<SnapshotVerifyState>(raw_verify_state) {
Err(_) => true, // no last verification, always include
Ok(last_verify) => {
match manifest.verify_state() {
Err(err) => {
warn!("error reading manifest: {err:#}");
true
}
Ok(None) => true, // no last verification, always include
Ok(Some(last_verify)) => {
match outdated_after {
None => false, // never re-verify if ignored and no max age
Some(max_age) => {