From 9ace06e0c2ca7f416b6b3f7252791013306dd4f9 Mon Sep 17 00:00:00 2001 From: baude Date: Wed, 30 May 2018 10:03:46 -0500 Subject: sort containers and images by create time When running podman ps or podman images, the containers and images should be sorted by newest to oldest. Resolves: #830 Signed-off-by: baude Closes: #848 Approved by: mheon --- cmd/podman/images.go | 39 ++++++++++++++++-------- cmd/podman/ps.go | 83 +++++++++++++++++++++++++++++----------------------- 2 files changed, 73 insertions(+), 49 deletions(-) (limited to 'cmd/podman') diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 305d2f11e..6c8af4512 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -14,15 +14,17 @@ import ( "github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod/image" "github.com/urfave/cli" + "sort" ) type imagesTemplateParams struct { - Repository string - Tag string - ID string - Digest digest.Digest - Created string - Size string + Repository string + Tag string + ID string + Digest digest.Digest + Created string + CreatedTime time.Time + Size string } type imagesJSONParams struct { @@ -42,6 +44,13 @@ type imagesOptions struct { outputformat string } +// Type declaration and functions for sorting the PS output by time +type imagesSorted []imagesTemplateParams + +func (a imagesSorted) Len() int { return len(a) } +func (a imagesSorted) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a imagesSorted) Less(i, j int) bool { return a[i].CreatedTime.After(a[j].CreatedTime) } + var ( imagesFlags = []cli.Flag{ cli.BoolFlag{ @@ -183,7 +192,7 @@ func imagesToGeneric(templParams []imagesTemplateParams, JSONParams []imagesJSON } // 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 []imagesTemplateParams) { +func getImagesTemplateOutput(ctx context.Context, runtime *libpod.Runtime, images []*image.Image, opts imagesOptions) (imagesOutput imagesSorted) { for _, img := range images { createdTime := img.Created() @@ -199,17 +208,21 @@ func getImagesTemplateOutput(ctx context.Context, runtime *libpod.Runtime, image size = nil } params := imagesTemplateParams{ - Repository: repo, - Tag: tag, - ID: imageID, - Digest: img.Digest(), - Created: units.HumanDuration(time.Since((createdTime))) + " ago", - Size: units.HumanSizeWithPrecision(float64(*size), 3), + Repository: repo, + Tag: tag, + ID: imageID, + Digest: img.Digest(), + CreatedTime: createdTime, + Created: units.HumanDuration(time.Since((createdTime))) + " ago", + Size: units.HumanSizeWithPrecision(float64(*size), 3), } imagesOutput = append(imagesOutput, params) } } } + + // Sort images by created time + sort.Sort(imagesSorted(imagesOutput)) return } diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index 9f5bdfc26..4ca9b13a3 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "reflect" + "sort" "strconv" "strings" "time" @@ -26,25 +27,26 @@ import ( const mountTruncLength = 12 type psTemplateParams struct { - ID string - Image string - Command string - CreatedAt string - RunningFor string - Status string - Ports string - Size string - Names string - Labels string - Mounts string - PID int - Cgroup string - IPC string - MNT string - NET string - PIDNS string - User string - UTS string + ID string + Image string + Command string + CreatedAtTime time.Time + Created string + RunningFor string + Status string + Ports string + Size string + Names string + Labels string + Mounts string + PID int + Cgroup string + IPC string + MNT string + NET string + PIDNS string + User string + UTS string } // psJSONParams is only used when the JSON format is specified, @@ -69,6 +71,13 @@ type psJSONParams struct { Namespaces *batchcontainer.Namespace `json:"namespace,omitempty"` } +// Type declaration and functions for sorting the PS output by time +type psSorted []psTemplateParams + +func (a psSorted) Len() int { return len(a) } +func (a psSorted) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a psSorted) Less(i, j int) bool { return a[i].CreatedAtTime.After(a[j].CreatedAtTime) } + var ( psFlags = []cli.Flag{ cli.BoolFlag{ @@ -335,7 +344,7 @@ func genPsFormat(format string, quiet, size, namespace bool) string { if namespace { return "table {{.ID}}\t{{.Names}}\t{{.PID}}\t{{.Cgroup}}\t{{.IPC}}\t{{.MNT}}\t{{.NET}}\t{{.PIDNS}}\t{{.User}}\t{{.UTS}}\t" } - format = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.CreatedAt}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}\t" + format = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.Created}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}\t" if size { format += "{{.Size}}\t" } @@ -372,9 +381,9 @@ func (p *psTemplateParams) headerMap() map[string]string { } // getTemplateOutput returns the modified container information -func getTemplateOutput(containers []*libpod.Container, opts batchcontainer.PsOptions) ([]psTemplateParams, error) { +func getTemplateOutput(containers []*libpod.Container, opts batchcontainer.PsOptions) (psSorted, error) { var ( - psOutput []psTemplateParams + psOutput psSorted status, size string ns *batchcontainer.Namespace ) @@ -399,7 +408,6 @@ func getTemplateOutput(containers []*libpod.Container, opts batchcontainer.PsOpt if !batchInfo.StartedTime.IsZero() { runningFor = units.HumanDuration(time.Since(batchInfo.StartedTime)) } - createdAt := batchInfo.ConConfig.CreatedTime.Format("2006-01-02 15:04:05 -0700 MST") imageName := batchInfo.ConConfig.RootfsImageName var createArtifact cc.CreateConfig @@ -446,20 +454,20 @@ func getTemplateOutput(containers []*libpod.Container, opts batchcontainer.PsOpt ctrID = shortID(ctr.ID()) imageName = batchInfo.ConConfig.RootfsImageName } - params := psTemplateParams{ - ID: ctrID, - Image: imageName, - Command: command, - CreatedAt: createdAt, - RunningFor: runningFor, - Status: status, - Ports: ports, - Size: size, - Names: ctr.Name(), - Labels: labels, - Mounts: mounts, - PID: batchInfo.Pid, + ID: ctrID, + Image: imageName, + Command: command, + CreatedAtTime: batchInfo.ConConfig.CreatedTime, + Created: units.HumanDuration(time.Since(batchInfo.ConConfig.CreatedTime)) + " ago", + RunningFor: runningFor, + Status: status, + Ports: ports, + Size: size, + Names: ctr.Name(), + Labels: labels, + Mounts: mounts, + PID: batchInfo.Pid, } if opts.Namespace { @@ -473,6 +481,9 @@ func getTemplateOutput(containers []*libpod.Container, opts batchcontainer.PsOpt } psOutput = append(psOutput, params) } + // Sort the ps entries by created time + sort.Sort(psSorted(psOutput)) + return psOutput, nil } -- cgit v1.2.3-54-g00ecf