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(
42 &config,
43 &request.deployment_name,
44 &mut unresolved_observations,
45 );
46
47 let install_state = read_named_deployment_install_state_from_root(
48 &request.icp_root,
49 &request.network,
50 &request.deployment_name,
51 )
52 .map_err(|err| DeploymentTruthError::LocalState(err.to_string()))?;
53 let raw_config_sha256 = observe_config_sha256(&config, &mut unresolved_observations);
54 let canonical_runtime_config_digest =
55 observe_canonical_runtime_config_digest(&config, &mut unresolved_observations);
56 let deployment_manifest_digest = observe_deployment_manifest_digest(
57 &request.icp_root,
58 &request.network,
59 &mut unresolved_observations,
60 );
61 let observed_artifacts = collect_observed_artifacts(
62 &request.icp_root,
63 &request.network,
64 &local_config_facts.roles,
65 &mut unresolved_observations,
66 );
67 let (observed_canisters, observed_pool) = install_state_observations(
68 install_state.as_ref(),
69 request,
70 &local_config_facts.pool_expectations,
71 &mut unresolved_observations,
72 );
73 let observed_root = observed_root_observation(
74 install_state.as_ref(),
75 request,
76 &local_config_facts.fleet_name,
77 &observed_canisters,
78 );
79 let observed_identity = Some(local_inventory_identity(
80 request,
81 InventoryIdentityFacts {
82 root_principal: install_state
83 .as_ref()
84 .map(|state| state.root_canister_id.clone()),
85 deployment_manifest_digest,
86 canonical_runtime_config_digest: canonical_runtime_config_digest.clone(),
87 observed_canisters: &observed_canisters,
88 observed_artifacts: &observed_artifacts,
89 observed_pool: &observed_pool,
90 },
91 ));
92
93 Ok(DeploymentInventoryV1 {
94 schema_version: DEPLOYMENT_TRUTH_SCHEMA_VERSION,
95 inventory_id: format!("local:{}:{}", request.network, request.deployment_name),
96 observed_at: request.observed_at.clone(),
97 observed_identity,
98 observed_root,
99 local_config: LocalDeploymentConfigV1 {
100 config_path: Some(config.display().to_string()),
101 raw_config_sha256,
102 canonical_embedded_config_sha256: canonical_runtime_config_digest,
103 },
104 observed_canisters,
105 observed_pool,
106 observed_artifacts,
107 observed_verifier_readiness: VerifierReadinessObservationV1 {
108 status: ObservationStatusV1::NotObserved,
109 role_epochs: Vec::new(),
110 },
111 unresolved_observations,
112 })
113}