Browse Source

vendor: github.com/docker/distribution v2.8.3

- Fix storageDriver gcs not registered in binaries
- reference: replace uses of deprecated function SplitHostname
- Dont parse errors as JSON unless Content-Type is set to JSON
- update to go1.20.8
- Set Content-Type header in registry client ReadFrom
- deprecate reference package, migrate to github.com/distribution/reference
- digestset: deprecate package in favor of go-digest/digestset
- Do not close HTTP request body in HTTP handler

full diff: https://github.com/distribution/distribution/compare/v2.8.2...v2.8.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 1 year ago
parent
commit
e1d0aacb6a
30 changed files with 427 additions and 1104 deletions
  1. 1 2
      distribution/pull_v2_test.go
  2. 1 1
      vendor.mod
  3. 2 2
      vendor.sum
  4. 8 2
      vendor/github.com/docker/distribution/.golangci.yml
  5. 3 0
      vendor/github.com/docker/distribution/.mailmap
  6. 1 1
      vendor/github.com/docker/distribution/BUILDING.md
  7. 4 4
      vendor/github.com/docker/distribution/Dockerfile
  8. 1 1
      vendor/github.com/docker/distribution/Makefile
  9. 1 1
      vendor/github.com/docker/distribution/blobs.go
  10. 0 247
      vendor/github.com/docker/distribution/digestset/set.go
  11. 1 1
      vendor/github.com/docker/distribution/manifest/schema1/config_builder.go
  12. 1 1
      vendor/github.com/docker/distribution/manifest/schema1/reference_builder.go
  13. 0 42
      vendor/github.com/docker/distribution/reference/helpers.go
  14. 34 0
      vendor/github.com/docker/distribution/reference/helpers_deprecated.go
  15. 0 199
      vendor/github.com/docker/distribution/reference/normalize.go
  16. 92 0
      vendor/github.com/docker/distribution/reference/normalize_deprecated.go
  17. 0 433
      vendor/github.com/docker/distribution/reference/reference.go
  18. 172 0
      vendor/github.com/docker/distribution/reference/reference_deprecated.go
  19. 0 143
      vendor/github.com/docker/distribution/reference/regexp.go
  20. 50 0
      vendor/github.com/docker/distribution/reference/regexp_deprecated.go
  21. 10 0
      vendor/github.com/docker/distribution/reference/sort_deprecated.go
  22. 1 1
      vendor/github.com/docker/distribution/registry.go
  23. 1 1
      vendor/github.com/docker/distribution/registry/api/v2/descriptors.go
  24. 1 1
      vendor/github.com/docker/distribution/registry/api/v2/urls.go
  25. 2 0
      vendor/github.com/docker/distribution/registry/client/blob_writer.go
  26. 35 16
      vendor/github.com/docker/distribution/registry/client/errors.go
  27. 1 1
      vendor/github.com/docker/distribution/registry/client/repository.go
  28. 1 1
      vendor/github.com/docker/distribution/registry/storage/cache/memory/memory.go
  29. 2 1
      vendor/github.com/docker/distribution/vendor.conf
  30. 1 2
      vendor/modules.txt

+ 1 - 2
distribution/pull_v2_test.go

@@ -268,10 +268,9 @@ func TestPullSchema2Config(t *testing.T) {
 			name: "unauthorized",
 			handler: func(callCount int, w http.ResponseWriter) {
 				w.WriteHeader(http.StatusUnauthorized)
-				// FIXME: current distribution client does not handle plain-text error-responses, so this response is ignored.
 				_, _ = w.Write([]byte("you need to be authenticated"))
 			},
-			expectError:    "unauthorized: authentication required",
+			expectError:    "unauthorized: you need to be authenticated",
 			expectAttempts: 1,
 		},
 		{

+ 1 - 1
vendor.mod

@@ -35,7 +35,7 @@ require (
 	github.com/creack/pty v1.1.18
 	github.com/deckarep/golang-set/v2 v2.3.0
 	github.com/distribution/reference v0.5.0
-	github.com/docker/distribution v2.8.2+incompatible
+	github.com/docker/distribution v2.8.3+incompatible
 	github.com/docker/go-connections v0.4.0
 	github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c
 	github.com/docker/go-metrics v0.0.1

+ 2 - 2
vendor.sum

@@ -404,8 +404,8 @@ github.com/docker/cli v20.10.0-beta1.0.20201029214301-1d20b15adc38+incompatible/
 github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
 github.com/docker/distribution v2.6.0-rc.1.0.20180327202408-83389a148052+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
-github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
+github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/docker/docker v0.0.0-20200511152416-a93e9eb0e95c/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker v1.4.2-0.20180531152204-71cd53e4a197/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=

+ 8 - 2
vendor/github.com/docker/distribution/.golangci.yml

@@ -1,7 +1,5 @@
 linters:
   enable:
-    - structcheck
-    - varcheck
     - staticcheck
     - unconvert
     - gofmt
@@ -14,6 +12,14 @@ linters:
   disable:
     - errcheck
 
+linters-settings:
+  revive:
+    rules:
+      # TODO(thaJeztah): temporarily disabled the "unused-parameter" check.
+      # It produces many warnings, and some of those may need to be looked at.
+      - name: unused-parameter
+        disabled: true
+
 run:
   deadline: 2m
   skip-dirs:

+ 3 - 0
vendor/github.com/docker/distribution/.mailmap

@@ -49,3 +49,6 @@ Hayley Swimelar <hswimelar@gmail.com>
 Jose D. Gomez R <jose.gomez@suse.com>
 Shengjing Zhu <zhsj@debian.org>
 Silvin Lubecki <31478878+silvin-lubecki@users.noreply.github.com>
+James Hewitt <james.hewitt@gmail.com>
+Marcus Pettersen Irgens <m@mrcus.dev>
+Ben Manuel <bmanuel@users.noreply.github.com>

+ 1 - 1
vendor/github.com/docker/distribution/BUILDING.md

@@ -114,4 +114,4 @@ the registry binary generated in the "./bin" directory:
 ### Optional build tags
 
 Optional [build tags](http://golang.org/pkg/go/build/) can be provided using
-the environment variable `DOCKER_BUILDTAGS`.
+the environment variable `BUILDTAGS`.

+ 4 - 4
vendor/github.com/docker/distribution/Dockerfile

@@ -1,7 +1,7 @@
 # syntax=docker/dockerfile:1
 
-ARG GO_VERSION=1.19.9
-ARG ALPINE_VERSION=3.16
+ARG GO_VERSION=1.20.8
+ARG ALPINE_VERSION=3.18
 ARG XX_VERSION=1.2.1
 
 FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
@@ -22,12 +22,12 @@ RUN --mount=target=. \
 FROM base AS build
 ARG TARGETPLATFORM
 ARG LDFLAGS="-s -w"
-ARG BUILDTAGS="include_oss include_gcs"
+ARG BUILDTAGS="include_oss,include_gcs"
 RUN --mount=type=bind,target=/go/src/github.com/docker/distribution,rw \
     --mount=type=cache,target=/root/.cache/go-build \
     --mount=target=/go/pkg/mod,type=cache \
     --mount=type=bind,source=/tmp/.ldflags,target=/tmp/.ldflags,from=version \
-      set -x ; xx-go build -trimpath -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -o /usr/bin/registry ./cmd/registry \
+      set -x ; xx-go build -tags "${BUILDTAGS}" -trimpath -ldflags "$(cat /tmp/.ldflags) ${LDFLAGS}" -o /usr/bin/registry ./cmd/registry \
       && xx-verify --static /usr/bin/registry
 
 FROM scratch AS binary

+ 1 - 1
vendor/github.com/docker/distribution/Makefile

@@ -50,7 +50,7 @@ version/version.go:
 
 check: ## run all linters (TODO: enable "unused", "varcheck", "ineffassign", "unconvert", "staticheck", "goimports", "structcheck")
 	@echo "$(WHALE) $@"
-	@GO111MODULE=off golangci-lint run
+	@GO111MODULE=off golangci-lint --build-tags "${BUILDTAGS}" run
 
 test: ## run tests, except integration test with test.short
 	@echo "$(WHALE) $@"

+ 1 - 1
vendor/github.com/docker/distribution/blobs.go

@@ -8,7 +8,7 @@ import (
 	"net/http"
 	"time"
 
-	"github.com/docker/distribution/reference"
+	"github.com/distribution/reference"
 	"github.com/opencontainers/go-digest"
 	v1 "github.com/opencontainers/image-spec/specs-go/v1"
 )

+ 0 - 247
vendor/github.com/docker/distribution/digestset/set.go

@@ -1,247 +0,0 @@
-package digestset
-
-import (
-	"errors"
-	"sort"
-	"strings"
-	"sync"
-
-	digest "github.com/opencontainers/go-digest"
-)
-
-var (
-	// ErrDigestNotFound is used when a matching digest
-	// could not be found in a set.
-	ErrDigestNotFound = errors.New("digest not found")
-
-	// ErrDigestAmbiguous is used when multiple digests
-	// are found in a set. None of the matching digests
-	// should be considered valid matches.
-	ErrDigestAmbiguous = errors.New("ambiguous digest string")
-)
-
-// Set is used to hold a unique set of digests which
-// may be easily referenced by easily  referenced by a string
-// representation of the digest as well as short representation.
-// The uniqueness of the short representation is based on other
-// digests in the set. If digests are omitted from this set,
-// collisions in a larger set may not be detected, therefore it
-// is important to always do short representation lookups on
-// the complete set of digests. To mitigate collisions, an
-// appropriately long short code should be used.
-type Set struct {
-	mutex   sync.RWMutex
-	entries digestEntries
-}
-
-// NewSet creates an empty set of digests
-// which may have digests added.
-func NewSet() *Set {
-	return &Set{
-		entries: digestEntries{},
-	}
-}
-
-// checkShortMatch checks whether two digests match as either whole
-// values or short values. This function does not test equality,
-// rather whether the second value could match against the first
-// value.
-func checkShortMatch(alg digest.Algorithm, hex, shortAlg, shortHex string) bool {
-	if len(hex) == len(shortHex) {
-		if hex != shortHex {
-			return false
-		}
-		if len(shortAlg) > 0 && string(alg) != shortAlg {
-			return false
-		}
-	} else if !strings.HasPrefix(hex, shortHex) {
-		return false
-	} else if len(shortAlg) > 0 && string(alg) != shortAlg {
-		return false
-	}
-	return true
-}
-
-// Lookup looks for a digest matching the given string representation.
-// If no digests could be found ErrDigestNotFound will be returned
-// with an empty digest value. If multiple matches are found
-// ErrDigestAmbiguous will be returned with an empty digest value.
-func (dst *Set) Lookup(d string) (digest.Digest, error) {
-	dst.mutex.RLock()
-	defer dst.mutex.RUnlock()
-	if len(dst.entries) == 0 {
-		return "", ErrDigestNotFound
-	}
-	var (
-		searchFunc func(int) bool
-		alg        digest.Algorithm
-		hex        string
-	)
-	dgst, err := digest.Parse(d)
-	if err == digest.ErrDigestInvalidFormat {
-		hex = d
-		searchFunc = func(i int) bool {
-			return dst.entries[i].val >= d
-		}
-	} else {
-		hex = dgst.Hex()
-		alg = dgst.Algorithm()
-		searchFunc = func(i int) bool {
-			if dst.entries[i].val == hex {
-				return dst.entries[i].alg >= alg
-			}
-			return dst.entries[i].val >= hex
-		}
-	}
-	idx := sort.Search(len(dst.entries), searchFunc)
-	if idx == len(dst.entries) || !checkShortMatch(dst.entries[idx].alg, dst.entries[idx].val, string(alg), hex) {
-		return "", ErrDigestNotFound
-	}
-	if dst.entries[idx].alg == alg && dst.entries[idx].val == hex {
-		return dst.entries[idx].digest, nil
-	}
-	if idx+1 < len(dst.entries) && checkShortMatch(dst.entries[idx+1].alg, dst.entries[idx+1].val, string(alg), hex) {
-		return "", ErrDigestAmbiguous
-	}
-
-	return dst.entries[idx].digest, nil
-}
-
-// Add adds the given digest to the set. An error will be returned
-// if the given digest is invalid. If the digest already exists in the
-// set, this operation will be a no-op.
-func (dst *Set) Add(d digest.Digest) error {
-	if err := d.Validate(); err != nil {
-		return err
-	}
-	dst.mutex.Lock()
-	defer dst.mutex.Unlock()
-	entry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d}
-	searchFunc := func(i int) bool {
-		if dst.entries[i].val == entry.val {
-			return dst.entries[i].alg >= entry.alg
-		}
-		return dst.entries[i].val >= entry.val
-	}
-	idx := sort.Search(len(dst.entries), searchFunc)
-	if idx == len(dst.entries) {
-		dst.entries = append(dst.entries, entry)
-		return nil
-	} else if dst.entries[idx].digest == d {
-		return nil
-	}
-
-	entries := append(dst.entries, nil)
-	copy(entries[idx+1:], entries[idx:len(entries)-1])
-	entries[idx] = entry
-	dst.entries = entries
-	return nil
-}
-
-// Remove removes the given digest from the set. An err will be
-// returned if the given digest is invalid. If the digest does
-// not exist in the set, this operation will be a no-op.
-func (dst *Set) Remove(d digest.Digest) error {
-	if err := d.Validate(); err != nil {
-		return err
-	}
-	dst.mutex.Lock()
-	defer dst.mutex.Unlock()
-	entry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d}
-	searchFunc := func(i int) bool {
-		if dst.entries[i].val == entry.val {
-			return dst.entries[i].alg >= entry.alg
-		}
-		return dst.entries[i].val >= entry.val
-	}
-	idx := sort.Search(len(dst.entries), searchFunc)
-	// Not found if idx is after or value at idx is not digest
-	if idx == len(dst.entries) || dst.entries[idx].digest != d {
-		return nil
-	}
-
-	entries := dst.entries
-	copy(entries[idx:], entries[idx+1:])
-	entries = entries[:len(entries)-1]
-	dst.entries = entries
-
-	return nil
-}
-
-// All returns all the digests in the set
-func (dst *Set) All() []digest.Digest {
-	dst.mutex.RLock()
-	defer dst.mutex.RUnlock()
-	retValues := make([]digest.Digest, len(dst.entries))
-	for i := range dst.entries {
-		retValues[i] = dst.entries[i].digest
-	}
-
-	return retValues
-}
-
-// ShortCodeTable returns a map of Digest to unique short codes. The
-// length represents the minimum value, the maximum length may be the
-// entire value of digest if uniqueness cannot be achieved without the
-// full value. This function will attempt to make short codes as short
-// as possible to be unique.
-func ShortCodeTable(dst *Set, length int) map[digest.Digest]string {
-	dst.mutex.RLock()
-	defer dst.mutex.RUnlock()
-	m := make(map[digest.Digest]string, len(dst.entries))
-	l := length
-	resetIdx := 0
-	for i := 0; i < len(dst.entries); i++ {
-		var short string
-		extended := true
-		for extended {
-			extended = false
-			if len(dst.entries[i].val) <= l {
-				short = dst.entries[i].digest.String()
-			} else {
-				short = dst.entries[i].val[:l]
-				for j := i + 1; j < len(dst.entries); j++ {
-					if checkShortMatch(dst.entries[j].alg, dst.entries[j].val, "", short) {
-						if j > resetIdx {
-							resetIdx = j
-						}
-						extended = true
-					} else {
-						break
-					}
-				}
-				if extended {
-					l++
-				}
-			}
-		}
-		m[dst.entries[i].digest] = short
-		if i >= resetIdx {
-			l = length
-		}
-	}
-	return m
-}
-
-type digestEntry struct {
-	alg    digest.Algorithm
-	val    string
-	digest digest.Digest
-}
-
-type digestEntries []*digestEntry
-
-func (d digestEntries) Len() int {
-	return len(d)
-}
-
-func (d digestEntries) Less(i, j int) bool {
-	if d[i].val != d[j].val {
-		return d[i].val < d[j].val
-	}
-	return d[i].alg < d[j].alg
-}
-
-func (d digestEntries) Swap(i, j int) {
-	d[i], d[j] = d[j], d[i]
-}

+ 1 - 1
vendor/github.com/docker/distribution/manifest/schema1/config_builder.go

@@ -8,9 +8,9 @@ import (
 	"fmt"
 	"time"
 
+	"github.com/distribution/reference"
 	"github.com/docker/distribution"
 	"github.com/docker/distribution/manifest"
-	"github.com/docker/distribution/reference"
 	"github.com/docker/libtrust"
 	"github.com/opencontainers/go-digest"
 )

+ 1 - 1
vendor/github.com/docker/distribution/manifest/schema1/reference_builder.go

@@ -5,9 +5,9 @@ import (
 	"errors"
 	"fmt"
 
+	"github.com/distribution/reference"
 	"github.com/docker/distribution"
 	"github.com/docker/distribution/manifest"
-	"github.com/docker/distribution/reference"
 	"github.com/docker/libtrust"
 	"github.com/opencontainers/go-digest"
 )

+ 0 - 42
vendor/github.com/docker/distribution/reference/helpers.go

@@ -1,42 +0,0 @@
-package reference
-
-import "path"
-
-// IsNameOnly returns true if reference only contains a repo name.
-func IsNameOnly(ref Named) bool {
-	if _, ok := ref.(NamedTagged); ok {
-		return false
-	}
-	if _, ok := ref.(Canonical); ok {
-		return false
-	}
-	return true
-}
-
-// FamiliarName returns the familiar name string
-// for the given named, familiarizing if needed.
-func FamiliarName(ref Named) string {
-	if nn, ok := ref.(normalizedNamed); ok {
-		return nn.Familiar().Name()
-	}
-	return ref.Name()
-}
-
-// FamiliarString returns the familiar string representation
-// for the given reference, familiarizing if needed.
-func FamiliarString(ref Reference) string {
-	if nn, ok := ref.(normalizedNamed); ok {
-		return nn.Familiar().String()
-	}
-	return ref.String()
-}
-
-// FamiliarMatch reports whether ref matches the specified pattern.
-// See https://godoc.org/path#Match for supported patterns.
-func FamiliarMatch(pattern string, ref Reference) (bool, error) {
-	matched, err := path.Match(pattern, FamiliarString(ref))
-	if namedRef, isNamed := ref.(Named); isNamed && !matched {
-		matched, _ = path.Match(pattern, FamiliarName(namedRef))
-	}
-	return matched, err
-}

+ 34 - 0
vendor/github.com/docker/distribution/reference/helpers_deprecated.go

@@ -0,0 +1,34 @@
+package reference
+
+import "github.com/distribution/reference"
+
+// IsNameOnly returns true if reference only contains a repo name.
+//
+// Deprecated: use [reference.IsNameOnly].
+func IsNameOnly(ref reference.Named) bool {
+	return reference.IsNameOnly(ref)
+}
+
+// FamiliarName returns the familiar name string
+// for the given named, familiarizing if needed.
+//
+// Deprecated: use [reference.FamiliarName].
+func FamiliarName(ref reference.Named) string {
+	return reference.FamiliarName(ref)
+}
+
+// FamiliarString returns the familiar string representation
+// for the given reference, familiarizing if needed.
+//
+// Deprecated: use [reference.FamiliarString].
+func FamiliarString(ref reference.Reference) string {
+	return reference.FamiliarString(ref)
+}
+
+// FamiliarMatch reports whether ref matches the specified pattern.
+// See [path.Match] for supported patterns.
+//
+// Deprecated: use [reference.FamiliarMatch].
+func FamiliarMatch(pattern string, ref reference.Reference) (bool, error) {
+	return reference.FamiliarMatch(pattern, ref)
+}

+ 0 - 199
vendor/github.com/docker/distribution/reference/normalize.go

@@ -1,199 +0,0 @@
-package reference
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-
-	"github.com/docker/distribution/digestset"
-	"github.com/opencontainers/go-digest"
-)
-
-var (
-	legacyDefaultDomain = "index.docker.io"
-	defaultDomain       = "docker.io"
-	officialRepoName    = "library"
-	defaultTag          = "latest"
-)
-
-// normalizedNamed represents a name which has been
-// normalized and has a familiar form. A familiar name
-// is what is used in Docker UI. An example normalized
-// name is "docker.io/library/ubuntu" and corresponding
-// familiar name of "ubuntu".
-type normalizedNamed interface {
-	Named
-	Familiar() Named
-}
-
-// ParseNormalizedNamed parses a string into a named reference
-// transforming a familiar name from Docker UI to a fully
-// qualified reference. If the value may be an identifier
-// use ParseAnyReference.
-func ParseNormalizedNamed(s string) (Named, error) {
-	if ok := anchoredIdentifierRegexp.MatchString(s); ok {
-		return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s)
-	}
-	domain, remainder := splitDockerDomain(s)
-	var remoteName string
-	if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 {
-		remoteName = remainder[:tagSep]
-	} else {
-		remoteName = remainder
-	}
-	if strings.ToLower(remoteName) != remoteName {
-		return nil, errors.New("invalid reference format: repository name must be lowercase")
-	}
-
-	ref, err := Parse(domain + "/" + remainder)
-	if err != nil {
-		return nil, err
-	}
-	named, isNamed := ref.(Named)
-	if !isNamed {
-		return nil, fmt.Errorf("reference %s has no name", ref.String())
-	}
-	return named, nil
-}
-
-// ParseDockerRef normalizes the image reference following the docker convention. This is added
-// mainly for backward compatibility.
-// The reference returned can only be either tagged or digested. For reference contains both tag
-// and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@
-// sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as
-// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa.
-func ParseDockerRef(ref string) (Named, error) {
-	named, err := ParseNormalizedNamed(ref)
-	if err != nil {
-		return nil, err
-	}
-	if _, ok := named.(NamedTagged); ok {
-		if canonical, ok := named.(Canonical); ok {
-			// The reference is both tagged and digested, only
-			// return digested.
-			newNamed, err := WithName(canonical.Name())
-			if err != nil {
-				return nil, err
-			}
-			newCanonical, err := WithDigest(newNamed, canonical.Digest())
-			if err != nil {
-				return nil, err
-			}
-			return newCanonical, nil
-		}
-	}
-	return TagNameOnly(named), nil
-}
-
-// splitDockerDomain splits a repository name to domain and remotename string.
-// If no valid domain is found, the default domain is used. Repository name
-// needs to be already validated before.
-func splitDockerDomain(name string) (domain, remainder string) {
-	i := strings.IndexRune(name, '/')
-	if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
-		domain, remainder = defaultDomain, name
-	} else {
-		domain, remainder = name[:i], name[i+1:]
-	}
-	if domain == legacyDefaultDomain {
-		domain = defaultDomain
-	}
-	if domain == defaultDomain && !strings.ContainsRune(remainder, '/') {
-		remainder = officialRepoName + "/" + remainder
-	}
-	return
-}
-
-// familiarizeName returns a shortened version of the name familiar
-// to to the Docker UI. Familiar names have the default domain
-// "docker.io" and "library/" repository prefix removed.
-// For example, "docker.io/library/redis" will have the familiar
-// name "redis" and "docker.io/dmcgowan/myapp" will be "dmcgowan/myapp".
-// Returns a familiarized named only reference.
-func familiarizeName(named namedRepository) repository {
-	repo := repository{
-		domain: named.Domain(),
-		path:   named.Path(),
-	}
-
-	if repo.domain == defaultDomain {
-		repo.domain = ""
-		// Handle official repositories which have the pattern "library/<official repo name>"
-		if split := strings.Split(repo.path, "/"); len(split) == 2 && split[0] == officialRepoName {
-			repo.path = split[1]
-		}
-	}
-	return repo
-}
-
-func (r reference) Familiar() Named {
-	return reference{
-		namedRepository: familiarizeName(r.namedRepository),
-		tag:             r.tag,
-		digest:          r.digest,
-	}
-}
-
-func (r repository) Familiar() Named {
-	return familiarizeName(r)
-}
-
-func (t taggedReference) Familiar() Named {
-	return taggedReference{
-		namedRepository: familiarizeName(t.namedRepository),
-		tag:             t.tag,
-	}
-}
-
-func (c canonicalReference) Familiar() Named {
-	return canonicalReference{
-		namedRepository: familiarizeName(c.namedRepository),
-		digest:          c.digest,
-	}
-}
-
-// TagNameOnly adds the default tag "latest" to a reference if it only has
-// a repo name.
-func TagNameOnly(ref Named) Named {
-	if IsNameOnly(ref) {
-		namedTagged, err := WithTag(ref, defaultTag)
-		if err != nil {
-			// Default tag must be valid, to create a NamedTagged
-			// type with non-validated input the WithTag function
-			// should be used instead
-			panic(err)
-		}
-		return namedTagged
-	}
-	return ref
-}
-
-// ParseAnyReference parses a reference string as a possible identifier,
-// full digest, or familiar name.
-func ParseAnyReference(ref string) (Reference, error) {
-	if ok := anchoredIdentifierRegexp.MatchString(ref); ok {
-		return digestReference("sha256:" + ref), nil
-	}
-	if dgst, err := digest.Parse(ref); err == nil {
-		return digestReference(dgst), nil
-	}
-
-	return ParseNormalizedNamed(ref)
-}
-
-// ParseAnyReferenceWithSet parses a reference string as a possible short
-// identifier to be matched in a digest set, a full digest, or familiar name.
-func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) {
-	if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok {
-		dgst, err := ds.Lookup(ref)
-		if err == nil {
-			return digestReference(dgst), nil
-		}
-	} else {
-		if dgst, err := digest.Parse(ref); err == nil {
-			return digestReference(dgst), nil
-		}
-	}
-
-	return ParseNormalizedNamed(ref)
-}

+ 92 - 0
vendor/github.com/docker/distribution/reference/normalize_deprecated.go

@@ -0,0 +1,92 @@
+package reference
+
+import (
+	"regexp"
+
+	"github.com/distribution/reference"
+	"github.com/opencontainers/go-digest"
+	"github.com/opencontainers/go-digest/digestset"
+)
+
+// ParseNormalizedNamed parses a string into a named reference
+// transforming a familiar name from Docker UI to a fully
+// qualified reference. If the value may be an identifier
+// use ParseAnyReference.
+//
+// Deprecated: use [reference.ParseNormalizedNamed].
+func ParseNormalizedNamed(s string) (reference.Named, error) {
+	return reference.ParseNormalizedNamed(s)
+}
+
+// ParseDockerRef normalizes the image reference following the docker convention,
+// which allows for references to contain both a tag and a digest.
+//
+// Deprecated: use [reference.ParseDockerRef].
+func ParseDockerRef(ref string) (reference.Named, error) {
+	return reference.ParseDockerRef(ref)
+}
+
+// TagNameOnly adds the default tag "latest" to a reference if it only has
+// a repo name.
+//
+// Deprecated: use [reference.TagNameOnly].
+func TagNameOnly(ref reference.Named) reference.Named {
+	return reference.TagNameOnly(ref)
+}
+
+// ParseAnyReference parses a reference string as a possible identifier,
+// full digest, or familiar name.
+//
+// Deprecated: use [reference.ParseAnyReference].
+func ParseAnyReference(ref string) (reference.Reference, error) {
+	return reference.ParseAnyReference(ref)
+}
+
+// Functions and types below have been removed in distribution v3 and
+// have not been ported to github.com/distribution/reference. See
+// https://github.com/distribution/distribution/pull/3774
+
+var (
+	// ShortIdentifierRegexp is the format used to represent a prefix
+	// of an identifier. A prefix may be used to match a sha256 identifier
+	// within a list of trusted identifiers.
+	//
+	// Deprecated: support for short-identifiers is deprecated, and will be removed in v3.
+	ShortIdentifierRegexp = regexp.MustCompile(shortIdentifier)
+
+	shortIdentifier = `([a-f0-9]{6,64})`
+
+	// anchoredShortIdentifierRegexp is used to check if a value
+	// is a possible identifier prefix, anchored at start and end
+	// of string.
+	anchoredShortIdentifierRegexp = regexp.MustCompile(`^` + shortIdentifier + `$`)
+)
+
+type digestReference digest.Digest
+
+func (d digestReference) String() string {
+	return digest.Digest(d).String()
+}
+
+func (d digestReference) Digest() digest.Digest {
+	return digest.Digest(d)
+}
+
+// ParseAnyReferenceWithSet parses a reference string as a possible short
+// identifier to be matched in a digest set, a full digest, or familiar name.
+//
+// Deprecated: support for short-identifiers is deprecated, and will be removed in v3.
+func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) {
+	if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok {
+		dgst, err := ds.Lookup(ref)
+		if err == nil {
+			return digestReference(dgst), nil
+		}
+	} else {
+		if dgst, err := digest.Parse(ref); err == nil {
+			return digestReference(dgst), nil
+		}
+	}
+
+	return reference.ParseNormalizedNamed(ref)
+}

+ 0 - 433
vendor/github.com/docker/distribution/reference/reference.go

@@ -1,433 +0,0 @@
-// Package reference provides a general type to represent any way of referencing images within the registry.
-// Its main purpose is to abstract tags and digests (content-addressable hash).
-//
-// Grammar
-//
-//	reference                       := name [ ":" tag ] [ "@" digest ]
-//	name                            := [domain '/'] path-component ['/' path-component]*
-//	domain                          := domain-component ['.' domain-component]* [':' port-number]
-//	domain-component                := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
-//	port-number                     := /[0-9]+/
-//	path-component                  := alpha-numeric [separator alpha-numeric]*
-//	alpha-numeric                   := /[a-z0-9]+/
-//	separator                       := /[_.]|__|[-]*/
-//
-//	tag                             := /[\w][\w.-]{0,127}/
-//
-//	digest                          := digest-algorithm ":" digest-hex
-//	digest-algorithm                := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*
-//	digest-algorithm-separator      := /[+.-_]/
-//	digest-algorithm-component      := /[A-Za-z][A-Za-z0-9]*/
-//	digest-hex                      := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
-//
-//	identifier                      := /[a-f0-9]{64}/
-//	short-identifier                := /[a-f0-9]{6,64}/
-package reference
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-
-	"github.com/opencontainers/go-digest"
-)
-
-const (
-	// NameTotalLengthMax is the maximum total number of characters in a repository name.
-	NameTotalLengthMax = 255
-)
-
-var (
-	// ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.
-	ErrReferenceInvalidFormat = errors.New("invalid reference format")
-
-	// ErrTagInvalidFormat represents an error while trying to parse a string as a tag.
-	ErrTagInvalidFormat = errors.New("invalid tag format")
-
-	// ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.
-	ErrDigestInvalidFormat = errors.New("invalid digest format")
-
-	// ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters.
-	ErrNameContainsUppercase = errors.New("repository name must be lowercase")
-
-	// ErrNameEmpty is returned for empty, invalid repository names.
-	ErrNameEmpty = errors.New("repository name must have at least one component")
-
-	// ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.
-	ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", NameTotalLengthMax)
-
-	// ErrNameNotCanonical is returned when a name is not canonical.
-	ErrNameNotCanonical = errors.New("repository name must be canonical")
-)
-
-// Reference is an opaque object reference identifier that may include
-// modifiers such as a hostname, name, tag, and digest.
-type Reference interface {
-	// String returns the full reference
-	String() string
-}
-
-// Field provides a wrapper type for resolving correct reference types when
-// working with encoding.
-type Field struct {
-	reference Reference
-}
-
-// AsField wraps a reference in a Field for encoding.
-func AsField(reference Reference) Field {
-	return Field{reference}
-}
-
-// Reference unwraps the reference type from the field to
-// return the Reference object. This object should be
-// of the appropriate type to further check for different
-// reference types.
-func (f Field) Reference() Reference {
-	return f.reference
-}
-
-// MarshalText serializes the field to byte text which
-// is the string of the reference.
-func (f Field) MarshalText() (p []byte, err error) {
-	return []byte(f.reference.String()), nil
-}
-
-// UnmarshalText parses text bytes by invoking the
-// reference parser to ensure the appropriately
-// typed reference object is wrapped by field.
-func (f *Field) UnmarshalText(p []byte) error {
-	r, err := Parse(string(p))
-	if err != nil {
-		return err
-	}
-
-	f.reference = r
-	return nil
-}
-
-// Named is an object with a full name
-type Named interface {
-	Reference
-	Name() string
-}
-
-// Tagged is an object which has a tag
-type Tagged interface {
-	Reference
-	Tag() string
-}
-
-// NamedTagged is an object including a name and tag.
-type NamedTagged interface {
-	Named
-	Tag() string
-}
-
-// Digested is an object which has a digest
-// in which it can be referenced by
-type Digested interface {
-	Reference
-	Digest() digest.Digest
-}
-
-// Canonical reference is an object with a fully unique
-// name including a name with domain and digest
-type Canonical interface {
-	Named
-	Digest() digest.Digest
-}
-
-// namedRepository is a reference to a repository with a name.
-// A namedRepository has both domain and path components.
-type namedRepository interface {
-	Named
-	Domain() string
-	Path() string
-}
-
-// Domain returns the domain part of the Named reference
-func Domain(named Named) string {
-	if r, ok := named.(namedRepository); ok {
-		return r.Domain()
-	}
-	domain, _ := splitDomain(named.Name())
-	return domain
-}
-
-// Path returns the name without the domain part of the Named reference
-func Path(named Named) (name string) {
-	if r, ok := named.(namedRepository); ok {
-		return r.Path()
-	}
-	_, path := splitDomain(named.Name())
-	return path
-}
-
-func splitDomain(name string) (string, string) {
-	match := anchoredNameRegexp.FindStringSubmatch(name)
-	if len(match) != 3 {
-		return "", name
-	}
-	return match[1], match[2]
-}
-
-// SplitHostname splits a named reference into a
-// hostname and name string. If no valid hostname is
-// found, the hostname is empty and the full value
-// is returned as name
-// DEPRECATED: Use Domain or Path
-func SplitHostname(named Named) (string, string) {
-	if r, ok := named.(namedRepository); ok {
-		return r.Domain(), r.Path()
-	}
-	return splitDomain(named.Name())
-}
-
-// Parse parses s and returns a syntactically valid Reference.
-// If an error was encountered it is returned, along with a nil Reference.
-// NOTE: Parse will not handle short digests.
-func Parse(s string) (Reference, error) {
-	matches := ReferenceRegexp.FindStringSubmatch(s)
-	if matches == nil {
-		if s == "" {
-			return nil, ErrNameEmpty
-		}
-		if ReferenceRegexp.FindStringSubmatch(strings.ToLower(s)) != nil {
-			return nil, ErrNameContainsUppercase
-		}
-		return nil, ErrReferenceInvalidFormat
-	}
-
-	if len(matches[1]) > NameTotalLengthMax {
-		return nil, ErrNameTooLong
-	}
-
-	var repo repository
-
-	nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])
-	if len(nameMatch) == 3 {
-		repo.domain = nameMatch[1]
-		repo.path = nameMatch[2]
-	} else {
-		repo.domain = ""
-		repo.path = matches[1]
-	}
-
-	ref := reference{
-		namedRepository: repo,
-		tag:             matches[2],
-	}
-	if matches[3] != "" {
-		var err error
-		ref.digest, err = digest.Parse(matches[3])
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	r := getBestReferenceType(ref)
-	if r == nil {
-		return nil, ErrNameEmpty
-	}
-
-	return r, nil
-}
-
-// ParseNamed parses s and returns a syntactically valid reference implementing
-// the Named interface. The reference must have a name and be in the canonical
-// form, otherwise an error is returned.
-// If an error was encountered it is returned, along with a nil Reference.
-// NOTE: ParseNamed will not handle short digests.
-func ParseNamed(s string) (Named, error) {
-	named, err := ParseNormalizedNamed(s)
-	if err != nil {
-		return nil, err
-	}
-	if named.String() != s {
-		return nil, ErrNameNotCanonical
-	}
-	return named, nil
-}
-
-// WithName returns a named object representing the given string. If the input
-// is invalid ErrReferenceInvalidFormat will be returned.
-func WithName(name string) (Named, error) {
-	if len(name) > NameTotalLengthMax {
-		return nil, ErrNameTooLong
-	}
-
-	match := anchoredNameRegexp.FindStringSubmatch(name)
-	if match == nil || len(match) != 3 {
-		return nil, ErrReferenceInvalidFormat
-	}
-	return repository{
-		domain: match[1],
-		path:   match[2],
-	}, nil
-}
-
-// WithTag combines the name from "name" and the tag from "tag" to form a
-// reference incorporating both the name and the tag.
-func WithTag(name Named, tag string) (NamedTagged, error) {
-	if !anchoredTagRegexp.MatchString(tag) {
-		return nil, ErrTagInvalidFormat
-	}
-	var repo repository
-	if r, ok := name.(namedRepository); ok {
-		repo.domain = r.Domain()
-		repo.path = r.Path()
-	} else {
-		repo.path = name.Name()
-	}
-	if canonical, ok := name.(Canonical); ok {
-		return reference{
-			namedRepository: repo,
-			tag:             tag,
-			digest:          canonical.Digest(),
-		}, nil
-	}
-	return taggedReference{
-		namedRepository: repo,
-		tag:             tag,
-	}, nil
-}
-
-// WithDigest combines the name from "name" and the digest from "digest" to form
-// a reference incorporating both the name and the digest.
-func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
-	if !anchoredDigestRegexp.MatchString(digest.String()) {
-		return nil, ErrDigestInvalidFormat
-	}
-	var repo repository
-	if r, ok := name.(namedRepository); ok {
-		repo.domain = r.Domain()
-		repo.path = r.Path()
-	} else {
-		repo.path = name.Name()
-	}
-	if tagged, ok := name.(Tagged); ok {
-		return reference{
-			namedRepository: repo,
-			tag:             tagged.Tag(),
-			digest:          digest,
-		}, nil
-	}
-	return canonicalReference{
-		namedRepository: repo,
-		digest:          digest,
-	}, nil
-}
-
-// TrimNamed removes any tag or digest from the named reference.
-func TrimNamed(ref Named) Named {
-	domain, path := SplitHostname(ref)
-	return repository{
-		domain: domain,
-		path:   path,
-	}
-}
-
-func getBestReferenceType(ref reference) Reference {
-	if ref.Name() == "" {
-		// Allow digest only references
-		if ref.digest != "" {
-			return digestReference(ref.digest)
-		}
-		return nil
-	}
-	if ref.tag == "" {
-		if ref.digest != "" {
-			return canonicalReference{
-				namedRepository: ref.namedRepository,
-				digest:          ref.digest,
-			}
-		}
-		return ref.namedRepository
-	}
-	if ref.digest == "" {
-		return taggedReference{
-			namedRepository: ref.namedRepository,
-			tag:             ref.tag,
-		}
-	}
-
-	return ref
-}
-
-type reference struct {
-	namedRepository
-	tag    string
-	digest digest.Digest
-}
-
-func (r reference) String() string {
-	return r.Name() + ":" + r.tag + "@" + r.digest.String()
-}
-
-func (r reference) Tag() string {
-	return r.tag
-}
-
-func (r reference) Digest() digest.Digest {
-	return r.digest
-}
-
-type repository struct {
-	domain string
-	path   string
-}
-
-func (r repository) String() string {
-	return r.Name()
-}
-
-func (r repository) Name() string {
-	if r.domain == "" {
-		return r.path
-	}
-	return r.domain + "/" + r.path
-}
-
-func (r repository) Domain() string {
-	return r.domain
-}
-
-func (r repository) Path() string {
-	return r.path
-}
-
-type digestReference digest.Digest
-
-func (d digestReference) String() string {
-	return digest.Digest(d).String()
-}
-
-func (d digestReference) Digest() digest.Digest {
-	return digest.Digest(d)
-}
-
-type taggedReference struct {
-	namedRepository
-	tag string
-}
-
-func (t taggedReference) String() string {
-	return t.Name() + ":" + t.tag
-}
-
-func (t taggedReference) Tag() string {
-	return t.tag
-}
-
-type canonicalReference struct {
-	namedRepository
-	digest digest.Digest
-}
-
-func (c canonicalReference) String() string {
-	return c.Name() + "@" + c.digest.String()
-}
-
-func (c canonicalReference) Digest() digest.Digest {
-	return c.digest
-}

+ 172 - 0
vendor/github.com/docker/distribution/reference/reference_deprecated.go

@@ -0,0 +1,172 @@
+// Package reference is deprecated, and has moved to github.com/distribution/reference.
+//
+// Deprecated: use github.com/distribution/reference instead.
+package reference
+
+import (
+	"github.com/distribution/reference"
+	"github.com/opencontainers/go-digest"
+)
+
+const (
+	// NameTotalLengthMax is the maximum total number of characters in a repository name.
+	//
+	// Deprecated: use [reference.NameTotalLengthMax].
+	NameTotalLengthMax = reference.NameTotalLengthMax
+)
+
+var (
+	// ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.
+	//
+	// Deprecated: use [reference.ErrReferenceInvalidFormat].
+	ErrReferenceInvalidFormat = reference.ErrReferenceInvalidFormat
+
+	// ErrTagInvalidFormat represents an error while trying to parse a string as a tag.
+	//
+	// Deprecated: use [reference.ErrTagInvalidFormat].
+	ErrTagInvalidFormat = reference.ErrTagInvalidFormat
+
+	// ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.
+	//
+	// Deprecated: use [reference.ErrDigestInvalidFormat].
+	ErrDigestInvalidFormat = reference.ErrDigestInvalidFormat
+
+	// ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters.
+	//
+	// Deprecated: use [reference.ErrNameContainsUppercase].
+	ErrNameContainsUppercase = reference.ErrNameContainsUppercase
+
+	// ErrNameEmpty is returned for empty, invalid repository names.
+	//
+	// Deprecated: use [reference.ErrNameEmpty].
+	ErrNameEmpty = reference.ErrNameEmpty
+
+	// ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.
+	//
+	// Deprecated: use [reference.ErrNameTooLong].
+	ErrNameTooLong = reference.ErrNameTooLong
+
+	// ErrNameNotCanonical is returned when a name is not canonical.
+	//
+	// Deprecated: use [reference.ErrNameNotCanonical].
+	ErrNameNotCanonical = reference.ErrNameNotCanonical
+)
+
+// Reference is an opaque object reference identifier that may include
+// modifiers such as a hostname, name, tag, and digest.
+//
+// Deprecated: use [reference.Reference].
+type Reference = reference.Reference
+
+// Field provides a wrapper type for resolving correct reference types when
+// working with encoding.
+//
+// Deprecated: use [reference.Field].
+type Field = reference.Field
+
+// AsField wraps a reference in a Field for encoding.
+//
+// Deprecated: use [reference.AsField].
+func AsField(ref reference.Reference) reference.Field {
+	return reference.AsField(ref)
+}
+
+// Named is an object with a full name
+//
+// Deprecated: use [reference.Named].
+type Named = reference.Named
+
+// Tagged is an object which has a tag
+//
+// Deprecated: use [reference.Tagged].
+type Tagged = reference.Tagged
+
+// NamedTagged is an object including a name and tag.
+//
+// Deprecated: use [reference.NamedTagged].
+type NamedTagged reference.NamedTagged
+
+// Digested is an object which has a digest
+// in which it can be referenced by
+//
+// Deprecated: use [reference.Digested].
+type Digested reference.Digested
+
+// Canonical reference is an object with a fully unique
+// name including a name with domain and digest
+//
+// Deprecated: use [reference.Canonical].
+type Canonical reference.Canonical
+
+// Domain returns the domain part of the [Named] reference.
+//
+// Deprecated: use [reference.Domain].
+func Domain(named reference.Named) string {
+	return reference.Domain(named)
+}
+
+// Path returns the name without the domain part of the [Named] reference.
+//
+// Deprecated: use [reference.Path].
+func Path(named reference.Named) (name string) {
+	return reference.Path(named)
+}
+
+// SplitHostname splits a named reference into a
+// hostname and name string. If no valid hostname is
+// found, the hostname is empty and the full value
+// is returned as name
+//
+// Deprecated: Use [reference.Domain] or [reference.Path].
+func SplitHostname(named reference.Named) (string, string) {
+	return reference.SplitHostname(named)
+}
+
+// Parse parses s and returns a syntactically valid Reference.
+// If an error was encountered it is returned, along with a nil Reference.
+//
+// Deprecated: use [reference.Parse].
+func Parse(s string) (reference.Reference, error) {
+	return reference.Parse(s)
+}
+
+// ParseNamed parses s and returns a syntactically valid reference implementing
+// the Named interface. The reference must have a name and be in the canonical
+// form, otherwise an error is returned.
+// If an error was encountered it is returned, along with a nil Reference.
+//
+// Deprecated: use [reference.ParseNamed].
+func ParseNamed(s string) (reference.Named, error) {
+	return reference.ParseNamed(s)
+}
+
+// WithName returns a named object representing the given string. If the input
+// is invalid ErrReferenceInvalidFormat will be returned.
+//
+// Deprecated: use [reference.WithName].
+func WithName(name string) (reference.Named, error) {
+	return reference.WithName(name)
+}
+
+// WithTag combines the name from "name" and the tag from "tag" to form a
+// reference incorporating both the name and the tag.
+//
+// Deprecated: use [reference.WithTag].
+func WithTag(name reference.Named, tag string) (reference.NamedTagged, error) {
+	return reference.WithTag(name, tag)
+}
+
+// WithDigest combines the name from "name" and the digest from "digest" to form
+// a reference incorporating both the name and the digest.
+//
+// Deprecated: use [reference.WithDigest].
+func WithDigest(name reference.Named, digest digest.Digest) (reference.Canonical, error) {
+	return reference.WithDigest(name, digest)
+}
+
+// TrimNamed removes any tag or digest from the named reference.
+//
+// Deprecated: use [reference.TrimNamed].
+func TrimNamed(ref reference.Named) reference.Named {
+	return reference.TrimNamed(ref)
+}

+ 0 - 143
vendor/github.com/docker/distribution/reference/regexp.go

@@ -1,143 +0,0 @@
-package reference
-
-import "regexp"
-
-var (
-	// alphaNumericRegexp defines the alpha numeric atom, typically a
-	// component of names. This only allows lower case characters and digits.
-	alphaNumericRegexp = match(`[a-z0-9]+`)
-
-	// separatorRegexp defines the separators allowed to be embedded in name
-	// components. This allow one period, one or two underscore and multiple
-	// dashes.
-	separatorRegexp = match(`(?:[._]|__|[-]*)`)
-
-	// nameComponentRegexp restricts registry path component names to start
-	// with at least one letter or number, with following parts able to be
-	// separated by one period, one or two underscore and multiple dashes.
-	nameComponentRegexp = expression(
-		alphaNumericRegexp,
-		optional(repeated(separatorRegexp, alphaNumericRegexp)))
-
-	// domainComponentRegexp restricts the registry domain component of a
-	// repository name to start with a component as defined by DomainRegexp
-	// and followed by an optional port.
-	domainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
-
-	// DomainRegexp defines the structure of potential domain components
-	// that may be part of image names. This is purposely a subset of what is
-	// allowed by DNS to ensure backwards compatibility with Docker image
-	// names.
-	DomainRegexp = expression(
-		domainComponentRegexp,
-		optional(repeated(literal(`.`), domainComponentRegexp)),
-		optional(literal(`:`), match(`[0-9]+`)))
-
-	// TagRegexp matches valid tag names. From docker/docker:graph/tags.go.
-	TagRegexp = match(`[\w][\w.-]{0,127}`)
-
-	// anchoredTagRegexp matches valid tag names, anchored at the start and
-	// end of the matched string.
-	anchoredTagRegexp = anchored(TagRegexp)
-
-	// DigestRegexp matches valid digests.
-	DigestRegexp = match(`[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`)
-
-	// anchoredDigestRegexp matches valid digests, anchored at the start and
-	// end of the matched string.
-	anchoredDigestRegexp = anchored(DigestRegexp)
-
-	// NameRegexp is the format for the name component of references. The
-	// regexp has capturing groups for the domain and name part omitting
-	// the separating forward slash from either.
-	NameRegexp = expression(
-		optional(DomainRegexp, literal(`/`)),
-		nameComponentRegexp,
-		optional(repeated(literal(`/`), nameComponentRegexp)))
-
-	// anchoredNameRegexp is used to parse a name value, capturing the
-	// domain and trailing components.
-	anchoredNameRegexp = anchored(
-		optional(capture(DomainRegexp), literal(`/`)),
-		capture(nameComponentRegexp,
-			optional(repeated(literal(`/`), nameComponentRegexp))))
-
-	// ReferenceRegexp is the full supported format of a reference. The regexp
-	// is anchored and has capturing groups for name, tag, and digest
-	// components.
-	ReferenceRegexp = anchored(capture(NameRegexp),
-		optional(literal(":"), capture(TagRegexp)),
-		optional(literal("@"), capture(DigestRegexp)))
-
-	// IdentifierRegexp is the format for string identifier used as a
-	// content addressable identifier using sha256. These identifiers
-	// are like digests without the algorithm, since sha256 is used.
-	IdentifierRegexp = match(`([a-f0-9]{64})`)
-
-	// ShortIdentifierRegexp is the format used to represent a prefix
-	// of an identifier. A prefix may be used to match a sha256 identifier
-	// within a list of trusted identifiers.
-	ShortIdentifierRegexp = match(`([a-f0-9]{6,64})`)
-
-	// anchoredIdentifierRegexp is used to check or match an
-	// identifier value, anchored at start and end of string.
-	anchoredIdentifierRegexp = anchored(IdentifierRegexp)
-
-	// anchoredShortIdentifierRegexp is used to check if a value
-	// is a possible identifier prefix, anchored at start and end
-	// of string.
-	anchoredShortIdentifierRegexp = anchored(ShortIdentifierRegexp)
-)
-
-// match compiles the string to a regular expression.
-var match = regexp.MustCompile
-
-// literal compiles s into a literal regular expression, escaping any regexp
-// reserved characters.
-func literal(s string) *regexp.Regexp {
-	re := match(regexp.QuoteMeta(s))
-
-	if _, complete := re.LiteralPrefix(); !complete {
-		panic("must be a literal")
-	}
-
-	return re
-}
-
-// expression defines a full expression, where each regular expression must
-// follow the previous.
-func expression(res ...*regexp.Regexp) *regexp.Regexp {
-	var s string
-	for _, re := range res {
-		s += re.String()
-	}
-
-	return match(s)
-}
-
-// optional wraps the expression in a non-capturing group and makes the
-// production optional.
-func optional(res ...*regexp.Regexp) *regexp.Regexp {
-	return match(group(expression(res...)).String() + `?`)
-}
-
-// repeated wraps the regexp in a non-capturing group to get one or more
-// matches.
-func repeated(res ...*regexp.Regexp) *regexp.Regexp {
-	return match(group(expression(res...)).String() + `+`)
-}
-
-// group wraps the regexp in a non-capturing group.
-func group(res ...*regexp.Regexp) *regexp.Regexp {
-	return match(`(?:` + expression(res...).String() + `)`)
-}
-
-// capture wraps the expression in a capturing group.
-func capture(res ...*regexp.Regexp) *regexp.Regexp {
-	return match(`(` + expression(res...).String() + `)`)
-}
-
-// anchored anchors the regular expression by adding start and end delimiters.
-func anchored(res ...*regexp.Regexp) *regexp.Regexp {
-	return match(`^` + expression(res...).String() + `$`)
-}

+ 50 - 0
vendor/github.com/docker/distribution/reference/regexp_deprecated.go

@@ -0,0 +1,50 @@
+package reference
+
+import (
+	"github.com/distribution/reference"
+)
+
+// DigestRegexp matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
+//
+// Deprecated: use [reference.DigestRegexp].
+var DigestRegexp = reference.DigestRegexp
+
+// DomainRegexp matches hostname or IP-addresses, optionally including a port
+// number. It defines the structure of potential domain components that may be
+// part of image names. This is purposely a subset of what is allowed by DNS to
+// ensure backwards compatibility with Docker image names. It may be a subset of
+// DNS domain name, an IPv4 address in decimal format, or an IPv6 address between
+// square brackets (excluding zone identifiers as defined by [RFC 6874] or special
+// addresses such as IPv4-Mapped).
+//
+// Deprecated: use [reference.DomainRegexp].
+//
+// [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874.
+var DomainRegexp = reference.DigestRegexp
+
+// IdentifierRegexp is the format for string identifier used as a
+// content addressable identifier using sha256. These identifiers
+// are like digests without the algorithm, since sha256 is used.
+//
+// Deprecated: use [reference.IdentifierRegexp].
+var IdentifierRegexp = reference.IdentifierRegexp
+
+// NameRegexp is the format for the name component of references, including
+// an optional domain and port, but without tag or digest suffix.
+//
+// Deprecated: use [reference.NameRegexp].
+var NameRegexp = reference.NameRegexp
+
+// ReferenceRegexp is the full supported format of a reference. The regexp
+// is anchored and has capturing groups for name, tag, and digest
+// components.
+//
+// Deprecated: use [reference.ReferenceRegexp].
+var ReferenceRegexp = reference.ReferenceRegexp
+
+// TagRegexp matches valid tag names. From [docker/docker:graph/tags.go].
+//
+// Deprecated: use [reference.TagRegexp].
+//
+// [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28
+var TagRegexp = reference.TagRegexp

+ 10 - 0
vendor/github.com/docker/distribution/reference/sort_deprecated.go

@@ -0,0 +1,10 @@
+package reference
+
+import "github.com/distribution/reference"
+
+// Sort sorts string references preferring higher information references.
+//
+// Deprecated: use [reference.Sort].
+func Sort(references []string) []string {
+	return reference.Sort(references)
+}

+ 1 - 1
vendor/github.com/docker/distribution/registry.go

@@ -3,7 +3,7 @@ package distribution
 import (
 	"context"
 
-	"github.com/docker/distribution/reference"
+	"github.com/distribution/reference"
 )
 
 // Scope defines the set of items that match a namespace.

+ 1 - 1
vendor/github.com/docker/distribution/registry/api/v2/descriptors.go

@@ -4,7 +4,7 @@ import (
 	"net/http"
 	"regexp"
 
-	"github.com/docker/distribution/reference"
+	"github.com/distribution/reference"
 	"github.com/docker/distribution/registry/api/errcode"
 	"github.com/opencontainers/go-digest"
 )

+ 1 - 1
vendor/github.com/docker/distribution/registry/api/v2/urls.go

@@ -6,7 +6,7 @@ import (
 	"net/url"
 	"strings"
 
-	"github.com/docker/distribution/reference"
+	"github.com/distribution/reference"
 	"github.com/gorilla/mux"
 )
 

+ 2 - 0
vendor/github.com/docker/distribution/registry/client/blob_writer.go

@@ -42,6 +42,8 @@ func (hbu *httpBlobUpload) ReadFrom(r io.Reader) (n int64, err error) {
 	}
 	defer req.Body.Close()
 
+	req.Header.Set("Content-Type", "application/octet-stream")
+
 	resp, err := hbu.client.Do(req)
 	if err != nil {
 		return 0, err

+ 35 - 16
vendor/github.com/docker/distribution/registry/client/errors.go

@@ -4,8 +4,8 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"io"
 	"io/ioutil"
+	"mime"
 	"net/http"
 
 	"github.com/docker/distribution/registry/api/errcode"
@@ -38,13 +38,29 @@ func (e *UnexpectedHTTPResponseError) Error() string {
 	return fmt.Sprintf("error parsing HTTP %d response body: %s: %q", e.StatusCode, e.ParseErr.Error(), string(e.Response))
 }
 
-func parseHTTPErrorResponse(statusCode int, r io.Reader) error {
+func parseHTTPErrorResponse(resp *http.Response) error {
 	var errors errcode.Errors
-	body, err := ioutil.ReadAll(r)
+	body, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
 		return err
 	}
 
+	statusCode := resp.StatusCode
+	ctHeader := resp.Header.Get("Content-Type")
+
+	if ctHeader == "" {
+		return makeError(statusCode, string(body))
+	}
+
+	contentType, _, err := mime.ParseMediaType(ctHeader)
+	if err != nil {
+		return fmt.Errorf("failed parsing content-type: %w", err)
+	}
+
+	if contentType != "application/json" && contentType != "application/vnd.api+json" {
+		return makeError(statusCode, string(body))
+	}
+
 	// For backward compatibility, handle irregularly formatted
 	// messages that contain a "details" field.
 	var detailsErr struct {
@@ -52,16 +68,7 @@ func parseHTTPErrorResponse(statusCode int, r io.Reader) error {
 	}
 	err = json.Unmarshal(body, &detailsErr)
 	if err == nil && detailsErr.Details != "" {
-		switch statusCode {
-		case http.StatusUnauthorized:
-			return errcode.ErrorCodeUnauthorized.WithMessage(detailsErr.Details)
-		case http.StatusForbidden:
-			return errcode.ErrorCodeDenied.WithMessage(detailsErr.Details)
-		case http.StatusTooManyRequests:
-			return errcode.ErrorCodeTooManyRequests.WithMessage(detailsErr.Details)
-		default:
-			return errcode.ErrorCodeUnknown.WithMessage(detailsErr.Details)
-		}
+		return makeError(statusCode, detailsErr.Details)
 	}
 
 	if err := json.Unmarshal(body, &errors); err != nil {
@@ -85,6 +92,19 @@ func parseHTTPErrorResponse(statusCode int, r io.Reader) error {
 	return errors
 }
 
+func makeError(statusCode int, details string) error {
+	switch statusCode {
+	case http.StatusUnauthorized:
+		return errcode.ErrorCodeUnauthorized.WithMessage(details)
+	case http.StatusForbidden:
+		return errcode.ErrorCodeDenied.WithMessage(details)
+	case http.StatusTooManyRequests:
+		return errcode.ErrorCodeTooManyRequests.WithMessage(details)
+	default:
+		return errcode.ErrorCodeUnknown.WithMessage(details)
+	}
+}
+
 func makeErrorList(err error) []error {
 	if errL, ok := err.(errcode.Errors); ok {
 		return []error(errL)
@@ -121,11 +141,10 @@ func HandleErrorResponse(resp *http.Response) error {
 				} else {
 					err.Message = err.Code.Message()
 				}
-
-				return mergeErrors(err, parseHTTPErrorResponse(resp.StatusCode, resp.Body))
+				return mergeErrors(err, parseHTTPErrorResponse(resp))
 			}
 		}
-		err := parseHTTPErrorResponse(resp.StatusCode, resp.Body)
+		err := parseHTTPErrorResponse(resp)
 		if uErr, ok := err.(*UnexpectedHTTPResponseError); ok && resp.StatusCode == 401 {
 			return errcode.ErrorCodeUnauthorized.WithDetail(uErr.Response)
 		}

+ 1 - 1
vendor/github.com/docker/distribution/registry/client/repository.go

@@ -14,8 +14,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/distribution/reference"
 	"github.com/docker/distribution"
-	"github.com/docker/distribution/reference"
 	v2 "github.com/docker/distribution/registry/api/v2"
 	"github.com/docker/distribution/registry/client/transport"
 	"github.com/docker/distribution/registry/storage/cache"

+ 1 - 1
vendor/github.com/docker/distribution/registry/storage/cache/memory/memory.go

@@ -4,8 +4,8 @@ import (
 	"context"
 	"sync"
 
+	"github.com/distribution/reference"
 	"github.com/docker/distribution"
-	"github.com/docker/distribution/reference"
 	"github.com/docker/distribution/registry/storage/cache"
 	"github.com/opencontainers/go-digest"
 )

+ 2 - 1
vendor/github.com/docker/distribution/vendor.conf

@@ -9,6 +9,7 @@ github.com/bugsnag/osext 0dd3f918b21bec95ace9dc86c7e70266cfc5c702
 github.com/bugsnag/panicwrap e2c28503fcd0675329da73bf48b33404db873782
 github.com/denverdino/aliyungo afedced274aa9a7fcdd47ac97018f0f8db4e5de2
 github.com/dgrijalva/jwt-go 4bbdd8ac624fc7a9ef7aec841c43d99b5fe65a29 https://github.com/golang-jwt/jwt.git # v3.2.2
+github.com/distribution/reference 49c28499d219290c3226822e9cfcd4ede6d75379 # v0.5.0
 github.com/docker/go-metrics 399ea8c73916000c64c2c76e8da00ca82f8387ab
 github.com/docker/libtrust fa567046d9b14f6aa788882a950d69651d230b21
 github.com/garyburd/redigo 535138d7bcd717d6531c701ef5933d98b1866257
@@ -47,5 +48,5 @@ gopkg.in/check.v1 64131543e7896d5bcc6bd5a76287eb75ea96c673
 gopkg.in/square/go-jose.v1 40d457b439244b546f023d056628e5184136899b
 gopkg.in/yaml.v2 v2.2.1
 rsc.io/letsencrypt e770c10b0f1a64775ae91d240407ce00d1a5bdeb https://github.com/dmcgowan/letsencrypt.git
-github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb
+github.com/opencontainers/go-digest ea51bea511f75cfa3ef6098cc253c5c3609b037a # v1.0.0
 github.com/opencontainers/image-spec 67d2d5658fe0476ab9bf414cec164077ebff3920 # v1.0.2

+ 1 - 2
vendor/modules.txt

@@ -421,10 +421,9 @@ github.com/dimchansky/utfbom
 # github.com/distribution/reference v0.5.0
 ## explicit; go 1.20
 github.com/distribution/reference
-# github.com/docker/distribution v2.8.2+incompatible
+# github.com/docker/distribution v2.8.3+incompatible
 ## explicit
 github.com/docker/distribution
-github.com/docker/distribution/digestset
 github.com/docker/distribution/manifest
 github.com/docker/distribution/manifest/manifestlist
 github.com/docker/distribution/manifest/ocischema