summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/top.go19
-rw-r--r--libpod/container_top.go24
-rw-r--r--test/e2e/top_test.go8
3 files changed, 38 insertions, 13 deletions
diff --git a/cmd/podman/top.go b/cmd/podman/top.go
index 7ea8a1169..d848723e2 100644
--- a/cmd/podman/top.go
+++ b/cmd/podman/top.go
@@ -2,6 +2,8 @@ package main
import (
"fmt"
+ "os"
+ "text/tabwriter"
"github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
@@ -34,8 +36,7 @@ func topCmd(c *cli.Context) error {
var container *libpod.Container
var err error
args := c.Args()
- var psArgs []string
- psOpts := []string{"-o", "uid,pid,ppid,c,stime,tname,time,cmd"}
+
if len(args) < 1 && !c.Bool("latest") {
return errors.Errorf("you must provide the name or id of a running container")
}
@@ -48,9 +49,6 @@ func topCmd(c *cli.Context) error {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)
- if len(args) > 1 {
- psOpts = args[1:]
- }
if c.Bool("latest") {
container, err = runtime.GetLatestContainer()
@@ -69,14 +67,15 @@ func topCmd(c *cli.Context) error {
return errors.Errorf("top can only be used on running containers")
}
- psArgs = append(psArgs, psOpts...)
-
- psOutput, err := container.GetContainerPidInformation(psArgs)
+ psOutput, err := container.GetContainerPidInformation([]string{})
if err != nil {
return err
}
- for _, line := range psOutput {
- fmt.Println(line)
+
+ w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
+ for _, proc := range psOutput {
+ fmt.Fprintln(w, proc)
}
+ w.Flush()
return nil
}
diff --git a/libpod/container_top.go b/libpod/container_top.go
index a83303036..f5d314d49 100644
--- a/libpod/container_top.go
+++ b/libpod/container_top.go
@@ -44,8 +44,20 @@ func (c *Container) getContainerPids() ([]string, error) {
}
// GetContainerPidInformation calls ps with the appropriate options and returns
-// the results as a string and the container's PIDs as a []string
+// the results as a string and the container's PIDs as a []string. Note that
+// the ps output columns of each string are separated by a '\t\'. Currently,
+// the args argument is overwriten with []string{"-ef"} until there is a
+// portable library for ps-1 or to parse the procFS to extract all data.
func (c *Container) GetContainerPidInformation(args []string) ([]string, error) {
+ // XXX(ps-issue): args is overwriten with []{"-ef"} as the ps-1 tool
+ // doesn't support a generic way of splitting columns, rendering its
+ // output hard to parse. Docker first deterimes the number of columns
+ // and merges all exceeding ones into the last one. We believe that
+ // writing a go library which parses procFS in a ps-compatible way may
+ // be more beneficial in the long run. Until then, args will be
+ // ignored.
+ args = []string{"-ef"}
+
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
@@ -80,7 +92,7 @@ func filterPids(psOutput string, pids []string) ([]string, error) {
// Pids that don't belong.
// append the headers back in
- output = append(output, results[0])
+ output = append(output, strings.Join(headers, "\t"))
pidIndex := -1
for i, header := range headers {
@@ -98,7 +110,13 @@ func filterPids(psOutput string, pids []string) ([]string, error) {
cols := fieldsASCII(l)
pid := cols[pidIndex]
if util.StringInSlice(pid, pids) {
- output = append(output, l)
+ // XXX(ps-issue): Strip cols down to the header's size
+ // and merge exceeding fields. This is required to
+ // "merge" the overhanging CMD entries which can
+ // contain white spaces.
+ out := cols[:len(headers)-1]
+ out = append(out, strings.Join(cols[len(headers)-1:], " "))
+ output = append(output, strings.Join(out, "\t"))
}
}
return output, nil
diff --git a/test/e2e/top_test.go b/test/e2e/top_test.go
index 4b4cb47e4..e7ac90219 100644
--- a/test/e2e/top_test.go
+++ b/test/e2e/top_test.go
@@ -59,7 +59,14 @@ var _ = Describe("Podman top", func() {
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
})
+ // XXX(ps-issue): for the time being, podman-top and the libpod API
+ // GetContainerPidInformation(...) will ignore any arguments passed to ps,
+ // so we have to disable the tests below. Please refer to
+ // https://github.com/projectatomic/libpod/pull/939 for more background
+ // information.
+
It("podman top with options", func() {
+ Skip("podman-top with options: options are temporarily ignored")
session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top", "-d", "2"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -71,6 +78,7 @@ var _ = Describe("Podman top", func() {
})
It("podman top on container invalid options", func() {
+ Skip("podman-top with invalid options: options are temporarily ignored")
top := podmanTest.RunTopContainer("")
top.WaitWithDefaultTimeout()
Expect(top.ExitCode()).To(Equal(0))