More descriptive, easier to process container portmappings information in the API

This commit is contained in:
shin- 2013-08-28 00:20:35 +02:00
parent 4a3b039c2a
commit 98018df078
6 changed files with 50 additions and 16 deletions

View file

@ -1,5 +1,7 @@
package docker package docker
import "encoding/json"
type APIHistory struct { type APIHistory struct {
ID string `json:"Id"` ID string `json:"Id"`
Tags []string `json:",omitempty"` Tags []string `json:",omitempty"`
@ -47,7 +49,7 @@ type APIContainers struct {
Command string Command string
Created int64 Created int64
Status string Status string
Ports string Ports []APIPort
SizeRw int64 SizeRw int64
SizeRootFs int64 SizeRootFs int64
} }
@ -67,7 +69,17 @@ type APIRun struct {
} }
type APIPort 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 { type APIVersion struct {

View file

@ -20,6 +20,7 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"runtime" "runtime"
"sort"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
@ -996,6 +997,19 @@ func (cli *DockerCli) CmdImages(args ...string) error {
return nil 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 { func (cli *DockerCli) CmdPs(args ...string) error {
cmd := Subcmd("ps", "[OPTIONS]", "List containers") cmd := Subcmd("ps", "[OPTIONS]", "List containers")
quiet := cmd.Bool("q", false, "Only display numeric IDs") quiet := cmd.Bool("q", false, "Only display numeric IDs")
@ -1053,9 +1067,9 @@ func (cli *DockerCli) CmdPs(args ...string) error {
for _, out := range outs { for _, out := range outs {
if !*quiet { if !*quiet {
if *noTrunc { 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 { } 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 *size {
if out.SizeRootFs > 0 { if out.SizeRootFs > 0 {

View file

@ -152,7 +152,6 @@ func TestRunWorkdirExists(t *testing.T) {
} }
func TestRunExit(t *testing.T) { func TestRunExit(t *testing.T) {
stdin, stdinPipe := io.Pipe() stdin, stdinPipe := io.Pipe()
stdout, stdoutPipe := io.Pipe() stdout, stdoutPipe := io.Pipe()

View file

@ -15,7 +15,6 @@ import (
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"sort"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
@ -253,17 +252,28 @@ type NetworkSettings struct {
PortMapping map[string]PortMapping PortMapping map[string]PortMapping
} }
// String returns a human-readable description of the port mapping defined in the settings // returns a more easy to process description of the port mapping defined in the settings
func (settings *NetworkSettings) PortMappingHuman() string { func (settings *NetworkSettings) PortMappingAPI() []APIPort {
var mapping []string var mapping []APIPort
for private, public := range settings.PortMapping["Tcp"] { 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"] { 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 mapping
return strings.Join(mapping, ", ")
} }
// Inject the io.Reader at the given path. Note: do not close the reader // Inject the io.Reader at the given path. Note: do not close the reader

View file

@ -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.Command = fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
c.Created = container.Created.Unix() c.Created = container.Created.Unix()
c.Status = container.State.String() c.Status = container.State.String()
c.Ports = container.NetworkSettings.PortMappingHuman() c.Ports = container.NetworkSettings.PortMappingAPI()
if size { if size {
c.SizeRw, c.SizeRootFs = container.GetSize() c.SizeRw, c.SizeRootFs = container.GetSize()
} }

View file

@ -27,10 +27,9 @@ func setupWorkingDirectory(workdir string) {
if workdir == "" { if workdir == "" {
return return
} }
syscall.Chdir(workdir) syscall.Chdir(workdir)
} }
// Takes care of dropping privileges to the desired user // Takes care of dropping privileges to the desired user
func changeUser(u string) { func changeUser(u string) {
if u == "" { if u == "" {