diff --git a/daemon/networkdriver/bridge/driver.go b/daemon/networkdriver/bridge/driver.go index 7fe04550ef..e0467b6bd7 100644 --- a/daemon/networkdriver/bridge/driver.go +++ b/daemon/networkdriver/bridge/driver.go @@ -11,7 +11,6 @@ import ( log "github.com/Sirupsen/logrus" "github.com/docker/docker/daemon/networkdriver" "github.com/docker/docker/daemon/networkdriver/ipallocator" - "github.com/docker/docker/daemon/networkdriver/portallocator" "github.com/docker/docker/daemon/networkdriver/portmapper" "github.com/docker/docker/engine" "github.com/docker/docker/nat" @@ -468,22 +467,13 @@ func AllocatePort(job *engine.Job) engine.Status { if host, err = portmapper.Map(container, ip, hostPort); err == nil { break } - - if allocerr, ok := err.(portallocator.ErrPortAlreadyAllocated); ok { - // There is no point in immediately retrying to map an explicitly - // chosen port. - if hostPort != 0 { - job.Logf("Failed to bind %s for container address %s: %s", allocerr.IPPort(), container.String(), allocerr.Error()) - break - } - - // Automatically chosen 'free' port failed to bind: move on the next. - job.Logf("Failed to bind %s for container address %s. Trying another port.", allocerr.IPPort(), container.String()) - } else { - // some other error during mapping - job.Logf("Received an unexpected error during port allocation: %s", err.Error()) + // There is no point in immediately retrying to map an explicitly + // chosen port. + if hostPort != 0 { + job.Logf("Failed to allocate and map port %d: %s", hostPort, err) break } + job.Logf("Failed to allocate and map port: %s, retry: %d", err, i+1) } if err != nil { diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 844fc62ddd..20a096f196 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -2701,3 +2701,44 @@ func TestRunTLSverify(t *testing.T) { logDone("run - verify tls is set for --tlsverify") } + +func TestRunPortFromDockerRangeInUse(t *testing.T) { + defer deleteAllContainers() + // first find allocator current position + cmd := exec.Command(dockerBinary, "run", "-d", "-p", ":80", "busybox", "top") + out, _, err := runCommandWithOutput(cmd) + if err != nil { + t.Fatal(out, err) + } + id := strings.TrimSpace(out) + cmd = exec.Command(dockerBinary, "port", id) + out, _, err = runCommandWithOutput(cmd) + if err != nil { + t.Fatal(out, err) + } + out = strings.TrimSpace(out) + out = strings.Split(out, ":")[1] + lastPort, err := strconv.Atoi(out) + if err != nil { + t.Fatal(err) + } + port := lastPort + 1 + l, err := net.Listen("tcp", ":"+strconv.Itoa(port)) + if err != nil { + t.Fatal(err) + } + defer l.Close() + cmd = exec.Command(dockerBinary, "run", "-d", "-p", ":80", "busybox", "top") + out, _, err = runCommandWithOutput(cmd) + if err != nil { + t.Fatalf(out, err) + } + id = strings.TrimSpace(out) + cmd = exec.Command(dockerBinary, "port", id) + out, _, err = runCommandWithOutput(cmd) + if err != nil { + t.Fatal(out, err) + } + + logDone("run - find another port if port from autorange already bound") +}