diff options
-rw-r--r-- | .github/ISSUE_TEMPLATE.md | 2 | ||||
-rw-r--r-- | README.md | 31 | ||||
-rw-r--r-- | cmd/podman/commands.go | 2 | ||||
-rw-r--r-- | cmd/podman/errors.go | 20 | ||||
-rw-r--r-- | cmd/podman/play_kube.go | 2 | ||||
-rw-r--r-- | cmd/podman/rm.go | 20 | ||||
-rw-r--r-- | cmd/podman/rmi.go | 54 | ||||
-rw-r--r-- | docs/podman-container-cleanup.1.md | 2 | ||||
-rw-r--r-- | docs/podman-rm.1.md | 13 | ||||
-rw-r--r-- | docs/podman-rmi.1.md | 10 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 25 | ||||
-rw-r--r-- | test/e2e/rm_test.go | 5 | ||||
-rw-r--r-- | test/e2e/rmi_test.go | 2 |
13 files changed, 109 insertions, 79 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index a7663f3e3..2946f0b91 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -52,7 +52,7 @@ Briefly describe the problem you are having in a few paragraphs. (paste your output here) ``` -**Output of `podman info`:** +**Output of `podman info --debug`:** ``` (paste your output here) @@ -83,18 +83,23 @@ Information about contributing to this project. ## Buildah and Podman relationship -Buildah and Podman are two complementary Open-source projects that are available on -most Linux platforms and both projects reside at [GitHub.com](https://github.com) -with [Buildah](https://buildah.io) [(GitHub)](https://github.com/containers/buildah) and -[Podman](https://podman.io) [(GitHub)](https://github.com/containers/libpod). Both Buildah and Podman are -command line tools that work on OCI images and containers. The two projects -differentiate in their specialization. +Buildah and Podman are two complementary open-source projects that are +available on most Linux platforms and both projects reside at +[GitHub.com](https://github.com) with Buildah +[here](https://github.com/containers/buildah) and Podman +[here](https://github.com/containers/libpod). Both, Buildah and Podman are +command line tools that work on Open Container Initiative (OCI) images and +containers. The two projects differentiate in their specialization. Buildah specializes in building OCI images. Buildah's commands replicate all -of the commands that are found in a Dockerfile. Buildah’s goal is also to -provide a lower level coreutils interface to build images, allowing people to build -containers without requiring a Dockerfile. The intent with Buildah is to allow other -scripting languages to build container images, without requiring a daemon. +of the commands that are found in a Dockerfile. This allows building images +with and without Dockerfiles while not requiring any root privileges. +Buildah’s ultimate goal is to provide a lower-level coreutils interface to +build images. The flexibility of building images without Dockerfiles allows +for the integration of other scripting languages into the build process. +Buildah follows a simple fork-exec model and does not run as a daemon +but it is based on a comprehensive API in golang, which can be vendored +into other tools. Podman specializes in all of the commands and functions that help you to maintain and modify OCI images, such as pulling and tagging. It also allows you to create, run, and maintain those containers @@ -103,12 +108,12 @@ created from those images. A major difference between Podman and Buildah is their concept of a container. Podman allows users to create "traditional containers" where the intent of these containers is to be long lived. While Buildah containers are really just created to allow content -to be added back to the container image. An easy way to think of it is the +to be added back to the container image. An easy way to think of it is the `buildah run` command emulates the RUN command in a Dockerfile while the `podman run` command emulates the `docker run` command in functionality. Because of this and their underlying -storage differences, you cannot see Podman containers from within Buildah or vice versa. +storage differences, you can not see Podman containers from within Buildah or vice versa. -In short Buildah is an efficient way to create OCI images while Podman allows +In short, Buildah is an efficient way to create OCI images while Podman allows you to manage and maintain those images and containers in a production environment using familiar container cli commands. For more details, see the [Container Tools Guide](https://github.com/containers/buildah/tree/master/docs/containertools). diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index fef5f1763..53aa62eb9 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -17,7 +17,6 @@ func getMainCommands() []*cobra.Command { _diffCommand, _execCommand, _generateCommand, - _containerKubeCommand, _playCommand, _psCommand, _loginCommand, @@ -39,7 +38,6 @@ func getMainCommands() []*cobra.Command { _topCommand, _umountCommand, _unpauseCommand, - volumeCommand.Command, _waitCommand, } diff --git a/cmd/podman/errors.go b/cmd/podman/errors.go index 192f97049..2572b8779 100644 --- a/cmd/podman/errors.go +++ b/cmd/podman/errors.go @@ -6,8 +6,6 @@ import ( "os/exec" "syscall" - "github.com/containers/libpod/cmd/podman/varlink" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -20,22 +18,6 @@ func outputError(err error) { exitCode = status.ExitStatus() } } - var ne error - switch e := err.(type) { - // For some reason golang wont let me list them with commas so listing them all. - case *iopodman.ImageNotFound: - ne = errors.New(e.Reason) - case *iopodman.ContainerNotFound: - ne = errors.New(e.Reason) - case *iopodman.PodNotFound: - ne = errors.New(e.Reason) - case *iopodman.VolumeNotFound: - ne = errors.New(e.Reason) - case *iopodman.ErrorOccurred: - ne = errors.New(e.Reason) - default: - ne = err - } - fmt.Fprintln(os.Stderr, "Error:", ne.Error()) + fmt.Fprintln(os.Stderr, "Error:", err.Error()) } } diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go index 9fc06dde9..a59460b71 100644 --- a/cmd/podman/play_kube.go +++ b/cmd/podman/play_kube.go @@ -52,8 +52,6 @@ func init() { flags.BoolVarP(&playKubeCommand.Quiet, "quiet", "q", false, "Suppress output information when pulling images") flags.StringVar(&playKubeCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") flags.BoolVar(&playKubeCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries (default: true)") - - rootCmd.AddCommand(playKubeCommand.Command) } func playKubeYAMLCmd(c *cliconfig.KubePlayValues) error { diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go index 01ed70f52..2dcb491d7 100644 --- a/cmd/podman/rm.go +++ b/cmd/podman/rm.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/image" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -61,15 +62,21 @@ func rmCmd(c *cliconfig.RmValues) error { } defer runtime.Shutdown(false) + failureCnt := 0 delContainers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, -1, "all") if err != nil { if c.Force && len(c.InputArgs) > 0 { if errors.Cause(err) == libpod.ErrNoSuchCtr { err = nil + } else { + failureCnt++ } runtime.RemoveContainersFromStorage(c.InputArgs) } if len(delContainers) == 0 { + if err != nil && failureCnt == 0 { + exitCode = 1 + } return err } if err != nil { @@ -96,5 +103,16 @@ func rmCmd(c *cliconfig.RmValues) error { // Run the parallel funcs deleteErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, deleteFuncs) - return printParallelOutput(deleteErrors, errCount) + err = printParallelOutput(deleteErrors, errCount) + if err != nil { + for _, result := range deleteErrors { + if result != nil && errors.Cause(result) != image.ErrNoSuchCtr { + failureCnt++ + } + } + if failureCnt == 0 { + exitCode = 1 + } + } + return err } diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go index fbaa19336..709ed14e0 100644 --- a/cmd/podman/rmi.go +++ b/cmd/podman/rmi.go @@ -5,6 +5,8 @@ import ( "os" "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/cmd/podman/varlink" + "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/adapter" "github.com/containers/storage" "github.com/pkg/errors" @@ -29,6 +31,17 @@ var ( } ) +func imageNotFound(err error) bool { + if errors.Cause(err) == image.ErrNoSuchImage { + return true + } + switch err.(type) { + case *iopodman.ImageNotFound: + return true + } + return false +} + func init() { rmiCommand.Command = _rmiCommand rmiCommand.SetUsageTemplate(UsageTemplate()) @@ -39,10 +52,8 @@ func init() { func rmiCmd(c *cliconfig.RmiValues) error { var ( - lastError error - deleted bool - deleteErr error - msg string + lastError error + failureCnt int ) ctx := getContext() @@ -64,19 +75,21 @@ func rmiCmd(c *cliconfig.RmiValues) error { images := args[:] removeImage := func(img *adapter.ContainerImage) { - deleted = true - msg, deleteErr = runtime.RemoveImage(ctx, img, c.Force) - if deleteErr != nil { - if errors.Cause(deleteErr) == storage.ErrImageUsedByContainer { + msg, err := runtime.RemoveImage(ctx, img, c.Force) + if err != nil { + if errors.Cause(err) == storage.ErrImageUsedByContainer { fmt.Printf("A container associated with containers/storage, i.e. via Buildah, CRI-O, etc., may be associated with this image: %-12.12s\n", img.ID()) } + if !imageNotFound(err) { + failureCnt++ + } if lastError != nil { fmt.Fprintln(os.Stderr, lastError) } - lastError = deleteErr - } else { - fmt.Println(msg) + lastError = err + return } + fmt.Println(msg) } if removeAll { @@ -121,22 +134,21 @@ func rmiCmd(c *cliconfig.RmiValues) error { for _, i := range images { newImage, err := runtime.NewImageFromLocal(i) if err != nil { - fmt.Fprintln(os.Stderr, err) + if lastError != nil { + if !imageNotFound(lastError) { + failureCnt++ + } + fmt.Fprintln(os.Stderr, lastError) + } + lastError = err continue } removeImage(newImage) } } - // If the user calls remove all and there are none, it should not be a - // non-zero exit - if !deleted && removeAll { - return nil - } - // the user tries to remove images that do not exist, that should be a - // non-zero exit - if !deleted { - return errors.Errorf("no valid images to delete") + if imageNotFound(lastError) && failureCnt == 0 { + exitCode = 1 } return lastError diff --git a/docs/podman-container-cleanup.1.md b/docs/podman-container-cleanup.1.md index e375c12ec..2ad39d214 100644 --- a/docs/podman-container-cleanup.1.md +++ b/docs/podman-container-cleanup.1.md @@ -30,7 +30,7 @@ The latest option is not supported on the remote client. `podman container cleanup 860a4b23` -`podman container-cleanup -a` +`podman container cleanup -a` `podman container cleanup --latest` diff --git a/docs/podman-rm.1.md b/docs/podman-rm.1.md index 10ebe97f9..dc1729188 100644 --- a/docs/podman-rm.1.md +++ b/docs/podman-rm.1.md @@ -1,9 +1,11 @@ -% podman-rm(1) +% podman-container-rm(1) ## NAME -podman\-rm - Remove one or more containers +podman\-container\-rm (podman\-rm) - Remove one or more containers ## SYNOPSIS +**podman container rm** [*options*] *container* + **podman rm** [*options*] *container* ## DESCRIPTION @@ -57,8 +59,13 @@ Forcibly remove the latest container created. podman rm -f --latest ``` +## Exit Status +**_0_** if all specified containers removed +**_1_** if one of the specified containers did not exist, and no other failures +**_125_** if command fails for a reason other then an container did not exist + ## SEE ALSO -podman(1), podman-rmi(1) +podman(1), podman-image-rm(1) ## HISTORY August 2017, Originally compiled by Ryan Cole <rycole@redhat.com> diff --git a/docs/podman-rmi.1.md b/docs/podman-rmi.1.md index 9c080c9f1..8c22bba2c 100644 --- a/docs/podman-rmi.1.md +++ b/docs/podman-rmi.1.md @@ -1,9 +1,11 @@ -% podman-rmi(1) +% podman-image-rm(1) ## NAME -podman\-rmi - Removes one or more images +podman\-image\-rm (podman\-rmi) - Removes one or more images ## SYNOPSIS +**podman image rm** *image* ... + **podman rmi** *image* ... ## DESCRIPTION @@ -38,6 +40,10 @@ Remove all images and containers. ``` podman rmi -a -f ``` +## Exit Status +**_0_** if all specified images removed +**_1_** if one of the specified images did not exist, and no other failures +**_125_** if command fails for a reason other then an image did not exist ## SEE ALSO podman(1) diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 86f94477e..3c0c5c3cf 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -26,7 +26,6 @@ import ( "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/secrets" "github.com/containers/storage/pkg/idtools" - "github.com/mrunalp/fileutils" "github.com/opencontainers/runc/libcontainer/user" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" @@ -677,20 +676,12 @@ func (c *Container) makeBindMounts() error { // If it doesn't, don't copy them resolvPath, exists := bindMounts["/etc/resolv.conf"] if exists { - resolvDest := filepath.Join(c.state.RunDir, "resolv.conf") - if err := fileutils.CopyFile(resolvPath, resolvDest); err != nil { - return errors.Wrapf(err, "error copying resolv.conf from dependency container %s of container %s", depCtr.ID(), c.ID()) - } - c.state.BindMounts["/etc/resolv.conf"] = resolvDest - } + c.state.BindMounts["/etc/resolv.conf"] = resolvPath + } hostsPath, exists := bindMounts["/etc/hosts"] if exists { - hostsDest := filepath.Join(c.state.RunDir, "hosts") - if err := fileutils.CopyFile(hostsPath, hostsDest); err != nil { - return errors.Wrapf(err, "error copying hosts file from dependency container %s of container %s", depCtr.ID(), c.ID()) - } - c.state.BindMounts["/etc/hosts"] = hostsDest + c.state.BindMounts["/etc/hosts"] = hostsPath } } else { newResolv, err := c.generateResolvConf() @@ -705,6 +696,14 @@ func (c *Container) makeBindMounts() error { } c.state.BindMounts["/etc/hosts"] = newHosts } + + if err := label.Relabel(c.state.BindMounts["/etc/hosts"], c.config.MountLabel, true); err != nil { + return err + } + + if err := label.Relabel(c.state.BindMounts["/etc/resolv.conf"], c.config.MountLabel, true); err != nil { + return err + } } // SHM is always added when we mount the container @@ -809,7 +808,7 @@ func (c *Container) generateResolvConf() (string, error) { } // Relabel resolv.conf for the container - if err := label.Relabel(destPath, c.config.MountLabel, false); err != nil { + if err := label.Relabel(destPath, c.config.MountLabel, true); err != nil { return "", err } diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go index bc1431bce..71dacfa80 100644 --- a/test/e2e/rm_test.go +++ b/test/e2e/rm_test.go @@ -128,4 +128,9 @@ var _ = Describe("Podman rm", func() { Expect(podmanTest.NumberOfContainers()).To(Equal(1)) }) + It("podman rm bogus container", func() { + session := podmanTest.Podman([]string{"rm", "bogus"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(1)) + }) }) diff --git a/test/e2e/rmi_test.go b/test/e2e/rmi_test.go index c160e1bc5..dcbda2df4 100644 --- a/test/e2e/rmi_test.go +++ b/test/e2e/rmi_test.go @@ -36,7 +36,7 @@ var _ = Describe("Podman rmi", func() { It("podman rmi bogus image", func() { session := podmanTest.Podman([]string{"rmi", "debian:6.0.10"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session.ExitCode()).To(Equal(1)) }) |