Browse code

Group published and exposed ports by contiguous ranges

Signed-off-by: Colm Hally <colmhally@gmail.com>

Colm Hally authored on 2015/01/28 21:56:22
Showing 2 changed files
... ...
@@ -29,21 +29,78 @@ func ValidateHost(val string) (string, error) {
29 29
 	return host, nil
30 30
 }
31 31
 
32
-//TODO remove, used on < 1.5 in getContainersJSON
32
+// TODO remove, used on < 1.5 in getContainersJSON
33 33
 func DisplayablePorts(ports *engine.Table) string {
34
-	result := []string{}
35
-	ports.SetKey("PublicPort")
34
+	var (
35
+		result          = []string{}
36
+		hostMappings    = []string{}
37
+		startOfGroupMap map[string]int
38
+		lastInGroupMap  map[string]int
39
+	)
40
+	startOfGroupMap = make(map[string]int)
41
+	lastInGroupMap = make(map[string]int)
42
+	ports.SetKey("PrivatePort")
36 43
 	ports.Sort()
37 44
 	for _, port := range ports.Data {
38
-		if port.Get("IP") == "" {
39
-			result = append(result, fmt.Sprintf("%d/%s", port.GetInt("PrivatePort"), port.Get("Type")))
40
-		} else {
41
-			result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.Get("IP"), port.GetInt("PublicPort"), port.GetInt("PrivatePort"), port.Get("Type")))
45
+		var (
46
+			current      = port.GetInt("PrivatePort")
47
+			portKey      = port.Get("Type")
48
+			startOfGroup int
49
+			lastInGroup  int
50
+		)
51
+		if port.Get("IP") != "" {
52
+			if port.GetInt("PublicPort") != current {
53
+				hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.Get("IP"), port.GetInt("PublicPort"), port.GetInt("PrivatePort"), port.Get("Type")))
54
+				continue
55
+			}
56
+			portKey = fmt.Sprintf("%s/%s", port.Get("IP"), port.Get("Type"))
42 57
 		}
58
+		startOfGroup = startOfGroupMap[portKey]
59
+		lastInGroup = lastInGroupMap[portKey]
60
+
61
+		if startOfGroup == 0 {
62
+			startOfGroupMap[portKey] = current
63
+			lastInGroupMap[portKey] = current
64
+			continue
65
+		}
66
+
67
+		if current == (lastInGroup + 1) {
68
+			lastInGroupMap[portKey] = current
69
+			continue
70
+		}
71
+		result = append(result, FormGroup(portKey, startOfGroup, lastInGroup))
72
+		startOfGroupMap[portKey] = current
73
+		lastInGroupMap[portKey] = current
74
+	}
75
+	for portKey, startOfGroup := range startOfGroupMap {
76
+		result = append(result, FormGroup(portKey, startOfGroup, lastInGroupMap[portKey]))
43 77
 	}
78
+	result = append(result, hostMappings...)
44 79
 	return strings.Join(result, ", ")
45 80
 }
46 81
 
82
+func FormGroup(key string, start, last int) string {
83
+	var (
84
+		group     string
85
+		parts     = strings.Split(key, "/")
86
+		groupType = parts[0]
87
+		ip        = ""
88
+	)
89
+	if len(parts) > 1 {
90
+		ip = parts[0]
91
+		groupType = parts[1]
92
+	}
93
+	if start == last {
94
+		group = fmt.Sprintf("%d", start)
95
+	} else {
96
+		group = fmt.Sprintf("%d-%d", start, last)
97
+	}
98
+	if ip != "" {
99
+		group = fmt.Sprintf("%s:%s->%s", ip, group, group)
100
+	}
101
+	return fmt.Sprintf("%s/%s", group, groupType)
102
+}
103
+
47 104
 func MatchesContentType(contentType, expectedType string) bool {
48 105
 	mimetype, _, err := mime.ParseMediaType(contentType)
49 106
 	if err != nil {
... ...
@@ -1438,13 +1438,15 @@ The `docker rename` command allows the container to be renamed to a different na
1438 1438
 Running `docker ps --no-trunc` showing 2 linked containers.
1439 1439
 
1440 1440
     $ sudo docker ps
1441
-    CONTAINER ID                                                            IMAGE                        COMMAND                CREATED              STATUS              PORTS               NAMES
1442
-    f7ee772232194fcc088c6bdec6ea09f7b3f6c54d53934658164b8602d7cd4744        ubuntu:12.04                 bash                   17 seconds ago       Up 16 seconds                           webapp
1443
-    d0963715a061c7c7b7cc80b2646da913a959fbf13e80a971d4a60f6997a2f595        crosbymichael/redis:latest   /redis-server --dir    33 minutes ago       Up 33 minutes       6379/tcp            redis,webapp/db
1441
+    CONTAINER ID        IMAGE                        COMMAND                CREATED              STATUS              PORTS               NAMES
1442
+    4c01db0b339c        ubuntu:12.04                 bash                   17 seconds ago       Up 16 seconds       3300-3310/tcp       webapp
1443
+    d7886598dbe2        crosbymichael/redis:latest   /redis-server --dir    33 minutes ago       Up 33 minutes       6379/tcp            redis,webapp/db
1444 1444
 
1445 1445
 `docker ps` will show only running containers by default. To see all containers:
1446 1446
 `docker ps -a`
1447 1447
 
1448
+`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.
1449
+
1448 1450
 #### Filtering
1449 1451
 
1450 1452
 The filtering flag (`-f` or `--filter)` format is a `key=value` pair. If there is more