From d99532f55d5e01135b0f0c9433708c397aaa612c Mon Sep 17 00:00:00 2001
From: Boaz Shuster <ripcurld.github@gmail.com>
Date: Thu, 3 Nov 2016 12:07:18 +0200
Subject: [PATCH 1/5] Return an empty stats if the container is restarting

In case, a container is restarting indefinitely running
"docker stats --no-stream <restarting_container>" is suspended.

To fix this, the daemon makes sure the container is either not
running or restarting if `--no-stream` is set to true and if so
returns an empty stats.

Should fix #27772.

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
(cherry picked from commit 786a95493d54d74fa3eef020c1ec03baa4fe91c4)
Signed-off-by: Victor Vieux <victorvieux@gmail.com>
---
 daemon/stats.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/daemon/stats.go b/daemon/stats.go
index f76a689775..7f9bef08cb 100644
--- a/daemon/stats.go
+++ b/daemon/stats.go
@@ -30,8 +30,8 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
 		return err
 	}
 
-	// If the container is not running and requires no stream, return an empty stats.
-	if !container.IsRunning() && !config.Stream {
+	// If the container is either not running or restarting and requires no stream, return an empty stats.
+	if (!container.IsRunning() || container.IsRestarting()) && !config.Stream {
 		return json.NewEncoder(config.OutStream).Encode(&types.Stats{})
 	}
 

From 4da9f493397088eeb936a404a61d784ae966a0a5 Mon Sep 17 00:00:00 2001
From: Brian Goff <cpuguy83@gmail.com>
Date: Mon, 21 Nov 2016 14:24:53 -0500
Subject: [PATCH 2/5] re-vendor syslog log driver

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 00caf03132a1bf1a2a7a389c5f23d6fc81f2bc0b)
Signed-off-by: Victor Vieux <victorvieux@gmail.com>
---
 hack/vendor.sh                                |  2 +-
 .../src/github.com/RackSec/srslog/srslog.go   |  5 +-
 .../src/github.com/RackSec/srslog/writer.go   | 73 ++++++++++++-------
 3 files changed, 49 insertions(+), 31 deletions(-)

diff --git a/hack/vendor.sh b/hack/vendor.sh
index 23861046ba..3f4b031073 100755
--- a/hack/vendor.sh
+++ b/hack/vendor.sh
@@ -61,7 +61,7 @@ clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://gith
 clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
 clone git github.com/docker/go-connections fa2850ff103453a9ad190da0df0af134f0314b3d
 clone git github.com/docker/engine-api 4eca04ae18f4f93f40196a17b9aa6e11262a7269
-clone git github.com/RackSec/srslog 365bf33cd9acc21ae1c355209865f17228ca534e
+clone git github.com/RackSec/srslog 456df3a81436d29ba874f3590eeeee25d666f8a5
 clone git github.com/imdario/mergo 0.2.1
 
 #get libnetwork packages
diff --git a/vendor/src/github.com/RackSec/srslog/srslog.go b/vendor/src/github.com/RackSec/srslog/srslog.go
index 4469d720c3..b404dff7c5 100644
--- a/vendor/src/github.com/RackSec/srslog/srslog.go
+++ b/vendor/src/github.com/RackSec/srslog/srslog.go
@@ -77,10 +77,7 @@ func DialWithTLSConfig(network, raddr string, priority Priority, tag string, tls
 		tlsConfig: tlsConfig,
 	}
 
-	w.Lock()
-	defer w.Unlock()
-
-	err := w.connect()
+	_, err := w.connect()
 	if err != nil {
 		return nil, err
 	}
diff --git a/vendor/src/github.com/RackSec/srslog/writer.go b/vendor/src/github.com/RackSec/srslog/writer.go
index fdecaf61f6..ce3d867635 100644
--- a/vendor/src/github.com/RackSec/srslog/writer.go
+++ b/vendor/src/github.com/RackSec/srslog/writer.go
@@ -8,8 +8,6 @@ import (
 
 // A Writer is a connection to a syslog server.
 type Writer struct {
-	sync.Mutex // guards conn
-
 	priority  Priority
 	tag       string
 	hostname  string
@@ -19,28 +17,48 @@ type Writer struct {
 	framer    Framer
 	formatter Formatter
 
+	mu   sync.RWMutex // guards conn
 	conn serverConn
 }
 
+// getConn provides access to the internal conn, protected by a mutex. The
+// conn is threadsafe, so it can be used while unlocked, but we want to avoid
+// race conditions on grabbing a reference to it.
+func (w *Writer) getConn() serverConn {
+	w.mu.RLock()
+	conn := w.conn
+	w.mu.RUnlock()
+	return conn
+}
+
+// setConn updates the internal conn, protected by a mutex.
+func (w *Writer) setConn(c serverConn) {
+	w.mu.Lock()
+	w.conn = c
+	w.mu.Unlock()
+}
+
 // connect makes a connection to the syslog server.
-// It must be called with w.mu held.
-func (w *Writer) connect() (err error) {
-	if w.conn != nil {
+func (w *Writer) connect() (serverConn, error) {
+	conn := w.getConn()
+	if conn != nil {
 		// ignore err from close, it makes sense to continue anyway
-		w.conn.close()
-		w.conn = nil
+		conn.close()
+		w.setConn(nil)
 	}
 
-	var conn serverConn
 	var hostname string
+	var err error
 	dialer := w.getDialer()
 	conn, hostname, err = dialer.Call()
 	if err == nil {
-		w.conn = conn
+		w.setConn(conn)
 		w.hostname = hostname
-	}
 
-	return
+		return conn, nil
+	} else {
+		return nil, err
+	}
 }
 
 // SetFormatter changes the formatter function for subsequent messages.
@@ -59,14 +77,17 @@ func (w *Writer) Write(b []byte) (int, error) {
 	return w.writeAndRetry(w.priority, string(b))
 }
 
+// WriteWithPriority sends a log message with a custom priority
+func (w *Writer) WriteWithPriority(p Priority, b []byte) (int, error) {
+	return w.writeAndRetry(p, string(b))
+}
+
 // Close closes a connection to the syslog daemon.
 func (w *Writer) Close() error {
-	w.Lock()
-	defer w.Unlock()
-
-	if w.conn != nil {
-		err := w.conn.close()
-		w.conn = nil
+	conn := w.getConn()
+	if conn != nil {
+		err := conn.close()
+		w.setConn(nil)
 		return err
 	}
 	return nil
@@ -131,29 +152,29 @@ func (w *Writer) Debug(m string) (err error) {
 func (w *Writer) writeAndRetry(p Priority, s string) (int, error) {
 	pr := (w.priority & facilityMask) | (p & severityMask)
 
-	w.Lock()
-	defer w.Unlock()
-
-	if w.conn != nil {
-		if n, err := w.write(pr, s); err == nil {
+	conn := w.getConn()
+	if conn != nil {
+		if n, err := w.write(conn, pr, s); err == nil {
 			return n, err
 		}
 	}
-	if err := w.connect(); err != nil {
+
+	var err error
+	if conn, err = w.connect(); err != nil {
 		return 0, err
 	}
-	return w.write(pr, s)
+	return w.write(conn, pr, s)
 }
 
 // write generates and writes a syslog formatted string. It formats the
 // message based on the current Formatter and Framer.
-func (w *Writer) write(p Priority, msg string) (int, error) {
+func (w *Writer) write(conn serverConn, p Priority, msg string) (int, error) {
 	// ensure it ends in a \n
 	if !strings.HasSuffix(msg, "\n") {
 		msg += "\n"
 	}
 
-	err := w.conn.writeString(w.framer, w.formatter, p, w.hostname, w.tag, msg)
+	err := conn.writeString(w.framer, w.formatter, p, w.hostname, w.tag, msg)
 	if err != nil {
 		return 0, err
 	}

From ed6b8d61c6fc6f54960550654c3c0f6b94cd8fcd Mon Sep 17 00:00:00 2001
From: Stephen J Day <stephen.day@docker.com>
Date: Wed, 16 Nov 2016 18:58:55 -0800
Subject: [PATCH 3/5] api/server/httputils: ensure consistent status code

Error code resolution is powered by string matching. Not the greatest
thing in the world and I hope no one is proud of this code, but it
works. However, because a map is used, the iteration order of the map is
random, such that if an error matches two of the snippets, it may return
a different error code depending on the seed of the hashmap. This change
converts it to use a slice instead.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
(cherry picked from commit 3484e02590117d175d9c1ab24c583390b4e94a55)
Signed-off-by: Victor Vieux <victorvieux@gmail.com>
---
 api/server/httputils/errors.go | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/api/server/httputils/errors.go b/api/server/httputils/errors.go
index da4db97915..6991a06b8b 100644
--- a/api/server/httputils/errors.go
+++ b/api/server/httputils/errors.go
@@ -49,20 +49,23 @@ func GetHTTPErrorStatusCode(err error) int {
 		// If we need to differentiate between different possible error types,
 		// we should create appropriate error types that implement the httpStatusError interface.
 		errStr := strings.ToLower(errMsg)
-		for keyword, status := range map[string]int{
-			"not found":             http.StatusNotFound,
-			"no such":               http.StatusNotFound,
-			"bad parameter":         http.StatusBadRequest,
-			"no command":            http.StatusBadRequest,
-			"conflict":              http.StatusConflict,
-			"impossible":            http.StatusNotAcceptable,
-			"wrong login/password":  http.StatusUnauthorized,
-			"unauthorized":          http.StatusUnauthorized,
-			"hasn't been activated": http.StatusForbidden,
-			"this node":             http.StatusNotAcceptable,
+		for _, status := range []struct {
+			keyword string
+			code    int
+		}{
+			{"not found", http.StatusNotFound},
+			{"no such", http.StatusNotFound},
+			{"bad parameter", http.StatusBadRequest},
+			{"no command", http.StatusBadRequest},
+			{"conflict", http.StatusConflict},
+			{"impossible", http.StatusNotAcceptable},
+			{"wrong login/password", http.StatusUnauthorized},
+			{"unauthorized", http.StatusUnauthorized},
+			{"hasn't been activated", http.StatusForbidden},
+			{"this node", http.StatusNotAcceptable},
 		} {
-			if strings.Contains(errStr, keyword) {
-				statusCode = status
+			if strings.Contains(errStr, status.keyword) {
+				statusCode = status.code
 				break
 			}
 		}

From 9d7bae7c5d739f4e9153165bd794eb020fd3ed4a Mon Sep 17 00:00:00 2001
From: Andrew Hsu <andrewhsu@docker.com>
Date: Sun, 4 Dec 2016 16:24:44 -0800
Subject: [PATCH 4/5] run dnf upgrade before installing in fedora

Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
(cherry picked from commit ebd804bfb6af27b04514512676619b6a961551dc)
Signed-off-by: Victor Vieux <victorvieux@gmail.com>
---
 contrib/builder/rpm/amd64/fedora-23/Dockerfile | 1 +
 contrib/builder/rpm/amd64/fedora-24/Dockerfile | 1 +
 contrib/builder/rpm/amd64/generate.sh          | 3 +++
 3 files changed, 5 insertions(+)

diff --git a/contrib/builder/rpm/amd64/fedora-23/Dockerfile b/contrib/builder/rpm/amd64/fedora-23/Dockerfile
index 424840bd5b..a6d1508fd8 100644
--- a/contrib/builder/rpm/amd64/fedora-23/Dockerfile
+++ b/contrib/builder/rpm/amd64/fedora-23/Dockerfile
@@ -4,6 +4,7 @@
 
 FROM fedora:23
 
+RUN dnf -y upgrade
 RUN dnf install -y @development-tools fedora-packager
 RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git
 
diff --git a/contrib/builder/rpm/amd64/fedora-24/Dockerfile b/contrib/builder/rpm/amd64/fedora-24/Dockerfile
index 36091399c1..48d777b591 100644
--- a/contrib/builder/rpm/amd64/fedora-24/Dockerfile
+++ b/contrib/builder/rpm/amd64/fedora-24/Dockerfile
@@ -4,6 +4,7 @@
 
 FROM fedora:24
 
+RUN dnf -y upgrade
 RUN dnf install -y @development-tools fedora-packager
 RUN dnf install -y btrfs-progs-devel device-mapper-devel glibc-static libseccomp-devel libselinux-devel libtool-ltdl-devel pkgconfig selinux-policy selinux-policy-devel sqlite-devel systemd-devel tar git
 
diff --git a/contrib/builder/rpm/amd64/generate.sh b/contrib/builder/rpm/amd64/generate.sh
index 02306ea53b..52d30b49c7 100755
--- a/contrib/builder/rpm/amd64/generate.sh
+++ b/contrib/builder/rpm/amd64/generate.sh
@@ -49,6 +49,9 @@ for version in "${versions[@]}"; do
 			echo "RUN yum install -y kernel-uek-devel-4.1.12-32.el6uek"  >> "$version/Dockerfile"
 			echo >> "$version/Dockerfile"
 			;;
+		fedora:*)
+			echo "RUN ${installer} -y upgrade" >> "$version/Dockerfile"
+			;;
 		*) ;;
 	esac
 

From e2b0adeb5c440d19402b6545184899ffe460a1d5 Mon Sep 17 00:00:00 2001
From: Antonio Murdaca <runcom@redhat.com>
Date: Fri, 2 Dec 2016 19:56:27 +0100
Subject: [PATCH 5/5] hack/make.sh: fix BUILDTIME

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
(cherry picked from commit 7b1f77dcbc4c7cda754613f424f937056d3206ec)
Signed-off-by: Victor Vieux <victorvieux@gmail.com>
---
 hack/make.sh | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/hack/make.sh b/hack/make.sh
index 02db1d1a85..74d3970c60 100755
--- a/hack/make.sh
+++ b/hack/make.sh
@@ -81,6 +81,7 @@ DEFAULT_BUNDLES=(
 )
 
 VERSION=$(< ./VERSION)
+! BUILDTIME=$(date --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')
 if command -v git &> /dev/null && [ -d .git ] && git rev-parse &> /dev/null; then
 	GITCOMMIT=$(git rev-parse --short HEAD)
 	if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
@@ -94,11 +95,6 @@ if command -v git &> /dev/null && [ -d .git ] && git rev-parse &> /dev/null; the
 		git status --porcelain --untracked-files=no
 		echo "#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
 	fi
-	! BUILDTIME=$(date --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/') &> /dev/null
-	if [ -z $BUILDTIME ]; then
-		# If using bash 3.1 which doesn't support --rfc-3389, eg Windows CI
-		BUILDTIME=$(date -u)
-	fi
 elif [ "$DOCKER_GITCOMMIT" ]; then
 	GITCOMMIT="$DOCKER_GITCOMMIT"
 else