ic_backup/ops/persistence/execution_progress/
mod.rs1use super::{AttemptJournalError, BackupLayoutGuard, OperationPlanPersistenceError};
4use crate::{
5 model::{
6 artifacts::ArtifactChecksumRecord, attempt_journal::AttemptJournalRecord,
7 operation_plan::OperationPlanError,
8 },
9 policy::execution_progress::{ExecutionProgressError, ExecutionProgressView, admit_progress},
10};
11use thiserror::Error;
12
13pub fn read_execution_progress(
23 layout: &BackupLayoutGuard,
24 expected_plan: &ArtifactChecksumRecord,
25) -> Result<ExecutionProgressView, ExecutionProgressPersistenceError> {
26 let (plan, journals) = super::attempt_journal::read_original_plan_journals::<
27 ExecutionProgressPersistenceError,
28 >(layout, expected_plan, None)?;
29 Ok(admit_progress(&plan, journals.iter())?.project(&plan)?)
30}
31
32pub(super) fn admit_with_current(
33 layout: &BackupLayoutGuard,
34 expected_plan: &ArtifactChecksumRecord,
35 current: &AttemptJournalRecord,
36 require_dependencies: bool,
37) -> Result<(), ExecutionProgressPersistenceError> {
38 let (plan, journals) = super::attempt_journal::read_original_plan_journals::<
39 ExecutionProgressPersistenceError,
40 >(layout, expected_plan, Some(current))?;
41 let admitted = admit_progress(&plan, journals.iter())?;
42 let sequence = current.authority().binding().operation_sequence();
43 if require_dependencies
44 && !admitted.dependencies_applied(plan.operation(sequence)?.depends_on())
45 {
46 return Err(ExecutionProgressPersistenceError::DependenciesUnapplied(
47 sequence,
48 ));
49 }
50 Ok(())
51}
52
53#[derive(Debug, Error)]
55pub enum ExecutionProgressPersistenceError {
56 #[error(transparent)]
58 Plan(#[from] OperationPlanPersistenceError),
59 #[error(transparent)]
61 Authority(#[from] OperationPlanError),
62 #[error(transparent)]
64 Journal(#[from] AttemptJournalError),
65 #[error(transparent)]
67 Policy(#[from] ExecutionProgressError),
68 #[error("operation {0} has unapplied prerequisites")]
70 DependenciesUnapplied(u64),
71}
72
73#[cfg(all(test, unix))]
74mod tests;