@@ -26,8 +26,9 @@ use bollard::{
2626} ;
2727
2828use crate :: model:: types:: { TargetDir , VolumeFilesSpec } ;
29- use bollard_stubs:: query_parameters:: UploadToContainerOptions ;
30- use futures:: { StreamExt , future} ;
29+ use bollard_stubs:: models:: MountTypeEnum ;
30+ use bollard_stubs:: query_parameters:: { UploadToContainerOptions , WaitContainerOptions } ;
31+ use futures:: { StreamExt , TryStreamExt , future} ;
3132use std:: time:: { SystemTime , UNIX_EPOCH } ;
3233use std:: { collections:: HashMap , time:: Duration } ;
3334use tokio:: time:: { sleep, timeout} ;
@@ -487,19 +488,29 @@ timeout $TIMEOUT sh -c 'read _ < /tmp/exec_start' || exit 1
487488
488489echo "Exec session started"
489490read _ < /tmp/exec_end
490- echo "Exec session ended"
491- exit 0"# ;
491+ EXEC_EXIT_CODE=$(cat /tmp/exec_exit)
492+ echo "Exec session ended: $EXEC_EXIT_CODE"
493+ exit $EXEC_EXIT_CODE"# ;
492494
493495 let epv = inject ( & wait_for_exec, "entrypoint.sh" ) ;
494496 let entrypoint = epv. iter ( ) . map ( String :: as_str) . collect ( ) ;
497+ let work_dir = "/tmp/one-shot" ;
495498 let id = self
496499 . create ( RunSpec {
497500 reason : name,
498501 image : image. unwrap_or ( constants:: DEFAULT_IMAGE ) ,
499502 container_name : & id:: random_suffix ( "one-shot" ) ,
500503 command : Some ( entrypoint) ,
501- mounts,
504+ mounts : mounts. map ( |mut m| {
505+ m. extend_from_slice ( & [ Mount {
506+ target : Some ( work_dir. into ( ) ) ,
507+ typ : Some ( MountTypeEnum :: TMPFS ) ,
508+ ..Default :: default ( )
509+ } ] ) ;
510+ m
511+ } ) ,
502512 uid : uid. unwrap_or ( constants:: ROOT_UID ) ,
513+ work_dir : Some ( work_dir) ,
503514 ..Default :: default ( )
504515 } )
505516 . await
@@ -540,14 +551,13 @@ exit 0"#;
540551 . await ;
541552 } ) ;
542553 }
543-
544554 Ok ( id)
545555 }
546556
547557 fn format_cmd ( command : String ) -> Vec < String > {
548558 let cmd = format ! (
549559 r#"#!/bin/sh
550- trap 'echo end > /tmp/exec_end' EXIT
560+ trap 'echo $? > /tmp/exec_exit; echo end > /tmp/exec_end' EXIT
551561echo start > /tmp/exec_start
552562{}
553563 "# ,
@@ -562,11 +572,30 @@ echo start > /tmp/exec_start
562572 command : String ,
563573 mounts : Option < Vec < Mount > > ,
564574 uid : Option < & str > ,
575+ image : Option < & str > ,
565576 ) -> Result < OneShotResult , AnyError > {
566- let id = self . make_one_shot ( name, mounts, uid, None ) . await ?;
577+ let id = self . make_one_shot ( name, mounts, uid, image ) . await ?;
567578 let cmd = Self :: format_cmd ( command) ;
568579 let cmd = cmd. iter ( ) . map ( |x| x. as_str ( ) ) . collect :: < Vec < _ > > ( ) ;
569- let data = self . exec . output ( name, & id. clone ( ) , uid, Some ( cmd) ) . await ?;
580+
581+ let id_clone = id. clone ( ) ;
582+ let client = self . client . clone ( ) ;
583+
584+ let wait_handle = tokio:: spawn ( async move {
585+ client
586+ . wait_container ( & id_clone, None :: < WaitContainerOptions > )
587+ . try_collect :: < Vec < _ > > ( )
588+ . await
589+ } ) ;
590+
591+ let data = self . exec . output ( name, & id, uid, Some ( cmd) ) . await ?;
592+ let _ = match wait_handle. await ? {
593+ Ok ( r) => r,
594+ Err ( Error :: DockerContainerWaitError { code, .. } ) => {
595+ return Err ( format ! ( "One-shot cmd failed (exit {}): \n {}" , code, data) . into ( ) ) ;
596+ }
597+ Err ( e) => return Err ( e. into ( ) ) ,
598+ } ;
570599
571600 Ok ( OneShotResult { data } )
572601 }
0 commit comments