Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/icp-cli/src/commands/canister/binding_env_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use crate::{
commands::Context,
options::{EnvironmentOpt, IdentityOpt},
progress::{ProgressManager, ProgressManagerSettings},
store_artifact::LookupError as LookupArtifactError,
store_id::{Key, LookupError as LookupIdError},
store_artifact::LookupArtifactError,
store_id::{Key, LookupIdError},
};

#[derive(Clone, Debug, Args)]
Expand Down
4 changes: 2 additions & 2 deletions crates/icp-cli/src/commands/canister/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{
commands::Context,
options::{EnvironmentOpt, IdentityOpt},
progress::{ProgressManager, ProgressManagerSettings},
store_id::{Key, LookupError, RegisterError},
store_id::{Key, LookupIdError, RegisterError},
};

pub(crate) const DEFAULT_CANISTER_CYCLES: u128 = 2 * TRILLION;
Expand Down Expand Up @@ -268,7 +268,7 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
}

// Doesn't exist (include)
Err(LookupError::IdNotFound { .. }) => {}
Err(LookupIdError::IdNotFound { .. }) => {}

// Lookup failed
Err(err) => panic!("{err}"),
Expand Down
2 changes: 1 addition & 1 deletion crates/icp-cli/src/commands/canister/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use itertools::Itertools;
use crate::{
commands::Context,
options::{EnvironmentOpt, IdentityOpt},
store_id::{Key, LookupError as LookupIdError},
store_id::{Key, LookupIdError},
};

#[derive(Debug, Args)]
Expand Down
107 changes: 29 additions & 78 deletions crates/icp-cli/src/commands/canister/install.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
use std::collections::HashMap;

use clap::Args;
use futures::{StreamExt, stream::FuturesOrdered};
use futures::{StreamExt, future::try_join_all, stream::FuturesOrdered};
use ic_agent::AgentError;
use ic_utils::interfaces::management_canister::builders::CanisterInstallMode;
use icp::{agent, identity, network};
use tracing::debug;

use crate::{
commands::Context,
commands::{Context, GetAgentForEnvError, GetCanisterIdForEnvError, GetEnvironmentError},
options::{EnvironmentOpt, IdentityOpt},
progress::{ProgressManager, ProgressManagerSettings},
store_artifact::LookupError as LookupArtifactError,
store_id::{Key, LookupError as LookupIdError},
store_artifact::LookupArtifactError,
store_id::LookupIdError,
};

#[derive(Clone, Debug, Args)]
Expand All @@ -39,27 +37,12 @@ pub(crate) enum CommandError {
#[error(transparent)]
Identity(#[from] identity::LoadError),

#[error("project does not contain an environment named '{name}'")]
EnvironmentNotFound { name: String },

#[error(transparent)]
Access(#[from] network::AccessError),

#[error(transparent)]
Agent(#[from] agent::CreateError),

#[error("project does not contain a canister named '{name}'")]
CanisterNotFound { name: String },

#[error("environment '{environment}' does not include canister '{canister}'")]
EnvironmentCanister {
environment: String,
canister: String,
},

#[error("no canisters available to install")]
NoCanisters,

#[error(transparent)]
LookupCanisterId(#[from] LookupIdError),

Expand All @@ -68,66 +51,41 @@ pub(crate) enum CommandError {

#[error(transparent)]
InstallAgent(#[from] AgentError),
}

pub(crate) async fn exec(ctx: &Context, args: &InstallArgs) -> Result<(), CommandError> {
// Load the project
let p = ctx.project.load().await?;

// Load identity
let id = ctx.identity.load(args.identity.clone().into()).await?;
#[error(transparent)]
GetAgentForEnv(#[from] GetAgentForEnvError),

// Load target environment
let env =
p.environments
.get(args.environment.name())
.ok_or(CommandError::EnvironmentNotFound {
name: args.environment.name().to_owned(),
})?;
#[error(transparent)]
GetEnvironment(#[from] GetEnvironmentError),

// Access network
let access = ctx.network.access(&env.network).await?;
#[error(transparent)]
GetCanisterIdForEnv(#[from] GetCanisterIdForEnvError),
}

// Agent
let agent = ctx.agent.create(id, &access.url).await?;
pub(crate) async fn exec(ctx: &Context, args: &InstallArgs) -> Result<(), CommandError> {
let agent = ctx
.get_agent_for_env(&args.identity.clone().into(), args.environment.name())
.await?;

if let Some(k) = access.root_key {
agent.set_root_key(k);
}
// Load target environment
let env = ctx.get_environment(args.environment.name()).await?;

let cnames = match args.names.is_empty() {
let target_canisters = match args.names.is_empty() {
// No canisters specified
true => env.canisters.keys().cloned().collect(),
true => env.get_canister_names(),

// Individual canisters specified
false => args.names.clone(),
};

for name in &cnames {
if !p.canisters.contains_key(name) {
return Err(CommandError::CanisterNotFound {
name: name.to_owned(),
});
let canisters = try_join_all(target_canisters.into_iter().map(|name| {
let env_name = args.environment.name();
async move {
let cid = ctx.get_canister_id_for_env(&name, env_name).await?;
Ok::<_, CommandError>((name, cid))
}

if !env.canisters.contains_key(name) {
return Err(CommandError::EnvironmentCanister {
environment: env.name.to_owned(),
canister: name.to_owned(),
});
}
}

let cs = env
.canisters
.iter()
.filter(|(k, _)| cnames.contains(k))
.collect::<HashMap<_, _>>();

// Ensure at least one canister has been selected
if cs.is_empty() {
return Err(CommandError::NoCanisters);
}
}))
.await?;

// Management Interface
let mgmt = ic_utils::interfaces::ManagementCanister::create(&agent);
Expand All @@ -137,9 +95,9 @@ pub(crate) async fn exec(ctx: &Context, args: &InstallArgs) -> Result<(), Comman

let progress_manager = ProgressManager::new(ProgressManagerSettings { hidden: ctx.debug });

for (_, (_, c)) in cs {
for (name, cid) in canisters {
// Create progress bar with standard configuration
let pb = progress_manager.create_progress_bar(&c.name);
let pb = progress_manager.create_progress_bar(&name);

// Create an async closure that handles the operation for this specific canister
let install_fn = {
Expand All @@ -151,15 +109,8 @@ pub(crate) async fn exec(ctx: &Context, args: &InstallArgs) -> Result<(), Comman
// Indicate to user that the canister is being installed
pb.set_message("Installing...");

// Lookup the canister id
let cid = ctx.ids.lookup(&Key {
network: env.network.name.to_owned(),
environment: env.name.to_owned(),
canister: c.name.to_owned(),
})?;

// Lookup the canister build artifact
let wasm = ctx.artifacts.lookup(&c.name).await?;
let wasm = ctx.artifacts.lookup(&name).await?;

// Retrieve canister status
let (status,) = mgmt.canister_status(&cid).await?;
Expand Down
2 changes: 1 addition & 1 deletion crates/icp-cli/src/commands/canister/settings/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use icp::{agent, identity, network};
use crate::{
commands::Context,
options::{EnvironmentOpt, IdentityOpt},
store_id::{Key, LookupError as LookupIdError},
store_id::{Key, LookupIdError},
};

#[derive(Debug, Args)]
Expand Down
2 changes: 1 addition & 1 deletion crates/icp-cli/src/commands/canister/settings/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use icp::{agent, identity, network};
use crate::{
commands::Context,
options::{EnvironmentOpt, IdentityOpt},
store_id::{Key, LookupError as LookupIdError},
store_id::{Key, LookupIdError},
};

#[derive(Clone, Debug, Default, Args)]
Expand Down
2 changes: 1 addition & 1 deletion crates/icp-cli/src/commands/canister/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use icp::{agent, identity, network};
use crate::{
commands::Context,
options::{EnvironmentOpt, IdentityOpt},
store_id::{Key, LookupError as LookupIdError},
store_id::{Key, LookupIdError},
};

#[derive(Debug, Args)]
Expand Down
2 changes: 1 addition & 1 deletion crates/icp-cli/src/commands/canister/stop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use icp::{agent, identity, network};
use crate::{
commands::Context,
options::{EnvironmentOpt, IdentityOpt},
store_id::{Key, LookupError as LookupIdError},
store_id::{Key, LookupIdError},
};

#[derive(Debug, Args)]
Expand Down
4 changes: 2 additions & 2 deletions crates/icp-cli/src/commands/canister/top_up.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use icp_canister_interfaces::cycles_ledger::{
use crate::{
commands::Context,
options::{EnvironmentOpt, IdentityOpt},
store_id::{Key, LookupError},
store_id::{Key, LookupIdError},
};

#[derive(Debug, Args)]
Expand Down Expand Up @@ -53,7 +53,7 @@ pub(crate) enum CommandError {
},

#[error(transparent)]
Lookup(#[from] LookupError),
Lookup(#[from] LookupIdError),

#[error(transparent)]
Update(#[from] AgentError),
Expand Down
10 changes: 2 additions & 8 deletions crates/icp-cli/src/commands/deploy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ pub(crate) async fn exec(ctx: &Context, args: &DeployArgs) -> Result<(), Command

// Install the selected canisters
let _ = ctx.term.write_line("\n\nInstalling canisters:");
let out = install::exec(
install::exec(
ctx,
&install::InstallArgs {
names: cnames.to_owned(),
Expand All @@ -183,13 +183,7 @@ pub(crate) async fn exec(ctx: &Context, args: &DeployArgs) -> Result<(), Command
environment: args.environment.clone(),
},
)
.await;

if let Err(err) = out
&& !matches!(err, install::CommandError::NoCanisters)
{
return Err(err.into());
}
.await?;

// Sync the selected canisters
let _ = ctx.term.write_line("\n\nSyncing canisters:");
Expand Down
2 changes: 1 addition & 1 deletion crates/icp-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ pub(crate) enum GetCanisterIdForEnvError {
environment_name
))]
CanisterIdLookup {
source: crate::store_id::LookupError,
source: crate::store_id::LookupIdError,
canister_name: String,
environment_name: String,
},
Expand Down
4 changes: 2 additions & 2 deletions crates/icp-cli/src/commands/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
commands::Context,
options::{EnvironmentOpt, IdentityOpt},
progress::{ProgressManager, ProgressManagerSettings},
store_id::{Key, LookupError},
store_id::{Key, LookupIdError},
};

#[derive(Args, Debug)]
Expand Down Expand Up @@ -58,7 +58,7 @@ pub(crate) enum CommandError {
NoCanisters,

#[error(transparent)]
IdLookup(#[from] LookupError),
IdLookup(#[from] LookupIdError),

#[error(transparent)]
Synchronize(#[from] SynchronizeError),
Expand Down
12 changes: 6 additions & 6 deletions crates/icp-cli/src/store_artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub(crate) trait Access: Sync + Send {
async fn save(&self, name: &str, wasm: &[u8]) -> Result<(), SaveError>;

/// Lookup a canister artifact (WASM) from the store.
async fn lookup(&self, name: &str) -> Result<Vec<u8>, LookupError>;
async fn lookup(&self, name: &str) -> Result<Vec<u8>, LookupArtifactError>;
}

#[derive(Debug, Snafu)]
Expand All @@ -31,7 +31,7 @@ pub(crate) enum SaveError {
}

#[derive(Debug, Snafu)]
pub(crate) enum LookupError {
pub(crate) enum LookupArtifactError {
#[snafu(display("failed to read artifact file"))]
LookupReadFileError { source: icp::fs::Error },

Expand Down Expand Up @@ -85,13 +85,13 @@ impl Access for ArtifactStore {
.await?
}

async fn lookup(&self, name: &str) -> Result<Vec<u8>, LookupError> {
async fn lookup(&self, name: &str) -> Result<Vec<u8>, LookupArtifactError> {
self.lock
.with_read(async |store| {
let artifact = store.artifact_by_name(name);
// Not Found
if !artifact.exists() {
return Err(LookupError::LookupArtifactNotFound {
return Err(LookupArtifactError::LookupArtifactNotFound {
name: name.to_owned(),
});
}
Expand Down Expand Up @@ -137,12 +137,12 @@ impl Access for MockInMemoryArtifactStore {
Ok(())
}

async fn lookup(&self, name: &str) -> Result<Vec<u8>, LookupError> {
async fn lookup(&self, name: &str) -> Result<Vec<u8>, LookupArtifactError> {
let store = self.store.lock().unwrap();

match store.get(name) {
Some(wasm) => Ok(wasm.clone()),
None => Err(LookupError::LookupArtifactNotFound {
None => Err(LookupArtifactError::LookupArtifactNotFound {
name: name.to_owned(),
}),
}
Expand Down
Loading