Skip to main content

canic_host/install_root/
mod.rs

1use 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
65/// Discover installable Canic config choices under the current workspace.
66pub 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
82// Execute the local thin-root install flow against an already running replica.
83pub 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}