ic_backup/ops/persistence/inventory/mod.rs
1//! Immutable bounded inventory publication and exact local declared-identity admission.
2
3use super::{BackupLayoutGuard, JournalLockError, PersistenceError, immutable_record};
4use crate::model::{
5 artifacts::ArtifactChecksumRecord,
6 inventory::{InventoryRecord, MAX_INVENTORY_BYTES},
7};
8use thiserror::Error;
9
10/// Durably create `inventory.json` under held layout exclusion without replacing evidence.
11///
12/// # Errors
13/// Rejects excessive canonical bytes, existing/unsafe entries, replaced roots and IO/lock failures.
14pub fn create_inventory(
15 layout: &BackupLayoutGuard,
16 record: &InventoryRecord,
17) -> Result<(), InventoryError> {
18 immutable_record::create(layout, "inventory.json", MAX_INVENTORY_BYTES, record)
19}
20
21/// Read bounded validated local inventory under its original expected canonical digest.
22///
23/// This observes no remote membership or state. A failed/lost creation response
24/// may be reconciled by reading the exact declared digest, never overwriting it.
25///
26/// # Errors
27/// Rejects unsafe/missing/oversized records, invalid declarations, digest mismatch and locks.
28pub fn read_inventory(
29 layout: &BackupLayoutGuard,
30 expected: &ArtifactChecksumRecord,
31) -> Result<InventoryRecord, InventoryError> {
32 immutable_record::read(
33 layout,
34 "inventory.json",
35 MAX_INVENTORY_BYTES,
36 |record: &InventoryRecord| &record.digest() == expected,
37 || InventoryError::DigestMismatch,
38 )
39}
40
41/// Typed exact declared-identity or durable local inventory admission failure.
42#[derive(Debug, Error)]
43pub enum InventoryError {
44 /// Canonical retained declaration differs from its original selected digest.
45 #[error("inventory digest mismatch")]
46 DigestMismatch,
47 /// Exclusive layout/journal ownership failed.
48 #[error(transparent)]
49 Lock(#[from] JournalLockError),
50 /// Bounded JSON, model admission or durable filesystem access failed.
51 #[error(transparent)]
52 Persistence(#[from] PersistenceError),
53}
54
55#[cfg(all(test, unix))]
56mod tests;