canic_host/deployment_truth/observe/inventory/
mod.rs1use super::super::*;
2use super::artifacts::{
3 collect_observed_artifacts, observe_canonical_runtime_config_digest, observe_config_sha256,
4 observe_deployment_manifest_digest,
5};
6use super::config::observe_local_config_facts;
7use super::identity::{InventoryIdentityFacts, local_inventory_identity};
8use super::root::{install_state_observations, observed_root_observation};
9use crate::install_root::read_named_deployment_install_state_from_root;
10use std::path::PathBuf;
11use thiserror::Error as ThisError;
12
13#[derive(Clone, Debug, Eq, PartialEq)]
17pub struct LocalInventoryRequest {
18 pub deployment_name: String,
19 pub network: String,
20 pub workspace_root: PathBuf,
21 pub icp_root: PathBuf,
22 pub config_path: Option<PathBuf>,
23 pub observed_at: String,
24}
25
26#[derive(Debug, ThisError)]
30pub enum DeploymentTruthError {
31 #[error("failed to read local deployment state: {0}")]
32 LocalState(String),
33}
34
35pub fn collect_local_deployment_inventory(
37 request: &LocalInventoryRequest,
38) -> Result<DeploymentInventoryV1, DeploymentTruthError> {
39 let config = deployment_config_path(&request.workspace_root, request.config_path.as_deref());
40 let mut unresolved_observations = Vec::new();
41 let local_config_facts = observe_local_config_facts(&config, &mut unresolved_observations);
42
43 let install_state = read_named_deployment_install_state_from_root(
44 &request.icp_root,
45 &request.network,
46 &request.deployment_name,
47 )
48 .map_err(|err| DeploymentTruthError::LocalState(err.to_string()))?;
49 let raw_config_sha256 = observe_config_sha256(&config, &mut unresolved_observations);
50 let canonical_runtime_config_digest =
51 observe_canonical_runtime_config_digest(&config, &mut unresolved_observations);
52 let deployment_manifest_digest = observe_deployment_manifest_digest(
53 &request.icp_root,
54 &request.network,
55 &mut unresolved_observations,
56 );
57 let observed_artifacts = collect_observed_artifacts(
58 &request.icp_root,
59 &request.network,
60 &local_config_facts.roles,
61 &mut unresolved_observations,
62 );
63 let (observed_canisters, observed_pool) = install_state_observations(
64 install_state.as_ref(),
65 request,
66 &local_config_facts.pool_expectations,
67 &mut unresolved_observations,
68 );
69 let observed_root = observed_root_observation(
70 install_state.as_ref(),
71 request,
72 &local_config_facts.fleet_name,
73 &observed_canisters,
74 );
75 let observed_identity = Some(local_inventory_identity(
76 request,
77 InventoryIdentityFacts {
78 root_principal: install_state
79 .as_ref()
80 .map(|state| state.root_canister_id.clone()),
81 deployment_manifest_digest,
82 canonical_runtime_config_digest: canonical_runtime_config_digest.clone(),
83 observed_canisters: &observed_canisters,
84 observed_artifacts: &observed_artifacts,
85 observed_pool: &observed_pool,
86 },
87 ));
88
89 Ok(DeploymentInventoryV1 {
90 schema_version: DEPLOYMENT_TRUTH_SCHEMA_VERSION,
91 inventory_id: format!("local:{}:{}", request.network, request.deployment_name),
92 observed_at: request.observed_at.clone(),
93 observed_identity,
94 observed_root,
95 local_config: LocalDeploymentConfigV1 {
96 config_path: Some(config.display().to_string()),
97 raw_config_sha256,
98 canonical_embedded_config_sha256: canonical_runtime_config_digest,
99 },
100 observed_canisters,
101 observed_pool,
102 observed_artifacts,
103 observed_verifier_readiness: VerifierReadinessObservationV1 {
104 status: ObservationStatusV1::NotObserved,
105 role_epochs: Vec::new(),
106 },
107 unresolved_observations,
108 })
109}