diff options
author | baude <bbaude@redhat.com> | 2017-12-11 09:34:58 -0600 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2017-12-14 22:22:56 +0000 |
commit | 3ba2c3e11791b9da11661ea45d966d2db621a6ac (patch) | |
tree | ba83d175492e64b2949b27113cc4bdb98cc8f98a /cmd/kpod | |
parent | bbe6b21cb802737f933305f7c2013a86349ba43c (diff) | |
download | podman-3ba2c3e11791b9da11661ea45d966d2db621a6ac.tar.gz podman-3ba2c3e11791b9da11661ea45d966d2db621a6ac.tar.bz2 podman-3ba2c3e11791b9da11661ea45d966d2db621a6ac.zip |
kpod top
Display information about processes in a running container.
Signed-off-by: baude <bbaude@redhat.com>
Closes: #121
Approved by: rhatdan
Diffstat (limited to 'cmd/kpod')
-rw-r--r-- | cmd/kpod/images.go | 8 | ||||
-rw-r--r-- | cmd/kpod/main.go | 1 | ||||
-rw-r--r-- | cmd/kpod/top.go | 258 |
3 files changed, 267 insertions, 0 deletions
diff --git a/cmd/kpod/images.go b/cmd/kpod/images.go index 2b1003ebd..6384d61b8 100644 --- a/cmd/kpod/images.go +++ b/cmd/kpod/images.go @@ -155,8 +155,13 @@ func genImagesFormat(format string, quiet, noHeading, digests bool) string { func imagesToGeneric(templParams []imagesTemplateParams, JSONParams []imagesJSONParams) (genericParams []interface{}) { if len(templParams) > 0 { for _, v := range templParams { + fmt.Println(v) + fmt.Printf("%T\n", v) genericParams = append(genericParams, interface{}(v)) } + fmt.Println("###") + fmt.Println(genericParams) + fmt.Println("###") return } for _, v := range JSONParams { @@ -178,6 +183,9 @@ func (i *imagesTemplateParams) headerMap() map[string]string { } values[key] = strings.ToUpper(splitCamelCase(value)) } + fmt.Println("!!!") + fmt.Printf("%+v\n", values) + fmt.Println("!!!") return values } diff --git a/cmd/kpod/main.go b/cmd/kpod/main.go index 708031dc9..90a4d1d7f 100644 --- a/cmd/kpod/main.go +++ b/cmd/kpod/main.go @@ -62,6 +62,7 @@ func main() { statsCommand, stopCommand, tagCommand, + topCommand, umountCommand, unpauseCommand, versionCommand, diff --git a/cmd/kpod/top.go b/cmd/kpod/top.go new file mode 100644 index 000000000..9c2fcd34e --- /dev/null +++ b/cmd/kpod/top.go @@ -0,0 +1,258 @@ +package main + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/pkg/errors" + "github.com/projectatomic/libpod/cmd/kpod/formats" + "github.com/projectatomic/libpod/libpod" + "github.com/urfave/cli" +) + +var ( + topFlags = []cli.Flag{ + cli.StringFlag{ + Name: "format", + Usage: "Change the output to JSON", + }, + } + topDescription = ` + kpod top + + Display the running processes of the container. +` + + topCommand = cli.Command{ + Name: "top", + Usage: "Display the running processes of a container", + Description: topDescription, + Flags: topFlags, + Action: topCmd, + ArgsUsage: "CONTAINER-NAME", + SkipArgReorder: true, + } +) + +func topCmd(c *cli.Context) error { + doJSON := false + if c.IsSet("format") { + if strings.ToUpper(c.String("format")) == "JSON" { + doJSON = true + } else { + return errors.Errorf("only 'json' is supported for a format option") + } + } + args := c.Args() + var psArgs []string + psOpts := []string{"-o", "uid,pid,ppid,c,stime,tname,time,cmd"} + if len(args) < 1 { + return errors.Errorf("you must provide the name or id of a running container") + } + if err := validateFlags(c, topFlags); err != nil { + return err + } + + runtime, err := getRuntime(c) + if err != nil { + return errors.Wrapf(err, "error creating libpod runtime") + } + defer runtime.Shutdown(false) + if len(args) > 1 { + psOpts = args[1:] + } + + container, err := runtime.LookupContainer(args[0]) + if err != nil { + return errors.Wrapf(err, "unable to lookup %s", args[0]) + } + conStat, err := container.State() + if err != nil { + return errors.Wrapf(err, "unable to look up state for %s", args[0]) + } + if conStat != libpod.ContainerStateRunning { + return errors.Errorf("top can only be used on running containers") + } + + psArgs = append(psArgs, psOpts...) + + results, err := container.GetContainerPidInformation(psArgs) + if err != nil { + return err + } + headers := getHeaders(results[0]) + format := genTopFormat(headers) + var out formats.Writer + psParams, err := psDataToPSParams(results[1:], headers) + if err != nil { + return errors.Wrap(err, "unable to convert ps data to proper structure") + } + if doJSON { + out = formats.JSONStructArray{Output: topToGeneric(psParams)} + } else { + out = formats.StdoutTemplateArray{Output: topToGeneric(psParams), Template: format, Fields: createTopHeaderMap(headers)} + } + formats.Writer(out).Out() + return nil +} + +func getHeaders(s string) []string { + var headers []string + tmpHeaders := strings.Fields(s) + for _, header := range tmpHeaders { + headers = append(headers, strings.Replace(header, "%", "", -1)) + } + return headers +} + +func genTopFormat(headers []string) string { + format := "table " + for _, header := range headers { + format = fmt.Sprintf("%s{{.%s}}\t", format, header) + } + return format +} + +// imagesToGeneric creates an empty array of interfaces for output +func topToGeneric(templParams []PSParams) (genericParams []interface{}) { + for _, v := range templParams { + genericParams = append(genericParams, interface{}(v)) + } + return +} + +// generate the header based on the template provided +func createTopHeaderMap(v []string) map[string]string { + values := make(map[string]string) + for _, key := range v { + value := key + if value == "CPU" { + value = "%CPU" + } else if value == "MEM" { + value = "%MEM" + } + values[key] = strings.ToUpper(splitCamelCase(value)) + } + return values +} + +// PSDataToParams converts a string array of data and its headers to an +// arra if PSParams +func psDataToPSParams(data []string, headers []string) ([]PSParams, error) { + var params []PSParams + for _, line := range data { + tmpMap := make(map[string]string) + tmpArray := strings.Fields(line) + if len(tmpArray) == 0 { + continue + } + for index, v := range tmpArray { + header := headers[index] + tmpMap[header] = v + } + jsonData, _ := json.Marshal(tmpMap) + var r PSParams + err := json.Unmarshal(jsonData, &r) + if err != nil { + return []PSParams{}, err + } + params = append(params, r) + } + return params, nil +} + +//PSParams is a list of options that the command line ps recognizes +type PSParams struct { + CPU string `json: "%CPU"` + MEM string `json: "%MEM"` + COMMAND string + BLOCKED string + START string + TIME string + C string + CAUGHT string + CGROUP string + CLSCLS string + CLS string + CMD string + CP string + DRS string + EGID string + EGROUP string + EIP string + ESP string + ELAPSED string + EUIDE string + USER string + F string + FGID string + FGROUP string + FUID string + FUSER string + GID string + GROUP string + IGNORED string + IPCNS string + LABEL string + STARTED string + SESSION string + LWP string + MACHINE string + MAJFLT string + MINFLT string + MNTNS string + NETNS string + NI string + NLWP string + OWNER string + PENDING string + PGID string + PGRP string + PID string + PIDNS string + POL string + PPID string + PRI string + PSR string + RGID string + RGROUP string + RSS string + RSZ string + RTPRIO string + RUID string + RUSER string + S string + SCH string + SEAT string + SESS string + P string + SGID string + SGROUP string + SID string + SIZE string + SLICE string + SPID string + STACKP string + STIME string + SUID string + SUPGID string + SUPGRP string + SUSER string + SVGID string + SZ string + TGID string + THCNT string + TID string + TTY string + TPGID string + TRS string + TT string + UID string + UNIT string + USERNS string + UTSNS string + UUNIT string + VSZ string + WCHAN string +} |