diff --git a/components/engine/vendor.conf b/components/engine/vendor.conf index f1b6a2ae3a8..64ca88ed652 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 9edb625cfb4407da456cc7fc479db6d824fe81f3 +github.com/docker/swarmkit fb828cea0ec518dadea0f04900e0057e38194562 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/external.go b/components/engine/vendor/github.com/docker/swarmkit/ca/external.go index 11a6f875581..9369e0790c4 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/ca/external.go +++ b/components/engine/vendor/github.com/docker/swarmkit/ca/external.go @@ -8,6 +8,7 @@ import ( "encoding/hex" "encoding/json" "encoding/pem" + "io" "io/ioutil" "net/http" "sync" @@ -23,8 +24,18 @@ import ( "golang.org/x/net/context/ctxhttp" ) -// ExternalCrossSignProfile is the profile that we will be sending cross-signing CSR sign requests with -const ExternalCrossSignProfile = "CA" +const ( + // ExternalCrossSignProfile is the profile that we will be sending cross-signing CSR sign requests with + ExternalCrossSignProfile = "CA" + + // CertificateMaxSize is the maximum expected size of a certificate. + // While there is no specced upper limit to the size of an x509 certificate in PEM format, + // one with a ridiculous RSA key size (16384) and 26 256-character DNS SAN fields is about 14k. + // While there is no upper limit on the length of certificate chains, long chains are impractical. + // To be conservative, and to also account for external CA certificate responses in JSON format + // from CFSSL, we'll set the max to be 256KiB. + CertificateMaxSize int64 = 256 << 10 +) // ErrNoExternalCAURLs is an error used it indicate that an ExternalCA is // configured with no URLs to which it can proxy certificate signing requests. @@ -190,7 +201,8 @@ func makeExternalSignRequest(ctx context.Context, client *http.Client, url strin } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + b := io.LimitReader(resp.Body, CertificateMaxSize) + body, err := ioutil.ReadAll(b) if err != nil { return nil, recoverableErr{err: errors.Wrap(err, "unable to read CSR response body")} } diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/clusters.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/clusters.go index a495dacc924..495fc040378 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/clusters.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/clusters.go @@ -43,21 +43,11 @@ func init() { return err }, Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { - clusters, err := FindClusters(tx, All) - if err != nil { - return err + toStoreObj := make([]api.StoreObject, len(snapshot.Clusters)) + for i, x := range snapshot.Clusters { + toStoreObj[i] = x } - for _, n := range clusters { - if err := DeleteCluster(tx, n.ID); err != nil { - return err - } - } - for _, n := range snapshot.Clusters { - if err := CreateCluster(tx, n); err != nil { - return err - } - } - return nil + return RestoreTable(tx, tableCluster, toStoreObj) }, ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { switch v := sa.Target.(type) { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/configs.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/configs.go index 2bd44ae1bdd..d02e04ba9b5 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/configs.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/configs.go @@ -37,21 +37,11 @@ func init() { return err }, Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { - configs, err := FindConfigs(tx, All) - if err != nil { - return err + toStoreObj := make([]api.StoreObject, len(snapshot.Configs)) + for i, x := range snapshot.Configs { + toStoreObj[i] = x } - for _, s := range configs { - if err := DeleteConfig(tx, s.ID); err != nil { - return err - } - } - for _, s := range snapshot.Configs { - if err := CreateConfig(tx, s); err != nil { - return err - } - } - return nil + return RestoreTable(tx, tableConfig, toStoreObj) }, ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { switch v := sa.Target.(type) { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/extensions.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/extensions.go index 627d87d531a..8dac4baac75 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/extensions.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/extensions.go @@ -38,21 +38,11 @@ func init() { return err }, Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { - extensions, err := FindExtensions(tx, All) - if err != nil { - return err + toStoreObj := make([]api.StoreObject, len(snapshot.Extensions)) + for i, x := range snapshot.Extensions { + toStoreObj[i] = extensionEntry{x} } - for _, e := range extensions { - if err := DeleteExtension(tx, e.ID); err != nil { - return err - } - } - for _, e := range snapshot.Extensions { - if err := CreateExtension(tx, e); err != nil { - return err - } - } - return nil + return RestoreTable(tx, tableExtension, toStoreObj) }, ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { switch v := sa.Target.(type) { @@ -80,6 +70,14 @@ func (e extensionEntry) CopyStoreObject() api.StoreObject { return extensionEntry{Extension: e.Extension.Copy()} } +// ensure that when update events are emitted, we unwrap extensionEntry +func (e extensionEntry) EventUpdate(oldObject api.StoreObject) api.Event { + if oldObject != nil { + return api.EventUpdateExtension{Extension: e.Extension, OldExtension: oldObject.(extensionEntry).Extension} + } + return api.EventUpdateExtension{Extension: e.Extension} +} + // CreateExtension adds a new extension to the store. // Returns ErrExist if the ID is already taken. func CreateExtension(tx Tx, e *api.Extension) error { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/networks.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/networks.go index df549d429c4..3042def1bf6 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/networks.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/networks.go @@ -37,21 +37,11 @@ func init() { return err }, Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { - networks, err := FindNetworks(tx, All) - if err != nil { - return err + toStoreObj := make([]api.StoreObject, len(snapshot.Networks)) + for i, x := range snapshot.Networks { + toStoreObj[i] = x } - for _, n := range networks { - if err := DeleteNetwork(tx, n.ID); err != nil { - return err - } - } - for _, n := range snapshot.Networks { - if err := CreateNetwork(tx, n); err != nil { - return err - } - } - return nil + return RestoreTable(tx, tableNetwork, toStoreObj) }, ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { switch v := sa.Target.(type) { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/nodes.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/nodes.go index 0661a160535..fa6ae85bd75 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/nodes.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/nodes.go @@ -47,21 +47,11 @@ func init() { return err }, Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { - nodes, err := FindNodes(tx, All) - if err != nil { - return err + toStoreObj := make([]api.StoreObject, len(snapshot.Nodes)) + for i, x := range snapshot.Nodes { + toStoreObj[i] = x } - for _, n := range nodes { - if err := DeleteNode(tx, n.ID); err != nil { - return err - } - } - for _, n := range snapshot.Nodes { - if err := CreateNode(tx, n); err != nil { - return err - } - } - return nil + return RestoreTable(tx, tableNode, toStoreObj) }, ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { switch v := sa.Target.(type) { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/object.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/object.go index 5f495fdfab7..89029afb9f4 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/object.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/object.go @@ -13,3 +13,46 @@ type ObjectStoreConfig struct { Restore func(Tx, *api.StoreSnapshot) error ApplyStoreAction func(Tx, api.StoreAction) error } + +// RestoreTable takes a list of new objects of a particular type (e.g. clusters, +// nodes, etc., which conform to the StoreObject interface) and replaces the +// existing objects in the store of that type with the new objects. +func RestoreTable(tx Tx, table string, newObjects []api.StoreObject) error { + checkType := func(by By) error { + return nil + } + var oldObjects []api.StoreObject + appendResult := func(o api.StoreObject) { + oldObjects = append(oldObjects, o) + } + + err := tx.find(table, All, checkType, appendResult) + if err != nil { + return nil + } + + updated := make(map[string]struct{}) + + for _, o := range newObjects { + objectID := o.GetID() + if existing := tx.lookup(table, indexID, objectID); existing != nil { + if err := tx.update(table, o); err != nil { + return err + } + updated[objectID] = struct{}{} + } else { + if err := tx.create(table, o); err != nil { + return err + } + } + } + for _, o := range oldObjects { + objectID := o.GetID() + if _, ok := updated[objectID]; !ok { + if err := tx.delete(table, objectID); err != nil { + return err + } + } + } + return nil +} diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/resources.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/resources.go index 4e1ec7154b5..1f2c3904f1d 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/resources.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/resources.go @@ -40,21 +40,11 @@ func init() { return err }, Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { - resources, err := FindResources(tx, All) - if err != nil { - return err + toStoreObj := make([]api.StoreObject, len(snapshot.Resources)) + for i, x := range snapshot.Resources { + toStoreObj[i] = resourceEntry{x} } - for _, r := range resources { - if err := DeleteResource(tx, r.ID); err != nil { - return err - } - } - for _, r := range snapshot.Resources { - if err := CreateResource(tx, r); err != nil { - return err - } - } - return nil + return RestoreTable(tx, tableResource, toStoreObj) }, ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { switch v := sa.Target.(type) { @@ -82,6 +72,14 @@ func (r resourceEntry) CopyStoreObject() api.StoreObject { return resourceEntry{Resource: r.Resource.Copy()} } +// ensure that when update events are emitted, we unwrap resourceEntry +func (r resourceEntry) EventUpdate(oldObject api.StoreObject) api.Event { + if oldObject != nil { + return api.EventUpdateResource{Resource: r.Resource, OldResource: oldObject.(resourceEntry).Resource} + } + return api.EventUpdateResource{Resource: r.Resource} +} + func confirmExtension(tx Tx, r *api.Resource) error { // There must be an extension corresponding to the Kind field. extensions, err := FindExtensions(tx, ByName(r.Kind)) diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/secrets.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/secrets.go index 203c94c9749..bf5653fd720 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/secrets.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/secrets.go @@ -37,21 +37,11 @@ func init() { return err }, Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { - secrets, err := FindSecrets(tx, All) - if err != nil { - return err + toStoreObj := make([]api.StoreObject, len(snapshot.Secrets)) + for i, x := range snapshot.Secrets { + toStoreObj[i] = x } - for _, s := range secrets { - if err := DeleteSecret(tx, s.ID); err != nil { - return err - } - } - for _, s := range snapshot.Secrets { - if err := CreateSecret(tx, s); err != nil { - return err - } - } - return nil + return RestoreTable(tx, tableSecret, toStoreObj) }, ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { switch v := sa.Target.(type) { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/services.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/services.go index 884bc3533d7..1adbb87fe45 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/services.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/services.go @@ -58,21 +58,11 @@ func init() { return err }, Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { - services, err := FindServices(tx, All) - if err != nil { - return err + toStoreObj := make([]api.StoreObject, len(snapshot.Services)) + for i, x := range snapshot.Services { + toStoreObj[i] = x } - for _, s := range services { - if err := DeleteService(tx, s.ID); err != nil { - return err - } - } - for _, s := range snapshot.Services { - if err := CreateService(tx, s); err != nil { - return err - } - } - return nil + return RestoreTable(tx, tableService, toStoreObj) }, ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { switch v := sa.Target.(type) { diff --git a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/tasks.go b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/tasks.go index b8d8a731c95..bf31d764fb8 100644 --- a/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/tasks.go +++ b/components/engine/vendor/github.com/docker/swarmkit/manager/state/store/tasks.go @@ -82,21 +82,11 @@ func init() { return err }, Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { - tasks, err := FindTasks(tx, All) - if err != nil { - return err + toStoreObj := make([]api.StoreObject, len(snapshot.Tasks)) + for i, x := range snapshot.Tasks { + toStoreObj[i] = x } - for _, t := range tasks { - if err := DeleteTask(tx, t.ID); err != nil { - return err - } - } - for _, t := range snapshot.Tasks { - if err := CreateTask(tx, t); err != nil { - return err - } - } - return nil + return RestoreTable(tx, tableTask, toStoreObj) }, ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { switch v := sa.Target.(type) {