aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomSweeneyRedHat <tsweeney@redhat.com>2019-01-18 20:01:29 -0500
committerTomSweeneyRedHat <tsweeney@redhat.com>2019-02-09 20:00:19 -0500
commit1543a01be874af690b7ade9b226d9d62e43ac036 (patch)
tree1c0ced1346aedfb72f4936c740f176f8b527589c
parentc86e8f180c8b0cdbd1bafe327c4671370096c45f (diff)
downloadpodman-1543a01be874af690b7ade9b226d9d62e43ac036.tar.gz
podman-1543a01be874af690b7ade9b226d9d62e43ac036.tar.bz2
podman-1543a01be874af690b7ade9b226d9d62e43ac036.zip
Add --all-tags to pull command
Signed-off-by: TomSweeneyRedHat <tsweeney@redhat.com> Add --all-tags for the `podman pull` command so all tags of an image will be pulled, not just ':latest'. Emulates the change in Buildah https://github.com/containers/buildah/pull/1263 Signed-off-by: TomSweeneyRedHat <tsweeney@redhat.com>
-rw-r--r--cmd/podman/cliconfig/config.go1
-rw-r--r--cmd/podman/pull.go71
-rw-r--r--docs/podman-pull.1.md4
-rw-r--r--test/e2e/pull_test.go16
-rw-r--r--test/utils/utils.go2
5 files changed, 83 insertions, 11 deletions
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index b925d29ff..a4c1bf0c0 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -334,6 +334,7 @@ type PsValues struct {
type PullValues struct {
PodmanCommand
+ AllTags bool
Authfile string
CertDir string
Creds string
diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go
index d70719164..b9ef3f96b 100644
--- a/cmd/podman/pull.go
+++ b/cmd/podman/pull.go
@@ -6,11 +6,13 @@ 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/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod/adapter"
+ "github.com/containers/libpod/libpod/common"
image2 "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
@@ -41,6 +43,7 @@ specified, the image with the 'latest' tag (if it exists) is pulled
func init() {
pullCommand.Command = _pullCommand
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")
@@ -69,6 +72,15 @@ func pullCmd(c *cliconfig.PullValues) error {
logrus.Errorf("too many arguments. Requires exactly 1")
return nil
}
+
+ arr := strings.SplitN(args[0], ":", 2)
+ if len(arr) == 2 {
+ if c.Bool("all-tags") {
+ logrus.Errorf("tag can't be used with --all-tags")
+ return nil
+ }
+ }
+ ctx := getContext()
image := args[0]
var registryCreds *types.DockerAuthConfig
@@ -83,7 +95,6 @@ func pullCmd(c *cliconfig.PullValues) error {
var (
writer io.Writer
- imgID string
)
if !c.Quiet {
writer = os.Stderr
@@ -107,18 +118,58 @@ func pullCmd(c *cliconfig.PullValues) error {
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.Authfile)
- newImage, err := runtime.New(getContext(), image, c.SignaturePolicy, authfile, writer, &dockerRegistryOptions, image2.SigningOptions{}, true, nil)
+ authfile := getAuthFile(c.String("authfile"))
+ 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
}
diff --git a/docs/podman-pull.1.md b/docs/podman-pull.1.md
index 2196e251e..bce11b096 100644
--- a/docs/podman-pull.1.md
+++ b/docs/podman-pull.1.md
@@ -45,6 +45,10 @@ Image stored in local container/storage
## OPTIONS
+**--all-tags, a**
+
+All tagged images in the repository will be pulled.
+
**--authfile**
Path of the authentication file. Default is ${XDG_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`.
diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go
index bfae15152..faad8202e 100644
--- a/test/e2e/pull_test.go
+++ b/test/e2e/pull_test.go
@@ -163,4 +163,20 @@ var _ = Describe("Podman pull", func() {
Expect(pull.OutputToString()).To(ContainSubstring(shortImageId))
})
+
+ It("podman pull check all tags", func() {
+ session := podmanTest.Podman([]string{"pull", "--all-tags", "alpine"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.LineInOuputStartsWith("Pulled Images:")).To(BeTrue())
+
+ session = podmanTest.Podman([]string{"images"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 4))
+
+ rmi := podmanTest.Podman([]string{"rmi", "-a", "-f"})
+ rmi.WaitWithDefaultTimeout()
+ Expect(rmi.ExitCode()).To(Equal(0))
+ })
})
diff --git a/test/utils/utils.go b/test/utils/utils.go
index 23dcb95e3..aace018cd 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -270,7 +270,7 @@ func (s *PodmanSession) LineInOuputStartsWith(term string) bool {
}
//LineInOutputContains returns true if a line in a
-// session output starts with the supplied string
+// session output contains the supplied string
func (s *PodmanSession) LineInOutputContains(term string) bool {
for _, i := range s.OutputToStringArray() {
if strings.Contains(i, term) {