Skip to content

Commit f6c5862

Browse files
authored
Merge pull request #230 from AkihiroSuda/followup-223
follow-up to "setup docker top cmd" (#223)
2 parents 02badc3 + 390a9ea commit f6c5862

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ It does not necessarily mean that the corresponding features are missing in cont
168168
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
169169
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
170170

171+
171172
- [Run & Exec](#run--exec)
172173
- [:whale: nerdctl run](#whale-nerdctl-run)
173174
- [:whale: nerdctl exec](#whale-nerdctl-exec)
@@ -214,7 +215,7 @@ It does not necessarily mean that the corresponding features are missing in cont
214215
- [:whale: nerdctl events](#whale-nerdctl-events)
215216
- [:whale: nerdctl info](#whale-nerdctl-info)
216217
- [:whale: nerdctl version](#whale-nerdctl-version)
217-
- [Stats management](#stats-management)
218+
- [Stats](#stats)
218219
- [:whale: nerdctl top](#whale-nerdctl-top)
219220
- [Shell completion](#shell-completion)
220221
- [:nerd_face: nerdctl completion bash](#nerd_face-nerdctl-completion-bash)
@@ -755,7 +756,7 @@ Usage: `nerdctl version [OPTIONS]`
755756

756757
Unimplemented `docker version` flags: `--format`
757758

758-
## Stats management
759+
## Stats
759760
### :whale: nerdctl top
760761
Display the running processes of a container.
761762

top.go

+31-10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
limitations under the License.
1515
*/
1616

17+
/*
18+
Portions from:
19+
- https://github.com/moby/moby/blob/v20.10.6/api/types/container/container_top.go
20+
- https://github.com/moby/moby/blob/v20.10.6/daemon/top_unix.go
21+
Copyright (C) The Moby authors.
22+
Licensed under the Apache License, Version 2.0
23+
*/
24+
1725
package main
1826

1927
import (
@@ -34,6 +42,8 @@ import (
3442
"github.com/urfave/cli/v2"
3543
)
3644

45+
// ContainerTopOKBody is from https://github.com/moby/moby/blob/v20.10.6/api/types/container/container_top.go
46+
//
3747
// ContainerTopOKBody OK response to ContainerTop operation
3848
type ContainerTopOKBody struct {
3949

@@ -65,7 +75,11 @@ func topAction(clicontext *cli.Context) error {
6575
// NOTE: rootless container does not rely on cgroupv1.
6676
// more details about possible ways to resolve this concern: #223
6777
if rootlessutil.IsRootless() && infoutil.CgroupsVersion() == "1" {
68-
return fmt.Errorf("top is not supported for rootless container and cgroupv1")
78+
return errors.Errorf("top requires cgroup v2 for rootless containers, see https://rootlesscontaine.rs/getting-started/common/cgroup2/")
79+
}
80+
81+
if clicontext.String("cgroup-manager") == "none" {
82+
return errors.New("cgroup manager must not be \"none\"")
6983
}
7084

7185
client, ctx, cancel, err := newClient(clicontext)
@@ -93,7 +107,7 @@ func topAction(clicontext *cli.Context) error {
93107
return nil
94108
}
95109

96-
//function from moby/moby/daemon/top_unix.go
110+
// appendProcess2ProcList is from https://github.com/moby/moby/blob/v20.10.6/daemon/top_unix.go#L49-L55
97111
func appendProcess2ProcList(procList *ContainerTopOKBody, fields []string) {
98112
// Make sure number of fields equals number of header titles
99113
// merging "overhanging" fields
@@ -102,7 +116,8 @@ func appendProcess2ProcList(procList *ContainerTopOKBody, fields []string) {
102116
procList.Processes = append(procList.Processes, process)
103117
}
104118

105-
//function from moby/moby/daemon/top_unix.go
119+
// psPidsArg is from https://github.com/moby/moby/blob/v20.10.6/daemon/top_unix.go#L119-L131
120+
//
106121
// psPidsArg converts a slice of PIDs to a string consisting
107122
// of comma-separated list of PIDs prepended by "-q".
108123
// For example, psPidsArg([]uint32{1,2,3}) returns "-q1,2,3".
@@ -117,7 +132,7 @@ func psPidsArg(pids []uint32) string {
117132
return string(b)
118133
}
119134

120-
//function from moby/moby/daemon/top_unix.go
135+
// validatePSArgs is from https://github.com/moby/moby/blob/v20.10.6/daemon/top_unix.go#L19-L35
121136
func validatePSArgs(psArgs string) error {
122137
// NOTE: \\s does not detect unicode whitespaces.
123138
// So we use fieldsASCII instead of strings.Fields in parsePSOutput.
@@ -136,7 +151,8 @@ func validatePSArgs(psArgs string) error {
136151
return nil
137152
}
138153

139-
//function from moby/moby/daemon/top_unix.go
154+
// fieldsASCII is from https://github.com/moby/moby/blob/v20.10.6/daemon/top_unix.go#L37-L47
155+
//
140156
// fieldsASCII is similar to strings.Fields but only allows ASCII whitespaces
141157
func fieldsASCII(s string) []string {
142158
fn := func(r rune) bool {
@@ -149,7 +165,7 @@ func fieldsASCII(s string) []string {
149165
return strings.FieldsFunc(s, fn)
150166
}
151167

152-
//function from moby/moby/daemon/top_unix.go
168+
// hasPid is from https://github.com/moby/moby/blob/v20.10.6/daemon/top_unix.go#L57-L64
153169
func hasPid(procs []uint32, pid int) bool {
154170
for _, p := range procs {
155171
if int(p) == pid {
@@ -159,7 +175,7 @@ func hasPid(procs []uint32, pid int) bool {
159175
return false
160176
}
161177

162-
//function from moby/moby/daemon/top_unix.go
178+
// parsePSOutput is from https://github.com/moby/moby/blob/v20.10.6/daemon/top_unix.go#L66-L117
163179
func parsePSOutput(output []byte, procs []uint32) (*ContainerTopOKBody, error) {
164180
procList := &ContainerTopOKBody{}
165181

@@ -213,7 +229,8 @@ func parsePSOutput(output []byte, procs []uint32) (*ContainerTopOKBody, error) {
213229
return procList, nil
214230
}
215231

216-
// function inspired from moby/moby/daemon/top_unix.go
232+
// containerTop was inspired from https://github.com/moby/moby/blob/v20.10.6/daemon/top_unix.go#L133-L189
233+
//
217234
// ContainerTop lists the processes running inside of the given
218235
// container by calling ps with the given args, or with the flags
219236
// "-ef" if no args are given. An error is returned if the container
@@ -298,6 +315,10 @@ func topBashComplete(clicontext *cli.Context) {
298315
defaultBashComplete(clicontext)
299316
return
300317
}
301-
// show container names (TODO: only running containers)
302-
bashCompleteContainerNames(clicontext, nil)
318+
319+
// show running container names
320+
statusFilterFn := func(st containerd.ProcessStatus) bool {
321+
return st == containerd.Running
322+
}
323+
bashCompleteContainerNames(clicontext, statusFilterFn)
303324
}

top_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
func TestTop(t *testing.T) {
2828
//more details https://github.com/containerd/nerdctl/pull/223#issuecomment-851395178
2929
if rootlessutil.IsRootless() && infoutil.CgroupsVersion() == "1" {
30-
t.Skip("test skipped for rootless container with cgroup v1")
30+
t.Skip("test skipped for rootless containers on cgroup v1")
3131
}
3232
const (
3333
testContainerName = "nerdctl-test-top"

0 commit comments

Comments
 (0)