@@ -5,7 +5,12 @@ use candid::{Decode, Encode, Nat};
55use clap:: Args ;
66use futures:: { StreamExt , stream:: FuturesOrdered } ;
77use ic_agent:: { Agent , AgentError , export:: Principal } ;
8- use icp:: { agent, identity, network, prelude:: * } ;
8+ use icp:: {
9+ agent,
10+ context:: { GetAgentForEnvError , GetEnvironmentError } ,
11+ identity, network,
12+ prelude:: * ,
13+ } ;
914use icp_canister_interfaces:: {
1015 cycles_ledger:: {
1116 CYCLES_LEDGER_PRINCIPAL , CanisterSettingsArg , CreateCanisterArgs , CreateCanisterResponse ,
@@ -22,7 +27,7 @@ use crate::{
2227 options:: { EnvironmentOpt , IdentityOpt } ,
2328 progress:: { ProgressManager , ProgressManagerSettings } ,
2429} ;
25- use icp:: store_id:: { Key , LookupError , RegisterError } ;
30+ use icp:: store_id:: { Key , LookupIdError , RegisterError } ;
2631
2732pub ( crate ) const DEFAULT_CANISTER_CYCLES : u128 = 2 * TRILLION ;
2833
@@ -85,9 +90,6 @@ pub(crate) enum CommandError {
8590 #[ error( transparent) ]
8691 Identity ( #[ from] identity:: LoadError ) ,
8792
88- #[ error( "project does not contain an environment named '{name}'" ) ]
89- EnvironmentNotFound { name : String } ,
90-
9193 #[ error( transparent) ]
9294 Access ( #[ from] network:: AccessError ) ,
9395
@@ -103,9 +105,6 @@ pub(crate) enum CommandError {
103105 canister : String ,
104106 } ,
105107
106- #[ error( "no canisters available to create" ) ]
107- NoCanisters ,
108-
109108 #[ error( "canister exists already: {principal}" ) ]
110109 CanisterExists { principal : Principal } ,
111110
@@ -126,6 +125,12 @@ pub(crate) enum CommandError {
126125
127126 #[ error( transparent) ]
128127 Unexpected ( #[ from] anyhow:: Error ) ,
128+
129+ #[ error( transparent) ]
130+ GetAgentForEnv ( #[ from] GetAgentForEnvError ) ,
131+
132+ #[ error( transparent) ]
133+ GetEnvironment ( #[ from] GetEnvironmentError ) ,
129134}
130135
131136// Creates canister(s) by asking the cycles ledger to create them.
@@ -135,27 +140,15 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
135140 // Load project
136141 let p = ctx. project . load ( ) . await ?;
137142
138- // Load identity
139- let id = ctx. identity . load ( args. identity . clone ( ) . into ( ) ) . await ?;
140-
141143 // Load target environment
142- let env =
143- p. environments
144- . get ( args. environment . name ( ) )
145- . ok_or ( CommandError :: EnvironmentNotFound {
146- name : args. environment . name ( ) . to_owned ( ) ,
147- } ) ?;
148-
149- // Collect environment canisters
150- let cnames = match args. names . is_empty ( ) {
151- // No canisters specified
152- true => env. canisters . keys ( ) . cloned ( ) . collect ( ) ,
153-
154- // Individual canisters specified
144+ let env = ctx. get_environment ( args. environment . name ( ) ) . await ?;
145+
146+ let target_canisters = match args. names . is_empty ( ) {
147+ true => env. get_canister_names ( ) ,
155148 false => args. names . clone ( ) ,
156149 } ;
157150
158- for name in & cnames {
151+ for name in & target_canisters {
159152 if !p. canisters . contains_key ( name) {
160153 return Err ( CommandError :: CanisterNotFound {
161154 name : name. to_owned ( ) ,
@@ -170,17 +163,12 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
170163 }
171164 }
172165
173- let cs = env
166+ let canister_infos = env
174167 . canisters
175168 . iter ( )
176- . filter ( |( k, _) | cnames . contains ( k) )
169+ . filter ( |( k, _) | target_canisters . contains ( k) )
177170 . collect :: < HashMap < _ , _ > > ( ) ;
178171
179- // Ensure at least one canister has been selected
180- if cs. is_empty ( ) {
181- return Err ( CommandError :: NoCanisters ) ;
182- }
183-
184172 // Do we have any already existing canisters?
185173 let cexist: Vec < _ > = env
186174 . canisters
@@ -196,15 +184,10 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
196184 } )
197185 . collect ( ) ;
198186
199- // Access network
200- let access = ctx. network . access ( & env. network ) . await ?;
201-
202187 // Agent
203- let agent = ctx. agent . create ( id, & access. url ) . await ?;
204-
205- if let Some ( k) = access. root_key {
206- agent. set_root_key ( k) ;
207- }
188+ let agent = ctx
189+ . get_agent_for_env ( & args. identity . clone ( ) . into ( ) , args. environment . name ( ) )
190+ . await ?;
208191
209192 // Select which subnet to deploy the canisters to
210193 //
@@ -241,9 +224,10 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
241224
242225 let progress_manager = ProgressManager :: new ( ProgressManagerSettings { hidden : ctx. debug } ) ;
243226
244- for ( _, c) in cs. values ( ) {
227+ let env_ref = & env;
228+ for ( name, ( _path, info) ) in canister_infos. iter ( ) {
245229 // Create progress bar with standard configuration
246- let pb = progress_manager. create_progress_bar ( & c . name ) ;
230+ let pb = progress_manager. create_progress_bar ( name) ;
247231
248232 // Create an async closure that handles the operation for this specific canister
249233 let create_fn = {
@@ -257,9 +241,9 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
257241
258242 // Create canister-network association-key
259243 let k = Key {
260- network : env . network . name . to_owned ( ) ,
261- environment : env . name . to_owned ( ) ,
262- canister : c . name . to_owned ( ) ,
244+ network : env_ref . network . name . to_owned ( ) ,
245+ environment : env_ref . name . to_owned ( ) ,
246+ canister : name. to_string ( ) ,
263247 } ;
264248
265249 match ctx. ids . lookup ( & k) {
@@ -269,7 +253,7 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
269253 }
270254
271255 // Doesn't exist (include)
272- Err ( LookupError :: IdNotFound { .. } ) => { }
256+ Err ( LookupIdError :: IdNotFound { .. } ) => { }
273257
274258 // Lookup failed
275259 Err ( err) => panic ! ( "{err}" ) ,
@@ -280,7 +264,7 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
280264 freezing_threshold : cmd
281265 . settings
282266 . freezing_threshold
283- . or ( c . settings . freezing_threshold )
267+ . or ( info . settings . freezing_threshold )
284268 . map ( Nat :: from) ,
285269
286270 controllers : if cmd. controller . is_empty ( ) {
@@ -292,19 +276,19 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
292276 reserved_cycles_limit : cmd
293277 . settings
294278 . reserved_cycles_limit
295- . or ( c . settings . reserved_cycles_limit )
279+ . or ( info . settings . reserved_cycles_limit )
296280 . map ( Nat :: from) ,
297281
298282 memory_allocation : cmd
299283 . settings
300284 . memory_allocation
301- . or ( c . settings . memory_allocation )
285+ . or ( info . settings . memory_allocation )
302286 . map ( Nat :: from) ,
303287
304288 compute_allocation : cmd
305289 . settings
306290 . compute_allocation
307- . or ( c . settings . compute_allocation )
291+ . or ( info . settings . compute_allocation )
308292 . map ( Nat :: from) ,
309293 } ;
310294
0 commit comments