Skip to content

Commit

Permalink
feat: add distribution-registry module (#2341)
Browse files Browse the repository at this point in the history
* feat: bootstrap registry module

* chore: add options and tests for the module

* feat: support for pushing images to the registry

* feat: support for waiting for response headers

* feat: support deleting images from the registry

* docs: include ImageExists in the docs

* chore: bump ryuk to latest (#2395)

* feat: support passing io.Reader as ContainerFile (#2401)

* chore: run mod tidy

* feat: support passing a reader to the ContainerFile struct

* chore: fix lint

* chore(deps): bump github.com/docker/docker from 25.0.3+incompatible to 25.0.5+incompatible (#2444)

* chore(deps): bump github.com/docker/docker in /modules/mongodb

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/openldap

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/consul

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/nats

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/cassandra

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/mssql

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/neo4j

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/cockroachdb

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/weaviate

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /examples/nginx

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /examples/toxiproxy

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/elasticsearch

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/artemis

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/postgres

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/localstack

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/opensearch

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/minio

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/kafka

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/clickhouse

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/mariadb

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/pulsar

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/ollama

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/rabbitmq

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/surrealdb

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/redis

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/redpanda

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/qdrant

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/openfga

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/mysql

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/mockserver

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/k6

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/vault

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/gcloud

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/chroma

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/couchbase

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/k3s

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/compose

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.4-0.20240301160236-51e876cd964c+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/commits/v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker in /modules/milvus

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.3+incompatible to 25.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v25.0.3...v25.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump github.com/docker/docker from 25.0.3+incompatible to 25.0.5+incompatible in /modules/inbucket

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): Bumping ChromaGo client version (#2402)

* chore: Bumping ChromaGo client version

* feat: Added GetClient utility method

- Updated/Added a few examples

* feat: Added GetClient utility method

- Updated/Added a few examples
- Updated docs

* fix: Fixing docs built

* fix: Removing GetClient from ChromaContainer

* chore: mod tidy

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Trayan Azarov <tazarov@users.noreply.github.com>
  • Loading branch information
3 people committed Mar 22, 2024
1 parent 0866c3f commit 09648d1
Show file tree
Hide file tree
Showing 33 changed files with 1,276 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
matrix:
go-version: [1.21.x, 1.x]
platform: [ubuntu-latest]
module: [artemis, cassandra, chroma, clickhouse, cockroachdb, compose, consul, couchbase, elasticsearch, gcloud, inbucket, k3s, k6, kafka, localstack, mariadb, milvus, minio, mockserver, mongodb, mssql, mysql, nats, neo4j, ollama, openfga, openldap, opensearch, postgres, pulsar, qdrant, rabbitmq, redis, redpanda, surrealdb, vault, weaviate]
module: [artemis, cassandra, chroma, clickhouse, cockroachdb, compose, consul, couchbase, elasticsearch, gcloud, inbucket, k3s, k6, kafka, localstack, mariadb, milvus, minio, mockserver, mongodb, mssql, mysql, nats, neo4j, ollama, openfga, openldap, opensearch, postgres, pulsar, qdrant, rabbitmq, redis, redpanda, registry, surrealdb, vault, weaviate]
uses: ./.github/workflows/ci-test-go.yml
with:
go-version: ${{ matrix.go-version }}
Expand Down
4 changes: 4 additions & 0 deletions .vscode/.testcontainers-go.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@
"name": "module / redpanda",
"path": "../modules/redpanda"
},
{
"name": "module / registry",
"path": "../modules/registry"
},
{
"name": "module / surrealdb",
"path": "../modules/surrealdb"
Expand Down
113 changes: 113 additions & 0 deletions docs/modules/registry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Registry

Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

## Introduction

The Testcontainers module for Registry.

## Adding this module to your project dependencies

Please run the following command to add the Registry module to your Go dependencies:

```
go get github.com/testcontainers/testcontainers-go/modules/registry
```

## Usage example

<!--codeinclude-->
[Creating a Registry container](../../modules/registry/examples_test.go) inside_block:runRegistryContainer
<!--/codeinclude-->

## Module reference

The Registry module exposes one entrypoint function to create the Registry container, and this function receives two parameters:

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

- `context.Context`, the Go context.
- `testcontainers.ContainerCustomizer`, a variadic argument for passing options.

### Container Options

When starting the Registry container, you can pass options in a variadic way to configure it.

#### Image

If you need to set a different Registry Docker image, you can use `testcontainers.WithImage` with a valid Docker image
for Registry. E.g. `testcontainers.WithImage("registry:2.8.3")`.

{% include "../features/common_functional_options.md" %}

#### With Authentication

It's possible to enable authentication for the Registry container. By default, it is disabled, but you can enable it in two ways:
- You can use `WithHtpasswd` to enable authentication with a string representing the contents of a `htpasswd` file.
A temporary file will be created with the contents of the string and copied to the container.
- You can use `WithHtpasswdFile` to copy a `htpasswd` file from your local filesystem to the container.
In both cases, the `htpasswd` file will be copied into the `/auth` directory inside the container.
<!--codeinclude-->
[Htpasswd string](../../modules/registry/registry_test.go) inside_block:htpasswdString
[Htpasswd file](../../modules/registry/examples_test.go) inside_block:htpasswdFile
<!--/codeinclude-->
#### WithData
In the case you want to initialise the Registry with your own images, you can use `WithData` to copy a directory from your local filesystem to the container.
The directory will be copied into the `/data` directory inside the container.
The format of the directory should be the same as the one used by the Registry to store images.
Otherwise, the Registry will start but you won't be able to read any images from it.

<!--codeinclude-->
[Including data](../../modules/registry/examples_test.go) inside_block:htpasswdFile
<!--/codeinclude-->

### Container Methods

The Registry container exposes the following methods:

#### Address

This method returns the HTTP address string to connect to the Distribution Registry, so that you can use to connect to the Registry.
E.g. `http://localhost:32878/v2/_catalog`.

<!--codeinclude-->
[HTTP Address](../../modules/registry/registry_test.go) inside_block:httpAddress
<!--/codeinclude-->

#### ImageExists

The `ImageExists` method allows to check if an image exists in the Registry. It receives the Go context and the image reference as parameters.

!!! info
The image reference should be in the format `my-registry:port/image:tag` in order to be pushed to the Registry.

#### PushImage

The `PushImage` method allows to push an image to the Registry. It receives the Go context and the image reference as parameters.

!!! info
The image reference should be in the format `my-registry:port/image:tag` in order to be pushed to the Registry.

<!--codeinclude-->
[Pushing images to the registry](../../modules/registry/examples_test.go) inside_block:pushingImage
<!--/codeinclude-->

If the push operation is successful, the method will internally wait for the image to be available in the Registry, querying the Registry API, returning an error in case of any failure (e.g. pushing or waiting for the image).

#### DeleteImage

The `DeleteImage` method allows to delete an image from the Registry. It receives the Go context and the image reference as parameters.

!!! info
The image reference should be in the format `image:tag` in order to be deleted from the Registry.

<!--codeinclude-->
[Deleting images from the registry](../../modules/registry/examples_test.go) inside_block:deletingImage
<!--/codeinclude-->
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ nav:
- modules/rabbitmq.md
- modules/redis.md
- modules/redpanda.md
- modules/registry.md
- modules/surrealdb.md
- modules/vault.md
- modules/weaviate.md
Expand Down
5 changes: 5 additions & 0 deletions modules/registry/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include ../../commons-test.mk

.PHONY: test
test:
$(MAKE) test-registry
246 changes: 246 additions & 0 deletions modules/registry/examples_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
package registry_test

import (
"context"
"fmt"
"log"
"os"
"path/filepath"

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

func ExampleRunContainer() {
// runRegistryContainer {
registryContainer, err := registry.RunContainer(context.Background(), testcontainers.WithImage("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
}

func ExampleRunContainer_withAuthentication() {
// htpasswdFile {
registryContainer, err := registry.RunContainer(
context.Background(),
testcontainers.WithImage("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(context.Background()); err != nil {
log.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
}
}()

registryPort, err := registryContainer.MappedPort(context.Background(), "5000/tcp")
if err != nil {
log.Fatalf("failed to get mapped port: %s", err) // nolint:gocritic
}
strPort := registryPort.Port()

previousAuthConfig := os.Getenv("DOCKER_AUTH_CONFIG")

// make sure the Docker Auth credentials are set
// using the same as in the Docker Registry
// testuser:testpassword
os.Setenv("DOCKER_AUTH_CONFIG", `{
"auths": {
"localhost:`+strPort+`": { "username": "testuser", "password": "testpassword", "auth": "dGVzdHVzZXI6dGVzdHBhc3N3b3Jk" }
},
"credsStore": "desktop"
}`)
defer func() {
// reset the original state after the example.
os.Unsetenv("DOCKER_AUTH_CONFIG")
os.Setenv("DOCKER_AUTH_CONFIG", previousAuthConfig)
}()

// 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_PORT": &strPort,
},
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 ExampleRunContainer_pushImage() {
registryContainer, err := registry.RunContainer(
context.Background(),
testcontainers.WithImage("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(context.Background()); err != nil {
log.Fatalf("failed to terminate container: %s", err) // nolint:gocritic
}
}()

registryPort, err := registryContainer.MappedPort(context.Background(), "5000/tcp")
if err != nil {
log.Fatalf("failed to get mapped port: %s", err) // nolint:gocritic
}
strPort := registryPort.Port()

previousAuthConfig := os.Getenv("DOCKER_AUTH_CONFIG")

// make sure the Docker Auth credentials are set
// using the same as in the Docker Registry
// testuser:testpassword
// Besides, we are also setting the authentication
// for both the registry and localhost to make sure
// the image is pushed to the private registry.
os.Setenv("DOCKER_AUTH_CONFIG", `{
"auths": {
"localhost:`+strPort+`": { "username": "testuser", "password": "testpassword", "auth": "dGVzdHVzZXI6dGVzdHBhc3N3b3Jk" },
"`+registryContainer.RegistryName+`": { "username": "testuser", "password": "testpassword", "auth": "dGVzdHVzZXI6dGVzdHBhc3N3b3Jk" }
},
"credsStore": "desktop"
}`)
defer func() {
// reset the original state after the example.
os.Unsetenv("DOCKER_AUTH_CONFIG")
os.Setenv("DOCKER_AUTH_CONFIG", previousAuthConfig)
}()

// 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_PORT": &strPort,
},
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
}

0 comments on commit 09648d1

Please sign in to comment.