diff --git a/daemon/cluster/cluster.go b/daemon/cluster/cluster.go index e3a15d8c1b..911b6385b1 100644 --- a/daemon/cluster/cluster.go +++ b/daemon/cluster/cluster.go @@ -16,6 +16,7 @@ import ( "time" "github.com/Sirupsen/logrus" + distreference "github.com/docker/distribution/reference" apierrors "github.com/docker/docker/api/errors" apitypes "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/backend" @@ -1008,16 +1009,25 @@ func (c *Cluster) GetServices(options apitypes.ServiceListOptions) ([]types.Serv // imageWithDigestString takes an image such as name or name:tag // and returns the image pinned to a digest, such as name@sha256:34234... +// Due to the difference between the docker/docker/reference, and the +// docker/distribution/reference packages, we're parsing the image twice. +// As the two packages converge, this function should be simplified. +// TODO(nishanttotla): After the packages converge, the function must +// convert distreference.Named -> distreference.Canonical, and the logic simplified. func (c *Cluster) imageWithDigestString(ctx context.Context, image string, authConfig *apitypes.AuthConfig) (string, error) { - ref, err := reference.ParseNamed(image) + ref, err := distreference.ParseNamed(image) if err != nil { return "", err } // only query registry if not a canonical reference (i.e. with digest) - if _, ok := ref.(reference.Canonical); !ok { - ref = reference.WithDefaultTag(ref) - - namedTaggedRef, ok := ref.(reference.NamedTagged) + if _, ok := ref.(distreference.Canonical); !ok { + // create a docker/docker/reference Named object because GetRepository needs it + dockerRef, err := reference.ParseNamed(image) + if err != nil { + return "", err + } + dockerRef = reference.WithDefaultTag(dockerRef) + namedTaggedRef, ok := dockerRef.(reference.NamedTagged) if !ok { return "", fmt.Errorf("unable to cast image to NamedTagged reference object") } @@ -1031,15 +1041,11 @@ func (c *Cluster) imageWithDigestString(ctx context.Context, image string, authC return "", err } - // TODO(nishanttotla): Currently, the service would lose the tag while calling WithDigest - // To prevent this, we create the image string manually, which is a bad idea in general - // This will be fixed when https://github.com/docker/distribution/pull/2044 is vendored - // namedDigestedRef, err := reference.WithDigest(ref, dscrptr.Digest) - // if err != nil { - // return "", err - // } - // return namedDigestedRef.String(), nil - return image + "@" + dscrptr.Digest.String(), nil + namedDigestedRef, err := distreference.WithDigest(distreference.EnsureTagged(ref), dscrptr.Digest) + if err != nil { + return "", err + } + return namedDigestedRef.String(), nil } else { // reference already contains a digest, so just return it return ref.String(), nil diff --git a/vendor.conf b/vendor.conf index 5ea45b32e5..aa9a3e1a89 100644 --- a/vendor.conf +++ b/vendor.conf @@ -44,7 +44,7 @@ github.com/boltdb/bolt fff57c100f4dea1905678da7e90d92429dff2904 github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7 # get graph and distribution packages -github.com/docker/distribution 8016d2d8903e378edacac11e4d809efbc987ad61 +github.com/docker/distribution d22e09a6686c32be8c17b684b639da4b90efe320 github.com/vbatts/tar-split v0.10.1 # get go-zfs packages diff --git a/vendor/github.com/docker/distribution/reference/helpers.go b/vendor/github.com/docker/distribution/reference/helpers.go new file mode 100644 index 0000000000..dd7ee0ea65 --- /dev/null +++ b/vendor/github.com/docker/distribution/reference/helpers.go @@ -0,0 +1,12 @@ +package reference + +// 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 +} diff --git a/vendor/github.com/docker/distribution/reference/normalize.go b/vendor/github.com/docker/distribution/reference/normalize.go new file mode 100644 index 0000000000..b19a34e3bf --- /dev/null +++ b/vendor/github.com/docker/distribution/reference/normalize.go @@ -0,0 +1,22 @@ +package reference + +var ( + defaultTag = "latest" +) + +// EnsureTagged adds the default tag "latest" to a reference if it only has +// a repo name. +func EnsureTagged(ref Named) NamedTagged { + namedTagged, ok := ref.(NamedTagged) + if !ok { + 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 namedTagged +}