This function was exported in 812f1136850f6c18bbe3f1b2a960a8ff8a8413f3 for use in other parts of the CLI, but it's now only used locally. Make it internal again, as it was never designed to be exported. There are no known external consumers of this function, but deprecating it first, in case there are. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
102 lines
3.0 KiB
Go
102 lines
3.0 KiB
Go
package image
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/distribution/reference"
|
|
"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/pkg/errors"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// PullOptions defines what and how to pull
|
|
type PullOptions = pullOptions
|
|
|
|
// 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(cmd.Context(), 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())
|
|
|
|
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
|
|
|
return cmd
|
|
}
|
|
|
|
// RunPull performs a pull against the engine based on the specified options
|
|
func RunPull(ctx context.Context, dockerCLI command.Cli, opts PullOptions) error {
|
|
return runPull(ctx, dockerCLI, opts)
|
|
}
|
|
|
|
// runPull performs a pull against the engine based on the specified options
|
|
func runPull(ctx context.Context, dockerCLI 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.Fprintln(dockerCLI.Out(), "Using default tag:", tagged.Tag())
|
|
}
|
|
}
|
|
|
|
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(dockerCLI), distributionRef.String())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Check if reference has a digest
|
|
_, isCanonical := distributionRef.(reference.Canonical)
|
|
if !opts.untrusted && !isCanonical {
|
|
err = trustedPull(ctx, dockerCLI, imgRefAndAuth, opts)
|
|
} else {
|
|
err = imagePullPrivileged(ctx, dockerCLI, 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(dockerCLI.Out(), imgRefAndAuth.Reference().String())
|
|
return nil
|
|
}
|