diff --git a/components/engine/hack/vendor.sh b/components/engine/hack/vendor.sh index 37db1688de..d952a344bf 100755 --- a/components/engine/hack/vendor.sh +++ b/components/engine/hack/vendor.sh @@ -27,7 +27,7 @@ clone git github.com/RackSec/srslog 6eb773f331e46fbba8eecb8e794e635e75fc04de clone git github.com/imdario/mergo 0.2.1 #get libnetwork packages -clone git github.com/docker/libnetwork v0.5.5 +clone git github.com/docker/libnetwork v0.5.6 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4 diff --git a/components/engine/integration-cli/docker_cli_restart_test.go b/components/engine/integration-cli/docker_cli_restart_test.go index dc57a94632..2bc28fd328 100644 --- a/components/engine/integration-cli/docker_cli_restart_test.go +++ b/components/engine/integration-cli/docker_cli_restart_test.go @@ -153,3 +153,46 @@ func (s *DockerSuite) TestContainerRestartSuccess(c *check.C) { err = waitInspect(id, "{{.State.Status}}", "running", 5*time.Second) c.Assert(err, check.IsNil) } + +func (s *DockerSuite) TestUserDefinedNetworkWithRestartPolicy(c *check.C) { + testRequires(c, DaemonIsLinux, SameHostDaemon, NotUserNamespace) + dockerCmd(c, "network", "create", "-d", "bridge", "udNet") + + dockerCmd(c, "run", "-d", "--net=udNet", "--name=first", "busybox", "top") + c.Assert(waitRun("first"), check.IsNil) + + dockerCmd(c, "run", "-d", "--restart=always", "--net=udNet", "--name=second", + "--link=first:foo", "busybox", "top") + c.Assert(waitRun("second"), check.IsNil) + + // ping to first and its alias foo must succeed + _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") + c.Assert(err, check.IsNil) + _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo") + c.Assert(err, check.IsNil) + + // Now kill the second container and let the restart policy kick in + pidStr, err := inspectField("second", "State.Pid") + c.Assert(err, check.IsNil) + + pid, err := strconv.Atoi(pidStr) + c.Assert(err, check.IsNil) + + p, err := os.FindProcess(pid) + c.Assert(err, check.IsNil) + c.Assert(p, check.NotNil) + + err = p.Kill() + c.Assert(err, check.IsNil) + + err = waitInspect("second", "{{.RestartCount}}", "1", 5*time.Second) + c.Assert(err, check.IsNil) + + err = waitInspect("second", "{{.State.Status}}", "running", 5*time.Second) + + // ping to first and its alias foo must still succeed + _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") + c.Assert(err, check.IsNil) + _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo") + c.Assert(err, check.IsNil) +} diff --git a/components/engine/vendor/src/github.com/docker/libnetwork/CHANGELOG.md b/components/engine/vendor/src/github.com/docker/libnetwork/CHANGELOG.md index 98e3913327..ea136da5b4 100644 --- a/components/engine/vendor/src/github.com/docker/libnetwork/CHANGELOG.md +++ b/components/engine/vendor/src/github.com/docker/libnetwork/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 0.5.6 (2016-01-14) +- Setup embedded DNS server correctly on container restart. Fixes docker/docker#19354 + ## 0.5.5 (2016-01-14) - Allow network-scoped alias to be resolved for anonymous endpoint - Self repair corrupted IP database that could happen in 1.9.0 & 1.9.1 diff --git a/components/engine/vendor/src/github.com/docker/libnetwork/resolver.go b/components/engine/vendor/src/github.com/docker/libnetwork/resolver.go index 3cd74e03ad..d395ab46b3 100644 --- a/components/engine/vendor/src/github.com/docker/libnetwork/resolver.go +++ b/components/engine/vendor/src/github.com/docker/libnetwork/resolver.go @@ -15,7 +15,8 @@ import ( type Resolver interface { // Start starts the name server for the container Start() error - // Stop stops the name server for the container + // Stop stops the name server for the container. Stopped resolver + // can be reused after running the SetupFunc again. Stop() // SetupFunc() provides the setup function that should be run // in the container's network namespace. @@ -102,6 +103,8 @@ func (r *resolver) Stop() { if r.server != nil { r.server.Shutdown() } + r.conn = nil + r.err = fmt.Errorf("setup not done yet") } func (r *resolver) SetExtServers(dns []string) { diff --git a/components/engine/vendor/src/github.com/docker/libnetwork/sandbox.go b/components/engine/vendor/src/github.com/docker/libnetwork/sandbox.go index 8977cf349f..9dbb100ef9 100644 --- a/components/engine/vendor/src/github.com/docker/libnetwork/sandbox.go +++ b/components/engine/vendor/src/github.com/docker/libnetwork/sandbox.go @@ -488,23 +488,22 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin } func (sb *sandbox) SetKey(basePath string) error { - var err error if basePath == "" { return types.BadRequestErrorf("invalid sandbox key") } sb.Lock() - osSbox := sb.osSbox + oldosSbox := sb.osSbox sb.Unlock() - if osSbox != nil { + if oldosSbox != nil { // If we already have an OS sandbox, release the network resources from that // and destroy the OS snab. We are moving into a new home further down. Note that none // of the network resources gets destroyed during the move. sb.releaseOSSbox() } - osSbox, err = osl.GetSandboxForExternalKey(basePath, sb.Key()) + osSbox, err := osl.GetSandboxForExternalKey(basePath, sb.Key()) if err != nil { return err } @@ -520,6 +519,17 @@ func (sb *sandbox) SetKey(basePath string) error { } }() + // If the resolver was setup before stop it and set it up in the + // new osl sandbox. + if oldosSbox != nil && sb.resolver != nil { + sb.resolver.Stop() + + sb.osSbox.InvokeFunc(sb.resolver.SetupFunc()) + if err := sb.resolver.Start(); err != nil { + log.Errorf("Resolver Setup/Start failed for container %s, %q", sb.ContainerID(), err) + } + } + for _, ep := range sb.getConnectedEndpoints() { if err = sb.populateNetworkResources(ep); err != nil { return err