diff --git a/components/engine/daemon/cluster/convert/swarm.go b/components/engine/daemon/cluster/convert/swarm.go index 0d5c8738c9f..2ea89b968eb 100644 --- a/components/engine/daemon/cluster/convert/swarm.go +++ b/components/engine/daemon/cluster/convert/swarm.go @@ -31,9 +31,10 @@ func SwarmFromGRPC(c swarmapi.Cluster) types.Swarm { AutoLockManagers: c.Spec.EncryptionConfig.AutoLockManagers, }, CAConfig: types.CAConfig{ - // do not include the signing CA key (it should already be redacted via the swarm APIs) - SigningCACert: string(c.Spec.CAConfig.SigningCACert), - ForceRotate: c.Spec.CAConfig.ForceRotate, + // do not include the signing CA cert or key (it should already be redacted via the swarm APIs) - + // the key because it's secret, and the cert because otherwise doing a get + update on the spec + // can cause issues because the key would be missing and the cert wouldn't + ForceRotate: c.Spec.CAConfig.ForceRotate, }, }, TLSInfo: types.TLSInfo{ diff --git a/components/engine/integration-cli/docker_api_swarm_test.go b/components/engine/integration-cli/docker_api_swarm_test.go index 9f3f3e53ca7..aa6fbfac249 100644 --- a/components/engine/integration-cli/docker_api_swarm_test.go +++ b/components/engine/integration-cli/docker_api_swarm_test.go @@ -966,20 +966,21 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) { for j := 0; j < 18; j++ { info, err := m.SwarmInfo() c.Assert(err, checker.IsNil) - c.Assert(info.Cluster.Spec.CAConfig.SigningCACert, checker.Equals, expectedCert) - // the desired CA key is always redacted + + // the desired CA cert and key is always redacted c.Assert(info.Cluster.Spec.CAConfig.SigningCAKey, checker.Equals, "") + c.Assert(info.Cluster.Spec.CAConfig.SigningCACert, checker.Equals, "") clusterTLSInfo = info.Cluster.TLSInfo - if !info.Cluster.RootRotationInProgress { + // if root rotation is done and the trust root has changed, we don't have to poll anymore + if !info.Cluster.RootRotationInProgress && clusterTLSInfo.TrustRoot != currentTrustRoot { break } // root rotation not done time.Sleep(250 * time.Millisecond) } - c.Assert(clusterTLSInfo.TrustRoot, checker.Not(checker.Equals), currentTrustRoot) if cert != nil { c.Assert(clusterTLSInfo.TrustRoot, checker.Equals, expectedCert) } diff --git a/components/engine/vendor.conf b/components/engine/vendor.conf index 4b4e1dacad6..1fc9e2681c6 100644 --- a/components/engine/vendor.conf +++ b/components/engine/vendor.conf @@ -107,7 +107,7 @@ github.com/containerd/containerd cfb82a876ecc11b5ca0977d1733adbe58599088a github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4 # cluster -github.com/docker/swarmkit bf9b892c0b27bb3e13195bcef4d964fce2987bf1 +github.com/docker/swarmkit 9edb625cfb4407da456cc7fc479db6d824fe81f3 github.com/gogo/protobuf v0.4 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e diff --git a/components/engine/vendor/github.com/docker/swarmkit/ca/certificates.go b/components/engine/vendor/github.com/docker/swarmkit/ca/certificates.go index 8e004c1b5f2..7a638fe136b 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/ca/certificates.go +++ b/components/engine/vendor/github.com/docker/swarmkit/ca/certificates.go @@ -887,7 +887,7 @@ func GetRemoteSignedCertificate(ctx context.Context, csr []byte, rootCAPool *x50 caClient = api.NewNodeCAClient(conn.ClientConn) // If there was no deadline exceeded error, and the certificate was issued, return - case err == nil && statusResponse.Status.State == api.IssuanceStateIssued: + case err == nil && (statusResponse.Status.State == api.IssuanceStateIssued || statusResponse.Status.State == api.IssuanceStateRotate): if statusResponse.Certificate == nil { conn.Close(false) return nil, errors.New("no certificate in CertificateStatus response") diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go b/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go index 9832272a3fa..7e9dea2ce58 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go @@ -247,6 +247,11 @@ func redactClusters(clusters []*api.Cluster) []*api.Cluster { // Do not copy secret keys redactedSpec := cluster.Spec.Copy() redactedSpec.CAConfig.SigningCAKey = nil + // the cert is not a secret, but if API users get the cluster spec and then update, + // then because the cert is included but not the key, the user can get update errors + // or unintended consequences (such as telling swarm to forget about the key so long + // as there is a corresponding external CA) + redactedSpec.CAConfig.SigningCACert = nil redactedRootCA := cluster.RootCA.Copy() redactedRootCA.CAKey = nil diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go index 7f899d8b26f..b83704a18df 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go @@ -4,7 +4,6 @@ import ( "container/heap" "errors" "strings" - "time" "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/manager/constraint" @@ -32,16 +31,6 @@ func (ns *nodeSet) nodeInfo(nodeID string) (NodeInfo, error) { // addOrUpdateNode sets the number of tasks for a given node. It adds the node // to the set if it wasn't already tracked. func (ns *nodeSet) addOrUpdateNode(n NodeInfo) { - if n.Tasks == nil { - n.Tasks = make(map[string]*api.Task) - } - if n.ActiveTasksCountByService == nil { - n.ActiveTasksCountByService = make(map[string]int) - } - if n.recentFailures == nil { - n.recentFailures = make(map[string][]time.Time) - } - ns.nodes[n.ID] = n } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go index a6479b88340..96df5633a5d 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go @@ -296,19 +296,26 @@ func (s *Scheduler) deleteTask(ctx context.Context, t *api.Task) bool { } func (s *Scheduler) createOrUpdateNode(n *api.Node) { - nodeInfo, _ := s.nodeSet.nodeInfo(n.ID) + nodeInfo, nodeInfoErr := s.nodeSet.nodeInfo(n.ID) var resources api.Resources if n.Description != nil && n.Description.Resources != nil { resources = *n.Description.Resources // reconcile resources by looping over all tasks in this node - for _, task := range nodeInfo.Tasks { - reservations := taskReservations(task.Spec) - resources.MemoryBytes -= reservations.MemoryBytes - resources.NanoCPUs -= reservations.NanoCPUs + if nodeInfoErr == nil { + for _, task := range nodeInfo.Tasks { + reservations := taskReservations(task.Spec) + resources.MemoryBytes -= reservations.MemoryBytes + resources.NanoCPUs -= reservations.NanoCPUs + } } } - nodeInfo.Node = n - nodeInfo.AvailableResources = resources + + if nodeInfoErr != nil { + nodeInfo = newNodeInfo(n, nil, resources) + } else { + nodeInfo.Node = n + nodeInfo.AvailableResources = resources + } s.nodeSet.addOrUpdateNode(nodeInfo) }