浏览代码

Merge pull request #1544 from docker/race_condition

Nicolas De loof 4 年之前
父节点
当前提交
6941445868
共有 5 个文件被更改,包括 15 次插入20 次删除
  1. 4 1
      local/compose/containers.go
  2. 5 10
      local/compose/convergence.go
  3. 1 1
      local/compose/exec.go
  4. 2 3
      local/compose/resize.go
  5. 3 5
      local/compose/run.go

+ 4 - 1
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

+ 5 - 10
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
 		}
 	}

+ 1 - 1
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
 		}

+ 2 - 3
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
 }

+ 3 - 5
local/compose/run.go

@@ -89,17 +89,15 @@ 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
 	}
 
-	err = s.monitorTTySize(ctx, containerID, s.apiClient.ContainerResize)
-	if err != nil {
-		return 0, err
-	}
+	s.monitorTTySize(ctx, containerID, s.apiClient.ContainerResize)
 
-	statusC, errC := s.apiClient.ContainerWait(context.Background(), oneoffContainer.ID, container.WaitConditionNotRunning)
 	select {
 	case status := <-statusC:
 		return int(status.StatusCode), nil