Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support Ryuk for the compose module #2485

Merged
merged 19 commits into from
Apr 22, 2024
Merged
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: support removing networks from compose
mdelapenya committed Apr 22, 2024
commit 51539e1b3a133ed4cc385ccd9bb93236c56f101c
4 changes: 4 additions & 0 deletions docker.go
Original file line number Diff line number Diff line change
@@ -851,6 +851,10 @@ func (n *DockerNetwork) Remove(ctx context.Context) error {
return n.provider.client.NetworkRemove(ctx, n.ID)
}

func (n *DockerNetwork) SetTerminationSignal(signal chan bool) {
n.terminationSignal = signal
}

// DockerProvider implements the ContainerProvider interface
type DockerProvider struct {
*DockerProviderOptions
1 change: 1 addition & 0 deletions modules/compose/compose.go
Original file line number Diff line number Diff line change
@@ -149,6 +149,7 @@ func NewDockerComposeWith(opts ...ComposeStackOption) (*dockerCompose, error) {
dockerClient: dockerCli.Client(),
waitStrategies: make(map[string]wait.Strategy),
containers: make(map[string]*testcontainers.DockerContainer),
networks: make(map[string]*testcontainers.DockerNetwork),
sessionID: testcontainers.SessionID(),
reaper: composeReaper,
}
69 changes: 69 additions & 0 deletions modules/compose/compose_api.go
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ import (
"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/cli/cli/command"
"github.com/docker/compose/v2/pkg/api"
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
@@ -134,6 +135,10 @@ type dockerCompose struct {
// used in ServiceContainer(...) function to avoid calls to the Docker API
containers map[string]*testcontainers.DockerContainer

// cache for containers that are part of the stack
// used in ServiceContainer(...) function to avoid calls to the Docker API
networks map[string]*testcontainers.DockerNetwork

// docker/compose API service instance used to control the compose stack
composeService api.Service

@@ -241,6 +246,28 @@ func (d *dockerCompose) Up(ctx context.Context, opts ...StackUpOption) error {
return err
}

err = d.lookupNetworks(ctx)
if err != nil {
return err
}

if d.reaper != nil {
for _, n := range d.networks {
termSignal, err := d.reaper.Connect()
if err != nil {
return fmt.Errorf("failed to connect to reaper: %w", err)
}
n.SetTerminationSignal(termSignal)

// Cleanup on error, otherwise set termSignal to nil before successful return.
defer func() {
if termSignal != nil {
termSignal <- true
}
}()
}
}

errGrpContainers, errGrpCtx := errgroup.WithContext(ctx)

for _, srv := range d.project.Services {
@@ -374,6 +401,34 @@ func (d *dockerCompose) lookupContainer(ctx context.Context, svcName string) (*t
return container, nil
}

func (d *dockerCompose) lookupNetworks(ctx context.Context) error {
d.containersLock.Lock()
defer d.containersLock.Unlock()

listOptions := dockertypes.NetworkListOptions{
Filters: filters.NewArgs(
filters.Arg("label", fmt.Sprintf("%s=%s", api.ProjectLabel, d.name)),
),
}

networks, err := d.dockerClient.NetworkList(ctx, listOptions)
if err != nil {
return err
}

for _, n := range networks {
dn := &testcontainers.DockerNetwork{
ID: n.ID,
Name: n.Name,
Driver: n.Driver,
}

d.networks[n.ID] = dn
}

return nil
}

func (d *dockerCompose) compileProject(ctx context.Context) (*types.Project, error) {
const nameAndDefaultConfigPath = 2
projectOptions := make([]cli.ProjectOptionsFn, len(d.projectOptions), len(d.projectOptions)+nameAndDefaultConfigPath)
@@ -413,6 +468,20 @@ func (d *dockerCompose) compileProject(ctx context.Context) (*types.Project, err
proj.Services[i] = s
}

for key, n := range proj.Networks {
n.Labels = map[string]string{
api.ProjectLabel: proj.Name,
api.NetworkLabel: n.Name,
api.VersionLabel: api.ComposeVersion,
}

for k, label := range testcontainers.GenericLabels() {
n.Labels[k] = label
}

proj.Networks[key] = n
}

return proj, nil
}