From 2e7cf6b0cec3e5cc6f05fa5011cf7b5e49a44ae4 Mon Sep 17 00:00:00 2001 From: Alexandr Morozov Date: Tue, 9 Sep 2014 16:47:25 +0400 Subject: [PATCH] Deallocate port before trying to delete iptables chain Fixes #7954 Signed-off-by: Alexandr Morozov --- daemon/networkdriver/portmapper/mapper.go | 8 ++----- integration-cli/docker_cli_run_test.go | 29 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/daemon/networkdriver/portmapper/mapper.go b/daemon/networkdriver/portmapper/mapper.go index b9dc531b38..7e8e266bb4 100644 --- a/daemon/networkdriver/portmapper/mapper.go +++ b/daemon/networkdriver/portmapper/mapper.go @@ -4,11 +4,11 @@ import ( "errors" "fmt" "net" - "strings" "sync" "github.com/docker/docker/daemon/networkdriver/portallocator" "github.com/docker/docker/pkg/iptables" + "github.com/docker/docker/pkg/log" ) type mapping struct { @@ -127,10 +127,7 @@ func Unmap(host net.Addr) error { containerIP, containerPort := getIPAndPort(data.container) hostIP, hostPort := getIPAndPort(data.host) if err := forward(iptables.Delete, data.proto, hostIP, hostPort, containerIP.String(), containerPort); err != nil { - // skip "no chain" errors because we can safely release port in this case - if !strings.Contains(err.Error(), "No chain/target/match by that name") { - return err - } + log.Errorf("Error on iptables delete: %s", err) } switch a := host.(type) { @@ -139,7 +136,6 @@ func Unmap(host net.Addr) error { case *net.UDPAddr: return portallocator.ReleasePort(a.IP, "udp", a.Port) } - return nil } diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index bee77fb179..e781f3782a 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -1846,3 +1846,32 @@ func TestRunNetworkNotInitializedNoneMode(t *testing.T) { deleteAllContainers() logDone("run - network must not be initialized in 'none' mode") } + +func TestRunDeallocatePortOnMissingIptablesRule(t *testing.T) { + cmd := exec.Command(dockerBinary, "run", "-d", "-p", "23:23", "busybox", "top") + out, _, err := runCommandWithOutput(cmd) + if err != nil { + t.Fatal(err) + } + id := strings.TrimSpace(out) + ip, err := inspectField(id, "NetworkSettings.IPAddress") + if err != nil { + t.Fatal(err) + } + iptCmd := exec.Command("iptables", "-D", "FORWARD", "-d", fmt.Sprintf("%s/32", ip), + "!", "-i", "docker0", "-o", "docker0", "-p", "tcp", "-m", "tcp", "--dport", "23", "-j", "ACCEPT") + out, _, err = runCommandWithOutput(iptCmd) + if err != nil { + t.Fatal(err, out) + } + if err := deleteContainer(id); err != nil { + t.Fatal(err) + } + cmd = exec.Command(dockerBinary, "run", "-d", "-p", "23:23", "busybox", "top") + out, _, err = runCommandWithOutput(cmd) + if err != nil { + t.Fatal(err, out) + } + deleteAllContainers() + logDone("run - port should be deallocated even on iptables error") +}