From 35d6def3aa8f07fdafac0bba14afa14956f2a7d0 Mon Sep 17 00:00:00 2001 From: "Kai Qiang Wu(Kennan)" <wkqwu@cn.ibm.com> Date: Thu, 7 Apr 2016 02:09:13 +0000 Subject: [PATCH 01/13] Fix deprecated format for security-opt Signed-off-by: Kai Qiang Wu(Kennan) <wkqwu@cn.ibm.com> (cherry picked from commit 0b207e75585cd4ba9a40460d87766052dd7508a7) --- docs/reference/run.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/run.md b/docs/reference/run.md index 170dd35079..b37dd5ae80 100644 --- a/docs/reference/run.md +++ b/docs/reference/run.md @@ -608,8 +608,8 @@ with the same logic -- if the original volume was specified with a name it will to the container --security-opt="no-new-privileges" : Disable container processes from gaining new privileges - --security-opt="seccomp:unconfined": Turn off seccomp confinement for the container - --security-opt="seccomp:profile.json: White listed syscalls seccomp Json file to be used as a seccomp filter + --security-opt="seccomp=unconfined": Turn off seccomp confinement for the container + --security-opt="seccomp=profile.json: White listed syscalls seccomp Json file to be used as a seccomp filter You can override the default labeling scheme for each container by specifying From b1b86e91667939491a471dc7604780ebc1661e25 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi <tonistiigi@gmail.com> Date: Wed, 6 Apr 2016 16:49:45 -0700 Subject: [PATCH 02/13] Fix closing attach streams on lost tcp connection Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> (cherry picked from commit a47cd639158ee9cfd228c0ae8257301b8510f3ad) --- pkg/ioutils/bytespipe.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/ioutils/bytespipe.go b/pkg/ioutils/bytespipe.go index e263c284f0..fcaecc37b5 100644 --- a/pkg/ioutils/bytespipe.go +++ b/pkg/ioutils/bytespipe.go @@ -49,6 +49,7 @@ func (bp *BytesPipe) Write(p []byte) (int, error) { bp.mu.Lock() defer bp.mu.Unlock() written := 0 +loop0: for { if bp.closeErr != nil { return written, ErrClosed @@ -75,6 +76,9 @@ func (bp *BytesPipe) Write(p []byte) (int, error) { // block if too much data is still in the buffer for bp.bufLen >= blockThreshold { bp.wait.Wait() + if bp.closeErr != nil { + continue loop0 + } } // allocate slice that has twice the size of the last unless maximum reached From 52b8adea4dd84dbc53a223d8675e107795b84ce6 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi <tonistiigi@gmail.com> Date: Thu, 7 Apr 2016 11:00:54 -0700 Subject: [PATCH 03/13] vendor: patch template init in trace pkg for performance Temporarily include a fork of golang/net package that includes a performance patch. Measured performance gain is ~60ms for every `docker run` command. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> (cherry picked from commit 07fe6947a403124041dda50eb6d7f00e74f96ce7) --- hack/vendor.sh | 3 ++- vendor/src/golang.org/x/net/trace/events.go | 20 +++++++++++++------ .../src/golang.org/x/net/trace/histogram.go | 15 +++++++++++--- vendor/src/golang.org/x/net/trace/trace.go | 18 ++++++++++++----- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/hack/vendor.sh b/hack/vendor.sh index 6fe46e5dcc..f3fdea3438 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -20,7 +20,8 @@ clone git github.com/mattn/go-sqlite3 v1.1.0 clone git github.com/mistifyio/go-zfs v2.1.1 clone git github.com/tchap/go-patricia v2.1.0 clone git github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 -clone git golang.org/x/net 47990a1ba55743e6ef1affd3a14e5bac8553615d https://github.com/golang/net.git +# forked golang.org/x/net package includes a patch for lazy loading trace templates +clone git golang.org/x/net 78cb2c067747f08b343f20614155233ab4ea2ad3 https://github.com/tonistiigi/net.git clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3 clone git github.com/docker/go-connections v0.2.0 diff --git a/vendor/src/golang.org/x/net/trace/events.go b/vendor/src/golang.org/x/net/trace/events.go index e66c7e3282..d8daec1a79 100644 --- a/vendor/src/golang.org/x/net/trace/events.go +++ b/vendor/src/golang.org/x/net/trace/events.go @@ -21,11 +21,6 @@ import ( "time" ) -var eventsTmpl = template.Must(template.New("events").Funcs(template.FuncMap{ - "elapsed": elapsed, - "trimSpace": strings.TrimSpace, -}).Parse(eventsHTML)) - const maxEventsPerLog = 100 type bucket struct { @@ -101,7 +96,7 @@ func RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) { famMu.RLock() defer famMu.RUnlock() - if err := eventsTmpl.Execute(w, data); err != nil { + if err := eventsTmpl().Execute(w, data); err != nil { log.Printf("net/trace: Failed executing template: %v", err) } } @@ -421,6 +416,19 @@ func freeEventLog(el *eventLog) { } } +var eventsTmplCache *template.Template +var eventsTmplOnce sync.Once + +func eventsTmpl() *template.Template { + eventsTmplOnce.Do(func() { + eventsTmplCache = template.Must(template.New("events").Funcs(template.FuncMap{ + "elapsed": elapsed, + "trimSpace": strings.TrimSpace, + }).Parse(eventsHTML)) + }) + return eventsTmplCache +} + const eventsHTML = ` <html> <head> diff --git a/vendor/src/golang.org/x/net/trace/histogram.go b/vendor/src/golang.org/x/net/trace/histogram.go index bb42aa5320..9bf4286c79 100644 --- a/vendor/src/golang.org/x/net/trace/histogram.go +++ b/vendor/src/golang.org/x/net/trace/histogram.go @@ -12,6 +12,7 @@ import ( "html/template" "log" "math" + "sync" "golang.org/x/net/internal/timeseries" ) @@ -320,15 +321,20 @@ func (h *histogram) newData() *data { func (h *histogram) html() template.HTML { buf := new(bytes.Buffer) - if err := distTmpl.Execute(buf, h.newData()); err != nil { + if err := distTmpl().Execute(buf, h.newData()); err != nil { buf.Reset() log.Printf("net/trace: couldn't execute template: %v", err) } return template.HTML(buf.String()) } -// Input: data -var distTmpl = template.Must(template.New("distTmpl").Parse(` +var distTmplCache *template.Template +var distTmplOnce sync.Once + +func distTmpl() *template.Template { + distTmplOnce.Do(func() { + // Input: data + distTmplCache = template.Must(template.New("distTmpl").Parse(` <table> <tr> <td style="padding:0.25em">Count: {{.Count}}</td> @@ -354,3 +360,6 @@ var distTmpl = template.Must(template.New("distTmpl").Parse(` {{end}} </table> `)) + }) + return distTmplCache +} diff --git a/vendor/src/golang.org/x/net/trace/trace.go b/vendor/src/golang.org/x/net/trace/trace.go index c44cb7ec9e..0a232a1016 100644 --- a/vendor/src/golang.org/x/net/trace/trace.go +++ b/vendor/src/golang.org/x/net/trace/trace.go @@ -232,7 +232,7 @@ func Render(w io.Writer, req *http.Request, sensitive bool) { completedMu.RLock() defer completedMu.RUnlock() - if err := pageTmpl.ExecuteTemplate(w, "Page", data); err != nil { + if err := pageTmpl().ExecuteTemplate(w, "Page", data); err != nil { log.Printf("net/trace: Failed executing template: %v", err) } } @@ -888,10 +888,18 @@ func elapsed(d time.Duration) string { return string(b) } -var pageTmpl = template.Must(template.New("Page").Funcs(template.FuncMap{ - "elapsed": elapsed, - "add": func(a, b int) int { return a + b }, -}).Parse(pageHTML)) +var pageTmplCache *template.Template +var pageTmplOnce sync.Once + +func pageTmpl() *template.Template { + pageTmplOnce.Do(func() { + pageTmplCache = template.Must(template.New("Page").Funcs(template.FuncMap{ + "elapsed": elapsed, + "add": func(a, b int) int { return a + b }, + }).Parse(pageHTML)) + }) + return pageTmplCache +} const pageHTML = ` {{template "Prolog" .}} From 716b5b2547cb3949410708e4021456eb7384c7bc Mon Sep 17 00:00:00 2001 From: Tonis Tiigi <tonistiigi@gmail.com> Date: Thu, 7 Apr 2016 16:12:05 -0700 Subject: [PATCH 04/13] Fix restart monitor stopping on manual restart Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> (cherry picked from commit 20390f65c487cfbe18e1f21650086a00e41eadff) --- container/container.go | 1 + integration-cli/docker_cli_restart_test.go | 30 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/container/container.go b/container/container.go index c9991629be..58892e7788 100644 --- a/container/container.go +++ b/container/container.go @@ -909,6 +909,7 @@ func (container *Container) FullHostname() string { func (container *Container) RestartManager(reset bool) restartmanager.RestartManager { if reset { container.RestartCount = 0 + container.restartManager = nil } if container.restartManager == nil { container.restartManager = restartmanager.New(container.HostConfig.RestartPolicy) diff --git a/integration-cli/docker_cli_restart_test.go b/integration-cli/docker_cli_restart_test.go index 297e16a169..12fe1c4e54 100644 --- a/integration-cli/docker_cli_restart_test.go +++ b/integration-cli/docker_cli_restart_test.go @@ -188,3 +188,33 @@ func (s *DockerSuite) TestRestartWithPolicyUserDefinedNetwork(c *check.C) { _, _, err = dockerCmdWithError("exec", "second", "ping", "-c", "1", "foo") c.Assert(err, check.IsNil) } + +func (s *DockerSuite) TestRestartPolicyAfterRestart(c *check.C) { + testRequires(c, SameHostDaemon) + + out, _ := runSleepingContainer(c, "-d", "--restart=always") + id := strings.TrimSpace(out) + c.Assert(waitRun(id), check.IsNil) + + dockerCmd(c, "restart", id) + + c.Assert(waitRun(id), check.IsNil) + + pidStr := inspectField(c, id, "State.Pid") + + 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(id, "{{.RestartCount}}", "1", 30*time.Second) + c.Assert(err, check.IsNil) + + err = waitInspect(id, "{{.State.Status}}", "running", 30*time.Second) + c.Assert(err, check.IsNil) +} From 9cdfce68f8a7d635341daa6f6568e8a11e523319 Mon Sep 17 00:00:00 2001 From: Hyzhou <1187766782@qq.com> Date: Fri, 8 Apr 2016 08:52:10 +0800 Subject: [PATCH 05/13] Fix the docker image --no-trunk output format docker 1.10 change the output format of image id. Signed-off-by: hyzhou.zhy <hyzhou.zhy@alibaba-inc.com> (cherry picked from commit b83e9df7609e705a85545a8a63db81ef73d85b0e) --- docs/reference/commandline/images.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/reference/commandline/images.md b/docs/reference/commandline/images.md index 8419fd0c52..9ab97684c4 100644 --- a/docs/reference/commandline/images.md +++ b/docs/reference/commandline/images.md @@ -85,16 +85,16 @@ If nothing matches `REPOSITORY[:TAG]`, the list is empty. ## Listing the full length image IDs $ docker images --no-trunc - REPOSITORY TAG IMAGE ID CREATED SIZE - <none> <none> 77af4d6b9913e693e8d0b4b294fa62ade6054e6b2f1ffb617ac955dd63fb0182 19 hours ago 1.089 GB - committest latest b6fa739cedf5ea12a620a439402b6004d057da800f91c7524b5086a5e4749c9f 19 hours ago 1.089 GB - <none> <none> 78a85c484f71509adeaace20e72e941f6bdd2b25b4c75da8693efd9f61a37921 19 hours ago 1.089 GB - docker latest 30557a29d5abc51e5f1d5b472e79b7e296f595abcf19fe6b9199dbbc809c6ff4 20 hours ago 1.089 GB - <none> <none> 0124422dd9f9cf7ef15c0617cda3931ee68346455441d66ab8bdc5b05e9fdce5 20 hours ago 1.089 GB - <none> <none> 18ad6fad340262ac2a636efd98a6d1f0ea775ae3d45240d3418466495a19a81b 22 hours ago 1.082 GB - <none> <none> f9f1e26352f0a3ba6a0ff68167559f64f3e21ff7ada60366e2d44a04befd1d3a 23 hours ago 1.089 GB - tryout latest 2629d1fa0b81b222fca63371ca16cbf6a0772d07759ff80e8d1369b926940074 23 hours ago 131.5 MB - <none> <none> 5ed6274db6ceb2397844896966ea239290555e74ef307030ebb01ff91b1914df 24 hours ago 1.089 GB + REPOSITORY TAG IMAGE ID CREATED SIZE + <none> <none> sha256:77af4d6b9913e693e8d0b4b294fa62ade6054e6b2f1ffb617ac955dd63fb0182 19 hours ago 1.089 GB + committest latest sha256:b6fa739cedf5ea12a620a439402b6004d057da800f91c7524b5086a5e4749c9f 19 hours ago 1.089 GB + <none> <none> sha256:78a85c484f71509adeaace20e72e941f6bdd2b25b4c75da8693efd9f61a37921 19 hours ago 1.089 GB + docker latest sha256:30557a29d5abc51e5f1d5b472e79b7e296f595abcf19fe6b9199dbbc809c6ff4 20 hours ago 1.089 GB + <none> <none> sha256:0124422dd9f9cf7ef15c0617cda3931ee68346455441d66ab8bdc5b05e9fdce5 20 hours ago 1.089 GB + <none> <none> sha256:18ad6fad340262ac2a636efd98a6d1f0ea775ae3d45240d3418466495a19a81b 22 hours ago 1.082 GB + <none> <none> sha256:f9f1e26352f0a3ba6a0ff68167559f64f3e21ff7ada60366e2d44a04befd1d3a 23 hours ago 1.089 GB + tryout latest sha256:2629d1fa0b81b222fca63371ca16cbf6a0772d07759ff80e8d1369b926940074 23 hours ago 131.5 MB + <none> <none> sha256:5ed6274db6ceb2397844896966ea239290555e74ef307030ebb01ff91b1914df 24 hours ago 1.089 GB ## Listing image digests From 133773a4d091b830ca4bd2dc953e223ea376064f Mon Sep 17 00:00:00 2001 From: Zhang Wei <zhangwei555@huawei.com> Date: Thu, 7 Apr 2016 11:38:12 +0800 Subject: [PATCH 06/13] Add missing "start" event back for auto-restart container When container is automatically restarted based on restart policy, docker events can't get "start" event but only get "die" event, this is not consistent with previous behavior. This commit will add "start" event back. Signed-off-by: Zhang Wei <zhangwei555@huawei.com> (cherry picked from commit fdfaaeb9aa72404bde5207510bf5910893414b5d) --- daemon/monitor.go | 1 + daemon/start.go | 4 ++- integration-cli/docker_cli_events_test.go | 41 +++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/daemon/monitor.go b/daemon/monitor.go index 0a82c5f8fd..f9f7def98d 100644 --- a/daemon/monitor.go +++ b/daemon/monitor.go @@ -77,6 +77,7 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error { c.Reset(false) return err } + daemon.LogContainerEvent(c, "start") case libcontainerd.StatePause: c.Paused = true daemon.LogContainerEvent(c, "pause") diff --git a/daemon/start.go b/daemon/start.go index 52531f511e..1b34f42692 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -131,7 +131,6 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error) return err } - defer daemon.LogContainerEvent(container, "start") // this is logged even on error if err := daemon.containerd.Create(container.ID, *spec, libcontainerd.WithRestartManager(container.RestartManager(true))); err != nil { // if we receive an internal error from the initial start of a container then lets // return it instead of entering the restart loop @@ -149,6 +148,9 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error) } container.Reset(false) + + // start event is logged even on error + daemon.LogContainerEvent(container, "start") return err } diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go index f426650c2b..f17b711cc2 100644 --- a/integration-cli/docker_cli_events_test.go +++ b/integration-cli/docker_cli_events_test.go @@ -604,3 +604,44 @@ func (s *DockerSuite) TestEventsFilterImageInContainerAction(c *check.C) { events := strings.Split(strings.TrimSpace(out), "\n") c.Assert(len(events), checker.GreaterThan, 1, check.Commentf(out)) } + +func (s *DockerSuite) TestEventsContainerRestart(c *check.C) { + dockerCmd(c, "run", "-d", "--name=testEvent", "--restart=on-failure:3", "busybox", "false") + + // wait until test2 is auto removed. + waitTime := 10 * time.Second + if daemonPlatform == "windows" { + // nslookup isn't present in Windows busybox. Is built-in. + waitTime = 90 * time.Second + } + + err := waitInspect("testEvent", "{{ .State.Restarting }} {{ .State.Running }}", "false false", waitTime) + c.Assert(err, checker.IsNil) + + var ( + createCount int + startCount int + dieCount int + ) + out, _ := dockerCmd(c, "events", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "-f", "container=testEvent") + events := strings.Split(strings.TrimSpace(out), "\n") + + nEvents := len(events) + c.Assert(nEvents, checker.GreaterOrEqualThan, 1) //Missing expected event + actions := eventActionsByIDAndType(c, events, "testEvent", "container") + + for _, a := range actions { + switch a { + case "create": + createCount++ + case "start": + startCount++ + case "die": + dieCount++ + } + } + c.Assert(createCount, checker.Equals, 1, check.Commentf("testEvent should be created 1 times: %v", actions)) + c.Assert(startCount, checker.Equals, 4, check.Commentf("testEvent should start 4 times: %v", actions)) + c.Assert(dieCount, checker.Equals, 4, check.Commentf("testEvent should die 4 times: %v", actions)) + +} From eb405d2b73f90c2bf311110f8f39c0c415837297 Mon Sep 17 00:00:00 2001 From: Lei Jitang <leijitang@huawei.com> Date: Thu, 7 Apr 2016 22:09:07 -0400 Subject: [PATCH 07/13] Fix docker stats missing memory limit Signed-off-by: Lei Jitang <leijitang@huawei.com> (cherry picked from commit a0a6d031d76c1bf9d5581a8310b8a2d1df4b7b82) --- daemon/daemon_unix.go | 5 +++++ daemon/stats_collector_unix.go | 7 ++++++ integration-cli/docker_api_stats_test.go | 28 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index a152fd0e95..9a4ab32296 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -1092,6 +1092,11 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) { MaxUsage: mem.MaxUsage, Stats: cgs.MemoryStats.Stats, Failcnt: mem.Failcnt, + Limit: mem.Limit, + } + // if the container does not set memory limit, use the machineMemory + if mem.Limit > daemon.statsCollector.machineMemory && daemon.statsCollector.machineMemory > 0 { + s.MemoryStats.Limit = daemon.statsCollector.machineMemory } if cgs.PidsStats != nil { s.PidsStats = types.PidsStats{ diff --git a/daemon/stats_collector_unix.go b/daemon/stats_collector_unix.go index 5010281498..fb1931dfb8 100644 --- a/daemon/stats_collector_unix.go +++ b/daemon/stats_collector_unix.go @@ -14,6 +14,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/container" "github.com/docker/docker/pkg/pubsub" + sysinfo "github.com/docker/docker/pkg/system" "github.com/docker/engine-api/types" "github.com/opencontainers/runc/libcontainer/system" ) @@ -35,6 +36,11 @@ func (daemon *Daemon) newStatsCollector(interval time.Duration) *statsCollector clockTicksPerSecond: uint64(system.GetClockTicks()), bufReader: bufio.NewReaderSize(nil, 128), } + meminfo, err := sysinfo.ReadMemInfo() + if err == nil && meminfo.MemTotal > 0 { + s.machineMemory = uint64(meminfo.MemTotal) + } + go s.run() return s } @@ -47,6 +53,7 @@ type statsCollector struct { clockTicksPerSecond uint64 publishers map[*container.Container]*pubsub.Publisher bufReader *bufio.Reader + machineMemory uint64 } // collect registers the container with the collector and adds it to diff --git a/integration-cli/docker_api_stats_test.go b/integration-cli/docker_api_stats_test.go index 10c9fd5b20..7c3f8d3916 100644 --- a/integration-cli/docker_api_stats_test.go +++ b/integration-cli/docker_api_stats_test.go @@ -227,3 +227,31 @@ func (s *DockerSuite) TestApiStatsContainerNotFound(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(status, checker.Equals, http.StatusNotFound) } + +func (s *DockerSuite) TestApiStatsContainerGetMemoryLimit(c *check.C) { + testRequires(c, DaemonIsLinux) + + resp, body, err := sockRequestRaw("GET", "/info", nil, "application/json") + c.Assert(err, checker.IsNil) + c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) + var info types.Info + err = json.NewDecoder(body).Decode(&info) + c.Assert(err, checker.IsNil) + body.Close() + + // don't set a memory limit, the memory limit should be system memory + conName := "foo" + dockerCmd(c, "run", "-d", "--name", conName, "busybox", "top") + c.Assert(waitRun(conName), checker.IsNil) + + resp, body, err = sockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", conName), nil, "") + c.Assert(err, checker.IsNil) + c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) + c.Assert(resp.Header.Get("Content-Type"), checker.Equals, "application/json") + + var v *types.Stats + err = json.NewDecoder(body).Decode(&v) + c.Assert(err, checker.IsNil) + body.Close() + c.Assert(fmt.Sprintf("%d", v.MemoryStats.Limit), checker.Equals, fmt.Sprintf("%d", info.MemTotal)) +} From 0b25417cce2ddb2b6ec14fd24a6b9d3ec93b2271 Mon Sep 17 00:00:00 2001 From: Yi EungJun <eungjun.yi@navercorp.com> Date: Sat, 9 Apr 2016 19:15:55 +0900 Subject: [PATCH 08/13] Fix errata; s/RequestUri/ReqestURI/ Signed-off-by: Yi EungJun <eungjun.yi@navercorp.com> (cherry picked from commit 94985b4bfff4fec6f4a7cb0b0f8b641a7dcfcbd1) --- docs/extend/plugins_authorization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/extend/plugins_authorization.md b/docs/extend/plugins_authorization.md index 7db31b85c4..31a6a072ab 100644 --- a/docs/extend/plugins_authorization.md +++ b/docs/extend/plugins_authorization.md @@ -149,7 +149,7 @@ should implement the following two methods: "User": "The user identification", "UserAuthNMethod": "The authentication method used", "RequestMethod": "The HTTP method", - "RequestUri": "The HTTP request URI", + "RequestURI": "The HTTP request URI", "RequestBody": "Byte array containing the raw HTTP request body", "RequestHeader": "Byte array containing the raw HTTP request header as a map[string][]string ", "RequestStatusCode": "Request status code" @@ -174,7 +174,7 @@ should implement the following two methods: "User": "The user identification", "UserAuthNMethod": "The authentication method used", "RequestMethod": "The HTTP method", - "RequestUri": "The HTTP request URI", + "RequestURI": "The HTTP request URI", "RequestBody": "Byte array containing the raw HTTP request body", "RequestHeader": "Byte array containing the raw HTTP request header as a map[string][]string", "RequestStatusCode": "Request status code", From cbd50baf8b8e52cfbf7a762389b3be4f9915fc27 Mon Sep 17 00:00:00 2001 From: Yong Tang <yong.tang.github@outlook.com> Date: Sat, 9 Apr 2016 18:30:48 +0000 Subject: [PATCH 09/13] Fix incorrect request json body for `/containers/create` in remote API docs. This fix tries to fix the incorrect request json body for `/containers/create` in remote API docs. When using the example json request for `/containers/create`, there are two errors: (1). `invalid character '"' after object key:value pair` This is because a `,` is missing after `"Volumes": {}` This issue exists in v1.20-v1.24 (2). `Invalid --security-opt: ""` This is becasue in `"SecurityOpt": [""]` line, an empty string `""` is passed yet `""` is not a valid `SecurityOpt`. Either no string, or a valid string (e.g., "no-new-privileges") could be used. This issue exists in v1.15-v1.24 This fix updates the docs and correct the above two issues. Signed-off-by: Yong Tang <yong.tang.github@outlook.com> (cherry picked from commit f919a26a9fb96ef07133183b4f693ff9508ae823) --- docs/reference/api/docker_remote_api_v1.15.md | 2 +- docs/reference/api/docker_remote_api_v1.16.md | 2 +- docs/reference/api/docker_remote_api_v1.17.md | 2 +- docs/reference/api/docker_remote_api_v1.18.md | 2 +- docs/reference/api/docker_remote_api_v1.19.md | 2 +- docs/reference/api/docker_remote_api_v1.20.md | 4 ++-- docs/reference/api/docker_remote_api_v1.21.md | 4 ++-- docs/reference/api/docker_remote_api_v1.22.md | 4 ++-- docs/reference/api/docker_remote_api_v1.23.md | 4 ++-- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/reference/api/docker_remote_api_v1.15.md b/docs/reference/api/docker_remote_api_v1.15.md index c95a66b0a4..f6a860a4f9 100644 --- a/docs/reference/api/docker_remote_api_v1.15.md +++ b/docs/reference/api/docker_remote_api_v1.15.md @@ -151,7 +151,7 @@ Create a container "ExposedPorts": { "22/tcp": {} }, - "SecurityOpts": [""], + "SecurityOpts": [], "HostConfig": { "Binds": ["/tmp:/tmp"], "Links": ["redis3:redis"], diff --git a/docs/reference/api/docker_remote_api_v1.16.md b/docs/reference/api/docker_remote_api_v1.16.md index f91f408495..630da70144 100644 --- a/docs/reference/api/docker_remote_api_v1.16.md +++ b/docs/reference/api/docker_remote_api_v1.16.md @@ -151,7 +151,7 @@ Create a container "ExposedPorts": { "22/tcp": {} }, - "SecurityOpts": [""], + "SecurityOpts": [], "HostConfig": { "Binds": ["/tmp:/tmp"], "Links": ["redis3:redis"], diff --git a/docs/reference/api/docker_remote_api_v1.17.md b/docs/reference/api/docker_remote_api_v1.17.md index 3da962b074..9baa758cc5 100644 --- a/docs/reference/api/docker_remote_api_v1.17.md +++ b/docs/reference/api/docker_remote_api_v1.17.md @@ -168,7 +168,7 @@ Create a container "RestartPolicy": { "Name": "", "MaximumRetryCount": 0 }, "NetworkMode": "bridge", "Devices": [], - "SecurityOpt": [""] + "SecurityOpt": [] } } diff --git a/docs/reference/api/docker_remote_api_v1.18.md b/docs/reference/api/docker_remote_api_v1.18.md index 421b169623..9de2cc6cf1 100644 --- a/docs/reference/api/docker_remote_api_v1.18.md +++ b/docs/reference/api/docker_remote_api_v1.18.md @@ -184,7 +184,7 @@ Create a container "Devices": [], "Ulimits": [{}], "LogConfig": { "Type": "json-file", Config: {} }, - "SecurityOpt": [""], + "SecurityOpt": [], "CgroupParent": "" } } diff --git a/docs/reference/api/docker_remote_api_v1.19.md b/docs/reference/api/docker_remote_api_v1.19.md index 9eeb353efe..e049dbe7c4 100644 --- a/docs/reference/api/docker_remote_api_v1.19.md +++ b/docs/reference/api/docker_remote_api_v1.19.md @@ -191,7 +191,7 @@ Create a container "Devices": [], "Ulimits": [{}], "LogConfig": { "Type": "json-file", "Config": {} }, - "SecurityOpt": [""], + "SecurityOpt": [], "CgroupParent": "" } } diff --git a/docs/reference/api/docker_remote_api_v1.20.md b/docs/reference/api/docker_remote_api_v1.20.md index ac0fc80813..dd47ff7f1f 100644 --- a/docs/reference/api/docker_remote_api_v1.20.md +++ b/docs/reference/api/docker_remote_api_v1.20.md @@ -156,7 +156,7 @@ Create a container }, "Volumes": { "/volumes/data": {} - } + }, "WorkingDir": "", "NetworkDisabled": false, "MacAddress": "12:34:56:78:9a:bc", @@ -193,7 +193,7 @@ Create a container "Devices": [], "Ulimits": [{}], "LogConfig": { "Type": "json-file", "Config": {} }, - "SecurityOpt": [""], + "SecurityOpt": [], "CgroupParent": "" } } diff --git a/docs/reference/api/docker_remote_api_v1.21.md b/docs/reference/api/docker_remote_api_v1.21.md index 6b3ac2e825..7cdfd0f3f3 100644 --- a/docs/reference/api/docker_remote_api_v1.21.md +++ b/docs/reference/api/docker_remote_api_v1.21.md @@ -160,7 +160,7 @@ Create a container }, "Volumes": { "/volumes/data": {} - } + }, "WorkingDir": "", "NetworkDisabled": false, "MacAddress": "12:34:56:78:9a:bc", @@ -201,7 +201,7 @@ Create a container "Devices": [], "Ulimits": [{}], "LogConfig": { "Type": "json-file", "Config": {} }, - "SecurityOpt": [""], + "SecurityOpt": [], "CgroupParent": "", "VolumeDriver": "" } diff --git a/docs/reference/api/docker_remote_api_v1.22.md b/docs/reference/api/docker_remote_api_v1.22.md index badd170566..d9a860a774 100644 --- a/docs/reference/api/docker_remote_api_v1.22.md +++ b/docs/reference/api/docker_remote_api_v1.22.md @@ -248,7 +248,7 @@ Create a container }, "Volumes": { "/volumes/data": {} - } + }, "WorkingDir": "", "NetworkDisabled": false, "MacAddress": "12:34:56:78:9a:bc", @@ -294,7 +294,7 @@ Create a container "Devices": [], "Ulimits": [{}], "LogConfig": { "Type": "json-file", "Config": {} }, - "SecurityOpt": [""], + "SecurityOpt": [], "CgroupParent": "", "VolumeDriver": "", "ShmSize": 67108864 diff --git a/docs/reference/api/docker_remote_api_v1.23.md b/docs/reference/api/docker_remote_api_v1.23.md index d235e4219c..eac495f09f 100644 --- a/docs/reference/api/docker_remote_api_v1.23.md +++ b/docs/reference/api/docker_remote_api_v1.23.md @@ -267,7 +267,7 @@ Create a container }, "Volumes": { "/volumes/data": {} - } + }, "WorkingDir": "", "NetworkDisabled": false, "MacAddress": "12:34:56:78:9a:bc", @@ -313,7 +313,7 @@ Create a container "Devices": [], "Ulimits": [{}], "LogConfig": { "Type": "json-file", "Config": {} }, - "SecurityOpt": [""], + "SecurityOpt": [], "CgroupParent": "", "VolumeDriver": "", "ShmSize": 67108864 From b4f0d6884352ed5b33c932be68ac4377fd487f9e Mon Sep 17 00:00:00 2001 From: Steve Durrheimer <s.durrheimer@gmail.com> Date: Sat, 9 Apr 2016 17:34:46 +0200 Subject: [PATCH 10/13] Add zsh completion for '--log-opt syslog-format' Signed-off-by: Steve Durrheimer <s.durrheimer@gmail.com> (cherry picked from commit 6e14ebd030ac8803438a183d5135100320caa035) --- contrib/completion/zsh/_docker | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index 1351ae9579..cb007b90d4 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -216,7 +216,7 @@ __docker_get_log_options() { gelf_options=("env" "gelf-address" "gelf-compression-level" "gelf-compression-type" "labels" "tag") journald_options=("env" "labels" "tag") json_file_options=("env" "labels" "max-file" "max-size") - syslog_options=("syslog-address" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "syslog-facility" "tag") + syslog_options=("syslog-address" "syslog-format" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "syslog-facility" "tag") splunk_options=("env" "labels" "splunk-caname" "splunk-capath" "splunk-index" "splunk-insecureskipverify" "splunk-source" "splunk-sourcetype" "splunk-token" "splunk-url" "tag") [[ $log_driver = (awslogs|all) ]] && _describe -t awslogs-options "awslogs options" awslogs_options "$@" && ret=0 @@ -236,7 +236,15 @@ __docker_log_options() { integer ret=1 if compset -P '*='; then - _message 'value' && ret=0 + case "${${words[-1]%=*}#*=}" in + (syslog-format) + syslog_format_opts=('rfc3164' 'rfc5424') + _describe -t syslog-format-opts "Syslog format Options" syslog_format_opts && ret=0 + ;; + *) + _message 'value' && ret=0 + ;; + esac else __docker_get_log_options -qS "=" && ret=0 fi From 7ae170ddab1248d1abf2841cb7e8430cbfe4a62b Mon Sep 17 00:00:00 2001 From: Zhang Wei <zhangwei555@huawei.com> Date: Thu, 7 Apr 2016 22:05:29 +0800 Subject: [PATCH 11/13] Fix critical bug: can't restart a restarting container When user try to restart a restarting container, docker client report error: "container is already active", and container will be stopped instead be restarted which is seriously wrong. What's more critical is that when user try to start this container again, it will always fail. This error can also be reproduced with a `docker stop`+`docker start`. And this commit will fix the bug. Signed-off-by: Zhang Wei <zhangwei555@huawei.com> (cherry picked from commit a705e166cf3bcca62543150c2b3f9bfeae45ecfa) --- daemon/kill.go | 10 +++++++- integration-cli/docker_cli_restart_test.go | 29 ++++++++++++++++++++++ libcontainerd/client_linux.go | 2 +- libcontainerd/container_linux.go | 1 + restartmanager/restartmanager.go | 2 +- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/daemon/kill.go b/daemon/kill.go index e6ccfc7955..3967f0f299 100644 --- a/daemon/kill.go +++ b/daemon/kill.go @@ -3,6 +3,7 @@ package daemon import ( "fmt" "runtime" + "strings" "syscall" "time" @@ -81,7 +82,14 @@ func (daemon *Daemon) killWithSignal(container *container.Container, sig int) er } if err := daemon.kill(container, sig); err != nil { - return fmt.Errorf("Cannot kill container %s: %s", container.ID, err) + err = fmt.Errorf("Cannot kill container %s: %s", container.ID, err) + // if container or process not exists, ignore the error + if strings.Contains(err.Error(), "container not found") || + strings.Contains(err.Error(), "no such process") { + logrus.Warnf("%s", err.Error()) + } else { + return err + } } attributes := map[string]string{ diff --git a/integration-cli/docker_cli_restart_test.go b/integration-cli/docker_cli_restart_test.go index 12fe1c4e54..31c8920385 100644 --- a/integration-cli/docker_cli_restart_test.go +++ b/integration-cli/docker_cli_restart_test.go @@ -218,3 +218,32 @@ func (s *DockerSuite) TestRestartPolicyAfterRestart(c *check.C) { err = waitInspect(id, "{{.State.Status}}", "running", 30*time.Second) c.Assert(err, check.IsNil) } + +func (s *DockerSuite) TestRestartContainerwithRestartPolicy(c *check.C) { + out1, _ := dockerCmd(c, "run", "-d", "--restart=on-failure:3", "busybox", "false") + out2, _ := dockerCmd(c, "run", "-d", "--restart=always", "busybox", "false") + + id1 := strings.TrimSpace(string(out1)) + id2 := strings.TrimSpace(string(out2)) + err := waitInspect(id1, "{{ .State.Restarting }} {{ .State.Running }}", "false false", 30*time.Second) + c.Assert(err, checker.IsNil) + + // TODO: fix racey problem during restart: + // https://jenkins.dockerproject.org/job/Docker-PRs-Win2Lin/24665/console + // Error response from daemon: Cannot restart container 6655f620d90b390527db23c0a15b3e46d86a58ecec20a5697ab228d860174251: remove /var/run/docker/libcontainerd/6655f620d90b390527db23c0a15b3e46d86a58ecec20a5697ab228d860174251/rootfs: device or resource busy + if _, _, err := dockerCmdWithError("restart", id1); err != nil { + // if restart met racey problem, try again + time.Sleep(500 * time.Millisecond) + dockerCmd(c, "restart", id1) + } + if _, _, err := dockerCmdWithError("restart", id2); err != nil { + // if restart met racey problem, try again + time.Sleep(500 * time.Millisecond) + dockerCmd(c, "restart", id2) + } + + dockerCmd(c, "stop", id1) + dockerCmd(c, "stop", id2) + dockerCmd(c, "start", id1) + dockerCmd(c, "start", id2) +} diff --git a/libcontainerd/client_linux.go b/libcontainerd/client_linux.go index f747b2fe2e..01806da889 100644 --- a/libcontainerd/client_linux.go +++ b/libcontainerd/client_linux.go @@ -134,7 +134,7 @@ func (clnt *client) Create(containerID string, spec Spec, options ...CreateOptio defer clnt.unlock(containerID) if ctr, err := clnt.getContainer(containerID); err == nil { - if ctr.restarting { // docker doesn't actually call start if restart is on atm, but probably should in the future + if ctr.restarting { ctr.restartManager.Cancel() ctr.clean() } else { diff --git a/libcontainerd/container_linux.go b/libcontainerd/container_linux.go index 506a1770dd..6f168ca1da 100644 --- a/libcontainerd/container_linux.go +++ b/libcontainerd/container_linux.go @@ -121,6 +121,7 @@ func (ctr *container) handleEvent(e *containerd.Event) error { } else if restart { st.State = StateRestart ctr.restarting = true + ctr.client.deleteContainer(e.Id) go func() { err := <-wait ctr.restarting = false diff --git a/restartmanager/restartmanager.go b/restartmanager/restartmanager.go index e534b2cf73..39b8b1502c 100644 --- a/restartmanager/restartmanager.go +++ b/restartmanager/restartmanager.go @@ -51,7 +51,7 @@ func (rm *restartManager) ShouldRestart(exitCode uint32) (bool, chan error, erro }() if rm.canceled { - return false, nil, nil + return false, nil, fmt.Errorf("restartmanager canceled") } if rm.active { From 490c26524ca2fd3b559f1ea5f94f94cbe972799e Mon Sep 17 00:00:00 2001 From: Mihai Borobocea <MihaiBorob@gmail.com> Date: Sun, 10 Apr 2016 17:22:02 +0300 Subject: [PATCH 12/13] docs: fix grammar typo in 'Network containers' Signed-off-by: Mihai Borobocea <MihaiBorob@gmail.com> (cherry picked from commit a609c2c48b5d504120777db2ac1ba83bfe355b66) --- docs/userguide/containers/networkingcontainers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/userguide/containers/networkingcontainers.md b/docs/userguide/containers/networkingcontainers.md index 1ac1364d3a..9355e756f6 100644 --- a/docs/userguide/containers/networkingcontainers.md +++ b/docs/userguide/containers/networkingcontainers.md @@ -35,7 +35,7 @@ You name your container by using the `--name` flag, for example launch a new con $ docker run -d -P --name web training/webapp python app.py -Use the `docker ps` command to see check the name: +Use the `docker ps` command to check the name: $ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES From 3522bdfc996ba4a81f0d6d0a38b8cf3735490485 Mon Sep 17 00:00:00 2001 From: Santhosh Manohar <santhosh@docker.com> Date: Fri, 8 Apr 2016 19:00:35 -0700 Subject: [PATCH 13/13] Vendor Libnetwork v0.7.0-rc.6 Signed-off-by: Santhosh Manohar <santhosh@docker.com> (cherry picked from commit 6dd2c3321793c3fe60abb94b88018e4b096f12c7) --- hack/vendor.sh | 2 +- .../github.com/docker/libnetwork/CHANGELOG.md | 10 ++++++++++ .../docker/libnetwork/Dockerfile.build | 1 - .../docker/libnetwork/drivers/remote/driver.go | 9 ++------- .../github.com/docker/libnetwork/endpoint.go | 4 ++++ .../src/github.com/docker/libnetwork/network.go | 17 +++++++++++++++++ .../github.com/docker/libnetwork/resolver.go | 13 ++++++++----- 7 files changed, 42 insertions(+), 14 deletions(-) diff --git a/hack/vendor.sh b/hack/vendor.sh index f3fdea3438..033e88dc65 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -30,7 +30,7 @@ clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837 clone git github.com/imdario/mergo 0.2.1 #get libnetwork packages -clone git github.com/docker/libnetwork v0.7.0-rc.4 +clone git github.com/docker/libnetwork v0.7.0-rc.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/vendor/src/github.com/docker/libnetwork/CHANGELOG.md b/vendor/src/github.com/docker/libnetwork/CHANGELOG.md index 0eb85cde52..883830f5cd 100644 --- a/vendor/src/github.com/docker/libnetwork/CHANGELOG.md +++ b/vendor/src/github.com/docker/libnetwork/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.7.0-rc.6 (2016-04-10) +- Flush cached resolver socket on default gateway change + +## 0.7.0-rc.5 (2016-04-08) +- Persist ipam driver options +- Fixes https://github.com/docker/libnetwork/issues/1087 +- Use go vet from go tool +- Godep update to pick up latest docker/docker packages +- Validate remote driver response using docker plugins package method. + ## 0.7.0-rc.4 (2016-04-06) - Fix the handling for default gateway Endpoint join/leave. diff --git a/vendor/src/github.com/docker/libnetwork/Dockerfile.build b/vendor/src/github.com/docker/libnetwork/Dockerfile.build index 01b690e955..035f852c03 100644 --- a/vendor/src/github.com/docker/libnetwork/Dockerfile.build +++ b/vendor/src/github.com/docker/libnetwork/Dockerfile.build @@ -3,6 +3,5 @@ RUN apt-get update && apt-get -y install iptables RUN go get github.com/tools/godep \ github.com/golang/lint/golint \ - golang.org/x/tools/cmd/vet \ golang.org/x/tools/cmd/cover\ github.com/mattn/goveralls diff --git a/vendor/src/github.com/docker/libnetwork/drivers/remote/driver.go b/vendor/src/github.com/docker/libnetwork/drivers/remote/driver.go index 32533533dd..e3f2cd58e2 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/remote/driver.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/remote/driver.go @@ -3,7 +3,6 @@ package remote import ( "fmt" "net" - "strings" log "github.com/Sirupsen/logrus" "github.com/docker/docker/pkg/plugins" @@ -14,10 +13,6 @@ import ( "github.com/docker/libnetwork/types" ) -const ( - missingMethod = "404 page not found" -) - type driver struct { endpoint *plugins.Client networkType string @@ -260,7 +255,7 @@ func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string Options: options, } err := d.call("ProgramExternalConnectivity", data, &api.ProgramExternalConnectivityResponse{}) - if err != nil && strings.Contains(err.Error(), missingMethod) { + if err != nil && plugins.IsNotFound(err) { // It is not mandatory yet to support this method return nil } @@ -274,7 +269,7 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error { EndpointID: eid, } err := d.call("RevokeExternalConnectivity", data, &api.RevokeExternalConnectivityResponse{}) - if err != nil && strings.Contains(err.Error(), missingMethod) { + if err != nil && plugins.IsNotFound(err) { // It is not mandatory yet to support this method return nil } diff --git a/vendor/src/github.com/docker/libnetwork/endpoint.go b/vendor/src/github.com/docker/libnetwork/endpoint.go index 55b3a8e1ab..7608dd7457 100644 --- a/vendor/src/github.com/docker/libnetwork/endpoint.go +++ b/vendor/src/github.com/docker/libnetwork/endpoint.go @@ -477,6 +477,10 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error { ep.Name(), ep.ID(), err) } } + + if sb.resolver != nil { + sb.resolver.FlushExtServers() + } } if !sb.needDefaultGW() { diff --git a/vendor/src/github.com/docker/libnetwork/network.go b/vendor/src/github.com/docker/libnetwork/network.go index ed2b52c790..a14550cd7e 100644 --- a/vendor/src/github.com/docker/libnetwork/network.go +++ b/vendor/src/github.com/docker/libnetwork/network.go @@ -320,6 +320,13 @@ func (n *network) CopyTo(o datastore.KVObject) error { dstN.labels[k] = v } + if n.ipamOptions != nil { + dstN.ipamOptions = make(map[string]string, len(n.ipamOptions)) + for k, v := range n.ipamOptions { + dstN.ipamOptions[k] = v + } + } + for _, v4conf := range n.ipamV4Config { dstV4Conf := &IpamConf{} v4conf.CopyTo(dstV4Conf) @@ -372,6 +379,7 @@ func (n *network) MarshalJSON() ([]byte, error) { netMap["scope"] = n.scope netMap["labels"] = n.labels netMap["ipamType"] = n.ipamType + netMap["ipamOptions"] = n.ipamOptions netMap["addrSpace"] = n.addrSpace netMap["enableIPv6"] = n.enableIPv6 if n.generic != nil { @@ -432,6 +440,15 @@ func (n *network) UnmarshalJSON(b []byte) (err error) { } } + if v, ok := netMap["ipamOptions"]; ok { + if iOpts, ok := v.(map[string]interface{}); ok { + n.ipamOptions = make(map[string]string, len(iOpts)) + for k, v := range iOpts { + n.ipamOptions[k] = v.(string) + } + } + } + if v, ok := netMap["generic"]; ok { n.generic = v.(map[string]interface{}) // Restore opts in their map[string]string form diff --git a/vendor/src/github.com/docker/libnetwork/resolver.go b/vendor/src/github.com/docker/libnetwork/resolver.go index 7af1850cf6..cff692fd1f 100644 --- a/vendor/src/github.com/docker/libnetwork/resolver.go +++ b/vendor/src/github.com/docker/libnetwork/resolver.go @@ -45,7 +45,7 @@ const ( ptrIPv6domain = ".ip6.arpa." respTTL = 600 maxExtDNS = 3 //max number of external servers to try - extIOTimeout = 3 * time.Second + extIOTimeout = 4 * time.Second defaultRespSize = 512 maxConcurrent = 50 logInterval = 2 * time.Second @@ -158,6 +158,10 @@ func (r *resolver) Start() error { func (r *resolver) FlushExtServers() { for i := 0; i < maxExtDNS; i++ { + if r.extDNSList[i].extConn != nil { + r.extDNSList[i].extConn.Close() + } + r.extDNSList[i].extConn = nil r.extDNSList[i].extOnce = sync.Once{} } @@ -344,9 +348,6 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) { if extDNS.ipStr == "" { break } - log.Debugf("Query %s[%d] from %s, forwarding to %s:%s", name, query.Question[0].Qtype, - w.LocalAddr().String(), proto, extDNS.ipStr) - extConnect := func() { addr := fmt.Sprintf("%s:%d", extDNS.ipStr, 53) extConn, err = net.DialTimeout(proto, addr, extIOTimeout) @@ -378,6 +379,8 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) { if extConn == nil { continue } + log.Debugf("Query %s[%d] from %s, forwarding to %s:%s", name, query.Question[0].Qtype, + extConn.LocalAddr().String(), proto, extDNS.ipStr) // Timeout has to be set for every IO operation. extConn.SetDeadline(time.Now().Add(extIOTimeout)) @@ -424,7 +427,7 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) { break } - if resp == nil { + if resp == nil || w == nil { return } }