@@ -90,9 +90,10 @@ type dockerRunner struct {
9090}
9191
9292type dockerContainer struct {
93+ log zerolog.Logger
9394 client * docker.Client
9495 container * docker.Container
95- output io. Writer
96+ waiter docker. CloseWaiter
9697}
9798
9899func (r * dockerRunner ) GetContainerDir (hostDir , defaultContainerDir string ) string {
@@ -215,6 +216,8 @@ func (r *dockerRunner) start(image string, command string, args []string, volume
215216 Entrypoint : []string {command },
216217 Cmd : args ,
217218 Tty : r .tty ,
219+ AttachStdout : output != nil ,
220+ AttachStderr : output != nil ,
218221 User : r .user ,
219222 ExposedPorts : make (map [docker.Port ]struct {}),
220223 Labels : map [string ]string {
@@ -260,6 +263,29 @@ func (r *dockerRunner) start(image string, command string, args []string, volume
260263 return nil , maskAny (err )
261264 }
262265 r .recordContainerID (c .ID ) // Record ID so we can clean it up later
266+
267+ var waiter docker.CloseWaiter
268+ if output != nil {
269+ // Attach output to container
270+ r .log .Debug ().Msgf ("Attaching to output of container %s" , containerName )
271+ success := make (chan struct {})
272+ defer close (success )
273+ waiter , err = r .client .AttachToContainerNonBlocking (docker.AttachToContainerOptions {
274+ Container : c .ID ,
275+ OutputStream : output ,
276+ Logs : true ,
277+ Stdout : true ,
278+ Stderr : true ,
279+ Success : success ,
280+ Stream : true ,
281+ RawTerminal : true ,
282+ })
283+ if err != nil {
284+ r .log .Error ().Err (err ).Msgf ("Failed to attach to output of container %s" , c .ID )
285+ return nil , maskAny (err )
286+ }
287+ <- success
288+ }
263289 r .log .Debug ().Msgf ("Starting container %s" , containerName )
264290 if err := r .client .StartContainer (c .ID , opts .HostConfig ); err != nil {
265291 return nil , maskAny (err )
@@ -276,9 +302,10 @@ func (r *dockerRunner) start(image string, command string, args []string, volume
276302 return nil , maskAny (err )
277303 }
278304 return & dockerContainer {
305+ log : r .log .With ().Str ("container" , c .ID ).Logger (),
279306 client : r .client ,
280307 container : c ,
281- output : output ,
308+ waiter : waiter ,
282309 }, nil
283310}
284311
@@ -486,16 +513,14 @@ func (p *dockerContainer) HostPort(containerPort int) (int, error) {
486513}
487514
488515func (p * dockerContainer ) Wait () {
489- p .client .WaitContainer (p .container .ID )
490- if p .output != nil {
491- // Fetch logs
492- if err := p .client .Logs (docker.LogsOptions {
493- Container : p .container .ID ,
494- OutputStream : p .output ,
495- Stdout : true ,
496- }); err != nil {
497- p .output .Write ([]byte (err .Error ()))
498- }
516+ if p .waiter != nil {
517+ p .waiter .Wait ()
518+ }
519+ exitCode , err := p .client .WaitContainer (p .container .ID )
520+ if err != nil {
521+ p .log .Error ().Err (err ).Msg ("WaitContainer failed" )
522+ } else if exitCode != 0 {
523+ p .log .Debug ().Int ("exitcode" , exitCode ).Msg ("Container terminated with non-zero exit code" )
499524 }
500525}
501526
0 commit comments