Merge pull request #9572 from laurazard/dont-wait-for-oneshots

Use appropriate dependency condition for one-shot containers when running `compose up --wait`
This commit is contained in:
Laura Brehm 2022-06-26 14:48:49 +02:00 committed by GitHub
commit 3ccf4349e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 1 deletions

View File

@ -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

View File

@ -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")
}

View File

@ -0,0 +1,10 @@
services:
oneshot:
image: alpine
command: echo 'hello world'
longrunning:
image: alpine
depends_on:
oneshot:
condition: service_completed_successfully
command: sleep infinity