use super::*;
use candid::utils::ArgumentEncoder;
impl MgmtOps {
pub async fn create_canister(
controllers: Vec<Principal>,
cycles: Cycles,
) -> Result<Principal, InternalError> {
let pid = management_call(
ManagementCallMetricOperation::CreateCanister,
MgmtInfra::create_canister(controllers, cycles),
)
.await?;
SystemMetrics::increment(SystemMetricKind::CreateCanister);
Ok(pid)
}
pub async fn install_chunked_code<T: ArgumentEncoder>(
mode: CanisterInstallMode,
target_canister: Principal,
store_canister: Principal,
chunk_hashes_list: Vec<Vec<u8>>,
wasm_module_hash: Vec<u8>,
args: T,
) -> Result<(), InternalError> {
let chunk_count = chunk_hashes_list.len();
management_call(
ManagementCallMetricOperation::InstallChunkedCode,
MgmtInfra::install_chunked_code(
install_mode_to_infra(mode),
target_canister,
store_canister,
chunk_hashes_list,
wasm_module_hash,
args,
),
)
.await?;
let metric_kind = match mode {
CanisterInstallMode::Install => SystemMetricKind::InstallCode,
CanisterInstallMode::Reinstall => SystemMetricKind::ReinstallCode,
CanisterInstallMode::Upgrade(_) => SystemMetricKind::UpgradeCode,
};
SystemMetrics::increment(metric_kind);
log!(
Topic::CanisterLifecycle,
Ok,
"install_chunked_code: {target_canister} mode={mode:?} store={store_canister} chunks={chunk_count}"
);
Ok(())
}
pub async fn install_code<T: ArgumentEncoder>(
mode: CanisterInstallMode,
target_canister: Principal,
wasm_module: Vec<u8>,
args: T,
) -> Result<(), InternalError> {
let payload_size_bytes = wasm_module.len();
management_call(
ManagementCallMetricOperation::InstallCode,
MgmtInfra::install_code(
install_mode_to_infra(mode),
target_canister,
wasm_module,
args,
),
)
.await?;
let metric_kind = match mode {
CanisterInstallMode::Install => SystemMetricKind::InstallCode,
CanisterInstallMode::Reinstall => SystemMetricKind::ReinstallCode,
CanisterInstallMode::Upgrade(_) => SystemMetricKind::UpgradeCode,
};
SystemMetrics::increment(metric_kind);
log!(
Topic::CanisterLifecycle,
Ok,
"install_code: {target_canister} mode={mode:?} embedded_bytes={payload_size_bytes}"
);
Ok(())
}
pub async fn install_chunked_canister_with_payload<P: CandidType>(
mode: CanisterInstallMode,
target_canister: Principal,
store_canister: Principal,
chunk_hashes_list: Vec<Vec<u8>>,
wasm_module_hash: Vec<u8>,
payload: P,
extra_arg: Option<Vec<u8>>,
) -> Result<(), InternalError> {
Self::install_chunked_code(
mode,
target_canister,
store_canister,
chunk_hashes_list,
wasm_module_hash,
(payload, extra_arg),
)
.await
}
pub async fn install_embedded_canister_with_payload<P: CandidType>(
mode: CanisterInstallMode,
target_canister: Principal,
wasm_module: Vec<u8>,
payload: P,
extra_arg: Option<Vec<u8>>,
) -> Result<(), InternalError> {
Self::install_code(mode, target_canister, wasm_module, (payload, extra_arg)).await
}
pub async fn upload_chunk(
canister_pid: Principal,
chunk: Vec<u8>,
) -> Result<Vec<u8>, InternalError> {
let chunk_len = chunk.len();
let hash = management_call(
ManagementCallMetricOperation::UploadChunk,
MgmtInfra::upload_chunk(canister_pid, chunk),
)
.await?;
#[expect(clippy::cast_precision_loss)]
let bytes_kb = chunk_len as f64 / 1_000.0;
log!(
Topic::CanisterLifecycle,
Ok,
"upload_chunk: {canister_pid} ({bytes_kb} KB)"
);
Ok(hash)
}
pub async fn stored_chunks(canister_pid: Principal) -> Result<Vec<Vec<u8>>, InternalError> {
management_call(
ManagementCallMetricOperation::StoredChunks,
MgmtInfra::stored_chunks(canister_pid),
)
.await
}
pub async fn clear_chunk_store(canister_pid: Principal) -> Result<(), InternalError> {
management_call(
ManagementCallMetricOperation::ClearChunkStore,
MgmtInfra::clear_chunk_store(canister_pid),
)
.await?;
log!(
Topic::CanisterLifecycle,
Ok,
"clear_chunk_store: {canister_pid}"
);
Ok(())
}
pub async fn uninstall_code(canister_pid: Principal) -> Result<(), InternalError> {
management_call(
ManagementCallMetricOperation::UninstallCode,
MgmtInfra::uninstall_code(canister_pid),
)
.await?;
SystemMetrics::increment(SystemMetricKind::UninstallCode);
log!(
Topic::CanisterLifecycle,
Ok,
"🗑️ uninstall_code: {canister_pid}"
);
Ok(())
}
pub async fn stop_canister(canister_pid: Principal) -> Result<(), InternalError> {
management_call(
ManagementCallMetricOperation::StopCanister,
MgmtInfra::stop_canister(canister_pid),
)
.await?;
log!(
Topic::CanisterLifecycle,
Ok,
"stop_canister: {canister_pid}"
);
Ok(())
}
pub async fn delete_canister(canister_pid: Principal) -> Result<(), InternalError> {
management_call(
ManagementCallMetricOperation::DeleteCanister,
MgmtInfra::delete_canister(canister_pid),
)
.await?;
SystemMetrics::increment(SystemMetricKind::DeleteCanister);
Ok(())
}
pub async fn raw_rand() -> Result<[u8; 32], InternalError> {
let seed = management_call(
ManagementCallMetricOperation::RawRand,
MgmtInfra::raw_rand(),
)
.await?;
SystemMetrics::increment(SystemMetricKind::RawRand);
Ok(seed)
}
}