Upgrade multiple canister at the same time

Greetings everyone!

I would like to ask if there is a way to do a multiple canister upgrade using another canister assuming each of my users owns a canister? I know there is an install_code with mode = #upgrade but I’m not sure what to add with arg and wasm_module. Thank you!

To get the wasm in Javascript.

const get_wasm = (name, wasmPath) => {
	const buffer = readFileSync(`${process.cwd()}/${wasmPath}/${name}/${name}.wasm`);
	return [...new Uint8Array(buffer)];
};

Motoko

public shared ({ caller }) func install_code(
		canister_id : Principal,
		arg : Blob,
		wasm_module : Blob
	) : async Text {
		let principal = Principal.toText(caller);

		if (Text.equal(principal, "x")) {
			await ic.install_code({
				arg = arg;
				wasm_module = wasm_module;
				mode = #upgrade;
				canister_id = canister_id;
			});

			return "success";
		};

		return "not_authorized";
	};

wasm_module is buffer of the canister wasm
arg is args to class actor actor class Project(is_prod : Bool)

you send IDL.encode([IDL.Bool], [true])

Hi cyberowl! May I ask where do I run the JS code that you placed? Also is there an easier way in Motoko to do this using Motoko only? Thanks!

Here’s how you could do it:

  1. The manager canister would need to be the controller of the user canisters. This would allow the manager canister to upgrade the user canisters.
  2. You would use the install_code method, with the mode set to #upgrade.

In this scenario, the arg argument is the initialization data for the canister you are upgrading. The exact format of this argument will depend on the specific canister’s implementation, but it is generally used to set the initial state of the canister.

The wasm_module argument is the actual compiled WebAssembly binary that the canister will execute. You’d need to upload this binary to the manager canister (or retrieve it in some other way), so that the manager canister can provide it as an argument to the install_code method.

This is if you want to upload from you local machine. I think you want to update from another canister. You would need to upload the wasm to another canister and allow that canister to be a controller of the canister u are trying to upgrade.

Final question, how could I get the wasm_module? I noticed that you gave me a code snippet, but I do not know where to run this. Thanks cyberowl!

Yeah this was code to convert it to unit8 array within javascript script. It basically get the buffer from the wasm from the path to the wasm file in your dfx/local dir:

const get_wasm = (name, wasmPath) => {
	const buffer = readFileSync(`${process.cwd()}/${wasmPath}/${name}/${name}.wasm`);
	return [...new Uint8Array(buffer)];
};

You will need something similar to this to read the wasm. There might be a way to do it via a dfx command but I don’t know it.