Skip to content

Commit

Permalink
Merge branch 'master' into spofford/backtrace
Browse files Browse the repository at this point in the history
  • Loading branch information
adamspofford-dfinity committed Oct 10, 2024
2 parents 256ffb6 + 7618065 commit 2b83371
Show file tree
Hide file tree
Showing 32 changed files with 838 additions and 197 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,30 @@

# UNRELEASED

### feat: Support canister log allowed viewer list

Added support for the canister log allowed viewer list, enabling specified users to access a canister's logs without needing to be set as the canister's controller.
Valid settings are:
- `--add-log-viewer`, `--remove-log-viewer` and `--set-log-viewer` flags with `dfx canister update-settings`
- `--log-viewer` flag with `dfx canister create`
- `canisters[].initialization_values.log_visibility.allowed_viewers` in `dfx.json`

# 0.24.1

### feat: More PocketIC flags supported

`dfx start --pocketic` is now compatible with `--artificial-delay` and the `subnet_type` configuration option, and enables `--enable-canister-http` by default.

## Dependencies

### Frontend canister

#### feat: Better error messages when proposing a batch

Add the batch id in the error messages of `propose_commit_batch`.

Module hash: 2c9e30df9be951a6884c702a97bbb8c0b438f33d4208fa612b1de6fb1752db76

### Motoko

Updated Motoko to [0.13.0](https://github.com/dfinity/motoko/releases/tag/0.13.0)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions docs/cli-reference/dfx-canister.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ You can use the following options with the `dfx canister create` command.
| `--memory-allocation <memory>` | Specifies how much memory the canister is allowed to use in total. This should be a value in the range [0..12 GiB]. A setting of 0 means the canister will have access to memory on a “best-effort” basis: It will only be charged for the memory it uses, but at any point in time may stop running if it tries to allocate more memory when there isn’t space available on the subnet. |
| `--reserved-cycles-limit <limit>` | Specifies the upper limit for the canister's reserved cycles. |
| `--wasm-memory-limit <limit>` | Specifies a soft upper limit for the canister's heap memory. |
| `--log-visibility <visibility>` | Specifies who is allowed to read the canister's logs. Can be either "controllers" or "public". |
| `--log-viewer <principal>` | Specifies the principal as an allowed viewers. Can be specified more than once. Cannot be used with `--log-visibility`. |
| `--log-visibility <visibility>` | Specifies who can read the canister's logs: "controllers" or "public". For custom allowed viewers, use `--log-viewer`. |
| `--no-wallet` | Performs the call with the user Identity as the Sender of messages. Bypasses the Wallet canister. Enabled by default. |
| `--with-cycles <number-of-cycles>` | Specifies the initial cycle balance to deposit into the newly created canister. The specified amount needs to take the canister create fee into account. This amount is deducted from the wallet's cycle balance. |
| `--specified-id <PRINCIPAL>` | Attempts to create the canister with this Canister ID |
Expand Down Expand Up @@ -1137,14 +1138,17 @@ You can specify the following options for the `dfx canister update-settings` com
| Option | Description |
|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--add-controller <principal>` | Add a principal to the list of controllers of the canister. |
| `--add-log-viewer <principal>` | Add a principal to the list of log viewers of the canister. Can be specified more than once to add multiple log viewers. If current log visibility is `public` or `controllers`, it will be changed to the custom allowed viewer list. |
| `-c`, `--compute-allocation <allocation>` | Specifies the canister's compute allocation. This should be a percent in the range [0..100]. |
| `--confirm-very-long-freezing-threshold` | Freezing thresholds above ~1.5 years require this option as confirmation. |
| `--set-controller <principal>` | Specifies the identity name or the principal of the new controller. Can be specified more than once, indicating the canister will have multiple controllers. If any controllers are set with this parameter, any other controllers will be removed. |
| `--set-log-viewer <principal>` | Specifies the the principal of the log viewer of the canister. Can be specified more than once, indicating the canister will have multiple log viewers. If any log viewers are set with this parameter, any other log viewers will be removed. If current log visibility is `public` or `controllers`, it will be changed to the custom allowed viewer list. |
| `--memory-allocation <allocation>` | Specifies how much memory the canister is allowed to use in total. This should be a value in the range [0..12 GiB]. A setting of 0 means the canister will have access to memory on a “best-effort” basis: It will only be charged for the memory it uses, but at any point in time may stop running if it tries to allocate more memory when there isn’t space available on the subnet. |
| `--reserved-cycles-limit <limit>` | Specifies the upper limit of the canister's reserved cycles. |
| `--wasm-memory-limit <limit>` | Specifies a soft upper limit for the canister's heap memory. |
| `--log-visibility <visibility>` | Specifies who is allowed to read the canister's logs. Can be either "controllers" or "public". |
| `--log-visibility <visibility>` | Specifies who is allowed to read the canister's logs. Can be either "controllers" or "public". For custom allowed viewers, use `--set-log-viewer` or `--add-log-viewer`. |
| `--remove-controller <principal>` | Removes a principal from the list of controllers of the canister. |
| `--remove-log-viewer <principal>` | Removes a principal from the list of log viewers of the canister. Can be specified more than once to remove multiple log viewers. |
| `--freezing-threshold <seconds>` | Set the [freezing threshold](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-create_canister) in seconds for a canister. This should be a value in the range [0..2^64^-1]. Very long thresholds require the `--confirm-very-long-freezing-threshold` option. |
| `-y`, `--yes` | Skips yes/no checks by answering 'yes'. Such checks can result in loss of control, so this is not recommended outside of CI. |

Expand Down
8 changes: 8 additions & 0 deletions docs/cli-reference/dfx-envars.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,11 @@ DFX_VERSION=0.13.1 dfx deploy --network ic
## DFX_DISABLE_QUERY_VERIFICATION

Set this to a non-empty value to disable verification of replica-signed queries.

## DFX_REPLICA_PATH

Use the `DFX_REPLICA_PATH` environment variable to specify a file path to a local version of the replica. If this option is used, `canister_sandbox` and `sandbox_launcher` must be in the same directory with the desired replica version.

## DFX_IC_STARTER_PATH

Use the `DFX_IC_STARTER_PATH` environment variable to specify a file path to a local version of `ic-starter`.
29 changes: 24 additions & 5 deletions docs/dfx-json-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,29 @@
}
},
"CanisterLogVisibility": {
"type": "string",
"enum": [
"controllers",
"public"
"oneOf": [
{
"type": "string",
"enum": [
"controllers",
"public"
]
},
{
"type": "object",
"required": [
"allowed_viewers"
],
"properties": {
"allowed_viewers": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false
}
]
},
"CanisterMetadataSection": {
Expand Down Expand Up @@ -947,7 +966,7 @@
},
"log_visibility": {
"title": "Log Visibility",
"description": "Specifies who is allowed to read the canister's logs.\n\nCan be \"public\" or \"controllers\".",
"description": "Specifies who is allowed to read the canister's logs.\n\nCan be \"public\", \"controllers\" or \"allowed_viewers\" with a list of principals.",
"anyOf": [
{
"$ref": "#/definitions/CanisterLogVisibility"
Expand Down
26 changes: 26 additions & 0 deletions e2e/tests-dfx/canister_logs.bash
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,29 @@ dfx_canister_logs_tail_n_1() {
assert_not_contains "Alice"
assert_contains "Bob"
}

@test "canister logs only visible to allowed viewers." {
install_asset logs
dfx_start
dfx canister create --all
dfx build
dfx canister install e2e_project
dfx canister call e2e_project hello Alice
sleep 2

assert_command dfx canister logs e2e_project
assert_contains "Hello, Alice!"

# Create identity for viewers.
assert_command dfx identity new --storage-mode plaintext alice
ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice)

assert_command_fail dfx canister logs e2e_project --identity alice

assert_command dfx canister update-settings --add-log-viewer="${ALICE_PRINCIPAL}" e2e_project
assert_command dfx canister status e2e_project
assert_contains "${ALICE_PRINCIPAL}"

assert_command dfx canister logs e2e_project --identity alice
assert_contains "Hello, Alice!"
}
82 changes: 82 additions & 0 deletions e2e/tests-dfx/create.bash
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,85 @@ teardown() {
assert_contains 'Freezing threshold: 2_592_000'
assert_contains 'Log visibility: controllers'
}

@test "create with multiple log allowed viewer list in dfx.json" {
# Create two identities
assert_command dfx identity new --storage-mode plaintext alice
assert_command dfx identity new --storage-mode plaintext bob
ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice)
BOB_PRINCIPAL=$(dfx identity get-principal --identity bob)

jq '.canisters.e2e_project_backend.initialization_values={
"compute_allocation": 5,
"freezing_threshold": "7days",
"memory_allocation": "2 GiB",
"reserved_cycles_limit": 1000000000000,
"wasm_memory_limit": "1 GiB",
"log_visibility": {
"allowed_viewers" :
['\""$ALICE_PRINCIPAL"\"', '\""$BOB_PRINCIPAL"\"']
}
}' dfx.json | sponge dfx.json
dfx_start
assert_command dfx deploy e2e_project_backend --no-wallet
assert_command dfx canister status e2e_project_backend
assert_contains 'Memory allocation: 2_147_483_648'
assert_contains 'Compute allocation: 5'
assert_contains 'Reserved cycles limit: 1_000_000_000_000'
assert_contains 'Wasm memory limit: 1_073_741_824'
assert_contains 'Freezing threshold: 604_800'
assert_contains "${ALICE_PRINCIPAL}"
assert_contains "${BOB_PRINCIPAL}"
}

@test "create with multiple log allowed viewer list" {
# Create two identities
assert_command dfx identity new --storage-mode plaintext alice
assert_command dfx identity new --storage-mode plaintext bob
ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice)
BOB_PRINCIPAL=$(dfx identity get-principal --identity bob)

dfx_start
assert_command dfx canister create --all --log-viewer "${ALICE_PRINCIPAL}" --log-viewer "${BOB_PRINCIPAL}" --no-wallet
assert_command dfx deploy e2e_project_backend --no-wallet
assert_command dfx canister status e2e_project_backend
assert_contains "${ALICE_PRINCIPAL}"
assert_contains "${BOB_PRINCIPAL}"
}

# The following function decodes a canister id in the textual form into its binary form
# and is taken from the [IC Interface Specification](https://internetcomputer.org/docs/current/references/ic-interface-spec#principal).
function textual_decode() {
echo -n "$1" | tr -d - | tr "[:lower:]" "[:upper:]" |
fold -w 8 | xargs -n1 printf '%-8s' | tr ' ' = |
base32 -d | xxd -p | tr -d '\n' | cut -b9- | tr "[:lower:]" "[:upper:]"
}

@test "create targets application subnet in PocketIC" {
[[ ! "$USE_POCKETIC" ]] && skip "skipped for replica: no support for multiple subnets"
dfx_start
# create the backend canister without a wallet canister so that the backend canister is the only canister ever created
assert_command dfx canister create e2e_project_backend --no-wallet
# actual canister id
CANISTER_ID="$(dfx canister id e2e_project_backend)"
# base64 encode the actual canister id
CANISTER_ID_BASE64="$(textual_decode "${CANISTER_ID}" | xxd -r -p | base64)"
# fetch topology from PocketIC server
TOPOLOGY="$(curl "http://127.0.0.1:$(dfx info replica-port)/instances/0/read/topology")"
# find application subnet id in the topology
for subnet_id in $(echo "${TOPOLOGY}" | jq keys[])
do
SUBNET_KIND="$(echo "$TOPOLOGY" | jq -r ".${subnet_id}.\"subnet_kind\"")"
if [ "${SUBNET_KIND}" == "Application" ]
then
# find the expected canister id as the beginning of the first canister range of the app subnet
EXPECTED_CANISTER_ID_BASE64="$(echo "$TOPOLOGY" | jq -r ".${subnet_id}.\"canister_ranges\"[0].\"start\".\"canister_id\"")"
fi
done
# check if the actual canister id matches the expected canister id
if [ "${CANISTER_ID_BASE64}" != "${EXPECTED_CANISTER_ID_BASE64}" ]
then
echo "Canister id ${CANISTER_ID_BASE64} does not match expected canister id ${EXPECTED_CANISTER_ID_BASE64}"
exit 1
fi
}
Loading

0 comments on commit 2b83371

Please sign in to comment.