diff options
Diffstat (limited to 'cmd/podman/batchcontainer/container.go')
-rw-r--r-- | cmd/podman/batchcontainer/container.go | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/cmd/podman/batchcontainer/container.go b/cmd/podman/batchcontainer/container.go new file mode 100644 index 000000000..5d3171c42 --- /dev/null +++ b/cmd/podman/batchcontainer/container.go @@ -0,0 +1,159 @@ +package batchcontainer + +import ( + "time" + + "github.com/pkg/errors" + "github.com/projectatomic/libpod/libpod" + "github.com/sirupsen/logrus" + "os" + "path/filepath" + "regexp" + "strconv" + "strings" +) + +// PsOptions describes the struct being formed for ps +type PsOptions struct { + All bool + Filter string + Format string + Last int + Latest bool + NoTrunc bool + Quiet bool + Size bool + Label string + Namespace bool +} + +// BatchContainerStruct is the return obkect from BatchContainer and contains +// container related information +type BatchContainerStruct struct { + ConConfig *libpod.ContainerConfig + ConState libpod.ContainerStatus + ExitCode int32 + Pid int + RootFsSize, RwSize int64 + StartedTime time.Time +} + +// Namespace describes output for ps namespace +type Namespace struct { + PID string `json:"pid,omitempty"` + Cgroup string `json:"cgroup,omitempty"` + IPC string `json:"ipc,omitempty"` + MNT string `json:"mnt,omitempty"` + NET string `json:"net,omitempty"` + PIDNS string `json:"pidns,omitempty"` + User string `json:"user,omitempty"` + UTS string `json:"uts,omitempty"` +} + +// BatchContainer is used in ps to reduce performance hits by "batching" +// locks. +func BatchContainerOp(ctr *libpod.Container, opts PsOptions) (BatchContainerStruct, error) { + var ( + conConfig *libpod.ContainerConfig + conState libpod.ContainerStatus + err error + exitCode int32 + pid int + rootFsSize, rwSize int64 + startedTime time.Time + ) + + batchErr := ctr.Batch(func(c *libpod.Container) error { + conConfig = c.Config() + conState, err = c.State() + if err != nil { + return errors.Wrapf(err, "unable to obtain container state") + } + + exitCode, err = c.ExitCode() + if err != nil { + return errors.Wrapf(err, "unable to obtain container exit code") + } + startedTime, err = c.StartedTime() + if err != nil { + logrus.Errorf("error getting started time for %q: %v", c.ID(), err) + } + + if !opts.Size && !opts.Namespace { + return nil + } + + if opts.Namespace { + pid, err = c.PID() + if err != nil { + return errors.Wrapf(err, "unable to obtain container pid") + } + } + if opts.Size { + rootFsSize, err = c.RootFsSize() + if err != nil { + logrus.Errorf("error getting root fs size for %q: %v", c.ID(), err) + } + + rwSize, err = c.RWSize() + if err != nil { + logrus.Errorf("error getting rw size for %q: %v", c.ID(), err) + } + + } + return nil + }) + if batchErr != nil { + return BatchContainerStruct{}, batchErr + } + return BatchContainerStruct{ + ConConfig: conConfig, + ConState: conState, + ExitCode: exitCode, + Pid: pid, + RootFsSize: rootFsSize, + RwSize: rwSize, + StartedTime: startedTime, + }, nil +} + +// GetNamespaces returns a populated namespace struct +func GetNamespaces(pid int) *Namespace { + ctrPID := strconv.Itoa(pid) + cgroup, _ := getNamespaceInfo(filepath.Join("/proc", ctrPID, "ns", "cgroup")) + ipc, _ := getNamespaceInfo(filepath.Join("/proc", ctrPID, "ns", "ipc")) + mnt, _ := getNamespaceInfo(filepath.Join("/proc", ctrPID, "ns", "mnt")) + net, _ := getNamespaceInfo(filepath.Join("/proc", ctrPID, "ns", "net")) + pidns, _ := getNamespaceInfo(filepath.Join("/proc", ctrPID, "ns", "pid")) + user, _ := getNamespaceInfo(filepath.Join("/proc", ctrPID, "ns", "user")) + uts, _ := getNamespaceInfo(filepath.Join("/proc", ctrPID, "ns", "uts")) + + return &Namespace{ + PID: ctrPID, + Cgroup: cgroup, + IPC: ipc, + MNT: mnt, + NET: net, + PIDNS: pidns, + User: user, + UTS: uts, + } +} + +func getNamespaceInfo(path string) (string, error) { + val, err := os.Readlink(path) + if err != nil { + return "", errors.Wrapf(err, "error getting info from %q", path) + } + return getStrFromSquareBrackets(val), nil +} + +// getStrFromSquareBrackets gets the string inside [] from a string +func getStrFromSquareBrackets(cmd string) string { + reg, err := regexp.Compile(".*\\[|\\].*") + if err != nil { + return "" + } + arr := strings.Split(reg.ReplaceAllLiteralString(cmd, ""), ",") + return strings.Join(arr, ",") +} |