From 597598cb7ac3958ce4f1a3438f184b0bfa635288 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Wed, 14 Apr 2021 18:31:02 +0200 Subject: [PATCH 1/2] only start container once we have a wait channel set, to prevent race condition with fast terminating container see https://github.com/docker/cli/blob/master/cli/command/container/run.go#L157-L168 Signed-off-by: Nicolas De Loof --- local/compose/containers.go | 5 ++++- local/compose/convergence.go | 15 +++++---------- local/compose/run.go | 3 ++- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/local/compose/containers.go b/local/compose/containers.go index ad1790971..4b57ad7d4 100644 --- a/local/compose/containers.go +++ b/local/compose/containers.go @@ -43,6 +43,9 @@ func (s *composeService) getContainers(ctx context.Context, project string, oneO f := filters.NewArgs( projectFilter(project), ) + if len(selectedServices) == 1 { + f.Add("label", fmt.Sprintf("%s=%s", serviceLabel, selectedServices[0])) + } switch oneOff { case oneOffOnly: f.Add("label", fmt.Sprintf("%s=%s", oneoffLabel, "True")) @@ -57,7 +60,7 @@ func (s *composeService) getContainers(ctx context.Context, project string, oneO if err != nil { return nil, err } - if len(selectedServices) > 0 { + if len(selectedServices) > 1 { containers = containers.filter(isService(selectedServices...)) } return containers, nil diff --git a/local/compose/convergence.go b/local/compose/convergence.go index 37f6baf11..559919603 100644 --- a/local/compose/convergence.go +++ b/local/compose/convergence.go @@ -337,16 +337,14 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin } func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Project, service string) (bool, error) { - containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{ - Filters: filters.NewArgs( - projectFilter(project.Name), - serviceFilter(service), - ), - }) + containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, service) if err != nil { return false, err } + if len(containers) == 0 { + return false, nil + } for _, c := range containers { container, err := s.apiClient.ContainerInspect(ctx, c.ID) if err != nil { @@ -355,10 +353,7 @@ func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Pr if container.State == nil || container.State.Health == nil { return false, fmt.Errorf("container for service %q has no healthcheck configured", service) } - switch container.State.Health.Status { - case "starting": - return false, nil - case "unhealthy": + if container.State.Health.Status != moby.Healthy { return false, nil } } diff --git a/local/compose/run.go b/local/compose/run.go index 79b355677..8adbadeb7 100644 --- a/local/compose/run.go +++ b/local/compose/run.go @@ -89,6 +89,8 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types. } defer restore() + statusC, errC := s.apiClient.ContainerWait(context.Background(), oneoffContainer.ID, container.WaitConditionNextExit) + err = s.apiClient.ContainerStart(ctx, containerID, apitypes.ContainerStartOptions{}) if err != nil { return 0, err @@ -99,7 +101,6 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types. return 0, err } - statusC, errC := s.apiClient.ContainerWait(context.Background(), oneoffContainer.ID, container.WaitConditionNotRunning) select { case status := <-statusC: return int(status.StatusCode), nil From 0ab75d28ba7c14bdce11ba5c3187e2fa69a9820a Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Wed, 14 Apr 2021 18:54:20 +0200 Subject: [PATCH 2/2] don't report error resizing tty, as container could stop any time see https://github.com/docker/cli/blob/04dad42c3c82733c3c82b1f859829d62d8608128/cli/command/container/tty.go#L71 wich always return nil Signed-off-by: Nicolas De Loof --- local/compose/exec.go | 2 +- local/compose/resize.go | 5 ++--- local/compose/run.go | 5 +---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/local/compose/exec.go b/local/compose/exec.go index d2230085a..90fcba37e 100644 --- a/local/compose/exec.go +++ b/local/compose/exec.go @@ -83,7 +83,7 @@ func (s *composeService) Exec(ctx context.Context, project *types.Project, opts defer resp.Close() if opts.Tty { - err := s.monitorTTySize(ctx, exec.ID, s.apiClient.ContainerExecResize) + s.monitorTTySize(ctx, exec.ID, s.apiClient.ContainerExecResize) if err != nil { return err } diff --git a/local/compose/resize.go b/local/compose/resize.go index 8453d4e63..0c9723810 100644 --- a/local/compose/resize.go +++ b/local/compose/resize.go @@ -28,13 +28,13 @@ import ( "github.com/docker/docker/pkg/signal" ) -func (s *composeService) monitorTTySize(ctx context.Context, container string, resize func(context.Context, string, moby.ResizeOptions) error) error { +func (s *composeService) monitorTTySize(ctx context.Context, container string, resize func(context.Context, string, moby.ResizeOptions) error) { err := resize(ctx, container, moby.ResizeOptions{ // nolint:errcheck Height: uint(goterm.Height()), Width: uint(goterm.Width()), }) if err != nil { - return err + return } sigchan := make(chan os.Signal, 1) @@ -71,5 +71,4 @@ func (s *composeService) monitorTTySize(ctx context.Context, container string, r } } }() - return nil } diff --git a/local/compose/run.go b/local/compose/run.go index 8adbadeb7..aad04d7b4 100644 --- a/local/compose/run.go +++ b/local/compose/run.go @@ -96,10 +96,7 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types. return 0, err } - err = s.monitorTTySize(ctx, containerID, s.apiClient.ContainerResize) - if err != nil { - return 0, err - } + s.monitorTTySize(ctx, containerID, s.apiClient.ContainerResize) select { case status := <-statusC: