Skip to content

Commit 9880d3a

Browse files
committed
stop dependent containers before recreating diverged service
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent a742443 commit 9880d3a

File tree

3 files changed

+67
-25
lines changed

3 files changed

+67
-25
lines changed

pkg/compose/convergence.go

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ import (
4545
)
4646

4747
const (
48-
extLifecycle = "x-lifecycle"
49-
forceRecreate = "force_recreate"
50-
5148
doubledContainerNameWarning = "WARNING: The %q service is using the custom container name %q. " +
5249
"Docker requires each container to have a unique name. " +
5350
"Remove the custom name to scale the service.\n"
@@ -108,9 +105,7 @@ func (c *convergence) apply(ctx context.Context, project *types.Project, options
108105
})
109106
}
110107

111-
var mu sync.Mutex
112-
113-
func (c *convergence) ensureService(ctx context.Context, project *types.Project, service types.ServiceConfig, recreate string, inherit bool, timeout *time.Duration) error {
108+
func (c *convergence) ensureService(ctx context.Context, project *types.Project, service types.ServiceConfig, recreate string, inherit bool, timeout *time.Duration) error { //nolint:gocyclo
114109
expected, err := getScale(service)
115110
if err != nil {
116111
return err
@@ -147,6 +142,7 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
147142
// If we don't get a container number (?) just sort by creation date
148143
return containers[i].Created < containers[j].Created
149144
})
145+
150146
for i, container := range containers {
151147
if i >= expected {
152148
// Scale Down
@@ -163,6 +159,11 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
163159
return err
164160
}
165161
if mustRecreate {
162+
err := c.stopDependentContainers(ctx, project, service)
163+
if err != nil {
164+
return err
165+
}
166+
166167
i, container := i, container
167168
eg.Go(tracing.SpanWrapFuncForErrGroup(ctx, "container/recreate", tracing.ContainerOptions(container), func(ctx context.Context) error {
168169
recreated, err := c.service.recreateContainer(ctx, project, service, container, inherit, timeout)
@@ -172,8 +173,8 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
172173
continue
173174
}
174175

175-
// Enforce non-diverged containers are running
176176
w := progress.ContextWriter(ctx)
177+
// Enforce non-diverged containers are running
177178
name := getContainerProgressName(container)
178179
switch container.State {
179180
case ContainerRunning:
@@ -217,6 +218,25 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
217218
return err
218219
}
219220

221+
func (c *convergence) stopDependentContainers(ctx context.Context, project *types.Project, service types.ServiceConfig) error {
222+
w := progress.ContextWriter(ctx)
223+
// Stop dependent containers, so they will be restarted after service is re-created
224+
dependents := project.GetDependentsForService(service)
225+
for _, name := range dependents {
226+
dependents := c.observedState[name]
227+
err := c.service.stopContainers(ctx, w, dependents, nil)
228+
if err != nil {
229+
return err
230+
}
231+
for i, dependent := range dependents {
232+
dependent.State = ContainerExited
233+
dependents[i] = dependent
234+
}
235+
c.observedState[name] = dependents
236+
}
237+
return nil
238+
}
239+
220240
func getScale(config types.ServiceConfig) (int, error) {
221241
scale := config.GetScale()
222242
if scale > 1 && config.ContainerName != "" {
@@ -296,7 +316,7 @@ func mustRecreate(expected types.ServiceConfig, actual moby.Container, policy st
296316
if policy == api.RecreateNever {
297317
return false, nil
298318
}
299-
if policy == api.RecreateForce || expected.Extensions[extLifecycle] == forceRecreate {
319+
if policy == api.RecreateForce {
300320
return true, nil
301321
}
302322
configHash, err := ServiceHash(expected)
@@ -535,26 +555,9 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
535555
}
536556

537557
w.Event(progress.NewEvent(getContainerProgressName(replaced), progress.Done, "Recreated"))
538-
setDependentLifecycle(project, service.Name, forceRecreate)
539558
return created, err
540559
}
541560

542-
// setDependentLifecycle define the Lifecycle strategy for all services to depend on specified service
543-
func setDependentLifecycle(project *types.Project, service string, strategy string) {
544-
mu.Lock()
545-
defer mu.Unlock()
546-
547-
for i, s := range project.Services {
548-
if utils.StringContains(s.GetDependencies(), service) {
549-
if s.Extensions == nil {
550-
s.Extensions = map[string]interface{}{}
551-
}
552-
s.Extensions[extLifecycle] = strategy
553-
project.Services[i] = s
554-
}
555-
}
556-
}
557-
558561
func (s *composeService) startContainer(ctx context.Context, container moby.Container) error {
559562
w := progress.ContextWriter(ctx)
560563
w.Event(progress.NewEvent(getContainerProgressName(container), progress.Working, "Restart"))

pkg/e2e/compose_up_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,23 @@ func TestStdoutStderr(t *testing.T) {
9090

9191
c.RunDockerComposeCmd(t, "--project-name", projectName, "down", "--remove-orphans")
9292
}
93+
94+
func TestLoggingDriver(t *testing.T) {
95+
c := NewCLI(t)
96+
const projectName = "e2e-logging-driver"
97+
98+
host := "HOST=127.0.0.1"
99+
res := c.RunDockerCmd(t, "info", "-f", "{{.OperatingSystem}}")
100+
os := res.Stdout()
101+
if strings.TrimSpace(os) == "Docker Desktop" {
102+
host = "HOST=host.docker.internal"
103+
}
104+
105+
cmd := c.NewDockerComposeCmd(t, "-f", "fixtures/logging-driver/compose.yaml", "--project-name", projectName, "up", "-d")
106+
cmd.Env = append(cmd.Env, host, "BAR=foo")
107+
icmd.RunCmd(cmd).Assert(t, icmd.Success)
108+
109+
cmd = c.NewDockerComposeCmd(t, "-f", "fixtures/logging-driver/compose.yaml", "--project-name", projectName, "up", "-d")
110+
cmd.Env = append(cmd.Env, host, "BAR=zot")
111+
icmd.RunCmd(cmd).Assert(t, icmd.Success)
112+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
services:
2+
fluentbit:
3+
image: fluent/fluent-bit:3.1.7-debug
4+
ports:
5+
- "24224:24224"
6+
- "24224:24224/udp"
7+
environment:
8+
FOO: ${BAR}
9+
10+
app:
11+
image: nginx
12+
depends_on:
13+
fluentbit:
14+
condition: service_started
15+
restart: true
16+
logging:
17+
driver: fluentd
18+
options:
19+
fluentd-address: ${HOST:-127.0.0.1}:24224

0 commit comments

Comments
 (0)