Allocate daemon listening ports
| ... | ... |
@@ -27,6 +27,7 @@ import ( |
| 27 | 27 |
|
| 28 | 28 |
log "github.com/Sirupsen/logrus" |
| 29 | 29 |
"github.com/docker/docker/api" |
| 30 |
+ "github.com/docker/docker/daemon/networkdriver/portallocator" |
|
| 30 | 31 |
"github.com/docker/docker/engine" |
| 31 | 32 |
"github.com/docker/docker/pkg/listenbuffer" |
| 32 | 33 |
"github.com/docker/docker/pkg/parsers" |
| ... | ... |
@@ -1502,6 +1503,32 @@ func setupUnixHttp(addr string, job *engine.Job) (*HttpServer, error) {
|
| 1502 | 1502 |
return &HttpServer{&http.Server{Addr: addr, Handler: r}, l}, nil
|
| 1503 | 1503 |
} |
| 1504 | 1504 |
|
| 1505 |
+func allocateDaemonPort(addr string) error {
|
|
| 1506 |
+ host, port, err := net.SplitHostPort(addr) |
|
| 1507 |
+ if err != nil {
|
|
| 1508 |
+ return err |
|
| 1509 |
+ } |
|
| 1510 |
+ |
|
| 1511 |
+ intPort, err := strconv.Atoi(port) |
|
| 1512 |
+ if err != nil {
|
|
| 1513 |
+ return err |
|
| 1514 |
+ } |
|
| 1515 |
+ |
|
| 1516 |
+ var hostIPs []net.IP |
|
| 1517 |
+ if parsedIP := net.ParseIP(host); parsedIP != nil {
|
|
| 1518 |
+ hostIPs = append(hostIPs, parsedIP) |
|
| 1519 |
+ } else if hostIPs, err = net.LookupIP(host); err != nil {
|
|
| 1520 |
+ return fmt.Errorf("failed to lookup %s address in host specification", host)
|
|
| 1521 |
+ } |
|
| 1522 |
+ |
|
| 1523 |
+ for _, hostIP := range hostIPs {
|
|
| 1524 |
+ if _, err := portallocator.RequestPort(hostIP, "tcp", intPort); err != nil {
|
|
| 1525 |
+ return fmt.Errorf("failed to allocate daemon listening port %d (err: %v)", intPort, err)
|
|
| 1526 |
+ } |
|
| 1527 |
+ } |
|
| 1528 |
+ return nil |
|
| 1529 |
+} |
|
| 1530 |
+ |
|
| 1505 | 1531 |
func setupTcpHttp(addr string, job *engine.Job) (*HttpServer, error) {
|
| 1506 | 1532 |
if !strings.HasPrefix(addr, "127.0.0.1") && !job.GetenvBool("TlsVerify") {
|
| 1507 | 1533 |
log.Infof("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
|
| ... | ... |
@@ -1517,6 +1544,10 @@ func setupTcpHttp(addr string, job *engine.Job) (*HttpServer, error) {
|
| 1517 | 1517 |
return nil, err |
| 1518 | 1518 |
} |
| 1519 | 1519 |
|
| 1520 |
+ if err := allocateDaemonPort(addr); err != nil {
|
|
| 1521 |
+ return nil, err |
|
| 1522 |
+ } |
|
| 1523 |
+ |
|
| 1520 | 1524 |
if job.GetenvBool("Tls") || job.GetenvBool("TlsVerify") {
|
| 1521 | 1525 |
var tlsCa string |
| 1522 | 1526 |
if job.GetenvBool("TlsVerify") {
|
| ... | ... |
@@ -2,6 +2,7 @@ package main |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"encoding/json" |
| 5 |
+ "fmt" |
|
| 5 | 6 |
"io/ioutil" |
| 6 | 7 |
"os" |
| 7 | 8 |
"os/exec" |
| ... | ... |
@@ -284,3 +285,33 @@ func TestDaemonLoggingLevel(t *testing.T) {
|
| 284 | 284 |
|
| 285 | 285 |
logDone("daemon - Logging Level")
|
| 286 | 286 |
} |
| 287 |
+ |
|
| 288 |
+func TestDaemonAllocatesListeningPort(t *testing.T) {
|
|
| 289 |
+ listeningPorts := [][]string{
|
|
| 290 |
+ {"0.0.0.0", "0.0.0.0", "5678"},
|
|
| 291 |
+ {"127.0.0.1", "127.0.0.1", "1234"},
|
|
| 292 |
+ {"localhost", "127.0.0.1", "1235"},
|
|
| 293 |
+ } |
|
| 294 |
+ |
|
| 295 |
+ cmdArgs := []string{}
|
|
| 296 |
+ for _, hostDirective := range listeningPorts {
|
|
| 297 |
+ cmdArgs = append(cmdArgs, "--host", fmt.Sprintf("tcp://%s:%s", hostDirective[0], hostDirective[2]))
|
|
| 298 |
+ } |
|
| 299 |
+ |
|
| 300 |
+ d := NewDaemon(t) |
|
| 301 |
+ if err := d.StartWithBusybox(cmdArgs...); err != nil {
|
|
| 302 |
+ t.Fatalf("Could not start daemon with busybox: %v", err)
|
|
| 303 |
+ } |
|
| 304 |
+ defer d.Stop() |
|
| 305 |
+ |
|
| 306 |
+ for _, hostDirective := range listeningPorts {
|
|
| 307 |
+ output, err := d.Cmd("run", "-p", fmt.Sprintf("%s:%s:80", hostDirective[1], hostDirective[2]), "busybox", "true")
|
|
| 308 |
+ if err == nil {
|
|
| 309 |
+ t.Fatalf("Container should not start, expected port already allocated error: %q", output)
|
|
| 310 |
+ } else if !strings.Contains(output, "port is already allocated") {
|
|
| 311 |
+ t.Fatalf("Expected port is already allocated error: %q", output)
|
|
| 312 |
+ } |
|
| 313 |
+ } |
|
| 314 |
+ |
|
| 315 |
+ logDone("daemon - daemon listening port is allocated")
|
|
| 316 |
+} |