add /proc to list running processes inside a container

This commit is contained in:
Victor Vieux 2013-06-28 15:51:58 +00:00
Родитель a11fc9f067
Коммит 2e79719622
5 изменённых файлов: 90 добавлений и 1 удалений

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"`

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 {