save last verify result in snapshot manifest
Save the state ("ok" or "failed") and the UPID of the respective verify task. With this we can easily allow to open the relevant task log and show when the last verify happened. As we already load the manifest when listing the snapshots, just add it there directly. Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
1ffe030123
commit
3b2046d263
@ -361,7 +361,7 @@ pub fn list_snapshots (
|
|||||||
|
|
||||||
let mut size = None;
|
let mut size = None;
|
||||||
|
|
||||||
let (comment, files) = match get_all_snapshot_files(&datastore, &info) {
|
let (comment, verification, files) = match get_all_snapshot_files(&datastore, &info) {
|
||||||
Ok((manifest, files)) => {
|
Ok((manifest, files)) => {
|
||||||
size = Some(files.iter().map(|x| x.size.unwrap_or(0)).sum());
|
size = Some(files.iter().map(|x| x.size.unwrap_or(0)).sum());
|
||||||
// extract the first line from notes
|
// extract the first line from notes
|
||||||
@ -370,11 +370,21 @@ pub fn list_snapshots (
|
|||||||
.and_then(|notes| notes.lines().next())
|
.and_then(|notes| notes.lines().next())
|
||||||
.map(String::from);
|
.map(String::from);
|
||||||
|
|
||||||
(comment, files)
|
let verify = manifest.unprotected["verify_state"].clone();
|
||||||
|
let verify: Option<SnapshotVerifyState> = match serde_json::from_value(verify) {
|
||||||
|
Ok(verify) => verify,
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("error parsing verification state : '{}'", err);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(comment, verify, files)
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("error during snapshot file listing: '{}'", err);
|
eprintln!("error during snapshot file listing: '{}'", err);
|
||||||
(
|
(
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
info
|
info
|
||||||
.files
|
.files
|
||||||
@ -394,6 +404,7 @@ pub fn list_snapshots (
|
|||||||
backup_id: group.backup_id().to_string(),
|
backup_id: group.backup_id().to_string(),
|
||||||
backup_time: info.backup_dir.backup_time().timestamp(),
|
backup_time: info.backup_dir.backup_time().timestamp(),
|
||||||
comment,
|
comment,
|
||||||
|
verification,
|
||||||
files,
|
files,
|
||||||
size,
|
size,
|
||||||
owner: Some(owner),
|
owner: Some(owner),
|
||||||
|
@ -6,6 +6,7 @@ use proxmox::const_regex;
|
|||||||
use proxmox::{IPRE, IPV4RE, IPV6RE, IPV4OCTET, IPV6H16, IPV6LS32};
|
use proxmox::{IPRE, IPV4RE, IPV6RE, IPV4OCTET, IPV6H16, IPV6LS32};
|
||||||
|
|
||||||
use crate::backup::CryptMode;
|
use crate::backup::CryptMode;
|
||||||
|
use crate::server::UPID;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
@ -379,6 +380,25 @@ pub struct GroupListItem {
|
|||||||
pub owner: Option<Userid>,
|
pub owner: Option<Userid>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api(
|
||||||
|
properties: {
|
||||||
|
upid: {
|
||||||
|
schema: UPID_SCHEMA
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)]
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
/// Task properties.
|
||||||
|
pub struct SnapshotVerifyState {
|
||||||
|
/// UPID of the verify task
|
||||||
|
pub upid: UPID,
|
||||||
|
/// State of the verification. "failed" or "ok"
|
||||||
|
pub state: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[api(
|
#[api(
|
||||||
properties: {
|
properties: {
|
||||||
"backup-type": {
|
"backup-type": {
|
||||||
@ -394,6 +414,10 @@ pub struct GroupListItem {
|
|||||||
schema: SINGLE_LINE_COMMENT_SCHEMA,
|
schema: SINGLE_LINE_COMMENT_SCHEMA,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
verification: {
|
||||||
|
type: SnapshotVerifyState,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
files: {
|
files: {
|
||||||
items: {
|
items: {
|
||||||
schema: BACKUP_ARCHIVE_NAME_SCHEMA
|
schema: BACKUP_ARCHIVE_NAME_SCHEMA
|
||||||
@ -415,6 +439,9 @@ pub struct SnapshotListItem {
|
|||||||
/// The first line from manifest "notes"
|
/// The first line from manifest "notes"
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
pub comment: Option<String>,
|
pub comment: Option<String>,
|
||||||
|
/// The result of the last run verify task
|
||||||
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
|
pub verification: Option<SnapshotVerifyState>,
|
||||||
/// List of contained archive files.
|
/// List of contained archive files.
|
||||||
pub files: Vec<BackupContent>,
|
pub files: Vec<BackupContent>,
|
||||||
/// Overall snapshot size (sum of all archive sizes).
|
/// Overall snapshot size (sum of all archive sizes).
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use anyhow::{bail, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
|
|
||||||
use crate::server::WorkerTask;
|
use crate::server::WorkerTask;
|
||||||
|
use crate::api2::types::*;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
DataStore, BackupGroup, BackupDir, BackupInfo, IndexFile,
|
DataStore, BackupGroup, BackupDir, BackupInfo, IndexFile,
|
||||||
@ -178,7 +179,7 @@ pub fn verify_backup_dir(
|
|||||||
worker: &WorkerTask
|
worker: &WorkerTask
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
|
|
||||||
let manifest = match datastore.load_manifest(&backup_dir) {
|
let mut manifest = match datastore.load_manifest(&backup_dir) {
|
||||||
Ok((manifest, _)) => manifest,
|
Ok((manifest, _)) => manifest,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
worker.log(format!("verify {}:{} - manifest load error: {}", datastore.name(), backup_dir, err));
|
worker.log(format!("verify {}:{} - manifest load error: {}", datastore.name(), backup_dir, err));
|
||||||
@ -190,6 +191,7 @@ pub fn verify_backup_dir(
|
|||||||
|
|
||||||
let mut error_count = 0;
|
let mut error_count = 0;
|
||||||
|
|
||||||
|
let mut verify_result = "ok";
|
||||||
for info in manifest.files() {
|
for info in manifest.files() {
|
||||||
let result = proxmox::try_block!({
|
let result = proxmox::try_block!({
|
||||||
worker.log(format!(" check {}", info.filename));
|
worker.log(format!(" check {}", info.filename));
|
||||||
@ -221,9 +223,20 @@ pub fn verify_backup_dir(
|
|||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
worker.log(format!("verify {}:{}/{} failed: {}", datastore.name(), backup_dir, info.filename, err));
|
worker.log(format!("verify {}:{}/{} failed: {}", datastore.name(), backup_dir, info.filename, err));
|
||||||
error_count += 1;
|
error_count += 1;
|
||||||
|
verify_result = "failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let verify_state = SnapshotVerifyState {
|
||||||
|
state: verify_result.to_string(),
|
||||||
|
upid: worker.upid().clone(),
|
||||||
|
};
|
||||||
|
manifest.unprotected["verify_state"] = serde_json::to_value(verify_state)?;
|
||||||
|
datastore.store_manifest(&backup_dir, serde_json::to_value(manifest)?)
|
||||||
|
.map_err(|err| format_err!("unable to store manifest blob - {}", err))?;
|
||||||
|
|
||||||
|
|
||||||
Ok(error_count == 0)
|
Ok(error_count == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user