|
@@ -11,7 +11,6 @@ import (
|
|
"github.com/docker/libcontainer/netlink"
|
|
"github.com/docker/libcontainer/netlink"
|
|
"github.com/dotcloud/docker/daemon/networkdriver"
|
|
"github.com/dotcloud/docker/daemon/networkdriver"
|
|
"github.com/dotcloud/docker/daemon/networkdriver/ipallocator"
|
|
"github.com/dotcloud/docker/daemon/networkdriver/ipallocator"
|
|
- "github.com/dotcloud/docker/daemon/networkdriver/portallocator"
|
|
|
|
"github.com/dotcloud/docker/daemon/networkdriver/portmapper"
|
|
"github.com/dotcloud/docker/daemon/networkdriver/portmapper"
|
|
"github.com/dotcloud/docker/engine"
|
|
"github.com/dotcloud/docker/engine"
|
|
"github.com/dotcloud/docker/pkg/iptables"
|
|
"github.com/dotcloud/docker/pkg/iptables"
|
|
@@ -354,9 +353,6 @@ func Release(job *engine.Job) engine.Status {
|
|
var (
|
|
var (
|
|
id = job.Args[0]
|
|
id = job.Args[0]
|
|
containerInterface = currentInterfaces.Get(id)
|
|
containerInterface = currentInterfaces.Get(id)
|
|
- ip net.IP
|
|
|
|
- port int
|
|
|
|
- proto string
|
|
|
|
)
|
|
)
|
|
|
|
|
|
if containerInterface == nil {
|
|
if containerInterface == nil {
|
|
@@ -367,22 +363,6 @@ func Release(job *engine.Job) engine.Status {
|
|
if err := portmapper.Unmap(nat); err != nil {
|
|
if err := portmapper.Unmap(nat); err != nil {
|
|
log.Printf("Unable to unmap port %s: %s", nat, err)
|
|
log.Printf("Unable to unmap port %s: %s", nat, err)
|
|
}
|
|
}
|
|
-
|
|
|
|
- // this is host mappings
|
|
|
|
- switch a := nat.(type) {
|
|
|
|
- case *net.TCPAddr:
|
|
|
|
- proto = "tcp"
|
|
|
|
- ip = a.IP
|
|
|
|
- port = a.Port
|
|
|
|
- case *net.UDPAddr:
|
|
|
|
- proto = "udp"
|
|
|
|
- ip = a.IP
|
|
|
|
- port = a.Port
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if err := portallocator.ReleasePort(ip, proto, port); err != nil {
|
|
|
|
- log.Printf("Unable to release port %s", nat)
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if err := ipallocator.ReleaseIP(bridgeNetwork, &containerInterface.IP); err != nil {
|
|
if err := ipallocator.ReleaseIP(bridgeNetwork, &containerInterface.IP); err != nil {
|
|
@@ -399,7 +379,7 @@ func AllocatePort(job *engine.Job) engine.Status {
|
|
ip = defaultBindingIP
|
|
ip = defaultBindingIP
|
|
id = job.Args[0]
|
|
id = job.Args[0]
|
|
hostIP = job.Getenv("HostIP")
|
|
hostIP = job.Getenv("HostIP")
|
|
- origHostPort = job.GetenvInt("HostPort")
|
|
|
|
|
|
+ hostPort = job.GetenvInt("HostPort")
|
|
containerPort = job.GetenvInt("ContainerPort")
|
|
containerPort = job.GetenvInt("ContainerPort")
|
|
proto = job.Getenv("Proto")
|
|
proto = job.Getenv("Proto")
|
|
network = currentInterfaces.Get(id)
|
|
network = currentInterfaces.Get(id)
|
|
@@ -409,11 +389,16 @@ func AllocatePort(job *engine.Job) engine.Status {
|
|
ip = net.ParseIP(hostIP)
|
|
ip = net.ParseIP(hostIP)
|
|
}
|
|
}
|
|
|
|
|
|
- var (
|
|
|
|
- hostPort int
|
|
|
|
- container net.Addr
|
|
|
|
- host net.Addr
|
|
|
|
- )
|
|
|
|
|
|
+ // host ip, proto, and host port
|
|
|
|
+ var container net.Addr
|
|
|
|
+ switch proto {
|
|
|
|
+ case "tcp":
|
|
|
|
+ container = &net.TCPAddr{IP: network.IP, Port: containerPort}
|
|
|
|
+ case "udp":
|
|
|
|
+ container = &net.UDPAddr{IP: network.IP, Port: containerPort}
|
|
|
|
+ default:
|
|
|
|
+ return job.Errorf("unsupported address type %s", proto)
|
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
/*
|
|
Try up to 10 times to get a port that's not already allocated.
|
|
Try up to 10 times to get a port that's not already allocated.
|
|
@@ -421,27 +406,22 @@ func AllocatePort(job *engine.Job) engine.Status {
|
|
In the event of failure to bind, return the error that portmapper.Map
|
|
In the event of failure to bind, return the error that portmapper.Map
|
|
yields.
|
|
yields.
|
|
*/
|
|
*/
|
|
- for i := 0; i < 10; i++ {
|
|
|
|
- // host ip, proto, and host port
|
|
|
|
- hostPort, err = portallocator.RequestPort(ip, proto, origHostPort)
|
|
|
|
|
|
|
|
- if err != nil {
|
|
|
|
- return job.Error(err)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if proto == "tcp" {
|
|
|
|
- host = &net.TCPAddr{IP: ip, Port: hostPort}
|
|
|
|
- container = &net.TCPAddr{IP: network.IP, Port: containerPort}
|
|
|
|
- } else {
|
|
|
|
- host = &net.UDPAddr{IP: ip, Port: hostPort}
|
|
|
|
- container = &net.UDPAddr{IP: network.IP, Port: containerPort}
|
|
|
|
|
|
+ var host net.Addr
|
|
|
|
+ for i := 0; i < 10; i++ {
|
|
|
|
+ if host, err = portmapper.Map(container, ip, hostPort); err == nil {
|
|
|
|
+ break
|
|
}
|
|
}
|
|
|
|
|
|
- if err = portmapper.Map(container, ip, hostPort); err == nil {
|
|
|
|
|
|
+ // There is no point in immediately retrying to map an explicitely
|
|
|
|
+ // chosen port.
|
|
|
|
+ if hostPort != 0 {
|
|
|
|
+ job.Logf("Failed to bind %s for container address %s", host.String(), container.String())
|
|
break
|
|
break
|
|
}
|
|
}
|
|
|
|
|
|
- job.Logf("Failed to bind %s:%d for container address %s:%d. Trying another port.", ip.String(), hostPort, network.IP.String(), containerPort)
|
|
|
|
|
|
+ // Automatically chosen 'free' port failed to bind: move on the next.
|
|
|
|
+ job.Logf("Failed to bind %s for container address %s. Trying another port.", host.String(), container.String())
|
|
}
|
|
}
|
|
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -451,12 +431,18 @@ func AllocatePort(job *engine.Job) engine.Status {
|
|
network.PortMappings = append(network.PortMappings, host)
|
|
network.PortMappings = append(network.PortMappings, host)
|
|
|
|
|
|
out := engine.Env{}
|
|
out := engine.Env{}
|
|
- out.Set("HostIP", ip.String())
|
|
|
|
- out.SetInt("HostPort", hostPort)
|
|
|
|
-
|
|
|
|
|
|
+ switch netAddr := host.(type) {
|
|
|
|
+ case *net.TCPAddr:
|
|
|
|
+ out.Set("HostIP", netAddr.IP.String())
|
|
|
|
+ out.SetInt("HostPort", netAddr.Port)
|
|
|
|
+ case *net.UDPAddr:
|
|
|
|
+ out.Set("HostIP", netAddr.IP.String())
|
|
|
|
+ out.SetInt("HostPort", netAddr.Port)
|
|
|
|
+ }
|
|
if _, err := out.WriteTo(job.Stdout); err != nil {
|
|
if _, err := out.WriteTo(job.Stdout); err != nil {
|
|
return job.Error(err)
|
|
return job.Error(err)
|
|
}
|
|
}
|
|
|
|
+
|
|
return engine.StatusOK
|
|
return engine.StatusOK
|
|
}
|
|
}
|
|
|
|
|