diff --git a/api_params.go b/api_params.go index df879f63ee..43a536d601 100644 --- a/api_params.go +++ b/api_params.go @@ -1,5 +1,7 @@ package docker +import "encoding/json" + type APIHistory struct { ID string `json:"Id"` Tags []string `json:",omitempty"` @@ -47,7 +49,7 @@ type APIContainers struct { Command string Created int64 Status string - Ports string + Ports []APIPort SizeRw int64 SizeRootFs int64 } @@ -67,7 +69,17 @@ type APIRun struct { } type APIPort struct { - Port string + PrivatePort int64 + PublicPort int64 + Type string +} + +func (port *APIPort) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]interface{}{ + "PrivatePort": port.PrivatePort, + "PublicPort": port.PublicPort, + "Type": port.Type, + }) } type APIVersion struct { diff --git a/commands.go b/commands.go index b2a4d3db13..5ca8309f4f 100644 --- a/commands.go +++ b/commands.go @@ -21,6 +21,7 @@ import ( "path/filepath" "reflect" "runtime" + "sort" "strconv" "strings" "syscall" @@ -958,6 +959,19 @@ func (cli *DockerCli) CmdImages(args ...string) error { return nil } +func displayablePorts(ports []APIPort) string { + result := []string{} + for _, port := range ports { + if port.Type == "tcp" { + result = append(result, fmt.Sprintf("%d->%d", port.PublicPort, port.PrivatePort)) + } else { + result = append(result, fmt.Sprintf("%d->%d/%s", port.PublicPort, port.PrivatePort, port.Type)) + } + } + sort.Strings(result) + return strings.Join(result, ", ") +} + func (cli *DockerCli) CmdPs(args ...string) error { cmd := Subcmd("ps", "[OPTIONS]", "List containers") quiet := cmd.Bool("q", false, "Only display numeric IDs") @@ -1015,9 +1029,9 @@ func (cli *DockerCli) CmdPs(args ...string) error { for _, out := range outs { if !*quiet { if *noTrunc { - fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t", out.ID, out.Image, out.Command, utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Status, out.Ports) + fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t", out.ID, out.Image, out.Command, utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Status, displayablePorts(out.Ports)) } else { - fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t", utils.TruncateID(out.ID), out.Image, utils.Trunc(out.Command, 20), utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Status, out.Ports) + fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t", utils.TruncateID(out.ID), out.Image, utils.Trunc(out.Command, 20), utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Status, displayablePorts(out.Ports)) } if *size { if out.SizeRootFs > 0 { diff --git a/container.go b/container.go index 39c19c53d4..5122fd7fcf 100644 --- a/container.go +++ b/container.go @@ -15,7 +15,6 @@ import ( "os/exec" "path" "path/filepath" - "sort" "strconv" "strings" "syscall" @@ -253,17 +252,28 @@ type NetworkSettings struct { PortMapping map[string]PortMapping } -// String returns a human-readable description of the port mapping defined in the settings -func (settings *NetworkSettings) PortMappingHuman() string { - var mapping []string +// returns a more easy to process description of the port mapping defined in the settings +func (settings *NetworkSettings) PortMappingAPI() []APIPort { + var mapping []APIPort for private, public := range settings.PortMapping["Tcp"] { - mapping = append(mapping, fmt.Sprintf("%s->%s", public, private)) + pubint, _ := strconv.ParseInt(public, 0, 0) + privint, _ := strconv.ParseInt(private, 0, 0) + mapping = append(mapping, APIPort{ + PrivatePort: privint, + PublicPort: pubint, + Type: "tcp", + }) } for private, public := range settings.PortMapping["Udp"] { - mapping = append(mapping, fmt.Sprintf("%s->%s/udp", public, private)) + pubint, _ := strconv.ParseInt(public, 0, 0) + privint, _ := strconv.ParseInt(private, 0, 0) + mapping = append(mapping, APIPort{ + PrivatePort: privint, + PublicPort: pubint, + Type: "udp", + }) } - sort.Strings(mapping) - return strings.Join(mapping, ", ") + return mapping } // Inject the io.Reader at the given path. Note: do not close the reader diff --git a/server.go b/server.go index 646cb44877..386f0e27b4 100644 --- a/server.go +++ b/server.go @@ -386,7 +386,7 @@ func (srv *Server) Containers(all, size bool, n int, since, before string) []API 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.PortMappingHuman() + c.Ports = container.NetworkSettings.PortMappingAPI() if size { c.SizeRw, c.SizeRootFs = container.GetSize() }