Skip to main content

canic_core/dto/
component_provisioning.rs

1//! Module: dto::component_provisioning
2//!
3//! Responsibility: carry one canonical Fleet Component provisioning plan across boundaries.
4//! Does not own: plan derivation, validation, persistence, root effects, or receipts.
5//! Boundary: the Coordinator retains the complete plan and sends each root only its exact batch.
6
7use crate::{
8    config::{ComponentDeploymentLabel, ComponentDeploymentLimits, ComponentDeploymentPurpose},
9    dto::fleet_registry::FleetRegistryVersion,
10    ids::{
11        ComponentBinding, ComponentDeploymentConfigurationDigest, ComponentGroupDeploymentId,
12        ComponentGroupMemberPath, ComponentGroupPlacementId, ComponentGroupSpecId, ComponentSpecId,
13        FleetBinding, FleetSubnetRootBinding, FleetSubnetRootReleaseSet,
14    },
15};
16use candid::{CandidType, Principal};
17use serde::{Deserialize, Serialize};
18
19/// Complete canonical provisioning authority retained before any root effect.
20#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
21#[serde(deny_unknown_fields)]
22pub struct FleetComponentProvisioningPlan {
23    pub fleet: FleetBinding,
24    pub fleet_registry: FleetRegistryVersion,
25    pub configuration_digest: ComponentDeploymentConfigurationDigest,
26    pub operation: FleetComponentProvisioningOperation,
27    pub directory_confirmation_roots: Vec<Principal>,
28    pub batches: Vec<FleetSubnetRootProvisioningBatch>,
29}
30
31/// Controller-authenticated command that durably freezes one complete plan.
32#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
33#[serde(deny_unknown_fields)]
34pub struct FleetComponentProvisioningPrepareRequest {
35    pub operation_id: [u8; 32],
36    pub plan: FleetComponentProvisioningPlan,
37}
38
39/// Controller-authenticated command advancing one exact Coordinator root-acceptance step.
40#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
41#[serde(deny_unknown_fields)]
42pub struct FleetComponentProvisioningAdvanceRequest {
43    pub operation_id: [u8; 32],
44    pub plan_hash: [u8; 32],
45    pub expected_accepted_root_count: u32,
46}
47
48/// Exact passive lookup key for one Coordinator-owned provisioning operation.
49#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
50#[serde(deny_unknown_fields)]
51pub struct FleetComponentProvisioningStatusRequest {
52    pub operation_id: [u8; 32],
53    pub plan_hash: [u8; 32],
54}
55
56/// Durable Coordinator progress exposed without returning the complete plan.
57#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
58pub enum FleetComponentProvisioningPhase {
59    Planned,
60    AcceptingRoots,
61    RootsAccepted,
62}
63
64/// Compact exact status for one Coordinator-owned provisioning operation.
65#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
66#[serde(deny_unknown_fields)]
67pub struct FleetComponentProvisioningStatusResponse {
68    pub operation_id: [u8; 32],
69    pub plan_hash: [u8; 32],
70    pub fleet_registry: FleetRegistryVersion,
71    pub configuration_digest: ComponentDeploymentConfigurationDigest,
72    pub operation: FleetComponentProvisioningOperation,
73    pub phase: FleetComponentProvisioningPhase,
74    pub directory_confirmation_root_count: u32,
75    pub root_batch_count: u32,
76    pub accepted_root_count: u32,
77    pub acceptance_in_flight_root: Option<Principal>,
78    pub group_placement_count: u32,
79    pub component_count: u32,
80    pub planned_at_ns: u64,
81    pub roots_accepted_at_ns: Option<u64>,
82}
83
84/// Fresh-install or monotonic scale-out scope covered by one plan.
85#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
86#[serde(deny_unknown_fields)]
87pub enum FleetComponentProvisioningOperation {
88    FreshInstall,
89    ScaleOut {
90        deployment: ComponentGroupDeploymentId,
91        previous_placements: u32,
92        requested_placements: u32,
93    },
94}
95
96/// One selected root's complete canonical provisioning batch.
97#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
98#[serde(deny_unknown_fields)]
99pub struct FleetSubnetRootProvisioningBatch {
100    pub root: FleetSubnetRootBinding,
101    pub active_release_set: FleetSubnetRootReleaseSet,
102    pub placements: Vec<ComponentGroupPlacementPlan>,
103}
104
105/// One materialized copy of a completely flattened Component Group.
106#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
107#[serde(deny_unknown_fields)]
108pub struct ComponentGroupPlacementPlan {
109    pub group_placement: ComponentGroupPlacementId,
110    pub component_group: ComponentGroupSpecId,
111    pub entries: Vec<ComponentGroupPlanEntry>,
112}
113
114/// One exact top-level Component occurrence within a group placement.
115#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
116#[serde(deny_unknown_fields)]
117pub struct ComponentGroupPlanEntry {
118    pub member_path: ComponentGroupMemberPath,
119    pub component_spec: ComponentSpecId,
120    pub spec_hash: [u8; 32],
121    pub purpose: ComponentDeploymentPurpose,
122    pub labels: Vec<ComponentDeploymentLabel>,
123    pub limits: ComponentDeploymentLimits,
124}
125
126/// Coordinator-authenticated command asking one root to retain its exact plan batch.
127#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
128#[serde(deny_unknown_fields)]
129pub struct RootComponentProvisioningAcceptanceRequest {
130    pub fleet_registry: FleetRegistryVersion,
131    pub configuration_digest: ComponentDeploymentConfigurationDigest,
132    pub operation_id: [u8; 32],
133    pub plan_hash: [u8; 32],
134    pub batch: FleetSubnetRootProvisioningBatch,
135}
136
137/// Read-only lookup key for one exact root provisioning operation.
138#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
139#[serde(deny_unknown_fields)]
140pub struct RootComponentProvisioningStatusRequest {
141    pub operation_id: [u8; 32],
142    pub plan_hash: [u8; 32],
143}
144
145/// Coordinator-authenticated command advancing one exact bounded provisioning step.
146#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
147#[serde(deny_unknown_fields)]
148pub struct RootComponentProvisioningAdvanceRequest {
149    pub operation_id: [u8; 32],
150    pub plan_hash: [u8; 32],
151    pub expected_reserved_component_count: u32,
152    pub expected_claimed_component_count: u32,
153    pub expected_installed_component_count: u32,
154    pub expected_registry_committed_component_count: u32,
155}
156
157/// One exact provisioned Component occurrence and its committed Registry identity.
158#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
159#[serde(deny_unknown_fields)]
160pub struct RootProvisionedGroupMember {
161    pub member_path: ComponentGroupMemberPath,
162    pub component_spec: ComponentSpecId,
163    pub purpose: ComponentDeploymentPurpose,
164    pub limits: ComponentDeploymentLimits,
165    pub binding: ComponentBinding,
166    pub component_registry_revision: u64,
167    pub component_registry_content_hash: [u8; 32],
168}
169
170/// Complete provisioned result for one exact group placement on this root.
171#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
172#[serde(deny_unknown_fields)]
173pub struct RootProvisionedGroupPlacement {
174    pub group_placement: ComponentGroupPlacementId,
175    pub component_group: ComponentGroupSpecId,
176    pub members: Vec<RootProvisionedGroupMember>,
177}
178
179/// Complete group-partitioned result of one root provisioning operation.
180#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
181#[serde(deny_unknown_fields)]
182pub struct RootComponentProvisioningResult {
183    pub placements: Vec<RootProvisionedGroupPlacement>,
184}
185
186/// Durable aggregate progress of one root provisioning batch.
187#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
188pub enum RootComponentProvisioningPhase {
189    Accepted,
190    Provisioned,
191    Published,
192    RuntimesActive,
193}
194
195/// Durable progress or complete terminal result for one exact root provisioning operation.
196#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
197#[serde(deny_unknown_fields)]
198pub struct RootComponentProvisioningStatusResponse {
199    pub operation_id: [u8; 32],
200    pub plan_hash: [u8; 32],
201    pub fleet_registry: FleetRegistryVersion,
202    pub configuration_digest: ComponentDeploymentConfigurationDigest,
203    pub fleet_subnet_root: Principal,
204    pub phase: RootComponentProvisioningPhase,
205    pub placement_count: u32,
206    pub component_count: u32,
207    pub reserved_component_count: u32,
208    pub claimed_component_count: u32,
209    pub installed_component_count: u32,
210    pub registry_committed_component_count: u32,
211    pub result: Option<RootComponentProvisioningResult>,
212    pub accepted_at_ns: u64,
213    pub provisioned_at_ns: Option<u64>,
214    pub receipt_content_hash: [u8; 32],
215}