diff options
Diffstat (limited to 'cmd/podman/pods/ps.go')
-rw-r--r-- | cmd/podman/pods/ps.go | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go new file mode 100644 index 000000000..8cb7b6266 --- /dev/null +++ b/cmd/podman/pods/ps.go @@ -0,0 +1,229 @@ +package pods + +import ( + "context" + "encoding/json" + "fmt" + "io" + "os" + "strings" + "text/tabwriter" + "text/template" + "time" + + "github.com/docker/go-units" + + "github.com/containers/libpod/cmd/podman/registry" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + psDescription = "List all pods on system including their names, ids and current state." + + // Command: podman pod _ps_ + psCmd = &cobra.Command{ + Use: "ps", + Aliases: []string{"ls", "list"}, + Short: "list pods", + Long: psDescription, + RunE: pods, + } +) + +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 + lpr []ListPodReporter + ) + 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 + } + + for _, r := range responses { + lpr = append(lpr, ListPodReporter{r}) + } + headers, row := createPodPsOut() + 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 + } + tmpl, err := template.New("listPods").Parse(format) + if err != nil { + return err + } + if !psInput.Quiet { + w = tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) + } + if err := tmpl.Execute(w, lpr); err != nil { + return err + } + if flusher, ok := w.(interface{ Flush() error }); ok { + return flusher.Flush() + } + return nil +} + +func createPodPsOut() (string, string) { + var row string + headers := defaultHeaders + if noTrunc { + row += "{{.Id}}" + } else { + row += "{{slice .Id 0 12}}" + } + + row += "\t{{.Name}}\t{{.Status}}\t{{.Created}}" + + if psInput.CtrIds { + headers += "\tIDS" + row += "\t{{.ContainerIds}}" + } + if psInput.CtrNames { + headers += "\tNAMES" + row += "\t{{.ContainerNames}}" + } + if psInput.CtrStatus { + headers += "\tSTATUS" + row += "\t{{.ContainerStatuses}}" + } + if psInput.Namespace { + headers += "\tCGROUP\tNAMESPACES" + row += "\t{{.Cgroup}}\t{{.Namespace}}" + } + if !psInput.CtrStatus && !psInput.CtrNames && !psInput.CtrIds { + headers += "\t# OF CONTAINERS" + row += "\t{{.NumberOfContainers}}" + + } + headers += "\tINFRA ID\n" + if noTrunc { + row += "\t{{.InfraId}}\n" + } else { + row += "\t{{slice .InfraId 0 12}}\n" + } + return headers, row +} + +// ListPodReporter is a struct for pod ps output +type ListPodReporter struct { + *entities.ListPodsReport +} + +// Created returns a human readable created time/date +func (l ListPodReporter) Created() string { + return units.HumanDuration(time.Since(l.ListPodsReport.Created)) + " ago" +} + +// NumberofContainers returns an int representation for +// the number of containers belonging to the pod +func (l ListPodReporter) NumberOfContainers() int { + return len(l.Containers) +} + +// Added for backwards compatibility with podmanv1 +func (l ListPodReporter) InfraID() string { + return l.InfraId() +} + +// InfraId returns the infra container id for the pod +// depending on trunc +func (l ListPodReporter) InfraId() string { + if noTrunc { + return l.ListPodsReport.InfraId + } + return l.ListPodsReport.InfraId[0:12] +} + +func (l ListPodReporter) ContainerIds() string { + var ctrids []string + for _, c := range l.Containers { + id := c.Id + if !noTrunc { + id = id[0:12] + } + ctrids = append(ctrids, id) + } + return strings.Join(ctrids, ",") +} + +func (l ListPodReporter) ContainerNames() string { + var ctrNames []string + for _, c := range l.Containers { + ctrNames = append(ctrNames, c.Names) + } + return strings.Join(ctrNames, ",") +} + +func (l ListPodReporter) ContainerStatuses() string { + var statuses []string + for _, c := range l.Containers { + statuses = append(statuses, c.Status) + } + return strings.Join(statuses, ",") +} |