diff --git a/go.mod b/go.mod index 4bf44dfcb..0898c001a 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Microsoft/go-winio v0.6.2 github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/buger/goterm v1.0.4 - github.com/compose-spec/compose-go/v2 v2.4.9 + github.com/compose-spec/compose-go/v2 v2.4.10-0.20250319114556-312596f4c1fe github.com/containerd/containerd/v2 v2.0.4 github.com/containerd/platforms v1.0.0-rc.1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc diff --git a/go.sum b/go.sum index cd9dfd1d3..d0db0e78f 100644 --- a/go.sum +++ b/go.sum @@ -83,8 +83,8 @@ github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= -github.com/compose-spec/compose-go/v2 v2.4.9 h1:2K4TDw+1ba2idiR6empXHKRXvWYpnvAKoNQy93/sSOs= -github.com/compose-spec/compose-go/v2 v2.4.9/go.mod h1:6k5l/0TxCg0/2uLEhRVEsoBWBprS2uvZi32J7xub3lo= +github.com/compose-spec/compose-go/v2 v2.4.10-0.20250319114556-312596f4c1fe h1:gl5+6pDRe/b8tbqJOXvNOZWNQe4aFLymlMV0iqFp9GI= +github.com/compose-spec/compose-go/v2 v2.4.10-0.20250319114556-312596f4c1fe/go.mod h1:6k5l/0TxCg0/2uLEhRVEsoBWBprS2uvZi32J7xub3lo= github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo= github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 6d59576e8..da14323e9 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -225,7 +225,9 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project, func (c *convergence) stopDependentContainers(ctx context.Context, project *types.Project, service types.ServiceConfig) error { // Stop dependent containers, so they will be restarted after service is re-created - dependents := project.GetDependentsForService(service) + dependents := project.GetDependentsForService(service, func(dependency types.ServiceDependency) bool { + return dependency.Restart + }) if len(dependents) == 0 { return nil } diff --git a/pkg/compose/restart.go b/pkg/compose/restart.go index e18570afc..4de962231 100644 --- a/pkg/compose/restart.go +++ b/pkg/compose/restart.go @@ -77,13 +77,19 @@ func (s *composeService) restart(ctx context.Context, projectName string, option w := progress.ContextWriter(ctx) return InDependencyOrder(ctx, project, func(c context.Context, service string) error { + config := project.Services[service] + err = s.waitDependencies(ctx, project, service, config.DependsOn, containers, 0) + if err != nil { + return err + } + eg, ctx := errgroup.WithContext(ctx) for _, ctr := range containers.filter(isService(service)) { eg.Go(func() error { eventName := getContainerProgressName(ctr) w.Event(progress.RestartingEvent(eventName)) timeout := utils.DurationSecondToInt(options.Timeout) - err := s.apiClient().ContainerRestart(ctx, ctr.ID, container.StopOptions{Timeout: timeout}) + err = s.apiClient().ContainerRestart(ctx, ctr.ID, container.StopOptions{Timeout: timeout}) if err != nil { return err } diff --git a/pkg/e2e/fixtures/restart-test/compose-depends-on.yaml b/pkg/e2e/fixtures/restart-test/compose-depends-on.yaml index d209a4287..250d93f74 100644 --- a/pkg/e2e/fixtures/restart-test/compose-depends-on.yaml +++ b/pkg/e2e/fixtures/restart-test/compose-depends-on.yaml @@ -1,13 +1,13 @@ services: with-restart: - image: alpine + image: nginx:alpine init: true command: tail -f /dev/null depends_on: nginx: {condition: service_healthy, restart: true} no-restart: - image: alpine + image: nginx:alpine init: true command: tail -f /dev/null depends_on: @@ -15,6 +15,8 @@ services: nginx: image: nginx:alpine + labels: + TEST: ${LABEL:-test} healthcheck: test: "echo | nc -w 5 localhost:80" interval: 2s diff --git a/pkg/e2e/restart_test.go b/pkg/e2e/restart_test.go index 2b2a319f8..55e730c64 100644 --- a/pkg/e2e/restart_test.go +++ b/pkg/e2e/restart_test.go @@ -65,7 +65,7 @@ func TestRestart(t *testing.T) { } func TestRestartWithDependencies(t *testing.T) { - c := NewParallelCLI(t, WithEnv( + c := NewCLI(t, WithEnv( "COMPOSE_PROJECT_NAME=e2e-restart-deps", )) baseService := "nginx" @@ -80,9 +80,22 @@ func TestRestartWithDependencies(t *testing.T) { res := c.RunDockerComposeCmd(t, "restart", baseService) out := res.Combined() - assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Started", baseService)), out) + assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Restarting", baseService)), out) + assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Healthy", baseService)), out) assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Started", depWithRestart)), out) assert.Assert(t, !strings.Contains(out, depNoRestart), out) + + c = NewParallelCLI(t, WithEnv( + "COMPOSE_PROJECT_NAME=e2e-restart-deps", + "LABEL=recreate", + )) + res = c.RunDockerComposeCmd(t, "-f", "./fixtures/restart-test/compose-depends-on.yaml", "up", "-d") + out = res.Combined() + assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Stopped", depWithRestart)), out) + assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Recreated", baseService)), out) + assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Healthy", baseService)), out) + assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Started", depWithRestart)), out) + assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Running", depNoRestart)), out) } func TestRestartWithProfiles(t *testing.T) {