mirror of https://github.com/docker/compose.git
				
				
				
			Use appropriate dependency condition for one-shot containers when running `compose up --wait`
Also add e2e tests to ensure `compose up --wait` does not get stuck forever waiting for one-shot containers Signed-off-by: Laura Brehm <laurabrehm@hey.com>
This commit is contained in:
		
							parent
							
								
									ab25aabfb9
								
							
						
					
					
						commit
						fd8538f780
					
				|  | @ -80,7 +80,7 @@ func (s *composeService) start(ctx context.Context, projectName string, options | |||
| 		depends := types.DependsOnConfig{} | ||||
| 		for _, s := range project.Services { | ||||
| 			depends[s.Name] = types.ServiceDependency{ | ||||
| 				Condition: ServiceConditionRunningOrHealthy, | ||||
| 				Condition: getDependencyCondition(s, project), | ||||
| 			} | ||||
| 		} | ||||
| 		err = s.waitDependencies(ctx, project, depends) | ||||
|  | @ -92,6 +92,20 @@ func (s *composeService) start(ctx context.Context, projectName string, options | |||
| 	return eg.Wait() | ||||
| } | ||||
| 
 | ||||
| // getDependencyCondition checks if service is depended on by other services
 | ||||
| // with service_completed_successfully condition, and applies that condition
 | ||||
| // instead, or --wait will never finish waiting for one-shot containers
 | ||||
| func getDependencyCondition(service types.ServiceConfig, project *types.Project) string { | ||||
| 	for _, services := range project.Services { | ||||
| 		for dependencyService, dependencyConfig := range services.DependsOn { | ||||
| 			if dependencyService == service.Name && dependencyConfig.Condition == types.ServiceConditionCompletedSuccessfully { | ||||
| 				return types.ServiceConditionCompletedSuccessfully | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return ServiceConditionRunningOrHealthy | ||||
| } | ||||
| 
 | ||||
| type containerWatchFn func(container moby.Container) error | ||||
| 
 | ||||
| // watchContainers uses engine events to capture container start/die and notify ContainerEventListener
 | ||||
|  |  | |||
|  | @ -0,0 +1,47 @@ | |||
| /* | ||||
|    Copyright 2020 Docker Compose CLI authors | ||||
| 
 | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
| 
 | ||||
|        http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| 
 | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| package e2e | ||||
| 
 | ||||
| import ( | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"gotest.tools/v3/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestUpWait(t *testing.T) { | ||||
| 	c := NewParallelCLI(t) | ||||
| 	const projectName = "e2e-deps-wait" | ||||
| 
 | ||||
| 	timeout := time.After(30 * time.Second) | ||||
| 	done := make(chan bool) | ||||
| 	go func() { | ||||
| 		res := c.RunDockerComposeCmd(t, "-f", "fixtures/dependencies/deps-completed-successfully.yaml", "--project-name", projectName, "up", "--wait", "-d") | ||||
| 		assert.Assert(t, strings.Contains(res.Combined(), "e2e-deps-wait-oneshot-1"), res.Combined()) | ||||
| 		done <- true | ||||
| 	}() | ||||
| 
 | ||||
| 	select { | ||||
| 	case <-timeout: | ||||
| 		t.Fatal("test did not finish in time") | ||||
| 	case <-done: | ||||
| 		break | ||||
| 	} | ||||
| 
 | ||||
| 	c.RunDockerComposeCmd(t, "--project-name", projectName, "down") | ||||
| } | ||||
|  | @ -0,0 +1,11 @@ | |||
| version: '3' | ||||
| services: | ||||
|   oneshot: | ||||
|     image: ubuntu | ||||
|     command: echo 'hello world' | ||||
|   longrunning: | ||||
|     image: ubuntu | ||||
|     depends_on: | ||||
|       oneshot: | ||||
|         condition: service_completed_successfully | ||||
|     command: sleep infinity | ||||
		Loading…
	
		Reference in New Issue