@@ -7,22 +7,22 @@ import (
77 "os"
88 "strings"
99
10- "golang.org/x/net/context"
11-
1210 "github.com/Sirupsen/logrus"
1311 "github.com/docker/engine-api/client"
1412 "github.com/docker/engine-api/types"
1513 "github.com/docker/engine-api/types/container"
1614 "github.com/docker/go-connections/nat"
1715 "github.com/hyperhq/hypercli/pkg/promise"
1816 "github.com/hyperhq/hypercli/pkg/stdcopy"
17+ "github.com/hyperhq/hypercli/pkg/stringid"
1918 "github.com/hyperhq/hypercli/pkg/term"
2019 "github.com/hyperhq/libcompose/config"
2120 "github.com/hyperhq/libcompose/labels"
2221 "github.com/hyperhq/libcompose/logger"
2322 "github.com/hyperhq/libcompose/project"
2423 "github.com/hyperhq/libcompose/project/events"
2524 util "github.com/hyperhq/libcompose/utils"
25+ "golang.org/x/net/context"
2626)
2727
2828// Container holds information about a docker container and the service it is tied on.
@@ -325,12 +325,48 @@ func (c *Container) Run(ctx context.Context, imageName string, configOverride *c
325325 return - 1 , err
326326 }
327327
328- exitedContainer , err := c .client .ContainerInspect (ctx , container .ID )
329- if err != nil {
330- return - 1 , err
328+ var status int
329+ // Attached mode
330+ if c .service .context .Autoremove {
331+ // Warn user if they detached us
332+ js , err := c .client .ContainerInspect (ctx , container .ID )
333+ if err != nil {
334+ return - 1 , err
335+ }
336+ if js .State .Running == true || js .State .Paused == true {
337+ logrus .Infof ("Detached from %s, awaiting its termination in order to uphold \" --rm\" .\n " ,
338+ stringid .TruncateID (container .ID ))
339+ }
340+
341+ // Autoremove: wait for the container to finish, retrieve
342+ // the exit code and remove the container
343+ if status , err = c .client .ContainerWait (ctx , container .ID ); err != nil {
344+ return - 1 , err
345+ }
346+ exitedContainer , err := c .client .ContainerInspect (ctx , container .ID )
347+ if err != nil {
348+ return - 1 , err
349+ }
350+ status = exitedContainer .State .ExitCode
351+ } else {
352+ // No Autoremove: Simply retrieve the exit code
353+ if ! configOverride .Tty {
354+ // In non-TTY mode, we can't detach, so we must wait for container exit
355+ if status , err = c .client .ContainerWait (ctx , container .ID ); err != nil {
356+ return - 1 , err
357+ }
358+ } else {
359+ // In TTY mode, there is a race: if the process dies too slowly, the state could
360+ // be updated after the getExitCode call and result in the wrong exit code being reported
361+ exitedContainer , err := c .client .ContainerInspect (ctx , container .ID )
362+ if err != nil {
363+ return - 1 , err
364+ }
365+ status = exitedContainer .State .ExitCode
366+ }
331367 }
332368
333- return exitedContainer . State . ExitCode , nil
369+ return status , nil
334370}
335371
336372func holdHijackedConnection (tty bool , inputStream io.ReadCloser , outputStream , errorStream io.Writer , resp types.HijackedResponse ) error {
0 commit comments