diff options
-rw-r--r-- | cmd/podman/pull.go | 129 | ||||
-rw-r--r-- | docs/podman-pull.1.md | 2 | ||||
-rw-r--r-- | pkg/adapter/containers.go | 3 | ||||
-rw-r--r-- | test/e2e/stop_test.go | 78 |
4 files changed, 156 insertions, 56 deletions
diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go index 04eb5bd46..521419e7a 100644 --- a/cmd/podman/pull.go +++ b/cmd/podman/pull.go @@ -46,7 +46,7 @@ func init() { pullCommand.SetHelpTemplate(HelpTemplate()) pullCommand.SetUsageTemplate(UsageTemplate()) flags := pullCommand.Flags() - flags.BoolVar(&pullCommand.AllTags, "all-tags", false, "All tagged images inthe repository will be pulled") + flags.BoolVar(&pullCommand.AllTags, "all-tags", false, "All tagged images in the repository will be pulled") 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") @@ -94,8 +94,9 @@ func pullCmd(c *cliconfig.PullValues) (retError error) { return errors.Errorf("tag can't be used with --all-tags") } } + ctx := getContext() - img := args[0] + imgArg := args[0] var registryCreds *types.DockerAuthConfig @@ -122,68 +123,86 @@ func pullCmd(c *cliconfig.PullValues) (retError error) { dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify) } - // Possible for docker-archive to have multiple tags, so use LoadFromArchiveReference instead - if strings.HasPrefix(img, dockerarchive.Transport.Name()+":") { - srcRef, err := alltransports.ParseImageName(img) + // Special-case for docker-archive which allows multiple tags. + if strings.HasPrefix(imgArg, dockerarchive.Transport.Name()+":") { + srcRef, err := alltransports.ParseImageName(imgArg) if err != nil { - return errors.Wrapf(err, "error parsing %q", img) + return errors.Wrapf(err, "error parsing %q", imgArg) } newImage, err := runtime.LoadFromArchiveReference(getContext(), srcRef, c.SignaturePolicy, writer) if err != nil { - return errors.Wrapf(err, "error pulling image from %q", img) + return errors.Wrapf(err, "error pulling image from %q", imgArg) } fmt.Println(newImage[0].ID()) - } else { - authfile := getAuthFile(c.String("authfile")) - spec := img - systemContext := image.GetSystemContext("", authfile, false) - srcRef, err := alltransports.ParseImageName(spec) + + return nil + } + + authfile := getAuthFile(c.String("authfile")) + + // FIXME: the default pull consults the registries.conf's search registries + // while the all-tags pull does not. This behavior must be fixed in the + // future and span across c/buildah, c/image and c/libpod to avoid redundant + // and error prone code. + // + // See https://bugzilla.redhat.com/show_bug.cgi?id=1701922 for background + // information. + if !c.Bool("all-tags") { + newImage, err := runtime.New(getContext(), imgArg, c.SignaturePolicy, authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil) 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", img) - } - 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) + return errors.Wrapf(err, "error pulling image %q", imgArg) } - var foundIDs []string - foundImage := true - for _, name := range names { - newImage, err := runtime.New(getContext(), name, c.String("signature-policy"), authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil) - if err != nil { - logrus.Errorf("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", img) - } - if len(names) > 1 { - fmt.Println("Pulled Images:") + fmt.Println(newImage.ID()) + return nil + } + + // FIXME: all-tags should use the libpod backend instead of baking its own bread. + spec := imgArg + systemContext := image.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", imgArg) } - for _, id := range foundIDs { - fmt.Println(id) + srcRef = srcRef2 + } + var names []string + 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) + } + + var foundIDs []string + foundImage := true + for _, name := range names { + newImage, err := runtime.New(getContext(), name, c.String("signature-policy"), authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, true, nil) + if err != nil { + logrus.Errorf("error pulling image %q", name) + foundImage = false + continue } - } // end else if strings.HasPrefix(img, dockerarchive.Transport.Name()+":") + foundIDs = append(foundIDs, newImage.ID()) + } + if len(names) == 1 && !foundImage { + return errors.Wrapf(err, "error pulling image %q", imgArg) + } + if len(names) > 1 { + fmt.Println("Pulled Images:") + } + for _, id := range foundIDs { + fmt.Println(id) + } + return nil } diff --git a/docs/podman-pull.1.md b/docs/podman-pull.1.md index 92740c3af..ab01bb40d 100644 --- a/docs/podman-pull.1.md +++ b/docs/podman-pull.1.md @@ -49,6 +49,8 @@ Image stored in local container/storage All tagged images in the repository will be pulled. +Note: When using the all-tags flag, Podman will not iterate over the search registries in the containers-registries.conf(5) but will always use docker.io for unqualified image names. + **--authfile** Path of the authentication file. Default is ${XDG_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`. diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index 1c0a60234..8481a0cec 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -92,6 +92,9 @@ func (r *LocalRuntime) StopContainers(ctx context.Context, cli *cliconfig.StopVa if errors.Cause(err) == libpod.ErrCtrStopped { logrus.Debugf("Container %s is already stopped", c.ID()) return nil + } else if cli.All && errors.Cause(err) == libpod.ErrCtrStateInvalid { + logrus.Debugf("Container %s is not running, could not stop", c.ID()) + return nil } logrus.Debugf("Failed to stop container %s: %s", c.ID(), err.Error()) } diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go index 97c9287b9..717eea441 100644 --- a/test/e2e/stop_test.go +++ b/test/e2e/stop_test.go @@ -4,6 +4,7 @@ package integration import ( "os" + "strings" . "github.com/containers/libpod/test/utils" . "github.com/onsi/ginkgo" @@ -48,6 +49,11 @@ var _ = Describe("Podman stop", func() { session = podmanTest.Podman([]string{"stop", cid}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop container by name", func() { @@ -57,15 +63,25 @@ var _ = Describe("Podman stop", func() { session = podmanTest.Podman([]string{"stop", "test1"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) - It("podman stop container by name", func() { + It("podman container stop by name", func() { session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"container", "stop", "test1"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop stopped container", func() { @@ -80,6 +96,11 @@ var _ = Describe("Podman stop", func() { session3 := podmanTest.Podman([]string{"stop", "test1"}) session3.WaitWithDefaultTimeout() Expect(session3.ExitCode()).To(Equal(0)) + + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop all containers -t", func() { @@ -105,6 +126,11 @@ var _ = Describe("Podman stop", func() { Expect(output).To(ContainSubstring(cid1)) Expect(output).To(ContainSubstring(cid2)) Expect(output).To(ContainSubstring(cid3)) + + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop container --time", func() { @@ -118,6 +144,11 @@ var _ = Describe("Podman stop", func() { Expect(session.ExitCode()).To(Equal(0)) output := session.OutputToString() Expect(output).To(ContainSubstring(cid1)) + + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop container --timeout", func() { @@ -131,6 +162,11 @@ var _ = Describe("Podman stop", func() { Expect(session.ExitCode()).To(Equal(0)) output := session.OutputToString() Expect(output).To(ContainSubstring(cid1)) + + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) It("podman stop latest containers", func() { @@ -140,5 +176,45 @@ var _ = Describe("Podman stop", func() { session = podmanTest.Podman([]string{"stop", "-l", "-t", "1"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) }) + + It("podman stop all containers with one stopped", func() { + session := podmanTest.RunTopContainer("test1") + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session2 := podmanTest.RunTopContainer("test2") + session2.WaitWithDefaultTimeout() + Expect(session2.ExitCode()).To(Equal(0)) + session3 := podmanTest.Podman([]string{"stop", "-l", "-t", "1"}) + session3.WaitWithDefaultTimeout() + Expect(session3.ExitCode()).To(Equal(0)) + session4 := podmanTest.Podman([]string{"stop", "-a", "-t", "1"}) + session4.WaitWithDefaultTimeout() + Expect(session4.ExitCode()).To(Equal(0)) + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) + }) + + It("podman stop all containers with one created", func() { + session := podmanTest.RunTopContainer("test1") + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + session2 := podmanTest.Podman([]string{"create", ALPINE, "/bin/sh"}) + session2.WaitWithDefaultTimeout() + Expect(session2.ExitCode()).To(Equal(0)) + session3 := podmanTest.Podman([]string{"stop", "-a", "-t", "1"}) + session3.WaitWithDefaultTimeout() + Expect(session3.ExitCode()).To(Equal(0)) + finalCtrs := podmanTest.Podman([]string{"ps", "-q"}) + finalCtrs.WaitWithDefaultTimeout() + Expect(finalCtrs.ExitCode()).To(Equal(0)) + Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal("")) + }) + }) |