mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00

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)
86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
package image
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"golang.org/x/net/context"
|
|
|
|
"github.com/docker/distribution/reference"
|
|
"github.com/docker/docker/cli"
|
|
"github.com/docker/docker/cli/command"
|
|
"github.com/docker/docker/registry"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
type pullOptions struct {
|
|
remote string
|
|
all bool
|
|
}
|
|
|
|
// NewPullCommand creates a new `docker pull` command
|
|
func NewPullCommand(dockerCli *command.DockerCli) *cobra.Command {
|
|
var opts pullOptions
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "pull [OPTIONS] NAME[:TAG|@DIGEST]",
|
|
Short: "Pull an image or a repository from a registry",
|
|
Args: cli.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
opts.remote = args[0]
|
|
return runPull(dockerCli, opts)
|
|
},
|
|
}
|
|
|
|
flags := cmd.Flags()
|
|
|
|
flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")
|
|
command.AddTrustVerificationFlags(flags)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func runPull(dockerCli *command.DockerCli, opts pullOptions) error {
|
|
distributionRef, err := reference.ParseNormalizedNamed(opts.remote)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if opts.all && !reference.IsNameOnly(distributionRef) {
|
|
return errors.New("tag can't be used with --all-tags/-a")
|
|
}
|
|
|
|
if !opts.all && reference.IsNameOnly(distributionRef) {
|
|
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
|
|
repoInfo, err := registry.ParseRepositoryInfo(distributionRef)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
authConfig := command.ResolveAuthConfig(ctx, dockerCli, repoInfo.Index)
|
|
requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, repoInfo.Index, "pull")
|
|
|
|
// Check if reference has a digest
|
|
_, isCanonical := distributionRef.(reference.Canonical)
|
|
if command.IsTrusted() && !isCanonical {
|
|
err = trustedPull(ctx, dockerCli, repoInfo, distributionRef, authConfig, requestPrivilege)
|
|
} else {
|
|
err = imagePullPrivileged(ctx, dockerCli, authConfig, reference.FamiliarString(distributionRef), requestPrivilege, opts.all)
|
|
}
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "target is plugin") {
|
|
return errors.New(err.Error() + " - Use `docker plugin install`")
|
|
}
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|