Skip to content

Commit

Permalink
feat(ryuk): use an external ryuk
Browse files Browse the repository at this point in the history
  • Loading branch information
romainlaurent committed Oct 3, 2024
1 parent 755f116 commit 5b08390
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 27 deletions.
66 changes: 39 additions & 27 deletions docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,36 @@ func (p *DockerProvider) BuildImage(ctx context.Context, img ImageBuildInfo) (st
return buildOptions.Tags[0], nil
}

func (p *DockerProvider) getTermChan(ctx context.Context, sessionID string) (chan bool, error) {
var (
r *Reaper
err error
)

if p.config.RyukDisabled {
return nil, nil
}

if p.config.RyukExternalAddress != "" {
r = &Reaper{
Endpoint: p.config.RyukExternalAddress,
SessionID: sessionID,
}
} else {
r, err = reuseOrCreateReaper(context.WithValue(ctx, core.DockerHostContextKey, p.host), core.SessionID(), p)
if err != nil {
return nil, fmt.Errorf("%w: creating reaper failed", err)
}
}

termSignal, err := r.Connect()
if err != nil {
return nil, fmt.Errorf("%w: connecting to reaper failed", err)
}

return termSignal, nil
}

// CreateContainer fulfils a request for a container without starting it
func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerRequest) (Container, error) {
var err error
Expand Down Expand Up @@ -1026,14 +1056,10 @@ func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerReque
var termSignal chan bool
// the reaper does not need to start a reaper for itself
isReaperContainer := strings.HasSuffix(imageName, config.ReaperDefaultImage)
if !p.config.RyukDisabled && !isReaperContainer {
r, err := reuseOrCreateReaper(context.WithValue(ctx, core.DockerHostContextKey, p.host), core.SessionID(), p)
if err != nil {
return nil, fmt.Errorf("%w: creating reaper failed", err)
}
termSignal, err = r.Connect()
if !isReaperContainer {
termSignal, err = p.getTermChan(ctx, core.SessionID())
if err != nil {
return nil, fmt.Errorf("%w: connecting to reaper failed", err)
return nil, err
}
}

Expand Down Expand Up @@ -1277,16 +1303,9 @@ func (p *DockerProvider) ReuseOrCreateContainer(ctx context.Context, req Contain

sessionID := core.SessionID()

var termSignal chan bool
if !p.config.RyukDisabled {
r, err := reuseOrCreateReaper(context.WithValue(ctx, core.DockerHostContextKey, p.host), sessionID, p)
if err != nil {
return nil, fmt.Errorf("reaper: %w", err)
}
termSignal, err = r.Connect()
if err != nil {
return nil, fmt.Errorf("%w: connecting to reaper failed", err)
}
termSignal, err := p.getTermChan(ctx, sessionID)
if err != nil {
return nil, err
}

// default hooks include logger hook and pre-create hook
Expand Down Expand Up @@ -1483,16 +1502,9 @@ func (p *DockerProvider) CreateNetwork(ctx context.Context, req NetworkRequest)

sessionID := core.SessionID()

var termSignal chan bool
if !p.config.RyukDisabled {
r, err := reuseOrCreateReaper(context.WithValue(ctx, core.DockerHostContextKey, p.host), sessionID, p)
if err != nil {
return nil, fmt.Errorf("%w: creating network reaper failed", err)
}
termSignal, err = r.Connect()
if err != nil {
return nil, fmt.Errorf("%w: connecting to network reaper failed", err)
}
termSignal, err := p.getTermChan(ctx, sessionID)
if err != nil {
return nil, err
}

// add the labels that the reaper will use to terminate the network to the request
Expand Down
11 changes: 11 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ type Config struct {
// Environment variable: TESTCONTAINERS_RYUK_DISABLED
RyukDisabled bool `properties:"ryuk.disabled,default=false"`

// RyukExternalAddress is the address of the external Garbage Collector container.
// If set, Testcontainers will not attempt to start its own Ryuk container.
//
// Environment variable: TESTCONTAINERS_RYUK_EXTERNAL_ADDRESS
RyukExternalAddress string `properties:"ryuk.external.address,default="`

// RyukPrivileged is a flag to enable or disable the privileged mode for the Garbage Collector container.
// Setting this to true will run the Garbage Collector container in privileged mode.
//
Expand Down Expand Up @@ -116,6 +122,11 @@ func read() Config {
config.RyukDisabled = ryukDisabledEnv == "true"
}

ryukExternalAddress := os.Getenv("TESTCONTAINERS_RYUK_EXTERNAL_ADDRESS")
if ryukExternalAddress != "" {
config.RyukExternalAddress = ryukExternalAddress
}

hubImageNamePrefix := os.Getenv("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX")
if hubImageNamePrefix != "" {
config.HubImageNamePrefix = hubImageNamePrefix
Expand Down

0 comments on commit 5b08390

Please sign in to comment.