From 5dfef4fe08b890022f600fe742e5a4372b023767 Mon Sep 17 00:00:00 2001 From: Colm Hally Date: Wed, 28 Jan 2015 12:56:22 +0000 Subject: [PATCH 1/2] Group published and exposed ports by contiguous ranges Signed-off-by: Colm Hally --- api/common.go | 71 ++++++++++++++++++++--- docs/sources/reference/commandline/cli.md | 8 ++- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/api/common.go b/api/common.go index 4d8296df8..a8dc1a82a 100644 --- a/api/common.go +++ b/api/common.go @@ -29,21 +29,78 @@ func ValidateHost(val string) (string, error) { return host, nil } -//TODO remove, used on < 1.5 in getContainersJSON +// TODO remove, used on < 1.5 in getContainersJSON func DisplayablePorts(ports *engine.Table) string { - result := []string{} - ports.SetKey("PublicPort") + var ( + result = []string{} + hostMappings = []string{} + startOfGroupMap map[string]int + lastInGroupMap map[string]int + ) + startOfGroupMap = make(map[string]int) + lastInGroupMap = make(map[string]int) + ports.SetKey("PrivatePort") ports.Sort() for _, port := range ports.Data { - if port.Get("IP") == "" { - result = append(result, fmt.Sprintf("%d/%s", port.GetInt("PrivatePort"), port.Get("Type"))) - } else { - result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.Get("IP"), port.GetInt("PublicPort"), port.GetInt("PrivatePort"), port.Get("Type"))) + var ( + current = port.GetInt("PrivatePort") + portKey = port.Get("Type") + startOfGroup int + lastInGroup int + ) + if port.Get("IP") != "" { + if port.GetInt("PublicPort") != current { + hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.Get("IP"), port.GetInt("PublicPort"), port.GetInt("PrivatePort"), port.Get("Type"))) + continue + } + portKey = fmt.Sprintf("%s/%s", port.Get("IP"), port.Get("Type")) } + startOfGroup = startOfGroupMap[portKey] + lastInGroup = lastInGroupMap[portKey] + + if startOfGroup == 0 { + startOfGroupMap[portKey] = current + lastInGroupMap[portKey] = current + continue + } + + if current == (lastInGroup + 1) { + lastInGroupMap[portKey] = current + continue + } + result = append(result, FormGroup(portKey, startOfGroup, lastInGroup)) + startOfGroupMap[portKey] = current + lastInGroupMap[portKey] = current } + for portKey, startOfGroup := range startOfGroupMap { + result = append(result, FormGroup(portKey, startOfGroup, lastInGroupMap[portKey])) + } + result = append(result, hostMappings...) return strings.Join(result, ", ") } +func FormGroup(key string, start, last int) string { + var ( + group string + parts = strings.Split(key, "/") + groupType = parts[0] + ip = "" + ) + if len(parts) > 1 { + ip = parts[0] + groupType = parts[1] + } + if start == last { + group = fmt.Sprintf("%d", start) + } else { + group = fmt.Sprintf("%d-%d", start, last) + } + if ip != "" { + group = fmt.Sprintf("%s:%s->%s", ip, group, group) + } + return fmt.Sprintf("%s/%s", group, groupType) +} + func MatchesContentType(contentType, expectedType string) bool { mimetype, _, err := mime.ParseMediaType(contentType) if err != nil { diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 16d5ea0c8..9b3376eee 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -1438,13 +1438,15 @@ The `docker rename` command allows the container to be renamed to a different na Running `docker ps --no-trunc` showing 2 linked containers. $ sudo docker ps - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - f7ee772232194fcc088c6bdec6ea09f7b3f6c54d53934658164b8602d7cd4744 ubuntu:12.04 bash 17 seconds ago Up 16 seconds webapp - d0963715a061c7c7b7cc80b2646da913a959fbf13e80a971d4a60f6997a2f595 crosbymichael/redis:latest /redis-server --dir 33 minutes ago Up 33 minutes 6379/tcp redis,webapp/db + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 4c01db0b339c ubuntu:12.04 bash 17 seconds ago Up 16 seconds 3300-3310/tcp webapp + d7886598dbe2 crosbymichael/redis:latest /redis-server --dir 33 minutes ago Up 33 minutes 6379/tcp redis,webapp/db `docker ps` will show only running containers by default. To see all containers: `docker ps -a` +`docker ps` will group exposed ports into a single range if possible. E.g., a container that exposes TCP ports `100, 101, 102` will display `100-102/tcp` in the `PORTS` column. + #### Filtering The filtering flag (`-f` or `--filter)` format is a `key=value` pair. If there is more From ba99a73c2fc3050475bd6c066c32dcb557cf6f25 Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Mon, 16 Feb 2015 11:08:32 -0800 Subject: [PATCH 2/2] fix naming, add a test for port range on docker ps Docker-DCO-1.1-Signed-off-by: Jessie Frazelle (github: jfrazelle) --- api/common.go | 20 ++++++++++---------- integration-cli/docker_cli_ps_test.go | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/api/common.go b/api/common.go index a8dc1a82a..9e85c5ec3 100644 --- a/api/common.go +++ b/api/common.go @@ -34,10 +34,10 @@ func DisplayablePorts(ports *engine.Table) string { var ( result = []string{} hostMappings = []string{} - startOfGroupMap map[string]int + firstInGroupMap map[string]int lastInGroupMap map[string]int ) - startOfGroupMap = make(map[string]int) + firstInGroupMap = make(map[string]int) lastInGroupMap = make(map[string]int) ports.SetKey("PrivatePort") ports.Sort() @@ -45,7 +45,7 @@ func DisplayablePorts(ports *engine.Table) string { var ( current = port.GetInt("PrivatePort") portKey = port.Get("Type") - startOfGroup int + firstInGroup int lastInGroup int ) if port.Get("IP") != "" { @@ -55,11 +55,11 @@ func DisplayablePorts(ports *engine.Table) string { } portKey = fmt.Sprintf("%s/%s", port.Get("IP"), port.Get("Type")) } - startOfGroup = startOfGroupMap[portKey] + firstInGroup = firstInGroupMap[portKey] lastInGroup = lastInGroupMap[portKey] - if startOfGroup == 0 { - startOfGroupMap[portKey] = current + if firstInGroup == 0 { + firstInGroupMap[portKey] = current lastInGroupMap[portKey] = current continue } @@ -68,12 +68,12 @@ func DisplayablePorts(ports *engine.Table) string { lastInGroupMap[portKey] = current continue } - result = append(result, FormGroup(portKey, startOfGroup, lastInGroup)) - startOfGroupMap[portKey] = current + result = append(result, FormGroup(portKey, firstInGroup, lastInGroup)) + firstInGroupMap[portKey] = current lastInGroupMap[portKey] = current } - for portKey, startOfGroup := range startOfGroupMap { - result = append(result, FormGroup(portKey, startOfGroup, lastInGroupMap[portKey])) + for portKey, firstInGroup := range firstInGroupMap { + result = append(result, FormGroup(portKey, firstInGroup, lastInGroupMap[portKey])) } result = append(result, hostMappings...) return strings.Join(result, ", ") diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index b92c80416..e171ac003 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -566,3 +566,25 @@ func TestPsLinkedWithNoTrunc(t *testing.T) { t.Fatalf("Expected array: %v, got: %v", expected, names) } } + +func TestPsGroupPortRange(t *testing.T) { + defer deleteAllContainers() + + portRange := "3300-3900" + out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "--name", "porttest", "-p", portRange+":"+portRange, "busybox", "top")) + if err != nil { + t.Fatal(out, err) + } + + out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "ps")) + if err != nil { + t.Fatal(out, err) + } + + // check that the port range is in the output + if !strings.Contains(string(out), portRange) { + t.Fatalf("docker ps output should have had the port range %q: %s", portRange, string(out)) + } + + logDone("ps - port range") +}