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::{InstallStateError, 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 environment: String,
20 pub artifact_environment: String,
21 pub workspace_root: PathBuf,
22 pub icp_root: PathBuf,
23 pub config_path: Option<PathBuf>,
24 pub observed_at: String,
25}
26
27#[derive(Debug, ThisError)]
31pub enum DeploymentTruthError {
32 #[error("failed to read local deployment state: {0}")]
33 LocalState(#[source] InstallStateError),
34}
35
36pub fn collect_local_deployment_inventory(
38 request: &LocalInventoryRequest,
39) -> Result<DeploymentInventoryV1, DeploymentTruthError> {
40 let config = deployment_config_path(&request.workspace_root, request.config_path.as_deref());
41 let mut unresolved_observations = Vec::new();
42 let local_config_facts = observe_local_config_facts(&config, &mut unresolved_observations);
43
44 let install_state = read_named_deployment_install_state_from_root(
45 &request.icp_root,
46 &request.environment,
47 &request.deployment_name,
48 )
49 .map_err(DeploymentTruthError::LocalState)?;
50 let raw_config_sha256 = observe_config_sha256(&config, &mut unresolved_observations);
51 let canonical_runtime_config_digest =
52 observe_canonical_runtime_config_digest(&config, &mut unresolved_observations);
53 let deployment_manifest_digest = observe_deployment_manifest_digest(
54 &request.icp_root,
55 &request.artifact_environment,
56 &mut unresolved_observations,
57 );
58 let observed_artifacts = collect_observed_artifacts(
59 &request.icp_root,
60 &request.artifact_environment,
61 &local_config_facts.roles,
62 &mut unresolved_observations,
63 );
64 let (observed_canisters, observed_pool) = install_state_observations(
65 install_state.as_ref(),
66 request,
67 &local_config_facts.pool_expectations,
68 &mut unresolved_observations,
69 );
70 let observed_root = observed_root_observation(
71 install_state.as_ref(),
72 request,
73 &local_config_facts.fleet_name,
74 &observed_canisters,
75 );
76 let observed_identity = Some(local_inventory_identity(
77 request,
78 InventoryIdentityFacts {
79 root_principal: install_state
80 .as_ref()
81 .map(|state| state.root_canister_id.clone()),
82 deployment_manifest_digest,
83 canonical_runtime_config_digest: canonical_runtime_config_digest.clone(),
84 observed_canisters: &observed_canisters,
85 observed_artifacts: &observed_artifacts,
86 observed_pool: &observed_pool,
87 },
88 ));
89
90 Ok(DeploymentInventoryV1 {
91 schema_version: DEPLOYMENT_TRUTH_SCHEMA_VERSION,
92 inventory_id: format!("local:{}:{}", request.environment, request.deployment_name),
93 observed_at: request.observed_at.clone(),
94 observed_identity,
95 observed_root,
96 local_config: LocalDeploymentConfigV1 {
97 config_path: Some(config.display().to_string()),
98 raw_config_sha256,
99 canonical_embedded_config_sha256: canonical_runtime_config_digest,
100 },
101 observed_canisters,
102 observed_pool,
103 observed_artifacts,
104 observed_verifier_readiness: VerifierReadinessObservationV1 {
105 status: ObservationStatusV1::NotObserved,
106 role_epochs: Vec::new(),
107 },
108 unresolved_observations,
109 })
110}