summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/images.go28
-rw-r--r--docs/podman-images.1.md16
-rw-r--r--libpod/runtime.go5
-rw-r--r--test/e2e/images_test.go26
-rw-r--r--test/e2e/libpod_suite_test.go4
-rw-r--r--test/e2e/run_entrypoint_test.go14
6 files changed, 77 insertions, 16 deletions
diff --git a/cmd/podman/images.go b/cmd/podman/images.go
index 7b906178d..654e59845 100644
--- a/cmd/podman/images.go
+++ b/cmd/podman/images.go
@@ -7,6 +7,7 @@ import (
"strings"
"time"
+ "github.com/containers/storage"
"github.com/docker/go-units"
digest "github.com/opencontainers/go-digest"
"github.com/pkg/errors"
@@ -43,6 +44,7 @@ type imagesOptions struct {
format string
outputformat string
sort string
+ all bool
}
// Type declaration and functions for sorting the images output
@@ -178,6 +180,7 @@ func imagesCmd(c *cli.Context) error {
digests: c.Bool("digests"),
format: c.String("format"),
sort: c.String("sort"),
+ all: c.Bool("all"),
}
opts.outputformat = opts.setOutputFormat()
@@ -256,8 +259,14 @@ func sortImagesOutput(sortBy string, imagesOutput imagesSorted) imagesSorted {
}
// getImagesTemplateOutput returns the images information to be printed in human readable format
-func getImagesTemplateOutput(ctx context.Context, runtime *libpod.Runtime, images []*image.Image, opts imagesOptions) (imagesOutput imagesSorted) {
+func getImagesTemplateOutput(ctx context.Context, runtime *libpod.Runtime, images []*image.Image, opts imagesOptions, storageLayers []storage.Layer) (imagesOutput imagesSorted) {
for _, img := range images {
+ // If all is false and the image doesn't have a name, check to see if the top layer of the image is a parent
+ // to another image's top layer. If it is, then it is an intermediate image so don't print out if the --all flag
+ // is not set.
+ if !opts.all && len(img.Names()) == 0 && !layerIsLeaf(storageLayers, img.TopLayer()) {
+ continue
+ }
createdTime := img.Created()
imageID := "sha256:" + img.ID()
@@ -316,13 +325,17 @@ func generateImagesOutput(ctx context.Context, runtime *libpod.Runtime, images [
return nil
}
var out formats.Writer
+ storageLayers, err := runtime.GetLayers()
+ if err != nil {
+ return errors.Wrap(err, "error getting layers from store")
+ }
switch opts.format {
case formats.JSONString:
imagesOutput := getImagesJSONOutput(ctx, runtime, images)
out = formats.JSONStructArray{Output: imagesToGeneric([]imagesTemplateParams{}, imagesOutput)}
default:
- imagesOutput := getImagesTemplateOutput(ctx, runtime, images, opts)
+ imagesOutput := getImagesTemplateOutput(ctx, runtime, images, opts, storageLayers)
out = formats.StdoutTemplateArray{Output: imagesToGeneric(imagesOutput, []imagesJSONParams{}), Template: opts.outputformat, Fields: imagesOutput[0].HeaderMap()}
}
return formats.Writer(out).Out()
@@ -378,3 +391,14 @@ func CreateFilterFuncs(ctx context.Context, r *libpod.Runtime, c *cli.Context, i
}
return filterFuncs, nil
}
+
+// layerIsLeaf goes through the layers in the store and checks if "layer" is
+// the parent of any other layer in store.
+func layerIsLeaf(storageLayers []storage.Layer, layer string) bool {
+ for _, storeLayer := range storageLayers {
+ if storeLayer.Parent == layer {
+ return false
+ }
+ }
+ return true
+}
diff --git a/docs/podman-images.1.md b/docs/podman-images.1.md
index eb9712588..a97785de7 100644
--- a/docs/podman-images.1.md
+++ b/docs/podman-images.1.md
@@ -13,7 +13,7 @@ Displays locally stored images, their names, and their IDs.
**--all, -a**
-Show all images (by default filter out the intermediate image layers). The default is false. (This is a NOOP until podman build supports caching.)
+Show all images (by default filter out the intermediate image layers). The default is false.
**--digests**
@@ -133,6 +133,20 @@ registry.access.redhat.com/rhel7 latest 7a840db7f020 2 weeks ago
registry.fedoraproject.org/fedora 27 801894bc0e43 6 weeks ago 246MB
```
+```
+# podman images
+REPOSITORY TAG IMAGE ID CREATED SIZE
+localhost/test latest 18f0c080cd72 4 seconds ago 4.42MB
+docker.io/library/alpine latest 3fd9065eaf02 5 months ago 4.41MB
+# podman images -a
+REPOSITORY TAG IMAGE ID CREATED SIZE
+localhost/test latest 18f0c080cd72 6 seconds ago 4.42MB
+<none> <none> 270e70dc54c0 7 seconds ago 4.42MB
+<none> <none> 4ed6fbe43414 8 seconds ago 4.41MB
+<none> <none> 6b0df8e71508 8 seconds ago 4.41MB
+docker.io/library/alpine latest 3fd9065eaf02 5 months ago 4.41MB
+```
+
## SEE ALSO
podman(1)
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 5d4b895cb..2584c091d 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -666,3 +666,8 @@ func SaveDefaultConfig(path string) error {
func (r *Runtime) ImageRuntime() *image.Runtime {
return r.imageRuntime
}
+
+// GetLayers returns the layers available in the store
+func (r *Runtime) GetLayers() ([]storage.Layer, error) {
+ return r.store.Layers()
+}
diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go
index 5e30e95ec..c04ae91bd 100644
--- a/test/e2e/images_test.go
+++ b/test/e2e/images_test.go
@@ -100,7 +100,7 @@ var _ = Describe("Podman images", func() {
It("podman images filter before image", func() {
dockerfile := `FROM docker.io/library/alpine:latest
`
- podmanTest.BuildImage(dockerfile, "foobar.com/before:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
result := podmanTest.Podman([]string{"images", "-q", "-f", "before=foobar.com/before:latest"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
@@ -114,7 +114,7 @@ var _ = Describe("Podman images", func() {
dockerfile := `FROM docker.io/library/alpine:latest
`
- podmanTest.BuildImage(dockerfile, "foobar.com/before:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
result := podmanTest.Podman([]string{"images", "-q", "-f", "after=docker.io/library/alpine:latest"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
@@ -124,8 +124,8 @@ var _ = Describe("Podman images", func() {
It("podman images filter dangling", func() {
dockerfile := `FROM docker.io/library/alpine:latest
`
- podmanTest.BuildImage(dockerfile, "foobar.com/before:latest")
- podmanTest.BuildImage(dockerfile, "foobar.com/before:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
+ podmanTest.BuildImage(dockerfile, "foobar.com/before:latest", "false")
result := podmanTest.Podman([]string{"images", "-q", "-f", "dangling=true"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
@@ -165,4 +165,22 @@ var _ = Describe("Podman images", func() {
return size1 < size2
})).To(BeTrue())
})
+
+ It("podman images --all flag", func() {
+ dockerfile := `FROM docker.io/library/alpine:latest
+RUN mkdir hello
+RUN touch test.txt
+ENV foo=bar
+`
+ podmanTest.BuildImage(dockerfile, "test", "true")
+ session := podmanTest.Podman([]string{"images"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(len(session.OutputToStringArray())).To(Equal(4))
+
+ session2 := podmanTest.Podman([]string{"images", "--all"})
+ session2.WaitWithDefaultTimeout()
+ Expect(session2.ExitCode()).To(Equal(0))
+ Expect(len(session2.OutputToStringArray())).To(Equal(6))
+ })
})
diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go
index d06818fd3..3d444f662 100644
--- a/test/e2e/libpod_suite_test.go
+++ b/test/e2e/libpod_suite_test.go
@@ -593,11 +593,11 @@ func (p *PodmanTest) GetContainerStatus() string {
// BuildImage uses podman build and buildah to build an image
// called imageName based on a string dockerfile
-func (p *PodmanTest) BuildImage(dockerfile, imageName string) {
+func (p *PodmanTest) BuildImage(dockerfile, imageName string, layers string) {
dockerfilePath := filepath.Join(p.TempDir, "Dockerfile")
err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755)
Expect(err).To(BeNil())
- session := p.Podman([]string{"build", "-t", imageName, "--file", dockerfilePath, p.TempDir})
+ session := p.Podman([]string{"build", "--layers=" + layers, "-t", imageName, "--file", dockerfilePath, p.TempDir})
session.Wait(120)
Expect(session.ExitCode()).To(Equal(0))
}
diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go
index e06f8bb3a..7cae4e0df 100644
--- a/test/e2e/run_entrypoint_test.go
+++ b/test/e2e/run_entrypoint_test.go
@@ -33,7 +33,7 @@ var _ = Describe("Podman run entrypoint", func() {
ENTRYPOINT []
CMD []
`
- podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false")
session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(125))
@@ -43,7 +43,7 @@ CMD []
dockerfile := `FROM docker.io/library/alpine:latest
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
- podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false")
session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -55,7 +55,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
CMD [ "-v"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
- podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false")
session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -67,7 +67,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
CMD [ "-v"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
- podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false")
session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest", "-i"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -78,7 +78,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
dockerfile := `FROM docker.io/library/alpine:latest
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
- podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false")
session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest", "-i"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -90,7 +90,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
CMD ["-i"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
- podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false")
session := podmanTest.Podman([]string{"run", "--entrypoint=uname", "foobar.com/entrypoint:latest"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -102,7 +102,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
CMD ["-i"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
- podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest")
+ podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false")
session := podmanTest.Podman([]string{"run", "--entrypoint=uname", "foobar.com/entrypoint:latest", "-r"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))