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: Auth config for build images #602

27 changes: 17 additions & 10 deletions container.go
Expand Up @@ -65,21 +65,23 @@ type Container interface {

// ImageBuildInfo defines what is needed to build an image
type ImageBuildInfo interface {
GetContext() (io.Reader, error) // the path to the build context
GetDockerfile() string // the relative path to the Dockerfile, including the fileitself
ShouldPrintBuildLog() bool // allow build log to be printed to stdout
ShouldBuildImage() bool // return true if the image needs to be built
GetBuildArgs() map[string]*string // return the environment args used to build the from Dockerfile
GetContext() (io.Reader, error) // the path to the build context
GetDockerfile() string // the relative path to the Dockerfile, including the fileitself
ShouldPrintBuildLog() bool // allow build log to be printed to stdout
ShouldBuildImage() bool // return true if the image needs to be built
GetBuildArgs() map[string]*string // return the environment args used to build the from Dockerfile
GetAuthConfigs() map[string]types.AuthConfig // return the auth configs to be able to pull from an authenticated docker registry
}

// FromDockerfile represents the parameters needed to build an image from a Dockerfile
// rather than using a pre-built one
type FromDockerfile struct {
Context string // the path to the context of of the docker build
ContextArchive io.Reader // the tar archive file to send to docker that contains the build context
Dockerfile string // the path from the context to the Dockerfile for the image, defaults to "Dockerfile"
BuildArgs map[string]*string // enable user to pass build args to docker daemon
PrintBuildLog bool // enable user to print build log
Context string // the path to the context of of the docker build
ContextArchive io.Reader // the tar archive file to send to docker that contains the build context
Dockerfile string // the path from the context to the Dockerfile for the image, defaults to "Dockerfile"
BuildArgs map[string]*string // enable user to pass build args to docker daemon
PrintBuildLog bool // enable user to print build log
AuthConfigs map[string]types.AuthConfig // enable auth configs to be able to pull from an authenticated docker registry
}

type ContainerFile struct {
Expand Down Expand Up @@ -230,6 +232,11 @@ func (c *ContainerRequest) GetDockerfile() string {
return f
}

// GetAuthConfigs returns the auth configs to be able to pull from an authenticated docker registry
func (c *ContainerRequest) GetAuthConfigs() map[string]types.AuthConfig {
return c.FromDockerfile.AuthConfigs
}

func (c *ContainerRequest) ShouldBuildImage() bool {
return c.FromDockerfile.Context != "" || c.FromDockerfile.ContextArchive != nil
}
Expand Down
45 changes: 45 additions & 0 deletions container_test.go
Expand Up @@ -12,6 +12,7 @@ import (
"testing"
"time"

"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"

"github.com/testcontainers/testcontainers-go/wait"
Expand Down Expand Up @@ -127,6 +128,50 @@ func Test_GetDockerfile(t *testing.T) {
}
}

func Test_GetAuthConfigs(t *testing.T) {
paulozenida marked this conversation as resolved.
Show resolved Hide resolved
type TestCase struct {
name string
ExpectedAuthConfigs map[string]types.AuthConfig
ContainerRequest ContainerRequest
}

testTable := []TestCase{
{
name: "defaults to no auth",
ExpectedAuthConfigs: nil,
ContainerRequest: ContainerRequest{
FromDockerfile: FromDockerfile{},
},
},
{
name: "will specify credentials",
ExpectedAuthConfigs: map[string]types.AuthConfig{
"https://myregistry.com/": {
Username: "username",
Password: "password",
},
},
ContainerRequest: ContainerRequest{
FromDockerfile: FromDockerfile{
AuthConfigs: map[string]types.AuthConfig{
"https://myregistry.com/": {
Username: "username",
Password: "password",
},
},
},
},
},
}

for _, testCase := range testTable {
t.Run(testCase.name, func(t *testing.T) {
cfgs := testCase.ContainerRequest.GetAuthConfigs()
assert.Equal(t, testCase.ExpectedAuthConfigs, cfgs)
})
}
}

func Test_BuildImageWithContexts(t *testing.T) {
type TestCase struct {
Name string
Expand Down
1 change: 1 addition & 0 deletions docker.go
Expand Up @@ -879,6 +879,7 @@ func (p *DockerProvider) BuildImage(ctx context.Context, img ImageBuildInfo) (st
buildOptions := types.ImageBuildOptions{
BuildArgs: img.GetBuildArgs(),
Dockerfile: img.GetDockerfile(),
AuthConfigs: img.GetAuthConfigs(),
Context: buildContext,
Tags: []string{repoTag},
Remove: true,
Expand Down
21 changes: 21 additions & 0 deletions docs/features/build_from_dockerfile.md
Expand Up @@ -60,3 +60,24 @@ fromDockerfile := testcontainers.FromDockerfile{

**Please Note** if you specify a `ContextArchive` this will cause Testcontainers-go to ignore the path passed
in to `Context`.

## Images requiring auth

If you are building a local Docker image that is fetched from a Docker image in a registry requiring authentication
(e.g., assuming you are fetching from a custom registry such as `myregistry.com`), you will need to specify the
credentials to succeed, as follows:

```go
req := ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: "/path/to/build/context",
Dockerfile: "CustomDockerfile",
AuthConfigs: map[string]types.AuthConfig{
"https://myregistry.com": {
Username: "myusername",
Password: "mypassword",
},
},
},
}
```