mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Last step in removing engine.Tabel from api/client/*
Signed-off-by: Doug Davis <dug@us.ibm.com>
This commit is contained in:
parent
2a79d54f4c
commit
065648a832
6 changed files with 258 additions and 131 deletions
|
@ -1,13 +1,14 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
"github.com/docker/docker/pkg/parsers"
|
||||||
|
@ -18,26 +19,26 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// FIXME: --viz and --tree are deprecated. Remove them in a future version.
|
// FIXME: --viz and --tree are deprecated. Remove them in a future version.
|
||||||
func (cli *DockerCli) WalkTree(noTrunc bool, images *engine.Table, byParent map[string]*engine.Table, prefix string, printNode func(cli *DockerCli, noTrunc bool, image *engine.Env, prefix string)) {
|
func (cli *DockerCli) WalkTree(noTrunc bool, images []*types.Image, byParent map[string][]*types.Image, prefix string, printNode func(cli *DockerCli, noTrunc bool, image *types.Image, prefix string)) {
|
||||||
length := images.Len()
|
length := len(images)
|
||||||
if length > 1 {
|
if length > 1 {
|
||||||
for index, image := range images.Data {
|
for index, image := range images {
|
||||||
if index+1 == length {
|
if index+1 == length {
|
||||||
printNode(cli, noTrunc, image, prefix+"└─")
|
printNode(cli, noTrunc, image, prefix+"└─")
|
||||||
if subimages, exists := byParent[image.Get("Id")]; exists {
|
if subimages, exists := byParent[image.ID]; exists {
|
||||||
cli.WalkTree(noTrunc, subimages, byParent, prefix+" ", printNode)
|
cli.WalkTree(noTrunc, subimages, byParent, prefix+" ", printNode)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printNode(cli, noTrunc, image, prefix+"\u251C─")
|
printNode(cli, noTrunc, image, prefix+"\u251C─")
|
||||||
if subimages, exists := byParent[image.Get("Id")]; exists {
|
if subimages, exists := byParent[image.ID]; exists {
|
||||||
cli.WalkTree(noTrunc, subimages, byParent, prefix+"\u2502 ", printNode)
|
cli.WalkTree(noTrunc, subimages, byParent, prefix+"\u2502 ", printNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, image := range images.Data {
|
for _, image := range images {
|
||||||
printNode(cli, noTrunc, image, prefix+"└─")
|
printNode(cli, noTrunc, image, prefix+"└─")
|
||||||
if subimages, exists := byParent[image.Get("Id")]; exists {
|
if subimages, exists := byParent[image.ID]; exists {
|
||||||
cli.WalkTree(noTrunc, subimages, byParent, prefix+" ", printNode)
|
cli.WalkTree(noTrunc, subimages, byParent, prefix+" ", printNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,41 +46,41 @@ func (cli *DockerCli) WalkTree(noTrunc bool, images *engine.Table, byParent map[
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: --viz and --tree are deprecated. Remove them in a future version.
|
// FIXME: --viz and --tree are deprecated. Remove them in a future version.
|
||||||
func (cli *DockerCli) printVizNode(noTrunc bool, image *engine.Env, prefix string) {
|
func (cli *DockerCli) printVizNode(noTrunc bool, image *types.Image, prefix string) {
|
||||||
var (
|
var (
|
||||||
imageID string
|
imageID string
|
||||||
parentID string
|
parentID string
|
||||||
)
|
)
|
||||||
if noTrunc {
|
if noTrunc {
|
||||||
imageID = image.Get("Id")
|
imageID = image.ID
|
||||||
parentID = image.Get("ParentId")
|
parentID = image.ParentId
|
||||||
} else {
|
} else {
|
||||||
imageID = stringid.TruncateID(image.Get("Id"))
|
imageID = stringid.TruncateID(image.ID)
|
||||||
parentID = stringid.TruncateID(image.Get("ParentId"))
|
parentID = stringid.TruncateID(image.ParentId)
|
||||||
}
|
}
|
||||||
if parentID == "" {
|
if parentID == "" {
|
||||||
fmt.Fprintf(cli.out, " base -> \"%s\" [style=invis]\n", imageID)
|
fmt.Fprintf(cli.out, " base -> \"%s\" [style=invis]\n", imageID)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(cli.out, " \"%s\" -> \"%s\"\n", parentID, imageID)
|
fmt.Fprintf(cli.out, " \"%s\" -> \"%s\"\n", parentID, imageID)
|
||||||
}
|
}
|
||||||
if image.GetList("RepoTags")[0] != "<none>:<none>" {
|
if image.RepoTags[0] != "<none>:<none>" {
|
||||||
fmt.Fprintf(cli.out, " \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n",
|
fmt.Fprintf(cli.out, " \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n",
|
||||||
imageID, imageID, strings.Join(image.GetList("RepoTags"), "\\n"))
|
imageID, imageID, strings.Join(image.RepoTags, "\\n"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: --viz and --tree are deprecated. Remove them in a future version.
|
// FIXME: --viz and --tree are deprecated. Remove them in a future version.
|
||||||
func (cli *DockerCli) printTreeNode(noTrunc bool, image *engine.Env, prefix string) {
|
func (cli *DockerCli) printTreeNode(noTrunc bool, image *types.Image, prefix string) {
|
||||||
var imageID string
|
var imageID string
|
||||||
if noTrunc {
|
if noTrunc {
|
||||||
imageID = image.Get("Id")
|
imageID = image.ID
|
||||||
} else {
|
} else {
|
||||||
imageID = stringid.TruncateID(image.Get("Id"))
|
imageID = stringid.TruncateID(image.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, units.HumanSize(float64(image.GetInt64("VirtualSize"))))
|
fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, units.HumanSize(float64(image.VirtualSize)))
|
||||||
if image.GetList("RepoTags")[0] != "<none>:<none>" {
|
if image.RepoTags[0] != "<none>:<none>" {
|
||||||
fmt.Fprintf(cli.out, " Tags: %s\n", strings.Join(image.GetList("RepoTags"), ", "))
|
fmt.Fprintf(cli.out, " Tags: %s\n", strings.Join(image.RepoTags, ", "))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprint(cli.out, "\n")
|
fmt.Fprint(cli.out, "\n")
|
||||||
}
|
}
|
||||||
|
@ -101,7 +102,6 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
||||||
flFilter := opts.NewListOpts(nil)
|
flFilter := opts.NewListOpts(nil)
|
||||||
cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
|
cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
|
||||||
cmd.Require(flag.Max, 1)
|
cmd.Require(flag.Max, 1)
|
||||||
|
|
||||||
cmd.ParseFlags(args, true)
|
cmd.ParseFlags(args, true)
|
||||||
|
|
||||||
// Consolidate all filter flags, and sanity check them early.
|
// Consolidate all filter flags, and sanity check them early.
|
||||||
|
@ -129,44 +129,44 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
||||||
v.Set("filters", filterJSON)
|
v.Set("filters", filterJSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
body, _, err := readBody(cli.call("GET", "/images/json?"+v.Encode(), nil, nil))
|
rdr, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
outs := engine.NewTable("Created", 0)
|
images := []types.Image{}
|
||||||
if _, err := outs.ReadListFrom(body); err != nil {
|
err = json.NewDecoder(rdr).Decode(&images)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
printNode func(cli *DockerCli, noTrunc bool, image *engine.Env, prefix string)
|
printNode func(cli *DockerCli, noTrunc bool, image *types.Image, prefix string)
|
||||||
startImage *engine.Env
|
startImage *types.Image
|
||||||
|
|
||||||
roots = engine.NewTable("Created", outs.Len())
|
roots = []*types.Image{}
|
||||||
byParent = make(map[string]*engine.Table)
|
byParent = make(map[string][]*types.Image)
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, image := range outs.Data {
|
for _, image := range images {
|
||||||
if image.Get("ParentId") == "" {
|
if image.ParentId == "" {
|
||||||
roots.Add(image)
|
roots = append(roots, &image)
|
||||||
} else {
|
} else {
|
||||||
if children, exists := byParent[image.Get("ParentId")]; exists {
|
if children, exists := byParent[image.ParentId]; exists {
|
||||||
children.Add(image)
|
children = append(children, &image)
|
||||||
} else {
|
} else {
|
||||||
byParent[image.Get("ParentId")] = engine.NewTable("Created", 1)
|
byParent[image.ParentId] = []*types.Image{&image}
|
||||||
byParent[image.Get("ParentId")].Add(image)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if matchName != "" {
|
if matchName != "" {
|
||||||
if matchName == image.Get("Id") || matchName == stringid.TruncateID(image.Get("Id")) {
|
if matchName == image.ID || matchName == stringid.TruncateID(image.ID) {
|
||||||
startImage = image
|
startImage = &image
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, repotag := range image.GetList("RepoTags") {
|
for _, repotag := range image.RepoTags {
|
||||||
if repotag == matchName {
|
if repotag == matchName {
|
||||||
startImage = image
|
startImage = &image
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,8 +180,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if startImage != nil {
|
if startImage != nil {
|
||||||
root := engine.NewTable("Created", 1)
|
root := []*types.Image{startImage}
|
||||||
root.Add(startImage)
|
|
||||||
cli.WalkTree(*noTrunc, root, byParent, "", printNode)
|
cli.WalkTree(*noTrunc, root, byParent, "", printNode)
|
||||||
} else if matchName == "" {
|
} else if matchName == "" {
|
||||||
cli.WalkTree(*noTrunc, roots, byParent, "", printNode)
|
cli.WalkTree(*noTrunc, roots, byParent, "", printNode)
|
||||||
|
@ -207,14 +206,14 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
||||||
v.Set("all", "1")
|
v.Set("all", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
body, _, err := readBody(cli.call("GET", "/images/json?"+v.Encode(), nil, nil))
|
rdr, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
outs := engine.NewTable("Created", 0)
|
images := []types.Image{}
|
||||||
if _, err := outs.ReadListFrom(body); err != nil {
|
err = json.NewDecoder(rdr).Decode(&images)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,14 +226,14 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, out := range outs.Data {
|
for _, image := range images {
|
||||||
outID := out.Get("Id")
|
ID := image.ID
|
||||||
if !*noTrunc {
|
if !*noTrunc {
|
||||||
outID = stringid.TruncateID(outID)
|
ID = stringid.TruncateID(ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
repoTags := out.GetList("RepoTags")
|
repoTags := image.RepoTags
|
||||||
repoDigests := out.GetList("RepoDigests")
|
repoDigests := image.RepoDigests
|
||||||
|
|
||||||
if len(repoTags) == 1 && repoTags[0] == "<none>:<none>" && len(repoDigests) == 1 && repoDigests[0] == "<none>@<none>" {
|
if len(repoTags) == 1 && repoTags[0] == "<none>:<none>" && len(repoDigests) == 1 && repoDigests[0] == "<none>@<none>" {
|
||||||
// dangling image - clear out either repoTags or repoDigsts so we only show it once below
|
// dangling image - clear out either repoTags or repoDigsts so we only show it once below
|
||||||
|
@ -256,12 +255,12 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
||||||
|
|
||||||
if !*quiet {
|
if !*quiet {
|
||||||
if *showDigests {
|
if *showDigests {
|
||||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(float64(out.GetInt64("VirtualSize"))))
|
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize)))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(float64(out.GetInt64("VirtualSize"))))
|
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintln(w, outID)
|
fmt.Fprintln(w, ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -9,7 +10,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/pkg/parsers/filters"
|
"github.com/docker/docker/pkg/parsers/filters"
|
||||||
|
@ -85,13 +86,14 @@ func (cli *DockerCli) CmdPs(args ...string) error {
|
||||||
v.Set("filters", filterJSON)
|
v.Set("filters", filterJSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
body, _, err := readBody(cli.call("GET", "/containers/json?"+v.Encode(), nil, nil))
|
rdr, _, err := cli.call("GET", "/containers/json?"+v.Encode(), nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
outs := engine.NewTable("Created", 0)
|
containers := []types.Container{}
|
||||||
if _, err := outs.ReadListFrom(body); err != nil {
|
err = json.NewDecoder(rdr).Decode(&containers)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,54 +116,50 @@ func (cli *DockerCli) CmdPs(args ...string) error {
|
||||||
return ss
|
return ss
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, out := range outs.Data {
|
for _, container := range containers {
|
||||||
outID := out.Get("Id")
|
ID := container.ID
|
||||||
|
|
||||||
if !*noTrunc {
|
if !*noTrunc {
|
||||||
outID = stringid.TruncateID(outID)
|
ID = stringid.TruncateID(ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *quiet {
|
if *quiet {
|
||||||
fmt.Fprintln(w, outID)
|
fmt.Fprintln(w, ID)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
outNames = stripNamePrefix(out.GetList("Names"))
|
names = stripNamePrefix(container.Names)
|
||||||
outCommand = strconv.Quote(out.Get("Command"))
|
command = strconv.Quote(container.Command)
|
||||||
ports = engine.NewTable("", 0)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if !*noTrunc {
|
if !*noTrunc {
|
||||||
outCommand = utils.Trunc(outCommand, 20)
|
command = utils.Trunc(command, 20)
|
||||||
|
|
||||||
// only display the default name for the container with notrunc is passed
|
// only display the default name for the container with notrunc is passed
|
||||||
for _, name := range outNames {
|
for _, name := range names {
|
||||||
if len(strings.Split(name, "/")) == 1 {
|
if len(strings.Split(name, "/")) == 1 {
|
||||||
outNames = []string{name}
|
names = []string{name}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ports.ReadListFrom([]byte(out.Get("Ports")))
|
image := container.Image
|
||||||
|
|
||||||
image := out.Get("Image")
|
|
||||||
if image == "" {
|
if image == "" {
|
||||||
image = "<no image>"
|
image = "<no image>"
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", outID, image, outCommand,
|
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", ID, image, command,
|
||||||
units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))),
|
units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(container.Created), 0))),
|
||||||
out.Get("Status"), api.DisplayablePorts(ports), strings.Join(outNames, ","))
|
container.Status, api.NewDisplayablePorts(container.Ports), strings.Join(names, ","))
|
||||||
|
|
||||||
if *size {
|
if *size {
|
||||||
if out.GetInt("SizeRootFs") > 0 {
|
if container.SizeRootFs > 0 {
|
||||||
fmt.Fprintf(w, "%s (virtual %s)\n", units.HumanSize(float64(out.GetInt64("SizeRw"))), units.HumanSize(float64(out.GetInt64("SizeRootFs"))))
|
fmt.Fprintf(w, "%s (virtual %s)\n", units.HumanSize(float64(container.SizeRw)), units.HumanSize(float64(container.SizeRootFs)))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(w, "%s\n", units.HumanSize(float64(out.GetInt64("SizeRw"))))
|
fmt.Fprintf(w, "%s\n", units.HumanSize(float64(container.SizeRw)))
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -5,9 +5,11 @@ import (
|
||||||
"mime"
|
"mime"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
"github.com/docker/docker/pkg/parsers"
|
||||||
"github.com/docker/docker/pkg/version"
|
"github.com/docker/docker/pkg/version"
|
||||||
|
@ -31,6 +33,7 @@ func ValidateHost(val string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove, used on < 1.5 in getContainersJSON
|
// TODO remove, used on < 1.5 in getContainersJSON
|
||||||
|
// TODO this can go away when we get rid of engine.table
|
||||||
func DisplayablePorts(ports *engine.Table) string {
|
func DisplayablePorts(ports *engine.Table) string {
|
||||||
var (
|
var (
|
||||||
result = []string{}
|
result = []string{}
|
||||||
|
@ -80,6 +83,61 @@ func DisplayablePorts(ports *engine.Table) string {
|
||||||
return strings.Join(result, ", ")
|
return strings.Join(result, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ByPrivatePort []types.Port
|
||||||
|
|
||||||
|
func (r ByPrivatePort) Len() int { return len(r) }
|
||||||
|
func (r ByPrivatePort) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
||||||
|
func (r ByPrivatePort) Less(i, j int) bool { return r[i].PrivatePort < r[j].PrivatePort }
|
||||||
|
|
||||||
|
// TODO Rename to DisplayablePorts (remove "New") when engine.Table goes away
|
||||||
|
func NewDisplayablePorts(ports []types.Port) string {
|
||||||
|
var (
|
||||||
|
result = []string{}
|
||||||
|
hostMappings = []string{}
|
||||||
|
firstInGroupMap map[string]int
|
||||||
|
lastInGroupMap map[string]int
|
||||||
|
)
|
||||||
|
firstInGroupMap = make(map[string]int)
|
||||||
|
lastInGroupMap = make(map[string]int)
|
||||||
|
sort.Sort(ByPrivatePort(ports))
|
||||||
|
for _, port := range ports {
|
||||||
|
var (
|
||||||
|
current = port.PrivatePort
|
||||||
|
portKey = port.Type
|
||||||
|
firstInGroup int
|
||||||
|
lastInGroup int
|
||||||
|
)
|
||||||
|
if port.IP != "" {
|
||||||
|
if port.PublicPort != current {
|
||||||
|
hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
portKey = fmt.Sprintf("%s/%s", port.IP, port.Type)
|
||||||
|
}
|
||||||
|
firstInGroup = firstInGroupMap[portKey]
|
||||||
|
lastInGroup = lastInGroupMap[portKey]
|
||||||
|
|
||||||
|
if firstInGroup == 0 {
|
||||||
|
firstInGroupMap[portKey] = current
|
||||||
|
lastInGroupMap[portKey] = current
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if current == (lastInGroup + 1) {
|
||||||
|
lastInGroupMap[portKey] = current
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, FormGroup(portKey, firstInGroup, lastInGroup))
|
||||||
|
firstInGroupMap[portKey] = current
|
||||||
|
lastInGroupMap[portKey] = current
|
||||||
|
}
|
||||||
|
for portKey, firstInGroup := range firstInGroupMap {
|
||||||
|
result = append(result, FormGroup(portKey, firstInGroup, lastInGroupMap[portKey]))
|
||||||
|
}
|
||||||
|
result = append(result, hostMappings...)
|
||||||
|
return strings.Join(result, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
func FormGroup(key string, start, last int) string {
|
func FormGroup(key string, start, last int) string {
|
||||||
var (
|
var (
|
||||||
group string
|
group string
|
||||||
|
|
|
@ -56,3 +56,36 @@ type ImageDelete struct {
|
||||||
Untagged string `json:",omitempty"`
|
Untagged string `json:",omitempty"`
|
||||||
Deleted string `json:",omitempty"`
|
Deleted string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET "/images/json"
|
||||||
|
type Image struct {
|
||||||
|
ID string `json:"Id"`
|
||||||
|
ParentId string
|
||||||
|
RepoTags []string
|
||||||
|
RepoDigests []string
|
||||||
|
Created int
|
||||||
|
Size int
|
||||||
|
VirtualSize int
|
||||||
|
Labels map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET "/containers/json"
|
||||||
|
type Port struct {
|
||||||
|
IP string
|
||||||
|
PrivatePort int
|
||||||
|
PublicPort int
|
||||||
|
Type string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Container struct {
|
||||||
|
ID string `json:"Id"`
|
||||||
|
Names []string `json:,omitempty"`
|
||||||
|
Image string `json:,omitempty"`
|
||||||
|
Command string `json:,omitempty"`
|
||||||
|
Created int `json:,omitempty"`
|
||||||
|
Ports []Port `json:,omitempty"`
|
||||||
|
SizeRw int `json:,omitempty"`
|
||||||
|
SizeRootFs int `json:,omitempty"`
|
||||||
|
Labels map[string]string `json:,omitempty"`
|
||||||
|
Status string `json:,omitempty"`
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
package daemon
|
package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/graph"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/pkg/graphdb"
|
|
||||||
"github.com/docker/docker/utils"
|
|
||||||
|
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
|
"github.com/docker/docker/graph"
|
||||||
|
"github.com/docker/docker/nat"
|
||||||
|
"github.com/docker/docker/pkg/graphdb"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
"github.com/docker/docker/pkg/parsers"
|
||||||
"github.com/docker/docker/pkg/parsers/filters"
|
"github.com/docker/docker/pkg/parsers/filters"
|
||||||
|
"github.com/docker/docker/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// List returns an array of all containers registered in the daemon.
|
// List returns an array of all containers registered in the daemon.
|
||||||
|
@ -20,6 +23,12 @@ func (daemon *Daemon) List() []*Container {
|
||||||
return daemon.containers.List()
|
return daemon.containers.List()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ByCreated []types.Container
|
||||||
|
|
||||||
|
func (r ByCreated) Len() int { return len(r) }
|
||||||
|
func (r ByCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
||||||
|
func (r ByCreated) Less(i, j int) bool { return r[i].Created < r[j].Created }
|
||||||
|
|
||||||
func (daemon *Daemon) Containers(job *engine.Job) error {
|
func (daemon *Daemon) Containers(job *engine.Job) error {
|
||||||
var (
|
var (
|
||||||
foundBefore bool
|
foundBefore bool
|
||||||
|
@ -32,7 +41,7 @@ func (daemon *Daemon) Containers(job *engine.Job) error {
|
||||||
psFilters filters.Args
|
psFilters filters.Args
|
||||||
filtExited []int
|
filtExited []int
|
||||||
)
|
)
|
||||||
outs := engine.NewTable("Created", 0)
|
containers := []types.Container{}
|
||||||
|
|
||||||
psFilters, err := filters.FromParam(job.Getenv("filters"))
|
psFilters, err := filters.FromParam(job.Getenv("filters"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -126,15 +135,16 @@ func (daemon *Daemon) Containers(job *engine.Job) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
displayed++
|
displayed++
|
||||||
out := &engine.Env{}
|
newC := types.Container{
|
||||||
out.SetJson("Id", container.ID)
|
ID: container.ID,
|
||||||
out.SetList("Names", names[container.ID])
|
Names: names[container.ID],
|
||||||
|
}
|
||||||
img := container.Config.Image
|
img := container.Config.Image
|
||||||
_, tag := parsers.ParseRepositoryTag(container.Config.Image)
|
_, tag := parsers.ParseRepositoryTag(container.Config.Image)
|
||||||
if tag == "" {
|
if tag == "" {
|
||||||
img = utils.ImageReference(img, graph.DEFAULTTAG)
|
img = utils.ImageReference(img, graph.DEFAULTTAG)
|
||||||
}
|
}
|
||||||
out.SetJson("Image", img)
|
newC.Image = img
|
||||||
if len(container.Args) > 0 {
|
if len(container.Args) > 0 {
|
||||||
args := []string{}
|
args := []string{}
|
||||||
for _, arg := range container.Args {
|
for _, arg := range container.Args {
|
||||||
|
@ -146,24 +156,41 @@ func (daemon *Daemon) Containers(job *engine.Job) error {
|
||||||
}
|
}
|
||||||
argsAsString := strings.Join(args, " ")
|
argsAsString := strings.Join(args, " ")
|
||||||
|
|
||||||
out.Set("Command", fmt.Sprintf("\"%s %s\"", container.Path, argsAsString))
|
newC.Command = fmt.Sprintf("%s %s", container.Path, argsAsString)
|
||||||
} else {
|
} else {
|
||||||
out.Set("Command", fmt.Sprintf("\"%s\"", container.Path))
|
newC.Command = fmt.Sprintf("%s", container.Path)
|
||||||
}
|
}
|
||||||
out.SetInt64("Created", container.Created.Unix())
|
newC.Created = int(container.Created.Unix())
|
||||||
out.Set("Status", container.State.String())
|
newC.Status = container.State.String()
|
||||||
str, err := container.NetworkSettings.PortMappingAPI().ToListString()
|
|
||||||
if err != nil {
|
newC.Ports = []types.Port{}
|
||||||
return err
|
for port, bindings := range container.NetworkSettings.Ports {
|
||||||
|
p, _ := nat.ParsePort(port.Port())
|
||||||
|
if len(bindings) == 0 {
|
||||||
|
newC.Ports = append(newC.Ports, types.Port{
|
||||||
|
PrivatePort: p,
|
||||||
|
Type: port.Proto(),
|
||||||
|
})
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
out.Set("Ports", str)
|
for _, binding := range bindings {
|
||||||
|
h, _ := nat.ParsePort(binding.HostPort)
|
||||||
|
newC.Ports = append(newC.Ports, types.Port{
|
||||||
|
PrivatePort: p,
|
||||||
|
PublicPort: h,
|
||||||
|
Type: port.Proto(),
|
||||||
|
IP: binding.HostIp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if size {
|
if size {
|
||||||
sizeRw, sizeRootFs := container.GetSize()
|
sizeRw, sizeRootFs := container.GetSize()
|
||||||
out.SetInt64("SizeRw", sizeRw)
|
newC.SizeRw = int(sizeRw)
|
||||||
out.SetInt64("SizeRootFs", sizeRootFs)
|
newC.SizeRootFs = int(sizeRootFs)
|
||||||
}
|
}
|
||||||
out.SetJson("Labels", container.Config.Labels)
|
newC.Labels = container.Config.Labels
|
||||||
outs.Add(out)
|
containers = append(containers, newC)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,8 +202,8 @@ func (daemon *Daemon) Containers(job *engine.Job) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outs.ReverseSort()
|
sort.Sort(sort.Reverse(ByCreated(containers)))
|
||||||
if _, err := outs.WriteListTo(job.Stdout); err != nil {
|
if err = json.NewEncoder(job.Stdout).Encode(containers); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package graph
|
package graph
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"path"
|
"path"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
"github.com/docker/docker/image"
|
"github.com/docker/docker/image"
|
||||||
"github.com/docker/docker/pkg/parsers/filters"
|
"github.com/docker/docker/pkg/parsers/filters"
|
||||||
|
@ -17,6 +20,12 @@ var acceptedImageFilterTags = map[string]struct{}{
|
||||||
"label": {},
|
"label": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ByCreated []*types.Image
|
||||||
|
|
||||||
|
func (r ByCreated) Len() int { return len(r) }
|
||||||
|
func (r ByCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
||||||
|
func (r ByCreated) Less(i, j int) bool { return r[i].Created < r[j].Created }
|
||||||
|
|
||||||
func (s *TagStore) CmdImages(job *engine.Job) error {
|
func (s *TagStore) CmdImages(job *engine.Job) error {
|
||||||
var (
|
var (
|
||||||
allImages map[string]*image.Image
|
allImages map[string]*image.Image
|
||||||
|
@ -53,7 +62,8 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
lookup := make(map[string]*engine.Env)
|
|
||||||
|
lookup := make(map[string]*types.Image)
|
||||||
s.Lock()
|
s.Lock()
|
||||||
for repoName, repository := range s.Repositories {
|
for repoName, repository := range s.Repositories {
|
||||||
if job.Getenv("filter") != "" {
|
if job.Getenv("filter") != "" {
|
||||||
|
@ -69,12 +79,12 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if out, exists := lookup[id]; exists {
|
if lImage, exists := lookup[id]; exists {
|
||||||
if filtTagged {
|
if filtTagged {
|
||||||
if utils.DigestReference(ref) {
|
if utils.DigestReference(ref) {
|
||||||
out.SetList("RepoDigests", append(out.GetList("RepoDigests"), imgRef))
|
lImage.RepoDigests = append(lImage.RepoDigests, imgRef)
|
||||||
} else { // Tag Ref.
|
} else { // Tag Ref.
|
||||||
out.SetList("RepoTags", append(out.GetList("RepoTags"), imgRef))
|
lImage.RepoTags = append(lImage.RepoTags, imgRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -84,23 +94,23 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if filtTagged {
|
if filtTagged {
|
||||||
out := &engine.Env{}
|
newImage := new(types.Image)
|
||||||
out.SetJson("ParentId", image.Parent)
|
newImage.ParentId = image.Parent
|
||||||
out.SetJson("Id", image.ID)
|
newImage.ID = image.ID
|
||||||
out.SetInt64("Created", image.Created.Unix())
|
newImage.Created = int(image.Created.Unix())
|
||||||
out.SetInt64("Size", image.Size)
|
newImage.Size = int(image.Size)
|
||||||
out.SetInt64("VirtualSize", image.GetParentsSize(0)+image.Size)
|
newImage.VirtualSize = int(image.GetParentsSize(0) + image.Size)
|
||||||
out.SetJson("Labels", image.ContainerConfig.Labels)
|
newImage.Labels = image.ContainerConfig.Labels
|
||||||
|
|
||||||
if utils.DigestReference(ref) {
|
if utils.DigestReference(ref) {
|
||||||
out.SetList("RepoTags", []string{})
|
newImage.RepoTags = []string{}
|
||||||
out.SetList("RepoDigests", []string{imgRef})
|
newImage.RepoDigests = []string{imgRef}
|
||||||
} else {
|
} else {
|
||||||
out.SetList("RepoTags", []string{imgRef})
|
newImage.RepoTags = []string{imgRef}
|
||||||
out.SetList("RepoDigests", []string{})
|
newImage.RepoDigests = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
lookup[id] = out
|
lookup[id] = newImage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,9 +118,9 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
|
||||||
}
|
}
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
|
|
||||||
outs := engine.NewTable("Created", len(lookup))
|
images := []*types.Image{}
|
||||||
for _, value := range lookup {
|
for _, value := range lookup {
|
||||||
outs.Add(value)
|
images = append(images, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display images which aren't part of a repository/tag
|
// Display images which aren't part of a repository/tag
|
||||||
|
@ -119,21 +129,23 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
|
||||||
if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) {
|
if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
out := &engine.Env{}
|
newImage := new(types.Image)
|
||||||
out.SetJson("ParentId", image.Parent)
|
newImage.ParentId = image.Parent
|
||||||
out.SetList("RepoTags", []string{"<none>:<none>"})
|
newImage.RepoTags = []string{"<none>:<none>"}
|
||||||
out.SetList("RepoDigests", []string{"<none>@<none>"})
|
newImage.RepoDigests = []string{"<none>@<none>"}
|
||||||
out.SetJson("Id", image.ID)
|
newImage.ID = image.ID
|
||||||
out.SetInt64("Created", image.Created.Unix())
|
newImage.Created = int(image.Created.Unix())
|
||||||
out.SetInt64("Size", image.Size)
|
newImage.Size = int(image.Size)
|
||||||
out.SetInt64("VirtualSize", image.GetParentsSize(0)+image.Size)
|
newImage.VirtualSize = int(image.GetParentsSize(0) + image.Size)
|
||||||
out.SetJson("Labels", image.ContainerConfig.Labels)
|
newImage.Labels = image.ContainerConfig.Labels
|
||||||
outs.Add(out)
|
|
||||||
|
images = append(images, newImage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outs.ReverseSort()
|
sort.Sort(sort.Reverse(ByCreated(images)))
|
||||||
if _, err := outs.WriteListTo(job.Stdout); err != nil {
|
|
||||||
|
if err = json.NewEncoder(job.Stdout).Encode(images); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Add table
Reference in a new issue