Change exit code to 1 on podman rmi nosuch image

Make it easy for scripts to determine if an image removal
failure.   If only errors were no such image exit with 1
versus 125.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh 2019-02-24 07:36:27 -05:00
parent 73cfb9f127
commit fe4c0c3780
No known key found for this signature in database
GPG Key ID: A2DF901DABE2C028
5 changed files with 44 additions and 44 deletions

View File

@ -6,8 +6,6 @@ import (
"os/exec" "os/exec"
"syscall" "syscall"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -20,22 +18,6 @@ func outputError(err error) {
exitCode = status.ExitStatus() exitCode = status.ExitStatus()
} }
} }
var ne error fmt.Fprintln(os.Stderr, "Error:", err.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())
} }
} }

View File

@ -5,6 +5,8 @@ import (
"os" "os"
"github.com/containers/libpod/cmd/podman/cliconfig" "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/libpod/pkg/adapter"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/pkg/errors" "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() { func init() {
rmiCommand.Command = _rmiCommand rmiCommand.Command = _rmiCommand
rmiCommand.SetUsageTemplate(UsageTemplate()) rmiCommand.SetUsageTemplate(UsageTemplate())
@ -39,10 +52,8 @@ func init() {
func rmiCmd(c *cliconfig.RmiValues) error { func rmiCmd(c *cliconfig.RmiValues) error {
var ( var (
lastError error lastError error
deleted bool failureCnt int
deleteErr error
msg string
) )
ctx := getContext() ctx := getContext()
@ -64,19 +75,21 @@ func rmiCmd(c *cliconfig.RmiValues) error {
images := args[:] images := args[:]
removeImage := func(img *adapter.ContainerImage) { removeImage := func(img *adapter.ContainerImage) {
deleted = true msg, err := runtime.RemoveImage(ctx, img, c.Force)
msg, deleteErr = runtime.RemoveImage(ctx, img, c.Force) if err != nil {
if deleteErr != nil { if errors.Cause(err) == storage.ErrImageUsedByContainer {
if errors.Cause(deleteErr) == 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()) 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 { if lastError != nil {
fmt.Fprintln(os.Stderr, lastError) fmt.Fprintln(os.Stderr, lastError)
} }
lastError = deleteErr lastError = err
} else { return
fmt.Println(msg)
} }
fmt.Println(msg)
} }
if removeAll { if removeAll {
@ -121,22 +134,21 @@ func rmiCmd(c *cliconfig.RmiValues) error {
for _, i := range images { for _, i := range images {
newImage, err := runtime.NewImageFromLocal(i) newImage, err := runtime.NewImageFromLocal(i)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err) if lastError != nil {
if !imageNotFound(lastError) {
failureCnt++
}
fmt.Fprintln(os.Stderr, lastError)
}
lastError = err
continue continue
} }
removeImage(newImage) removeImage(newImage)
} }
} }
// If the user calls remove all and there are none, it should not be a if imageNotFound(lastError) && failureCnt == 0 {
// non-zero exit exitCode = 1
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")
} }
return lastError return lastError

View File

@ -30,7 +30,7 @@ The latest option is not supported on the remote client.
`podman container cleanup 860a4b23` `podman container cleanup 860a4b23`
`podman container-cleanup -a` `podman container cleanup -a`
`podman container cleanup --latest` `podman container cleanup --latest`

View File

@ -1,9 +1,11 @@
% podman-rmi(1) % podman-image-rm(1)
## NAME ## NAME
podman\-rmi - Removes one or more images podman\-image\-rm (podman\-rmi) - Removes one or more images
## SYNOPSIS ## SYNOPSIS
**podman image rm** *image* ...
**podman rmi** *image* ... **podman rmi** *image* ...
## DESCRIPTION ## DESCRIPTION
@ -38,6 +40,10 @@ Remove all images and containers.
``` ```
podman rmi -a -f 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 ## SEE ALSO
podman(1) podman(1)

View File

@ -36,7 +36,7 @@ var _ = Describe("Podman rmi", func() {
It("podman rmi bogus image", func() { It("podman rmi bogus image", func() {
session := podmanTest.Podman([]string{"rmi", "debian:6.0.10"}) session := podmanTest.Podman([]string{"rmi", "debian:6.0.10"})
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(125)) Expect(session.ExitCode()).To(Equal(1))
}) })