Modify the JSON output of kpod ps
Changed the JSON output to hold the actual type of the data. For example the creation time of a container will be of form time.Time. The human readable output modifies all the fields to type string, which is not helpful when the JSON output wants to be used for further processing. Signed-off-by: umohnani8 <umohnani@redhat.com>
This commit is contained in:
parent
6473eec86a
commit
d76e500b59
1 changed files with 89 additions and 57 deletions
146
cmd/kpod/ps.go
146
cmd/kpod/ps.go
|
@ -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 `json:"id"`
|
ID string
|
||||||
Image string `json:"image"`
|
Image string
|
||||||
Command string `json:"command"`
|
Command string
|
||||||
CreatedAt string `json:"created"`
|
CreatedAt string
|
||||||
RunningFor string `json:"running"`
|
RunningFor string
|
||||||
Status string `json:"status"`
|
Status string
|
||||||
Ports string `json:"ports"`
|
Ports string
|
||||||
Size string `json:"size"`
|
Size string
|
||||||
Names string `json:"names"`
|
Names string
|
||||||
Labels string `json:"labels"`
|
Labels string
|
||||||
Mounts string `json:"mounts"`
|
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"`
|
||||||
|
Image string `json:"image"`
|
||||||
|
Command string `json:"command"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
RunningFor time.Duration `json:"runningFor"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Ports map[string]struct{} `json:"ports"`
|
||||||
|
Size uint `json:"size"`
|
||||||
|
Names string `json:"names"`
|
||||||
|
Labels fields.Set `json:"labels"`
|
||||||
|
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
|
||||||
}
|
}
|
||||||
return genericParams
|
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()
|
||||||
|
|
Loading…
Reference in a new issue