ic_backup/ops/persistence/operation_plan/
mod.rs1use super::json::check_json_size;
4use super::{
5 BackupLayoutGuard, JournalLock, JournalLockError, PersistenceError, create_json_durable,
6 read_json,
7};
8use crate::model::{
9 artifacts::ArtifactChecksumRecord,
10 operation_plan::{MAX_OPERATION_PLAN_BYTES, OperationPlanRecord},
11};
12use thiserror::Error;
13
14pub fn create_operation_plan(
22 layout: &BackupLayoutGuard,
23 record: &OperationPlanRecord,
24) -> Result<(), OperationPlanPersistenceError> {
25 layout.check_root()?;
26 let path = layout.root().join("operation-plan.json");
27 let _lock = JournalLock::acquire(&path)?;
28 check_json_size(record, MAX_OPERATION_PLAN_BYTES)?;
29 create_json_durable(&path, record)?;
30 Ok(())
31}
32
33pub fn read_operation_plan(
41 layout: &BackupLayoutGuard,
42 expected: &ArtifactChecksumRecord,
43) -> Result<OperationPlanRecord, OperationPlanPersistenceError> {
44 layout.check_root()?;
45 let path = layout.root().join("operation-plan.json");
46 let _lock = JournalLock::acquire(&path)?;
47 let record: OperationPlanRecord = read_json(&path, MAX_OPERATION_PLAN_BYTES)?;
48 check_json_size(&record, MAX_OPERATION_PLAN_BYTES)?;
49 if &record.digest() != expected {
50 return Err(OperationPlanPersistenceError::DigestMismatch);
51 }
52 Ok(record)
53}
54
55#[derive(Debug, Error)]
57pub enum OperationPlanPersistenceError {
58 #[error("operation plan digest mismatch")]
60 DigestMismatch,
61 #[error(transparent)]
63 Lock(#[from] JournalLockError),
64 #[error(transparent)]
66 Persistence(#[from] PersistenceError),
67}
68
69#[cfg(all(test, unix))]
70mod tests;