summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorBrent Baude <bbaude@redhat.com>2020-03-29 14:46:35 -0500
committerBrent Baude <bbaude@redhat.com>2020-03-31 19:32:37 -0500
commit7def91910c07ee3782b2106f76877d57d646f9b4 (patch)
tree6b1f55e33d7c51df2084ea5365a1059237e17511 /cmd
parent6d36d05447fd594bedebea8a9a4366d348a78290 (diff)
downloadpodman-7def91910c07ee3782b2106f76877d57d646f9b4.tar.gz
podman-7def91910c07ee3782b2106f76877d57d646f9b4.tar.bz2
podman-7def91910c07ee3782b2106f76877d57d646f9b4.zip
podmanv2 pod ps
add the ability to list pods in podmanv2 Signed-off-by: Brent Baude <bbaude@redhat.com>
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podmanV2/pods/pod.go30
-rw-r--r--cmd/podmanV2/pods/ps.go134
-rw-r--r--cmd/podmanV2/report/templates.go3
3 files changed, 167 insertions, 0 deletions
diff --git a/cmd/podmanV2/pods/pod.go b/cmd/podmanV2/pods/pod.go
index 81c0d33e1..3766893bb 100644
--- a/cmd/podmanV2/pods/pod.go
+++ b/cmd/podmanV2/pods/pod.go
@@ -1,6 +1,9 @@
package pods
import (
+ "strings"
+ "text/template"
+
"github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/spf13/cobra"
@@ -18,6 +21,33 @@ var (
}
)
+var podFuncMap = template.FuncMap{
+ "numCons": func(cons []*entities.ListPodContainer) int {
+ return len(cons)
+ },
+ "podcids": func(cons []*entities.ListPodContainer) string {
+ var ctrids []string
+ for _, c := range cons {
+ ctrids = append(ctrids, c.Id[:12])
+ }
+ return strings.Join(ctrids, ",")
+ },
+ "podconnames": func(cons []*entities.ListPodContainer) string {
+ var ctrNames []string
+ for _, c := range cons {
+ ctrNames = append(ctrNames, c.Names[:12])
+ }
+ return strings.Join(ctrNames, ",")
+ },
+ "podconstatuses": func(cons []*entities.ListPodContainer) string {
+ var statuses []string
+ for _, c := range cons {
+ statuses = append(statuses, c.Status)
+ }
+ return strings.Join(statuses, ",")
+ },
+}
+
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
diff --git a/cmd/podmanV2/pods/ps.go b/cmd/podmanV2/pods/ps.go
index d4c625b2e..9546dff9e 100644
--- a/cmd/podmanV2/pods/ps.go
+++ b/cmd/podmanV2/pods/ps.go
@@ -1,8 +1,19 @@
package pods
import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+ "text/tabwriter"
+ "text/template"
+
"github.com/containers/libpod/cmd/podmanV2/registry"
+ "github.com/containers/libpod/cmd/podmanV2/report"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -19,14 +30,137 @@ var (
}
)
+var (
+ defaultHeaders string = "POD ID\tNAME\tSTATUS\tCREATED"
+ inputFilters string
+ noTrunc bool
+ psInput entities.PodPSOptions
+)
+
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: psCmd,
Parent: podCmd,
})
+ flags := psCmd.Flags()
+ flags.BoolVar(&psInput.CtrNames, "ctr-names", false, "Display the container names")
+ flags.BoolVar(&psInput.CtrIds, "ctr-ids", false, "Display the container UUIDs. If no-trunc is not set they will be truncated")
+ flags.BoolVar(&psInput.CtrStatus, "ctr-status", false, "Display the container status")
+ // TODO should we make this a [] ?
+ flags.StringVarP(&inputFilters, "filter", "f", "", "Filter output based on conditions given")
+ flags.StringVar(&psInput.Format, "format", "", "Pretty-print pods to JSON or using a Go template")
+ flags.BoolVarP(&psInput.Latest, "latest", "l", false, "Act on the latest pod podman is aware of")
+ flags.BoolVar(&psInput.Namespace, "namespace", false, "Display namespace information of the pod")
+ flags.BoolVar(&psInput.Namespace, "ns", false, "Display namespace information of the pod")
+ flags.BoolVar(&noTrunc, "no-trunc", false, "Do not truncate pod and container IDs")
+ flags.BoolVarP(&psInput.Quiet, "quiet", "q", false, "Print the numeric IDs of the pods only")
+ flags.StringVar(&psInput.Sort, "sort", "created", "Sort output by created, id, name, or number")
+ if registry.IsRemote() {
+ _ = flags.MarkHidden("latest")
+ }
}
func pods(cmd *cobra.Command, args []string) error {
+ var (
+ w io.Writer = os.Stdout
+ row string
+ )
+ if cmd.Flag("filter").Changed {
+ for _, f := range strings.Split(inputFilters, ",") {
+ split := strings.Split(f, "=")
+ if len(split) < 2 {
+ return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f)
+ }
+ psInput.Filters[split[0]] = append(psInput.Filters[split[0]], split[1])
+ }
+ }
+ responses, err := registry.ContainerEngine().PodPs(context.Background(), psInput)
+ if err != nil {
+ return err
+ }
+
+ if psInput.Format == "json" {
+ b, err := json.MarshalIndent(responses, "", " ")
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(b))
+ return nil
+ }
+ headers, row := createPodPsOut(cmd)
+ if psInput.Quiet {
+ if noTrunc {
+ row = "{{.Id}}\n"
+ } else {
+ row = "{{slice .Id 0 12}}\n"
+ }
+ }
+ if cmd.Flag("format").Changed {
+ row = psInput.Format
+ if !strings.HasPrefix(row, "\n") {
+ row += "\n"
+ }
+ }
+ format := "{{range . }}" + row + "{{end}}"
+ if !psInput.Quiet && !cmd.Flag("format").Changed {
+ format = headers + format
+ }
+ funcs := report.AppendFuncMap(podFuncMap)
+ tmpl, err := template.New("listPods").Funcs(funcs).Parse(format)
+ if err != nil {
+ return err
+ }
+ if !psInput.Quiet {
+ w = tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
+ }
+ if err := tmpl.Execute(w, responses); err != nil {
+ return err
+ }
+ if flusher, ok := w.(interface{ Flush() error }); ok {
+ return flusher.Flush()
+ }
return nil
}
+
+func createPodPsOut(cmd *cobra.Command) (string, string) {
+ var row string
+ headers := defaultHeaders
+ if noTrunc {
+ row += "{{.Id}}"
+ } else {
+ row += "{{slice .Id 0 12}}"
+ }
+
+ row += "\t{{.Name}}\t{{.Status}}\t{{humanDurationFromTime .Created}}"
+
+ //rowFormat string = "{{slice .Id 0 12}}\t{{.Name}}\t{{.Status}}\t{{humanDurationFromTime .Created}}"
+ if psInput.CtrIds {
+ headers += "\tIDS"
+ row += "\t{{podcids .Containers}}"
+ }
+ if psInput.CtrNames {
+ headers += "\tNAMES"
+ row += "\t{{podconnames .Containers}}"
+ }
+ if psInput.CtrStatus {
+ headers += "\tSTATUS"
+ row += "\t{{podconstatuses .Containers}}"
+ }
+ if psInput.Namespace {
+ headers += "\tCGROUP\tNAMESPACES"
+ row += "\t{{.Cgroup}}\t{{.Namespace}}"
+ }
+ if !psInput.CtrStatus && !psInput.CtrNames && !psInput.CtrIds {
+ headers += "\t# OF CONTAINERS"
+ row += "\t{{numCons .Containers}}"
+
+ }
+ headers += "\tINFRA ID\n"
+ if noTrunc {
+ row += "\t{{.InfraId}}\n"
+ } else {
+ row += "\t{{slice .InfraId 0 12}}\n"
+ }
+ return headers, row
+}
diff --git a/cmd/podmanV2/report/templates.go b/cmd/podmanV2/report/templates.go
index f3bc06405..e46048e97 100644
--- a/cmd/podmanV2/report/templates.go
+++ b/cmd/podmanV2/report/templates.go
@@ -19,6 +19,9 @@ var defaultFuncMap = template.FuncMap{
"humanDuration": func(t int64) string {
return units.HumanDuration(time.Since(time.Unix(t, 0))) + " ago"
},
+ "humanDurationFromTime": func(t time.Time) string {
+ return units.HumanDuration(time.Since(t)) + " ago"
+ },
"humanSize": func(sz int64) string {
s := units.HumanSizeWithPrecision(float64(sz), 3)
i := strings.LastIndexFunc(s, unicode.IsNumber)