From 073d80bc46a0ee596f3dac542104b064aaa64804 Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Tue, 20 Jun 2017 01:48:19 +0000 Subject: [PATCH 1/2] [engine] Vendor swarmkit to 9edb625cfb4407da456cc7fc479db6d824fe81f3 Brings in these pull requests: - https://github.com/docker/swarmkit/pull/2224 - https://github.com/docker/swarmkit/pull/2268 - https://github.com/docker/swarmkit/pull/2263 Signed-off-by: Tibor Vass --- components/engine/vendor.conf | 2 +- .../docker/swarmkit/ca/certificates.go | 2 +- .../swarmkit/manager/controlapi/cluster.go | 5 +++++ .../swarmkit/manager/scheduler/nodeset.go | 11 ---------- .../swarmkit/manager/scheduler/scheduler.go | 21 ++++++++++++------- 5 files changed, 21 insertions(+), 20 deletions(-) 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) } From bb23c93d28286115cd7d98cf710b196e313ac68d Mon Sep 17 00:00:00 2001 From: Ying Li Date: Thu, 15 Jun 2017 18:11:14 -0700 Subject: [PATCH 2/2] Redact the swarm's spec's signing CA cert when getting swarm info, because otherwise if the user gets the info from the API, makes a non-CA related change, then updates, swarm will interpret this as the user trying to remove the signing key from the swarm. We are redacting due to usability reasons, not because the signing cert is secret. The signing KEY is secret, hence it's redacted. Signed-off-by: Ying Li (cherry picked from commit bdfbd22afbbf16a07f0316656c6c17453df3e0f7) Signed-off-by: Tibor Vass --- components/engine/daemon/cluster/convert/swarm.go | 7 ++++--- .../engine/integration-cli/docker_api_swarm_test.go | 9 +++++---- 2 files changed, 9 insertions(+), 7 deletions(-) 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) }