Upgrading canisters deployed via code

My project involves a canister of type A that deploys other canisters of type B, C, D. Canister A manages and keeps track of multiple canisters and deploys them at the user’s request (through code).

pub async fn deploy(bytecode: Vec<u8>) -> Result<Principal, String> {
    let management_canister = Principal::management_canister();

    let create_result: Result<(DeploymentResult,), _> = api::call::call_with_payment128(
            management_canister,
            "create_canister",
            (),
            200000000000u128,
        )
        .await;

    let create_result = match create_result {
            Ok((result,)) => result,
            Err((code, msg)) => {
                ic_cdk::api::print(format!(
                    "Error creating canister: Code: {}, Message: {}",
                    code as u8, msg
                ));
                return Err(format!("Failed to create canister: {}: {}", code as u8, msg));
            }
        };

    let install_config = CanisterInstall {
        mode: InstallMode::Install,
        canister_id: create_result.canister_id,
        wasm_module: bytecode.clone(),
        arg: b" ".to_vec(),
    };

    match api::call::call(
            Principal::management_canister(),
            "install_code",
            (install_config,),
        )
        .await
        {
            Ok(x) => x,
            Err((code, msg)) => {
                return Err(format!(
                    "An error happened during the call: {}: {}",
                    code as u8, msg
                ))
            }
        };
    
    let id = create_result.canister_id.clone();
    Ok(id)
} 

I haven’t found a way to upgrade the canisters deployed via this method. I can only upgrade the ones that were deployed via dfx deploy, which only includes canister A.

Is there any way to upgrade canisters that have been deployed via code?

You can do a ‘naked’ dfx canister install <canister id> --wasm <new wasm.wasm> if your principal dfx identity get-principal is a controller of the canister. Or you could instruct A to call install_code with mode: upgrade using the new wasm

2 Likes