Просмотр исходного кода

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 <[email protected]>
Nicolas De Loof 4 лет назад
Родитель
Сommit
597598cb7a
3 измененных файлов с 11 добавлено и 12 удалено
  1. 4 1
      local/compose/containers.go
  2. 5 10
      local/compose/convergence.go
  3. 2 1
      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
 		}
 	}

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