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