From 10c37a2c93c76fb698e41dbdf076793c9a16d02b Mon Sep 17 00:00:00 2001
From: Kunal Kushwaha <kunal.kushwaha@gmail.com>
Date: Fri, 29 Nov 2019 14:28:34 +0900
Subject: filter added to container prune command

filter flag helps to filter the containers based on
labels, until(time), name, etc for prune command.

Signed-off-by: Kunal Kushwaha <kunal.kushwaha@gmail.com>
---
 cmd/podman/cliconfig/config.go |  3 ++-
 cmd/podman/containers_prune.go |  3 ++-
 cmd/podman/shared/container.go | 22 ++++++++++++++++++++--
 cmd/podman/system_prune.go     |  2 +-
 4 files changed, 25 insertions(+), 5 deletions(-)

(limited to 'cmd/podman')

diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index a34afa827..102186854 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -183,7 +183,8 @@ type PruneImagesValues struct {
 
 type PruneContainersValues struct {
 	PodmanCommand
-	Force bool
+	Force  bool
+	Filter []string
 }
 
 type PodPruneValues struct {
diff --git a/cmd/podman/containers_prune.go b/cmd/podman/containers_prune.go
index e18c829e0..78c50268c 100644
--- a/cmd/podman/containers_prune.go
+++ b/cmd/podman/containers_prune.go
@@ -41,6 +41,7 @@ func init() {
 	pruneContainersCommand.SetUsageTemplate(UsageTemplate())
 	flags := pruneContainersCommand.Flags()
 	flags.BoolVarP(&pruneContainersCommand.Force, "force", "f", false, "Force removal of a running container.  The default is false")
+	flags.StringArrayVar(&pruneContainersCommand.Filter, "filter", []string{}, "Provide filter values (e.g. 'until=<timestamp>')")
 }
 
 func pruneContainersCmd(c *cliconfig.PruneContainersValues) error {
@@ -67,7 +68,7 @@ Are you sure you want to continue? [y/N] `)
 	if c.GlobalIsSet("max-workers") {
 		maxWorkers = c.GlobalFlags.MaxWorks
 	}
-	ok, failures, err := runtime.Prune(getContext(), maxWorkers, c.Force)
+	ok, failures, err := runtime.Prune(getContext(), maxWorkers, c.Force, c.Filter)
 	if err != nil {
 		if errors.Cause(err) == define.ErrNoSuchCtr {
 			if len(c.InputArgs) > 1 {
diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go
index f49943477..364fede76 100644
--- a/cmd/podman/shared/container.go
+++ b/cmd/podman/shared/container.go
@@ -17,6 +17,7 @@ import (
 	"github.com/containers/libpod/libpod"
 	"github.com/containers/libpod/libpod/define"
 	"github.com/containers/libpod/libpod/image"
+	"github.com/containers/libpod/pkg/timetype"
 	"github.com/containers/libpod/pkg/util"
 	"github.com/cri-o/ocicni/pkg/ocicni"
 	"github.com/docker/go-units"
@@ -272,7 +273,8 @@ func worker(wg *sync.WaitGroup, jobs <-chan workerInput, results chan<- PsContai
 	}
 }
 
-func generateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime) (func(container *libpod.Container) bool, error) {
+// GenerateContainerFilterFuncs return ContainerFilter functions based of filter.
+func GenerateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime) (func(container *libpod.Container) bool, error) {
 	switch filter {
 	case "id":
 		return func(c *libpod.Container) bool {
@@ -394,6 +396,22 @@ func generateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime)
 			}
 			return hcStatus == filterValue
 		}, nil
+	case "until":
+		ts, err := timetype.GetTimestamp(filterValue, time.Now())
+		if err != nil {
+			return nil, err
+		}
+		seconds, nanoseconds, err := timetype.ParseTimestamps(ts, 0)
+		if err != nil {
+			return nil, err
+		}
+		until := time.Unix(seconds, nanoseconds)
+		return func(c *libpod.Container) bool {
+			if !until.IsZero() && c.CreatedTime().After((until)) {
+				return true
+			}
+			return false
+		}, nil
 	}
 	return nil, errors.Errorf("%s is an invalid filter", filter)
 }
@@ -411,7 +429,7 @@ func GetPsContainerOutput(r *libpod.Runtime, opts PsOptions, filters []string, m
 			if len(filterSplit) < 2 {
 				return nil, errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f)
 			}
-			generatedFunc, err := generateContainerFilterFuncs(filterSplit[0], filterSplit[1], r)
+			generatedFunc, err := GenerateContainerFilterFuncs(filterSplit[0], filterSplit[1], r)
 			if err != nil {
 				return nil, errors.Wrapf(err, "invalid filter")
 			}
diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go
index ae5d7ed2d..74fdcde99 100644
--- a/cmd/podman/system_prune.go
+++ b/cmd/podman/system_prune.go
@@ -92,7 +92,7 @@ Are you sure you want to continue? [y/N] `, volumeString)
 
 	rmWorkers := shared.Parallelize("rm")
 	fmt.Println("Deleted Containers")
-	ok, failures, err = runtime.Prune(ctx, rmWorkers, false)
+	ok, failures, err = runtime.Prune(ctx, rmWorkers, false, []string{})
 	if err != nil {
 		if lasterr != nil {
 			logrus.Errorf("%q", err)
-- 
cgit v1.2.3-54-g00ecf