mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #3728 from vieux/container_job
Move containers to a job
This commit is contained in:
commit
e2003fea3a
8 changed files with 240 additions and 144 deletions
45
api.go
45
api.go
|
@ -291,32 +291,37 @@ func getContainersJSON(srv *Server, version float64, w http.ResponseWriter, r *h
|
|||
if err := parseForm(r); err != nil {
|
||||
return err
|
||||
}
|
||||
all, err := getBoolParam(r.Form.Get("all"))
|
||||
if err != nil {
|
||||
var (
|
||||
err error
|
||||
outs *engine.Table
|
||||
job = srv.Eng.Job("containers")
|
||||
)
|
||||
|
||||
job.Setenv("all", r.Form.Get("all"))
|
||||
job.Setenv("size", r.Form.Get("size"))
|
||||
job.Setenv("since", r.Form.Get("since"))
|
||||
job.Setenv("before", r.Form.Get("before"))
|
||||
job.Setenv("limit", r.Form.Get("limit"))
|
||||
|
||||
if version > 1.5 {
|
||||
job.Stdout.Add(w)
|
||||
} else if outs, err = job.Stdout.AddTable(); err != nil {
|
||||
return err
|
||||
}
|
||||
size, err := getBoolParam(r.Form.Get("size"))
|
||||
if err != nil {
|
||||
if err = job.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
since := r.Form.Get("since")
|
||||
before := r.Form.Get("before")
|
||||
n, err := strconv.Atoi(r.Form.Get("limit"))
|
||||
if err != nil {
|
||||
n = -1
|
||||
}
|
||||
|
||||
outs := srv.Containers(all, size, n, since, before)
|
||||
|
||||
if version < 1.5 {
|
||||
outs2 := []APIContainersOld{}
|
||||
for _, ctnr := range outs {
|
||||
outs2 = append(outs2, *ctnr.ToLegacy())
|
||||
if version < 1.5 { // Convert to legacy format
|
||||
for _, out := range outs.Data {
|
||||
ports := engine.NewTable("", 0)
|
||||
ports.ReadListFrom([]byte(out.Get("Ports")))
|
||||
out.Set("Ports", displayablePorts(ports))
|
||||
}
|
||||
if _, err = outs.WriteListTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeJSON(w, http.StatusOK, outs2)
|
||||
}
|
||||
return writeJSON(w, http.StatusOK, outs)
|
||||
return nil
|
||||
}
|
||||
|
||||
func postImagesTag(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
|
|
|
@ -11,29 +11,6 @@ type (
|
|||
Untagged string `json:",omitempty"`
|
||||
}
|
||||
|
||||
APIContainers struct {
|
||||
ID string `json:"Id"`
|
||||
Image string
|
||||
Command string
|
||||
Created int64
|
||||
Status string
|
||||
Ports []APIPort
|
||||
SizeRw int64
|
||||
SizeRootFs int64
|
||||
Names []string
|
||||
}
|
||||
|
||||
APIContainersOld struct {
|
||||
ID string `json:"Id"`
|
||||
Image string
|
||||
Command string
|
||||
Created int64
|
||||
Status string
|
||||
Ports string
|
||||
SizeRw int64
|
||||
SizeRootFs int64
|
||||
}
|
||||
|
||||
APIID struct {
|
||||
ID string `json:"Id"`
|
||||
}
|
||||
|
@ -68,16 +45,3 @@ type (
|
|||
HostPath string
|
||||
}
|
||||
)
|
||||
|
||||
func (api APIContainers) ToLegacy() *APIContainersOld {
|
||||
return &APIContainersOld{
|
||||
ID: api.ID,
|
||||
Image: api.Image,
|
||||
Command: api.Command,
|
||||
Created: api.Created,
|
||||
Status: api.Status,
|
||||
Ports: displayablePorts(api.Ports),
|
||||
SizeRw: api.SizeRw,
|
||||
SizeRootFs: api.SizeRootFs,
|
||||
}
|
||||
}
|
||||
|
|
45
commands.go
45
commands.go
|
@ -1310,13 +1310,13 @@ func (cli *DockerCli) printTreeNode(noTrunc bool, image *engine.Env, prefix stri
|
|||
}
|
||||
}
|
||||
|
||||
func displayablePorts(ports []APIPort) string {
|
||||
func displayablePorts(ports *engine.Table) string {
|
||||
result := []string{}
|
||||
for _, port := range ports {
|
||||
if port.IP == "" {
|
||||
result = append(result, fmt.Sprintf("%d/%s", port.PublicPort, port.Type))
|
||||
for _, port := range ports.Data {
|
||||
if port.Get("IP") == "" {
|
||||
result = append(result, fmt.Sprintf("%d/%s", port.GetInt("PublicPort"), port.Get("Type")))
|
||||
} else {
|
||||
result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
|
||||
result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.Get("IP"), port.GetInt("PublicPort"), port.GetInt("PrivatePort"), port.Get("Type")))
|
||||
}
|
||||
}
|
||||
sort.Strings(result)
|
||||
|
@ -1362,9 +1362,8 @@ func (cli *DockerCli) CmdPs(args ...string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var outs []APIContainers
|
||||
err = json.Unmarshal(body, &outs)
|
||||
if err != nil {
|
||||
outs := engine.NewTable("Created", 0)
|
||||
if _, err := outs.ReadListFrom(body); err != nil {
|
||||
return err
|
||||
}
|
||||
w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
|
||||
|
@ -1377,32 +1376,42 @@ func (cli *DockerCli) CmdPs(args ...string) error {
|
|||
}
|
||||
}
|
||||
|
||||
for _, out := range outs {
|
||||
for _, out := range outs.Data {
|
||||
var (
|
||||
outID = out.Get("ID")
|
||||
outNames = out.GetList("Names")
|
||||
)
|
||||
|
||||
if !*noTrunc {
|
||||
out.ID = utils.TruncateID(out.ID)
|
||||
outID = utils.TruncateID(outID)
|
||||
}
|
||||
|
||||
// Remove the leading / from the names
|
||||
for i := 0; i < len(out.Names); i++ {
|
||||
out.Names[i] = out.Names[i][1:]
|
||||
for i := 0; i < len(outNames); i++ {
|
||||
outNames[i] = outNames[i][1:]
|
||||
}
|
||||
|
||||
if !*quiet {
|
||||
var (
|
||||
outCommand = out.Get("Command")
|
||||
ports = engine.NewTable("", 0)
|
||||
)
|
||||
if !*noTrunc {
|
||||
out.Command = utils.Trunc(out.Command, 20)
|
||||
outCommand = utils.Trunc(outCommand, 20)
|
||||
}
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", out.ID, out.Image, out.Command, utils.HumanDuration(time.Now().UTC().Sub(time.Unix(out.Created, 0))), out.Status, displayablePorts(out.Ports), strings.Join(out.Names, ","))
|
||||
ports.ReadListFrom([]byte(out.Get("Ports")))
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", outID, out.Get("Image"), outCommand, utils.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), out.Get("Status"), displayablePorts(ports), strings.Join(outNames, ","))
|
||||
if *size {
|
||||
if out.SizeRootFs > 0 {
|
||||
fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.SizeRw), utils.HumanSize(out.SizeRootFs))
|
||||
if out.GetInt("SizeRootFs") > 0 {
|
||||
fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.GetInt64("SizeRw")), utils.HumanSize(out.GetInt64("SizeRootFs")))
|
||||
} else {
|
||||
fmt.Fprintf(w, "%s\n", utils.HumanSize(out.SizeRw))
|
||||
fmt.Fprintf(w, "%s\n", utils.HumanSize(out.GetInt64("SizeRw")))
|
||||
}
|
||||
} else {
|
||||
fmt.Fprint(w, "\n")
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintln(w, out.ID)
|
||||
fmt.Fprintln(w, outID)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
28
container.go
28
container.go
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"github.com/dotcloud/docker/archive"
|
||||
"github.com/dotcloud/docker/engine"
|
||||
"github.com/dotcloud/docker/execdriver"
|
||||
"github.com/dotcloud/docker/graphdriver"
|
||||
"github.com/dotcloud/docker/networkdriver/ipallocator"
|
||||
|
@ -175,29 +176,28 @@ type NetworkSettings struct {
|
|||
Ports map[Port][]PortBinding
|
||||
}
|
||||
|
||||
func (settings *NetworkSettings) PortMappingAPI() []APIPort {
|
||||
var mapping []APIPort
|
||||
func (settings *NetworkSettings) PortMappingAPI() *engine.Table {
|
||||
var outs = engine.NewTable("", 0)
|
||||
for port, bindings := range settings.Ports {
|
||||
p, _ := parsePort(port.Port())
|
||||
if len(bindings) == 0 {
|
||||
mapping = append(mapping, APIPort{
|
||||
PublicPort: int64(p),
|
||||
Type: port.Proto(),
|
||||
})
|
||||
out := &engine.Env{}
|
||||
out.SetInt("PublicPort", p)
|
||||
out.Set("Type", port.Proto())
|
||||
outs.Add(out)
|
||||
continue
|
||||
}
|
||||
for _, binding := range bindings {
|
||||
p, _ := parsePort(port.Port())
|
||||
out := &engine.Env{}
|
||||
h, _ := parsePort(binding.HostPort)
|
||||
mapping = append(mapping, APIPort{
|
||||
PrivatePort: int64(p),
|
||||
PublicPort: int64(h),
|
||||
Type: port.Proto(),
|
||||
IP: binding.HostIp,
|
||||
})
|
||||
out.SetInt("PrivatePort", p)
|
||||
out.SetInt("PublicPort", h)
|
||||
out.Set("Type", port.Proto())
|
||||
out.Set("IP", binding.HostIp)
|
||||
outs.Add(out)
|
||||
}
|
||||
}
|
||||
return mapping
|
||||
return outs
|
||||
}
|
||||
|
||||
// Inject the io.Reader at the given path. Note: do not close the reader
|
||||
|
|
|
@ -313,6 +313,14 @@ func (t *Table) WriteListTo(dst io.Writer) (n int64, err error) {
|
|||
return n + 1, nil
|
||||
}
|
||||
|
||||
func (t *Table) ToListString() (string, error) {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if _, err := t.WriteListTo(buffer); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buffer.String(), nil
|
||||
}
|
||||
|
||||
func (t *Table) WriteTo(dst io.Writer) (n int64, err error) {
|
||||
for _, env := range t.Data {
|
||||
bytes, err := env.WriteTo(dst)
|
||||
|
|
|
@ -302,7 +302,16 @@ func TestGetContainersJSON(t *testing.T) {
|
|||
defer mkRuntimeFromEngine(eng, t).Nuke()
|
||||
srv := mkServerFromEngine(eng, t)
|
||||
|
||||
beginLen := len(srv.Containers(true, false, -1, "", ""))
|
||||
job := eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err := job.Stdout.AddTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
beginLen := len(outs.Data)
|
||||
|
||||
containerID := createTestContainer(eng, &docker.Config{
|
||||
Image: unitTestImageID,
|
||||
|
@ -323,15 +332,15 @@ func TestGetContainersJSON(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
assertHttpNotError(r, t)
|
||||
containers := []docker.APIContainers{}
|
||||
if err := json.Unmarshal(r.Body.Bytes(), &containers); err != nil {
|
||||
containers := engine.NewTable("", 0)
|
||||
if _, err := containers.ReadListFrom(r.Body.Bytes()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(containers) != beginLen+1 {
|
||||
t.Fatalf("Expected %d container, %d found (started with: %d)", beginLen+1, len(containers), beginLen)
|
||||
if len(containers.Data) != beginLen+1 {
|
||||
t.Fatalf("Expected %d container, %d found (started with: %d)", beginLen+1, len(containers.Data), beginLen)
|
||||
}
|
||||
if containers[0].ID != containerID {
|
||||
t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", containerID, containers[0].ID)
|
||||
if id := containers.Data[0].Get("ID"); id != containerID {
|
||||
t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", containerID, id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,6 @@ func TestImageTagImageDelete(t *testing.T) {
|
|||
|
||||
func TestCreateRm(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
srv := mkServerFromEngine(eng, t)
|
||||
defer mkRuntimeFromEngine(eng, t).Nuke()
|
||||
|
||||
config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
|
||||
|
@ -79,25 +78,44 @@ func TestCreateRm(t *testing.T) {
|
|||
|
||||
id := createTestContainer(eng, config, t)
|
||||
|
||||
if c := srv.Containers(true, false, -1, "", ""); len(c) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(c))
|
||||
job := eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err := job.Stdout.AddListTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
job := eng.Job("container_delete", id)
|
||||
if len(outs.Data) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
||||
}
|
||||
|
||||
job = eng.Job("container_delete", id)
|
||||
job.SetenvBool("removeVolume", true)
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if c := srv.Containers(true, false, -1, "", ""); len(c) != 0 {
|
||||
t.Errorf("Expected 0 container, %v found", len(c))
|
||||
job = eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err = job.Stdout.AddListTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(outs.Data) != 0 {
|
||||
t.Errorf("Expected 0 container, %v found", len(outs.Data))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCreateRmVolumes(t *testing.T) {
|
||||
eng := NewTestEngine(t)
|
||||
srv := mkServerFromEngine(eng, t)
|
||||
defer mkRuntimeFromEngine(eng, t).Nuke()
|
||||
|
||||
config, hostConfig, _, err := docker.ParseRun([]string{"-v", "/srv", unitTestImageID, "echo", "test"}, nil)
|
||||
|
@ -107,11 +125,21 @@ func TestCreateRmVolumes(t *testing.T) {
|
|||
|
||||
id := createTestContainer(eng, config, t)
|
||||
|
||||
if c := srv.Containers(true, false, -1, "", ""); len(c) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(c))
|
||||
job := eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err := job.Stdout.AddListTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
job := eng.Job("start", id)
|
||||
if len(outs.Data) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
||||
}
|
||||
|
||||
job = eng.Job("start", id)
|
||||
if err := job.ImportEnv(hostConfig); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -131,8 +159,18 @@ func TestCreateRmVolumes(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if c := srv.Containers(true, false, -1, "", ""); len(c) != 0 {
|
||||
t.Errorf("Expected 0 container, %v found", len(c))
|
||||
job = eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err = job.Stdout.AddListTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(outs.Data) != 0 {
|
||||
t.Errorf("Expected 0 container, %v found", len(outs.Data))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,11 +207,21 @@ func TestRestartKillWait(t *testing.T) {
|
|||
|
||||
id := createTestContainer(eng, config, t)
|
||||
|
||||
if c := srv.Containers(true, false, -1, "", ""); len(c) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(c))
|
||||
job := eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err := job.Stdout.AddListTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
job := eng.Job("start", id)
|
||||
if len(outs.Data) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
||||
}
|
||||
|
||||
job = eng.Job("start", id)
|
||||
if err := job.ImportEnv(hostConfig); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -200,13 +248,23 @@ func TestRestartKillWait(t *testing.T) {
|
|||
}
|
||||
|
||||
srv = mkServerFromEngine(eng, t)
|
||||
c := srv.Containers(true, false, -1, "", "")
|
||||
if len(c) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(c))
|
||||
|
||||
job = srv.Eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err = job.Stdout.AddListTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(outs.Data) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
||||
}
|
||||
|
||||
setTimeout(t, "Waiting on stopped container timedout", 5*time.Second, func() {
|
||||
job = srv.Eng.Job("wait", c[0].ID)
|
||||
job = srv.Eng.Job("wait", outs.Data[0].Get("ID"))
|
||||
var statusStr string
|
||||
job.Stdout.AddString(&statusStr)
|
||||
if err := job.Run(); err != nil {
|
||||
|
@ -227,11 +285,21 @@ func TestCreateStartRestartStopStartKillRm(t *testing.T) {
|
|||
|
||||
id := createTestContainer(eng, config, t)
|
||||
|
||||
if c := srv.Containers(true, false, -1, "", ""); len(c) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(c))
|
||||
job := srv.Eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err := job.Stdout.AddListTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
job := eng.Job("start", id)
|
||||
if len(outs.Data) != 1 {
|
||||
t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
||||
}
|
||||
|
||||
job = eng.Job("start", id)
|
||||
if err := job.ImportEnv(hostConfig); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -270,8 +338,18 @@ func TestCreateStartRestartStopStartKillRm(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if c := srv.Containers(true, false, -1, "", ""); len(c) != 0 {
|
||||
t.Errorf("Expected 0 container, %v found", len(c))
|
||||
job = srv.Eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err = job.Stdout.AddListTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(outs.Data) != 0 {
|
||||
t.Errorf("Expected 0 container, %v found", len(outs.Data))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -465,10 +543,18 @@ func TestDeleteTagWithExistingContainers(t *testing.T) {
|
|||
t.Fatal("No id returned")
|
||||
}
|
||||
|
||||
containers := srv.Containers(true, false, -1, "", "")
|
||||
job := srv.Eng.Job("containers")
|
||||
job.SetenvBool("all", true)
|
||||
outs, err := job.Stdout.AddListTable()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(containers) != 1 {
|
||||
t.Fatalf("Expected 1 container got %d", len(containers))
|
||||
if len(outs.Data) != 1 {
|
||||
t.Fatalf("Expected 1 container got %d", len(outs.Data))
|
||||
}
|
||||
|
||||
// Try to remove the tag
|
||||
|
|
59
server.go
59
server.go
|
@ -103,6 +103,7 @@ func jobInitApi(job *engine.Job) engine.Status {
|
|||
"inspect": srv.JobInspect,
|
||||
"events": srv.Events,
|
||||
"push": srv.ImagePush,
|
||||
"containers": srv.Containers,
|
||||
} {
|
||||
if err := job.Eng.Register(name, handler); err != nil {
|
||||
job.Error(err)
|
||||
|
@ -1055,10 +1056,17 @@ func (srv *Server) ContainerChanges(job *engine.Job) engine.Status {
|
|||
return engine.StatusOK
|
||||
}
|
||||
|
||||
func (srv *Server) Containers(all, size bool, n int, since, before string) []APIContainers {
|
||||
var foundBefore bool
|
||||
var displayed int
|
||||
out := []APIContainers{}
|
||||
func (srv *Server) Containers(job *engine.Job) engine.Status {
|
||||
var (
|
||||
foundBefore bool
|
||||
displayed int
|
||||
all = job.GetenvBool("all")
|
||||
since = job.Getenv("since")
|
||||
before = job.Getenv("before")
|
||||
n = job.GetenvInt("limit")
|
||||
size = job.GetenvBool("size")
|
||||
)
|
||||
outs := engine.NewTable("Created", 0)
|
||||
|
||||
names := map[string][]string{}
|
||||
srv.runtime.containerGraph.Walk("/", func(p string, e *graphdb.Entity) error {
|
||||
|
@ -1083,27 +1091,34 @@ func (srv *Server) Containers(all, size bool, n int, since, before string) []API
|
|||
break
|
||||
}
|
||||
displayed++
|
||||
c := createAPIContainer(names[container.ID], container, size, srv.runtime)
|
||||
out = append(out, c)
|
||||
out := &engine.Env{}
|
||||
out.Set("ID", container.ID)
|
||||
out.SetList("Names", names[container.ID])
|
||||
out.Set("Image", srv.runtime.repositories.ImageName(container.Image))
|
||||
out.Set("Command", fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " ")))
|
||||
out.SetInt64("Created", container.Created.Unix())
|
||||
out.Set("Status", container.State.String())
|
||||
str, err := container.NetworkSettings.PortMappingAPI().ToListString()
|
||||
if err != nil {
|
||||
job.Error(err)
|
||||
return engine.StatusErr
|
||||
}
|
||||
out.Set("Ports", str)
|
||||
if size {
|
||||
sizeRw, sizeRootFs := container.GetSize()
|
||||
out.SetInt64("SizeRw", sizeRw)
|
||||
out.SetInt64("SizeRootFs", sizeRootFs)
|
||||
}
|
||||
outs.Add(out)
|
||||
}
|
||||
return out
|
||||
outs.ReverseSort()
|
||||
if _, err := outs.WriteListTo(job.Stdout); err != nil {
|
||||
job.Error(err)
|
||||
return engine.StatusErr
|
||||
}
|
||||
return engine.StatusOK
|
||||
}
|
||||
|
||||
func createAPIContainer(names []string, container *Container, size bool, runtime *Runtime) APIContainers {
|
||||
c := APIContainers{
|
||||
ID: container.ID,
|
||||
}
|
||||
c.Names = names
|
||||
c.Image = runtime.repositories.ImageName(container.Image)
|
||||
c.Command = fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
|
||||
c.Created = container.Created.Unix()
|
||||
c.Status = container.State.String()
|
||||
c.Ports = container.NetworkSettings.PortMappingAPI()
|
||||
if size {
|
||||
c.SizeRw, c.SizeRootFs = container.GetSize()
|
||||
}
|
||||
return c
|
||||
}
|
||||
func (srv *Server) ContainerCommit(job *engine.Job) engine.Status {
|
||||
if len(job.Args) != 1 {
|
||||
job.Errorf("Not enough arguments. Usage: %s CONTAINER\n", job.Name)
|
||||
|
|
Loading…
Reference in a new issue