summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2019-04-09 13:07:27 -0500
committerbaude <bbaude@redhat.com>2019-04-09 15:00:35 -0500
commit23cd1928ec36a80f491b329dda3789b2dac32bcc (patch)
treec52ef533642c22cb3483790afe57e810ac615112
parentfe79bdd07e140176dc64ebef8da3eea2ae28b96b (diff)
downloadpodman-23cd1928ec36a80f491b329dda3789b2dac32bcc.tar.gz
podman-23cd1928ec36a80f491b329dda3789b2dac32bcc.tar.bz2
podman-23cd1928ec36a80f491b329dda3789b2dac32bcc.zip
podman-remote ps
add the ability to run ps on containers using the remote client. Signed-off-by: baude <bbaude@redhat.com>
-rw-r--r--cmd/podman/commands.go1
-rw-r--r--cmd/podman/main.go1
-rw-r--r--cmd/podman/ps.go183
-rw-r--r--cmd/podman/shared/container.go171
-rw-r--r--cmd/podman/varlink/io.podman.varlink43
-rw-r--r--libpod/container.go23
-rw-r--r--pkg/adapter/containers.go10
-rw-r--r--pkg/adapter/containers_remote.go72
-rw-r--r--pkg/varlinkapi/containers.go49
-rw-r--r--pkg/varlinkapi/util.go33
10 files changed, 407 insertions, 179 deletions
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index e9afcbc06..5b2581216 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -16,7 +16,6 @@ func getMainCommands() []*cobra.Command {
_execCommand,
_generateCommand,
_playCommand,
- &_psCommand,
_loginCommand,
_logoutCommand,
_mountCommand,
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index b44cf9f0a..52bf2daf0 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -52,6 +52,7 @@ var mainCommands = []*cobra.Command{
_loadCommand,
_logsCommand,
podCommand.Command,
+ &_psCommand,
_pullCommand,
_pushCommand,
&_rmiCommand,
diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go
index 759a03b86..59376b6aa 100644
--- a/cmd/podman/ps.go
+++ b/cmd/podman/ps.go
@@ -6,7 +6,6 @@ import (
"os"
"reflect"
"sort"
- "strconv"
"strings"
"text/tabwriter"
"time"
@@ -14,15 +13,12 @@ import (
tm "github.com/buger/goterm"
"github.com/containers/buildah/pkg/formats"
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
- "github.com/containers/libpod/libpod"
- "github.com/containers/libpod/pkg/util"
+ "github.com/containers/libpod/pkg/adapter"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/go-units"
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/fields"
)
@@ -224,7 +220,7 @@ func psCmd(c *cliconfig.PsValues) error {
return errors.Wrapf(err, "error with flags passed")
}
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
@@ -279,128 +275,6 @@ func checkFlagsPassed(c *cliconfig.PsValues) error {
return nil
}
-func generateContainerFilterFuncs(filter, filterValue string, runtime *libpod.Runtime) (func(container *libpod.Container) bool, error) {
- switch filter {
- case "id":
- return func(c *libpod.Container) bool {
- return strings.Contains(c.ID(), filterValue)
- }, nil
- case "label":
- var filterArray []string = strings.SplitN(filterValue, "=", 2)
- var filterKey string = filterArray[0]
- if len(filterArray) > 1 {
- filterValue = filterArray[1]
- } else {
- filterValue = ""
- }
- return func(c *libpod.Container) bool {
- for labelKey, labelValue := range c.Labels() {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
- return true
- }
- }
- return false
- }, nil
- case "name":
- return func(c *libpod.Container) bool {
- return strings.Contains(c.Name(), filterValue)
- }, nil
- case "exited":
- exitCode, err := strconv.ParseInt(filterValue, 10, 32)
- if err != nil {
- return nil, errors.Wrapf(err, "exited code out of range %q", filterValue)
- }
- return func(c *libpod.Container) bool {
- ec, exited, err := c.ExitCode()
- if ec == int32(exitCode) && err == nil && exited == true {
- return true
- }
- return false
- }, nil
- case "status":
- if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
- return nil, errors.Errorf("%s is not a valid status", filterValue)
- }
- return func(c *libpod.Container) bool {
- status, err := c.State()
- if err != nil {
- return false
- }
- if filterValue == "stopped" {
- filterValue = "exited"
- }
- state := status.String()
- if status == libpod.ContainerStateConfigured {
- state = "created"
- } else if status == libpod.ContainerStateStopped {
- state = "exited"
- }
- return state == filterValue
- }, nil
- case "ancestor":
- // This needs to refine to match docker
- // - ancestor=(<image-name>[:tag]|<image-id>| ⟨image@digest⟩) - containers created from an image or a descendant.
- return func(c *libpod.Container) bool {
- containerConfig := c.Config()
- if strings.Contains(containerConfig.RootfsImageID, filterValue) || strings.Contains(containerConfig.RootfsImageName, filterValue) {
- return true
- }
- return false
- }, nil
- case "before":
- ctr, err := runtime.LookupContainer(filterValue)
- if err != nil {
- return nil, errors.Errorf("unable to find container by name or id of %s", filterValue)
- }
- containerConfig := ctr.Config()
- createTime := containerConfig.CreatedTime
- return func(c *libpod.Container) bool {
- cc := c.Config()
- return createTime.After(cc.CreatedTime)
- }, nil
- case "since":
- ctr, err := runtime.LookupContainer(filterValue)
- if err != nil {
- return nil, errors.Errorf("unable to find container by name or id of %s", filterValue)
- }
- containerConfig := ctr.Config()
- createTime := containerConfig.CreatedTime
- return func(c *libpod.Container) bool {
- cc := c.Config()
- return createTime.Before(cc.CreatedTime)
- }, nil
- case "volume":
- //- volume=(<volume-name>|<mount-point-destination>)
- return func(c *libpod.Container) bool {
- containerConfig := c.Config()
- var dest string
- arr := strings.Split(filterValue, ":")
- source := arr[0]
- if len(arr) == 2 {
- dest = arr[1]
- }
- for _, mount := range containerConfig.Spec.Mounts {
- if dest != "" && (mount.Source == source && mount.Destination == dest) {
- return true
- }
- if dest == "" && mount.Source == source {
- return true
- }
- }
- return false
- }, nil
- case "health":
- return func(c *libpod.Container) bool {
- hcStatus, err := c.HealthCheckStatus()
- if err != nil {
- return false
- }
- return hcStatus == filterValue
- }, nil
- }
- return nil, errors.Errorf("%s is an invalid filter", filter)
-}
-
// generate the accurate header based on template given
func (p *psTemplateParams) headerMap() map[string]string {
v := reflect.Indirect(reflect.ValueOf(p))
@@ -550,11 +424,9 @@ func dumpJSON(containers []shared.PsContainerOutput) error {
return nil
}
-func psDisplay(c *cliconfig.PsValues, runtime *libpod.Runtime) error {
+func psDisplay(c *cliconfig.PsValues, runtime *adapter.LocalRuntime) error {
var (
- filterFuncs []libpod.ContainerFilter
- outputContainers []*libpod.Container
- err error
+ err error
)
opts := shared.PsOptions{
All: c.All,
@@ -570,51 +442,8 @@ func psDisplay(c *cliconfig.PsValues, runtime *libpod.Runtime) error {
Sync: c.Sync,
}
- maxWorkers := shared.Parallelize("ps")
- if c.GlobalIsSet("max-workers") {
- maxWorkers = c.GlobalFlags.MaxWorks
- }
- logrus.Debugf("Setting maximum workers to %d", maxWorkers)
-
- filters := c.Filter
- if len(filters) > 0 {
- for _, f := range filters {
- filterSplit := strings.SplitN(f, "=", 2)
- if len(filterSplit) < 2 {
- return errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f)
- }
- generatedFunc, err := generateContainerFilterFuncs(filterSplit[0], filterSplit[1], runtime)
- if err != nil {
- return errors.Wrapf(err, "invalid filter")
- }
- filterFuncs = append(filterFuncs, generatedFunc)
- }
- }
- if !opts.Latest {
- // Get all containers
- containers, err := runtime.GetContainers(filterFuncs...)
- if err != nil {
- return err
- }
-
- // We only want the last few containers
- if opts.Last > 0 && opts.Last <= len(containers) {
- return errors.Errorf("--last not yet supported")
- } else {
- outputContainers = containers
- }
- } else {
- // Get just the latest container
- // Ignore filters
- latestCtr, err := runtime.GetLatestContainer()
- if err != nil {
- return err
- }
-
- outputContainers = []*libpod.Container{latestCtr}
- }
-
- pss := shared.PBatch(outputContainers, maxWorkers, opts)
+ pss, err := runtime.Ps(c, opts)
+ // Here and down
if opts.Sort != "" {
pss, err = sortPsOutput(opts.Sort, pss)
if err != nil {
diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go
index 6826191c5..7bef62355 100644
--- a/cmd/podman/shared/container.go
+++ b/cmd/podman/shared/container.go
@@ -44,7 +44,6 @@ type PsOptions struct {
Quiet bool
Size bool
Sort string
- Label string
Namespace bool
Sync bool
}
@@ -274,6 +273,176 @@ func worker(wg *sync.WaitGroup, jobs <-chan workerInput, results chan<- PsContai
}
}
+func generateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime) (func(container *libpod.Container) bool, error) {
+ switch filter {
+ case "id":
+ return func(c *libpod.Container) bool {
+ return strings.Contains(c.ID(), filterValue)
+ }, nil
+ case "label":
+ var filterArray []string = strings.SplitN(filterValue, "=", 2)
+ var filterKey string = filterArray[0]
+ if len(filterArray) > 1 {
+ filterValue = filterArray[1]
+ } else {
+ filterValue = ""
+ }
+ return func(c *libpod.Container) bool {
+ for labelKey, labelValue := range c.Labels() {
+ if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ return true
+ }
+ }
+ return false
+ }, nil
+ case "name":
+ return func(c *libpod.Container) bool {
+ return strings.Contains(c.Name(), filterValue)
+ }, nil
+ case "exited":
+ exitCode, err := strconv.ParseInt(filterValue, 10, 32)
+ if err != nil {
+ return nil, errors.Wrapf(err, "exited code out of range %q", filterValue)
+ }
+ return func(c *libpod.Container) bool {
+ ec, exited, err := c.ExitCode()
+ if ec == int32(exitCode) && err == nil && exited == true {
+ return true
+ }
+ return false
+ }, nil
+ case "status":
+ if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
+ return nil, errors.Errorf("%s is not a valid status", filterValue)
+ }
+ return func(c *libpod.Container) bool {
+ status, err := c.State()
+ if err != nil {
+ return false
+ }
+ if filterValue == "stopped" {
+ filterValue = "exited"
+ }
+ state := status.String()
+ if status == libpod.ContainerStateConfigured {
+ state = "created"
+ } else if status == libpod.ContainerStateStopped {
+ state = "exited"
+ }
+ return state == filterValue
+ }, nil
+ case "ancestor":
+ // This needs to refine to match docker
+ // - ancestor=(<image-name>[:tag]|<image-id>| ⟨image@digest⟩) - containers created from an image or a descendant.
+ return func(c *libpod.Container) bool {
+ containerConfig := c.Config()
+ if strings.Contains(containerConfig.RootfsImageID, filterValue) || strings.Contains(containerConfig.RootfsImageName, filterValue) {
+ return true
+ }
+ return false
+ }, nil
+ case "before":
+ ctr, err := r.LookupContainer(filterValue)
+ if err != nil {
+ return nil, errors.Errorf("unable to find container by name or id of %s", filterValue)
+ }
+ containerConfig := ctr.Config()
+ createTime := containerConfig.CreatedTime
+ return func(c *libpod.Container) bool {
+ cc := c.Config()
+ return createTime.After(cc.CreatedTime)
+ }, nil
+ case "since":
+ ctr, err := r.LookupContainer(filterValue)
+ if err != nil {
+ return nil, errors.Errorf("unable to find container by name or id of %s", filterValue)
+ }
+ containerConfig := ctr.Config()
+ createTime := containerConfig.CreatedTime
+ return func(c *libpod.Container) bool {
+ cc := c.Config()
+ return createTime.Before(cc.CreatedTime)
+ }, nil
+ case "volume":
+ //- volume=(<volume-name>|<mount-point-destination>)
+ return func(c *libpod.Container) bool {
+ containerConfig := c.Config()
+ var dest string
+ arr := strings.Split(filterValue, ":")
+ source := arr[0]
+ if len(arr) == 2 {
+ dest = arr[1]
+ }
+ for _, mount := range containerConfig.Spec.Mounts {
+ if dest != "" && (mount.Source == source && mount.Destination == dest) {
+ return true
+ }
+ if dest == "" && mount.Source == source {
+ return true
+ }
+ }
+ return false
+ }, nil
+ case "health":
+ return func(c *libpod.Container) bool {
+ hcStatus, err := c.HealthCheckStatus()
+ if err != nil {
+ return false
+ }
+ return hcStatus == filterValue
+ }, nil
+ }
+ return nil, errors.Errorf("%s is an invalid filter", filter)
+}
+
+// GetPsContainerOutput returns a slice of containers specifically for ps output
+func GetPsContainerOutput(r *libpod.Runtime, opts PsOptions, filters []string, maxWorkers int) ([]PsContainerOutput, error) {
+ var (
+ filterFuncs []libpod.ContainerFilter
+ outputContainers []*libpod.Container
+ )
+
+ if len(filters) > 0 {
+ for _, f := range filters {
+ filterSplit := strings.SplitN(f, "=", 2)
+ if len(filterSplit) < 2 {
+ return nil, errors.Errorf("filter input must be in the form of filter=value: %s is invalid", f)
+ }
+ generatedFunc, err := generateContainerFilterFuncs(filterSplit[0], filterSplit[1], r)
+ if err != nil {
+ return nil, errors.Wrapf(err, "invalid filter")
+ }
+ filterFuncs = append(filterFuncs, generatedFunc)
+ }
+ }
+ if !opts.Latest {
+ // Get all containers
+ containers, err := r.GetContainers(filterFuncs...)
+ if err != nil {
+ return nil, err
+ }
+
+ // We only want the last few containers
+ if opts.Last > 0 && opts.Last <= len(containers) {
+ return nil, errors.Errorf("--last not yet supported")
+ } else {
+ outputContainers = containers
+ }
+ } else {
+ // Get just the latest container
+ // Ignore filters
+ latestCtr, err := r.GetLatestContainer()
+ if err != nil {
+ return nil, err
+ }
+
+ outputContainers = []*libpod.Container{latestCtr}
+ }
+
+ pss := PBatch(outputContainers, maxWorkers, opts)
+ return pss, nil
+}
+
// PBatch is performs batch operations on a container in parallel. It spawns the number of workers
// relative to the the number of parallel operations desired.
func PBatch(containers []*libpod.Container, workers int, opts PsOptions) []PsContainerOutput {
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 9098a9297..d8905326c 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -133,6 +133,47 @@ type ContainerStats (
pids: int
)
+type PsOpts (
+ all: bool,
+ filters: ?[]string,
+ last: ?int,
+ latest: ?bool,
+ noTrunc: ?bool,
+ pod: ?bool,
+ quiet: ?bool,
+ sort: ?string,
+ sync: ?bool
+)
+
+type PsContainer (
+ id: string,
+ image: string,
+ command: string,
+ created: string,
+ ports: string,
+ names: string,
+ isInfra: bool,
+ status: string,
+ state: string,
+ pidNum: int,
+ rootFsSize: int,
+ rwSize: int,
+ pod: string,
+ createdAt: string,
+ exitedAt: string,
+ startedAt: string,
+ labels: [string]string,
+ nsPid: string,
+ cgroup: string,
+ ipc: string,
+ mnt: string,
+ net: string,
+ pidNs: string,
+ user: string,
+ uts: string,
+ mounts: string
+)
+
# ContainerMount describes the struct for mounts in a container
type ContainerMount (
destination: string,
@@ -474,6 +515,8 @@ method GetInfo() -> (info: PodmanInfo)
# See also [GetContainer](#GetContainer).
method ListContainers() -> (containers: []Container)
+method Ps(opts: PsOpts) -> (containers: []PsContainer)
+
# GetContainer returns information about a single container. If a container
# with the given id doesn't exist, a [ContainerNotFound](#ContainerNotFound)
# error will be returned. See also [ListContainers](ListContainers) and
diff --git a/libpod/container.go b/libpod/container.go
index 6d5e063ab..523e571b1 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -401,6 +401,29 @@ func (t ContainerStatus) String() string {
return "bad state"
}
+// StringToContainerStatus converts a string representation of a containers
+// status into an actual container status type
+func StringToContainerStatus(status string) (ContainerStatus, error) {
+ switch status {
+ case ContainerStateUnknown.String():
+ return ContainerStateUnknown, nil
+ case ContainerStateConfigured.String():
+ return ContainerStateConfigured, nil
+ case ContainerStateCreated.String():
+ return ContainerStateCreated, nil
+ case ContainerStateRunning.String():
+ return ContainerStateRunning, nil
+ case ContainerStateStopped.String():
+ return ContainerStateStopped, nil
+ case ContainerStatePaused.String():
+ return ContainerStatePaused, nil
+ case ContainerStateExited.String():
+ return ContainerStateExited, nil
+ default:
+ return ContainerStateUnknown, errors.Wrapf(ErrInvalidArg, "unknown container state: %s", status)
+ }
+}
+
// Config accessors
// Unlocked
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 1bca99cec..598cde98e 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -304,3 +304,13 @@ func ReadExitFile(runtimeTmp, ctrID string) (int, error) {
return exitCode, nil
}
+
+// Ps ...
+func (r *LocalRuntime) Ps(c *cliconfig.PsValues, opts shared.PsOptions) ([]shared.PsContainerOutput, error) {
+ maxWorkers := shared.Parallelize("ps")
+ if c.GlobalIsSet("max-workers") {
+ maxWorkers = c.GlobalFlags.MaxWorks
+ }
+ logrus.Debugf("Setting maximum workers to %d", maxWorkers)
+ return shared.GetPsContainerOutput(r.Runtime, opts, c.Filter, maxWorkers)
+}
diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go
index 3730827c7..79177f5ff 100644
--- a/pkg/adapter/containers_remote.go
+++ b/pkg/adapter/containers_remote.go
@@ -292,3 +292,75 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
func ReadExitFile(runtimeTmp, ctrID string) (int, error) {
return 0, libpod.ErrNotImplemented
}
+
+// Ps ...
+func (r *LocalRuntime) Ps(c *cliconfig.PsValues, opts shared.PsOptions) ([]shared.PsContainerOutput, error) {
+ var psContainers []shared.PsContainerOutput
+ last := int64(c.Last)
+ PsOpts := iopodman.PsOpts{
+ All: c.All,
+ Filters: &c.Filter,
+ Last: &last,
+ Latest: &c.Latest,
+ NoTrunc: &c.NoTrunct,
+ Pod: &c.Pod,
+ Quiet: &c.Quiet,
+ Sort: &c.Sort,
+ Sync: &c.Sync,
+ }
+ containers, err := iopodman.Ps().Call(r.Conn, PsOpts)
+ if err != nil {
+ return nil, err
+ }
+ for _, ctr := range containers {
+ createdAt, err := time.Parse(time.RFC3339Nano, ctr.CreatedAt)
+ if err != nil {
+ return nil, err
+ }
+ exitedAt, err := time.Parse(time.RFC3339Nano, ctr.ExitedAt)
+ if err != nil {
+ return nil, err
+ }
+ startedAt, err := time.Parse(time.RFC3339Nano, ctr.StartedAt)
+ if err != nil {
+ return nil, err
+ }
+ containerSize := shared.ContainerSize{
+ RootFsSize: ctr.RootFsSize,
+ RwSize: ctr.RwSize,
+ }
+ state, err := libpod.StringToContainerStatus(ctr.State)
+ if err != nil {
+ return nil, err
+ }
+ psc := shared.PsContainerOutput{
+ ID: ctr.Id,
+ Image: ctr.Image,
+ Command: ctr.Command,
+ Created: ctr.Created,
+ Ports: ctr.Ports,
+ Names: ctr.Names,
+ IsInfra: ctr.IsInfra,
+ Status: ctr.Status,
+ State: state,
+ Pid: int(ctr.PidNum),
+ Size: &containerSize,
+ Pod: ctr.Pod,
+ CreatedAt: createdAt,
+ ExitedAt: exitedAt,
+ StartedAt: startedAt,
+ Labels: ctr.Labels,
+ PID: ctr.NsPid,
+ Cgroup: ctr.Cgroup,
+ IPC: ctr.Ipc,
+ MNT: ctr.Mnt,
+ NET: ctr.Net,
+ PIDNS: ctr.PidNs,
+ User: ctr.User,
+ UTS: ctr.Uts,
+ Mounts: ctr.Mounts,
+ }
+ psContainers = append(psContainers, psc)
+ }
+ return psContainers, nil
+}
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index ac1352dac..816a72953 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -47,6 +47,55 @@ func (i *LibpodAPI) ListContainers(call iopodman.VarlinkCall) error {
return call.ReplyListContainers(listContainers)
}
+func (i *LibpodAPI) Ps(call iopodman.VarlinkCall, opts iopodman.PsOpts) error {
+ var (
+ containers []iopodman.PsContainer
+ )
+ maxWorkers := shared.Parallelize("ps")
+ psOpts := makePsOpts(opts)
+ filters := []string{}
+ if opts.Filters != nil {
+ filters = *opts.Filters
+ }
+ psContainerOutputs, err := shared.GetPsContainerOutput(i.Runtime, psOpts, filters, maxWorkers)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+
+ for _, ctr := range psContainerOutputs {
+ container := iopodman.PsContainer{
+ Id: ctr.ID,
+ Image: ctr.Image,
+ Command: ctr.Command,
+ Created: ctr.Created,
+ Ports: ctr.Ports,
+ Names: ctr.Names,
+ IsInfra: ctr.IsInfra,
+ Status: ctr.Status,
+ State: ctr.State.String(),
+ PidNum: int64(ctr.Pid),
+ RootFsSize: ctr.Size.RootFsSize,
+ RwSize: ctr.Size.RwSize,
+ Pod: ctr.Pod,
+ CreatedAt: ctr.CreatedAt.Format(time.RFC3339Nano),
+ ExitedAt: ctr.ExitedAt.Format(time.RFC3339Nano),
+ StartedAt: ctr.StartedAt.Format(time.RFC3339Nano),
+ Labels: ctr.Labels,
+ NsPid: ctr.PID,
+ Cgroup: ctr.Cgroup,
+ Ipc: ctr.Cgroup,
+ Mnt: ctr.MNT,
+ Net: ctr.NET,
+ PidNs: ctr.PIDNS,
+ User: ctr.User,
+ Uts: ctr.UTS,
+ Mounts: ctr.Mounts,
+ }
+ containers = append(containers, container)
+ }
+ return call.ReplyPs(containers)
+}
+
// GetContainer ...
func (i *LibpodAPI) GetContainer(call iopodman.VarlinkCall, id string) error {
ctr, err := i.Runtime.LookupContainer(id)
diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go
index 3c4b9b79a..8716c963a 100644
--- a/pkg/varlinkapi/util.go
+++ b/pkg/varlinkapi/util.go
@@ -162,3 +162,36 @@ func stringPullPolicyToType(s string) buildah.PullPolicy {
}
return buildah.PullIfMissing
}
+
+func derefBool(inBool *bool) bool {
+ if inBool == nil {
+ return false
+ }
+ return *inBool
+}
+
+func derefString(in *string) string {
+ if in == nil {
+ return ""
+ }
+ return *in
+}
+
+func makePsOpts(inOpts iopodman.PsOpts) shared.PsOptions {
+ last := 0
+ if inOpts.Last != nil {
+ lastT := *inOpts.Last
+ last = int(lastT)
+ }
+ return shared.PsOptions{
+ All: inOpts.All,
+ Last: last,
+ Latest: derefBool(inOpts.Latest),
+ NoTrunc: derefBool(inOpts.NoTrunc),
+ Pod: derefBool(inOpts.Pod),
+ Size: true,
+ Sort: derefString(inOpts.Sort),
+ Namespace: true,
+ Sync: derefBool(inOpts.Sync),
+ }
+}