dfinity / sdk

IC SDK: a Software Development Kit for creating and managing canister smart contracts on the ICP blockchain.
https://internetcomputer.org/developers
Apache License 2.0
176 stars 85 forks source link

dfx redeploy fails if the source canister module is read-only #3308

Closed roman-kashitsyn closed 1 year ago

roman-kashitsyn commented 1 year ago

Description

I have a canister that I build with Bazel:

{
  "version": 1,
  "dfx": "0.14.3",
  "canisters": {
    "minter": {
      "type": "custom",
      "build": [
        "bazel build //rs/ethereum/cketh/minter:cketh_minter"
      ],
      "wasm": "../../../../bazel-bin/rs/ethereum/cketh/minter/cketh_minter.wasm",
      "candid": "../minter/cketh_minter.did",
      "shrink": false
    },
    "ledger": {
      "type": "custom",
      "build": [
        "bazel build //rs/rosetta-api/icrc1/ledger:ledger_canister_u256.wasm"
      ],
      "wasm": "../../../../bazel-bin/rs/rosetta-api/icrc1/ledger/ledger_canister_u256.wasm",
      "candid": "../../../rosetta-api/icrc1/ledger/ledger.did",
      "shrink": false
    }
  },
  "defaults": {
    "build": {
      "packtool": "",
      "args": ""
    }
  },
  "networks": {
    "local": {
      "bind": "127.0.0.1:8000",
      "type": "ephemeral"
    }
  }
}

(see https://sourcegraph.com/github.com/dfinity/ic@736c901206ff5b6b06b251f99861c8a78ad58d4e/-/blob/rs/ethereum/cketh/testnet/dfx.json)

The first time I deploy my canisters, everything works fine. But if I modify the canister source and run dfx deploy again, the deploy fails because the canister module in .dfx/local is read-only.

The most likely cause is that Bazel marks all build artifacts as read-only:

 ls -alh /Users/lifted/Projects/dfinity/rs/ethereum/cketh/testnet/../../../../bazel-bin/rs/ethereum/cketh/minter/cketh_minter.wasm
-r-xr-xr-x  1 lifted  wheel   895K Aug 17 11:38 /Users/lifted/Projects/dfinity/rs/ethereum/cketh/testnet/../../../../bazel-bin/rs/ethereum/cketh/minter/cketh_minter.wasm

and DFX copies custom Wasm files without changing the destination attributes:

pub fn copy(from: &Path, to: &Path) -> Result<u64, FsError> {
    std::fs::copy(from, to).map_err(|err| {
        FsError::new(CopyFileFailed(
            Box::new(from.to_path_buf()),
            Box::new(to.to_path_buf()),
            err,
        ))
    })
}

https://sourcegraph.com/github.com/dfinity/sdk@412ed4702689820d61b1c11d5b3e444d1416a51d/-/blob/src/dfx-core/src/fs/mod.rs?L18:8-18:12

I expected to see this happen: dfx deploy works every time even if the source Wasm module is read-only.

Instead, this happened: dfx deploy fails with the following error:

Caused by: Failed while trying to deploy canisters.
  Failed to build all canisters.
    Failed while trying to build all canisters.
      The post-build step failed for canister 'bd3sg-teaaa-aaaaa-qaaba-cai' (minter) with an embedded error: Failed to post-process wasm of canister 'minter'.: Failed to copy /Users/lifted/Projects/dfinity/rs/ethereum/cketh/testnet/../../../../bazel-bin/rs/ethereum/cketh/minter/cketh_minter.wasm to /Users/lifted/Projects/dfinity/rs/ethereum/cketh/testnet/.dfx/local/canisters/minter/minter.wasm: Permission denied (os error 13)

Workarounds

Removing the .dfx destination file and re-running dfx deploy works.

rm /Users/lifted/Projects/dfinity/rs/ethereum/cketh/testnet/.dfx/local/canisters/minter/minter.wasm

Meta

dfx --version:

dfx 0.14.3
ninegua commented 1 year ago

Have you tried https://github.com/dfinity/sdk/pull/3303? Might fix this issue. But it was only merged a couple days ago, so you need to build a dfx yourself.

roman-kashitsyn commented 1 year ago

Have you tried #3303? Might fix this issue. But it was only merged a couple days ago, so you need to build a dfx yourself.

Right, I used the latest official version. I'll wait for the next release then. Thanks!