moby/distribution
Sebastiaan van Stijn 8aacbb3ba9
api: fix "GET /distribution" endpoint ignoring mirrors
If the daemon is configured to use a mirror for the default (Docker Hub)
registry, the endpoint did not fall back to querying the upstream if the mirror
did not contain the given reference.

If the daemon is configured to use a mirror for the default (Docker Hub)
registry, did not fall back to querying the upstream if the mirror did not
contain the given reference.

For pull-through registry-mirrors, this was not a problem, as in that case the
registry would forward the request, but for other mirrors, no fallback would
happen. This was inconsistent with how "pulling" images handled this situation;
when pulling images, both the mirror and upstream would be tried.

This problem was caused by the logic used in GetRepository, which had an
optimization to only return the first registry it was successfully able to
configure (and connect to), with the assumption that the mirror either contained
all images used, or to be configured as a pull-through mirror.

This patch:

- Introduces a GetRepositories method, which returns all candidates (both
  mirror(s) and upstream).
- Updates the endpoint to try all

Before this patch:

    # the daemon is configured to use a mirror for Docker Hub
    cat /etc/docker/daemon.json
    { "registry-mirrors": ["http://localhost:5000"]}

    # start the mirror (empty registry, not configured as pull-through mirror)
    docker run -d --name registry -p 127.0.0.1:5000:5000 registry:2

    # querying the endpoint fails, because the image-manifest is not found in the mirror:
    curl -s --unix-socket /var/run/docker.sock http://localhost/v1.43/distribution/docker.io/library/hello-world:latest/json
    {
      "message": "manifest unknown: manifest unknown"
    }

With this patch applied:

    # the daemon is configured to use a mirror for Docker Hub
    cat /etc/docker/daemon.json
    { "registry-mirrors": ["http://localhost:5000"]}

    # start the mirror (empty registry, not configured as pull-through mirror)
    docker run -d --name registry -p 127.0.0.1:5000:5000 registry:2

    # querying the endpoint succeeds (manifest is fetched from the upstream Docker Hub registry):
    curl -s --unix-socket /var/run/docker.sock http://localhost/v1.43/distribution/docker.io/library/hello-world:latest/json | jq .
    {
      "Descriptor": {
        "mediaType": "application/vnd.oci.image.index.v1+json",
        "digest": "sha256:1b9844d846ce3a6a6af7013e999a373112c3c0450aca49e155ae444526a2c45e",
        "size": 3849
      },
      "Platforms": [
        {
          "architecture": "amd64",
          "os": "linux"
        }
      ]
    }

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-01-04 15:46:32 +01:00
..
fixtures/validate_manifest Add distribution package 2015-11-24 09:40:24 -08:00
metadata distribution: format code with gofumpt 2023-06-29 00:30:52 +02:00
utils migrate to github.com/containerd/log v0.1.0 2023-10-11 17:52:23 +02:00
xfer migrate to github.com/containerd/log v0.1.0 2023-10-11 17:52:23 +02:00
config.go image: implement CheckOS, deprecate pkg/system IsOSSupported 2023-09-07 22:14:44 +02:00
errors.go migrate to github.com/containerd/log v0.1.0 2023-10-11 17:52:23 +02:00
errors_test.go distribution: un-export internal errors and error-utilities 2022-04-21 22:53:02 +02:00
manifest.go migrate to github.com/containerd/log v0.1.0 2023-10-11 17:52:23 +02:00
manifest_test.go migrate to new github.com/distribution/reference module 2023-09-05 12:09:26 +02:00
pull.go distribution: Add Tags 2023-10-16 14:19:27 +02:00
pull_v2.go distribution: Add Tags 2023-10-16 14:19:27 +02:00
pull_v2_test.go vendor: github.com/docker/distribution v2.8.3 2023-10-11 17:11:25 +02:00
pull_v2_unix.go migrate to github.com/containerd/log v0.1.0 2023-10-11 17:52:23 +02:00
pull_v2_windows.go migrate to github.com/containerd/log v0.1.0 2023-10-11 17:52:23 +02:00
push.go migrate to github.com/containerd/log v0.1.0 2023-10-11 17:52:23 +02:00
push_v2.go migrate to github.com/containerd/log v0.1.0 2023-10-11 17:52:23 +02:00
push_v2_test.go migrate to new github.com/distribution/reference module 2023-09-05 12:09:26 +02:00
registry.go distribution: newRepository: remove naked return and intermediate vars 2023-09-08 15:44:58 +02:00
registry_unit_test.go migrate to github.com/containerd/log v0.1.0 2023-10-11 17:52:23 +02:00
repository.go api: fix "GET /distribution" endpoint ignoring mirrors 2024-01-04 15:46:32 +01:00