Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
| ... | ... |
@@ -291,32 +291,37 @@ func getContainersJSON(srv *Server, version float64, w http.ResponseWriter, r *h |
| 291 | 291 |
if err := parseForm(r); err != nil {
|
| 292 | 292 |
return err |
| 293 | 293 |
} |
| 294 |
- all, err := getBoolParam(r.Form.Get("all"))
|
|
| 295 |
- if err != nil {
|
|
| 294 |
+ var ( |
|
| 295 |
+ err error |
|
| 296 |
+ outs *engine.Table |
|
| 297 |
+ job = srv.Eng.Job("containers")
|
|
| 298 |
+ ) |
|
| 299 |
+ |
|
| 300 |
+ job.Setenv("all", r.Form.Get("all"))
|
|
| 301 |
+ job.Setenv("size", r.Form.Get("size"))
|
|
| 302 |
+ job.Setenv("since", r.Form.Get("since"))
|
|
| 303 |
+ job.Setenv("before", r.Form.Get("before"))
|
|
| 304 |
+ job.Setenv("limit", r.Form.Get("limit"))
|
|
| 305 |
+ |
|
| 306 |
+ if version > 1.5 {
|
|
| 307 |
+ job.Stdout.Add(w) |
|
| 308 |
+ } else if outs, err = job.Stdout.AddTable(); err != nil {
|
|
| 296 | 309 |
return err |
| 297 | 310 |
} |
| 298 |
- size, err := getBoolParam(r.Form.Get("size"))
|
|
| 299 |
- if err != nil {
|
|
| 311 |
+ if err = job.Run(); err != nil {
|
|
| 300 | 312 |
return err |
| 301 | 313 |
} |
| 302 |
- since := r.Form.Get("since")
|
|
| 303 |
- before := r.Form.Get("before")
|
|
| 304 |
- n, err := strconv.Atoi(r.Form.Get("limit"))
|
|
| 305 |
- if err != nil {
|
|
| 306 |
- n = -1 |
|
| 307 |
- } |
|
| 308 |
- |
|
| 309 |
- outs := srv.Containers(all, size, n, since, before) |
|
| 310 |
- |
|
| 311 |
- if version < 1.5 {
|
|
| 312 |
- outs2 := []APIContainersOld{}
|
|
| 313 |
- for _, ctnr := range outs {
|
|
| 314 |
- outs2 = append(outs2, *ctnr.ToLegacy()) |
|
| 314 |
+ if version < 1.5 { // Convert to legacy format
|
|
| 315 |
+ for _, out := range outs.Data {
|
|
| 316 |
+ ports := engine.NewTable("", 0)
|
|
| 317 |
+ ports.ReadListFrom([]byte(out.Get("Ports")))
|
|
| 318 |
+ out.Set("Ports", displayablePorts(ports))
|
|
| 319 |
+ } |
|
| 320 |
+ if _, err = outs.WriteListTo(w); err != nil {
|
|
| 321 |
+ return err |
|
| 315 | 322 |
} |
| 316 |
- |
|
| 317 |
- return writeJSON(w, http.StatusOK, outs2) |
|
| 318 | 323 |
} |
| 319 |
- return writeJSON(w, http.StatusOK, outs) |
|
| 324 |
+ return nil |
|
| 320 | 325 |
} |
| 321 | 326 |
|
| 322 | 327 |
func postImagesTag(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| ... | ... |
@@ -11,29 +11,6 @@ type ( |
| 11 | 11 |
Untagged string `json:",omitempty"` |
| 12 | 12 |
} |
| 13 | 13 |
|
| 14 |
- APIContainers struct {
|
|
| 15 |
- ID string `json:"Id"` |
|
| 16 |
- Image string |
|
| 17 |
- Command string |
|
| 18 |
- Created int64 |
|
| 19 |
- Status string |
|
| 20 |
- Ports []APIPort |
|
| 21 |
- SizeRw int64 |
|
| 22 |
- SizeRootFs int64 |
|
| 23 |
- Names []string |
|
| 24 |
- } |
|
| 25 |
- |
|
| 26 |
- APIContainersOld struct {
|
|
| 27 |
- ID string `json:"Id"` |
|
| 28 |
- Image string |
|
| 29 |
- Command string |
|
| 30 |
- Created int64 |
|
| 31 |
- Status string |
|
| 32 |
- Ports string |
|
| 33 |
- SizeRw int64 |
|
| 34 |
- SizeRootFs int64 |
|
| 35 |
- } |
|
| 36 |
- |
|
| 37 | 14 |
APIID struct {
|
| 38 | 15 |
ID string `json:"Id"` |
| 39 | 16 |
} |
| ... | ... |
@@ -68,16 +45,3 @@ type ( |
| 68 | 68 |
HostPath string |
| 69 | 69 |
} |
| 70 | 70 |
) |
| 71 |
- |
|
| 72 |
-func (api APIContainers) ToLegacy() *APIContainersOld {
|
|
| 73 |
- return &APIContainersOld{
|
|
| 74 |
- ID: api.ID, |
|
| 75 |
- Image: api.Image, |
|
| 76 |
- Command: api.Command, |
|
| 77 |
- Created: api.Created, |
|
| 78 |
- Status: api.Status, |
|
| 79 |
- Ports: displayablePorts(api.Ports), |
|
| 80 |
- SizeRw: api.SizeRw, |
|
| 81 |
- SizeRootFs: api.SizeRootFs, |
|
| 82 |
- } |
|
| 83 |
-} |
| ... | ... |
@@ -1310,13 +1310,13 @@ func (cli *DockerCli) printTreeNode(noTrunc bool, image *engine.Env, prefix stri |
| 1310 | 1310 |
} |
| 1311 | 1311 |
} |
| 1312 | 1312 |
|
| 1313 |
-func displayablePorts(ports []APIPort) string {
|
|
| 1313 |
+func displayablePorts(ports *engine.Table) string {
|
|
| 1314 | 1314 |
result := []string{}
|
| 1315 |
- for _, port := range ports {
|
|
| 1316 |
- if port.IP == "" {
|
|
| 1317 |
- result = append(result, fmt.Sprintf("%d/%s", port.PublicPort, port.Type))
|
|
| 1315 |
+ for _, port := range ports.Data {
|
|
| 1316 |
+ if port.Get("IP") == "" {
|
|
| 1317 |
+ result = append(result, fmt.Sprintf("%d/%s", port.GetInt("PublicPort"), port.Get("Type")))
|
|
| 1318 | 1318 |
} else {
|
| 1319 |
- result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
|
|
| 1319 |
+ result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.Get("IP"), port.GetInt("PublicPort"), port.GetInt("PrivatePort"), port.Get("Type")))
|
|
| 1320 | 1320 |
} |
| 1321 | 1321 |
} |
| 1322 | 1322 |
sort.Strings(result) |
| ... | ... |
@@ -1362,9 +1362,8 @@ func (cli *DockerCli) CmdPs(args ...string) error {
|
| 1362 | 1362 |
return err |
| 1363 | 1363 |
} |
| 1364 | 1364 |
|
| 1365 |
- var outs []APIContainers |
|
| 1366 |
- err = json.Unmarshal(body, &outs) |
|
| 1367 |
- if err != nil {
|
|
| 1365 |
+ outs := engine.NewTable("Created", 0)
|
|
| 1366 |
+ if _, err := outs.ReadListFrom(body); err != nil {
|
|
| 1368 | 1367 |
return err |
| 1369 | 1368 |
} |
| 1370 | 1369 |
w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) |
| ... | ... |
@@ -1377,32 +1376,42 @@ func (cli *DockerCli) CmdPs(args ...string) error {
|
| 1377 | 1377 |
} |
| 1378 | 1378 |
} |
| 1379 | 1379 |
|
| 1380 |
- for _, out := range outs {
|
|
| 1380 |
+ for _, out := range outs.Data {
|
|
| 1381 |
+ var ( |
|
| 1382 |
+ outID = out.Get("ID")
|
|
| 1383 |
+ outNames = out.GetList("Names")
|
|
| 1384 |
+ ) |
|
| 1385 |
+ |
|
| 1381 | 1386 |
if !*noTrunc {
|
| 1382 |
- out.ID = utils.TruncateID(out.ID) |
|
| 1387 |
+ outID = utils.TruncateID(outID) |
|
| 1383 | 1388 |
} |
| 1384 | 1389 |
|
| 1385 | 1390 |
// Remove the leading / from the names |
| 1386 |
- for i := 0; i < len(out.Names); i++ {
|
|
| 1387 |
- out.Names[i] = out.Names[i][1:] |
|
| 1391 |
+ for i := 0; i < len(outNames); i++ {
|
|
| 1392 |
+ outNames[i] = outNames[i][1:] |
|
| 1388 | 1393 |
} |
| 1389 | 1394 |
|
| 1390 | 1395 |
if !*quiet {
|
| 1396 |
+ var ( |
|
| 1397 |
+ outCommand = out.Get("Command")
|
|
| 1398 |
+ ports = engine.NewTable("", 0)
|
|
| 1399 |
+ ) |
|
| 1391 | 1400 |
if !*noTrunc {
|
| 1392 |
- out.Command = utils.Trunc(out.Command, 20) |
|
| 1401 |
+ outCommand = utils.Trunc(outCommand, 20) |
|
| 1393 | 1402 |
} |
| 1394 |
- 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, ",")) |
|
| 1403 |
+ ports.ReadListFrom([]byte(out.Get("Ports")))
|
|
| 1404 |
+ 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, ","))
|
|
| 1395 | 1405 |
if *size {
|
| 1396 |
- if out.SizeRootFs > 0 {
|
|
| 1397 |
- fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.SizeRw), utils.HumanSize(out.SizeRootFs)) |
|
| 1406 |
+ if out.GetInt("SizeRootFs") > 0 {
|
|
| 1407 |
+ fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.GetInt64("SizeRw")), utils.HumanSize(out.GetInt64("SizeRootFs")))
|
|
| 1398 | 1408 |
} else {
|
| 1399 |
- fmt.Fprintf(w, "%s\n", utils.HumanSize(out.SizeRw)) |
|
| 1409 |
+ fmt.Fprintf(w, "%s\n", utils.HumanSize(out.GetInt64("SizeRw")))
|
|
| 1400 | 1410 |
} |
| 1401 | 1411 |
} else {
|
| 1402 | 1412 |
fmt.Fprint(w, "\n") |
| 1403 | 1413 |
} |
| 1404 | 1414 |
} else {
|
| 1405 |
- fmt.Fprintln(w, out.ID) |
|
| 1415 |
+ fmt.Fprintln(w, outID) |
|
| 1406 | 1416 |
} |
| 1407 | 1417 |
} |
| 1408 | 1418 |
|
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"errors" |
| 6 | 6 |
"fmt" |
| 7 | 7 |
"github.com/dotcloud/docker/archive" |
| 8 |
+ "github.com/dotcloud/docker/engine" |
|
| 8 | 9 |
"github.com/dotcloud/docker/execdriver" |
| 9 | 10 |
"github.com/dotcloud/docker/graphdriver" |
| 10 | 11 |
"github.com/dotcloud/docker/networkdriver/ipallocator" |
| ... | ... |
@@ -175,29 +176,28 @@ type NetworkSettings struct {
|
| 175 | 175 |
Ports map[Port][]PortBinding |
| 176 | 176 |
} |
| 177 | 177 |
|
| 178 |
-func (settings *NetworkSettings) PortMappingAPI() []APIPort {
|
|
| 179 |
- var mapping []APIPort |
|
| 178 |
+func (settings *NetworkSettings) PortMappingAPI() *engine.Table {
|
|
| 179 |
+ var outs = engine.NewTable("", 0)
|
|
| 180 | 180 |
for port, bindings := range settings.Ports {
|
| 181 | 181 |
p, _ := parsePort(port.Port()) |
| 182 | 182 |
if len(bindings) == 0 {
|
| 183 |
- mapping = append(mapping, APIPort{
|
|
| 184 |
- PublicPort: int64(p), |
|
| 185 |
- Type: port.Proto(), |
|
| 186 |
- }) |
|
| 183 |
+ out := &engine.Env{}
|
|
| 184 |
+ out.SetInt("PublicPort", p)
|
|
| 185 |
+ out.Set("Type", port.Proto())
|
|
| 186 |
+ outs.Add(out) |
|
| 187 | 187 |
continue |
| 188 | 188 |
} |
| 189 | 189 |
for _, binding := range bindings {
|
| 190 |
- p, _ := parsePort(port.Port()) |
|
| 190 |
+ out := &engine.Env{}
|
|
| 191 | 191 |
h, _ := parsePort(binding.HostPort) |
| 192 |
- mapping = append(mapping, APIPort{
|
|
| 193 |
- PrivatePort: int64(p), |
|
| 194 |
- PublicPort: int64(h), |
|
| 195 |
- Type: port.Proto(), |
|
| 196 |
- IP: binding.HostIp, |
|
| 197 |
- }) |
|
| 192 |
+ out.SetInt("PrivatePort", p)
|
|
| 193 |
+ out.SetInt("PublicPort", h)
|
|
| 194 |
+ out.Set("Type", port.Proto())
|
|
| 195 |
+ out.Set("IP", binding.HostIp)
|
|
| 196 |
+ outs.Add(out) |
|
| 198 | 197 |
} |
| 199 | 198 |
} |
| 200 |
- return mapping |
|
| 199 |
+ return outs |
|
| 201 | 200 |
} |
| 202 | 201 |
|
| 203 | 202 |
// 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) {
|
| 313 | 313 |
return n + 1, nil |
| 314 | 314 |
} |
| 315 | 315 |
|
| 316 |
+func (t *Table) ToListString() (string, error) {
|
|
| 317 |
+ buffer := bytes.NewBuffer(nil) |
|
| 318 |
+ if _, err := t.WriteListTo(buffer); err != nil {
|
|
| 319 |
+ return "", err |
|
| 320 |
+ } |
|
| 321 |
+ return buffer.String(), nil |
|
| 322 |
+} |
|
| 323 |
+ |
|
| 316 | 324 |
func (t *Table) WriteTo(dst io.Writer) (n int64, err error) {
|
| 317 | 325 |
for _, env := range t.Data {
|
| 318 | 326 |
bytes, err := env.WriteTo(dst) |
| ... | ... |
@@ -302,7 +302,16 @@ func TestGetContainersJSON(t *testing.T) {
|
| 302 | 302 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 303 | 303 |
srv := mkServerFromEngine(eng, t) |
| 304 | 304 |
|
| 305 |
- beginLen := len(srv.Containers(true, false, -1, "", "")) |
|
| 305 |
+ job := eng.Job("containers")
|
|
| 306 |
+ job.SetenvBool("all", true)
|
|
| 307 |
+ outs, err := job.Stdout.AddTable() |
|
| 308 |
+ if err != nil {
|
|
| 309 |
+ t.Fatal(err) |
|
| 310 |
+ } |
|
| 311 |
+ if err := job.Run(); err != nil {
|
|
| 312 |
+ t.Fatal(err) |
|
| 313 |
+ } |
|
| 314 |
+ beginLen := len(outs.Data) |
|
| 306 | 315 |
|
| 307 | 316 |
containerID := createTestContainer(eng, &docker.Config{
|
| 308 | 317 |
Image: unitTestImageID, |
| ... | ... |
@@ -323,15 +332,15 @@ func TestGetContainersJSON(t *testing.T) {
|
| 323 | 323 |
t.Fatal(err) |
| 324 | 324 |
} |
| 325 | 325 |
assertHttpNotError(r, t) |
| 326 |
- containers := []docker.APIContainers{}
|
|
| 327 |
- if err := json.Unmarshal(r.Body.Bytes(), &containers); err != nil {
|
|
| 326 |
+ containers := engine.NewTable("", 0)
|
|
| 327 |
+ if _, err := containers.ReadListFrom(r.Body.Bytes()); err != nil {
|
|
| 328 | 328 |
t.Fatal(err) |
| 329 | 329 |
} |
| 330 |
- if len(containers) != beginLen+1 {
|
|
| 331 |
- t.Fatalf("Expected %d container, %d found (started with: %d)", beginLen+1, len(containers), beginLen)
|
|
| 330 |
+ if len(containers.Data) != beginLen+1 {
|
|
| 331 |
+ t.Fatalf("Expected %d container, %d found (started with: %d)", beginLen+1, len(containers.Data), beginLen)
|
|
| 332 | 332 |
} |
| 333 |
- if containers[0].ID != containerID {
|
|
| 334 |
- t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", containerID, containers[0].ID)
|
|
| 333 |
+ if id := containers.Data[0].Get("ID"); id != containerID {
|
|
| 334 |
+ t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", containerID, id)
|
|
| 335 | 335 |
} |
| 336 | 336 |
} |
| 337 | 337 |
|
| ... | ... |
@@ -69,7 +69,6 @@ func TestImageTagImageDelete(t *testing.T) {
|
| 69 | 69 |
|
| 70 | 70 |
func TestCreateRm(t *testing.T) {
|
| 71 | 71 |
eng := NewTestEngine(t) |
| 72 |
- srv := mkServerFromEngine(eng, t) |
|
| 73 | 72 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 74 | 73 |
|
| 75 | 74 |
config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
|
| ... | ... |
@@ -79,25 +78,44 @@ func TestCreateRm(t *testing.T) {
|
| 79 | 79 |
|
| 80 | 80 |
id := createTestContainer(eng, config, t) |
| 81 | 81 |
|
| 82 |
- if c := srv.Containers(true, false, -1, "", ""); len(c) != 1 {
|
|
| 83 |
- t.Errorf("Expected 1 container, %v found", len(c))
|
|
| 82 |
+ job := eng.Job("containers")
|
|
| 83 |
+ job.SetenvBool("all", true)
|
|
| 84 |
+ outs, err := job.Stdout.AddListTable() |
|
| 85 |
+ if err != nil {
|
|
| 86 |
+ t.Fatal(err) |
|
| 87 |
+ } |
|
| 88 |
+ if err := job.Run(); err != nil {
|
|
| 89 |
+ t.Fatal(err) |
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ if len(outs.Data) != 1 {
|
|
| 93 |
+ t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
|
| 84 | 94 |
} |
| 85 | 95 |
|
| 86 |
- job := eng.Job("container_delete", id)
|
|
| 96 |
+ job = eng.Job("container_delete", id)
|
|
| 87 | 97 |
job.SetenvBool("removeVolume", true)
|
| 88 | 98 |
if err := job.Run(); err != nil {
|
| 89 | 99 |
t.Fatal(err) |
| 90 | 100 |
} |
| 91 | 101 |
|
| 92 |
- if c := srv.Containers(true, false, -1, "", ""); len(c) != 0 {
|
|
| 93 |
- t.Errorf("Expected 0 container, %v found", len(c))
|
|
| 102 |
+ job = eng.Job("containers")
|
|
| 103 |
+ job.SetenvBool("all", true)
|
|
| 104 |
+ outs, err = job.Stdout.AddListTable() |
|
| 105 |
+ if err != nil {
|
|
| 106 |
+ t.Fatal(err) |
|
| 107 |
+ } |
|
| 108 |
+ if err := job.Run(); err != nil {
|
|
| 109 |
+ t.Fatal(err) |
|
| 110 |
+ } |
|
| 111 |
+ |
|
| 112 |
+ if len(outs.Data) != 0 {
|
|
| 113 |
+ t.Errorf("Expected 0 container, %v found", len(outs.Data))
|
|
| 94 | 114 |
} |
| 95 | 115 |
|
| 96 | 116 |
} |
| 97 | 117 |
|
| 98 | 118 |
func TestCreateRmVolumes(t *testing.T) {
|
| 99 | 119 |
eng := NewTestEngine(t) |
| 100 |
- srv := mkServerFromEngine(eng, t) |
|
| 101 | 120 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 102 | 121 |
|
| 103 | 122 |
config, hostConfig, _, err := docker.ParseRun([]string{"-v", "/srv", unitTestImageID, "echo", "test"}, nil)
|
| ... | ... |
@@ -107,11 +125,21 @@ func TestCreateRmVolumes(t *testing.T) {
|
| 107 | 107 |
|
| 108 | 108 |
id := createTestContainer(eng, config, t) |
| 109 | 109 |
|
| 110 |
- if c := srv.Containers(true, false, -1, "", ""); len(c) != 1 {
|
|
| 111 |
- t.Errorf("Expected 1 container, %v found", len(c))
|
|
| 110 |
+ job := eng.Job("containers")
|
|
| 111 |
+ job.SetenvBool("all", true)
|
|
| 112 |
+ outs, err := job.Stdout.AddListTable() |
|
| 113 |
+ if err != nil {
|
|
| 114 |
+ t.Fatal(err) |
|
| 115 |
+ } |
|
| 116 |
+ if err := job.Run(); err != nil {
|
|
| 117 |
+ t.Fatal(err) |
|
| 112 | 118 |
} |
| 113 | 119 |
|
| 114 |
- job := eng.Job("start", id)
|
|
| 120 |
+ if len(outs.Data) != 1 {
|
|
| 121 |
+ t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
|
| 122 |
+ } |
|
| 123 |
+ |
|
| 124 |
+ job = eng.Job("start", id)
|
|
| 115 | 125 |
if err := job.ImportEnv(hostConfig); err != nil {
|
| 116 | 126 |
t.Fatal(err) |
| 117 | 127 |
} |
| ... | ... |
@@ -131,8 +159,18 @@ func TestCreateRmVolumes(t *testing.T) {
|
| 131 | 131 |
t.Fatal(err) |
| 132 | 132 |
} |
| 133 | 133 |
|
| 134 |
- if c := srv.Containers(true, false, -1, "", ""); len(c) != 0 {
|
|
| 135 |
- t.Errorf("Expected 0 container, %v found", len(c))
|
|
| 134 |
+ job = eng.Job("containers")
|
|
| 135 |
+ job.SetenvBool("all", true)
|
|
| 136 |
+ outs, err = job.Stdout.AddListTable() |
|
| 137 |
+ if err != nil {
|
|
| 138 |
+ t.Fatal(err) |
|
| 139 |
+ } |
|
| 140 |
+ if err := job.Run(); err != nil {
|
|
| 141 |
+ t.Fatal(err) |
|
| 142 |
+ } |
|
| 143 |
+ |
|
| 144 |
+ if len(outs.Data) != 0 {
|
|
| 145 |
+ t.Errorf("Expected 0 container, %v found", len(outs.Data))
|
|
| 136 | 146 |
} |
| 137 | 147 |
} |
| 138 | 148 |
|
| ... | ... |
@@ -169,11 +207,21 @@ func TestRestartKillWait(t *testing.T) {
|
| 169 | 169 |
|
| 170 | 170 |
id := createTestContainer(eng, config, t) |
| 171 | 171 |
|
| 172 |
- if c := srv.Containers(true, false, -1, "", ""); len(c) != 1 {
|
|
| 173 |
- t.Errorf("Expected 1 container, %v found", len(c))
|
|
| 172 |
+ job := eng.Job("containers")
|
|
| 173 |
+ job.SetenvBool("all", true)
|
|
| 174 |
+ outs, err := job.Stdout.AddListTable() |
|
| 175 |
+ if err != nil {
|
|
| 176 |
+ t.Fatal(err) |
|
| 177 |
+ } |
|
| 178 |
+ if err := job.Run(); err != nil {
|
|
| 179 |
+ t.Fatal(err) |
|
| 174 | 180 |
} |
| 175 | 181 |
|
| 176 |
- job := eng.Job("start", id)
|
|
| 182 |
+ if len(outs.Data) != 1 {
|
|
| 183 |
+ t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
|
| 184 |
+ } |
|
| 185 |
+ |
|
| 186 |
+ job = eng.Job("start", id)
|
|
| 177 | 187 |
if err := job.ImportEnv(hostConfig); err != nil {
|
| 178 | 188 |
t.Fatal(err) |
| 179 | 189 |
} |
| ... | ... |
@@ -200,13 +248,23 @@ func TestRestartKillWait(t *testing.T) {
|
| 200 | 200 |
} |
| 201 | 201 |
|
| 202 | 202 |
srv = mkServerFromEngine(eng, t) |
| 203 |
- c := srv.Containers(true, false, -1, "", "") |
|
| 204 |
- if len(c) != 1 {
|
|
| 205 |
- t.Errorf("Expected 1 container, %v found", len(c))
|
|
| 203 |
+ |
|
| 204 |
+ job = srv.Eng.Job("containers")
|
|
| 205 |
+ job.SetenvBool("all", true)
|
|
| 206 |
+ outs, err = job.Stdout.AddListTable() |
|
| 207 |
+ if err != nil {
|
|
| 208 |
+ t.Fatal(err) |
|
| 209 |
+ } |
|
| 210 |
+ if err := job.Run(); err != nil {
|
|
| 211 |
+ t.Fatal(err) |
|
| 212 |
+ } |
|
| 213 |
+ |
|
| 214 |
+ if len(outs.Data) != 1 {
|
|
| 215 |
+ t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
|
| 206 | 216 |
} |
| 207 | 217 |
|
| 208 | 218 |
setTimeout(t, "Waiting on stopped container timedout", 5*time.Second, func() {
|
| 209 |
- job = srv.Eng.Job("wait", c[0].ID)
|
|
| 219 |
+ job = srv.Eng.Job("wait", outs.Data[0].Get("ID"))
|
|
| 210 | 220 |
var statusStr string |
| 211 | 221 |
job.Stdout.AddString(&statusStr) |
| 212 | 222 |
if err := job.Run(); err != nil {
|
| ... | ... |
@@ -227,11 +285,21 @@ func TestCreateStartRestartStopStartKillRm(t *testing.T) {
|
| 227 | 227 |
|
| 228 | 228 |
id := createTestContainer(eng, config, t) |
| 229 | 229 |
|
| 230 |
- if c := srv.Containers(true, false, -1, "", ""); len(c) != 1 {
|
|
| 231 |
- t.Errorf("Expected 1 container, %v found", len(c))
|
|
| 230 |
+ job := srv.Eng.Job("containers")
|
|
| 231 |
+ job.SetenvBool("all", true)
|
|
| 232 |
+ outs, err := job.Stdout.AddListTable() |
|
| 233 |
+ if err != nil {
|
|
| 234 |
+ t.Fatal(err) |
|
| 235 |
+ } |
|
| 236 |
+ if err := job.Run(); err != nil {
|
|
| 237 |
+ t.Fatal(err) |
|
| 238 |
+ } |
|
| 239 |
+ |
|
| 240 |
+ if len(outs.Data) != 1 {
|
|
| 241 |
+ t.Errorf("Expected 1 container, %v found", len(outs.Data))
|
|
| 232 | 242 |
} |
| 233 | 243 |
|
| 234 |
- job := eng.Job("start", id)
|
|
| 244 |
+ job = eng.Job("start", id)
|
|
| 235 | 245 |
if err := job.ImportEnv(hostConfig); err != nil {
|
| 236 | 246 |
t.Fatal(err) |
| 237 | 247 |
} |
| ... | ... |
@@ -270,8 +338,18 @@ func TestCreateStartRestartStopStartKillRm(t *testing.T) {
|
| 270 | 270 |
t.Fatal(err) |
| 271 | 271 |
} |
| 272 | 272 |
|
| 273 |
- if c := srv.Containers(true, false, -1, "", ""); len(c) != 0 {
|
|
| 274 |
- t.Errorf("Expected 0 container, %v found", len(c))
|
|
| 273 |
+ job = srv.Eng.Job("containers")
|
|
| 274 |
+ job.SetenvBool("all", true)
|
|
| 275 |
+ outs, err = job.Stdout.AddListTable() |
|
| 276 |
+ if err != nil {
|
|
| 277 |
+ t.Fatal(err) |
|
| 278 |
+ } |
|
| 279 |
+ if err := job.Run(); err != nil {
|
|
| 280 |
+ t.Fatal(err) |
|
| 281 |
+ } |
|
| 282 |
+ |
|
| 283 |
+ if len(outs.Data) != 0 {
|
|
| 284 |
+ t.Errorf("Expected 0 container, %v found", len(outs.Data))
|
|
| 275 | 285 |
} |
| 276 | 286 |
} |
| 277 | 287 |
|
| ... | ... |
@@ -465,10 +543,18 @@ func TestDeleteTagWithExistingContainers(t *testing.T) {
|
| 465 | 465 |
t.Fatal("No id returned")
|
| 466 | 466 |
} |
| 467 | 467 |
|
| 468 |
- containers := srv.Containers(true, false, -1, "", "") |
|
| 468 |
+ job := srv.Eng.Job("containers")
|
|
| 469 |
+ job.SetenvBool("all", true)
|
|
| 470 |
+ outs, err := job.Stdout.AddListTable() |
|
| 471 |
+ if err != nil {
|
|
| 472 |
+ t.Fatal(err) |
|
| 473 |
+ } |
|
| 474 |
+ if err := job.Run(); err != nil {
|
|
| 475 |
+ t.Fatal(err) |
|
| 476 |
+ } |
|
| 469 | 477 |
|
| 470 |
- if len(containers) != 1 {
|
|
| 471 |
- t.Fatalf("Expected 1 container got %d", len(containers))
|
|
| 478 |
+ if len(outs.Data) != 1 {
|
|
| 479 |
+ t.Fatalf("Expected 1 container got %d", len(outs.Data))
|
|
| 472 | 480 |
} |
| 473 | 481 |
|
| 474 | 482 |
// Try to remove the tag |
| ... | ... |
@@ -103,6 +103,7 @@ func jobInitApi(job *engine.Job) engine.Status {
|
| 103 | 103 |
"inspect": srv.JobInspect, |
| 104 | 104 |
"events": srv.Events, |
| 105 | 105 |
"push": srv.ImagePush, |
| 106 |
+ "containers": srv.Containers, |
|
| 106 | 107 |
} {
|
| 107 | 108 |
if err := job.Eng.Register(name, handler); err != nil {
|
| 108 | 109 |
job.Error(err) |
| ... | ... |
@@ -1055,10 +1056,17 @@ func (srv *Server) ContainerChanges(job *engine.Job) engine.Status {
|
| 1055 | 1055 |
return engine.StatusOK |
| 1056 | 1056 |
} |
| 1057 | 1057 |
|
| 1058 |
-func (srv *Server) Containers(all, size bool, n int, since, before string) []APIContainers {
|
|
| 1059 |
- var foundBefore bool |
|
| 1060 |
- var displayed int |
|
| 1061 |
- out := []APIContainers{}
|
|
| 1058 |
+func (srv *Server) Containers(job *engine.Job) engine.Status {
|
|
| 1059 |
+ var ( |
|
| 1060 |
+ foundBefore bool |
|
| 1061 |
+ displayed int |
|
| 1062 |
+ all = job.GetenvBool("all")
|
|
| 1063 |
+ since = job.Getenv("since")
|
|
| 1064 |
+ before = job.Getenv("before")
|
|
| 1065 |
+ n = job.GetenvInt("limit")
|
|
| 1066 |
+ size = job.GetenvBool("size")
|
|
| 1067 |
+ ) |
|
| 1068 |
+ outs := engine.NewTable("Created", 0)
|
|
| 1062 | 1069 |
|
| 1063 | 1070 |
names := map[string][]string{}
|
| 1064 | 1071 |
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 |
| 1083 | 1083 |
break |
| 1084 | 1084 |
} |
| 1085 | 1085 |
displayed++ |
| 1086 |
- c := createAPIContainer(names[container.ID], container, size, srv.runtime) |
|
| 1087 |
- out = append(out, c) |
|
| 1088 |
- } |
|
| 1089 |
- return out |
|
| 1090 |
-} |
|
| 1091 |
- |
|
| 1092 |
-func createAPIContainer(names []string, container *Container, size bool, runtime *Runtime) APIContainers {
|
|
| 1093 |
- c := APIContainers{
|
|
| 1094 |
- ID: container.ID, |
|
| 1086 |
+ out := &engine.Env{}
|
|
| 1087 |
+ out.Set("ID", container.ID)
|
|
| 1088 |
+ out.SetList("Names", names[container.ID])
|
|
| 1089 |
+ out.Set("Image", srv.runtime.repositories.ImageName(container.Image))
|
|
| 1090 |
+ out.Set("Command", fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " ")))
|
|
| 1091 |
+ out.SetInt64("Created", container.Created.Unix())
|
|
| 1092 |
+ out.Set("Status", container.State.String())
|
|
| 1093 |
+ str, err := container.NetworkSettings.PortMappingAPI().ToListString() |
|
| 1094 |
+ if err != nil {
|
|
| 1095 |
+ job.Error(err) |
|
| 1096 |
+ return engine.StatusErr |
|
| 1097 |
+ } |
|
| 1098 |
+ out.Set("Ports", str)
|
|
| 1099 |
+ if size {
|
|
| 1100 |
+ sizeRw, sizeRootFs := container.GetSize() |
|
| 1101 |
+ out.SetInt64("SizeRw", sizeRw)
|
|
| 1102 |
+ out.SetInt64("SizeRootFs", sizeRootFs)
|
|
| 1103 |
+ } |
|
| 1104 |
+ outs.Add(out) |
|
| 1095 | 1105 |
} |
| 1096 |
- c.Names = names |
|
| 1097 |
- c.Image = runtime.repositories.ImageName(container.Image) |
|
| 1098 |
- c.Command = fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
|
|
| 1099 |
- c.Created = container.Created.Unix() |
|
| 1100 |
- c.Status = container.State.String() |
|
| 1101 |
- c.Ports = container.NetworkSettings.PortMappingAPI() |
|
| 1102 |
- if size {
|
|
| 1103 |
- c.SizeRw, c.SizeRootFs = container.GetSize() |
|
| 1106 |
+ outs.ReverseSort() |
|
| 1107 |
+ if _, err := outs.WriteListTo(job.Stdout); err != nil {
|
|
| 1108 |
+ job.Error(err) |
|
| 1109 |
+ return engine.StatusErr |
|
| 1104 | 1110 |
} |
| 1105 |
- return c |
|
| 1111 |
+ return engine.StatusOK |
|
| 1106 | 1112 |
} |
| 1113 |
+ |
|
| 1107 | 1114 |
func (srv *Server) ContainerCommit(job *engine.Job) engine.Status {
|
| 1108 | 1115 |
if len(job.Args) != 1 {
|
| 1109 | 1116 |
job.Errorf("Not enough arguments. Usage: %s CONTAINER\n", job.Name)
|