diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go index f5938ffb983..0af4996665a 100644 --- a/cmd/podman/rmi.go +++ b/cmd/podman/rmi.go @@ -3,7 +3,9 @@ package main import ( "fmt" "os" + "os/exec" + "github.com/containers/storage" "github.com/pkg/errors" "github.com/projectatomic/libpod/libpod" "github.com/urfave/cli" @@ -67,6 +69,20 @@ func rmiCmd(c *cli.Context) error { image := runtime.NewImage(arg) iid, err := image.Remove(c.Bool("force")) if err != nil { + if errors.Cause(err) == storage.ErrImageUsedByContainer { + buildahImage, err2 := runtime.GetImage(image.LocalName) + if err2 == nil { + errBuildah := rmiBuildahCmd(c, buildahImage.ID) + if errBuildah == nil { + err = nil + } else { + fmt.Printf("A container created with Buildah may be associated with this image.\n") + fmt.Printf("Remove the container with Buildah or retry using the --force option.\n") + } + } else { + fmt.Printf("Unable to find image %s\n", image.LocalName) + } + } if lastError != nil { fmt.Fprintln(os.Stderr, lastError) } @@ -77,3 +93,41 @@ func rmiCmd(c *cli.Context) error { } return lastError } + +func rmiBuildahCmd(c *cli.Context, imageID string) error { + rmiCmdArgs := []string{} + + // Handle Global Options + logLevel := c.GlobalString("log-level") + if logLevel == "debug" { + rmiCmdArgs = append(rmiCmdArgs, "--debug") + } + + rmiCmdArgs = append(rmiCmdArgs, "rmi") + + if c.Bool("force") { + rmiCmdArgs = append(rmiCmdArgs, "--force") + } + + rmiCmdArgs = append(rmiCmdArgs, imageID) + buildah := "buildah" + + if _, err := exec.LookPath(buildah); err != nil { + return errors.Wrapf(err, "buildah not found in PATH") + } + if _, err := exec.Command(buildah).Output(); err != nil { + return errors.Wrapf(err, "buildah is not operational on this server") + } + + cmd := exec.Command(buildah, rmiCmdArgs...) + + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + return errors.Wrapf(err, "error running the buildah rmi command") + } + + return nil +}