Procházet zdrojové kódy

Group published and exposed ports by contiguous ranges

Signed-off-by: Colm Hally <colmhally@gmail.com>
Colm Hally před 10 roky
rodič
revize
5dfef4fe08
2 změnil soubory, kde provedl 69 přidání a 10 odebrání
  1. 64 7
      api/common.go
  2. 5 3
      docs/sources/reference/commandline/cli.md

+ 64 - 7
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 {

+ 5 - 3
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