Skip to content

Commit f811a2b

Browse files
authored
Merge pull request #878 from HusterWan/zr/add-top-interface
feature: add container top interface
2 parents aac63a3 + 7c6890c commit f811a2b

File tree

9 files changed

+256
-0
lines changed

9 files changed

+256
-0
lines changed

apis/server/container_bridge.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,7 @@ func (s *Server) upgradeContainer(ctx context.Context, rw http.ResponseWriter, r
332332
rw.WriteHeader(http.StatusOK)
333333
return nil
334334
}
335+
336+
func (s *Server) topContainer(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
337+
return nil
338+
}

apis/server/router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func initRoute(s *Server) http.Handler {
4343
r.Path(versionMatcher + "/containers/{name:.*}/unpause").Methods(http.MethodPost).Handler(s.filter(s.unpauseContainer))
4444
r.Path(versionMatcher + "/containers/{name:.*}/update").Methods(http.MethodPost).Handler(s.filter(s.updateContainer))
4545
r.Path(versionMatcher + "/containers/{name:.*}/upgrade").Methods(http.MethodPost).Handler(s.filter(s.upgradeContainer))
46+
r.Path(versionMatcher + "/containers/{name:.*}/top").Methods(http.MethodGet).Handler(s.filter(s.topContainer))
4647

4748
// image
4849
r.Path(versionMatcher + "/images/create").Methods(http.MethodPost).Handler(s.filter(s.pullImage))

apis/swagger.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,27 @@ paths:
450450
$ref: "#/responses/500ErrorResponse"
451451
tags: ["Container"]
452452

453+
/containers/{id}/top:
454+
post:
455+
summary: "Display the running processes of a container"
456+
operationId: "ContainerTop"
457+
parameters:
458+
- $ref: "#/parameters/id"
459+
- name: "ps_args"
460+
in: "query"
461+
description: "top arguments"
462+
type: "string"
463+
responses:
464+
200:
465+
description: "no error"
466+
schema:
467+
$ref: "#/definitions/ContainerProcessList"
468+
404:
469+
$ref: "#/responses/404ErrorResponse"
470+
500:
471+
$ref: "#/responses/500ErrorResponse"
472+
tags: ["Container"]
473+
453474
/containers/{id}:
454475
delete:
455476
summary: "Remove one container"
@@ -2002,6 +2023,22 @@ definitions:
20022023
minItems: 1
20032024
items:
20042025
type: "string"
2026+
ContainerProcessList:
2027+
description: OK Response to ContainerTop operation
2028+
type: "object"
2029+
properties:
2030+
Titles:
2031+
description: "The ps column titles"
2032+
type: "array"
2033+
items:
2034+
type: "string"
2035+
Processes:
2036+
description: "Each process running in the container, where each is process is an array of values corresponding to the titles"
2037+
type: "array"
2038+
items:
2039+
type: "array"
2040+
items:
2041+
type: "string"
20052042

20062043
ExecCreateResp:
20072044
type: "object"

apis/types/container_process_list.go

Lines changed: 85 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/top.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
//"github.com/alibaba/pouch/apis/types"
8+
//"github.com/alibaba/pouch/pkg/reference"
9+
10+
"github.com/spf13/cobra"
11+
)
12+
13+
// topDescription
14+
var topDescription = ""
15+
16+
// TopCommand use to implement 'top' command, it displays all processes in a container.
17+
type TopCommand struct {
18+
baseCommand
19+
args []string
20+
}
21+
22+
// Init initialize top command.
23+
func (top *TopCommand) Init(c *Cli) {
24+
top.cli = c
25+
top.cmd = &cobra.Command{
26+
Use: "top CONTAINER",
27+
Short: "Display the running processes of a container",
28+
Long: topDescription,
29+
Args: cobra.ExactArgs(1),
30+
RunE: func(cmd *cobra.Command, args []string) error {
31+
return top.runTop(args)
32+
},
33+
Example: topExamples(),
34+
}
35+
}
36+
37+
// runTop is the entry of top command.
38+
func (top *TopCommand) runTop(args []string) error {
39+
ctx := context.Background()
40+
apiClient := top.cli.Client()
41+
42+
container := args[0]
43+
44+
arguments := args[1:]
45+
46+
resp, err := apiClient.ContainerTop(ctx, container, arguments)
47+
if err != nil {
48+
return fmt.Errorf("failed to execute top command in container %s: %v", container, err)
49+
}
50+
51+
fmt.Println(resp)
52+
return nil
53+
}
54+
55+
// topExamples shows examples in top command, and is used in auto-generated cli docs.
56+
func topExamples() string {
57+
return ``
58+
}

client/container.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"net"
77
"net/url"
8+
"strings"
89

910
"github.com/alibaba/pouch/apis/types"
1011
)
@@ -186,3 +187,21 @@ func (client *APIClient) ContainerUpdate(ctx context.Context, name string, confi
186187
func (client *APIClient) ContainerUpgrade(ctx context.Context, name string, config types.ContainerConfig, hostConfig *types.HostConfig) error {
187188
return nil
188189
}
190+
191+
// ContainerTop shows process information from within a container.
192+
func (client *APIClient) ContainerTop(ctx context.Context, name string, arguments []string) (types.ContainerProcessList, error) {
193+
response := types.ContainerProcessList{}
194+
query := url.Values{}
195+
if len(arguments) > 0 {
196+
query.Set("ps_args", strings.Join(arguments, " "))
197+
}
198+
199+
resp, err := client.get(ctx, "/containers/"+name+"/top", query, nil)
200+
if err != nil {
201+
return response, err
202+
}
203+
204+
err = decodeBody(&response, resp.Body)
205+
ensureCloseReader(resp)
206+
return response, err
207+
}

client/interface.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type ContainerAPIClient interface {
3434
ContainerUnpause(ctx context.Context, name string) error
3535
ContainerUpdate(ctx context.Context, name string, config *types.UpdateConfig) error
3636
ContainerUpgrade(ctx context.Context, name string, config types.ContainerConfig, hostConfig *types.HostConfig) error
37+
ContainerTop(ctx context.Context, name string, arguments []string) (types.ContainerProcessList, error)
3738
}
3839

3940
// ImageAPIClient defines methods of Image client.

test/api_container_top_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package main
2+
3+
import (
4+
"github.com/alibaba/pouch/test/environment"
5+
//"github.com/alibaba/pouch/test/request"
6+
7+
"github.com/go-check/check"
8+
)
9+
10+
// APIContainerTopSuite is the test suite for container top API.
11+
type APIContainerTopSuite struct{}
12+
13+
func init() {
14+
check.Suite(&APIContainerTopSuite{})
15+
}
16+
17+
// SetUpTest does common setup in the beginning of each test.
18+
func (suite *APIContainerTopSuite) SetUpTest(c *check.C) {
19+
SkipIfFalse(c, environment.IsLinux)
20+
21+
// TODO Add more
22+
}

test/cli_top_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package main
2+
3+
import (
4+
"github.com/alibaba/pouch/test/command"
5+
"github.com/alibaba/pouch/test/environment"
6+
7+
"github.com/go-check/check"
8+
"github.com/gotestyourself/gotestyourself/icmd"
9+
)
10+
11+
// PouchTopSuite is the test suite for top CLI.
12+
type PouchTopSuite struct{}
13+
14+
func init() {
15+
check.Suite(&PouchTopSuite{})
16+
}
17+
18+
// SetupSuite does common setup in the beginning of each test suite.
19+
func (suite *PouchTopSuite) SetupSuite(c *check.C) {
20+
SkipIfFalse(c, environment.IsLinux)
21+
22+
environment.PruneAllContainers(apiClient)
23+
24+
command.PouchRun("pull", busyboxImage).Assert(c, icmd.Success)
25+
}
26+
27+
// TearDownTest does cleanup work in the end of each test.
28+
func (suite *PouchTopSuite) TearDownTest(c *check.C) {
29+
}

0 commit comments

Comments
 (0)