Merge pull request #788 from umohnani8/kpod_ps

Modify the JSON output of kpod ps
This commit is contained in:
Daniel J Walsh 2017-08-28 08:48:08 -04:00 committed by GitHub
commit 2d358fff37

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"fmt"
"reflect" "reflect"
"regexp" "regexp"
"strconv" "strconv"
@ -33,18 +32,37 @@ type psOptions struct {
label string label string
} }
type psOutputParams struct { 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
}
// psJSONParams is only used when the JSON format is specified,
// and is better for data processing from JSON.
// psJSONParams will be populated by data from libkpod.ContainerData,
// the members of the struct are the sama data types as their sources.
type psJSONParams struct {
ID string `json:"id"` ID string `json:"id"`
Image string `json:"image"` Image string `json:"image"`
Command string `json:"command"` Command string `json:"command"`
CreatedAt string `json:"created"` CreatedAt time.Time `json:"createdAt"`
RunningFor string `json:"running"` RunningFor time.Duration `json:"runningFor"`
Status string `json:"status"` Status string `json:"status"`
Ports string `json:"ports"` Ports map[string]struct{} `json:"ports"`
Size string `json:"size"` Size uint `json:"size"`
Names string `json:"names"` Names string `json:"names"`
Labels string `json:"labels"` Labels fields.Set `json:"labels"`
Mounts string `json:"mounts"` Mounts []specs.Mount `json:"mounts"`
ContainerRunning bool `json:"ctrRunning"`
} }
const runningState = "running" const runningState = "running"
@ -159,7 +177,7 @@ func psCmd(c *cli.Context) error {
containerList := getContainersMatchingFilter(containers, params, server) containerList := getContainersMatchingFilter(containers, params, server)
return psOutput(containerList, server, opts) return generatePsOutput(containerList, server, opts)
} }
// generate the template based on conditions given // generate the template based on conditions given
@ -174,16 +192,21 @@ func genPsFormat(quiet, size bool) (format string) {
return return
} }
func psToGeneric(params []psOutputParams) []interface{} { func psToGeneric(templParams []psTemplateParams, JSONParams []psJSONParams) (genericParams []interface{}) {
genericParams := make([]interface{}, len(params)) if len(templParams) > 0 {
for i, v := range params { for _, v := range templParams {
genericParams[i] = interface{}(v) genericParams = append(genericParams, interface{}(v))
} }
return genericParams return
}
for _, v := range JSONParams {
genericParams = append(genericParams, interface{}(v))
}
return
} }
// generate the accurate header based on template given // generate the accurate header based on template given
func (p *psOutputParams) headerMap() map[string]string { func (p *psTemplateParams) headerMap() map[string]string {
v := reflect.Indirect(reflect.ValueOf(p)) v := reflect.Indirect(reflect.ValueOf(p))
values := make(map[string]string) values := make(map[string]string)
@ -221,38 +244,19 @@ func getContainers(containers []*libkpod.ContainerData, opts psOptions) []*libkp
return containersOutput return containersOutput
} }
func psOutput(containers []*libkpod.ContainerData, server *libkpod.ContainerServer, opts psOptions) error { // getTemplateOutput returns the modified container information
var ( func getTemplateOutput(containers []*libkpod.ContainerData, opts psOptions) (psOutput []psTemplateParams) {
output []psOutputParams var status string
containersOutput []*libkpod.ContainerData for _, ctr := range containers {
status string ctrID := ctr.ID
ctrID string runningFor := units.HumanDuration(time.Since(ctr.State.Created))
command string createdAt := runningFor + " ago"
runningFor string command := getCommand(ctr.ImageCreatedBy)
imageName string imageName := ctr.FromImage
mounts string mounts := getMounts(ctr.Mounts, opts.noTrunc)
ports string ports := getPorts(ctr.Config.ExposedPorts)
size string size := units.HumanSize(float64(ctr.SizeRootFs))
labels string labels := getLabels(ctr.Labels)
createdAt string
)
if len(containers) == 0 {
fmt.Println("hereee")
return nil
}
containersOutput = getContainers(containers, opts)
for _, ctr := range containersOutput {
ctrID = ctr.ID
runningFor = units.HumanDuration(time.Since(ctr.State.Created))
createdAt = runningFor + " ago"
command = getCommand(ctr.ImageCreatedBy)
imageName = ctr.FromImage
mounts = getMounts(ctr.Mounts, opts.noTrunc)
ports = getPorts(ctr.Config.ExposedPorts)
size = units.HumanSize(float64(ctr.SizeRootFs))
labels = getLabels(ctr.Labels)
switch ctr.State.Status { switch ctr.State.Status {
case "stopped": case "stopped":
@ -268,7 +272,7 @@ func psOutput(containers []*libkpod.ContainerData, server *libkpod.ContainerServ
imageName = getImageName(ctr.FromImage) imageName = getImageName(ctr.FromImage)
} }
params := psOutputParams{ params := psTemplateParams{
ID: ctrID, ID: ctrID,
Image: imageName, Image: imageName,
Command: command, Command: command,
@ -281,10 +285,36 @@ func psOutput(containers []*libkpod.ContainerData, server *libkpod.ContainerServ
Labels: labels, Labels: labels,
Mounts: mounts, Mounts: mounts,
} }
output = append(output, params) psOutput = append(psOutput, params)
} }
return
}
if len(output) == 0 { // getJSONOutput returns the container info in its raw form
func getJSONOutput(containers []*libkpod.ContainerData) (psOutput []psJSONParams) {
for _, ctr := range containers {
params := psJSONParams{
ID: ctr.ID,
Image: ctr.FromImage,
Command: ctr.ImageCreatedBy,
CreatedAt: ctr.State.Created,
RunningFor: time.Since(ctr.State.Created),
Status: ctr.State.Status,
Ports: ctr.Config.ExposedPorts,
Size: ctr.SizeRootFs,
Names: ctr.Name,
Labels: ctr.Labels,
Mounts: ctr.Mounts,
ContainerRunning: ctr.State.Status == runningState,
}
psOutput = append(psOutput, params)
}
return
}
func generatePsOutput(containers []*libkpod.ContainerData, server *libkpod.ContainerServer, opts psOptions) error {
containersOutput := getContainers(containers, opts)
if len(containersOutput) == 0 {
return nil return nil
} }
@ -292,9 +322,11 @@ func psOutput(containers []*libkpod.ContainerData, server *libkpod.ContainerServ
switch opts.format { switch opts.format {
case formats.JSONString: case formats.JSONString:
out = formats.JSONStructArray{Output: psToGeneric(output)} psOutput := getJSONOutput(containersOutput)
out = formats.JSONStructArray{Output: psToGeneric([]psTemplateParams{}, psOutput)}
default: default:
out = formats.StdoutTemplateArray{Output: psToGeneric(output), Template: opts.format, Fields: output[0].headerMap()} psOutput := getTemplateOutput(containersOutput, opts)
out = formats.StdoutTemplateArray{Output: psToGeneric(psOutput, []psJSONParams{}), Template: opts.format, Fields: psOutput[0].headerMap()}
} }
return formats.Writer(out).Out() return formats.Writer(out).Out()