Merge pull request #20175 from aaronlehmann/upper-case-hostnames-1.10
Allow uppercase characters in image reference hostname
This commit is contained in:
commit
53a9b1c77b
5 changed files with 17 additions and 10 deletions
|
@ -46,7 +46,7 @@ clone git github.com/boltdb/bolt v1.1.0
|
||||||
clone git github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
|
clone git github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
|
||||||
|
|
||||||
# get graph and distribution packages
|
# get graph and distribution packages
|
||||||
clone git github.com/docker/distribution c301f8ab27f4913c968b8d73a38e5dda79b9d3d7
|
clone git github.com/docker/distribution 0f2d99b13ae0cfbcf118eff103e6e680b726b47e
|
||||||
clone git github.com/vbatts/tar-split v0.9.11
|
clone git github.com/vbatts/tar-split v0.9.11
|
||||||
|
|
||||||
# get desired notary commit, might also need to be updated in Dockerfile
|
# get desired notary commit, might also need to be updated in Dockerfile
|
||||||
|
|
|
@ -30,7 +30,7 @@ func (s *DockerSuite) TestTagUnprefixedRepoByID(c *check.C) {
|
||||||
|
|
||||||
// ensure we don't allow the use of invalid repository names; these tag operations should fail
|
// ensure we don't allow the use of invalid repository names; these tag operations should fail
|
||||||
func (s *DockerSuite) TestTagInvalidUnprefixedRepo(c *check.C) {
|
func (s *DockerSuite) TestTagInvalidUnprefixedRepo(c *check.C) {
|
||||||
invalidRepos := []string{"fo$z$", "Foo@3cc", "Foo$3", "Foo*3", "Fo^3", "Foo!3", "F)xcz(", "fo%asd"}
|
invalidRepos := []string{"fo$z$", "Foo@3cc", "Foo$3", "Foo*3", "Fo^3", "Foo!3", "F)xcz(", "fo%asd", "FOO/bar"}
|
||||||
|
|
||||||
for _, repo := range invalidRepos {
|
for _, repo := range invalidRepos {
|
||||||
out, _, err := dockerCmdWithError("tag", "busybox", repo)
|
out, _, err := dockerCmdWithError("tag", "busybox", repo)
|
||||||
|
@ -57,7 +57,7 @@ func (s *DockerSuite) TestTagValidPrefixedRepo(c *check.C) {
|
||||||
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
|
||||||
}
|
}
|
||||||
|
|
||||||
validRepos := []string{"fooo/bar", "fooaa/test", "foooo:t"}
|
validRepos := []string{"fooo/bar", "fooaa/test", "foooo:t", "HOSTNAME.DOMAIN.COM:443/foo/bar"}
|
||||||
|
|
||||||
for _, repo := range validRepos {
|
for _, repo := range validRepos {
|
||||||
_, _, err := dockerCmdWithError("tag", "busybox:latest", repo)
|
_, _, err := dockerCmdWithError("tag", "busybox:latest", repo)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package reference
|
package reference
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -72,7 +73,10 @@ func ParseNamed(s string) (Named, error) {
|
||||||
// WithName returns a named object representing the given string. If the input
|
// WithName returns a named object representing the given string. If the input
|
||||||
// is invalid ErrReferenceInvalidFormat will be returned.
|
// is invalid ErrReferenceInvalidFormat will be returned.
|
||||||
func WithName(name string) (Named, error) {
|
func WithName(name string) (Named, error) {
|
||||||
name = normalize(name)
|
name, err := normalize(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if err := validateName(name); err != nil {
|
if err := validateName(name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -172,15 +176,18 @@ func splitHostname(name string) (hostname, remoteName string) {
|
||||||
|
|
||||||
// normalize returns a repository name in its normalized form, meaning it
|
// normalize returns a repository name in its normalized form, meaning it
|
||||||
// will not contain default hostname nor library/ prefix for official images.
|
// will not contain default hostname nor library/ prefix for official images.
|
||||||
func normalize(name string) string {
|
func normalize(name string) (string, error) {
|
||||||
host, remoteName := splitHostname(name)
|
host, remoteName := splitHostname(name)
|
||||||
|
if strings.ToLower(remoteName) != remoteName {
|
||||||
|
return "", errors.New("invalid reference format: repository name must be lowercase")
|
||||||
|
}
|
||||||
if host == DefaultHostname {
|
if host == DefaultHostname {
|
||||||
if strings.HasPrefix(remoteName, DefaultRepoPrefix) {
|
if strings.HasPrefix(remoteName, DefaultRepoPrefix) {
|
||||||
return strings.TrimPrefix(remoteName, DefaultRepoPrefix)
|
return strings.TrimPrefix(remoteName, DefaultRepoPrefix), nil
|
||||||
}
|
}
|
||||||
return remoteName
|
return remoteName, nil
|
||||||
}
|
}
|
||||||
return name
|
return name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateName(name string) error {
|
func validateName(name string) error {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// reference := repository [ ":" tag ] [ "@" digest ]
|
// reference := repository [ ":" tag ] [ "@" digest ]
|
||||||
// name := [hostname '/'] component ['/' component]*
|
// name := [hostname '/'] component ['/' component]*
|
||||||
// hostname := hostcomponent ['.' hostcomponent]* [':' port-number]
|
// hostname := hostcomponent ['.' hostcomponent]* [':' port-number]
|
||||||
// hostcomponent := /([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])/
|
// hostcomponent := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
|
||||||
// port-number := /[0-9]+/
|
// port-number := /[0-9]+/
|
||||||
// component := alpha-numeric [separator alpha-numeric]*
|
// component := alpha-numeric [separator alpha-numeric]*
|
||||||
// alpha-numeric := /[a-z0-9]+/
|
// alpha-numeric := /[a-z0-9]+/
|
||||||
|
|
|
@ -22,7 +22,7 @@ var (
|
||||||
// hostnameComponentRegexp restricts the registry hostname component of a
|
// hostnameComponentRegexp restricts the registry hostname component of a
|
||||||
// repository name to start with a component as defined by hostnameRegexp
|
// repository name to start with a component as defined by hostnameRegexp
|
||||||
// and followed by an optional port.
|
// and followed by an optional port.
|
||||||
hostnameComponentRegexp = match(`(?:[a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])`)
|
hostnameComponentRegexp = 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
|
// hostnameRegexp defines the structure of potential hostname components
|
||||||
// that may be part of image names. This is purposely a subset of what is
|
// that may be part of image names. This is purposely a subset of what is
|
||||||
|
|
Loading…
Add table
Reference in a new issue