mirror of
				https://github.com/docker/compose.git
				synced 2025-11-04 13:44:48 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			111 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package formatter
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"sort"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/docker/api/containers"
 | 
						|
)
 | 
						|
 | 
						|
type portGroup struct {
 | 
						|
	first uint32
 | 
						|
	last  uint32
 | 
						|
}
 | 
						|
 | 
						|
// PortsString returns a human readable published ports
 | 
						|
func PortsString(ports []containers.Port) string {
 | 
						|
	groupMap := make(map[string]*portGroup)
 | 
						|
	var (
 | 
						|
		result       []string
 | 
						|
		hostMappings []string
 | 
						|
		groupMapKeys []string
 | 
						|
	)
 | 
						|
 | 
						|
	sort.Slice(ports, func(i int, j int) bool {
 | 
						|
		return comparePorts(ports[i], ports[j])
 | 
						|
	})
 | 
						|
 | 
						|
	for _, port := range ports {
 | 
						|
		// Simple case: HOST_IP:PORT1:PORT2
 | 
						|
		hostIP := "0.0.0.0"
 | 
						|
		if port.HostIP != "" {
 | 
						|
			hostIP = port.HostIP
 | 
						|
		}
 | 
						|
 | 
						|
		if port.HostPort != port.ContainerPort {
 | 
						|
			hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", hostIP, port.HostPort, port.ContainerPort, port.Protocol))
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		current := port.ContainerPort
 | 
						|
		portKey := fmt.Sprintf("%s/%s", hostIP, port.Protocol)
 | 
						|
		group := groupMap[portKey]
 | 
						|
 | 
						|
		if group == nil {
 | 
						|
			groupMap[portKey] = &portGroup{first: current, last: current}
 | 
						|
			// record order that groupMap keys are created
 | 
						|
			groupMapKeys = append(groupMapKeys, portKey)
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		if current == (group.last + 1) {
 | 
						|
			group.last = current
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		result = append(result, formGroup(portKey, group.first, group.last))
 | 
						|
		groupMap[portKey] = &portGroup{first: current, last: current}
 | 
						|
	}
 | 
						|
 | 
						|
	for _, portKey := range groupMapKeys {
 | 
						|
		g := groupMap[portKey]
 | 
						|
		result = append(result, formGroup(portKey, g.first, g.last))
 | 
						|
	}
 | 
						|
 | 
						|
	result = append(result, hostMappings...)
 | 
						|
 | 
						|
	return strings.Join(result, ", ")
 | 
						|
}
 | 
						|
 | 
						|
func formGroup(key string, start uint32, last uint32) string {
 | 
						|
	parts := strings.Split(key, "/")
 | 
						|
	protocol := parts[0]
 | 
						|
	var ip string
 | 
						|
	if len(parts) > 1 {
 | 
						|
		ip = parts[0]
 | 
						|
		protocol = parts[1]
 | 
						|
	}
 | 
						|
	group := strconv.Itoa(int(start))
 | 
						|
 | 
						|
	// add range
 | 
						|
	if start != last {
 | 
						|
		group = fmt.Sprintf("%s-%d", group, last)
 | 
						|
	}
 | 
						|
 | 
						|
	// add host ip
 | 
						|
	if ip != "" {
 | 
						|
		group = fmt.Sprintf("%s:%s->%s", ip, group, group)
 | 
						|
	}
 | 
						|
 | 
						|
	// add protocol
 | 
						|
	return fmt.Sprintf("%s/%s", group, protocol)
 | 
						|
}
 | 
						|
 | 
						|
func comparePorts(i containers.Port, j containers.Port) bool {
 | 
						|
	if i.ContainerPort != j.ContainerPort {
 | 
						|
		return i.ContainerPort < j.ContainerPort
 | 
						|
	}
 | 
						|
 | 
						|
	if i.HostIP != j.HostIP {
 | 
						|
		return i.HostIP < j.HostIP
 | 
						|
	}
 | 
						|
 | 
						|
	if i.HostPort != j.HostPort {
 | 
						|
		return i.HostPort < j.HostPort
 | 
						|
	}
 | 
						|
 | 
						|
	return i.Protocol < j.Protocol
 | 
						|
}
 |