diff options
-rw-r--r-- | cmd/podman/imagefilters/filters.go | 24 | ||||
-rw-r--r-- | cmd/podman/images.go | 3 | ||||
-rw-r--r-- | test/e2e/images_test.go | 27 |
3 files changed, 54 insertions, 0 deletions
diff --git a/cmd/podman/imagefilters/filters.go b/cmd/podman/imagefilters/filters.go index d01eb7436..2932d61c0 100644 --- a/cmd/podman/imagefilters/filters.go +++ b/cmd/podman/imagefilters/filters.go @@ -2,11 +2,14 @@ package imagefilters import ( "context" + "fmt" + "path/filepath" "strings" "time" "github.com/containers/libpod/pkg/adapter" "github.com/containers/libpod/pkg/inspect" + "github.com/sirupsen/logrus" ) // ResultFilter is a mock function for image filtering @@ -61,6 +64,27 @@ func LabelFilter(ctx context.Context, labelfilter string) ResultFilter { } } +// ReferenceFilter allows you to filter by image name +// Replacing all '/' with '|' so that filepath.Match() can work +// '|' character is not valid in image name, so this is safe +func ReferenceFilter(ctx context.Context, referenceFilter string) ResultFilter { + filter := fmt.Sprintf("*%s*", referenceFilter) + filter = strings.Replace(filter, "/", "|", -1) + return func(i *adapter.ContainerImage) bool { + for _, name := range i.Names() { + newName := strings.Replace(name, "/", "|", -1) + match, err := filepath.Match(filter, newName) + if err != nil { + logrus.Errorf("failed to match %s and %s, %q", name, referenceFilter, err) + } + if match { + return true + } + } + return false + } +} + // OutputImageFilter allows you to filter by an a specific image name func OutputImageFilter(userImage *adapter.ContainerImage) ResultFilter { return func(i *adapter.ContainerImage) bool { diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 26e51bef7..a4f2e5e10 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -375,6 +375,9 @@ func CreateFilterFuncs(ctx context.Context, r *adapter.LocalRuntime, filters []s case "label": labelFilter := strings.Join(splitFilter[1:], "=") filterFuncs = append(filterFuncs, imagefilters.LabelFilter(ctx, labelFilter)) + case "reference": + referenceFilter := strings.Join(splitFilter[1:], "=") + filterFuncs = append(filterFuncs, imagefilters.ReferenceFilter(ctx, referenceFilter)) default: return nil, errors.Errorf("invalid filter %s ", splitFilter[0]) } diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go index e26f4affd..4cf58e5bf 100644 --- a/test/e2e/images_test.go +++ b/test/e2e/images_test.go @@ -114,6 +114,33 @@ var _ = Describe("Podman images", func() { Expect(len(session.OutputToStringArray())).To(Equal(1)) }) + It("podman images filter reference", func() { + if podmanTest.RemoteTest { + Skip("Does not work on remote client") + } + result := podmanTest.Podman([]string{"images", "-q", "-f", "reference=docker.io*"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(len(result.OutputToStringArray())).To(Equal(2)) + + retapline := podmanTest.Podman([]string{"images", "-f", "reference=a*pine"}) + retapline.WaitWithDefaultTimeout() + Expect(retapline.ExitCode()).To(Equal(0)) + Expect(len(retapline.OutputToStringArray())).To(Equal(2)) + Expect(retapline.LineInOutputContains("alpine")) + + retapline = podmanTest.Podman([]string{"images", "-f", "reference=alpine"}) + retapline.WaitWithDefaultTimeout() + Expect(retapline.ExitCode()).To(Equal(0)) + Expect(len(retapline.OutputToStringArray())).To(Equal(2)) + Expect(retapline.LineInOutputContains("alpine")) + + retnone := podmanTest.Podman([]string{"images", "-q", "-f", "reference=bogus"}) + retnone.WaitWithDefaultTimeout() + Expect(retnone.ExitCode()).To(Equal(0)) + Expect(len(retnone.OutputToStringArray())).To(Equal(0)) + }) + It("podman images filter before image", func() { if podmanTest.RemoteTest { Skip("Does not work on remote client") |