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 <bbaude@redhat.com>

Closes: #848
Approved by: mheon
This commit is contained in:
baude
2018-05-30 10:03:46 -05:00
committed by Atomic Bot
parent 71487466fb
commit 9ace06e0c2
2 changed files with 73 additions and 49 deletions

View File

@@ -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
}

View File

@@ -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
}