Skip to content

Commit

Permalink
fix: deleting project canister by id will clean up canister id store. (
Browse files Browse the repository at this point in the history
…#3442)

`dfx canister delete <by id>` would leave entries (canister name -> canister id) in the canister id store.  A subsequent `dfx deploy` would then fail because it would try to install to the deleted canister rather than creating a new one.

Fixes https://dfinity.atlassian.net/browse/SDK-1143
  • Loading branch information
ericswanson-dfinity authored Nov 15, 2023
1 parent 24d46de commit e91c27c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

# UNRELEASED

=== fix: `dfx canister delete <canister id>` removes the related entry from the canister id store

Previously, deleting a canister in the project by id rather than by name
would leave the canister id in the canister id store. This would cause
`dfx deploy` to fail.

=== fix: dfx extension install can no longer create a corrupt cache directory

Running `dfx cache delete && dfx extension install nns` would previously
Expand Down
13 changes: 13 additions & 0 deletions e2e/tests-dfx/delete.bash
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ teardown() {
standard_teardown
}

@test "delete by canister id cleans up canister id store" {
dfx_start
dfx deploy e2e_project_backend
id=$(dfx canister id e2e_project_backend)
dfx canister stop e2e_project_backend
assert_command dfx canister delete "$id"
assert_command_fail dfx canister info e2e_project_backend
assert_contains "Cannot find canister id. Please issue 'dfx canister create e2e_project_backend'."
assert_command_fail dfx canister status "$id"
assert_contains "Canister $id not found"
assert_command dfx deploy
}

@test "delete can be used to delete a canister" {
dfx_start
dfx deploy e2e_project_backend
Expand Down
6 changes: 5 additions & 1 deletion src/dfx-core/src/config/model/canister_id_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,14 @@ impl CanisterIdStore {
self.remote_ids
.as_ref()
.and_then(|remote_ids| self.get_name_in(canister_id, remote_ids))
.or_else(|| self.get_name_in(canister_id, &self.ids))
.or_else(|| self.get_name_in_project(canister_id))
.or_else(|| self.get_name_in_pull_ids(canister_id))
}

pub fn get_name_in_project(&self, canister_id: &str) -> Option<&String> {
self.get_name_in(canister_id, &self.ids)
}

pub fn get_name_in<'a>(
&'a self,
canister_id: &str,
Expand Down
14 changes: 11 additions & 3 deletions src/dfx/src/commands/canister/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,15 @@ async fn delete_canister(
) -> DfxResult {
let log = env.get_logger();
let mut canister_id_store = env.get_canister_id_store()?;
let (canister_id, canister_name_to_delete) = match Principal::from_text(canister) {
Ok(canister_id) => (
canister_id,
canister_id_store.get_name_in_project(canister).cloned(),
),
Err(_) => (canister_id_store.get(canister)?, Some(canister.to_string())),
};

if !env.get_network_descriptor().is_playground() {
let canister_id =
Principal::from_text(canister).or_else(|_| canister_id_store.get(canister))?;
let mut call_sender = call_sender;
let to_dank = withdraw_cycles_to_dank || withdraw_cycles_to_dank_principal.is_some();

Expand Down Expand Up @@ -268,7 +273,10 @@ async fn delete_canister(

canister::delete_canister(env, canister_id, call_sender).await?;
}
canister_id_store.remove(canister)?;

if let Some(canister_name) = canister_name_to_delete {
canister_id_store.remove(&canister_name)?;
}

Ok(())
}
Expand Down

0 comments on commit e91c27c

Please sign in to comment.