canic-host 0.111.0

Host-side App build and desired-state Fleet reconciliation library for Canic workspaces
Documentation
use std::path::PathBuf;

use serde::{Deserialize, Serialize};

pub(super) const LOCAL_ICP_TARGET: &str = "local";
pub(super) const REQUIRED_ICP_CLI_VERSION: &str = "1.5.0";
pub(super) const ICP_CLI_SUPPORTED_VERSION_RANGE: &str = ">=1.5.0, <2.0.0";

/// Direct local replica endpoint used when ICP project state is unavailable.
///
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct LocalReplicaTarget {
    /// Exact selected local environment; another environment must use its own network authority.
    pub environment: String,
    pub url: String,
    pub root_key: String,
}

///
/// IcpRawOutput
///

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct IcpRawOutput {
    pub success: bool,
    pub status: String,
    pub stdout: Vec<u8>,
    pub stderr: Vec<u8>,
}

///
/// IcpCli
///

#[derive(Clone, Debug)]
pub struct IcpCli {
    pub(super) timing: std::sync::Arc<super::timing::Timing>,
    pub(super) identity_lookup_millis: std::sync::Arc<std::sync::atomic::AtomicU64>,
    pub(super) identity_lookups: std::sync::Arc<std::sync::atomic::AtomicU64>,
    pub(super) remote_calls: std::sync::Arc<std::sync::atomic::AtomicU64>,
    pub(super) executable: String,
    pub(super) environment: Option<String>,
    pub(super) cwd: Option<PathBuf>,
    pub(super) local_replica: Option<LocalReplicaTarget>,
    pub(super) inherited_fd: Option<i32>,
    pub(super) identity_password_file: Option<PathBuf>,
    pub(super) selected_identity: std::sync::Arc<std::sync::OnceLock<String>>,
    pub(super) compatible_version: std::sync::Arc<std::sync::Mutex<Option<String>>>,
    pub(super) query_transport:
        std::sync::Arc<std::sync::Mutex<Option<std::sync::Arc<super::query::QueryTransport>>>>,
}

///
/// IcpCliVersion
///
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub(super) struct IcpCliVersion {
    pub(super) major: u64,
    pub(super) minor: u64,
    pub(super) patch: u64,
}

///
/// IcpSnapshot
///

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct IcpSnapshot {
    pub snapshot_id: String,
    pub taken_at_timestamp: Option<u64>,
    pub total_size_bytes: Option<u64>,
}

///
/// IcpCanisterStatusReport
///

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct IcpCanisterStatusReport {
    #[serde(default, rename = "version", alias = "canister_version")]
    pub canister_version: Option<u64>,
    #[serde(default, rename = "controllers")]
    pub public_controllers: Option<Vec<String>>,
    pub id: String,
    pub name: Option<String>,
    pub status: Option<String>,
    pub settings: Option<IcpCanisterStatusSettings>,
    pub module_hash: Option<String>,
    pub memory_size: Option<String>,
    pub cycles: Option<String>,
    pub reserved_cycles: Option<String>,
    pub idle_cycles_burned_per_day: Option<String>,
    pub query_stats: Option<IcpCanisterQueryStats>,
}

///
/// IcpCanisterStatusSettings
///

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct IcpCanisterStatusSettings {
    #[serde(default)]
    pub controllers: Vec<String>,
    pub compute_allocation: Option<String>,
    pub memory_allocation: Option<String>,
    pub freezing_threshold: Option<String>,
    pub reserved_cycles_limit: Option<String>,
    pub wasm_memory_limit: Option<String>,
    pub wasm_memory_threshold: Option<String>,
    pub log_memory_limit: Option<String>,
    pub log_visibility: Option<IcpCanisterVisibility>,
    pub snapshot_visibility: Option<IcpCanisterVisibility>,
    pub status_visibility: Option<IcpCanisterVisibility>,
}

/// Transport context identity excludes informational counters.
#[derive(Eq, PartialEq)]
struct IcpCommandIdentity<'a> {
    executable: &'a str,
    environment: Option<&'a str>,
    cwd: Option<&'a std::path::Path>,
    local_replica: Option<&'a LocalReplicaTarget>,
    inherited_fd: Option<i32>,
    identity_password_file: Option<&'a std::path::Path>,
    selected_identity: Option<&'a str>,
}

impl IcpCli {
    fn command_identity(&self) -> IcpCommandIdentity<'_> {
        IcpCommandIdentity {
            executable: &self.executable,
            environment: self.environment.as_deref(),
            cwd: self.cwd.as_deref(),
            local_replica: self.local_replica.as_ref(),
            inherited_fd: self.inherited_fd,
            identity_password_file: self.identity_password_file.as_deref(),
            selected_identity: self.selected_identity.get().map(String::as_str),
        }
    }
}

impl PartialEq for IcpCli {
    fn eq(&self, other: &Self) -> bool {
        self.command_identity() == other.command_identity()
    }
}
impl Eq for IcpCli {}
///
/// IcpCanisterVisibility
///
/// Visibility of one management observation surface; this grants no controller authority.
///

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(tag = "type", content = "value")]
pub enum IcpCanisterVisibility {
    AllowedViewers(Vec<candid::Principal>),
    Controllers,
    Public,
}

///
/// IcpCanisterQueryStats
///
/// Cumulative query counters preserving ICP's numeric text without narrowing.
///

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct IcpCanisterQueryStats {
    pub num_calls_total: String,
    pub num_instructions_total: String,
    pub request_payload_bytes_total: String,
    pub response_payload_bytes_total: String,
}