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