mirror of
https://github.com/containers/podman.git
synced 2026-03-13 08:01:19 +08:00
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:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user