From 3cfbac6624af1311a1c06c670da790fe4dab52ca Mon Sep 17 00:00:00 2001 From: Guillaume Lours <705411+glours@users.noreply.github.com> Date: Wed, 1 Mar 2023 17:34:33 +0100 Subject: [PATCH] restart only needed services by checking depends_on relations Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com> --- pkg/compose/compose.go | 8 ++++++- pkg/compose/create.go | 2 +- pkg/compose/restart.go | 5 +++-- .../restart-test/compose-depends-on.yaml | 20 ++++++++++++++++++ pkg/e2e/restart_test.go | 21 +++++++++++++++++++ 5 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 pkg/e2e/fixtures/restart-test/compose-depends-on.yaml diff --git a/pkg/compose/compose.go b/pkg/compose/compose.go index d54f48636..048a4fe09 100644 --- a/pkg/compose/compose.go +++ b/pkg/compose/compose.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "io" + "strconv" "strings" "github.com/compose-spec/compose-go/types" @@ -181,13 +182,18 @@ func (s *composeService) projectFromName(containers Containers, projectName stri for _, dc := range strings.Split(dependencies, ",") { dcArr := strings.Split(dc, ":") condition := ServiceConditionRunningOrHealthy + // Let's restart the dependency by default if we don't have the info stored in the label + restart := true dependency := dcArr[0] // backward compatibility if len(dcArr) > 1 { condition = dcArr[1] + if len(dcArr) > 2 { + restart, _ = strconv.ParseBool(dcArr[2]) + } } - service.DependsOn[dependency] = types.ServiceDependency{Condition: condition} + service.DependsOn[dependency] = types.ServiceDependency{Condition: condition, Restart: restart} } } project.Services = append(project.Services, *service) diff --git a/pkg/compose/create.go b/pkg/compose/create.go index 7c884fe0d..49cd960d5 100644 --- a/pkg/compose/create.go +++ b/pkg/compose/create.go @@ -470,7 +470,7 @@ func (s *composeService) prepareLabels(service types.ServiceConfig, number int) var dependencies []string for s, d := range service.DependsOn { - dependencies = append(dependencies, s+":"+d.Condition) + dependencies = append(dependencies, fmt.Sprintf("%s:%s:%t", s, d.Condition, d.Restart)) } labels[api.DependenciesLabel] = strings.Join(dependencies, ",") return labels, nil diff --git a/pkg/compose/restart.go b/pkg/compose/restart.go index b1dbff9bc..2f41aa6bb 100644 --- a/pkg/compose/restart.go +++ b/pkg/compose/restart.go @@ -20,6 +20,7 @@ import ( "context" "strings" + "github.com/compose-spec/compose-go/types" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/progress" "github.com/docker/compose/v2/pkg/utils" @@ -57,8 +58,8 @@ func (s *composeService) restart(ctx context.Context, projectName string, option project.Services[i] = service } - if len(options.Services) == 0 { - err = project.ForServices(options.Services) + if len(options.Services) != 0 { + err = project.ForServices(options.Services, types.IncludeDependents) 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 new file mode 100644 index 000000000..68228152c --- /dev/null +++ b/pkg/e2e/fixtures/restart-test/compose-depends-on.yaml @@ -0,0 +1,20 @@ +services: + with-restart: + image: alpine + command: tail -f /dev/null + depends_on: + nginx: {condition: service_healthy, restart: true} + + no-restart: + image: alpine + command: tail -f /dev/null + depends_on: + nginx: { condition: service_healthy } + + nginx: + image: nginx:alpine + healthcheck: + test: "echo | nc -w 5 localhost:80" + interval: 2s + timeout: 1s + retries: 10 diff --git a/pkg/e2e/restart_test.go b/pkg/e2e/restart_test.go index 7937785ba..6d00159b8 100644 --- a/pkg/e2e/restart_test.go +++ b/pkg/e2e/restart_test.go @@ -63,3 +63,24 @@ func TestRestart(t *testing.T) { c.RunDockerComposeCmd(t, "--project-name", projectName, "down") }) } + +func TestRestartWithDependencies(t *testing.T) { + c := NewParallelCLI(t, WithEnv( + "COMPOSE_PROJECT_NAME=e2e-restart-deps", + )) + baseService := "nginx" + depWithRestart := "with-restart" + depNoRestart := "no-restart" + + t.Cleanup(func() { + c.RunDockerComposeCmd(t, "down", "--remove-orphans") + }) + + c.RunDockerComposeCmd(t, "-f", "./fixtures/restart-test/compose-depends-on.yaml", "up", "-d") + + res := c.RunDockerComposeCmd(t, "restart", baseService) + fmt.Println(res.Combined()) + assert.Assert(t, strings.Contains(res.Combined(), fmt.Sprintf("Container e2e-restart-deps-%s-1 Started", baseService)), res.Combined()) + assert.Assert(t, strings.Contains(res.Combined(), fmt.Sprintf("Container e2e-restart-deps-%s-1 Started", depWithRestart)), res.Combined()) + assert.Assert(t, !strings.Contains(res.Combined(), depNoRestart), res.Combined()) +}