From 26b9b17d275d3b740a471e70cc8116f75de99a3d Mon Sep 17 00:00:00 2001 From: haircommander Date: Thu, 2 Aug 2018 10:48:56 -0400 Subject: Added ps --pod option Signed-off-by: haircommander Closes: #1205 Approved by: rhatdan --- cmd/podman/batchcontainer/container.go | 1 + cmd/podman/ps.go | 39 ++++++++++++++++++++++++++++------ completions/bash/podman | 1 + docs/podman-ps.1.md | 5 +++++ test/e2e/ps_test.go | 19 +++++++++++++++++ 5 files changed, 59 insertions(+), 6 deletions(-) diff --git a/cmd/podman/batchcontainer/container.go b/cmd/podman/batchcontainer/container.go index 017837a96..de127c64d 100644 --- a/cmd/podman/batchcontainer/container.go +++ b/cmd/podman/batchcontainer/container.go @@ -25,6 +25,7 @@ type PsOptions struct { Last int Latest bool NoTrunc bool + Pod bool Quiet bool Size bool Sort string diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index f795ee278..a0fb9dabc 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -44,6 +44,7 @@ type psTemplateParams struct { PIDNS string User string UTS string + Pod string } // psJSONParams is used as a base structure for the psParams @@ -69,6 +70,7 @@ type psJSONParams struct { Mounts []string `json:"mounts"` ContainerRunning bool `json:"ctrRunning"` Namespaces *batchcontainer.Namespace `json:"namespace,omitempty"` + Pod string `json:"pod,omitempty"` } // Type declaration and functions for sorting the PS output @@ -101,6 +103,10 @@ type psSortedNames struct{ psSorted } func (a psSortedNames) Less(i, j int) bool { return a.psSorted[i].Names < a.psSorted[j].Names } +type psSortedPod struct{ psSorted } + +func (a psSortedPod) Less(i, j int) bool { return a.psSorted[i].Pod < a.psSorted[j].Pod } + type psSortedRunningFor struct{ psSorted } func (a psSortedRunningFor) Less(i, j int) bool { @@ -151,6 +157,10 @@ var ( Name: "no-trunc", Usage: "Display the extended information", }, + cli.BoolFlag{ + Name: "pod", + Usage: "Print the ID and name of the pod the containers are associated with", + }, cli.BoolFlag{ Name: "quiet, q", Usage: "Print the numeric IDs of the containers only", @@ -206,7 +216,7 @@ func psCmd(c *cli.Context) error { return errors.Errorf("too many arguments, ps takes no arguments") } - format := genPsFormat(c.String("format"), c.Bool("quiet"), c.Bool("size"), c.Bool("namespace")) + format := genPsFormat(c.String("format"), c.Bool("quiet"), c.Bool("size"), c.Bool("namespace"), c.Bool("pod")) opts := batchcontainer.PsOptions{ All: c.Bool("all"), @@ -215,6 +225,7 @@ func psCmd(c *cli.Context) error { Last: c.Int("last"), Latest: c.Bool("latest"), NoTrunc: c.Bool("no-trunc"), + Pod: c.Bool("pod"), Quiet: c.Bool("quiet"), Size: c.Bool("size"), Namespace: c.Bool("namespace"), @@ -406,7 +417,7 @@ func generateContainerFilterFuncs(filter, filterValue string, runtime *libpod.Ru } // generate the template based on conditions given -func genPsFormat(format string, quiet, size, namespace bool) string { +func genPsFormat(format string, quiet, size, namespace, pod bool) string { if format != "" { // "\t" from the command line is not being recognized as a tab // replacing the string "\t" to a tab character if the user passes in "\t" @@ -415,10 +426,15 @@ func genPsFormat(format string, quiet, size, namespace bool) string { if quiet { return formats.IDString } + podappend := "" + if pod { + podappend = "{{.Pod}}\t" + } if namespace { - return "table {{.ID}}\t{{.Names}}\t{{.PID}}\t{{.Cgroup}}\t{{.IPC}}\t{{.MNT}}\t{{.NET}}\t{{.PIDNS}}\t{{.User}}\t{{.UTS}}\t" + return fmt.Sprintf("table {{.ID}}\t{{.Names}}\t%s{{.PID}}\t{{.Cgroup}}\t{{.IPC}}\t{{.MNT}}\t{{.NET}}\t{{.PIDNS}}\t{{.User}}\t{{.UTS}}\t", podappend) } format = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.Created}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}\t" + format += podappend if size { format += "{{.Size}}\t" } @@ -472,6 +488,8 @@ func sortPsOutput(sortBy string, psOutput psSorted) (psSorted, error) { sort.Sort(psSortedNames{psOutput}) case "created": sort.Sort(psSortedCreated{psOutput}) + case "pod": + sort.Sort(psSortedPod{psOutput}) default: return nil, errors.Errorf("invalid option for --sort, options are: command, created, id, image, names, runningfor, size, or status") } @@ -481,15 +499,18 @@ func sortPsOutput(sortBy string, psOutput psSorted) (psSorted, error) { // getTemplateOutput returns the modified container information func getTemplateOutput(psParams []psJSONParams, opts batchcontainer.PsOptions) ([]psTemplateParams, error) { var ( - psOutput []psTemplateParams - status, size string - ns *batchcontainer.Namespace + psOutput []psTemplateParams + pod, status, size string + ns *batchcontainer.Namespace ) // If the user is trying to filter based on size, or opted to sort on size // the size bool must be set. if strings.Contains(opts.Format, ".Size") || opts.Sort == "size" { opts.Size = true } + if strings.Contains(opts.Format, ".Pod") || opts.Sort == "pod" { + opts.Pod = true + } for _, psParam := range psParams { // do we need this? @@ -505,6 +526,9 @@ func getTemplateOutput(psParams []psJSONParams, opts batchcontainer.PsOptions) ( } size = units.HumanSizeWithPrecision(float64(psParam.Size.RwSize), 3) + " (virtual " + units.HumanSizeWithPrecision(float64(psParam.Size.RootFsSize), 3) + ")" } + if opts.Pod { + pod = psParam.Pod + } runningFor := units.HumanDuration(psParam.RunningFor) command := strings.Join(psParam.Command, " ") @@ -531,6 +555,7 @@ func getTemplateOutput(psParams []psJSONParams, opts batchcontainer.PsOptions) ( if !opts.NoTrunc { ctrID = shortID(psParam.ID) + pod = shortID(psParam.Pod) } params := psTemplateParams{ ID: ctrID, @@ -546,6 +571,7 @@ func getTemplateOutput(psParams []psJSONParams, opts batchcontainer.PsOptions) ( Labels: labels, Mounts: getMounts(psParam.Mounts, opts.NoTrunc), PID: psParam.PID, + Pod: pod, } if opts.Namespace { @@ -599,6 +625,7 @@ func getAndSortJSONParams(containers []*libpod.Container, opts batchcontainer.Ps Mounts: batchInfo.ConConfig.UserVolumes, ContainerRunning: batchInfo.ConState == libpod.ContainerStateRunning, Namespaces: ns, + Pod: ctr.PodID(), } if !batchInfo.StartedTime.IsZero() && batchInfo.ConState == libpod.ContainerStateRunning { diff --git a/completions/bash/podman b/completions/bash/podman index 563597f0b..f74450407 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -1924,6 +1924,7 @@ _podman_ps() { --all -a --latest -l --no-trunc + --pod --quiet -q --size -s --namespace --ns diff --git a/docs/podman-ps.1.md b/docs/podman-ps.1.md index 0ec39f5ac..72bb69ca6 100644 --- a/docs/podman-ps.1.md +++ b/docs/podman-ps.1.md @@ -24,6 +24,10 @@ all the containers information. By default it lists: Show all the containers, default is only running containers +**--pod** + +Display the pods the containers are associated with + **--no-trunc** Display the extended information @@ -46,6 +50,7 @@ Valid placeholders for the Go template are listed below: | .CreatedAt | Creation time for container | | .RunningFor | Time elapsed since container was started | | .Status | Status of container | +| .Pod | Pod the container is associated with | | .Ports | Exposed ports | | .Size | Size of container | | .Names | Name of container | diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index 1b8002166..5dfb385a8 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -246,4 +246,23 @@ var _ = Describe("Podman ps", func() { Expect(sort.SliceIsSorted(sortedArr, func(i, j int) bool { return sortedArr[i] < sortedArr[j] })).To(BeTrue()) }) + + It("podman --pod", func() { + session := podmanTest.Podman([]string{"pod", "create"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + podid := session.OutputToString() + + session = podmanTest.RunTopContainerInPod("", podid) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"ps", "--pod", "--no-trunc"}) + + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + Expect(session.OutputToString()).To(ContainSubstring(podid)) + + }) }) -- cgit v1.2.3-54-g00ecf