Merge pull request #871 from umohnani8/kpod_ps

Add namespace flag to kpod ps
This commit is contained in:
Daniel J Walsh 2017-09-11 10:14:39 -04:00 committed by GitHub
commit a3a0bb5e55
4 changed files with 140 additions and 26 deletions

View file

@ -1,6 +1,8 @@
package main
import (
"os"
"path/filepath"
"reflect"
"regexp"
"strconv"
@ -30,6 +32,7 @@ type psOptions struct {
quiet bool
size bool
label string
namespace bool
}
type psTemplateParams struct {
@ -44,6 +47,14 @@ type psTemplateParams struct {
Names string
Labels string
Mounts string
PID int
Cgroup string
IPC string
MNT string
NET string
PIDNS string
User string
UTS string
}
// psJSONParams is only used when the JSON format is specified,
@ -64,6 +75,18 @@ type psJSONParams struct {
Labels fields.Set `json:"labels"`
Mounts []specs.Mount `json:"mounts"`
ContainerRunning bool `json:"ctrRunning"`
Namespaces namespace `json:"namespace,omitempty"`
}
type namespace struct {
PID string `json:"ctrPID,omitempty"`
Cgroup string `json:"cgroup,omitempty"`
IPC string `json:"ipc,omitempty"`
MNT string `json:"mnt,omitempty"`
NET string `json:"net,omitempty"`
PIDNS string `json:"pid,omitempty"`
User string `json:"user,omitempty"`
UTS string `json:"uts,omitempty"`
}
const runningState = "running"
@ -103,6 +126,10 @@ var (
Name: "size, s",
Usage: "Display the total file sizes",
},
cli.BoolFlag{
Name: "namespace, ns",
Usage: "Display namespace information",
},
}
psDescription = "Prints out information about the containers"
psCommand = cli.Command{
@ -132,7 +159,7 @@ func psCmd(c *cli.Context) error {
return errors.Errorf("too many arguments, ps takes no arguments")
}
format := genPsFormat(c.Bool("quiet"), c.Bool("size"))
format := genPsFormat(c.Bool("quiet"), c.Bool("size"), c.Bool("namespace"))
if c.IsSet("format") {
format = c.String("format")
}
@ -146,6 +173,7 @@ func psCmd(c *cli.Context) error {
noTrunc: c.Bool("no-trunc"),
quiet: c.Bool("quiet"),
size: c.Bool("size"),
namespace: c.Bool("namespace"),
}
// all, latest, and last are mutually exclusive. Only one flag can be used at a time
@ -183,10 +211,14 @@ func psCmd(c *cli.Context) error {
}
// generate the template based on conditions given
func genPsFormat(quiet, size bool) (format string) {
func genPsFormat(quiet, size, namespace bool) (format string) {
if quiet {
return formats.IDString
}
if namespace {
format = "table {{.ID}}\t{{.Names}}\t{{.PID}}\t{{.Cgroup}}\t{{.IPC}}\t{{.MNT}}\t{{.NET}}\t{{.PIDNS}}\t{{.User}}\t{{.UTS}}\t"
return
}
format = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.CreatedAt}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}\t"
if size {
format += "{{.Size}}\t"
@ -253,13 +285,15 @@ func getTemplateOutput(containers []*libkpod.ContainerData, opts psOptions) (psO
ctrID := ctr.ID
runningFor := units.HumanDuration(time.Since(ctr.State.Created))
createdAt := runningFor + " ago"
command := getCommand(ctr.ImageCreatedBy)
command := getStrFromSquareBrackets(ctr.ImageCreatedBy)
imageName := ctr.FromImage
mounts := getMounts(ctr.Mounts, opts.noTrunc)
ports := getPorts(ctr.Config.ExposedPorts)
size := units.HumanSize(float64(ctr.SizeRootFs))
labels := getLabels(ctr.Labels)
ns := getNamespaces(ctr.State.Pid)
switch ctr.State.Status {
case "stopped":
status = "Exited (" + strconv.FormatInt(int64(ctr.State.ExitCode), 10) + ") " + runningFor + " ago"
@ -286,20 +320,63 @@ func getTemplateOutput(containers []*libkpod.ContainerData, opts psOptions) (psO
Names: ctr.Name,
Labels: labels,
Mounts: mounts,
PID: ctr.State.Pid,
Cgroup: ns.Cgroup,
IPC: ns.IPC,
MNT: ns.MNT,
NET: ns.NET,
PIDNS: ns.PID,
User: ns.User,
UTS: ns.UTS,
}
psOutput = append(psOutput, params)
}
return
}
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
}
// getJSONOutput returns the container info in its raw form
func getJSONOutput(containers []*libkpod.ContainerData) (psOutput []psJSONParams) {
func getJSONOutput(containers []*libkpod.ContainerData, nSpace bool) (psOutput []psJSONParams) {
var ns namespace
for _, ctr := range containers {
if nSpace {
ns = getNamespaces(ctr.State.Pid)
}
params := psJSONParams{
ID: ctr.ID,
Image: ctr.FromImage,
ImageID: ctr.FromImageID,
Command: getCommand(ctr.ImageCreatedBy),
Command: getStrFromSquareBrackets(ctr.ImageCreatedBy),
CreatedAt: ctr.State.Created,
RunningFor: time.Since(ctr.State.Created),
Status: ctr.State.Status,
@ -309,6 +386,7 @@ func getJSONOutput(containers []*libkpod.ContainerData) (psOutput []psJSONParams
Labels: ctr.Labels,
Mounts: ctr.Mounts,
ContainerRunning: ctr.State.Status == runningState,
Namespaces: ns,
}
psOutput = append(psOutput, params)
}
@ -325,7 +403,7 @@ func generatePsOutput(containers []*libkpod.ContainerData, server *libkpod.Conta
switch opts.format {
case formats.JSONString:
psOutput := getJSONOutput(containersOutput)
psOutput := getJSONOutput(containersOutput, opts.namespace)
out = formats.JSONStructArray{Output: psToGeneric([]psTemplateParams{}, psOutput)}
default:
psOutput := getTemplateOutput(containersOutput, opts)
@ -335,8 +413,8 @@ func generatePsOutput(containers []*libkpod.ContainerData, server *libkpod.Conta
return formats.Writer(out).Out()
}
// getCommand gets the actual command from the whole command
func getCommand(cmd string) string {
// getStrFromSquareBrackets gets the string inside [] from a string
func getStrFromSquareBrackets(cmd string) string {
reg, err := regexp.Compile(".*\\[|\\].*")
if err != nil {
return ""

View file

@ -361,6 +361,7 @@ _kpod_ps() {
--no-trunc
--quiet -q
--size -s
--namespace --ns
"
_complete_ "$options_with_args" "$boolean_options"
}

View file

@ -69,6 +69,9 @@ Valid placeholders for the Go template are listed below:
**--latest, -l**
show the latest container created (all states)
**--namespace, --ns**
Display namespace information
**--filter, -f**
Filter output based on conditions given
@ -108,6 +111,14 @@ sudo kpod ps -a --format "{{.ID}} {{.Image}} {{.Labels}} {{.Mounts}}"
69ed779d8ef9f redis:alpine batch=no,type=small proc,tmpfs,devpts,shm,mqueue,sysfs,cgroup,/var/run/,/var/run/
```
```
sudo kpod ps --ns -a
CONTAINER ID NAMES PID CGROUP IPC MNT NET PIDNS USER UTS
3557d882a82e3 k8s_container2_podsandbox1_redhat.test.crio_redhat-test-crio_1 29910 4026531835 4026532585 4026532593 4026532508 4026532595 4026531837 4026532594
09564cdae0bec k8s_container1_podsandbox1_redhat.test.crio_redhat-test-crio_1 29851 4026531835 4026532585 4026532590 4026532508 4026532592 4026531837 4026532591
a31ebbee9cee7 k8s_podsandbox1-redis_podsandbox1_redhat.test.crio_redhat-test-crio_0 29717 4026531835 4026532585 4026532587 4026532508 4026532589 4026531837 4026532588
```
## ps
Print a list of containers

View file

@ -179,6 +179,30 @@ KPOD_OPTIONS="--root $ROOT --runroot $RUNROOT ${STORAGE_OPTS}"
[ "$status" -eq 0 ]
}
@test "kpod ps namespace flag" {
start_crio
[ "$status" -eq 0 ]
run crioctl pod run --config "$TESTDATA"/sandbox_config.json
echo "$output"
[ "$status" -eq 0 ]
pod_id="$output"
run crioctl image pull "$IMAGE"
[ "$status" -eq 0 ]
run crioctl ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id"
echo "$output"
[ "$status" -eq 0 ]
run ${KPOD_BINARY} ${KPOD_OPTIONS} ps -a --ns
echo "$output"
[ "$status" -eq 0 ]
run ${KPOD_BINARY} ${KPOD_OPTIONS} ps --all --namespace
echo "$output"
[ "$status" -eq 0 ]
cleanup_ctrs
cleanup_pods
stop_crio
[ "$status" -eq 0 ]
}
@test "kpod ps format flag = json" {
start_crio
[ "$status" -eq 0 ]
@ -191,7 +215,7 @@ KPOD_OPTIONS="--root $ROOT --runroot $RUNROOT ${STORAGE_OPTS}"
run crioctl ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id"
echo "$output"
[ "$status" -eq 0 ]
run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} ps -a --format json | python -m json.tool"
run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} ps -a --ns --format json | python -m json.tool"
echo "$output"
[ "$status" -eq 0 ]
cleanup_ctrs