Skip to content

Commit

Permalink
feat: support overriding the default recreate options for compose (#2511
Browse files Browse the repository at this point in the history
)

* feat: support overriding the default recreate options for compose

* chore: validate recreation values
  • Loading branch information
mdelapenya committed Apr 22, 2024
1 parent 201b3de commit 39f63ec
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
8 changes: 6 additions & 2 deletions docs/features/docker_compose.md
Expand Up @@ -61,7 +61,9 @@ Use the advanced `NewDockerComposeWith(...)` constructor allowing you to customi

#### Compose Up options

- `RemoveOrphans`: remove orphaned containers after the stack is stopped.
- `Recreate`: recreate the containers. If any other value than `api.RecreateNever`, `api.RecreateForce` or `api.RecreateDiverged` is provided, the default value `api.RecreateForce` will be used.
- `RecreateDependencies`: recreate dependent containers. If any other value than `api.RecreateNever`, `api.RecreateForce` or `api.RecreateDiverged` is provided, the default value `api.RecreateForce` will be used.
- `RemoveOrphans`: remove orphaned containers when the stack is upped.
- `Wait`: will wait until the containers reached the running|healthy state.

#### Compose Down options
Expand All @@ -80,6 +82,8 @@ import (
"testing"

"github.com/stretchr/testify/require"

"github.com/docker/compose/v2/pkg/api"
tc "github.com/testcontainers/testcontainers-go/modules/compose"
)

Expand All @@ -95,7 +99,7 @@ func TestSomethingElse(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)

require.NoError(t, compose.Up(ctx, tc.Wait(true)), "compose.Up()")
require.NoError(t, compose.Up(ctx, tc.WithRecreate(api.RecreateNever), tc.Wait(true)), "compose.Up()")

// do some testing here
}
Expand Down
14 changes: 14 additions & 0 deletions modules/compose/compose.go
Expand Up @@ -93,6 +93,20 @@ type waitService struct {
publishedPort int
}

// WithRecreate defines the strategy to apply on existing containers. If any other value than
// api.RecreateNever, api.RecreateForce or api.RecreateDiverged is provided, the default value
// api.RecreateForce will be used.
func WithRecreate(recreate string) StackUpOption {
return Recreate(recreate)
}

// WithRecreateDependencies defines the strategy to apply on container dependencies. If any other value than
// api.RecreateNever, api.RecreateForce or api.RecreateDiverged is provided, the default value
// api.RecreateForce will be used.
func WithRecreateDependencies(recreate string) StackUpOption {
return RecreateDependencies(recreate)
}

func WithStackFiles(filePaths ...string) ComposeStackOption {
return ComposeStackFiles(filePaths)
}
Expand Down
23 changes: 23 additions & 0 deletions modules/compose/compose_api.go
Expand Up @@ -59,6 +59,29 @@ func (io IgnoreOrphans) applyToStackUp(co *api.CreateOptions, _ *api.StartOption
co.IgnoreOrphans = bool(io)
}

// Recreate will recreate the containers that are already running
type Recreate string

func (r Recreate) applyToStackUp(o *stackUpOptions) {
o.Recreate = validateRecreate(string(r))
}

// RecreateDependencies will recreate the dependencies of the services that are already running
type RecreateDependencies string

func (r RecreateDependencies) applyToStackUp(o *stackUpOptions) {
o.RecreateDependencies = validateRecreate(string(r))
}

func validateRecreate(r string) string {
switch r {
case api.RecreateDiverged, api.RecreateForce, api.RecreateNever:
return r
default:
return api.RecreateForce
}
}

// RemoveOrphans will clean up containers that are not declared on the compose model but own the same labels
type RemoveOrphans bool

Expand Down
17 changes: 17 additions & 0 deletions modules/compose/compose_api_test.go
Expand Up @@ -10,6 +10,7 @@ import (
"testing"
"time"

"github.com/docker/compose/v2/pkg/api"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/volume"
"github.com/google/uuid"
Expand Down Expand Up @@ -563,6 +564,22 @@ func TestDockerComposeAPIWithVolume(t *testing.T) {
require.NoError(t, err, "compose.Up()")
}

func TestDockerComposeAPIWithRecreate(t *testing.T) {
path, _ := RenderComposeComplex(t)
compose, err := NewDockerCompose(path)
require.NoError(t, err, "NewDockerCompose()")

t.Cleanup(func() {
require.NoError(t, compose.Down(context.Background(), RemoveOrphans(true), RemoveImagesLocal), "compose.Down()")
})

ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)

err = compose.Up(ctx, WithRecreate(api.RecreateNever), WithRecreateDependencies(api.RecreateNever), Wait(true))
require.NoError(t, err, "compose.Up()")
}

func TestDockerComposeAPIVolumesDeletedOnDown(t *testing.T) {
path := RenderComposeWithVolume(t)
identifier := uuid.New().String()
Expand Down

0 comments on commit 39f63ec

Please sign in to comment.