canic_host/install_root/
mod.rs1use crate::release_set::{icp_root, workspace_root};
2use config_selection::resolve_install_config_path;
3use std::{path::PathBuf, time::Instant};
4
5mod activation;
6mod artifact_promotion;
7mod build_environment;
8mod build_targets;
9mod capabilities;
10mod clock;
11mod commands;
12mod config_selection;
13mod current_execution;
14mod deployment_registration;
15mod deployment_truth_gate;
16mod execution_preflight;
17mod identity;
18mod install_state;
19mod operations;
20mod options;
21mod output;
22mod phase_receipts;
23mod plan_artifacts;
24mod preparation;
25mod readiness;
26mod receipt_io;
27mod root_canister;
28mod root_cycles;
29mod root_verification;
30mod staging;
31mod state;
32mod timing;
33mod truth_check;
34
35use activation::run_root_activation_phases;
36use artifact_promotion::write_artifact_promotion_execution_receipt_for_install;
37use build_environment::BuildEnvGuard;
38pub use config_selection::{
39 current_canic_project_root, discover_canic_config_choices, discover_canic_project_root_from,
40 discover_project_canic_config_choices, project_fleet_roots,
41};
42use current_execution::current_install_execution_context;
43pub use deployment_registration::{
44 RegisterDeploymentStateOptions, VerifyDeploymentRootOptions, register_deployment_state,
45 verify_registered_deployment_root,
46};
47use identity::resolve_install_identity;
48use install_state::{build_install_state, write_install_state_with_deployment_truth_receipt};
49pub use options::InstallRootOptions;
50use output::{print_install_result_summary, print_install_timing_summary};
51use phase_receipts::InstallReceiptScope;
52use plan_artifacts::emit_manifest_with_deployment_truth_receipt;
53use preparation::prepare_install_deployment_truth;
54pub use receipt_io::latest_deployment_truth_receipt_path_from_root;
55pub use state::{
56 InstallState, RootVerificationStatus, read_named_deployment_install_state,
57 read_named_deployment_install_state_from_root,
58};
59use timing::InstallTimingSummary as CurrentInstallTimingSummary;
60pub use truth_check::{check_install_deployment_truth, check_install_execution_preflight};
61
62#[cfg(test)]
63mod tests;
64
65pub fn discover_current_canic_config_choices() -> Result<Vec<PathBuf>, Box<dyn std::error::Error>> {
67 let project_root = current_canic_project_root()?;
68 let choices = config_selection::discover_workspace_canic_config_choices(&project_root)?;
69 if !choices.is_empty() {
70 return Ok(choices);
71 }
72
73 if let Ok(icp_root) = icp_root()
74 && icp_root != project_root
75 {
76 return config_selection::discover_workspace_canic_config_choices(&icp_root);
77 }
78
79 Ok(choices)
80}
81
82pub fn install_root(options: InstallRootOptions) -> Result<(), Box<dyn std::error::Error>> {
84 let workspace_root = workspace_root()?;
85 let icp_root = match &options.icp_root {
86 Some(path) => path.canonicalize()?,
87 None => icp_root()?,
88 };
89 let config_path = resolve_install_config_path(
90 &icp_root,
91 options.config_path.as_deref(),
92 options.interactive_config_selection,
93 )?;
94 let _install_env = BuildEnvGuard::apply(&options.network, &config_path, &icp_root);
95 let (fleet_name, deployment_name) = resolve_install_identity(&options, &config_path)?;
96 let total_started_at = Instant::now();
97 let mut timings = CurrentInstallTimingSummary::default();
98 let network = options.network.as_str();
99 let execution_context = current_install_execution_context(&workspace_root, &icp_root, network);
100
101 println!("Installing deployment {deployment_name}");
102 println!("Fleet template {fleet_name}");
103 println!();
104 let prepared = prepare_install_deployment_truth(
105 &options,
106 &workspace_root,
107 &icp_root,
108 &config_path,
109 &deployment_name,
110 &execution_context,
111 )?;
112 timings.create_canisters = prepared.timings.create_canisters;
113 timings.build_all = prepared.timings.build_all;
114
115 let (manifest_path, emit_manifest_duration) = emit_manifest_with_deployment_truth_receipt(
116 &workspace_root,
117 &icp_root,
118 &options,
119 &config_path,
120 &deployment_name,
121 &prepared.deployment_truth_check,
122 &execution_context,
123 )?;
124 timings.emit_manifest = emit_manifest_duration;
125 let activation_timings = run_root_activation_phases(
126 InstallReceiptScope {
127 icp_root: &icp_root,
128 network,
129 deployment_name: &deployment_name,
130 check: &prepared.deployment_truth_check,
131 execution_context: Some(&execution_context),
132 },
133 &options,
134 &prepared.root_canister_id,
135 &manifest_path,
136 total_started_at,
137 )?;
138 timings.install_root = activation_timings.install_root;
139 timings.fund_root = activation_timings.fund_root;
140 timings.stage_release_set = activation_timings.stage_release_set;
141 timings.resume_bootstrap = activation_timings.resume_bootstrap;
142 timings.wait_ready = activation_timings.wait_ready;
143 timings.finalize_root_funding = activation_timings.finalize_root_funding;
144
145 print_install_timing_summary(&timings, total_started_at.elapsed());
146 let state = build_install_state(
147 &options,
148 &workspace_root,
149 &icp_root,
150 &config_path,
151 &manifest_path,
152 (&deployment_name, &fleet_name),
153 &prepared.root_canister_id,
154 )?;
155 let state_path = write_install_state_with_deployment_truth_receipt(
156 InstallReceiptScope {
157 icp_root: &icp_root,
158 network,
159 deployment_name: &deployment_name,
160 check: &prepared.deployment_truth_check,
161 execution_context: Some(&execution_context),
162 },
163 &options.network,
164 &state,
165 )?;
166 write_artifact_promotion_execution_receipt_for_install(
167 &options,
168 &icp_root,
169 network,
170 &deployment_name,
171 &prepared.deployment_truth_check,
172 &execution_context,
173 )?;
174 print_install_result_summary(
175 &options.network,
176 &state.deployment_name,
177 &state.fleet_template,
178 &state_path,
179 );
180 Ok(())
181}