diff --git a/command/container/create.go b/command/container/create.go index cfd672e77a..9559ba0c05 100644 --- a/command/container/create.go +++ b/command/container/create.go @@ -168,11 +168,7 @@ func createContainer(ctx context.Context, dockerCli *command.DockerCli, config * return nil, err } if named, ok := ref.(reference.Named); ok { - if reference.IsNameOnly(named) { - namedRef = reference.EnsureTagged(named) - } else { - namedRef = named - } + namedRef = reference.TagNameOnly(named) if taggedRef, ok := namedRef.(reference.NamedTagged); ok && command.IsTrusted() { var err error diff --git a/command/formatter/disk_usage.go b/command/formatter/disk_usage.go index dc5eec41d7..fd7aabc7c2 100644 --- a/command/formatter/disk_usage.go +++ b/command/formatter/disk_usage.go @@ -94,12 +94,12 @@ func (ctx *DiskUsageContext) Write() { tag := "" if len(i.RepoTags) > 0 && !isDangling(*i) { // Only show the first tag - ref, err := reference.ParseNamed(i.RepoTags[0]) + ref, err := reference.ParseNormalizedNamed(i.RepoTags[0]) if err != nil { continue } if nt, ok := ref.(reference.NamedTagged); ok { - repo = ref.Name() + repo = reference.FamiliarName(ref) tag = nt.Tag() } } diff --git a/command/formatter/image.go b/command/formatter/image.go index 06319b9355..b6508224a3 100644 --- a/command/formatter/image.go +++ b/command/formatter/image.go @@ -94,7 +94,7 @@ func imageFormat(ctx ImageContext, images []types.ImageSummary, format func(subC repoTags := map[string][]string{} repoDigests := map[string][]string{} - for _, refString := range append(image.RepoTags) { + for _, refString := range image.RepoTags { ref, err := reference.ParseNormalizedNamed(refString) if err != nil { continue @@ -104,7 +104,7 @@ func imageFormat(ctx ImageContext, images []types.ImageSummary, format func(subC repoTags[familiarRef] = append(repoTags[familiarRef], nt.Tag()) } } - for _, refString := range append(image.RepoDigests) { + for _, refString := range image.RepoDigests { ref, err := reference.ParseNormalizedNamed(refString) if err != nil { continue diff --git a/command/formatter/service.go b/command/formatter/service.go index 9d9241b224..8e38cb3a11 100644 --- a/command/formatter/service.go +++ b/command/formatter/service.go @@ -5,7 +5,7 @@ import ( "strings" "time" - distreference "github.com/docker/distribution/reference" + "github.com/docker/distribution/reference" mounttypes "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/cli/command/inspect" @@ -409,11 +409,12 @@ func (c *serviceContext) Replicas() string { func (c *serviceContext) Image() string { c.AddHeader(imageHeader) image := c.service.Spec.TaskTemplate.ContainerSpec.Image - if ref, err := distreference.ParseNamed(image); err == nil { - // update image string for display - namedTagged, ok := ref.(distreference.NamedTagged) - if ok { - image = namedTagged.Name() + ":" + namedTagged.Tag() + if ref, err := reference.ParseNormalizedNamed(image); err == nil { + // update image string for display, (strips any digest) + if nt, ok := ref.(reference.NamedTagged); ok { + if namedTagged, err := reference.WithTag(reference.TrimNamed(nt), nt.Tag()); err == nil { + image = reference.FamiliarString(namedTagged) + } } } diff --git a/command/image/build.go b/command/image/build.go index 34e0a39500..96d90cf585 100644 --- a/command/image/build.go +++ b/command/image/build.go @@ -397,9 +397,7 @@ func rewriteDockerfileFrom(ctx context.Context, dockerfile io.Reader, translator if err != nil { return nil, nil, err } - if reference.IsNameOnly(ref) { - ref = reference.EnsureTagged(ref) - } + ref = reference.TagNameOnly(ref) if ref, ok := ref.(reference.NamedTagged); ok && command.IsTrusted() { trustedRef, err := translator(ctx, ref) if err != nil { diff --git a/command/image/pull.go b/command/image/pull.go index 967beca86f..515273d43c 100644 --- a/command/image/pull.go +++ b/command/image/pull.go @@ -42,7 +42,6 @@ func NewPullCommand(dockerCli *command.DockerCli) *cobra.Command { } func runPull(dockerCli *command.DockerCli, opts pullOptions) error { - var distributionRef reference.Named distributionRef, err := reference.ParseNormalizedNamed(opts.remote) if err != nil { return err @@ -52,9 +51,10 @@ func runPull(dockerCli *command.DockerCli, opts pullOptions) error { } if !opts.all && reference.IsNameOnly(distributionRef) { - taggedRef := reference.EnsureTagged(distributionRef) - fmt.Fprintf(dockerCli.Out(), "Using default tag: %s\n", taggedRef.Tag()) - distributionRef = taggedRef + distributionRef = reference.TagNameOnly(distributionRef) + if tagged, ok := distributionRef.(reference.Tagged); ok { + fmt.Fprintf(dockerCli.Out(), "Using default tag: %s\n", tagged.Tag()) + } } // Resolve the Repository name from fqn to RepositoryInfo diff --git a/command/image/trust.go b/command/image/trust.go index 2ff9b463d5..8332dd7deb 100644 --- a/command/image/trust.go +++ b/command/image/trust.go @@ -129,15 +129,15 @@ func PushTrustedReference(cli *command.DockerCli, repoInfo *registry.RepositoryI // Initialize the notary repository with a remotely managed snapshot key if err := repo.Initialize([]string{rootKeyID}, data.CanonicalSnapshotRole); err != nil { - return trust.NotaryError(repoInfo.FullName(), err) + return trust.NotaryError(repoInfo.Name.Name(), err) } - fmt.Fprintf(cli.Out(), "Finished initializing %q\n", repoInfo.FullName()) + fmt.Fprintf(cli.Out(), "Finished initializing %q\n", repoInfo.Name.Name()) err = repo.AddTarget(target, data.CanonicalTargetsRole) case nil: // already initialized and we have successfully downloaded the latest metadata err = addTargetToAllSignableRoles(repo, target) default: - return trust.NotaryError(repoInfo.FullName(), err) + return trust.NotaryError(repoInfo.Name.Name(), err) } if err == nil { @@ -145,11 +145,11 @@ func PushTrustedReference(cli *command.DockerCli, repoInfo *registry.RepositoryI } if err != nil { - fmt.Fprintf(cli.Out(), "Failed to sign %q:%s - %s\n", repoInfo.FullName(), tag, err.Error()) - return trust.NotaryError(repoInfo.FullName(), err) + fmt.Fprintf(cli.Out(), "Failed to sign %q:%s - %s\n", repoInfo.Name.Name(), tag, err.Error()) + return trust.NotaryError(repoInfo.Name.Name(), err) } - fmt.Fprintf(cli.Out(), "Successfully signed %q:%s\n", repoInfo.FullName(), tag) + fmt.Fprintf(cli.Out(), "Successfully signed %q:%s\n", repoInfo.Name.Name(), tag) return nil } @@ -342,12 +342,12 @@ func TrustedReference(ctx context.Context, cli *command.DockerCli, ref reference t, err := notaryRepo.GetTargetByName(ref.Tag(), trust.ReleasesRole, data.CanonicalTargetsRole) if err != nil { - return nil, trust.NotaryError(repoInfo.FullName(), err) + return nil, trust.NotaryError(repoInfo.Name.Name(), err) } // Only list tags in the top level targets role or the releases delegation role - ignore // all other delegation roles if t.Role != trust.ReleasesRole && t.Role != data.CanonicalTargetsRole { - return nil, trust.NotaryError(repoInfo.FullName(), fmt.Errorf("No trust data for %s", ref.Tag())) + return nil, trust.NotaryError(repoInfo.Name.Name(), fmt.Errorf("No trust data for %s", ref.Tag())) } r, err := convertTarget(t.Target) if err != nil { diff --git a/command/plugin/install.go b/command/plugin/install.go index 15877761af..9e9ea40e2a 100644 --- a/command/plugin/install.go +++ b/command/plugin/install.go @@ -7,7 +7,6 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" - registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/cli" "github.com/docker/docker/cli/command" "github.com/docker/docker/cli/command/image" @@ -54,20 +53,6 @@ func newInstallCommand(dockerCli *command.DockerCli) *cobra.Command { return cmd } -func getRepoIndexFromUnnormalizedRef(ref reference.Named) (*registrytypes.IndexInfo, error) { - named, err := reference.ParseNormalizedNamed(ref.Name()) - if err != nil { - return nil, err - } - - repoInfo, err := registry.ParseRepositoryInfo(named) - if err != nil { - return nil, err - } - - return repoInfo.Index, nil -} - type pluginRegistryService struct { registry.Service } @@ -104,9 +89,10 @@ func buildPullConfig(ctx context.Context, dockerCli *command.DockerCli, opts plu _, isCanonical := ref.(reference.Canonical) if command.IsTrusted() && !isCanonical { + ref = reference.TagNameOnly(ref) nt, ok := ref.(reference.NamedTagged) if !ok { - nt = reference.EnsureTagged(ref) + return types.PluginInstallOptions{}, fmt.Errorf("invalid name: %s", ref.String()) } ctx := context.Background() @@ -148,7 +134,7 @@ func runInstall(dockerCli *command.DockerCli, opts pluginOptions) error { if _, ok := aref.(reference.Canonical); ok { return fmt.Errorf("invalid name: %s", opts.localName) } - localName = reference.FamiliarString(reference.EnsureTagged(aref)) + localName = reference.FamiliarString(reference.TagNameOnly(aref)) } ctx := context.Background() diff --git a/command/plugin/push.go b/command/plugin/push.go index 6b826dce68..f3643b7f1b 100644 --- a/command/plugin/push.go +++ b/command/plugin/push.go @@ -40,10 +40,7 @@ func runPush(dockerCli *command.DockerCli, name string) error { return fmt.Errorf("invalid name: %s", name) } - taggedRef, ok := named.(reference.NamedTagged) - if !ok { - taggedRef = reference.EnsureTagged(named) - } + named = reference.TagNameOnly(named) ctx := context.Background() @@ -58,7 +55,7 @@ func runPush(dockerCli *command.DockerCli, name string) error { return err } - responseBody, err := dockerCli.Client().PluginPush(ctx, reference.FamiliarString(taggedRef), encodedAuth) + responseBody, err := dockerCli.Client().PluginPush(ctx, reference.FamiliarString(named), encodedAuth) if err != nil { return err } diff --git a/command/plugin/upgrade.go b/command/plugin/upgrade.go index 6861aa1b32..07f0c7bb91 100644 --- a/command/plugin/upgrade.go +++ b/command/plugin/upgrade.go @@ -5,10 +5,10 @@ import ( "fmt" "strings" + "github.com/docker/distribution/reference" "github.com/docker/docker/cli" "github.com/docker/docker/cli/command" "github.com/docker/docker/pkg/jsonmessage" - "github.com/docker/docker/reference" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -49,19 +49,19 @@ func runUpgrade(dockerCli *command.DockerCli, opts pluginOptions) error { if opts.remote == "" { opts.remote = p.PluginReference } - remote, err := reference.ParseNamed(opts.remote) + remote, err := reference.ParseNormalizedNamed(opts.remote) if err != nil { return errors.Wrap(err, "error parsing remote upgrade image reference") } - remote = reference.WithDefaultTag(remote) + remote = reference.TagNameOnly(remote) - old, err := reference.ParseNamed(p.PluginReference) + old, err := reference.ParseNormalizedNamed(p.PluginReference) if err != nil { return errors.Wrap(err, "error parsing current image reference") } - old = reference.WithDefaultTag(old) + old = reference.TagNameOnly(old) - fmt.Fprintf(dockerCli.Out(), "Upgrading plugin %s from %s to %s\n", p.Name, old, remote) + fmt.Fprintf(dockerCli.Out(), "Upgrading plugin %s from %s to %s\n", p.Name, reference.FamiliarString(old), reference.FamiliarString(remote)) if !opts.skipRemoteCheck && remote.String() != old.String() { if !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), "Plugin images do not match, are you sure?") { return errors.New("canceling upgrade request") diff --git a/command/service/trust.go b/command/service/trust.go index d466f3b648..3fd80ae879 100644 --- a/command/service/trust.go +++ b/command/service/trust.go @@ -33,10 +33,12 @@ func resolveServiceImageDigest(dockerCli *command.DockerCli, service *swarm.Serv namedRef, ok := ref.(reference.Named) if !ok { return errors.New("failed to resolve image digest using content trust: reference is not named") - } - - taggedRef := reference.EnsureTagged(namedRef) + namedRef = reference.TagNameOnly(namedRef) + taggedRef, ok := namedRef.(reference.NamedTagged) + if !ok { + return errors.New("failed to resolve image digest using content trust: reference is not tagged") + } resolvedImage, err := trustedResolveDigest(context.Background(), dockerCli, taggedRef) if err != nil { @@ -65,12 +67,12 @@ func trustedResolveDigest(ctx context.Context, cli *command.DockerCli, ref refer t, err := notaryRepo.GetTargetByName(ref.Tag(), trust.ReleasesRole, data.CanonicalTargetsRole) if err != nil { - return nil, trust.NotaryError(repoInfo.FullName(), err) + return nil, trust.NotaryError(repoInfo.Name.Name(), err) } // Only get the tag if it's in the top level targets role or the releases delegation role // ignore it if it's in any other delegation roles if t.Role != trust.ReleasesRole && t.Role != data.CanonicalTargetsRole { - return nil, trust.NotaryError(repoInfo.FullName(), fmt.Errorf("No trust data for %s", reference.FamiliarString(ref))) + return nil, trust.NotaryError(repoInfo.Name.Name(), fmt.Errorf("No trust data for %s", reference.FamiliarString(ref))) } logrus.Debugf("retrieving target for %s role\n", t.Role) diff --git a/command/task/print.go b/command/task/print.go index 60a2bca85b..d7e20bb59a 100644 --- a/command/task/print.go +++ b/command/task/print.go @@ -10,7 +10,7 @@ import ( "golang.org/x/net/context" - distreference "github.com/docker/distribution/reference" + "github.com/docker/distribution/reference" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/cli/command" "github.com/docker/docker/cli/command/idresolver" @@ -129,13 +129,15 @@ func print(out io.Writer, ctx context.Context, tasks []swarm.Task, resolver *idr image := task.Spec.ContainerSpec.Image if !noTrunc { - ref, err := distreference.ParseNamed(image) + ref, err := reference.ParseNormalizedNamed(image) if err == nil { - // update image string for display - namedTagged, ok := ref.(distreference.NamedTagged) - if ok { - image = namedTagged.Name() + ":" + namedTagged.Tag() + // update image string for display, (strips any digest) + if nt, ok := ref.(reference.NamedTagged); ok { + if namedTagged, err := reference.WithTag(reference.TrimNamed(nt), nt.Tag()); err == nil { + image = reference.FamiliarString(namedTagged) + } } + } } diff --git a/trust/trust.go b/trust/trust.go index 44f8197ba2..777a611181 100644 --- a/trust/trust.go +++ b/trust/trust.go @@ -148,7 +148,7 @@ func GetNotaryRepository(streams command.Streams, repoInfo *registry.RepositoryI } scope := auth.RepositoryScope{ - Repository: repoInfo.FullName(), + Repository: repoInfo.Name.Name(), Actions: actions, Class: repoInfo.Class, } @@ -166,7 +166,7 @@ func GetNotaryRepository(streams command.Streams, repoInfo *registry.RepositoryI return client.NewNotaryRepository( trustDirectory(), - repoInfo.FullName(), + repoInfo.Name.Name(), server, tr, getPassphraseRetriever(streams),