This code depended on the registry Service interface, which has been removed, so needed to be refactored. Digging further into the reason this code existed, it looked like the Class=plugin was previously required on Docker Hub to handle plugins, but this requirement is no longer there, so we can remove this special handling. This patch removes the special handling to both remove the use of the registry.Service interface, as well as removing complexity that is no longer needed. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
93 lines
2.6 KiB
Go
93 lines
2.6 KiB
Go
package image
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/docker/cli/cli"
|
|
"github.com/docker/cli/cli/command"
|
|
"github.com/docker/cli/cli/command/completion"
|
|
"github.com/docker/cli/cli/trust"
|
|
"github.com/docker/distribution/reference"
|
|
"github.com/pkg/errors"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// PullOptions defines what and how to pull
|
|
type PullOptions struct {
|
|
remote string
|
|
all bool
|
|
platform string
|
|
quiet bool
|
|
untrusted bool
|
|
}
|
|
|
|
// NewPullCommand creates a new `docker pull` command
|
|
func NewPullCommand(dockerCli command.Cli) *cobra.Command {
|
|
var opts PullOptions
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "pull [OPTIONS] NAME[:TAG|@DIGEST]",
|
|
Short: "Download an image from a registry",
|
|
Args: cli.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
opts.remote = args[0]
|
|
return RunPull(dockerCli, opts)
|
|
},
|
|
Annotations: map[string]string{
|
|
"category-top": "5",
|
|
"aliases": "docker image pull, docker pull",
|
|
},
|
|
ValidArgsFunction: completion.NoComplete,
|
|
}
|
|
|
|
flags := cmd.Flags()
|
|
|
|
flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")
|
|
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress verbose output")
|
|
|
|
command.AddPlatformFlag(flags, &opts.platform)
|
|
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
|
|
|
|
return cmd
|
|
}
|
|
|
|
// RunPull performs a pull against the engine based on the specified options
|
|
func RunPull(cli command.Cli, opts PullOptions) error {
|
|
distributionRef, err := reference.ParseNormalizedNamed(opts.remote)
|
|
switch {
|
|
case err != nil:
|
|
return err
|
|
case opts.all && !reference.IsNameOnly(distributionRef):
|
|
return errors.New("tag can't be used with --all-tags/-a")
|
|
case !opts.all && reference.IsNameOnly(distributionRef):
|
|
distributionRef = reference.TagNameOnly(distributionRef)
|
|
if tagged, ok := distributionRef.(reference.Tagged); ok && !opts.quiet {
|
|
fmt.Fprintf(cli.Out(), "Using default tag: %s\n", tagged.Tag())
|
|
}
|
|
}
|
|
|
|
ctx := context.Background()
|
|
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), distributionRef.String())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Check if reference has a digest
|
|
_, isCanonical := distributionRef.(reference.Canonical)
|
|
if !opts.untrusted && !isCanonical {
|
|
err = trustedPull(ctx, cli, imgRefAndAuth, opts)
|
|
} else {
|
|
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts)
|
|
}
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "when fetching 'plugin'") {
|
|
return errors.New(err.Error() + " - Use `docker plugin install`")
|
|
}
|
|
return err
|
|
}
|
|
fmt.Fprintln(cli.Out(), imgRefAndAuth.Reference().String())
|
|
return nil
|
|
}
|