ic_backup/ops/persistence/restore_safety/
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 operation_plan::OperationPlanRecord,
10 restore_safety::{
11 MAX_RESTORE_SAFETY_REQUIREMENT_BYTES, RestoreSafetyRequirementError,
12 RestoreSafetyRequirementRecord,
13 },
14};
15use thiserror::Error;
16
17pub fn create_restore_safety_requirement(
25 layout: &BackupLayoutGuard,
26 source_layout: &BackupLayoutGuard,
27 plan: &OperationPlanRecord,
28 source: &OperationPlanRecord,
29 record: &RestoreSafetyRequirementRecord,
30) -> Result<(), RestoreSafetyPersistenceError> {
31 record.validate_plans(plan, source)?;
32 read_operation_plan(layout, &plan.digest())?;
33 read_operation_plan(source_layout, &source.digest())?;
34 let path = layout.root().join("restore-safety-requirement.json");
35 let _lock = JournalLock::acquire(&path)?;
36 check_size(record)?;
37 create_json_durable(&path, record)?;
38 Ok(())
39}
40pub fn read_restore_safety_requirement(
47 layout: &BackupLayoutGuard,
48 source_layout: &BackupLayoutGuard,
49 plan: &OperationPlanRecord,
50 source: &OperationPlanRecord,
51 expected: &ArtifactChecksumRecord,
52) -> Result<RestoreSafetyRequirementRecord, RestoreSafetyPersistenceError> {
53 read_operation_plan(layout, &plan.digest())?;
54 read_operation_plan(source_layout, &source.digest())?;
55 let path = layout.root().join("restore-safety-requirement.json");
56 let _lock = JournalLock::acquire(&path)?;
57 let record: RestoreSafetyRequirementRecord =
58 read_json(&path, MAX_RESTORE_SAFETY_REQUIREMENT_BYTES)?;
59 check_size(&record)?;
60 record.validate_plans(plan, source)?;
61 if &record.digest() != expected {
62 return Err(RestoreSafetyPersistenceError::DigestMismatch);
63 }
64 Ok(record)
65}
66fn check_size(record: &RestoreSafetyRequirementRecord) -> Result<(), PersistenceError> {
67 super::json::check_json_size(record, MAX_RESTORE_SAFETY_REQUIREMENT_BYTES)
68}
69#[derive(Debug, Error)]
71pub enum RestoreSafetyPersistenceError {
72 #[error("restore safety requirement digest mismatch")]
74 DigestMismatch,
75 #[error(transparent)]
77 Requirement(#[from] RestoreSafetyRequirementError),
78 #[error(transparent)]
80 Plan(#[from] OperationPlanPersistenceError),
81 #[error(transparent)]
83 Lock(#[from] JournalLockError),
84 #[error(transparent)]
86 Persistence(#[from] PersistenceError),
87}
88
89#[cfg(all(test, unix))]
90mod tests;