canic_host/installed_fleet/
mod.rs1use crate::{
2 fleet_catalog::{FleetCatalogEntryV1, FleetCatalogError, read_fleet_catalog_entry_from_root},
3 icp::IcpCommandError,
4 registry::{RegistryEntry, RegistryParseError},
5 replica_query::ReplicaQueryError,
6};
7use std::{collections::BTreeMap, path::Path};
8use thiserror::Error as ThisError;
9
10#[derive(Clone, Debug, Eq, PartialEq)]
15pub struct InstalledFleetRequest {
16 pub fleet: String,
17 pub environment: String,
18 pub icp: String,
19 pub detect_lost_local_root: bool,
20}
21
22#[derive(Clone, Debug, Eq, PartialEq)]
27pub struct InstalledFleetResolution {
28 pub source: InstalledFleetSource,
29 pub fleet: FleetCatalogEntryV1,
30 pub registry: InstalledFleetRegistry,
31 pub topology: ResolvedFleetTopology,
32}
33
34#[derive(Clone, Copy, Debug, Eq, PartialEq)]
39pub enum InstalledFleetSource {
40 LocalReplica,
41 IcpCli,
42}
43
44#[derive(Clone, Debug, Eq, PartialEq)]
49pub struct InstalledFleetRegistry {
50 pub root_canister_id: String,
51 pub entries: Vec<RegistryEntry>,
52}
53
54#[derive(Clone, Debug, Eq, PartialEq)]
59pub struct ResolvedFleetTopology {
60 pub root_canister_id: String,
61 pub children_by_parent: BTreeMap<Option<String>, Vec<String>>,
62 pub roles_by_canister: BTreeMap<String, String>,
63}
64
65#[derive(Debug, ThisError)]
70pub enum InstalledFleetError {
71 #[error("Fleet {fleet} is not installed on environment {environment}")]
72 NoInstalledFleet { environment: String, fleet: String },
73
74 #[error("failed to read the canonical-network Fleet catalog: {0}")]
75 FleetCatalog(#[from] FleetCatalogError),
76
77 #[error("local replica query failed: {0}")]
78 ReplicaQuery(#[source] ReplicaQueryError),
79
80 #[error(transparent)]
81 Icp(#[from] IcpCommandError),
82
83 #[error(
84 "Fleet {fleet} points to root {root}, but that canister is not present on environment {environment}"
85 )]
86 LostLocalFleet {
87 fleet: String,
88 environment: String,
89 root: String,
90 },
91
92 #[error(
93 "Fleet {fleet} is Coordinator-anchored at {coordinator}; the removed single-root topology resolver cannot serve this operation"
94 )]
95 CoordinatorAnchoredTopologyUnavailable { fleet: String, coordinator: String },
96
97 #[error(transparent)]
98 Registry(#[from] RegistryParseError),
99
100 #[error(transparent)]
101 Io(#[from] std::io::Error),
102}
103
104pub fn resolve_installed_fleet_from_root(
105 request: &InstalledFleetRequest,
106 icp_root: &Path,
107) -> Result<InstalledFleetResolution, InstalledFleetError> {
108 let fleet = read_installed_fleet_from_root(&request.environment, &request.fleet, icp_root)?;
109 Err(
110 InstalledFleetError::CoordinatorAnchoredTopologyUnavailable {
111 fleet: fleet.fleet_name.to_string(),
112 coordinator: fleet.coordinator_principal,
113 },
114 )
115}
116
117pub fn read_installed_fleet_from_root(
118 environment: &str,
119 fleet: &str,
120 icp_root: &Path,
121) -> Result<FleetCatalogEntryV1, InstalledFleetError> {
122 read_fleet_catalog_entry_from_root(icp_root, environment, fleet)
123 .map_err(InstalledFleetError::FleetCatalog)?
124 .ok_or_else(|| InstalledFleetError::NoInstalledFleet {
125 environment: environment.to_string(),
126 fleet: fleet.to_string(),
127 })
128}
129
130#[cfg(test)]
131mod tests;