summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2019-01-22 09:17:34 -0600
committerbaude <bbaude@redhat.com>2019-01-29 16:51:48 -0600
commit656033ca969477ed809cbed57e752f959899d4f8 (patch)
treee2d595054ce380b5074bf0217e0c405ded94178a
parentad5579e1d9905996612dd135467ee2ee5f62b7d3 (diff)
downloadpodman-656033ca969477ed809cbed57e752f959899d4f8.tar.gz
podman-656033ca969477ed809cbed57e752f959899d4f8.tar.bz2
podman-656033ca969477ed809cbed57e752f959899d4f8.zip
podman image prune -- implement all flag
we now, by default, only prune dangling images. if --all is passed, we prune dangling images AND images that do not have an associated containers. also went ahead and enabled the podman-remote image prune side of things. Fixes: #2192 Signed-off-by: baude <bbaude@redhat.com>
-rwxr-xr-xAPI.md4
-rw-r--r--cmd/podman/images_prune.go29
-rw-r--r--cmd/podman/varlink/io.podman.varlink2
-rw-r--r--completions/bash/podman2
-rw-r--r--docs/podman-image-prune.1.md21
-rw-r--r--libpod/adapter/runtime.go5
-rw-r--r--libpod/adapter/runtime_remote.go3
-rw-r--r--libpod/image/prune.go39
-rw-r--r--pkg/varlinkapi/images.go17
-rw-r--r--test/e2e/prune_test.go7
10 files changed, 85 insertions, 44 deletions
diff --git a/API.md b/API.md
index fc14f1035..fba6c89ee 100755
--- a/API.md
+++ b/API.md
@@ -65,7 +65,7 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[func ImageExists(name: string) int](#ImageExists)
-[func ImagesPrune() []string](#ImagesPrune)
+[func ImagesPrune(all: bool) []string](#ImagesPrune)
[func ImportImage(source: string, reference: string, message: string, changes: []string) string](#ImportImage)
@@ -580,7 +580,7 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.ImageExists '{"name": "im
### <a name="ImagesPrune"></a>func ImagesPrune
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
-method ImagesPrune() [[]string](#[]string)</div>
+method ImagesPrune(all: [bool](https://godoc.org/builtin#bool)) [[]string](#[]string)</div>
ImagesPrune removes all unused images from the local store. Upon successful pruning,
the IDs of the removed images are returned.
### <a name="ImportImage"></a>func ImportImage
diff --git a/cmd/podman/images_prune.go b/cmd/podman/images_prune.go
index 06879e02d..aef387732 100644
--- a/cmd/podman/images_prune.go
+++ b/cmd/podman/images_prune.go
@@ -2,7 +2,7 @@ package main
import (
"fmt"
- "github.com/containers/libpod/cmd/podman/libpodruntime"
+ "github.com/containers/libpod/libpod/adapter"
"github.com/pkg/errors"
"github.com/urfave/cli"
)
@@ -13,33 +13,36 @@ var (
Removes all unnamed images from local storage
`
-
+ pruneImageFlags = []cli.Flag{
+ cli.BoolFlag{
+ Name: "all, a",
+ Usage: "remove all unused images, not just dangling ones",
+ },
+ }
pruneImagesCommand = cli.Command{
Name: "prune",
Usage: "Remove unused images",
Description: pruneImagesDescription,
Action: pruneImagesCmd,
OnUsageError: usageErrorHandler,
+ Flags: pruneImageFlags,
}
)
func pruneImagesCmd(c *cli.Context) error {
- runtime, err := libpodruntime.GetRuntime(c)
+ runtime, err := adapter.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
- pruneImages, err := runtime.ImageRuntime().GetPruneImages()
- if err != nil {
- return err
- }
-
- for _, i := range pruneImages {
- if err := i.Remove(true); err != nil {
- return errors.Wrapf(err, "failed to remove %s", i.ID())
+ // Call prune; if any cids are returned, print them and then
+ // return err in case an error also came up
+ pruneCids, err := runtime.PruneImages(c.Bool("all"))
+ if len(pruneCids) > 0 {
+ for _, cid := range pruneCids {
+ fmt.Println(cid)
}
- fmt.Println(i.ID())
}
- return nil
+ return err
}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 86c3eb7ff..80f0bbdfe 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -1019,7 +1019,7 @@ method UnmountContainer(name: string, force: bool) -> ()
# ImagesPrune removes all unused images from the local store. Upon successful pruning,
# the IDs of the removed images are returned.
-method ImagesPrune() -> (pruned: []string)
+method ImagesPrune(all: bool) -> (pruned: []string)
# This function is not implemented yet.
method ListContainerPorts(name: string) -> (notimplemented: NotImplemented)
diff --git a/completions/bash/podman b/completions/bash/podman
index 08891563c..9ef1d1a0d 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -2459,6 +2459,8 @@ _podman_images_prune() {
"
local boolean_options="
+ -a
+ --all
-h
--help
"
diff --git a/docs/podman-image-prune.1.md b/docs/podman-image-prune.1.md
index db76b26e0..df912c380 100644
--- a/docs/podman-image-prune.1.md
+++ b/docs/podman-image-prune.1.md
@@ -6,23 +6,38 @@ podman-image-prune - Remove all unused images
# SYNOPSIS
**podman image prune**
+[**-a**|**--all**]
[**-h**|**--help**]
# DESCRIPTION
-**podman image prune** removes all unused images from local storage. An unused image
-is defined as an image that does not have any containers based on it.
+**podman image prune** removes all dangling images from local storage. With the `all` option,
+you can delete all unused images. Unused images are dangling images as well as any image that
+does not have any containers based on it.
+
+## OPTIONS
+**--all, -a**
+
+Remove dangling images and images that have no associated containers.
## Examples ##
-Remove all unused images from local storage
+Remove all dangling images from local storage
```
$ sudo podman image prune
f3e20dc537fb04cb51672a5cb6fdf2292e61d411315549391a0d1f64e4e3097e
324a7a3b2e0135f4226ffdd473e4099fd9e477a74230cdc35de69e84c0f9d907
+```
+
+Remove all unused images from local storage
+```
+$ sudo podman image prune -a
+f3e20dc537fb04cb51672a5cb6fdf2292e61d411315549391a0d1f64e4e3097e
+324a7a3b2e0135f4226ffdd473e4099fd9e477a74230cdc35de69e84c0f9d907
6125002719feb1ddf3030acab1df6156da7ce0e78e571e9b6e9c250424d6220c
91e732da5657264c6f4641b8d0c4001c218ae6c1adb9dcef33ad00cafd37d8b6
e4e5109420323221f170627c138817770fb64832da7d8fe2babd863148287fca
77a57fa8285e9656dbb7b23d9efa837a106957409ddd702f995605af27a45ebe
+
```
## SEE ALSO
diff --git a/libpod/adapter/runtime.go b/libpod/adapter/runtime.go
index 1f3599082..f4961437e 100644
--- a/libpod/adapter/runtime.go
+++ b/libpod/adapter/runtime.go
@@ -99,3 +99,8 @@ func (r *LocalRuntime) LookupContainer(idOrName string) (*Container, error) {
}
return &Container{ctr}, nil
}
+
+// PruneImages is wrapper into PruneImages within the image pkg
+func (r *LocalRuntime) PruneImages(all bool) ([]string, error) {
+ return r.ImageRuntime().PruneImages(all)
+}
diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go
index 7189348bc..f184ce0a9 100644
--- a/libpod/adapter/runtime_remote.go
+++ b/libpod/adapter/runtime_remote.go
@@ -320,3 +320,6 @@ func (r *LocalRuntime) Config(name string) *libpod.ContainerConfig {
return &data
}
+func (r *LocalRuntime) PruneImages(all bool) ([]string, error) {
+ return iopodman.ImagesPrune().Call(r.Conn, all)
+}
diff --git a/libpod/image/prune.go b/libpod/image/prune.go
index 6a1f160d5..8602c222c 100644
--- a/libpod/image/prune.go
+++ b/libpod/image/prune.go
@@ -1,9 +1,11 @@
package image
+import "github.com/pkg/errors"
+
// GetPruneImages returns a slice of images that have no names/unused
-func (ir *Runtime) GetPruneImages() ([]*Image, error) {
+func (ir *Runtime) GetPruneImages(all bool) ([]*Image, error) {
var (
- unamedImages []*Image
+ pruneImages []*Image
)
allImages, err := ir.GetImages()
if err != nil {
@@ -11,16 +13,35 @@ func (ir *Runtime) GetPruneImages() ([]*Image, error) {
}
for _, i := range allImages {
if len(i.Names()) == 0 {
- unamedImages = append(unamedImages, i)
+ pruneImages = append(pruneImages, i)
continue
}
- containers, err := i.Containers()
- if err != nil {
- return nil, err
+ if all {
+ containers, err := i.Containers()
+ if err != nil {
+ return nil, err
+ }
+ if len(containers) < 1 {
+ pruneImages = append(pruneImages, i)
+ }
}
- if len(containers) < 1 {
- unamedImages = append(unamedImages, i)
+ }
+ return pruneImages, nil
+}
+
+// PruneImages prunes dangling and optionally all unused images from the local
+// image store
+func (ir *Runtime) PruneImages(all bool) ([]string, error) {
+ var prunedCids []string
+ pruneImages, err := ir.GetPruneImages(all)
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to get images to prune")
+ }
+ for _, p := range pruneImages {
+ if err := p.Remove(true); err != nil {
+ return nil, errors.Wrap(err, "failed to prune image")
}
+ prunedCids = append(prunedCids, p.ID())
}
- return unamedImages, nil
+ return prunedCids, nil
}
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go
index 744f031c0..d6a9b7301 100644
--- a/pkg/varlinkapi/images.go
+++ b/pkg/varlinkapi/images.go
@@ -627,19 +627,10 @@ func (i *LibpodAPI) ContainerRunlabel(call iopodman.VarlinkCall, input iopodman.
}
// ImagesPrune ....
-func (i *LibpodAPI) ImagesPrune(call iopodman.VarlinkCall) error {
- var (
- pruned []string
- )
- pruneImages, err := i.Runtime.ImageRuntime().GetPruneImages()
+func (i *LibpodAPI) ImagesPrune(call iopodman.VarlinkCall, all bool) error {
+ prunedImages, err := i.Runtime.ImageRuntime().PruneImages(all)
if err != nil {
- return err
- }
- for _, i := range pruneImages {
- if err := i.Remove(true); err != nil {
- return call.ReplyErrorOccurred(err.Error())
- }
- pruned = append(pruned, i.ID())
+ return call.ReplyErrorOccurred(err.Error())
}
- return call.ReplyImagesPrune(pruned)
+ return call.ReplyImagesPrune(prunedImages)
}
diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go
index 50a279232..81fb82b20 100644
--- a/test/e2e/prune_test.go
+++ b/test/e2e/prune_test.go
@@ -1,5 +1,3 @@
-// +build !remoteclient
-
package integration
import (
@@ -41,6 +39,7 @@ var _ = Describe("Podman rm", func() {
})
It("podman container prune containers", func() {
+ SkipIfRemote()
top := podmanTest.RunTopContainer("")
top.WaitWithDefaultTimeout()
Expect(top.ExitCode()).To(Equal(0))
@@ -57,6 +56,7 @@ var _ = Describe("Podman rm", func() {
})
It("podman image prune none images", func() {
+ SkipIfRemote()
podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true")
none := podmanTest.Podman([]string{"images", "-a"})
@@ -74,10 +74,11 @@ var _ = Describe("Podman rm", func() {
Expect(none.ExitCode()).To(Equal(0))
hasNoneAfter, _ := after.GrepString("<none>")
Expect(hasNoneAfter).To(BeFalse())
+ Expect(len(after.OutputToStringArray()) > 1).To(BeTrue())
})
It("podman image prune unused images", func() {
- prune := podmanTest.Podman([]string{"image", "prune"})
+ prune := podmanTest.Podman([]string{"image", "prune", "-a"})
prune.WaitWithDefaultTimeout()
Expect(prune.ExitCode()).To(Equal(0))