canic_host/deployment_truth/
plan.rs1use super::*;
2use crate::release_set::{configured_fleet_name, configured_fleet_roles};
3use std::path::PathBuf;
4
5#[derive(Clone, Debug, Eq, PartialEq)]
9pub struct LocalDeploymentPlanRequest {
10 pub deployment_name: String,
11 pub network: String,
12 pub workspace_root: PathBuf,
13 pub icp_root: PathBuf,
14 pub config_path: Option<PathBuf>,
15 pub runtime_variant: String,
16 pub build_profile: String,
17}
18
19#[must_use]
22pub fn build_local_deployment_plan(request: &LocalDeploymentPlanRequest) -> DeploymentPlanV1 {
23 let config = deployment_config_path(&request.workspace_root, request.config_path.as_deref());
24 let mut unresolved_assumptions = Vec::new();
25 let fleet_template = configured_fleet_name(&config).unwrap_or_else(|err| {
26 unresolved_assumptions.push(assumption(
27 "local_config.fleet_name",
28 format!(
29 "could not resolve fleet template name from {}: {err}",
30 config.display()
31 ),
32 ));
33 request.deployment_name.clone()
34 });
35 let roles = configured_fleet_roles(&config).unwrap_or_else(|err| {
36 unresolved_assumptions.push(assumption(
37 "local_config.roles",
38 format!(
39 "could not resolve configured roles from {}: {err}",
40 config.display()
41 ),
42 ));
43 Vec::new()
44 });
45 let artifact_manifest = collect_local_role_artifact_manifest(&LocalArtifactManifestRequest {
46 network: request.network.clone(),
47 workspace_root: request.workspace_root.clone(),
48 icp_root: request.icp_root.clone(),
49 config_path: Some(config),
50 });
51 unresolved_assumptions.extend(
52 artifact_manifest
53 .unresolved_artifacts
54 .into_iter()
55 .map(|gap| assumption(gap.key, gap.description)),
56 );
57
58 DeploymentPlanV1 {
59 schema_version: DEPLOYMENT_TRUTH_SCHEMA_VERSION,
60 plan_id: format!("local:{}:{}:plan", request.network, request.deployment_name),
61 deployment_identity: DeploymentIdentityV1 {
62 deployment_name: request.deployment_name.clone(),
63 network: request.network.clone(),
64 root_principal: None,
65 authority_profile_hash: None,
66 role_topology_hash: None,
67 deployment_manifest_digest: None,
68 canonical_runtime_config_digest: None,
69 role_embedded_config_set_digest: None,
70 artifact_set_digest: None,
71 pool_identity_set_digest: None,
72 canic_version: Some(env!("CARGO_PKG_VERSION").to_string()),
73 ic_memory_version: None,
74 },
75 trust_domain: TrustDomainV1 {
76 root_trust_anchor: None,
77 migration_from: None,
78 },
79 fleet_template,
80 runtime_variant: request.runtime_variant.clone(),
81 authority_profile: AuthorityProfileV1 {
82 profile_id: format!(
83 "local:{}:{}:authority",
84 request.network, request.deployment_name
85 ),
86 expected_controllers: Vec::new(),
87 staging_controllers: Vec::new(),
88 emergency_controllers: Vec::new(),
89 },
90 role_artifacts: artifact_manifest
91 .role_artifacts
92 .into_iter()
93 .map(|mut artifact| {
94 artifact.build_profile.clone_from(&request.build_profile);
95 artifact
96 })
97 .collect(),
98 expected_canisters: roles
99 .into_iter()
100 .map(|role| ExpectedCanisterV1 {
101 role,
102 canister_id: None,
103 control_class: CanisterControlClassV1::DeploymentControlled,
104 })
105 .collect(),
106 expected_pool: Vec::new(),
107 expected_verifier_readiness: VerifierReadinessExpectationV1 {
108 required: false,
109 expected_role_epochs: Vec::new(),
110 },
111 unresolved_assumptions,
112 }
113}
114
115fn assumption(key: impl Into<String>, description: impl Into<String>) -> DeploymentAssumptionV1 {
116 DeploymentAssumptionV1 {
117 key: key.into(),
118 description: description.into(),
119 }
120}