| ... | ... |
@@ -1,5 +1,7 @@ |
| 1 | 1 |
package docker |
| 2 | 2 |
|
| 3 |
+import "encoding/json" |
|
| 4 |
+ |
|
| 3 | 5 |
type APIHistory struct {
|
| 4 | 6 |
ID string `json:"Id"` |
| 5 | 7 |
Tags []string `json:",omitempty"` |
| ... | ... |
@@ -47,7 +49,7 @@ type APIContainers struct {
|
| 47 | 47 |
Command string |
| 48 | 48 |
Created int64 |
| 49 | 49 |
Status string |
| 50 |
- Ports string |
|
| 50 |
+ Ports []APIPort |
|
| 51 | 51 |
SizeRw int64 |
| 52 | 52 |
SizeRootFs int64 |
| 53 | 53 |
} |
| ... | ... |
@@ -67,7 +69,17 @@ type APIRun struct {
|
| 67 | 67 |
} |
| 68 | 68 |
|
| 69 | 69 |
type APIPort struct {
|
| 70 |
- Port string |
|
| 70 |
+ PrivatePort int64 |
|
| 71 |
+ PublicPort int64 |
|
| 72 |
+ Type string |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+func (port *APIPort) MarshalJSON() ([]byte, error) {
|
|
| 76 |
+ return json.Marshal(map[string]interface{}{
|
|
| 77 |
+ "PrivatePort": port.PrivatePort, |
|
| 78 |
+ "PublicPort": port.PublicPort, |
|
| 79 |
+ "Type": port.Type, |
|
| 80 |
+ }) |
|
| 71 | 81 |
} |
| 72 | 82 |
|
| 73 | 83 |
type APIVersion struct {
|
| ... | ... |
@@ -20,6 +20,7 @@ import ( |
| 20 | 20 |
"path/filepath" |
| 21 | 21 |
"reflect" |
| 22 | 22 |
"runtime" |
| 23 |
+ "sort" |
|
| 23 | 24 |
"strconv" |
| 24 | 25 |
"strings" |
| 25 | 26 |
"syscall" |
| ... | ... |
@@ -996,6 +997,19 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
| 996 | 996 |
return nil |
| 997 | 997 |
} |
| 998 | 998 |
|
| 999 |
+func displayablePorts(ports []APIPort) string {
|
|
| 1000 |
+ result := []string{}
|
|
| 1001 |
+ for _, port := range ports {
|
|
| 1002 |
+ if port.Type == "tcp" {
|
|
| 1003 |
+ result = append(result, fmt.Sprintf("%d->%d", port.PublicPort, port.PrivatePort))
|
|
| 1004 |
+ } else {
|
|
| 1005 |
+ result = append(result, fmt.Sprintf("%d->%d/%s", port.PublicPort, port.PrivatePort, port.Type))
|
|
| 1006 |
+ } |
|
| 1007 |
+ } |
|
| 1008 |
+ sort.Strings(result) |
|
| 1009 |
+ return strings.Join(result, ", ") |
|
| 1010 |
+} |
|
| 1011 |
+ |
|
| 999 | 1012 |
func (cli *DockerCli) CmdPs(args ...string) error {
|
| 1000 | 1013 |
cmd := Subcmd("ps", "[OPTIONS]", "List containers")
|
| 1001 | 1014 |
quiet := cmd.Bool("q", false, "Only display numeric IDs")
|
| ... | ... |
@@ -1053,9 +1067,9 @@ func (cli *DockerCli) CmdPs(args ...string) error {
|
| 1053 | 1053 |
for _, out := range outs {
|
| 1054 | 1054 |
if !*quiet {
|
| 1055 | 1055 |
if *noTrunc {
|
| 1056 |
- 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) |
|
| 1056 |
+ 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)) |
|
| 1057 | 1057 |
} else {
|
| 1058 |
- 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) |
|
| 1058 |
+ 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)) |
|
| 1059 | 1059 |
} |
| 1060 | 1060 |
if *size {
|
| 1061 | 1061 |
if out.SizeRootFs > 0 {
|
| ... | ... |
@@ -15,7 +15,6 @@ import ( |
| 15 | 15 |
"os/exec" |
| 16 | 16 |
"path" |
| 17 | 17 |
"path/filepath" |
| 18 |
- "sort" |
|
| 19 | 18 |
"strconv" |
| 20 | 19 |
"strings" |
| 21 | 20 |
"syscall" |
| ... | ... |
@@ -253,17 +252,28 @@ type NetworkSettings struct {
|
| 253 | 253 |
PortMapping map[string]PortMapping |
| 254 | 254 |
} |
| 255 | 255 |
|
| 256 |
-// String returns a human-readable description of the port mapping defined in the settings |
|
| 257 |
-func (settings *NetworkSettings) PortMappingHuman() string {
|
|
| 258 |
- var mapping []string |
|
| 256 |
+// returns a more easy to process description of the port mapping defined in the settings |
|
| 257 |
+func (settings *NetworkSettings) PortMappingAPI() []APIPort {
|
|
| 258 |
+ var mapping []APIPort |
|
| 259 | 259 |
for private, public := range settings.PortMapping["Tcp"] {
|
| 260 |
- mapping = append(mapping, fmt.Sprintf("%s->%s", public, private))
|
|
| 260 |
+ pubint, _ := strconv.ParseInt(public, 0, 0) |
|
| 261 |
+ privint, _ := strconv.ParseInt(private, 0, 0) |
|
| 262 |
+ mapping = append(mapping, APIPort{
|
|
| 263 |
+ PrivatePort: privint, |
|
| 264 |
+ PublicPort: pubint, |
|
| 265 |
+ Type: "tcp", |
|
| 266 |
+ }) |
|
| 261 | 267 |
} |
| 262 | 268 |
for private, public := range settings.PortMapping["Udp"] {
|
| 263 |
- mapping = append(mapping, fmt.Sprintf("%s->%s/udp", public, private))
|
|
| 269 |
+ pubint, _ := strconv.ParseInt(public, 0, 0) |
|
| 270 |
+ privint, _ := strconv.ParseInt(private, 0, 0) |
|
| 271 |
+ mapping = append(mapping, APIPort{
|
|
| 272 |
+ PrivatePort: privint, |
|
| 273 |
+ PublicPort: pubint, |
|
| 274 |
+ Type: "udp", |
|
| 275 |
+ }) |
|
| 264 | 276 |
} |
| 265 |
- sort.Strings(mapping) |
|
| 266 |
- return strings.Join(mapping, ", ") |
|
| 277 |
+ return mapping |
|
| 267 | 278 |
} |
| 268 | 279 |
|
| 269 | 280 |
// Inject the io.Reader at the given path. Note: do not close the reader |
| ... | ... |
@@ -386,7 +386,7 @@ func (srv *Server) Containers(all, size bool, n int, since, before string) []API |
| 386 | 386 |
c.Command = fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
|
| 387 | 387 |
c.Created = container.Created.Unix() |
| 388 | 388 |
c.Status = container.State.String() |
| 389 |
- c.Ports = container.NetworkSettings.PortMappingHuman() |
|
| 389 |
+ c.Ports = container.NetworkSettings.PortMappingAPI() |
|
| 390 | 390 |
if size {
|
| 391 | 391 |
c.SizeRw, c.SizeRootFs = container.GetSize() |
| 392 | 392 |
} |
| ... | ... |
@@ -27,10 +27,9 @@ func setupWorkingDirectory(workdir string) {
|
| 27 | 27 |
if workdir == "" {
|
| 28 | 28 |
return |
| 29 | 29 |
} |
| 30 |
- syscall.Chdir(workdir) |
|
| 30 |
+ syscall.Chdir(workdir) |
|
| 31 | 31 |
} |
| 32 | 32 |
|
| 33 |
- |
|
| 34 | 33 |
// Takes care of dropping privileges to the desired user |
| 35 | 34 |
func changeUser(u string) {
|
| 36 | 35 |
if u == "" {
|