Browse code

Remove use of forked reference package for cli

Use resolving to repo info as the split point between the
legitimate reference package and forked reference package.

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)

Derek McGowan authored on 2017/01/12 06:54:52
Showing 20 changed files
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"io"
6 6
 	"os"
7 7
 
8
+	"github.com/docker/distribution/reference"
8 9
 	"github.com/docker/docker/api/types"
9 10
 	"github.com/docker/docker/api/types/container"
10 11
 	networktypes "github.com/docker/docker/api/types/network"
... ...
@@ -13,8 +14,6 @@ import (
13 13
 	"github.com/docker/docker/cli/command/image"
14 14
 	apiclient "github.com/docker/docker/client"
15 15
 	"github.com/docker/docker/pkg/jsonmessage"
16
-	// FIXME migrate to docker/distribution/reference
17
-	"github.com/docker/docker/reference"
18 16
 	"github.com/docker/docker/registry"
19 17
 	"github.com/spf13/cobra"
20 18
 	"github.com/spf13/pflag"
... ...
@@ -72,7 +71,7 @@ func runCreate(dockerCli *command.DockerCli, flags *pflag.FlagSet, opts *createO
72 72
 }
73 73
 
74 74
 func pullImage(ctx context.Context, dockerCli *command.DockerCli, image string, out io.Writer) error {
75
-	ref, err := reference.ParseNamed(image)
75
+	ref, err := reference.ParseNormalizedNamed(image)
76 76
 	if err != nil {
77 77
 		return err
78 78
 	}
... ...
@@ -150,7 +149,12 @@ func newCIDFile(path string) (*cidFile, error) {
150 150
 func createContainer(ctx context.Context, dockerCli *command.DockerCli, config *container.Config, hostConfig *container.HostConfig, networkingConfig *networktypes.NetworkingConfig, cidfile, name string) (*container.ContainerCreateCreatedBody, error) {
151 151
 	stderr := dockerCli.Err()
152 152
 
153
-	var containerIDFile *cidFile
153
+	var (
154
+		containerIDFile *cidFile
155
+		trustedRef      reference.Canonical
156
+		namedRef        reference.Named
157
+	)
158
+
154 159
 	if cidfile != "" {
155 160
 		var err error
156 161
 		if containerIDFile, err = newCIDFile(cidfile); err != nil {
... ...
@@ -159,21 +163,24 @@ func createContainer(ctx context.Context, dockerCli *command.DockerCli, config *
159 159
 		defer containerIDFile.Close()
160 160
 	}
161 161
 
162
-	var trustedRef reference.Canonical
163
-	_, ref, err := reference.ParseIDOrReference(config.Image)
162
+	ref, err := reference.ParseAnyReference(config.Image)
164 163
 	if err != nil {
165 164
 		return nil, err
166 165
 	}
167
-	if ref != nil {
168
-		ref = reference.WithDefaultTag(ref)
166
+	if named, ok := ref.(reference.Named); ok {
167
+		if reference.IsNameOnly(named) {
168
+			namedRef = reference.EnsureTagged(named)
169
+		} else {
170
+			namedRef = named
171
+		}
169 172
 
170
-		if ref, ok := ref.(reference.NamedTagged); ok && command.IsTrusted() {
173
+		if taggedRef, ok := namedRef.(reference.NamedTagged); ok && command.IsTrusted() {
171 174
 			var err error
172
-			trustedRef, err = image.TrustedReference(ctx, dockerCli, ref, nil)
175
+			trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef, nil)
173 176
 			if err != nil {
174 177
 				return nil, err
175 178
 			}
176
-			config.Image = trustedRef.String()
179
+			config.Image = reference.FamiliarString(trustedRef)
177 180
 		}
178 181
 	}
179 182
 
... ...
@@ -182,15 +189,15 @@ func createContainer(ctx context.Context, dockerCli *command.DockerCli, config *
182 182
 
183 183
 	//if image not found try to pull it
184 184
 	if err != nil {
185
-		if apiclient.IsErrImageNotFound(err) && ref != nil {
186
-			fmt.Fprintf(stderr, "Unable to find image '%s' locally\n", ref.String())
185
+		if apiclient.IsErrImageNotFound(err) && namedRef != nil {
186
+			fmt.Fprintf(stderr, "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef))
187 187
 
188 188
 			// we don't want to write to stdout anything apart from container.ID
189 189
 			if err = pullImage(ctx, dockerCli, config.Image, stderr); err != nil {
190 190
 				return nil, err
191 191
 			}
192
-			if ref, ok := ref.(reference.NamedTagged); ok && trustedRef != nil {
193
-				if err := image.TagTrusted(ctx, dockerCli, trustedRef, ref); err != nil {
192
+			if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
193
+				if err := image.TagTrusted(ctx, dockerCli, trustedRef, taggedRef); err != nil {
194 194
 					return nil, err
195 195
 				}
196 196
 			}
... ...
@@ -4,9 +4,9 @@ import (
4 4
 	"fmt"
5 5
 	"time"
6 6
 
7
+	"github.com/docker/distribution/reference"
7 8
 	"github.com/docker/docker/api/types"
8 9
 	"github.com/docker/docker/pkg/stringid"
9
-	"github.com/docker/docker/reference"
10 10
 	units "github.com/docker/go-units"
11 11
 )
12 12
 
... ...
@@ -95,21 +95,23 @@ func imageFormat(ctx ImageContext, images []types.ImageSummary, format func(subC
95 95
 			repoDigests := map[string][]string{}
96 96
 
97 97
 			for _, refString := range append(image.RepoTags) {
98
-				ref, err := reference.ParseNamed(refString)
98
+				ref, err := reference.ParseNormalizedNamed(refString)
99 99
 				if err != nil {
100 100
 					continue
101 101
 				}
102 102
 				if nt, ok := ref.(reference.NamedTagged); ok {
103
-					repoTags[ref.Name()] = append(repoTags[ref.Name()], nt.Tag())
103
+					familiarRef := reference.FamiliarName(ref)
104
+					repoTags[familiarRef] = append(repoTags[familiarRef], nt.Tag())
104 105
 				}
105 106
 			}
106 107
 			for _, refString := range append(image.RepoDigests) {
107
-				ref, err := reference.ParseNamed(refString)
108
+				ref, err := reference.ParseNormalizedNamed(refString)
108 109
 				if err != nil {
109 110
 					continue
110 111
 				}
111 112
 				if c, ok := ref.(reference.Canonical); ok {
112
-					repoDigests[ref.Name()] = append(repoDigests[ref.Name()], c.Digest().String())
113
+					familiarRef := reference.FamiliarName(ref)
114
+					repoDigests[familiarRef] = append(repoDigests[familiarRef], c.Digest().String())
113 115
 				}
114 116
 			}
115 117
 
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"regexp"
12 12
 	"runtime"
13 13
 
14
+	"github.com/docker/distribution/reference"
14 15
 	"github.com/docker/docker/api"
15 16
 	"github.com/docker/docker/api/types"
16 17
 	"github.com/docker/docker/api/types/container"
... ...
@@ -25,7 +26,6 @@ import (
25 25
 	"github.com/docker/docker/pkg/progress"
26 26
 	"github.com/docker/docker/pkg/streamformatter"
27 27
 	"github.com/docker/docker/pkg/urlutil"
28
-	"github.com/docker/docker/reference"
29 28
 	runconfigopts "github.com/docker/docker/runconfig/opts"
30 29
 	units "github.com/docker/go-units"
31 30
 	"github.com/spf13/cobra"
... ...
@@ -360,7 +360,7 @@ type translatorFunc func(context.Context, reference.NamedTagged) (reference.Cano
360 360
 
361 361
 // validateTag checks if the given image name can be resolved.
362 362
 func validateTag(rawRepo string) (string, error) {
363
-	_, err := reference.ParseNamed(rawRepo)
363
+	_, err := reference.ParseNormalizedNamed(rawRepo)
364 364
 	if err != nil {
365 365
 		return "", err
366 366
 	}
... ...
@@ -392,18 +392,21 @@ func rewriteDockerfileFrom(ctx context.Context, dockerfile io.Reader, translator
392 392
 		matches := dockerfileFromLinePattern.FindStringSubmatch(line)
393 393
 		if matches != nil && matches[1] != api.NoBaseImageSpecifier {
394 394
 			// Replace the line with a resolved "FROM repo@digest"
395
-			ref, err := reference.ParseNamed(matches[1])
395
+			var ref reference.Named
396
+			ref, err = reference.ParseNormalizedNamed(matches[1])
396 397
 			if err != nil {
397 398
 				return nil, nil, err
398 399
 			}
399
-			ref = reference.WithDefaultTag(ref)
400
+			if reference.IsNameOnly(ref) {
401
+				ref = reference.EnsureTagged(ref)
402
+			}
400 403
 			if ref, ok := ref.(reference.NamedTagged); ok && command.IsTrusted() {
401 404
 				trustedRef, err := translator(ctx, ref)
402 405
 				if err != nil {
403 406
 					return nil, nil, err
404 407
 				}
405 408
 
406
-				line = dockerfileFromLinePattern.ReplaceAllLiteralString(line, fmt.Sprintf("FROM %s", trustedRef.String()))
409
+				line = dockerfileFromLinePattern.ReplaceAllLiteralString(line, fmt.Sprintf("FROM %s", reference.FamiliarString(trustedRef)))
407 410
 				resolvedTags = append(resolvedTags, &resolvedTag{
408 411
 					digestRef: trustedRef,
409 412
 					tagRef:    ref,
... ...
@@ -7,9 +7,9 @@ import (
7 7
 
8 8
 	"golang.org/x/net/context"
9 9
 
10
+	"github.com/docker/distribution/reference"
10 11
 	"github.com/docker/docker/cli"
11 12
 	"github.com/docker/docker/cli/command"
12
-	"github.com/docker/docker/reference"
13 13
 	"github.com/docker/docker/registry"
14 14
 	"github.com/spf13/cobra"
15 15
 )
... ...
@@ -42,7 +42,8 @@ func NewPullCommand(dockerCli *command.DockerCli) *cobra.Command {
42 42
 }
43 43
 
44 44
 func runPull(dockerCli *command.DockerCli, opts pullOptions) error {
45
-	distributionRef, err := reference.ParseNamed(opts.remote)
45
+	var distributionRef reference.Named
46
+	distributionRef, err := reference.ParseNormalizedNamed(opts.remote)
46 47
 	if err != nil {
47 48
 		return err
48 49
 	}
... ...
@@ -51,8 +52,9 @@ func runPull(dockerCli *command.DockerCli, opts pullOptions) error {
51 51
 	}
52 52
 
53 53
 	if !opts.all && reference.IsNameOnly(distributionRef) {
54
-		distributionRef = reference.WithDefaultTag(distributionRef)
55
-		fmt.Fprintf(dockerCli.Out(), "Using default tag: %s\n", reference.DefaultTag)
54
+		taggedRef := reference.EnsureTagged(distributionRef)
55
+		fmt.Fprintf(dockerCli.Out(), "Using default tag: %s\n", taggedRef.Tag())
56
+		distributionRef = taggedRef
56 57
 	}
57 58
 
58 59
 	// Resolve the Repository name from fqn to RepositoryInfo
... ...
@@ -71,7 +73,7 @@ func runPull(dockerCli *command.DockerCli, opts pullOptions) error {
71 71
 	if command.IsTrusted() && !isCanonical {
72 72
 		err = trustedPull(ctx, dockerCli, repoInfo, distributionRef, authConfig, requestPrivilege)
73 73
 	} else {
74
-		err = imagePullPrivileged(ctx, dockerCli, authConfig, distributionRef.String(), requestPrivilege, opts.all)
74
+		err = imagePullPrivileged(ctx, dockerCli, authConfig, reference.FamiliarString(distributionRef), requestPrivilege, opts.all)
75 75
 	}
76 76
 	if err != nil {
77 77
 		if strings.Contains(err.Error(), "target is plugin") {
... ...
@@ -3,10 +3,10 @@ package image
3 3
 import (
4 4
 	"golang.org/x/net/context"
5 5
 
6
+	"github.com/docker/distribution/reference"
6 7
 	"github.com/docker/docker/cli"
7 8
 	"github.com/docker/docker/cli/command"
8 9
 	"github.com/docker/docker/pkg/jsonmessage"
9
-	"github.com/docker/docker/reference"
10 10
 	"github.com/docker/docker/registry"
11 11
 	"github.com/spf13/cobra"
12 12
 )
... ...
@@ -30,7 +30,7 @@ func NewPushCommand(dockerCli *command.DockerCli) *cobra.Command {
30 30
 }
31 31
 
32 32
 func runPush(dockerCli *command.DockerCli, remote string) error {
33
-	ref, err := reference.ParseNamed(remote)
33
+	ref, err := reference.ParseNormalizedNamed(remote)
34 34
 	if err != nil {
35 35
 		return err
36 36
 	}
... ...
@@ -51,7 +51,7 @@ func runPush(dockerCli *command.DockerCli, remote string) error {
51 51
 		return trustedPush(ctx, dockerCli, repoInfo, ref, authConfig, requestPrivilege)
52 52
 	}
53 53
 
54
-	responseBody, err := imagePushPrivileged(ctx, dockerCli, authConfig, ref.String(), requestPrivilege)
54
+	responseBody, err := imagePushPrivileged(ctx, dockerCli, authConfig, ref, requestPrivilege)
55 55
 	if err != nil {
56 56
 		return err
57 57
 	}
... ...
@@ -10,11 +10,11 @@ import (
10 10
 	"sort"
11 11
 
12 12
 	"github.com/Sirupsen/logrus"
13
+	"github.com/docker/distribution/reference"
13 14
 	"github.com/docker/docker/api/types"
14 15
 	"github.com/docker/docker/cli/command"
15 16
 	"github.com/docker/docker/cli/trust"
16 17
 	"github.com/docker/docker/pkg/jsonmessage"
17
-	"github.com/docker/docker/reference"
18 18
 	"github.com/docker/docker/registry"
19 19
 	"github.com/docker/notary/client"
20 20
 	"github.com/docker/notary/tuf/data"
... ...
@@ -30,7 +30,7 @@ type target struct {
30 30
 
31 31
 // trustedPush handles content trust pushing of an image
32 32
 func trustedPush(ctx context.Context, cli *command.DockerCli, repoInfo *registry.RepositoryInfo, ref reference.Named, authConfig types.AuthConfig, requestPrivilege types.RequestPrivilegeFunc) error {
33
-	responseBody, err := imagePushPrivileged(ctx, cli, authConfig, ref.String(), requestPrivilege)
33
+	responseBody, err := imagePushPrivileged(ctx, cli, authConfig, ref, requestPrivilege)
34 34
 	if err != nil {
35 35
 		return err
36 36
 	}
... ...
@@ -202,7 +202,7 @@ func addTargetToAllSignableRoles(repo *client.NotaryRepository, target *client.T
202 202
 }
203 203
 
204 204
 // imagePushPrivileged push the image
205
-func imagePushPrivileged(ctx context.Context, cli *command.DockerCli, authConfig types.AuthConfig, ref string, requestPrivilege types.RequestPrivilegeFunc) (io.ReadCloser, error) {
205
+func imagePushPrivileged(ctx context.Context, cli *command.DockerCli, authConfig types.AuthConfig, ref reference.Named, requestPrivilege types.RequestPrivilegeFunc) (io.ReadCloser, error) {
206 206
 	encodedAuth, err := command.EncodeAuthToBase64(authConfig)
207 207
 	if err != nil {
208 208
 		return nil, err
... ...
@@ -212,7 +212,7 @@ func imagePushPrivileged(ctx context.Context, cli *command.DockerCli, authConfig
212 212
 		PrivilegeFunc: requestPrivilege,
213 213
 	}
214 214
 
215
-	return cli.Client().ImagePush(ctx, ref, options)
215
+	return cli.Client().ImagePush(ctx, reference.FamiliarString(ref), options)
216 216
 }
217 217
 
218 218
 // trustedPull handles content trust pulling of an image
... ...
@@ -229,12 +229,12 @@ func trustedPull(ctx context.Context, cli *command.DockerCli, repoInfo *registry
229 229
 		// List all targets
230 230
 		targets, err := notaryRepo.ListTargets(trust.ReleasesRole, data.CanonicalTargetsRole)
231 231
 		if err != nil {
232
-			return trust.NotaryError(repoInfo.FullName(), err)
232
+			return trust.NotaryError(ref.Name(), err)
233 233
 		}
234 234
 		for _, tgt := range targets {
235 235
 			t, err := convertTarget(tgt.Target)
236 236
 			if err != nil {
237
-				fmt.Fprintf(cli.Out(), "Skipping target for %q\n", repoInfo.Name())
237
+				fmt.Fprintf(cli.Out(), "Skipping target for %q\n", reference.FamiliarName(ref))
238 238
 				continue
239 239
 			}
240 240
 			// Only list tags in the top level targets role or the releases delegation role - ignore
... ...
@@ -245,17 +245,17 @@ func trustedPull(ctx context.Context, cli *command.DockerCli, repoInfo *registry
245 245
 			refs = append(refs, t)
246 246
 		}
247 247
 		if len(refs) == 0 {
248
-			return trust.NotaryError(repoInfo.FullName(), fmt.Errorf("No trusted tags for %s", repoInfo.FullName()))
248
+			return trust.NotaryError(ref.Name(), fmt.Errorf("No trusted tags for %s", ref.Name()))
249 249
 		}
250 250
 	} else {
251 251
 		t, err := notaryRepo.GetTargetByName(tagged.Tag(), trust.ReleasesRole, data.CanonicalTargetsRole)
252 252
 		if err != nil {
253
-			return trust.NotaryError(repoInfo.FullName(), err)
253
+			return trust.NotaryError(ref.Name(), err)
254 254
 		}
255 255
 		// Only get the tag if it's in the top level targets role or the releases delegation role
256 256
 		// ignore it if it's in any other delegation roles
257 257
 		if t.Role != trust.ReleasesRole && t.Role != data.CanonicalTargetsRole {
258
-			return trust.NotaryError(repoInfo.FullName(), fmt.Errorf("No trust data for %s", tagged.Tag()))
258
+			return trust.NotaryError(ref.Name(), fmt.Errorf("No trust data for %s", tagged.Tag()))
259 259
 		}
260 260
 
261 261
 		logrus.Debugf("retrieving target for %s role\n", t.Role)
... ...
@@ -272,24 +272,21 @@ func trustedPull(ctx context.Context, cli *command.DockerCli, repoInfo *registry
272 272
 		if displayTag != "" {
273 273
 			displayTag = ":" + displayTag
274 274
 		}
275
-		fmt.Fprintf(cli.Out(), "Pull (%d of %d): %s%s@%s\n", i+1, len(refs), repoInfo.Name(), displayTag, r.digest)
275
+		fmt.Fprintf(cli.Out(), "Pull (%d of %d): %s%s@%s\n", i+1, len(refs), reference.FamiliarName(ref), displayTag, r.digest)
276 276
 
277
-		ref, err := reference.WithDigest(reference.TrimNamed(repoInfo), r.digest)
277
+		trustedRef, err := reference.WithDigest(reference.TrimNamed(ref), r.digest)
278 278
 		if err != nil {
279 279
 			return err
280 280
 		}
281
-		if err := imagePullPrivileged(ctx, cli, authConfig, ref.String(), requestPrivilege, false); err != nil {
281
+		if err := imagePullPrivileged(ctx, cli, authConfig, reference.FamiliarString(trustedRef), requestPrivilege, false); err != nil {
282 282
 			return err
283 283
 		}
284 284
 
285
-		tagged, err := reference.WithTag(repoInfo, r.name)
286
-		if err != nil {
287
-			return err
288
-		}
289
-		trustedRef, err := reference.WithDigest(reference.TrimNamed(repoInfo), r.digest)
285
+		tagged, err := reference.WithTag(reference.TrimNamed(ref), r.name)
290 286
 		if err != nil {
291 287
 			return err
292 288
 		}
289
+
293 290
 		if err := TagTrusted(ctx, cli, trustedRef, tagged); err != nil {
294 291
 			return err
295 292
 		}
... ...
@@ -375,7 +372,11 @@ func convertTarget(t client.Target) (target, error) {
375 375
 
376 376
 // TagTrusted tags a trusted ref
377 377
 func TagTrusted(ctx context.Context, cli *command.DockerCli, trustedRef reference.Canonical, ref reference.NamedTagged) error {
378
-	fmt.Fprintf(cli.Out(), "Tagging %s as %s\n", trustedRef.String(), ref.String())
378
+	// Use familiar references when interacting with client and output
379
+	familiarRef := reference.FamiliarString(ref)
380
+	trustedFamiliarRef := reference.FamiliarString(trustedRef)
381
+
382
+	fmt.Fprintf(cli.Out(), "Tagging %s as %s\n", trustedFamiliarRef, familiarRef)
379 383
 
380
-	return cli.Client().ImageTag(ctx, trustedRef.String(), ref.String())
384
+	return cli.Client().ImageTag(ctx, trustedFamiliarRef, familiarRef)
381 385
 }
... ...
@@ -8,18 +8,18 @@ import (
8 8
 	"path/filepath"
9 9
 
10 10
 	"github.com/Sirupsen/logrus"
11
+	"github.com/docker/distribution/reference"
11 12
 	"github.com/docker/docker/api/types"
12 13
 	"github.com/docker/docker/cli"
13 14
 	"github.com/docker/docker/cli/command"
14 15
 	"github.com/docker/docker/pkg/archive"
15
-	"github.com/docker/docker/reference"
16 16
 	"github.com/spf13/cobra"
17 17
 	"golang.org/x/net/context"
18 18
 )
19 19
 
20 20
 // validateTag checks if the given repoName can be resolved.
21 21
 func validateTag(rawRepo string) error {
22
-	_, err := reference.ParseNamed(rawRepo)
22
+	_, err := reference.ParseNormalizedNamed(rawRepo)
23 23
 
24 24
 	return err
25 25
 }
... ...
@@ -6,14 +6,13 @@ import (
6 6
 	"fmt"
7 7
 	"strings"
8 8
 
9
-	distreference "github.com/docker/distribution/reference"
9
+	"github.com/docker/distribution/reference"
10 10
 	"github.com/docker/docker/api/types"
11 11
 	registrytypes "github.com/docker/docker/api/types/registry"
12 12
 	"github.com/docker/docker/cli"
13 13
 	"github.com/docker/docker/cli/command"
14 14
 	"github.com/docker/docker/cli/command/image"
15 15
 	"github.com/docker/docker/pkg/jsonmessage"
16
-	"github.com/docker/docker/reference"
17 16
 	"github.com/docker/docker/registry"
18 17
 	"github.com/spf13/cobra"
19 18
 	"golang.org/x/net/context"
... ...
@@ -52,8 +51,8 @@ func newInstallCommand(dockerCli *command.DockerCli) *cobra.Command {
52 52
 	return cmd
53 53
 }
54 54
 
55
-func getRepoIndexFromUnnormalizedRef(ref distreference.Named) (*registrytypes.IndexInfo, error) {
56
-	named, err := reference.ParseNamed(ref.Name())
55
+func getRepoIndexFromUnnormalizedRef(ref reference.Named) (*registrytypes.IndexInfo, error) {
56
+	named, err := reference.ParseNormalizedNamed(ref.Name())
57 57
 	if err != nil {
58 58
 		return nil, err
59 59
 	}
... ...
@@ -85,71 +84,60 @@ func newRegistryService() registry.Service {
85 85
 }
86 86
 
87 87
 func runInstall(dockerCli *command.DockerCli, opts pluginOptions) error {
88
-	// Parse name using distribution reference package to support name
89
-	// containing both tag and digest. Names with both tag and digest
90
-	// will be treated by the daemon as a pull by digest with
91
-	// an alias for the tag (if no alias is provided).
92
-	ref, err := distreference.ParseNamed(opts.name)
88
+	// Names with both tag and digest will be treated by the daemon
89
+	// as a pull by digest with an alias for the tag
90
+	// (if no alias is provided).
91
+	ref, err := reference.ParseNormalizedNamed(opts.name)
93 92
 	if err != nil {
94 93
 		return err
95 94
 	}
96 95
 
97 96
 	alias := ""
98 97
 	if opts.alias != "" {
99
-		aref, err := reference.ParseNamed(opts.alias)
98
+		aref, err := reference.ParseNormalizedNamed(opts.alias)
100 99
 		if err != nil {
101 100
 			return err
102 101
 		}
103
-		aref = reference.WithDefaultTag(aref)
104
-		if _, ok := aref.(reference.NamedTagged); !ok {
102
+		if _, ok := aref.(reference.Canonical); ok {
105 103
 			return fmt.Errorf("invalid name: %s", opts.alias)
106 104
 		}
107
-		alias = aref.String()
105
+		alias = reference.FamiliarString(reference.EnsureTagged(aref))
108 106
 	}
109 107
 	ctx := context.Background()
110 108
 
111
-	index, err := getRepoIndexFromUnnormalizedRef(ref)
109
+	repoInfo, err := registry.ParseRepositoryInfo(ref)
112 110
 	if err != nil {
113 111
 		return err
114 112
 	}
115 113
 
116 114
 	remote := ref.String()
117 115
 
118
-	_, isCanonical := ref.(distreference.Canonical)
116
+	_, isCanonical := ref.(reference.Canonical)
119 117
 	if command.IsTrusted() && !isCanonical {
120 118
 		if alias == "" {
121
-			alias = ref.String()
119
+			alias = reference.FamiliarString(ref)
122 120
 		}
123
-		var nt reference.NamedTagged
124
-		named, err := reference.ParseNamed(ref.Name())
125
-		if err != nil {
126
-			return err
127
-		}
128
-		if tagged, ok := ref.(distreference.Tagged); ok {
129
-			nt, err = reference.WithTag(named, tagged.Tag())
130
-			if err != nil {
131
-				return err
132
-			}
133
-		} else {
134
-			named = reference.WithDefaultTag(named)
135
-			nt = named.(reference.NamedTagged)
121
+
122
+		nt, ok := ref.(reference.NamedTagged)
123
+		if !ok {
124
+			nt = reference.EnsureTagged(ref)
136 125
 		}
137 126
 
138 127
 		trusted, err := image.TrustedReference(ctx, dockerCli, nt, newRegistryService())
139 128
 		if err != nil {
140 129
 			return err
141 130
 		}
142
-		remote = trusted.String()
131
+		remote = reference.FamiliarString(trusted)
143 132
 	}
144 133
 
145
-	authConfig := command.ResolveAuthConfig(ctx, dockerCli, index)
134
+	authConfig := command.ResolveAuthConfig(ctx, dockerCli, repoInfo.Index)
146 135
 
147 136
 	encodedAuth, err := command.EncodeAuthToBase64(authConfig)
148 137
 	if err != nil {
149 138
 		return err
150 139
 	}
151 140
 
152
-	registryAuthFunc := command.RegistryAuthenticationPrivilegedFunc(dockerCli, index, "plugin install")
141
+	registryAuthFunc := command.RegistryAuthenticationPrivilegedFunc(dockerCli, repoInfo.Index, "plugin install")
153 142
 
154 143
 	options := types.PluginInstallOptions{
155 144
 		RegistryAuth:          encodedAuth,
... ...
@@ -5,11 +5,11 @@ import (
5 5
 
6 6
 	"golang.org/x/net/context"
7 7
 
8
+	"github.com/docker/distribution/reference"
8 9
 	"github.com/docker/docker/cli"
9 10
 	"github.com/docker/docker/cli/command"
10 11
 	"github.com/docker/docker/cli/command/image"
11 12
 	"github.com/docker/docker/pkg/jsonmessage"
12
-	"github.com/docker/docker/reference"
13 13
 	"github.com/docker/docker/registry"
14 14
 	"github.com/spf13/cobra"
15 15
 )
... ...
@@ -32,16 +32,17 @@ func newPushCommand(dockerCli *command.DockerCli) *cobra.Command {
32 32
 }
33 33
 
34 34
 func runPush(dockerCli *command.DockerCli, name string) error {
35
-	named, err := reference.ParseNamed(name) // FIXME: validate
35
+	named, err := reference.ParseNormalizedNamed(name)
36 36
 	if err != nil {
37 37
 		return err
38 38
 	}
39
-	if reference.IsNameOnly(named) {
40
-		named = reference.WithDefaultTag(named)
39
+	if _, ok := named.(reference.Canonical); ok {
40
+		return fmt.Errorf("invalid name: %s", name)
41 41
 	}
42
-	ref, ok := named.(reference.NamedTagged)
42
+
43
+	taggedRef, ok := named.(reference.NamedTagged)
43 44
 	if !ok {
44
-		return fmt.Errorf("invalid name: %s", named.String())
45
+		taggedRef = reference.EnsureTagged(named)
45 46
 	}
46 47
 
47 48
 	ctx := context.Background()
... ...
@@ -56,7 +57,8 @@ func runPush(dockerCli *command.DockerCli, name string) error {
56 56
 	if err != nil {
57 57
 		return err
58 58
 	}
59
-	responseBody, err := dockerCli.Client().PluginPush(ctx, ref.String(), encodedAuth)
59
+
60
+	responseBody, err := dockerCli.Client().PluginPush(ctx, reference.FamiliarString(taggedRef), encodedAuth)
60 61
 	if err != nil {
61 62
 		return err
62 63
 	}
... ...
@@ -12,10 +12,10 @@ import (
12 12
 
13 13
 	"golang.org/x/net/context"
14 14
 
15
+	"github.com/docker/distribution/reference"
15 16
 	"github.com/docker/docker/api/types"
16 17
 	registrytypes "github.com/docker/docker/api/types/registry"
17 18
 	"github.com/docker/docker/pkg/term"
18
-	"github.com/docker/docker/reference"
19 19
 	"github.com/docker/docker/registry"
20 20
 )
21 21
 
... ...
@@ -174,7 +174,7 @@ func RetrieveAuthTokenFromImage(ctx context.Context, cli *DockerCli, image strin
174 174
 
175 175
 // resolveAuthConfigFromImage retrieves that AuthConfig using the image string
176 176
 func resolveAuthConfigFromImage(ctx context.Context, cli *DockerCli, image string) (types.AuthConfig, error) {
177
-	registryRef, err := reference.ParseNamed(image)
177
+	registryRef, err := reference.ParseNormalizedNamed(image)
178 178
 	if err != nil {
179 179
 		return types.AuthConfig{}, err
180 180
 	}
... ...
@@ -5,11 +5,10 @@ import (
5 5
 	"fmt"
6 6
 
7 7
 	"github.com/Sirupsen/logrus"
8
-	distreference "github.com/docker/distribution/reference"
8
+	"github.com/docker/distribution/reference"
9 9
 	"github.com/docker/docker/api/types/swarm"
10 10
 	"github.com/docker/docker/cli/command"
11 11
 	"github.com/docker/docker/cli/trust"
12
-	"github.com/docker/docker/reference"
13 12
 	"github.com/docker/docker/registry"
14 13
 	"github.com/docker/notary/tuf/data"
15 14
 	"github.com/opencontainers/go-digest"
... ...
@@ -24,41 +23,34 @@ func resolveServiceImageDigest(dockerCli *command.DockerCli, service *swarm.Serv
24 24
 		return nil
25 25
 	}
26 26
 
27
-	image := service.TaskTemplate.ContainerSpec.Image
28
-
29
-	// We only attempt to resolve the digest if the reference
30
-	// could be parsed as a digest reference. Specifying an image ID
31
-	// is valid but not resolvable. There is no warning message for
32
-	// an image ID because it's valid to use one.
33
-	if _, err := digest.Parse(image); err == nil {
34
-		return nil
35
-	}
36
-
37
-	ref, err := reference.ParseNamed(image)
27
+	ref, err := reference.ParseAnyReference(service.TaskTemplate.ContainerSpec.Image)
38 28
 	if err != nil {
39
-		return fmt.Errorf("Could not parse image reference %s", service.TaskTemplate.ContainerSpec.Image)
29
+		return errors.Wrapf(err, "invalid reference %s", service.TaskTemplate.ContainerSpec.Image)
40 30
 	}
41
-	if _, ok := ref.(reference.Canonical); !ok {
42
-		ref = reference.WithDefaultTag(ref)
43 31
 
44
-		taggedRef, ok := ref.(reference.NamedTagged)
32
+	// If reference does not have digest (is not canonical nor image id)
33
+	if _, ok := ref.(reference.Digested); !ok {
34
+		namedRef, ok := ref.(reference.Named)
45 35
 		if !ok {
46
-			// This should never happen because a reference either
47
-			// has a digest, or WithDefaultTag would give it a tag.
48
-			return errors.New("Failed to resolve image digest using content trust: reference is missing a tag")
36
+			return errors.New("failed to resolve image digest using content trust: reference is not named")
37
+
49 38
 		}
50 39
 
40
+		taggedRef := reference.EnsureTagged(namedRef)
41
+
51 42
 		resolvedImage, err := trustedResolveDigest(context.Background(), dockerCli, taggedRef)
52 43
 		if err != nil {
53
-			return fmt.Errorf("Failed to resolve image digest using content trust: %v", err)
44
+			return errors.Wrap(err, "failed to resolve image digest using content trust")
54 45
 		}
55
-		logrus.Debugf("resolved image tag to %s using content trust", resolvedImage.String())
56
-		service.TaskTemplate.ContainerSpec.Image = resolvedImage.String()
46
+		resolvedFamiliar := reference.FamiliarString(resolvedImage)
47
+		logrus.Debugf("resolved image tag to %s using content trust", resolvedFamiliar)
48
+		service.TaskTemplate.ContainerSpec.Image = resolvedFamiliar
57 49
 	}
50
+
58 51
 	return nil
59 52
 }
60 53
 
61
-func trustedResolveDigest(ctx context.Context, cli *command.DockerCli, ref reference.NamedTagged) (distreference.Canonical, error) {
54
+func trustedResolveDigest(ctx context.Context, cli *command.DockerCli, ref reference.NamedTagged) (reference.Canonical, error) {
62 55
 	repoInfo, err := registry.ParseRepositoryInfo(ref)
63 56
 	if err != nil {
64 57
 		return nil, err
... ...
@@ -78,7 +70,7 @@ func trustedResolveDigest(ctx context.Context, cli *command.DockerCli, ref refer
78 78
 	// Only get the tag if it's in the top level targets role or the releases delegation role
79 79
 	// ignore it if it's in any other delegation roles
80 80
 	if t.Role != trust.ReleasesRole && t.Role != data.CanonicalTargetsRole {
81
-		return nil, trust.NotaryError(repoInfo.FullName(), fmt.Errorf("No trust data for %s", ref.String()))
81
+		return nil, trust.NotaryError(repoInfo.FullName(), fmt.Errorf("No trust data for %s", reference.FamiliarString(ref)))
82 82
 	}
83 83
 
84 84
 	logrus.Debugf("retrieving target for %s role\n", t.Role)
... ...
@@ -89,8 +81,6 @@ func trustedResolveDigest(ctx context.Context, cli *command.DockerCli, ref refer
89 89
 
90 90
 	dgst := digest.NewDigestFromHex("sha256", hex.EncodeToString(h))
91 91
 
92
-	// Using distribution reference package to make sure that adding a
93
-	// digest does not erase the tag. When the two reference packages
94
-	// are unified, this will no longer be an issue.
95
-	return distreference.WithDigest(ref, dgst)
92
+	// Allow returning canonical reference with tag
93
+	return reference.WithDigest(ref, dgst)
96 94
 }
... ...
@@ -202,7 +202,7 @@ func TestLayerAlreadyExists(t *testing.T) {
202 202
 			checkOtherRepositories: true,
203 203
 			metadata: []metadata.V2Metadata{
204 204
 				{Digest: digest.Digest("apple"), SourceRepository: "docker.io/library/hello-world"},
205
-				{Digest: digest.Digest("orange"), SourceRepository: "docker.io/library/busybox/subapp"},
205
+				{Digest: digest.Digest("orange"), SourceRepository: "docker.io/busybox/subapp"},
206 206
 				{Digest: digest.Digest("pear"), SourceRepository: "docker.io/busybox"},
207 207
 				{Digest: digest.Digest("plum"), SourceRepository: "busybox"},
208 208
 				{Digest: digest.Digest("banana"), SourceRepository: "127.0.0.1/busybox"},
... ...
@@ -3082,7 +3082,7 @@ func (s *DockerSuite) TestBuildInvalidTag(c *check.C) {
3082 3082
 	name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200)
3083 3083
 	buildImage(name, withDockerfile("FROM "+minimalBaseImage()+"\nMAINTAINER quux\n")).Assert(c, icmd.Expected{
3084 3084
 		ExitCode: 125,
3085
-		Err:      "Error parsing reference",
3085
+		Err:      "invalid reference format",
3086 3086
 	})
3087 3087
 }
3088 3088
 
... ...
@@ -274,7 +274,7 @@ func (s *DockerSuite) TestCreateByImageID(c *check.C) {
274 274
 		c.Fatalf("expected non-zero exit code; received %d", exit)
275 275
 	}
276 276
 
277
-	if expected := "Error parsing reference"; !strings.Contains(out, expected) {
277
+	if expected := "invalid reference format"; !strings.Contains(out, expected) {
278 278
 		c.Fatalf(`Expected %q in output; got: %s`, expected, out)
279 279
 	}
280 280
 
... ...
@@ -3863,8 +3863,8 @@ func (s *DockerSuite) TestRunInvalidReference(c *check.C) {
3863 3863
 		c.Fatalf("expected non-zero exist code; received %d", exit)
3864 3864
 	}
3865 3865
 
3866
-	if !strings.Contains(out, "Error parsing reference") {
3867
-		c.Fatalf(`Expected "Error parsing reference" in output; got: %s`, out)
3866
+	if !strings.Contains(out, "invalid reference format") {
3867
+		c.Fatalf(`Expected "invalid reference format" in output; got: %s`, out)
3868 3868
 	}
3869 3869
 }
3870 3870
 
... ...
@@ -12,6 +12,7 @@ import (
12 12
 	"sync"
13 13
 
14 14
 	"github.com/Sirupsen/logrus"
15
+	"github.com/docker/distribution/reference"
15 16
 	"github.com/docker/docker/api/types"
16 17
 	"github.com/docker/docker/image"
17 18
 	"github.com/docker/docker/layer"
... ...
@@ -19,7 +20,6 @@ import (
19 19
 	"github.com/docker/docker/pkg/ioutils"
20 20
 	"github.com/docker/docker/pkg/mount"
21 21
 	"github.com/docker/docker/plugin/v2"
22
-	"github.com/docker/docker/reference"
23 22
 	"github.com/docker/docker/registry"
24 23
 	"github.com/opencontainers/go-digest"
25 24
 	"github.com/pkg/errors"
... ...
@@ -1,13 +1,12 @@
1 1
 package reference
2 2
 
3 3
 import (
4
-	"errors"
5 4
 	"fmt"
6
-	"strings"
7 5
 
8 6
 	distreference "github.com/docker/distribution/reference"
9 7
 	"github.com/docker/docker/pkg/stringid"
10 8
 	"github.com/opencontainers/go-digest"
9
+	"github.com/pkg/errors"
11 10
 )
12 11
 
13 12
 const (
... ...
@@ -53,21 +52,31 @@ type Canonical interface {
53 53
 // returned.
54 54
 // If an error was encountered it is returned, along with a nil Reference.
55 55
 func ParseNamed(s string) (Named, error) {
56
-	named, err := distreference.ParseNamed(s)
56
+	named, err := distreference.ParseNormalizedNamed(s)
57 57
 	if err != nil {
58
-		return nil, fmt.Errorf("Error parsing reference: %q is not a valid repository/tag: %s", s, err)
58
+		return nil, errors.Wrapf(err, "failed to parse reference %q", s)
59 59
 	}
60
-	r, err := WithName(named.Name())
61
-	if err != nil {
60
+	if err := validateName(distreference.FamiliarName(named)); err != nil {
62 61
 		return nil, err
63 62
 	}
63
+
64
+	// Ensure returned reference cannot have tag and digest
64 65
 	if canonical, isCanonical := named.(distreference.Canonical); isCanonical {
65
-		return WithDigest(r, canonical.Digest())
66
+		r, err := distreference.WithDigest(distreference.TrimNamed(named), canonical.Digest())
67
+		if err != nil {
68
+			return nil, err
69
+		}
70
+		return &canonicalRef{namedRef{r}}, nil
66 71
 	}
67 72
 	if tagged, isTagged := named.(distreference.NamedTagged); isTagged {
68
-		return WithTag(r, tagged.Tag())
73
+		r, err := distreference.WithTag(distreference.TrimNamed(named), tagged.Tag())
74
+		if err != nil {
75
+			return nil, err
76
+		}
77
+		return &taggedRef{namedRef{r}}, nil
69 78
 	}
70
-	return r, nil
79
+
80
+	return &namedRef{named}, nil
71 81
 }
72 82
 
73 83
 // TrimNamed removes any tag or digest from the named reference
... ...
@@ -78,16 +87,15 @@ func TrimNamed(ref Named) Named {
78 78
 // WithName returns a named object representing the given string. If the input
79 79
 // is invalid ErrReferenceInvalidFormat will be returned.
80 80
 func WithName(name string) (Named, error) {
81
-	name, err := normalize(name)
81
+	r, err := distreference.ParseNormalizedNamed(name)
82 82
 	if err != nil {
83 83
 		return nil, err
84 84
 	}
85
-	if err := validateName(name); err != nil {
85
+	if err := validateName(distreference.FamiliarName(r)); err != nil {
86 86
 		return nil, err
87 87
 	}
88
-	r, err := distreference.WithName(name)
89
-	if err != nil {
90
-		return nil, err
88
+	if !distreference.IsNameOnly(r) {
89
+		return nil, distreference.ErrReferenceInvalidFormat
91 90
 	}
92 91
 	return &namedRef{r}, nil
93 92
 }
... ...
@@ -122,17 +130,22 @@ type canonicalRef struct {
122 122
 	namedRef
123 123
 }
124 124
 
125
+func (r *namedRef) Name() string {
126
+	return distreference.FamiliarName(r.Named)
127
+}
128
+
129
+func (r *namedRef) String() string {
130
+	return distreference.FamiliarString(r.Named)
131
+}
132
+
125 133
 func (r *namedRef) FullName() string {
126
-	hostname, remoteName := splitHostname(r.Name())
127
-	return hostname + "/" + remoteName
134
+	return r.Named.Name()
128 135
 }
129 136
 func (r *namedRef) Hostname() string {
130
-	hostname, _ := splitHostname(r.Name())
131
-	return hostname
137
+	return distreference.Domain(r.Named)
132 138
 }
133 139
 func (r *namedRef) RemoteName() string {
134
-	_, remoteName := splitHostname(r.Name())
135
-	return remoteName
140
+	return distreference.Path(r.Named)
136 141
 }
137 142
 func (r *taggedRef) Tag() string {
138 143
 	return r.namedRef.Named.(distreference.NamedTagged).Tag()
... ...
@@ -173,41 +186,6 @@ func ParseIDOrReference(idOrRef string) (digest.Digest, Named, error) {
173 173
 	return "", ref, err
174 174
 }
175 175
 
176
-// splitHostname splits a repository name to hostname and remotename string.
177
-// If no valid hostname is found, the default hostname is used. Repository name
178
-// needs to be already validated before.
179
-func splitHostname(name string) (hostname, remoteName string) {
180
-	i := strings.IndexRune(name, '/')
181
-	if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
182
-		hostname, remoteName = DefaultHostname, name
183
-	} else {
184
-		hostname, remoteName = name[:i], name[i+1:]
185
-	}
186
-	if hostname == LegacyDefaultHostname {
187
-		hostname = DefaultHostname
188
-	}
189
-	if hostname == DefaultHostname && !strings.ContainsRune(remoteName, '/') {
190
-		remoteName = DefaultRepoPrefix + remoteName
191
-	}
192
-	return
193
-}
194
-
195
-// normalize returns a repository name in its normalized form, meaning it
196
-// will not contain default hostname nor library/ prefix for official images.
197
-func normalize(name string) (string, error) {
198
-	host, remoteName := splitHostname(name)
199
-	if strings.ToLower(remoteName) != remoteName {
200
-		return "", errors.New("invalid reference format: repository name must be lowercase")
201
-	}
202
-	if host == DefaultHostname {
203
-		if strings.HasPrefix(remoteName, DefaultRepoPrefix) {
204
-			return strings.TrimPrefix(remoteName, DefaultRepoPrefix), nil
205
-		}
206
-		return remoteName, nil
207
-	}
208
-	return name, nil
209
-}
210
-
211 176
 func validateName(name string) error {
212 177
 	if err := stringid.ValidateID(name); err == nil {
213 178
 		return fmt.Errorf("Invalid repository name (%s), cannot specify 64-byte hexadecimal strings", name)
... ...
@@ -1,16 +1,17 @@
1 1
 package registry
2 2
 
3 3
 import (
4
-	"errors"
5 4
 	"fmt"
6 5
 	"net"
7 6
 	"net/url"
8 7
 	"strings"
9 8
 
10 9
 	"github.com/Sirupsen/logrus"
10
+	"github.com/docker/distribution/reference"
11 11
 	registrytypes "github.com/docker/docker/api/types/registry"
12 12
 	"github.com/docker/docker/opts"
13
-	"github.com/docker/docker/reference"
13
+	forkedref "github.com/docker/docker/reference"
14
+	"github.com/pkg/errors"
14 15
 	"github.com/spf13/pflag"
15 16
 )
16 17
 
... ...
@@ -270,8 +271,8 @@ func ValidateMirror(val string) (string, error) {
270 270
 
271 271
 // ValidateIndexName validates an index name.
272 272
 func ValidateIndexName(val string) (string, error) {
273
-	if val == reference.LegacyDefaultHostname {
274
-		val = reference.DefaultHostname
273
+	if val == forkedref.LegacyDefaultHostname {
274
+		val = forkedref.DefaultHostname
275 275
 	}
276 276
 	if strings.HasPrefix(val, "-") || strings.HasSuffix(val, "-") {
277 277
 		return "", fmt.Errorf("Invalid index name (%s). Cannot begin or end with a hyphen.", val)
... ...
@@ -321,13 +322,19 @@ func GetAuthConfigKey(index *registrytypes.IndexInfo) string {
321 321
 
322 322
 // newRepositoryInfo validates and breaks down a repository name into a RepositoryInfo
323 323
 func newRepositoryInfo(config *serviceConfig, name reference.Named) (*RepositoryInfo, error) {
324
-	index, err := newIndexInfo(config, name.Hostname())
324
+	index, err := newIndexInfo(config, reference.Domain(name))
325
+	if err != nil {
326
+		return nil, err
327
+	}
328
+	official := !strings.ContainsRune(reference.FamiliarName(name), '/')
329
+
330
+	// TODO: remove used of forked reference package
331
+	nameref, err := forkedref.ParseNamed(name.String())
325 332
 	if err != nil {
326 333
 		return nil, err
327 334
 	}
328
-	official := !strings.ContainsRune(name.Name(), '/')
329 335
 	return &RepositoryInfo{
330
-		Named:    name,
336
+		Named:    nameref,
331 337
 		Index:    index,
332 338
 		Official: official,
333 339
 	}, nil
... ...
@@ -10,10 +10,11 @@ import (
10 10
 	"strings"
11 11
 	"testing"
12 12
 
13
+	"github.com/docker/distribution/reference"
13 14
 	"github.com/docker/distribution/registry/client/transport"
14 15
 	"github.com/docker/docker/api/types"
15 16
 	registrytypes "github.com/docker/docker/api/types/registry"
16
-	"github.com/docker/docker/reference"
17
+	forkedref "github.com/docker/docker/reference"
17 18
 )
18 19
 
19 20
 var (
... ...
@@ -201,7 +202,7 @@ func TestGetRemoteImageLayer(t *testing.T) {
201 201
 
202 202
 func TestGetRemoteTag(t *testing.T) {
203 203
 	r := spawnTestRegistrySession(t)
204
-	repoRef, err := reference.ParseNamed(REPO)
204
+	repoRef, err := forkedref.ParseNamed(REPO)
205 205
 	if err != nil {
206 206
 		t.Fatal(err)
207 207
 	}
... ...
@@ -211,7 +212,7 @@ func TestGetRemoteTag(t *testing.T) {
211 211
 	}
212 212
 	assertEqual(t, tag, imageID, "Expected tag test to map to "+imageID)
213 213
 
214
-	bazRef, err := reference.ParseNamed("foo42/baz")
214
+	bazRef, err := forkedref.ParseNamed("foo42/baz")
215 215
 	if err != nil {
216 216
 		t.Fatal(err)
217 217
 	}
... ...
@@ -223,7 +224,7 @@ func TestGetRemoteTag(t *testing.T) {
223 223
 
224 224
 func TestGetRemoteTags(t *testing.T) {
225 225
 	r := spawnTestRegistrySession(t)
226
-	repoRef, err := reference.ParseNamed(REPO)
226
+	repoRef, err := forkedref.ParseNamed(REPO)
227 227
 	if err != nil {
228 228
 		t.Fatal(err)
229 229
 	}
... ...
@@ -235,7 +236,7 @@ func TestGetRemoteTags(t *testing.T) {
235 235
 	assertEqual(t, tags["latest"], imageID, "Expected tag latest to map to "+imageID)
236 236
 	assertEqual(t, tags["test"], imageID, "Expected tag test to map to "+imageID)
237 237
 
238
-	bazRef, err := reference.ParseNamed("foo42/baz")
238
+	bazRef, err := forkedref.ParseNamed("foo42/baz")
239 239
 	if err != nil {
240 240
 		t.Fatal(err)
241 241
 	}
... ...
@@ -252,7 +253,7 @@ func TestGetRepositoryData(t *testing.T) {
252 252
 		t.Fatal(err)
253 253
 	}
254 254
 	host := "http://" + parsedURL.Host + "/v1/"
255
-	repoRef, err := reference.ParseNamed(REPO)
255
+	repoRef, err := forkedref.ParseNamed(REPO)
256 256
 	if err != nil {
257 257
 		t.Fatal(err)
258 258
 	}
... ...
@@ -505,7 +506,7 @@ func TestParseRepositoryInfo(t *testing.T) {
505 505
 	}
506 506
 
507 507
 	for reposName, expectedRepoInfo := range expectedRepoInfos {
508
-		named, err := reference.WithName(reposName)
508
+		named, err := reference.ParseNormalizedNamed(reposName)
509 509
 		if err != nil {
510 510
 			t.Error(err)
511 511
 		}
... ...
@@ -669,7 +670,7 @@ func TestMirrorEndpointLookup(t *testing.T) {
669 669
 	if err != nil {
670 670
 		t.Error(err)
671 671
 	}
672
-	pushAPIEndpoints, err := s.LookupPushEndpoints(imageName.Hostname())
672
+	pushAPIEndpoints, err := s.LookupPushEndpoints(reference.Domain(imageName))
673 673
 	if err != nil {
674 674
 		t.Fatal(err)
675 675
 	}
... ...
@@ -677,7 +678,7 @@ func TestMirrorEndpointLookup(t *testing.T) {
677 677
 		t.Fatal("Push endpoint should not contain mirror")
678 678
 	}
679 679
 
680
-	pullAPIEndpoints, err := s.LookupPullEndpoints(imageName.Hostname())
680
+	pullAPIEndpoints, err := s.LookupPullEndpoints(reference.Domain(imageName))
681 681
 	if err != nil {
682 682
 		t.Fatal(err)
683 683
 	}
... ...
@@ -688,7 +689,7 @@ func TestMirrorEndpointLookup(t *testing.T) {
688 688
 
689 689
 func TestPushRegistryTag(t *testing.T) {
690 690
 	r := spawnTestRegistrySession(t)
691
-	repoRef, err := reference.ParseNamed(REPO)
691
+	repoRef, err := forkedref.ParseNamed(REPO)
692 692
 	if err != nil {
693 693
 		t.Fatal(err)
694 694
 	}
... ...
@@ -710,7 +711,7 @@ func TestPushImageJSONIndex(t *testing.T) {
710 710
 			Checksum: "sha256:bea7bf2e4bacd479344b737328db47b18880d09096e6674165533aa994f5e9f2",
711 711
 		},
712 712
 	}
713
-	repoRef, err := reference.ParseNamed(REPO)
713
+	repoRef, err := forkedref.ParseNamed(REPO)
714 714
 	if err != nil {
715 715
 		t.Fatal(err)
716 716
 	}
... ...
@@ -11,10 +11,10 @@ import (
11 11
 	"golang.org/x/net/context"
12 12
 
13 13
 	"github.com/Sirupsen/logrus"
14
+	"github.com/docker/distribution/reference"
14 15
 	"github.com/docker/distribution/registry/client/auth"
15 16
 	"github.com/docker/docker/api/types"
16 17
 	registrytypes "github.com/docker/docker/api/types/registry"
17
-	"github.com/docker/docker/reference"
18 18
 )
19 19
 
20 20
 const (