aboutsummaryrefslogtreecommitdiff
path: root/cmd/podman/pull.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman/pull.go')
-rw-r--r--cmd/podman/pull.go168
1 files changed, 106 insertions, 62 deletions
diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go
index 2349265d0..71f555162 100644
--- a/cmd/podman/pull.go
+++ b/cmd/podman/pull.go
@@ -6,88 +6,93 @@ import (
"os"
"strings"
+ "github.com/containers/image/docker"
dockerarchive "github.com/containers/image/docker/archive"
"github.com/containers/image/transports/alltransports"
"github.com/containers/image/types"
- "github.com/containers/libpod/libpod/adapter"
+ "github.com/containers/libpod/cmd/podman/cliconfig"
+ "github.com/containers/libpod/libpod/common"
image2 "github.com/containers/libpod/libpod/image"
+ "github.com/containers/libpod/pkg/adapter"
"github.com/containers/libpod/pkg/util"
+ opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "github.com/urfave/cli"
+ "github.com/spf13/cobra"
)
var (
- pullFlags = []cli.Flag{
- cli.StringFlag{
- Name: "authfile",
- Usage: "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override. ",
- },
- cli.StringFlag{
- Name: "cert-dir",
- Usage: "`pathname` of a directory containing TLS certificates and keys",
- },
- cli.StringFlag{
- Name: "creds",
- Usage: "`credentials` (USERNAME:PASSWORD) to use for authenticating to a registry",
- },
- cli.BoolFlag{
- Name: "quiet, q",
- Usage: "Suppress output information when pulling images",
- },
- cli.StringFlag{
- Name: "signature-policy",
- Usage: "`pathname` of signature policy file (not usually used)",
- },
- cli.BoolTFlag{
- Name: "tls-verify",
- Usage: "Require HTTPS and verify certificates when contacting registries (default: true)",
- },
- }
-
+ pullCommand cliconfig.PullValues
pullDescription = `
Pulls an image from a registry and stores it locally.
An image can be pulled using its tag or digest. If a tag is not
specified, the image with the 'latest' tag (if it exists) is pulled
`
- pullCommand = cli.Command{
- Name: "pull",
- Usage: "Pull an image from a registry",
- Description: pullDescription,
- Flags: sortFlags(pullFlags),
- Action: pullCmd,
- ArgsUsage: "",
- OnUsageError: usageErrorHandler,
+ _pullCommand = &cobra.Command{
+ Use: "pull",
+ Short: "Pull an image from a registry",
+ Long: pullDescription,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ pullCommand.InputArgs = args
+ pullCommand.GlobalFlags = MainGlobalOpts
+ return pullCmd(&pullCommand)
+ },
+ Example: `podman pull imageName
+ podman pull --cert-dir image/certs --authfile temp-auths/myauths.json docker://docker.io/myrepo/finaltest
+ podman pull fedora:latest`,
}
)
+func init() {
+ pullCommand.Command = _pullCommand
+ pullCommand.SetUsageTemplate(UsageTemplate())
+ flags := pullCommand.Flags()
+ flags.BoolVar(&pullCommand.AllTags, "all-tags", false, "All tagged images inthe repository will be pulled")
+ flags.StringVar(&pullCommand.Authfile, "authfile", "", "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override")
+ flags.StringVar(&pullCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys")
+ flags.StringVar(&pullCommand.Creds, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry")
+ flags.BoolVarP(&pullCommand.Quiet, "quiet", "q", false, "Suppress output information when pulling images")
+ flags.StringVar(&pullCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)")
+ flags.BoolVar(&pullCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries (default: true)")
+
+}
+
// pullCmd gets the data from the command line and calls pullImage
// to copy an image from a registry to a local machine
-func pullCmd(c *cli.Context) error {
- runtime, err := adapter.GetRuntime(c)
+func pullCmd(c *cliconfig.PullValues) error {
+ if c.Bool("trace") {
+ span, _ := opentracing.StartSpanFromContext(Ctx, "pullCmd")
+ defer span.Finish()
+ }
+
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
- args := c.Args()
+ args := c.InputArgs
if len(args) == 0 {
- logrus.Errorf("an image name must be specified")
- return nil
+ return errors.Errorf("an image name must be specified")
}
if len(args) > 1 {
- logrus.Errorf("too many arguments. Requires exactly 1")
- return nil
+ return errors.Errorf("too many arguments. Requires exactly 1")
}
- if err := validateFlags(c, pullFlags); err != nil {
- return err
+
+ arr := strings.SplitN(args[0], ":", 2)
+ if len(arr) == 2 {
+ if c.Bool("all-tags") {
+ return errors.Errorf("tag can't be used with --all-tags")
+ }
}
+ ctx := getContext()
image := args[0]
var registryCreds *types.DockerAuthConfig
- if c.IsSet("creds") {
- creds, err := util.ParseRegistryCreds(c.String("creds"))
+ if c.Flag("creds").Changed {
+ creds, err := util.ParseRegistryCreds(c.Creds)
if err != nil {
return err
}
@@ -96,18 +101,17 @@ func pullCmd(c *cli.Context) error {
var (
writer io.Writer
- imgID string
)
- if !c.Bool("quiet") {
+ if !c.Quiet {
writer = os.Stderr
}
dockerRegistryOptions := image2.DockerRegistryOptions{
DockerRegistryCreds: registryCreds,
- DockerCertPath: c.String("cert-dir"),
+ DockerCertPath: c.CertDir,
}
- if c.IsSet("tls-verify") {
- dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.BoolT("tls-verify"))
+ if c.Flag("tls-verify").Changed {
+ dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify)
}
// Possible for docker-archive to have multiple tags, so use LoadFromArchiveReference instead
@@ -116,22 +120,62 @@ func pullCmd(c *cli.Context) error {
if err != nil {
return errors.Wrapf(err, "error parsing %q", image)
}
- newImage, err := runtime.LoadFromArchiveReference(getContext(), srcRef, c.String("signature-policy"), writer)
+ newImage, err := runtime.LoadFromArchiveReference(getContext(), srcRef, c.SignaturePolicy, writer)
if err != nil {
return errors.Wrapf(err, "error pulling image from %q", image)
}
- imgID = newImage[0].ID()
+ fmt.Println(newImage[0].ID())
} else {
authfile := getAuthFile(c.String("authfile"))
- newImage, err := runtime.New(getContext(), image, c.String("signature-policy"), authfile, writer, &dockerRegistryOptions, image2.SigningOptions{}, true, nil)
+ spec := image
+ systemContext := common.GetSystemContext("", authfile, false)
+ srcRef, err := alltransports.ParseImageName(spec)
if err != nil {
+ dockerTransport := "docker://"
+ logrus.Debugf("error parsing image name %q, trying with transport %q: %v", spec, dockerTransport, err)
+ spec = dockerTransport + spec
+ srcRef2, err2 := alltransports.ParseImageName(spec)
+ if err2 != nil {
+ return errors.Wrapf(err2, "error parsing image name %q", image)
+ }
+ srcRef = srcRef2
+ }
+ var names []string
+ if c.Bool("all-tags") {
+ if srcRef.DockerReference() == nil {
+ return errors.New("Non-docker transport is currently not supported")
+ }
+ tags, err := docker.GetRepositoryTags(ctx, systemContext, srcRef)
+ if err != nil {
+ return errors.Wrapf(err, "error getting repository tags")
+ }
+ for _, tag := range tags {
+ name := spec + ":" + tag
+ names = append(names, name)
+ }
+ } else {
+ names = append(names, spec)
+ }
+ var foundIDs []string
+ foundImage := true
+ for _, name := range names {
+ newImage, err := runtime.New(getContext(), name, c.String("signature-policy"), authfile, writer, &dockerRegistryOptions, image2.SigningOptions{}, true, nil)
+ if err != nil {
+ println(errors.Wrapf(err, "error pulling image %q", name))
+ foundImage = false
+ continue
+ }
+ foundIDs = append(foundIDs, newImage.ID())
+ }
+ if len(names) == 1 && !foundImage {
return errors.Wrapf(err, "error pulling image %q", image)
}
- imgID = newImage.ID()
- }
-
- // Intentionally choosing to ignore if there is an error because
- // outputting the image ID is a NTH and not integral to the pull
- fmt.Println(imgID)
+ if len(names) > 1 {
+ fmt.Println("Pulled Images:")
+ }
+ for _, id := range foundIDs {
+ fmt.Println(id)
+ }
+ } // end else if strings.HasPrefix(image, dockerarchive.Transport.Name()+":")
return nil
}