mirror of https://github.com/docker/cli.git
Use distribution reference
Remove forked reference package. Use normalized named values everywhere and familiar functions to convert back to familiar strings for UX and storage compatibility. Enforce that the source repository in the distribution metadata is always a normalized string, ignore invalid values which are not. Update distribution tests to use normalized values. Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
parent
a4cd8a978f
commit
635d686a88
|
@ -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
|
||||
|
|
|
@ -94,12 +94,12 @@ func (ctx *DiskUsageContext) Write() {
|
|||
tag := "<none>"
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,14 +129,16 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue