mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
add /proc to list running processes inside a container
This commit is contained in:
parent
a11fc9f067
commit
2e79719622
5 changed files with 90 additions and 1 deletions
18
api.go
18
api.go
|
@ -250,6 +250,23 @@ func getContainersChanges(srv *Server, version float64, w http.ResponseWriter, r
|
|||
return nil
|
||||
}
|
||||
|
||||
func getContainersProc(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
if vars == nil {
|
||||
return fmt.Errorf("Missing parameter")
|
||||
}
|
||||
name := vars["name"]
|
||||
procsStr, err := srv.ContainerProc(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b, err := json.Marshal(procsStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writeJSON(w, b)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getContainersJSON(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
if err := parseForm(r); err != nil {
|
||||
return err
|
||||
|
@ -842,6 +859,7 @@ func createRouter(srv *Server, logging bool) (*mux.Router, error) {
|
|||
"/containers/{name:.*}/export": getContainersExport,
|
||||
"/containers/{name:.*}/changes": getContainersChanges,
|
||||
"/containers/{name:.*}/json": getContainersByName,
|
||||
"/containers/{name:.*}/proc": getContainersProc,
|
||||
},
|
||||
"POST": {
|
||||
"/auth": postAuth,
|
||||
|
|
|
@ -26,6 +26,13 @@ type APIInfo struct {
|
|||
SwapLimit bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
type APIProc struct {
|
||||
PID string
|
||||
Tty string
|
||||
Time string
|
||||
Cmd string
|
||||
}
|
||||
|
||||
type APIRmi struct {
|
||||
Deleted string `json:",omitempty"`
|
||||
Untagged string `json:",omitempty"`
|
||||
|
|
28
commands.go
28
commands.go
|
@ -90,6 +90,7 @@ func (cli *DockerCli) CmdHelp(args ...string) error {
|
|||
{"login", "Register or Login to the docker registry server"},
|
||||
{"logs", "Fetch the logs of a container"},
|
||||
{"port", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT"},
|
||||
{"proc", "Lookup the running processes of a container"},
|
||||
{"ps", "List containers"},
|
||||
{"pull", "Pull an image or a repository from the docker registry server"},
|
||||
{"push", "Push an image or a repository to the docker registry server"},
|
||||
|
@ -555,6 +556,33 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cli *DockerCli) CmdProc(args ...string) error {
|
||||
cmd := Subcmd("proc", "CONTAINER", "Lookup the running processes of a container")
|
||||
if err := cmd.Parse(args); err != nil {
|
||||
return nil
|
||||
}
|
||||
if cmd.NArg() != 1 {
|
||||
cmd.Usage()
|
||||
return nil
|
||||
}
|
||||
body, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/proc", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var procs []APIProc
|
||||
err = json.Unmarshal(body, &procs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
|
||||
fmt.Fprintln(w, "PID\tTTY\tTIME\tCMD")
|
||||
for _, proc := range procs {
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", proc.PID, proc.Tty, proc.Time, proc.Cmd)
|
||||
}
|
||||
w.Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *DockerCli) CmdPort(args ...string) error {
|
||||
cmd := Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port which is NAT-ed to PRIVATE_PORT")
|
||||
if err := cmd.Parse(args); err != nil {
|
||||
|
|
36
server.go
36
server.go
|
@ -1,6 +1,7 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/dotcloud/docker/auth"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
@ -247,6 +249,40 @@ func (srv *Server) ImageHistory(name string) ([]APIHistory, error) {
|
|||
|
||||
}
|
||||
|
||||
func (srv *Server) ContainerProc(name string) ([]APIProc, error) {
|
||||
if container := srv.runtime.Get(name); container != nil {
|
||||
output, err := exec.Command("lxc-ps", "--name", container.ID).CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error trying to use lxc-ps: %s (%s)", err, output)
|
||||
}
|
||||
var procs []APIProc
|
||||
for i, line := range strings.Split(string(output), "\n") {
|
||||
if i == 0 || len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
proc := APIProc{}
|
||||
scanner := bufio.NewScanner(strings.NewReader(line))
|
||||
scanner.Split(bufio.ScanWords)
|
||||
if !scanner.Scan() {
|
||||
return nil, fmt.Errorf("Error trying to use lxc-ps")
|
||||
}
|
||||
// no scanner.Text because we skip container id
|
||||
scanner.Scan()
|
||||
proc.PID = scanner.Text()
|
||||
scanner.Scan()
|
||||
proc.Tty = scanner.Text()
|
||||
scanner.Scan()
|
||||
proc.Time = scanner.Text()
|
||||
scanner.Scan()
|
||||
proc.Cmd = scanner.Text()
|
||||
procs = append(procs, proc)
|
||||
}
|
||||
return procs, nil
|
||||
|
||||
}
|
||||
return nil, fmt.Errorf("No such container: %s", name)
|
||||
}
|
||||
|
||||
func (srv *Server) ContainerChanges(name string) ([]Change, error) {
|
||||
if container := srv.runtime.Get(name); container != nil {
|
||||
return container.Changes()
|
||||
|
|
|
@ -78,7 +78,7 @@ func (r *progressReader) Read(p []byte) (n int, err error) {
|
|||
read, err := io.ReadCloser(r.reader).Read(p)
|
||||
r.readProgress += read
|
||||
|
||||
updateEvery := 1024*512 //512kB
|
||||
updateEvery := 1024 * 512 //512kB
|
||||
if r.readTotal > 0 {
|
||||
// Update progress for every 1% read if 1% < 512kB
|
||||
if increment := int(0.01 * float64(r.readTotal)); increment < updateEvery {
|
||||
|
|
Loading…
Reference in a new issue