List all ports when calling docker port container

Docker-DCO-1.1-Signed-off-by: SvenDowideit <SvenDowideit@home.org.au> (github: SvenDowideit)
This commit is contained in:
SvenDowideit 2014-06-24 12:03:08 +10:00
parent 6eaac7d571
commit 4e340cedec
4 changed files with 191 additions and 25 deletions

View file

@ -861,26 +861,15 @@ func (cli *DockerCli) CmdTop(args ...string) error {
}
func (cli *DockerCli) CmdPort(args ...string) error {
cmd := cli.Subcmd("port", "CONTAINER PRIVATE_PORT", "Lookup the public-facing port that is NAT-ed to PRIVATE_PORT")
cmd := cli.Subcmd("port", "CONTAINER [PRIVATE_PORT[/PROTO]]", "List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT")
if err := cmd.Parse(args); err != nil {
return nil
}
if cmd.NArg() != 2 {
if cmd.NArg() < 1 {
cmd.Usage()
return nil
}
var (
port = cmd.Arg(1)
proto = "tcp"
parts = strings.SplitN(port, "/", 2)
)
if len(parts) == 2 && len(parts[1]) != 0 {
port = parts[0]
proto = parts[1]
}
steam, _, err := cli.call("GET", "/containers/"+cmd.Arg(0)+"/json", nil, false)
if err != nil {
return err
@ -895,14 +884,34 @@ func (cli *DockerCli) CmdPort(args ...string) error {
return err
}
if frontends, exists := ports[nat.Port(port+"/"+proto)]; exists && frontends != nil {
for _, frontend := range frontends {
fmt.Fprintf(cli.out, "%s:%s\n", frontend.HostIp, frontend.HostPort)
if cmd.NArg() == 2 {
var (
port = cmd.Arg(1)
proto = "tcp"
parts = strings.SplitN(port, "/", 2)
)
if len(parts) == 2 && len(parts[1]) != 0 {
port = parts[0]
proto = parts[1]
}
return nil
natPort := port + "/" + proto
if frontends, exists := ports[nat.Port(port+"/"+proto)]; exists && frontends != nil {
for _, frontend := range frontends {
fmt.Fprintf(cli.out, "%s:%s\n", frontend.HostIp, frontend.HostPort)
}
return nil
}
return fmt.Errorf("Error: No public port '%s' published for %s", natPort, cmd.Arg(0))
}
return fmt.Errorf("Error: No public port '%s' published for %s", cmd.Arg(1), cmd.Arg(0))
for from, frontends := range ports {
for _, frontend := range frontends {
fmt.Fprintf(cli.out, "%s -> %s:%s\n", from, frontend.HostIp, frontend.HostPort)
}
}
return nil
}
// 'docker rmi IMAGE' removes all images with the name IMAGE

View file

@ -2,14 +2,30 @@
% Docker Community
% JUNE 2014
# NAME
docker-port - Lookup the public-facing port that is NAT-ed to PRIVATE_PORT
docker-port - List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT
# SYNOPSIS
**docker port**
CONTAINER PRIVATE_PORT
**docker port** CONTAINER [PRIVATE_PORT[/PROTO]]
# OPTIONS
There are no available options.
# DESCRIPTION
List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT
# EXAMPLES
You can find out all the ports mapped by not specifying a `PRIVATE_PORT`, or
ask for just a specific mapping:
$ docker ps test
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b650456536c7 busybox:latest top 54 minutes ago Up 54 minutes 0.0.0.0:1234->9876/tcp, 0.0.0.0:4321->7890/tcp test
$ docker port test
7890/tcp -> 0.0.0.0:4321
9876/tcp -> 0.0.0.0:1234
$ docker port test 7890/tcp
0.0.0.0:4321
$ docker port test 7890/udp
2014/06/24 11:53:36 Error: No public port '7890/udp' published for test
$ docker port test 7890
0.0.0.0:4321
# HISTORY
April 2014, Originally compiled by William Henry (whenry at redhat dot com)

View file

@ -764,9 +764,25 @@ log entry.
## port
Usage: docker port CONTAINER PRIVATE_PORT
Usage: docker port CONTAINER [PRIVATE_PORT[/PROTO]]
Lookup the public-facing port that is NAT-ed to PRIVATE_PORT
List port mappings for the CONTAINER, or lookup the public-facing port that is NAT-ed to the PRIVATE_PORT
You can find out all the ports mapped by not specifying a `PRIVATE_PORT`, or
just a specific mapping:
$ docker ps test
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b650456536c7 busybox:latest top 54 minutes ago Up 54 minutes 0.0.0.0:1234->9876/tcp, 0.0.0.0:4321->7890/tcp test
$ docker port test
7890/tcp -> 0.0.0.0:4321
9876/tcp -> 0.0.0.0:1234
$ docker port test 7890/tcp
0.0.0.0:4321
$ docker port test 7890/udp
2014/06/24 11:53:36 Error: No public port '7890/udp' published for test
$ docker port test 7890
0.0.0.0:4321
## pause

View file

@ -0,0 +1,125 @@
package main
import (
"os/exec"
"sort"
"strings"
"testing"
)
func TestListPorts(t *testing.T) {
// one port
runCmd := exec.Command(dockerBinary, "run", "-d", "-p", "9876:80", "busybox", "top")
out, _, err := runCommandWithOutput(runCmd)
errorOut(err, t, out)
firstID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "port", firstID, "80")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if !assertPortList(t, out, []string{"0.0.0.0:9876"}) {
t.Error("Port list is not correct")
}
runCmd = exec.Command(dockerBinary, "port", firstID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if !assertPortList(t, out, []string{"80/tcp -> 0.0.0.0:9876"}) {
t.Error("Port list is not correct")
}
runCmd = exec.Command(dockerBinary, "rm", "-f", firstID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
// three port
runCmd = exec.Command(dockerBinary, "run", "-d",
"-p", "9876:80",
"-p", "9877:81",
"-p", "9878:82",
"busybox", "top")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
ID := stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "port", ID, "80")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if !assertPortList(t, out, []string{"0.0.0.0:9876"}) {
t.Error("Port list is not correct")
}
runCmd = exec.Command(dockerBinary, "port", ID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if !assertPortList(t, out, []string{
"80/tcp -> 0.0.0.0:9876",
"81/tcp -> 0.0.0.0:9877",
"82/tcp -> 0.0.0.0:9878"}) {
t.Error("Port list is not correct")
}
runCmd = exec.Command(dockerBinary, "rm", "-f", ID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
// more and one port mapped to the same container port
runCmd = exec.Command(dockerBinary, "run", "-d",
"-p", "9876:80",
"-p", "9999:80",
"-p", "9877:81",
"-p", "9878:82",
"busybox", "top")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
ID = stripTrailingCharacters(out)
runCmd = exec.Command(dockerBinary, "port", ID, "80")
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if !assertPortList(t, out, []string{"0.0.0.0:9876", "0.0.0.0:9999"}) {
t.Error("Port list is not correct")
}
runCmd = exec.Command(dockerBinary, "port", ID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
if !assertPortList(t, out, []string{
"80/tcp -> 0.0.0.0:9876",
"80/tcp -> 0.0.0.0:9999",
"81/tcp -> 0.0.0.0:9877",
"82/tcp -> 0.0.0.0:9878"}) {
t.Error("Port list is not correct\n", out)
}
runCmd = exec.Command(dockerBinary, "rm", "-f", ID)
out, _, err = runCommandWithOutput(runCmd)
errorOut(err, t, out)
deleteAllContainers()
logDone("port - test port list")
}
func assertPortList(t *testing.T, out string, expected []string) bool {
//lines := strings.Split(out, "\n")
lines := strings.Split(strings.Trim(out, "\n "), "\n")
if len(lines) != len(expected) {
t.Errorf("different size lists %s, %d, %d", out, len(lines), len(expected))
return false
}
sort.Strings(lines)
sort.Strings(expected)
for i := 0; i < len(expected); i++ {
if lines[i] != expected[i] {
t.Error("|" + lines[i] + "!=" + expected[i] + "|")
return false
}
}
return true
}