@@ -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,41 +163,30 @@ 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
187175 . values ( )
188176 . filter_map ( |( _, c) | {
189177 ctx. ids
190178 . lookup ( & Key {
191- network : env. network . name . to_owned ( ) ,
192179 environment : env. name . to_owned ( ) ,
193180 canister : c. name . to_owned ( ) ,
194181 } )
195182 . ok ( )
196183 } )
197184 . collect ( ) ;
198185
199- // Access network
200- let access = ctx. network . access ( & env. network ) . await ?;
201-
202186 // 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- }
187+ let agent = ctx
188+ . get_agent_for_env ( & args. identity . clone ( ) . into ( ) , args. environment . name ( ) )
189+ . await ?;
208190
209191 // Select which subnet to deploy the canisters to
210192 //
@@ -241,9 +223,10 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
241223
242224 let progress_manager = ProgressManager :: new ( ProgressManagerSettings { hidden : ctx. debug } ) ;
243225
244- for ( _, c) in cs. values ( ) {
226+ let env_ref = & env;
227+ for ( name, ( _path, info) ) in canister_infos. iter ( ) {
245228 // Create progress bar with standard configuration
246- let pb = progress_manager. create_progress_bar ( & c . name ) ;
229+ let pb = progress_manager. create_progress_bar ( name) ;
247230
248231 // Create an async closure that handles the operation for this specific canister
249232 let create_fn = {
@@ -255,11 +238,10 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
255238 // Indicate to user that the canister is created
256239 pb. set_message ( "Creating..." ) ;
257240
258- // Create canister-network association-key
241+ // Create canister-environment association-key
259242 let k = Key {
260- network : env. network . name . to_owned ( ) ,
261- environment : env. name . to_owned ( ) ,
262- canister : c. name . to_owned ( ) ,
243+ environment : env_ref. name . to_owned ( ) ,
244+ canister : name. to_string ( ) ,
263245 } ;
264246
265247 match ctx. ids . lookup ( & k) {
@@ -269,7 +251,7 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
269251 }
270252
271253 // Doesn't exist (include)
272- Err ( LookupError :: IdNotFound { .. } ) => { }
254+ Err ( LookupIdError :: IdNotFound { .. } ) => { }
273255
274256 // Lookup failed
275257 Err ( err) => panic ! ( "{err}" ) ,
@@ -280,7 +262,7 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
280262 freezing_threshold : cmd
281263 . settings
282264 . freezing_threshold
283- . or ( c . settings . freezing_threshold )
265+ . or ( info . settings . freezing_threshold )
284266 . map ( Nat :: from) ,
285267
286268 controllers : if cmd. controller . is_empty ( ) {
@@ -292,19 +274,19 @@ pub(crate) async fn exec(ctx: &Context, args: &CreateArgs) -> Result<(), Command
292274 reserved_cycles_limit : cmd
293275 . settings
294276 . reserved_cycles_limit
295- . or ( c . settings . reserved_cycles_limit )
277+ . or ( info . settings . reserved_cycles_limit )
296278 . map ( Nat :: from) ,
297279
298280 memory_allocation : cmd
299281 . settings
300282 . memory_allocation
301- . or ( c . settings . memory_allocation )
283+ . or ( info . settings . memory_allocation )
302284 . map ( Nat :: from) ,
303285
304286 compute_allocation : cmd
305287 . settings
306288 . compute_allocation
307- . or ( c . settings . compute_allocation )
289+ . or ( info . settings . compute_allocation )
308290 . map ( Nat :: from) ,
309291 } ;
310292
0 commit comments