Re-vendor SwarmKit to 4b872cfac8ffc0cc7fff434902cc05dbc7612da5

Includes:
- docker/swarmkit#2203
- docker/swarmkit#2210
- docker/swarmkit#2212

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
Signed-off-by: Tibor Vass <tibor@docker.com>
diff --git a/vendor.conf b/vendor.conf
index 6d9eb33..8f15435 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -107,7 +107,7 @@
 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
 
 # cluster
-github.com/docker/swarmkit 1a3e510517be82d18ac04380b5f71eddf06c2fc0
+github.com/docker/swarmkit 4b872cfac8ffc0cc7fff434902cc05dbc7612da5
 github.com/gogo/protobuf v0.4
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
 github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
diff --git a/vendor/github.com/docker/swarmkit/ca/config.go b/vendor/github.com/docker/swarmkit/ca/config.go
index 2aaaf78..a853fa6 100644
--- a/vendor/github.com/docker/swarmkit/ca/config.go
+++ b/vendor/github.com/docker/swarmkit/ca/config.go
@@ -157,6 +157,8 @@
 
 	s.rootCA = rootCA
 	s.externalCAClientRootPool = externalCARootPool
+	s.externalCA.UpdateRootCA(rootCA)
+
 	return s.updateTLSCredentials(s.certificate, s.issuerInfo)
 }
 
diff --git a/vendor/github.com/docker/swarmkit/ca/external.go b/vendor/github.com/docker/swarmkit/ca/external.go
index 6f23ff1..11a6f87 100644
--- a/vendor/github.com/docker/swarmkit/ca/external.go
+++ b/vendor/github.com/docker/swarmkit/ca/external.go
@@ -23,6 +23,9 @@
 	"golang.org/x/net/context/ctxhttp"
 )
 
+// ExternalCrossSignProfile is the profile that we will be sending cross-signing CSR sign requests with
+const ExternalCrossSignProfile = "CA"
+
 // ErrNoExternalCAURLs is an error used it indicate that an ExternalCA is
 // configured with no URLs to which it can proxy certificate signing requests.
 var ErrNoExternalCAURLs = errors.New("no external CA URLs")
@@ -79,8 +82,7 @@
 	}
 }
 
-// UpdateURLs updates the list of CSR API endpoints by setting it to the given
-// urls.
+// UpdateURLs updates the list of CSR API endpoints by setting it to the given urls.
 func (eca *ExternalCA) UpdateURLs(urls ...string) {
 	eca.mu.Lock()
 	defer eca.mu.Unlock()
@@ -88,6 +90,13 @@
 	eca.urls = urls
 }
 
+// UpdateRootCA changes the root CA used to append intermediates
+func (eca *ExternalCA) UpdateRootCA(rca *RootCA) {
+	eca.mu.Lock()
+	eca.rootCA = rca
+	eca.mu.Unlock()
+}
+
 // Sign signs a new certificate by proxying the given certificate signing
 // request to an external CFSSL API server.
 func (eca *ExternalCA) Sign(ctx context.Context, req signer.SignRequest) (cert []byte, err error) {
@@ -96,6 +105,7 @@
 	eca.mu.Lock()
 	urls := eca.urls
 	client := eca.client
+	intermediates := eca.rootCA.Intermediates
 	eca.mu.Unlock()
 
 	if len(urls) == 0 {
@@ -114,7 +124,7 @@
 		cert, err = makeExternalSignRequest(requestCtx, client, url, csrJSON)
 		cancel()
 		if err == nil {
-			return append(cert, eca.rootCA.Intermediates...), err
+			return append(cert, intermediates...), err
 		}
 		logrus.Debugf("unable to proxy certificate signing request to %s: %s", url, err)
 	}
@@ -157,6 +167,7 @@
 			CN:    rootCert.Subject.CommonName,
 			Names: cfCSRObj.Names,
 		},
+		Profile: ExternalCrossSignProfile,
 	}
 	// cfssl actually ignores non subject alt name extensions in the CSR, so we have to add the CA extension in the signing
 	// request as well
diff --git a/vendor/github.com/docker/swarmkit/manager/manager.go b/vendor/github.com/docker/swarmkit/manager/manager.go
index 005a56c..01c296a 100644
--- a/vendor/github.com/docker/swarmkit/manager/manager.go
+++ b/vendor/github.com/docker/swarmkit/manager/manager.go
@@ -217,7 +217,6 @@
 
 	m := &Manager{
 		config:          *config,
-		collector:       metrics.NewCollector(raftNode.MemoryStore()),
 		caserver:        ca.NewServer(raftNode.MemoryStore(), config.SecurityConfig, config.RootCAPaths),
 		dispatcher:      dispatcher.New(raftNode, dispatcher.DefaultConfig()),
 		logbroker:       logbroker.New(raftNode.MemoryStore()),
@@ -502,12 +501,16 @@
 	healthServer.SetServingStatus("Raft", api.HealthCheckResponse_SERVING)
 
 	if err := m.raftNode.JoinAndStart(ctx); err != nil {
+		// Don't block future calls to Stop.
+		close(m.started)
 		return errors.Wrap(err, "can't initialize raft node")
 	}
 
 	localHealthServer.SetServingStatus("ControlAPI", api.HealthCheckResponse_SERVING)
 
 	// Start metrics collection.
+
+	m.collector = metrics.NewCollector(m.raftNode.MemoryStore())
 	go func(collector *metrics.Collector) {
 		if err := collector.Run(ctx); err != nil {
 			log.G(ctx).WithError(err).Error("collector failed with an error")
@@ -590,7 +593,10 @@
 
 	m.raftNode.Cancel()
 
-	m.collector.Stop()
+	if m.collector != nil {
+		m.collector.Stop()
+	}
+
 	m.dispatcher.Stop()
 	m.logbroker.Stop()
 	m.caserver.Stop()
diff --git a/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go b/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go
index 82a550d..b793374 100644
--- a/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go
+++ b/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go
@@ -361,7 +361,7 @@
 		if err != nil {
 			n.stopMu.Lock()
 			// to shutdown transport
-			close(n.stopped)
+			n.cancelFunc()
 			n.stopMu.Unlock()
 			n.done()
 		} else {