Kaynağa Gözat

Vendor updated distribution

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Derek McGowan 8 yıl önce
ebeveyn
işleme
3dfb7590a1

+ 1 - 1
vendor.conf

@@ -43,7 +43,7 @@ github.com/boltdb/bolt fff57c100f4dea1905678da7e90d92429dff2904
 github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
 
 # get graph and distribution packages
-github.com/docker/distribution 7dba427612198a11b161a27f9d40bb2dca1ccd20
+github.com/docker/distribution 129ad8ea0c3760d878b34cffdb9c3be874a7b2f7
 github.com/vbatts/tar-split v0.10.1
 github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb
 

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

@@ -10,3 +10,21 @@ func IsNameOnly(ref Named) bool {
 	}
 	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()
+}

+ 147 - 1
vendor/github.com/docker/distribution/reference/normalize.go

@@ -1,9 +1,125 @@
 package reference
 
+import (
+	"errors"
+	"fmt"
+	"strings"
+
+	"github.com/docker/distribution/digestset"
+	"github.com/opencontainers/go-digest"
+)
+
 var (
-	defaultTag = "latest"
+	legacyDefaultDomain = "index.docker.io"
+	defaultDomain       = "docker.io"
+	defaultRepoPrefix   = "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) (NormalizedNamed, 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.(NormalizedNamed)
+	if !isNamed {
+		return nil, fmt.Errorf("reference %s has no name", ref.String())
+	}
+	return 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 = defaultRepoPrefix + 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 = ""
+		repo.path = strings.TrimPrefix(repo.path, defaultRepoPrefix)
+	}
+	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,
+	}
+}
+
 // EnsureTagged adds the default tag "latest" to a reference if it only has
 // a repo name.
 func EnsureTagged(ref Named) NamedTagged {
@@ -20,3 +136,33 @@ func EnsureTagged(ref Named) NamedTagged {
 	}
 	return namedTagged
 }
+
+// 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)
+}

+ 125 - 53
vendor/github.com/docker/distribution/reference/reference.go

@@ -4,11 +4,11 @@
 // Grammar
 //
 // 	reference                       := name [ ":" tag ] [ "@" digest ]
-//	name                            := [hostname '/'] component ['/' component]*
-//	hostname                        := hostcomponent ['.' hostcomponent]* [':' port-number]
-//	hostcomponent                   := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
+//	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]+/
-//	component                       := alpha-numeric [separator alpha-numeric]*
+//	path-component                  := alpha-numeric [separator alpha-numeric]*
 // 	alpha-numeric                   := /[a-z0-9]+/
 //	separator                       := /[_.]|__|[-]*/
 //
@@ -19,6 +19,9 @@
 //	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 (
@@ -126,23 +129,56 @@ type Digested interface {
 }
 
 // Canonical reference is an object with a fully unique
-// name including a name with hostname and digest
+// 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) {
-	name := named.Name()
-	match := anchoredNameRegexp.FindStringSubmatch(name)
-	if len(match) != 3 {
-		return "", name
+	if r, ok := named.(namedRepository); ok {
+		return r.Domain(), r.Path()
 	}
-	return match[1], match[2]
+	return splitDomain(named.Name())
 }
 
 // Parse parses s and returns a syntactically valid Reference.
@@ -164,9 +200,20 @@ func Parse(s string) (Reference, error) {
 		return nil, ErrNameTooLong
 	}
 
+	var repo repository
+
+	nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])
+	if nameMatch != nil && len(nameMatch) == 3 {
+		repo.domain = nameMatch[1]
+		repo.path = nameMatch[2]
+	} else {
+		repo.domain = ""
+		repo.path = matches[1]
+	}
+
 	ref := reference{
-		name: matches[1],
-		tag:  matches[2],
+		namedRepository: repo,
+		tag:             matches[2],
 	}
 	if matches[3] != "" {
 		var err error
@@ -207,10 +254,15 @@ func WithName(name string) (Named, error) {
 	if len(name) > NameTotalLengthMax {
 		return nil, ErrNameTooLong
 	}
-	if !anchoredNameRegexp.MatchString(name) {
+
+	match := anchoredNameRegexp.FindStringSubmatch(name)
+	if match == nil || len(match) != 3 {
 		return nil, ErrReferenceInvalidFormat
 	}
-	return repository(name), nil
+	return repository{
+		domain: match[1],
+		path:   match[2],
+	}, nil
 }
 
 // WithTag combines the name from "name" and the tag from "tag" to form a
@@ -219,16 +271,23 @@ 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{
-			name:   name.Name(),
-			tag:    tag,
-			digest: canonical.Digest(),
+			namedRepository: repo,
+			tag:             tag,
+			digest:          canonical.Digest(),
 		}, nil
 	}
 	return taggedReference{
-		name: name.Name(),
-		tag:  tag,
+		namedRepository: repo,
+		tag:             tag,
 	}, nil
 }
 
@@ -238,16 +297,23 @@ 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{
-			name:   name.Name(),
-			tag:    tagged.Tag(),
-			digest: digest,
+			namedRepository: repo,
+			tag:             tagged.Tag(),
+			digest:          digest,
 		}, nil
 	}
 	return canonicalReference{
-		name:   name.Name(),
-		digest: digest,
+		namedRepository: repo,
+		digest:          digest,
 	}, nil
 }
 
@@ -263,11 +329,15 @@ func Match(pattern string, ref Reference) (bool, error) {
 
 // TrimNamed removes any tag or digest from the named reference.
 func TrimNamed(ref Named) Named {
-	return repository(ref.Name())
+	domain, path := SplitHostname(ref)
+	return repository{
+		domain: domain,
+		path:   path,
+	}
 }
 
 func getBestReferenceType(ref reference) Reference {
-	if ref.name == "" {
+	if ref.Name() == "" {
 		// Allow digest only references
 		if ref.digest != "" {
 			return digestReference(ref.digest)
@@ -277,16 +347,16 @@ func getBestReferenceType(ref reference) Reference {
 	if ref.tag == "" {
 		if ref.digest != "" {
 			return canonicalReference{
-				name:   ref.name,
-				digest: ref.digest,
+				namedRepository: ref.namedRepository,
+				digest:          ref.digest,
 			}
 		}
-		return repository(ref.name)
+		return ref.namedRepository
 	}
 	if ref.digest == "" {
 		return taggedReference{
-			name: ref.name,
-			tag:  ref.tag,
+			namedRepository: ref.namedRepository,
+			tag:             ref.tag,
 		}
 	}
 
@@ -294,17 +364,13 @@ func getBestReferenceType(ref reference) Reference {
 }
 
 type reference struct {
-	name   string
+	namedRepository
 	tag    string
 	digest digest.Digest
 }
 
 func (r reference) String() string {
-	return r.name + ":" + r.tag + "@" + r.digest.String()
-}
-
-func (r reference) Name() string {
-	return r.name
+	return r.Name() + ":" + r.tag + "@" + r.digest.String()
 }
 
 func (r reference) Tag() string {
@@ -315,14 +381,28 @@ func (r reference) Digest() digest.Digest {
 	return r.digest
 }
 
-type repository string
+type repository struct {
+	domain string
+	path   string
+}
 
 func (r repository) String() string {
-	return string(r)
+	return r.Name()
 }
 
 func (r repository) Name() string {
-	return string(r)
+	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
@@ -336,16 +416,12 @@ func (d digestReference) Digest() digest.Digest {
 }
 
 type taggedReference struct {
-	name string
-	tag  string
+	namedRepository
+	tag string
 }
 
 func (t taggedReference) String() string {
-	return t.name + ":" + t.tag
-}
-
-func (t taggedReference) Name() string {
-	return t.name
+	return t.Name() + ":" + t.tag
 }
 
 func (t taggedReference) Tag() string {
@@ -353,16 +429,12 @@ func (t taggedReference) Tag() string {
 }
 
 type canonicalReference struct {
-	name   string
+	namedRepository
 	digest digest.Digest
 }
 
 func (c canonicalReference) String() string {
-	return c.name + "@" + c.digest.String()
-}
-
-func (c canonicalReference) Name() string {
-	return c.name
+	return c.Name() + "@" + c.digest.String()
 }
 
 func (c canonicalReference) Digest() digest.Digest {

+ 30 - 11
vendor/github.com/docker/distribution/reference/regexp.go

@@ -19,18 +19,18 @@ var (
 		alphaNumericRegexp,
 		optional(repeated(separatorRegexp, alphaNumericRegexp)))
 
-	// hostnameComponentRegexp restricts the registry hostname component of a
-	// repository name to start with a component as defined by hostnameRegexp
+	// 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.
-	hostnameComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
+	domainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
 
-	// hostnameRegexp defines the structure of potential hostname components
+	// 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.
-	hostnameRegexp = expression(
-		hostnameComponentRegexp,
-		optional(repeated(literal(`.`), hostnameComponentRegexp)),
+	domainRegexp = expression(
+		domainComponentRegexp,
+		optional(repeated(literal(`.`), domainComponentRegexp)),
 		optional(literal(`:`), match(`[0-9]+`)))
 
 	// TagRegexp matches valid tag names. From docker/docker:graph/tags.go.
@@ -48,17 +48,17 @@ var (
 	anchoredDigestRegexp = anchored(DigestRegexp)
 
 	// NameRegexp is the format for the name component of references. The
-	// regexp has capturing groups for the hostname and name part omitting
+	// regexp has capturing groups for the domain and name part omitting
 	// the separating forward slash from either.
 	NameRegexp = expression(
-		optional(hostnameRegexp, literal(`/`)),
+		optional(domainRegexp, literal(`/`)),
 		nameComponentRegexp,
 		optional(repeated(literal(`/`), nameComponentRegexp)))
 
 	// anchoredNameRegexp is used to parse a name value, capturing the
-	// hostname and trailing components.
+	// domain and trailing components.
 	anchoredNameRegexp = anchored(
-		optional(capture(hostnameRegexp), literal(`/`)),
+		optional(capture(domainRegexp), literal(`/`)),
 		capture(nameComponentRegexp,
 			optional(repeated(literal(`/`), nameComponentRegexp))))
 
@@ -68,6 +68,25 @@ var (
 	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.