@@ -11,18 +11,15 @@ use crate::{
1111 config:: { ComputePlatform , Config } ,
1212 cscs:: {
1313 api_client:: {
14- client:: CscsApi ,
14+ client:: { CscsApi , JobStartOptions } ,
1515 types:: { FileStat , FileSystemType , Job , JobDetail , PathEntry , PathType , S3Upload , System , UserInfo } ,
1616 } ,
1717 oauth2:: {
1818 CLIENT_ID_SECRET_NAME , CLIENT_SECRET_SECRET_NAME , client_credentials_login, finish_cscs_device_login,
1919 start_cscs_device_login,
2020 } ,
2121 } ,
22- util:: {
23- keyring:: { Secret , get_secret, store_secret} ,
24- types:: DockerImageUrl ,
25- } ,
22+ util:: keyring:: { Secret , get_secret, store_secret} ,
2623} ;
2724
2825const CSCS_MAX_DIRECT_SIZE : usize = 5242880 ;
@@ -134,10 +131,19 @@ pub async fn cscs_job_log(
134131 return Err ( eyre ! ( "couldn't find job {}" , job_id) ) ;
135132 }
136133 let path = if stderr {
137- PathBuf :: from ( job. unwrap ( ) . stderr )
134+ job. unwrap ( ) . stderr
138135 } else {
139- PathBuf :: from ( job. unwrap ( ) . stdout )
136+ job. unwrap ( ) . stdout
140137 } ;
138+ if path. is_empty ( ) {
139+ return Err ( eyre ! (
140+ "No {} log exists for job {}" ,
141+ if stderr { "stderr" } else { "stdout" } ,
142+ job_id
143+ ) ) ;
144+ }
145+
146+ let path = PathBuf :: from ( path) ;
141147 api_client. tail ( current_system, path, 100 ) . await
142148 }
143149 Err ( e) => Err ( e) ,
@@ -160,12 +166,7 @@ pub async fn cscs_job_cancel(job_id: i64, system: Option<String>, platform: Opti
160166#[ allow( clippy:: too_many_arguments) ]
161167pub async fn cscs_start_job (
162168 name : Option < String > ,
163- script_file : Option < PathBuf > ,
164- image : Option < DockerImageUrl > ,
165- command : Option < Vec < String > > ,
166- container_workdir : Option < String > ,
167- env : Vec < ( String , String ) > ,
168- mount : Vec < ( String , String ) > ,
169+ options : JobStartOptions ,
169170 system : Option < String > ,
170171 platform : Option < ComputePlatform > ,
171172 account : Option < String > ,
@@ -193,12 +194,15 @@ pub async fn cscs_start_job(
193194 return Err ( eyre ! ( "couldn't get system description for {}" , current_system) ) ;
194195 }
195196 } ;
196- let container_workdir = container_workdir. unwrap_or ( config. cscs . workdir . unwrap_or ( "/scratch" . to_owned ( ) ) ) ;
197+ let container_workdir = options
198+ . container_workdir
199+ . clone ( )
200+ . unwrap_or ( config. cscs . workdir . unwrap_or ( "/scratch" . to_owned ( ) ) ) ;
197201 let base_path = scratch. join ( user_info. name . clone ( ) ) . join ( & job_name) ;
198202
199203 let mut envvars = config. cscs . env . clone ( ) ;
200- envvars. extend ( env) ;
201- let mut mount: HashMap < String , String > = mount. into_iter ( ) . collect ( ) ;
204+ envvars. extend ( options . env . clone ( ) ) ;
205+ let mut mount: HashMap < String , String > = options . mount . clone ( ) . into_iter ( ) . collect ( ) ;
202206 mount. entry ( "${SCRATCH}" . to_owned ( ) ) . or_insert ( "/scratch" . to_owned ( ) ) ;
203207
204208 let mut tera = tera:: Tera :: default ( ) ;
@@ -207,7 +211,7 @@ pub async fn cscs_start_job(
207211 let environment_template = config. cscs . edf_file_template ;
208212 tera. add_raw_template ( "environment.toml" , & environment_template) ?;
209213
210- let docker_image = image. unwrap_or ( config. cscs . image . try_into ( ) ?) ;
214+ let docker_image = options . image . clone ( ) . unwrap_or ( config. cscs . image . try_into ( ) ?) ;
211215 let meta = docker_image. inspect ( ) . await ?;
212216 if let Some ( system_info) = config. cscs . systems . get ( current_system) {
213217 let mut compatible = false ;
@@ -246,13 +250,18 @@ pub async fn cscs_start_job(
246250
247251 // upload script
248252 let script_path = base_path. join ( "script.sh" ) ;
249- let script_template = script_file
253+ let script_template = options
254+ . script_file
255+ . clone ( )
250256 . map ( std:: fs:: read_to_string)
251257 . unwrap_or ( Ok ( config. cscs . sbatch_script_template ) ) ?;
252258 tera. add_raw_template ( "script.sh" , & script_template) ?;
253259 let mut context = tera:: Context :: new ( ) ;
254260 context. insert ( "name" , & job_name) ;
255- context. insert ( "command" , & command. unwrap_or ( config. cscs . command ) . join ( " " ) ) ;
261+ context. insert (
262+ "command" ,
263+ & options. command . clone ( ) . unwrap_or ( config. cscs . command ) . join ( " " ) ,
264+ ) ;
256265 context. insert ( "environment_file" , & environment_path) ;
257266 context. insert ( "container_workdir" , & container_workdir) ;
258267 let script = tera. render ( "script.sh" , & context) ?;
@@ -262,7 +271,7 @@ pub async fn cscs_start_job(
262271
263272 // start job
264273 api_client
265- . start_job ( current_system, account, & job_name, script_path, envvars)
274+ . start_job ( current_system, account, & job_name, script_path, envvars, options )
266275 . await ?;
267276 Ok ( ( ) )
268277 }
@@ -294,6 +303,11 @@ pub async fn cscs_file_download(
294303 system : Option < String > ,
295304 platform : Option < ComputePlatform > ,
296305) -> Result < Option < ( i64 , Url , usize ) > > {
306+ let local = if local. is_dir ( ) {
307+ local. join ( remote. file_name ( ) . ok_or ( eyre ! ( "couldn't get name of remote file" ) ) ?)
308+ } else {
309+ local
310+ } ;
297311 match get_access_token ( ) . await {
298312 Ok ( access_token) => {
299313 let api_client = CscsApi :: new ( access_token. 0 , platform) . unwrap ( ) ;
0 commit comments