Skip to content

Commit

Permalink
add inspect command to get pid of container (#213)
Browse files Browse the repository at this point in the history
feature: add inspect command to get pid of container
  • Loading branch information
CodeJuan authored and allencloud committed Dec 5, 2017
1 parent c8cb371 commit 432a53d
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 1 deletion.
18 changes: 18 additions & 0 deletions apis/server/container_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,21 @@ func (s *Server) getContainers(ctx context.Context, resp http.ResponseWriter, re
resp.WriteHeader(http.StatusOK)
return json.NewEncoder(resp).Encode(cs)
}

func (s *Server) getContainer(ctx context.Context, resp http.ResponseWriter, req *http.Request) error {
name := mux.Vars(req)["name"]
ci, err := s.ContainerMgr.Get(name)
if err != nil {
return err
}

c := types.ContainerJSON{
ID: ci.ID,
Name: ci.Name,
Image: ci.Config.Image,
Created: ci.StartedAt.Format("2006-01-02 15:04:05"),
State: &types.ContainerState{Pid: ci.Pid},
}
resp.WriteHeader(http.StatusOK)
return json.NewEncoder(resp).Encode(c)
}
1 change: 1 addition & 0 deletions apis/server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func initRoute(s *Server) http.Handler {
r.Path("/containers/{name:.*}/stop").Methods(http.MethodPost).Handler(s.filter(s.stopContainer))
r.Path("/containers/{name:.*}/attach").Methods(http.MethodPost).Handler(s.filter(s.attachContainer))
r.Path("/containers/json").Methods(http.MethodGet).Handler(s.filter(s.getContainers))
r.Path("/containers/{name:.*}/json").Methods(http.MethodGet).Handler(s.filter(s.getContainer))
r.Path("/containers/{name:.*}").Methods(http.MethodDelete).Handler(s.filter(s.removeContainers))
r.Path("/containers/{name:.*}/exec").Methods(http.MethodPost).Handler(s.filter(s.createContainerExec))
r.Path("/exec/{name:.*}/start").Methods(http.MethodPost).Handler(s.filter(s.startContainerExec))
Expand Down
36 changes: 36 additions & 0 deletions apis/types/container_json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package types

// ContainerJSON contains response of Remote API:
// GET "/containers/{name:.*}/json"
type ContainerJSON struct {
ID string `json:"Id"`
Created string
Path string
Args []string
State *ContainerState
Image string
ResolvConfPath string
HostnamePath string
HostsPath string
LogPath string
Name string
RestartCount int
Driver string
MountLabel string
ProcessLabel string
AppArmorProfile string
ExecIDs []string
HostConfig *HostConfig
SizeRw *int64 `json:",omitempty"`
SizeRootFs *int64 `json:",omitempty"`
HostRootPath string
}

// TODO
// ContainerJSON is newly used struct along with MountPoint
//type ContainerJSON struct {
// *ContainerJSONBase
// Mounts []MountPoint
// Config *container.Config
// NetworkSettings *NetworkSettings
//}
81 changes: 81 additions & 0 deletions cli/inspect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package main

import (
"encoding/json"
"fmt"

"github.com/spf13/cobra"
)

// inspectDescription is used to describe inspect command in detail and auto generate command doc.
var inspectDescription = "Return detailed information on Pouch container"

// InspectCommand is used to implement 'inspect' command.
type InspectCommand struct {
baseCommand
}

// Init initializes InspectCommand command.
func (p *InspectCommand) Init(c *Cli) {
p.cli = c
p.cmd = &cobra.Command{
Use: "inspect [container]",
Short: "Get the detailed information of container",
Long: inspectDescription,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return p.runInpsect(args)
},
Example: inspectExample(),
}
}

// runInpsect is the entry of InspectCommand command.
func (p *InspectCommand) runInpsect(args []string) error {
apiClient := p.cli.Client()
name := args[0]
container, err := apiClient.ContainerGet(name)
if err != nil {
return err
}

containerjson, err := json.MarshalIndent(&container, "", " ")
if err != nil {
return err
}
fmt.Print(string(containerjson) + "\n")
return nil
}

// inspectExample shows examples in inspect command, and is used in auto-generated cli docs.
func inspectExample() string {
return `$ pouch inspect 08e
{
"Id": "08ee444faa3c6634ecdecea26de46e8a6a16efefd9afb72eb3457320b333fc60",
"Created": "2017-12-04 14:48:59",
"Path": "",
"Args": null,
"State": {
"StartedAt": "0001-01-01T00:00:00Z",
"Status": 0,
"FinishedAt": "0001-01-01T00:00:00Z",
"Pid": 25006,
"ExitCode": 0,
"Error": ""
},
"Image": "registry.docker-cn.com/library/centos:latest",
"ResolvConfPath": "",
"HostnamePath": "",
"HostsPath": "",
"LogPath": "",
"Name": "08ee44",
"RestartCount": 0,
"Driver": "",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": null,
"HostRootPath": ""
}`
}
1 change: 1 addition & 0 deletions cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func main() {
cli.AddCommand(base, &VersionCommand{})
cli.AddCommand(base, &ImageCommand{})
cli.AddCommand(base, &VolumeCommand{})
cli.AddCommand(base, &InspectCommand{})

// add generate doc command
cli.AddCommand(base, &GenDocCommand{})
Expand Down
14 changes: 14 additions & 0 deletions client/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,17 @@ func (client *APIClient) ContainerStartExec(execid string, config *types.ExecSta

return client.hijack("/exec/"+execid+"/start", url.Values{}, config, header)
}

// ContainerGet returns the detailed information of container.
func (client *APIClient) ContainerGet(name string) (*types.ContainerJSON, error) {
resp, err := client.get("/containers/"+name+"/json", nil)
if err != nil {
return nil, err
}

container := types.ContainerJSON{}
err = decodeBody(&container, resp.Body)
ensureCloseReader(resp)

return &container, err
}
14 changes: 13 additions & 1 deletion daemon/mgr/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type ContainerMgr interface {

// Remove removes a container, it may be running or stopped and so on.
Remove(ctx context.Context, name string, option *ContainerRemoveOption) error

// Get the detailed information of container
Get(s string) (*types.ContainerInfo, error)
}

// ContainerManager is the default implement of interface ContainerMgr.
Expand Down Expand Up @@ -285,7 +288,11 @@ func (cm *ContainerManager) Start(ctx context.Context, cfg types.ContainerStartC
if err == nil {
c.Status = types.RUNNING
c.StartedAt = time.Now()
//TODO get and set container pid
pid, err := cm.Client.ContainerPID(ctx, c.ID)
if err != nil {
return errors.Wrapf(err, "failed to get PID of container: %s", c.ID)
}
c.Pid = pid
} else {
c.FinishedAt = time.Now()
c.ErrorMsg = err.Error()
Expand Down Expand Up @@ -364,6 +371,11 @@ func (cm *ContainerManager) List(ctx context.Context) ([]*types.ContainerInfo, e
return cis, nil
}

// Get the detailed information of container
func (cm *ContainerManager) Get(s string) (*types.ContainerInfo, error) {
return cm.containerInfo(s)
}

// containerInfo returns the 'ContainerInfo' object, the parameter 's' may be container's
// name, id or prefix id.
func (cm *ContainerManager) containerInfo(s string) (*types.ContainerInfo, error) {
Expand Down

0 comments on commit 432a53d

Please sign in to comment.