Skip to content

feat: add --proxy flag to canister subcommands and icp deploy#484

Open
lwshang wants to merge 13 commits intomainfrom
lwshang/proxy_more
Open

feat: add --proxy flag to canister subcommands and icp deploy#484
lwshang wants to merge 13 commits intomainfrom
lwshang/proxy_more

Conversation

@lwshang
Copy link
Copy Markdown
Contributor

@lwshang lwshang commented Apr 2, 2026

Summary

Add a --proxy <canister-id> flag to all icp canister subcommands and icp deploy, allowing users to route management canister calls through a proxy canister instead of calling the management canister directly.

  • Introduce a proxy_management module that wraps every management canister method (create_canister, install_code, start_canister, stop_canister, delete_canister, canister_status, update_settings, fetch_canister_logs, and all snapshot operations) with an update_or_proxy dispatcher that either calls the management canister directly or forwards the call through the specified proxy.
  • Refactor all existing ic_utils::ManagementCanister call sites to use the new proxy_management wrappers, fixing issues with effective canister ID routing and Candid encoding along the way.
  • Wire the --proxy CLI flag through every affected command: start, stop, delete, install, status, logs, migrate-id, settings update/sync, snapshot create/restore/list/delete, and deploy.
  • Add integration tests covering the proxy path for each updated command.

Known limitations

  • icp deploy --proxy with frontend canisters: Asset upload/sync steps may not work correctly when using --proxy, because the asset canister sync logic does not yet route calls through the proxy.
  • canister logs --proxy: fetch_canister_logs is not yet available as a replicated call, so --proxy for this command won't work until the "logs extension" feature is merged into the IC spec. The flag is hidden from --help and the integration test is #[ignore]d.

Reviewer guide

This PR is large but most of the diff is mechanical. Focus review on:

  1. crates/icp-cli/src/operations/proxy_management.rs — the new module containing all proxy dispatch logic. This is the core of the change.
  2. crates/icp-cli/src/operations/proxy.rs — the low-level update_or_proxy helper.
  3. crates/icp-cli/src/commands/deploy.rs — how --proxy is threaded through the deploy pipeline.

Lower priority (mechanical wiring / test boilerplate):

  • Other files under commands/canister/ — each just adds a --proxy CLI arg and passes it through.
  • Files under operations/ like install.rs, settings.rs, snapshot_transfer.rs — signature changes to accept Option<Principal> for proxy.
  • All tests/ files — integration test scaffolding for the new flag.

Test plan

  • Unit/integration tests for all canister subcommands with --proxy
  • Integration test for icp deploy --proxy

lwshang and others added 11 commits April 2, 2026 13:39
Extract the proxied management canister create_canister call into a
dedicated proxy_management module, keeping raw IC types as the interface.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace every `ManagementCanister::create` / `ic_utils` builder call
with the corresponding `proxy_management::*` wrapper that dispatches
via `update_or_proxy`. Each call site now accepts an optional proxy
principal, currently passed as `None`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Management canister calls routed through `update_or_proxy` were missing
the effective_canister_id, causing the IC HTTP endpoint to fail with
"canister_not_found" when routing the request. The old `ic_utils::ManagementCanister`
set this automatically; the new raw `agent.update()` path needs it explicitly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When no init args are provided, the old ic_utils builder serialized
an empty Candid message (DIDL\x00\x00) via `Encode!()`. The refactored
code used `unwrap_or_default()` producing raw empty bytes, which the
management canister cannot parse as valid Candid.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fetch_canister_logs is a query method on the management canister, not an
update. When no proxy is provided, make a direct query call instead of
routing through update_or_proxy. Introduce FetchCanisterLogsError to
model the distinct direct-query and proxied-update error paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a --proxy CLI flag to all `icp canister` subcommands that involve
management canister calls via proxy_management, allowing users to route
these calls through a proxy canister.

Commands updated: start, stop, delete, install, status, logs,
migrate-id, settings update, settings sync, snapshot create/restore/
list/delete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Route management canister calls through a proxy canister during deploy.
Includes a TODO for the known limitation where sync steps (asset uploads)
fail for newly created frontend canisters when using --proxy.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cover deploy, install, delete, status, stop, start, settings update,
settings sync, and the full snapshot workflow through a proxy canister.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fetch_canister_logs is not yet available in replicated mode, so hide the
--proxy flag from --help and mark the test as #[ignore] until the IC
spec change lands (dfinity/portal#6106).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When --proxy is set, the proxy canister is the effective controller
making management calls. The self-removal warning now checks the proxy
principal instead of the caller's identity, preventing false prompts
(and "not a terminal" errors in tests) when adding controllers to
proxy-deployed canisters. Warning messages are also updated to be
accurate for each case.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lwshang lwshang requested a review from Copilot April 2, 2026 23:20
@lwshang lwshang changed the title feat: add --proxy flag for routing management canister calls through a proxy feat: add --proxy flag to canister subcommands and icp deploy Apr 2, 2026
@lwshang lwshang marked this pull request as ready for review April 2, 2026 23:23
@lwshang lwshang requested a review from a team as a code owner April 2, 2026 23:23
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a --proxy <canister-id> flag to route management canister operations through a proxy canister, and refactors management-canister call sites to use a new proxy-aware dispatch layer.

Changes:

  • Introduces operations::proxy_management wrappers for management canister methods and extends update_or_proxy to support effective_canister_id routing.
  • Threads --proxy through icp deploy and multiple icp canister ... subcommands (start/stop/delete/status/settings/snapshot/logs/install/migrate-id).
  • Adds integration tests exercising --proxy flows (including deploy-through-proxy and various canister subcommands).

Reviewed changes

Copilot reviewed 35 out of 35 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
docs/reference/cli.md Documents the new --proxy flag on impacted CLI commands.
CHANGELOG.md Notes the new --proxy support across canister subcommands and deploy.
crates/icp-cli/src/operations/mod.rs Exposes the new proxy_management module.
crates/icp-cli/src/operations/proxy.rs Extends proxy dispatch to support effective_canister_id for correct management-canister routing.
crates/icp-cli/src/operations/proxy_management.rs Adds proxy-aware wrappers for management canister methods (core routing layer).
crates/icp-cli/src/operations/snapshot_transfer.rs Refactors snapshot transfer reads/writes to use proxy-aware management wrappers.
crates/icp-cli/src/operations/settings.rs Refactors settings sync to call management methods via proxy wrappers.
crates/icp-cli/src/operations/install.rs Refactors install flow (including chunked install) to use proxy-aware management wrappers.
crates/icp-cli/src/operations/create.rs Routes create-canister via proxy when requested (subnet placement via proxy subnet).
crates/icp-cli/src/operations/binding_env_vars.rs Refactors env-var settings updates to use proxy-aware management wrappers.
crates/icp-cli/src/commands/deploy.rs Adds --proxy to deploy and threads it through create/install/settings/env-vars steps.
crates/icp-cli/src/commands/canister/start.rs Adds --proxy and routes start via proxy_management.
crates/icp-cli/src/commands/canister/stop.rs Adds --proxy and routes stop via proxy_management.
crates/icp-cli/src/commands/canister/delete.rs Adds --proxy and routes delete via proxy_management.
crates/icp-cli/src/commands/canister/status.rs Adds --proxy and routes status via proxy_management.
crates/icp-cli/src/commands/canister/install.rs Adds --proxy and threads it into install-mode resolution + install operations.
crates/icp-cli/src/commands/canister/logs.rs Adds hidden --proxy and routes through proxy-aware log fetch path.
crates/icp-cli/src/commands/canister/migrate_id.rs Adds --proxy and routes mgmt calls during migration via proxy_management.
crates/icp-cli/src/commands/canister/settings/update.rs Adds --proxy and routes settings updates via proxy_management.
crates/icp-cli/src/commands/canister/settings/sync.rs Adds --proxy and threads it into settings sync operation.
crates/icp-cli/src/commands/canister/snapshot/create.rs Adds --proxy and routes snapshot create via proxy_management.
crates/icp-cli/src/commands/canister/snapshot/list.rs Adds --proxy and routes snapshot listing via proxy_management.
crates/icp-cli/src/commands/canister/snapshot/restore.rs Adds --proxy and routes snapshot restore via proxy_management.
crates/icp-cli/src/commands/canister/snapshot/delete.rs Adds --proxy and routes snapshot deletion via proxy_management.
crates/icp-cli/src/commands/canister/call.rs Updates proxy call path to pass the new effective_canister_id argument.
crates/icp-cli/tests/common/context.rs Adds helper to discover the proxy canister principal from network status JSON.
crates/icp-cli/tests/deploy_tests.rs Adds deploy-through-proxy integration test.
crates/icp-cli/tests/canister_start_tests.rs Adds canister start-through-proxy integration test.
crates/icp-cli/tests/canister_stop_tests.rs Adds canister stop-through-proxy integration test.
crates/icp-cli/tests/canister_delete_tests.rs Adds canister delete-through-proxy integration test.
crates/icp-cli/tests/canister_status_tests.rs Adds canister status-through-proxy integration test.
crates/icp-cli/tests/canister_install_tests.rs Adds canister install-through-proxy integration test.
crates/icp-cli/tests/canister_settings_tests.rs Adds settings update/sync-through-proxy integration tests.
crates/icp-cli/tests/canister_snapshot_tests.rs Adds snapshot workflow-through-proxy integration test.
crates/icp-cli/tests/canister_logs_tests.rs Adds ignored logs-through-proxy integration test (pending replicated logs support).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

lwshang and others added 2 commits April 2, 2026 19:38
Thread proxy through all snapshot transfer operations so that
snapshot download/upload can be routed through a proxy canister.
Also extend the proxy workflow integration test to cover these commands.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants