ic_backup/ops/persistence/consistency/
mod.rs1use super::{
4 BackupLayoutGuard, JournalLock, JournalLockError, OperationPlanPersistenceError,
5 PersistenceError, create_json_durable, read_json, read_operation_plan,
6};
7use crate::model::{
8 artifacts::ArtifactChecksumRecord,
9 consistency::{
10 ConsistencyRequirementError, ConsistencyRequirementRecord,
11 MAX_CONSISTENCY_REQUIREMENT_BYTES,
12 },
13 operation_plan::OperationPlanRecord,
14};
15use thiserror::Error;
16
17pub fn create_consistency_requirement(
24 layout: &BackupLayoutGuard,
25 plan: &OperationPlanRecord,
26 record: &ConsistencyRequirementRecord,
27) -> Result<(), ConsistencyPersistenceError> {
28 record.validate_plan(plan)?;
29 read_operation_plan(layout, &plan.digest())?;
30 let path = layout.root().join("consistency-requirement.json");
31 let _lock = JournalLock::acquire(&path)?;
32 check_size(record)?;
33 create_json_durable(&path, record)?;
34 Ok(())
35}
36pub fn read_consistency_requirement(
43 layout: &BackupLayoutGuard,
44 plan: &OperationPlanRecord,
45 expected: &ArtifactChecksumRecord,
46) -> Result<ConsistencyRequirementRecord, ConsistencyPersistenceError> {
47 read_operation_plan(layout, &plan.digest())?;
48 let path = layout.root().join("consistency-requirement.json");
49 let _lock = JournalLock::acquire(&path)?;
50 let record: ConsistencyRequirementRecord = read_json(&path, MAX_CONSISTENCY_REQUIREMENT_BYTES)?;
51 check_size(&record)?;
52 record.validate_plan(plan)?;
53 if &record.digest() != expected {
54 return Err(ConsistencyPersistenceError::DigestMismatch);
55 }
56 Ok(record)
57}
58fn check_size(record: &ConsistencyRequirementRecord) -> Result<(), PersistenceError> {
59 if serde_json::to_vec_pretty(record)?.len() as u64 > MAX_CONSISTENCY_REQUIREMENT_BYTES {
60 return Err(PersistenceError::RecordTooLarge {
61 limit: MAX_CONSISTENCY_REQUIREMENT_BYTES,
62 });
63 }
64 Ok(())
65}
66#[derive(Debug, Error)]
68pub enum ConsistencyPersistenceError {
69 #[error("consistency requirement digest mismatch")]
71 DigestMismatch,
72 #[error(transparent)]
74 Requirement(#[from] ConsistencyRequirementError),
75 #[error(transparent)]
77 Plan(#[from] OperationPlanPersistenceError),
78 #[error(transparent)]
80 Lock(#[from] JournalLockError),
81 #[error(transparent)]
83 Persistence(#[from] PersistenceError),
84}
85
86#[cfg(all(test, unix))]
87mod tests;