From d274c2f46899ef46381569fefd0812b5c2b58fd7 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Mon, 20 Sep 2021 14:13:30 +0200 Subject: [PATCH] support supplementary groups Add two new descriptors: * `groups` for supplementary groups inside the container * `hgroups` for the counterpart on the host Example: ``` podman (main) $ ./bin/podman top -l pid,hpid,group,hgroup,groups,hgroups PID HPID GROUP HGROUP GROUPS HGROUPS 1 92536 root 1000 root,bin,daemon,sys,adm,disk,wheel,floppy,dialout,tape,video 1000,100000,100001,100002,100003,100005,100009,100010,100019,100025,100026 ``` Closes: #87 Signed-off-by: Valentin Rothberg --- README.md | 4 ++++ psgo.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ test/format.bats | 19 ++++++++++++++++++- test/list.bats | 2 +- 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fed42c6..684c80a 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,12 @@ The ps library is compatible with all AIX format descriptors of the ps command-l - Set of inheritable capabilities. See capabilities(7) for more information. - **capprm** - Set of permitted capabilities. See capabilities(7) for more information. +- **groups** + - Supplmentary groups inside the container. - **hgroup** - The corresponding effective group of a container process on the host. +- **hgroups** + - Supplmentary groups on the host. - **hpid** - The corresponding host PID of a container process. - **huser** diff --git a/psgo.go b/psgo.go index e48a2d1..ea893e7 100644 --- a/psgo.go +++ b/psgo.go @@ -174,6 +174,11 @@ var ( header: "GROUP", procFn: processGROUP, }, + { + normal: "groups", + header: "GROUPS", + procFn: processGROUPS, + }, { code: "%P", normal: "ppid", @@ -305,6 +310,12 @@ var ( onHost: true, procFn: processHGROUP, }, + { + normal: "hgroups", + header: "HGROUPS", + onHost: true, + procFn: processHGROUPS, + }, { normal: "rss", header: "RSS", @@ -626,6 +637,21 @@ func processGROUP(p *process.Process, ctx *psContext) (string, error) { return process.LookupGID(p.Status.Gids[1]) } +// processGROUPS returns the supplementary groups of the process separated by +// comma. This will be the textual group ID, if it can be obtained, or a +// decimal representation otherwise. +func processGROUPS(p *process.Process, ctx *psContext) (string, error) { + var err error + groups := make([]string, len(p.Status.Groups)) + for i, g := range p.Status.Groups { + groups[i], err = process.LookupGID(g) + if err != nil { + return "", err + } + } + return strings.Join(groups, ","), nil +} + // processRGROUP returns the real group ID of the process. This will be // the textual group ID, if it can be obtained, or a decimal representation // otherwise. @@ -867,6 +893,26 @@ func processHGROUP(p *process.Process, ctx *psContext) (string, error) { return "?", nil } +// processHGROUPS returns the supplementary groups of the corresponding host +// process of the (container) or "?" if no corresponding process could be +// found. +func processHGROUPS(p *process.Process, ctx *psContext) (string, error) { + if hp := findHostProcess(p, ctx); hp != nil { + groups := hp.Status.Groups + if ctx.opts != nil && len(ctx.opts.GIDMap) > 0 { + var err error + for i, g := range groups { + groups[i], err = findID(g, ctx.opts.GIDMap, process.LookupGID, "/proc/sys/fs/overflowgid") + if err != nil { + return "", err + } + } + } + return strings.Join(groups, ","), nil + } + return "?", nil +} + // processRSS returns the resident set size of process p in KiB (1024-byte // units). func processRSS(p *process.Process, ctx *psContext) (string, error) { diff --git a/test/format.bats b/test/format.bats index c399704..e0979e2 100644 --- a/test/format.bats +++ b/test/format.bats @@ -33,6 +33,12 @@ [[ ${lines[0]} =~ "GROUP" ]] } +@test "GROUPS header" { + run ./bin/psgo -format "groups" + [ "$status" -eq 0 ] + [[ ${lines[0]} =~ "GROUPS" ]] +} + @test "PPID header" { run ./bin/psgo -format "%P" [ "$status" -eq 0 ] @@ -213,6 +219,15 @@ [[ ${lines[1]} =~ "?" ]] } +@test "HGROUPS header" { + run ./bin/psgo -format "hgroups" + [ "$status" -eq 0 ] + [[ ${lines[0]} =~ "HGROUPS" ]] + # host groups are only extracted with `-pid` + [[ ${lines[1]} =~ "?" ]] +} + + function is_labeling_enabled() { if [ -e /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then echo 1 @@ -250,11 +265,12 @@ function is_labeling_enabled() { } @test "ALL header" { - run ./bin/psgo -format "pcpu, group, ppid, user, args, comm, rgroup, nice, pid, pgid, etime, ruser, time, tty, vsz, capamb, capinh, capprm, capeff, capbnd, seccomp, hpid, huser, hgroup, rss, state" + run ./bin/psgo -format "pcpu, group, groups, ppid, user, args, comm, rgroup, nice, pid, pgid, etime, ruser, time, tty, vsz, capamb, capinh, capprm, capeff, capbnd, seccomp, hpid, huser, hgroup, hgroups, rss, state" [ "$status" -eq 0 ] [[ ${lines[0]} =~ "%CPU" ]] [[ ${lines[0]} =~ "GROUP" ]] + [[ ${lines[0]} =~ "GROUPS" ]] [[ ${lines[0]} =~ "PPID" ]] [[ ${lines[0]} =~ "USER" ]] [[ ${lines[0]} =~ "COMMAND" ]] @@ -276,6 +292,7 @@ function is_labeling_enabled() { [[ ${lines[0]} =~ "HPID" ]] [[ ${lines[0]} =~ "HUSER" ]] [[ ${lines[0]} =~ "HGROUP" ]] + [[ ${lines[0]} =~ "HGROUPS" ]] [[ ${lines[0]} =~ "RSS" ]] [[ ${lines[0]} =~ "STATE" ]] } diff --git a/test/list.bats b/test/list.bats index 57c7a99..4edfb1f 100644 --- a/test/list.bats +++ b/test/list.bats @@ -3,5 +3,5 @@ @test "List descriptors" { run ./bin/psgo -list [ "$status" -eq 0 ] - [[ ${lines[0]} =~ "args, capamb, capbnd, capeff, capinh, capprm, comm, etime, group, hgroup, hpid, huser, label, nice, pcpu, pgid, pid, ppid, rgroup, rss, ruser, seccomp, state, stime, time, tty, user, vsz" ]] + [[ ${lines[0]} =~ "args, capamb, capbnd, capeff, capinh, capprm, comm, etime, group, groups, hgroup, hgroups, hpid, huser, label, nice, pcpu, pgid, pid, ppid, rgroup, rss, ruser, seccomp, state, stime, time, tty, user, vsz" ]] }