registry

package module
v0.33.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2024 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Examples

Constants

View Source
const (

	// DefaultImage is the default image used by the Registry container.
	DefaultImage = "registry:2.8.3"
)

Variables

This section is empty.

Functions

func DockerAuthConfig added in v0.33.0

func DockerAuthConfig(host, username, password string, additional ...string) (map[string]dockercfg.AuthConfig, error)

DockerAuthConfig returns a map of AuthConfigs including base64 encoded Auth field for the provided details. It also accepts additional host, username and password triples to add more auth configurations.

func SetDockerAuthConfig added in v0.33.0

func SetDockerAuthConfig(host, username, password string, additional ...string) (func(), error)

SetDockerAuthConfig sets the DOCKER_AUTH_CONFIG environment variable with authentication for the given host, username and password sets. It returns a function to reset the environment back to the previous state.

func WithData

func WithData(dataPath string) testcontainers.CustomizeRequestOption

WithData is a custom option to set the data directory for the registry, which is used to store the images. It will copy the data from the host to the container in the /data path. The container will be configured to use this path as the root directory for the registry, thanks to the REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY environment variable. The dataPath must have the same structure as the registry data directory.

func WithHtpasswd

func WithHtpasswd(credentials string) testcontainers.CustomizeRequestOption

WithHtpasswd is a custom option to set the htpasswd credentials for the registry It will create a temporary file with the credentials and copy it to the container in the /auth/htpasswd path. The container will be configured to use this file as the htpasswd file, thanks to the REGISTRY_AUTH_HTPASSWD_PATH environment variable.

func WithHtpasswdFile

func WithHtpasswdFile(htpasswdPath string) testcontainers.CustomizeRequestOption

WithHtpasswdFile is a custom option to set the htpasswd file for the registry It will copy a file with the credentials in the /auth/htpasswd path. The container will be configured to use this file as the htpasswd file, thanks to the REGISTRY_AUTH_HTPASSWD_PATH environment variable.

Types

type RegistryContainer

type RegistryContainer struct {
	testcontainers.Container
	RegistryName string
}

RegistryContainer represents the Registry container type used in the module

func Run added in v0.32.0

func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*RegistryContainer, error)

Run creates an instance of the Registry container type

Example
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/testcontainers/testcontainers-go/modules/registry"
)

func main() {
	// runRegistryContainer {
	registryContainer, err := registry.Run(context.Background(), "registry:2.8.3")
	if err != nil {
		log.Fatalf("failed to start container: %s", err)
	}

	// Clean up the container
	defer func() {
		if err := registryContainer.Terminate(context.Background()); err != nil {
			log.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
		}
	}()
	// }

	state, err := registryContainer.State(context.Background())
	if err != nil {
		log.Fatalf("failed to get container state: %s", err) // nolint:gocritic
	}

	fmt.Println(state.Running)

}
Output:

true
Example (PushImage)
ctx := context.Background()
registryContainer, err := registry.Run(
	ctx,
	registry.DefaultImage,
	registry.WithHtpasswdFile(filepath.Join("testdata", "auth", "htpasswd")),
	registry.WithData(filepath.Join("testdata", "data")),
)
if err != nil {
	log.Fatalf("failed to start container: %s", err)
}
defer func() {
	if err := registryContainer.Terminate(ctx); err != nil {
		log.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
	}
}()

registryHost, err := registryContainer.HostAddress(ctx)
if err != nil {
	log.Fatalf("failed to get host: %s", err) // nolint:gocritic
}

// Besides, we are also setting the authentication
// for both the registry and localhost to make sure
// the image is pushed to the private registry.
cleanup, err := registry.SetDockerAuthConfig(
	registryHost, "testuser", "testpassword",
	registryContainer.RegistryName, "testuser", "testpassword",
)
if err != nil {
	log.Fatalf("failed to set docker auth config: %s", err) // nolint:gocritic
}
defer cleanup()

// build a custom redis image from the private registry,
// using RegistryName of the container as the registry.
// We are agoing to build the image with a fixed tag
// that matches the private registry, and we are going to
// push it again to the registry after the build.

repo := registryContainer.RegistryName + "/customredis"
tag := "v1.2.3"

redisC, err := testcontainers.GenericContainer(context.Background(), testcontainers.GenericContainerRequest{
	ContainerRequest: testcontainers.ContainerRequest{
		FromDockerfile: testcontainers.FromDockerfile{
			Context: filepath.Join("testdata", "redis"),
			BuildArgs: map[string]*string{
				"REGISTRY_HOST": &registryHost,
			},
			Repo:          repo,
			Tag:           tag,
			PrintBuildLog: true,
		},
		AlwaysPullImage: true, // make sure the authentication takes place
		ExposedPorts:    []string{"6379/tcp"},
		WaitingFor:      wait.ForLog("Ready to accept connections"),
	},
	Started: true,
})
if err != nil {
	log.Fatalf("failed to start container: %s", err) // nolint:gocritic
}
defer func() {
	if err := redisC.Terminate(context.Background()); err != nil {
		log.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
	}
}()

// pushingImage {
// repo is localhost:32878/customredis
// tag is v1.2.3
err = registryContainer.PushImage(context.Background(), fmt.Sprintf("%s:%s", repo, tag))
if err != nil {
	log.Fatalf("failed to push image: %s", err) // nolint:gocritic
}
// }

newImage := fmt.Sprintf("%s:%s", repo, tag)

// now run a container from the new image
// But first remove the local image to avoid using the local one.

// deletingImage {
// newImage is customredis:v1.2.3
err = registryContainer.DeleteImage(context.Background(), newImage)
if err != nil {
	log.Fatalf("failed to delete image: %s", err) // nolint:gocritic
}
// }

newRedisC, err := testcontainers.GenericContainer(context.Background(), testcontainers.GenericContainerRequest{
	ContainerRequest: testcontainers.ContainerRequest{
		Image:        newImage,
		ExposedPorts: []string{"6379/tcp"},
		WaitingFor:   wait.ForLog("Ready to accept connections"),
	},
	Started: true,
})
if err != nil {
	log.Fatalf("failed to start container from %s: %s", newImage, err) // nolint:gocritic
}
defer func() {
	if err := newRedisC.Terminate(context.Background()); err != nil {
		log.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
	}
}()

state, err := newRedisC.State(context.Background())
if err != nil {
	log.Fatalf("failed to get redis container state from %s: %s", newImage, err) // nolint:gocritic
}

fmt.Println(state.Running)
Output:

true
Example (WithAuthentication)
// htpasswdFile {
ctx := context.Background()
registryContainer, err := registry.Run(
	ctx,
	"registry:2.8.3",
	registry.WithHtpasswdFile(filepath.Join("testdata", "auth", "htpasswd")),
	registry.WithData(filepath.Join("testdata", "data")),
)
// }
if err != nil {
	log.Fatalf("failed to start container: %s", err)
}
defer func() {
	if err := registryContainer.Terminate(ctx); err != nil {
		log.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
	}
}()

registryHost, err := registryContainer.HostAddress(ctx)
if err != nil {
	log.Fatalf("failed to get host: %s", err) // nolint:gocritic
}

cleanup, err := registry.SetDockerAuthConfig(registryHost, "testuser", "testpassword")
if err != nil {
	log.Fatalf("failed to set docker auth config: %s", err) // nolint:gocritic
}
defer cleanup()

// build a custom redis image from the private registry,
// using RegistryName of the container as the registry.

redisC, err := testcontainers.GenericContainer(context.Background(), testcontainers.GenericContainerRequest{
	ContainerRequest: testcontainers.ContainerRequest{
		FromDockerfile: testcontainers.FromDockerfile{
			Context: filepath.Join("testdata", "redis"),
			BuildArgs: map[string]*string{
				"REGISTRY_HOST": &registryHost,
			},
			PrintBuildLog: true,
		},
		AlwaysPullImage: true, // make sure the authentication takes place
		ExposedPorts:    []string{"6379/tcp"},
		WaitingFor:      wait.ForLog("Ready to accept connections"),
	},
	Started: true,
})
if err != nil {
	log.Fatalf("failed to start container: %s", err) // nolint:gocritic
}
defer func() {
	if err := redisC.Terminate(context.Background()); err != nil {
		log.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
	}
}()

state, err := redisC.State(context.Background())
if err != nil {
	log.Fatalf("failed to get redis container state: %s", err) // nolint:gocritic
}

fmt.Println(state.Running)
Output:

true

func RunContainer deprecated

func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomizer) (*RegistryContainer, error)

Deprecated: use Run instead RunContainer creates an instance of the Registry container type

func (*RegistryContainer) Address

func (c *RegistryContainer) Address(ctx context.Context) (string, error)

Address returns the address of the Registry container, using the HTTP protocol

func (*RegistryContainer) DeleteImage

func (c *RegistryContainer) DeleteImage(ctx context.Context, imageRef string) error

DeleteImage deletes an image reference from the Registry container. It will use the HTTP endpoint of the Registry container to delete it, doing a HEAD request to get the image digest and then a DELETE request to actually delete the image. E.g. imageRef = "localhost:5000/alpine:latest"

func (*RegistryContainer) HostAddress added in v0.33.0

func (c *RegistryContainer) HostAddress(ctx context.Context) (string, error)

HostAddress returns the host address including port of the Registry container.

func (*RegistryContainer) ImageExists

func (c *RegistryContainer) ImageExists(ctx context.Context, imageRef string) error

ImageExists checks if an image exists in the Registry container. It will use the v2 HTTP endpoint of the Registry container to check if the image reference exists. E.g. imageRef = "localhost:5000/alpine:latest"

func (*RegistryContainer) PushImage

func (c *RegistryContainer) PushImage(ctx context.Context, ref string) error

PushImage pushes an image to the Registry container. It will use the internally stored RegistryName to push the image to the container, and it will finally wait for the image to be pushed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL