diff --git a/daemon/links/links.go b/daemon/links/links.go index f607d38bdd..1f4355cd7a 100644 --- a/daemon/links/links.go +++ b/daemon/links/links.go @@ -48,41 +48,47 @@ func NewLink(parentIP, childIP, name string, env []string, exposedPorts map[nat. // the form of environment variables which will be later exported on container // startup. func (l *Link) ToEnv() []string { - env := []string{} - _, n := path.Split(l.Name) alias := strings.ReplaceAll(strings.ToUpper(n), "-", "_") // sort the ports so that we can bulk the continuous ports together nat.Sort(l.Ports, withTCPPriority) - for i := 0; i < len(l.Ports); { - p := l.Ports[i] + var pStart, pEnd nat.Port + env := make([]string, 0, 1+len(l.Ports)*4) + for i, p := range l.Ports { if i == 0 { + pStart, pEnd = p, p env = append(env, fmt.Sprintf("%s_PORT=%s://%s:%s", alias, p.Proto(), l.ChildIP, p.Port())) } - j := nextContiguous(l.Ports, p.Int(), i) - if j > i+1 { - env = append(env, fmt.Sprintf("%s_PORT_%s_%s_START=%s://%s:%s", alias, p.Port(), strings.ToUpper(p.Proto()), p.Proto(), l.ChildIP, p.Port())) - env = append(env, fmt.Sprintf("%s_PORT_%s_%s_ADDR=%s", alias, p.Port(), strings.ToUpper(p.Proto()), l.ChildIP)) - env = append(env, fmt.Sprintf("%s_PORT_%s_%s_PROTO=%s", alias, p.Port(), strings.ToUpper(p.Proto()), p.Proto())) - env = append(env, fmt.Sprintf("%s_PORT_%s_%s_PORT_START=%s", alias, p.Port(), strings.ToUpper(p.Proto()), p.Port())) - q := l.Ports[j] - env = append(env, fmt.Sprintf("%s_PORT_%s_%s_END=%s://%s:%s", alias, p.Port(), strings.ToUpper(q.Proto()), q.Proto(), l.ChildIP, q.Port())) - env = append(env, fmt.Sprintf("%s_PORT_%s_%s_PORT_END=%s", alias, p.Port(), strings.ToUpper(q.Proto()), q.Port())) + // These env-vars are produced for every port, regardless if they're + // part of a port-range. + prefix := fmt.Sprintf("%s_PORT_%s_%s", alias, p.Port(), strings.ToUpper(p.Proto())) + env = append(env, fmt.Sprintf("%s=%s://%s:%s", prefix, p.Proto(), l.ChildIP, p.Port())) + env = append(env, fmt.Sprintf("%s_ADDR=%s", prefix, l.ChildIP)) + env = append(env, fmt.Sprintf("%s_PORT=%s", prefix, p.Port())) + env = append(env, fmt.Sprintf("%s_PROTO=%s", prefix, p.Proto())) - i = j + 1 - continue - } else { - i++ + // Detect whether this port is part of a range (consecutive port number + // and same protocol). + if p.Int() == pEnd.Int()+1 && strings.EqualFold(p.Proto(), pStart.Proto()) { + pEnd = p + if i < len(l.Ports)-1 { + continue + } } - } - for _, p := range l.Ports { - env = append(env, fmt.Sprintf("%s_PORT_%s_%s=%s://%s:%s", alias, p.Port(), strings.ToUpper(p.Proto()), p.Proto(), l.ChildIP, p.Port())) - env = append(env, fmt.Sprintf("%s_PORT_%s_%s_ADDR=%s", alias, p.Port(), strings.ToUpper(p.Proto()), l.ChildIP)) - env = append(env, fmt.Sprintf("%s_PORT_%s_%s_PORT=%s", alias, p.Port(), strings.ToUpper(p.Proto()), p.Port())) - env = append(env, fmt.Sprintf("%s_PORT_%s_%s_PROTO=%s", alias, p.Port(), strings.ToUpper(p.Proto()), p.Proto())) + + if pEnd != pStart { + prefix = fmt.Sprintf("%s_PORT_%s_%s", alias, pStart.Port(), strings.ToUpper(pStart.Proto())) + env = append(env, fmt.Sprintf("%s_START=%s://%s:%s", prefix, pStart.Proto(), l.ChildIP, pStart.Port())) + env = append(env, fmt.Sprintf("%s_PORT_START=%s", prefix, pStart.Port())) + env = append(env, fmt.Sprintf("%s_END=%s://%s:%s", prefix, pEnd.Proto(), l.ChildIP, pEnd.Port())) + env = append(env, fmt.Sprintf("%s_PORT_END=%s", prefix, pEnd.Port())) + } + + // Reset for next range (if any) + pStart, pEnd = p, p } // Load the linked container's name into the environment @@ -120,17 +126,3 @@ func withTCPPriority(ip, jp nat.Port) bool { return strings.ToLower(ip.Proto()) < strings.ToLower(jp.Proto()) } - -func nextContiguous(ports []nat.Port, value int, index int) int { - if index+1 == len(ports) { - return index - } - for i := index + 1; i < len(ports); i++ { - if ports[i].Int() > value+1 || !strings.EqualFold(ports[i].Proto(), ports[i-1].Proto()) { - return i - 1 - } - - value++ - } - return len(ports) - 1 -} diff --git a/daemon/links/links_test.go b/daemon/links/links_test.go index 8a00129ab8..9a352ff67b 100644 --- a/daemon/links/links_test.go +++ b/daemon/links/links_test.go @@ -110,13 +110,11 @@ func TestLinkMultipleEnv(t *testing.T) { "DOCKER_PORT_6379_TCP=tcp://172.0.17.2:6379", "DOCKER_PORT_6379_TCP_ADDR=172.0.17.2", - "DOCKER_PORT_6379_TCP_ADDR=172.0.17.2", // FIXME(thaJeztah): duplicate? "DOCKER_PORT_6379_TCP_END=tcp://172.0.17.2:6381", "DOCKER_PORT_6379_TCP_PORT=6379", "DOCKER_PORT_6379_TCP_PORT_END=6381", "DOCKER_PORT_6379_TCP_PORT_START=6379", "DOCKER_PORT_6379_TCP_PROTO=tcp", - "DOCKER_PORT_6379_TCP_PROTO=tcp", // FIXME(thaJeztah): duplicate? "DOCKER_PORT_6379_TCP_START=tcp://172.0.17.2:6379", "DOCKER_PORT_6380_TCP=tcp://172.0.17.2:6380",