diff --git a/daemon/container_operations_unix.go b/daemon/container_operations_unix.go index 99d17e41b5..277c83e083 100644 --- a/daemon/container_operations_unix.go +++ b/daemon/container_operations_unix.go @@ -191,9 +191,9 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) { "name": s.File.Name, "path": fPath, }).Debug("injecting secret") - secret := c.DependencyStore.Secrets().Get(s.SecretID) - if secret == nil { - return fmt.Errorf("unable to get secret from secret store") + secret, err := c.DependencyStore.Secrets().Get(s.SecretID) + if err != nil { + return errors.Wrap(err, "unable to get secret from secret store") } if err := ioutil.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil { return errors.Wrap(err, "error injecting secret") @@ -266,9 +266,9 @@ func (daemon *Daemon) setupConfigDir(c *container.Container) (setupErr error) { } log.Debug("injecting config") - config := c.DependencyStore.Configs().Get(configRef.ConfigID) - if config == nil { - return fmt.Errorf("unable to get config from config store") + config, err := c.DependencyStore.Configs().Get(configRef.ConfigID) + if err != nil { + return errors.Wrap(err, "unable to get config from config store") } if err := ioutil.WriteFile(fPath, config.Spec.Data, configRef.File.Mode); err != nil { return errors.Wrap(err, "error injecting config") diff --git a/daemon/container_operations_windows.go b/daemon/container_operations_windows.go index 058089e7ca..45da6391a5 100644 --- a/daemon/container_operations_windows.go +++ b/daemon/container_operations_windows.go @@ -53,9 +53,9 @@ func (daemon *Daemon) setupConfigDir(c *container.Container) (setupErr error) { log := logrus.WithFields(logrus.Fields{"name": configRef.File.Name, "path": fPath}) log.Debug("injecting config") - config := c.DependencyStore.Configs().Get(configRef.ConfigID) - if config == nil { - return fmt.Errorf("unable to get config from config store") + config, err := c.DependencyStore.Configs().Get(configRef.ConfigID) + if err != nil { + return errors.Wrap(err, "unable to get config from config store") } if err := ioutil.WriteFile(fPath, config.Spec.Data, configRef.File.Mode); err != nil { return errors.Wrap(err, "error injecting config") @@ -128,9 +128,9 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) { "name": s.File.Name, "path": fPath, }).Debug("injecting secret") - secret := c.DependencyStore.Secrets().Get(s.SecretID) - if secret == nil { - return fmt.Errorf("unable to get secret from secret store") + secret, err := c.DependencyStore.Secrets().Get(s.SecretID) + if err != nil { + return errors.Wrap(err, "unable to get secret from secret store") } if err := ioutil.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil { return errors.Wrap(err, "error injecting secret") diff --git a/vendor.conf b/vendor.conf index e524c518ab..9629944d59 100644 --- a/vendor.conf +++ b/vendor.conf @@ -104,7 +104,7 @@ github.com/containerd/containerd 3addd840653146c90a254301d6c3a663c7fd6429 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4 # cluster -github.com/docker/swarmkit a4bf0135f63fb60f0e76ae81579cde87f580db6e +github.com/docker/swarmkit 79381d0840be27f8b3f5c667b348a4467d866eeb 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/agent/configs/configs.go b/vendor/github.com/docker/swarmkit/agent/configs/configs.go index f29e8afcba..ae5fc8c18c 100644 --- a/vendor/github.com/docker/swarmkit/agent/configs/configs.go +++ b/vendor/github.com/docker/swarmkit/agent/configs/configs.go @@ -1,6 +1,7 @@ package configs import ( + "fmt" "sync" "github.com/docker/swarmkit/agent/exec" @@ -22,13 +23,13 @@ func NewManager() exec.ConfigsManager { } // Get returns a config by ID. If the config doesn't exist, returns nil. -func (r *configs) Get(configID string) *api.Config { +func (r *configs) Get(configID string) (*api.Config, error) { r.mu.RLock() defer r.mu.RUnlock() if r, ok := r.m[configID]; ok { - return r + return r, nil } - return nil + return nil, fmt.Errorf("config %s not found", configID) } // Add adds one or more configs to the config map. @@ -63,9 +64,9 @@ type taskRestrictedConfigsProvider struct { configIDs map[string]struct{} // allow list of config ids } -func (sp *taskRestrictedConfigsProvider) Get(configID string) *api.Config { +func (sp *taskRestrictedConfigsProvider) Get(configID string) (*api.Config, error) { if _, ok := sp.configIDs[configID]; !ok { - return nil + return nil, fmt.Errorf("task not authorized to access config %s", configID) } return sp.configs.Get(configID) diff --git a/vendor/github.com/docker/swarmkit/agent/exec/executor.go b/vendor/github.com/docker/swarmkit/agent/exec/executor.go index 12bf29b4d2..8c3fd03506 100644 --- a/vendor/github.com/docker/swarmkit/agent/exec/executor.go +++ b/vendor/github.com/docker/swarmkit/agent/exec/executor.go @@ -52,7 +52,7 @@ type DependencyGetter interface { type SecretGetter interface { // Get returns the the secret with a specific secret ID, if available. // When the secret is not available, the return will be nil. - Get(secretID string) *api.Secret + Get(secretID string) (*api.Secret, error) } // SecretsManager is the interface for secret storage and updates. @@ -68,7 +68,7 @@ type SecretsManager interface { type ConfigGetter interface { // Get returns the the config with a specific config ID, if available. // When the config is not available, the return will be nil. - Get(configID string) *api.Config + Get(configID string) (*api.Config, error) } // ConfigsManager is the interface for config storage and updates. diff --git a/vendor/github.com/docker/swarmkit/agent/secrets/secrets.go b/vendor/github.com/docker/swarmkit/agent/secrets/secrets.go index 2f68fa20f3..233101d0fb 100644 --- a/vendor/github.com/docker/swarmkit/agent/secrets/secrets.go +++ b/vendor/github.com/docker/swarmkit/agent/secrets/secrets.go @@ -1,6 +1,7 @@ package secrets import ( + "fmt" "sync" "github.com/docker/swarmkit/agent/exec" @@ -22,13 +23,13 @@ func NewManager() exec.SecretsManager { } // Get returns a secret by ID. If the secret doesn't exist, returns nil. -func (s *secrets) Get(secretID string) *api.Secret { +func (s *secrets) Get(secretID string) (*api.Secret, error) { s.mu.RLock() defer s.mu.RUnlock() if s, ok := s.m[secretID]; ok { - return s + return s, nil } - return nil + return nil, fmt.Errorf("secret %s not found", secretID) } // Add adds one or more secrets to the secret map. @@ -63,9 +64,9 @@ type taskRestrictedSecretsProvider struct { secretIDs map[string]struct{} // allow list of secret ids } -func (sp *taskRestrictedSecretsProvider) Get(secretID string) *api.Secret { +func (sp *taskRestrictedSecretsProvider) Get(secretID string) (*api.Secret, error) { if _, ok := sp.secretIDs[secretID]; !ok { - return nil + return nil, fmt.Errorf("task not authorized to access secret %s", secretID) } return sp.secrets.Get(secretID) diff --git a/vendor/github.com/docker/swarmkit/api/specs.pb.go b/vendor/github.com/docker/swarmkit/api/specs.pb.go index 39b0c0abf0..8578cf3849 100644 --- a/vendor/github.com/docker/swarmkit/api/specs.pb.go +++ b/vendor/github.com/docker/swarmkit/api/specs.pb.go @@ -760,6 +760,12 @@ type SecretSpec struct { Annotations Annotations `protobuf:"bytes,1,opt,name=annotations" json:"annotations"` // Data is the secret payload - the maximum size is 500KB (that is, 500*1024 bytes) Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Templating *Driver `protobuf:"bytes,3,opt,name=templating" json:"templating,omitempty"` } func (m *SecretSpec) Reset() { *m = SecretSpec{} } @@ -773,6 +779,12 @@ type ConfigSpec struct { // TODO(aaronl): Do we want to revise this to include multiple payloads in a single // ConfigSpec? Define this to be a tar? etc... Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Templating *Driver `protobuf:"bytes,3,opt,name=templating" json:"templating,omitempty"` } func (m *ConfigSpec) Reset() { *m = ConfigSpec{} } @@ -1224,6 +1236,10 @@ func (m *SecretSpec) CopyFrom(src interface{}) { m.Data = make([]byte, len(o.Data)) copy(m.Data, o.Data) } + if o.Templating != nil { + m.Templating = &Driver{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Templating, o.Templating) + } } func (m *ConfigSpec) Copy() *ConfigSpec { @@ -1244,6 +1260,10 @@ func (m *ConfigSpec) CopyFrom(src interface{}) { m.Data = make([]byte, len(o.Data)) copy(m.Data, o.Data) } + if o.Templating != nil { + m.Templating = &Driver{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Templating, o.Templating) + } } func (m *NodeSpec) Marshal() (dAtA []byte, err error) { @@ -2227,6 +2247,16 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintSpecs(dAtA, i, uint64(len(m.Data))) i += copy(dAtA[i:], m.Data) } + if m.Templating != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size())) + n37, err := m.Templating.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n37 + } return i, nil } @@ -2248,17 +2278,27 @@ func (m *ConfigSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size())) - n37, err := m.Annotations.MarshalTo(dAtA[i:]) + n38, err := m.Annotations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n38 if len(m.Data) > 0 { dAtA[i] = 0x12 i++ i = encodeVarintSpecs(dAtA, i, uint64(len(m.Data))) i += copy(dAtA[i:], m.Data) } + if m.Templating != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size())) + n39, err := m.Templating.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n39 + } return i, nil } @@ -2685,6 +2725,10 @@ func (m *SecretSpec) Size() (n int) { if l > 0 { n += 1 + l + sovSpecs(uint64(l)) } + if m.Templating != nil { + l = m.Templating.Size() + n += 1 + l + sovSpecs(uint64(l)) + } return n } @@ -2697,6 +2741,10 @@ func (m *ConfigSpec) Size() (n int) { if l > 0 { n += 1 + l + sovSpecs(uint64(l)) } + if m.Templating != nil { + l = m.Templating.Size() + n += 1 + l + sovSpecs(uint64(l)) + } return n } @@ -2973,6 +3021,7 @@ func (this *SecretSpec) String() string { s := strings.Join([]string{`&SecretSpec{`, `Annotations:` + strings.Replace(strings.Replace(this.Annotations.String(), "Annotations", "Annotations", 1), `&`, ``, 1) + `,`, `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `Templating:` + strings.Replace(fmt.Sprintf("%v", this.Templating), "Driver", "Driver", 1) + `,`, `}`, }, "") return s @@ -2984,6 +3033,7 @@ func (this *ConfigSpec) String() string { s := strings.Join([]string{`&ConfigSpec{`, `Annotations:` + strings.Replace(strings.Replace(this.Annotations.String(), "Annotations", "Annotations", 1), `&`, ``, 1) + `,`, `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `Templating:` + strings.Replace(fmt.Sprintf("%v", this.Templating), "Driver", "Driver", 1) + `,`, `}`, }, "") return s @@ -5800,6 +5850,39 @@ func (m *SecretSpec) Unmarshal(dAtA []byte) error { m.Data = []byte{} } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Templating", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Templating == nil { + m.Templating = &Driver{} + } + if err := m.Templating.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSpecs(dAtA[iNdEx:]) @@ -5911,6 +5994,39 @@ func (m *ConfigSpec) Unmarshal(dAtA []byte) error { m.Data = []byte{} } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Templating", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Templating == nil { + m.Templating = &Driver{} + } + if err := m.Templating.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSpecs(dAtA[iNdEx:]) @@ -6040,121 +6156,122 @@ var ( func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) } var fileDescriptorSpecs = []byte{ - // 1846 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xcf, 0x73, 0x1b, 0x49, - 0x15, 0xb6, 0x6c, 0x59, 0x3f, 0xde, 0xc8, 0x89, 0xd2, 0x24, 0x61, 0xac, 0xb0, 0xb2, 0xa2, 0x0d, - 0xc1, 0xcb, 0x16, 0x72, 0x61, 0xa8, 0x25, 0x4b, 0x58, 0x40, 0xb2, 0x84, 0x63, 0x8c, 0x1d, 0x55, - 0xdb, 0x1b, 0xc8, 0x49, 0xd5, 0x9e, 0x69, 0x4b, 0x53, 0x1e, 0x75, 0x0f, 0xdd, 0x3d, 0xda, 0xd2, - 0x8d, 0xe3, 0x56, 0xae, 0x9c, 0x5d, 0x1c, 0xf8, 0x67, 0x72, 0xa4, 0x38, 0x71, 0x72, 0xb1, 0xfe, - 0x17, 0xb8, 0x71, 0x81, 0xea, 0x9e, 0x1e, 0xfd, 0x48, 0xc6, 0x9b, 0x54, 0x11, 0x6e, 0xdd, 0xaf, - 0xbf, 0xef, 0x75, 0xf7, 0xeb, 0xaf, 0xfb, 0xbd, 0x06, 0x47, 0x46, 0xd4, 0x93, 0xad, 0x48, 0x70, - 0xc5, 0x11, 0xf2, 0xb9, 0x77, 0x41, 0x45, 0x4b, 0x7e, 0x45, 0xc4, 0xf8, 0x22, 0x50, 0xad, 0xc9, - 0x8f, 0x6b, 0x8e, 0x9a, 0x46, 0xd4, 0x02, 0x6a, 0x77, 0x87, 0x7c, 0xc8, 0x4d, 0x73, 0x47, 0xb7, - 0xac, 0xb5, 0x3e, 0xe4, 0x7c, 0x18, 0xd2, 0x1d, 0xd3, 0x3b, 0x8b, 0xcf, 0x77, 0xfc, 0x58, 0x10, - 0x15, 0x70, 0x66, 0xc7, 0x37, 0xdf, 0x1c, 0x27, 0x6c, 0x9a, 0x0c, 0x35, 0x2f, 0xf3, 0x50, 0x3a, - 0xe6, 0x3e, 0x3d, 0x89, 0xa8, 0x87, 0xf6, 0xc1, 0x21, 0x8c, 0x71, 0x65, 0xb8, 0xd2, 0xcd, 0x35, - 0x72, 0xdb, 0xce, 0xee, 0x56, 0xeb, 0xed, 0x45, 0xb5, 0xda, 0x73, 0x58, 0x27, 0xff, 0xfa, 0x6a, - 0x6b, 0x05, 0x2f, 0x32, 0xd1, 0xaf, 0xa0, 0xe2, 0x53, 0x19, 0x08, 0xea, 0x0f, 0x04, 0x0f, 0xa9, - 0xbb, 0xda, 0xc8, 0x6d, 0xdf, 0xda, 0xfd, 0x5e, 0x96, 0x27, 0x3d, 0x39, 0xe6, 0x21, 0xc5, 0x8e, - 0x65, 0xe8, 0x0e, 0xda, 0x07, 0x18, 0xd3, 0xf1, 0x19, 0x15, 0x72, 0x14, 0x44, 0xee, 0x9a, 0xa1, - 0xff, 0xe0, 0x26, 0xba, 0x5e, 0x7b, 0xeb, 0x68, 0x06, 0xc7, 0x0b, 0x54, 0x74, 0x04, 0x15, 0x32, - 0x21, 0x41, 0x48, 0xce, 0x82, 0x30, 0x50, 0x53, 0x37, 0x6f, 0x5c, 0x7d, 0xf2, 0xad, 0xae, 0xda, - 0x0b, 0x04, 0xbc, 0x44, 0x6f, 0xfa, 0x00, 0xf3, 0x89, 0xd0, 0x63, 0x28, 0xf6, 0x7b, 0xc7, 0xdd, - 0x83, 0xe3, 0xfd, 0xea, 0x4a, 0x6d, 0xf3, 0xd5, 0x65, 0xe3, 0x9e, 0xf6, 0x31, 0x07, 0xf4, 0x29, - 0xf3, 0x03, 0x36, 0x44, 0xdb, 0x50, 0x6a, 0xef, 0xed, 0xf5, 0xfa, 0xa7, 0xbd, 0x6e, 0x35, 0x57, - 0xab, 0xbd, 0xba, 0x6c, 0xdc, 0x5f, 0x06, 0xb6, 0x3d, 0x8f, 0x46, 0x8a, 0xfa, 0xb5, 0xfc, 0xd7, - 0x7f, 0xad, 0xaf, 0x34, 0xbf, 0xce, 0x41, 0x65, 0x71, 0x11, 0xe8, 0x31, 0x14, 0xda, 0x7b, 0xa7, - 0x07, 0x2f, 0x7a, 0xd5, 0x95, 0x39, 0x7d, 0x11, 0xd1, 0xf6, 0x54, 0x30, 0xa1, 0xe8, 0x11, 0xac, - 0xf7, 0xdb, 0x5f, 0x9e, 0xf4, 0xaa, 0xb9, 0xf9, 0x72, 0x16, 0x61, 0x7d, 0x12, 0x4b, 0x83, 0xea, - 0xe2, 0xf6, 0xc1, 0x71, 0x75, 0x35, 0x1b, 0xd5, 0x15, 0x24, 0x60, 0x76, 0x29, 0x7f, 0xc9, 0x83, - 0x73, 0x42, 0xc5, 0x24, 0xf0, 0x3e, 0xb0, 0x44, 0x3e, 0x83, 0xbc, 0x22, 0xf2, 0xc2, 0x48, 0xc3, - 0xc9, 0x96, 0xc6, 0x29, 0x91, 0x17, 0x7a, 0x52, 0x4b, 0x37, 0x78, 0xad, 0x0c, 0x41, 0xa3, 0x30, - 0xf0, 0x88, 0xa2, 0xbe, 0x51, 0x86, 0xb3, 0xfb, 0xfd, 0x2c, 0x36, 0x9e, 0xa1, 0xec, 0xfa, 0x9f, - 0xad, 0xe0, 0x05, 0x2a, 0x7a, 0x0a, 0x85, 0x61, 0xc8, 0xcf, 0x48, 0x68, 0x34, 0xe1, 0xec, 0x3e, - 0xcc, 0x72, 0xb2, 0x6f, 0x10, 0x73, 0x07, 0x96, 0x82, 0x9e, 0x40, 0x21, 0x8e, 0x7c, 0xa2, 0xa8, - 0x5b, 0x30, 0xe4, 0x46, 0x16, 0xf9, 0x4b, 0x83, 0xd8, 0xe3, 0xec, 0x3c, 0x18, 0x62, 0x8b, 0x47, - 0x87, 0x50, 0x62, 0x54, 0x7d, 0xc5, 0xc5, 0x85, 0x74, 0x8b, 0x8d, 0xb5, 0x6d, 0x67, 0xf7, 0xd3, - 0x4c, 0x31, 0x26, 0x98, 0xb6, 0x52, 0xc4, 0x1b, 0x8d, 0x29, 0x53, 0x89, 0x9b, 0xce, 0xaa, 0x9b, - 0xc3, 0x33, 0x07, 0xe8, 0x17, 0x50, 0xa2, 0xcc, 0x8f, 0x78, 0xc0, 0x94, 0x5b, 0xba, 0x79, 0x21, - 0x3d, 0x8b, 0xd1, 0xc1, 0xc4, 0x33, 0x86, 0x66, 0x0b, 0x1e, 0x86, 0x67, 0xc4, 0xbb, 0x70, 0xcb, - 0xef, 0xb9, 0x8d, 0x19, 0xa3, 0x53, 0x80, 0xfc, 0x98, 0xfb, 0xb4, 0xb9, 0x03, 0x77, 0xde, 0x0a, - 0x35, 0xaa, 0x41, 0xc9, 0x86, 0x3a, 0xd1, 0x48, 0x1e, 0xcf, 0xfa, 0xcd, 0xdb, 0xb0, 0xb1, 0x14, - 0xd6, 0xe6, 0xdf, 0xf3, 0x50, 0x4a, 0xcf, 0x1a, 0xb5, 0xa1, 0xec, 0x71, 0xa6, 0x48, 0xc0, 0xa8, - 0xb0, 0xf2, 0xca, 0x3c, 0x99, 0xbd, 0x14, 0xa4, 0x59, 0xcf, 0x56, 0xf0, 0x9c, 0x85, 0x7e, 0x03, - 0x65, 0x41, 0x25, 0x8f, 0x85, 0x47, 0xa5, 0xd5, 0xd7, 0x76, 0xb6, 0x42, 0x12, 0x10, 0xa6, 0x7f, - 0x8c, 0x03, 0x41, 0x75, 0x94, 0x25, 0x9e, 0x53, 0xd1, 0x53, 0x28, 0x0a, 0x2a, 0x15, 0x11, 0xea, - 0xdb, 0x24, 0x82, 0x13, 0x48, 0x9f, 0x87, 0x81, 0x37, 0xc5, 0x29, 0x03, 0x3d, 0x85, 0x72, 0x14, - 0x12, 0xcf, 0x78, 0x75, 0xd7, 0x0d, 0xfd, 0xa3, 0x2c, 0x7a, 0x3f, 0x05, 0xe1, 0x39, 0x1e, 0x7d, - 0x0e, 0x10, 0xf2, 0xe1, 0xc0, 0x17, 0xc1, 0x84, 0x0a, 0x2b, 0xb1, 0x5a, 0x16, 0xbb, 0x6b, 0x10, - 0xb8, 0x1c, 0xf2, 0x61, 0xd2, 0x44, 0xfb, 0xff, 0x93, 0xbe, 0x16, 0xb4, 0x75, 0x08, 0x40, 0x66, - 0xa3, 0x56, 0x5d, 0x9f, 0xbc, 0x97, 0x2b, 0x7b, 0x22, 0x0b, 0x74, 0xf4, 0x10, 0x2a, 0xe7, 0x5c, - 0x78, 0x74, 0x60, 0x6f, 0x4d, 0xd9, 0x68, 0xc2, 0x31, 0xb6, 0x44, 0x5f, 0xa8, 0x03, 0xc5, 0x21, - 0x65, 0x54, 0x04, 0x9e, 0x0b, 0x66, 0xb2, 0xc7, 0x99, 0x17, 0x32, 0x81, 0xe0, 0x98, 0xa9, 0x60, - 0x4c, 0xed, 0x4c, 0x29, 0xb1, 0x53, 0x86, 0xa2, 0x48, 0x46, 0x9a, 0x7f, 0x00, 0xf4, 0x36, 0x16, - 0x21, 0xc8, 0x5f, 0x04, 0xcc, 0x37, 0xc2, 0x2a, 0x63, 0xd3, 0x46, 0x2d, 0x28, 0x46, 0x64, 0x1a, - 0x72, 0xe2, 0x5b, 0xb1, 0xdc, 0x6d, 0x25, 0xf9, 0xb2, 0x95, 0xe6, 0xcb, 0x56, 0x9b, 0x4d, 0x71, - 0x0a, 0x6a, 0x1e, 0xc2, 0xbd, 0xcc, 0x2d, 0xa3, 0x5d, 0xa8, 0xcc, 0x44, 0x38, 0x08, 0xec, 0x24, - 0x9d, 0xdb, 0xd7, 0x57, 0x5b, 0xce, 0x4c, 0xad, 0x07, 0x5d, 0xec, 0xcc, 0x40, 0x07, 0x7e, 0xf3, - 0xcf, 0x65, 0xd8, 0x58, 0x92, 0x32, 0xba, 0x0b, 0xeb, 0xc1, 0x98, 0x0c, 0xa9, 0x5d, 0x63, 0xd2, - 0x41, 0x3d, 0x28, 0x84, 0xe4, 0x8c, 0x86, 0x5a, 0xd0, 0xfa, 0x50, 0x7f, 0xf4, 0xce, 0x3b, 0xd1, - 0xfa, 0x9d, 0xc1, 0xf7, 0x98, 0x12, 0x53, 0x6c, 0xc9, 0xc8, 0x85, 0xa2, 0xc7, 0xc7, 0x63, 0xc2, - 0xf4, 0xd3, 0xb9, 0xb6, 0x5d, 0xc6, 0x69, 0x57, 0x47, 0x86, 0x88, 0xa1, 0x74, 0xf3, 0xc6, 0x6c, - 0xda, 0xa8, 0x0a, 0x6b, 0x94, 0x4d, 0xdc, 0x75, 0x63, 0xd2, 0x4d, 0x6d, 0xf1, 0x83, 0x44, 0x91, - 0x65, 0xac, 0x9b, 0x9a, 0x17, 0x4b, 0x2a, 0xdc, 0x62, 0x12, 0x51, 0xdd, 0x46, 0x3f, 0x83, 0xc2, - 0x98, 0xc7, 0x4c, 0x49, 0xb7, 0x64, 0x16, 0xbb, 0x99, 0xb5, 0xd8, 0x23, 0x8d, 0xb0, 0x4f, 0xbb, - 0x85, 0xa3, 0x1e, 0xdc, 0x91, 0x8a, 0x47, 0x83, 0xa1, 0x20, 0x1e, 0x1d, 0x44, 0x54, 0x04, 0xdc, - 0xb7, 0x4f, 0xd3, 0xe6, 0x5b, 0x87, 0xd2, 0xb5, 0x45, 0x0e, 0xbe, 0xad, 0x39, 0xfb, 0x9a, 0xd2, - 0x37, 0x0c, 0xd4, 0x87, 0x4a, 0x14, 0x87, 0xe1, 0x80, 0x47, 0x49, 0x96, 0x4a, 0xf4, 0xf4, 0x1e, - 0x21, 0xeb, 0xc7, 0x61, 0xf8, 0x3c, 0x21, 0x61, 0x27, 0x9a, 0x77, 0xd0, 0x7d, 0x28, 0x0c, 0x05, - 0x8f, 0x23, 0xe9, 0x3a, 0x26, 0x18, 0xb6, 0x87, 0xbe, 0x80, 0xa2, 0xa4, 0x9e, 0xa0, 0x4a, 0xba, - 0x15, 0xb3, 0xd5, 0x8f, 0xb3, 0x26, 0x39, 0x31, 0x10, 0x4c, 0xcf, 0xa9, 0xa0, 0xcc, 0xa3, 0x38, - 0xe5, 0xa0, 0x4d, 0x58, 0x53, 0x6a, 0xea, 0x6e, 0x34, 0x72, 0xdb, 0xa5, 0x4e, 0xf1, 0xfa, 0x6a, - 0x6b, 0xed, 0xf4, 0xf4, 0x25, 0xd6, 0x36, 0xfd, 0x82, 0x8e, 0xb8, 0x54, 0x8c, 0x8c, 0xa9, 0x7b, - 0xcb, 0xc4, 0x76, 0xd6, 0x47, 0x2f, 0x01, 0x7c, 0x26, 0x07, 0x9e, 0xb9, 0xb2, 0xee, 0x6d, 0xb3, - 0xbb, 0x4f, 0xdf, 0xbd, 0xbb, 0xee, 0xf1, 0x89, 0xcd, 0x22, 0x1b, 0xd7, 0x57, 0x5b, 0xe5, 0x59, - 0x17, 0x97, 0x7d, 0x26, 0x93, 0x26, 0xea, 0x80, 0x33, 0xa2, 0x24, 0x54, 0x23, 0x6f, 0x44, 0xbd, - 0x0b, 0xb7, 0x7a, 0x73, 0x5a, 0x78, 0x66, 0x60, 0xd6, 0xc3, 0x22, 0x49, 0x2b, 0x58, 0x2f, 0x55, - 0xba, 0x77, 0x4c, 0xac, 0x92, 0x0e, 0xfa, 0x08, 0x80, 0x47, 0x94, 0x0d, 0xa4, 0xf2, 0x03, 0xe6, - 0x22, 0xbd, 0x65, 0x5c, 0xd6, 0x96, 0x13, 0x6d, 0x40, 0x0f, 0xf4, 0xa3, 0x4d, 0xfc, 0x01, 0x67, - 0xe1, 0xd4, 0xfd, 0x8e, 0x19, 0x2d, 0x69, 0xc3, 0x73, 0x16, 0x4e, 0xd1, 0x16, 0x38, 0x46, 0x17, - 0x32, 0x18, 0x32, 0x12, 0xba, 0x77, 0x4d, 0x3c, 0x40, 0x9b, 0x4e, 0x8c, 0x45, 0x9f, 0x43, 0x12, - 0x0d, 0xe9, 0xde, 0xbb, 0xf9, 0x1c, 0xec, 0x62, 0xe7, 0xe7, 0x60, 0x39, 0xe8, 0x97, 0x00, 0x91, - 0x08, 0x26, 0x41, 0x48, 0x87, 0x54, 0xba, 0xf7, 0xcd, 0xa6, 0xeb, 0x99, 0xaf, 0xf5, 0x0c, 0x85, - 0x17, 0x18, 0xb5, 0xcf, 0xc1, 0x59, 0xb8, 0x6d, 0xfa, 0x96, 0x5c, 0xd0, 0xa9, 0xbd, 0xc0, 0xba, - 0xa9, 0x43, 0x32, 0x21, 0x61, 0x9c, 0x54, 0xc2, 0x65, 0x9c, 0x74, 0x7e, 0xbe, 0xfa, 0x24, 0x57, - 0xdb, 0x05, 0x67, 0x41, 0x75, 0xe8, 0x63, 0xd8, 0x10, 0x74, 0x18, 0x48, 0x25, 0xa6, 0x03, 0x12, - 0xab, 0x91, 0xfb, 0x6b, 0x43, 0xa8, 0xa4, 0xc6, 0x76, 0xac, 0x46, 0xb5, 0x01, 0xcc, 0x0f, 0x0f, - 0x35, 0xc0, 0xd1, 0xa2, 0x90, 0x54, 0x4c, 0xa8, 0xd0, 0xd9, 0x56, 0xc7, 0x7c, 0xd1, 0xa4, 0xc5, - 0x2b, 0x29, 0x11, 0xde, 0xc8, 0xbc, 0x1d, 0x65, 0x6c, 0x7b, 0xfa, 0x31, 0x48, 0x6f, 0x88, 0x7d, - 0x0c, 0x6c, 0xb7, 0xf9, 0xaf, 0x1c, 0x54, 0x16, 0x8b, 0x06, 0xb4, 0x97, 0x24, 0x7b, 0xb3, 0xa5, - 0x5b, 0xbb, 0x3b, 0xef, 0x2a, 0x32, 0x4c, 0x6a, 0x0d, 0x63, 0xed, 0xec, 0x48, 0xd7, 0xf7, 0x86, - 0x8c, 0x7e, 0x0a, 0xeb, 0x11, 0x17, 0x2a, 0x7d, 0xc2, 0xb2, 0x03, 0xcc, 0x45, 0x9a, 0x8a, 0x12, - 0x70, 0x73, 0x04, 0xb7, 0x96, 0xbd, 0xa1, 0x47, 0xb0, 0xf6, 0xe2, 0xa0, 0x5f, 0x5d, 0xa9, 0x3d, - 0x78, 0x75, 0xd9, 0xf8, 0xee, 0xf2, 0xe0, 0x8b, 0x40, 0xa8, 0x98, 0x84, 0x07, 0x7d, 0xf4, 0x43, - 0x58, 0xef, 0x1e, 0x9f, 0x60, 0x5c, 0xcd, 0xd5, 0xb6, 0x5e, 0x5d, 0x36, 0x1e, 0x2c, 0xe3, 0xf4, - 0x10, 0x8f, 0x99, 0x8f, 0xf9, 0xd9, 0xac, 0xd6, 0xfd, 0xf7, 0x2a, 0x38, 0xf6, 0x65, 0xff, 0xd0, - 0xdf, 0xa1, 0x8d, 0x24, 0x95, 0xa7, 0x57, 0x76, 0xf5, 0x9d, 0x19, 0xbd, 0x92, 0x10, 0xec, 0x19, - 0x3f, 0x84, 0x4a, 0x10, 0x4d, 0x3e, 0x1b, 0x50, 0x46, 0xce, 0x42, 0x5b, 0xf6, 0x96, 0xb0, 0xa3, - 0x6d, 0xbd, 0xc4, 0xa4, 0xdf, 0x8b, 0x80, 0x29, 0x2a, 0x98, 0x2d, 0x68, 0x4b, 0x78, 0xd6, 0x47, - 0x5f, 0x40, 0x3e, 0x88, 0xc8, 0xd8, 0x96, 0x21, 0x99, 0x3b, 0x38, 0xe8, 0xb7, 0x8f, 0xac, 0x06, - 0x3b, 0xa5, 0xeb, 0xab, 0xad, 0xbc, 0x36, 0x60, 0x43, 0x43, 0xf5, 0xb4, 0x12, 0xd0, 0x33, 0x99, - 0xb7, 0xbf, 0x84, 0x17, 0x2c, 0x5a, 0x47, 0x01, 0x1b, 0x0a, 0x2a, 0xa5, 0xc9, 0x02, 0x25, 0x9c, - 0x76, 0x51, 0x0d, 0x8a, 0xb6, 0x9e, 0x30, 0x05, 0x44, 0x59, 0xe7, 0x6a, 0x6b, 0xe8, 0x6c, 0x80, - 0x93, 0x44, 0x63, 0x70, 0x2e, 0xf8, 0xb8, 0xf9, 0x9f, 0x3c, 0x38, 0x7b, 0x61, 0x2c, 0x95, 0x4d, - 0x83, 0x1f, 0x2c, 0xf8, 0x2f, 0xe1, 0x0e, 0x31, 0xdf, 0x2b, 0xc2, 0x74, 0x4e, 0x31, 0x65, 0x9a, - 0x3d, 0x80, 0x47, 0x99, 0xee, 0x66, 0xe0, 0xa4, 0xa4, 0xeb, 0x14, 0xb4, 0x4f, 0x37, 0x87, 0xab, - 0xe4, 0x8d, 0x11, 0x74, 0x02, 0x1b, 0x5c, 0x78, 0x23, 0x2a, 0x55, 0x92, 0x89, 0xec, 0x77, 0x24, - 0xf3, 0xa3, 0xfa, 0x7c, 0x11, 0x68, 0x9f, 0xe1, 0x64, 0xb5, 0xcb, 0x3e, 0xd0, 0x13, 0xc8, 0x0b, - 0x72, 0x9e, 0x96, 0x9c, 0x99, 0x97, 0x04, 0x93, 0x73, 0xb5, 0xe4, 0xc2, 0x30, 0xd0, 0x6f, 0x01, - 0xfc, 0x40, 0x46, 0x44, 0x79, 0x23, 0x2a, 0xec, 0x61, 0x67, 0x6e, 0xb1, 0x3b, 0x43, 0x2d, 0x79, - 0x59, 0x60, 0xa3, 0x43, 0x28, 0x7b, 0x24, 0x95, 0x6b, 0xe1, 0xe6, 0x3f, 0xda, 0x5e, 0xdb, 0xba, - 0xa8, 0x6a, 0x17, 0xd7, 0x57, 0x5b, 0xa5, 0xd4, 0x82, 0x4b, 0x1e, 0xb1, 0xf2, 0x3d, 0x84, 0x0d, - 0xfd, 0x77, 0x1b, 0xf8, 0xf4, 0x9c, 0xc4, 0xa1, 0x4a, 0x64, 0x72, 0x43, 0x5a, 0xd1, 0x1f, 0x81, - 0xae, 0xc5, 0xd9, 0x75, 0x55, 0xd4, 0x82, 0x0d, 0xfd, 0x1e, 0xee, 0x50, 0xe6, 0x89, 0xa9, 0x11, - 0x6b, 0xba, 0xc2, 0xd2, 0xcd, 0x9b, 0xed, 0xcd, 0xc0, 0x4b, 0x9b, 0xad, 0xd2, 0x37, 0xec, 0xcd, - 0x00, 0x20, 0x49, 0xd4, 0x1f, 0x56, 0x7f, 0x08, 0xf2, 0x3e, 0x51, 0xc4, 0x48, 0xae, 0x82, 0x4d, - 0x5b, 0x4f, 0x95, 0x4c, 0xfa, 0x7f, 0x9f, 0xaa, 0xe3, 0xbe, 0xfe, 0xa6, 0xbe, 0xf2, 0x8f, 0x6f, - 0xea, 0x2b, 0x7f, 0xba, 0xae, 0xe7, 0x5e, 0x5f, 0xd7, 0x73, 0x7f, 0xbb, 0xae, 0xe7, 0xfe, 0x79, - 0x5d, 0xcf, 0x9d, 0x15, 0x4c, 0x25, 0xf5, 0x93, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xb3, 0x21, - 0x2b, 0x33, 0x82, 0x12, 0x00, 0x00, + // 1867 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x73, 0x1b, 0x49, + 0x15, 0xb6, 0x6c, 0x59, 0x3f, 0xde, 0xc8, 0x89, 0xd2, 0x24, 0x61, 0xa2, 0xb0, 0xb2, 0xa2, 0x0d, + 0xc1, 0xcb, 0x16, 0x72, 0x61, 0xa8, 0x25, 0xbb, 0x61, 0x01, 0xc9, 0x12, 0x8e, 0x31, 0x76, 0x54, + 0x6d, 0x6f, 0x20, 0x27, 0x55, 0x7b, 0xa6, 0x3d, 0x9a, 0xf2, 0xa8, 0x7b, 0xe8, 0xe9, 0xd1, 0x96, + 0x6e, 0x1c, 0xb7, 0x72, 0xe5, 0xec, 0xe2, 0x40, 0xf1, 0xbf, 0xe4, 0x48, 0x71, 0xe2, 0xe4, 0x62, + 0xfd, 0x2f, 0x70, 0xe3, 0x02, 0xd5, 0x3d, 0x3d, 0xd2, 0x28, 0x19, 0x27, 0xa9, 0x22, 0x07, 0x6e, + 0xdd, 0xaf, 0xbf, 0xef, 0xcd, 0xeb, 0xd7, 0x5f, 0xf7, 0x7b, 0x03, 0x56, 0x14, 0x52, 0x27, 0xea, + 0x84, 0x82, 0x4b, 0x8e, 0x90, 0xcb, 0x9d, 0x73, 0x2a, 0x3a, 0xd1, 0xd7, 0x44, 0x4c, 0xce, 0x7d, + 0xd9, 0x99, 0xfe, 0xb8, 0x61, 0xc9, 0x59, 0x48, 0x0d, 0xa0, 0x71, 0xdb, 0xe3, 0x1e, 0xd7, 0xc3, + 0x6d, 0x35, 0x32, 0xd6, 0xa6, 0xc7, 0xb9, 0x17, 0xd0, 0x6d, 0x3d, 0x3b, 0x8d, 0xcf, 0xb6, 0xdd, + 0x58, 0x10, 0xe9, 0x73, 0x66, 0xd6, 0xef, 0xbd, 0xbe, 0x4e, 0xd8, 0x2c, 0x59, 0x6a, 0x5f, 0x14, + 0xa1, 0x72, 0xc4, 0x5d, 0x7a, 0x1c, 0x52, 0x07, 0xed, 0x81, 0x45, 0x18, 0xe3, 0x52, 0x73, 0x23, + 0xbb, 0xd0, 0x2a, 0x6c, 0x59, 0x3b, 0x9b, 0x9d, 0x37, 0x83, 0xea, 0x74, 0x17, 0xb0, 0x5e, 0xf1, + 0xd5, 0xe5, 0xe6, 0x0a, 0xce, 0x32, 0xd1, 0x2f, 0xa1, 0xe6, 0xd2, 0xc8, 0x17, 0xd4, 0x1d, 0x09, + 0x1e, 0x50, 0x7b, 0xb5, 0x55, 0xd8, 0xba, 0xb1, 0xf3, 0xbd, 0x3c, 0x4f, 0xea, 0xe3, 0x98, 0x07, + 0x14, 0x5b, 0x86, 0xa1, 0x26, 0x68, 0x0f, 0x60, 0x42, 0x27, 0xa7, 0x54, 0x44, 0x63, 0x3f, 0xb4, + 0xd7, 0x34, 0xfd, 0x07, 0xd7, 0xd1, 0x55, 0xec, 0x9d, 0xc3, 0x39, 0x1c, 0x67, 0xa8, 0xe8, 0x10, + 0x6a, 0x64, 0x4a, 0xfc, 0x80, 0x9c, 0xfa, 0x81, 0x2f, 0x67, 0x76, 0x51, 0xbb, 0xfa, 0xe4, 0xad, + 0xae, 0xba, 0x19, 0x02, 0x5e, 0xa2, 0xb7, 0x5d, 0x80, 0xc5, 0x87, 0xd0, 0x23, 0x28, 0x0f, 0x07, + 0x47, 0xfd, 0xfd, 0xa3, 0xbd, 0xfa, 0x4a, 0xe3, 0xde, 0xcb, 0x8b, 0xd6, 0x1d, 0xe5, 0x63, 0x01, + 0x18, 0x52, 0xe6, 0xfa, 0xcc, 0x43, 0x5b, 0x50, 0xe9, 0xee, 0xee, 0x0e, 0x86, 0x27, 0x83, 0x7e, + 0xbd, 0xd0, 0x68, 0xbc, 0xbc, 0x68, 0xdd, 0x5d, 0x06, 0x76, 0x1d, 0x87, 0x86, 0x92, 0xba, 0x8d, + 0xe2, 0x37, 0x7f, 0x69, 0xae, 0xb4, 0xbf, 0x29, 0x40, 0x2d, 0x1b, 0x04, 0x7a, 0x04, 0xa5, 0xee, + 0xee, 0xc9, 0xfe, 0xf3, 0x41, 0x7d, 0x65, 0x41, 0xcf, 0x22, 0xba, 0x8e, 0xf4, 0xa7, 0x14, 0x3d, + 0x84, 0xf5, 0x61, 0xf7, 0xab, 0xe3, 0x41, 0xbd, 0xb0, 0x08, 0x27, 0x0b, 0x1b, 0x92, 0x38, 0xd2, + 0xa8, 0x3e, 0xee, 0xee, 0x1f, 0xd5, 0x57, 0xf3, 0x51, 0x7d, 0x41, 0x7c, 0x66, 0x42, 0xf9, 0x73, + 0x11, 0xac, 0x63, 0x2a, 0xa6, 0xbe, 0xf3, 0x81, 0x25, 0xf2, 0x19, 0x14, 0x25, 0x89, 0xce, 0xb5, + 0x34, 0xac, 0x7c, 0x69, 0x9c, 0x90, 0xe8, 0x5c, 0x7d, 0xd4, 0xd0, 0x35, 0x5e, 0x29, 0x43, 0xd0, + 0x30, 0xf0, 0x1d, 0x22, 0xa9, 0xab, 0x95, 0x61, 0xed, 0x7c, 0x3f, 0x8f, 0x8d, 0xe7, 0x28, 0x13, + 0xff, 0xd3, 0x15, 0x9c, 0xa1, 0xa2, 0x27, 0x50, 0xf2, 0x02, 0x7e, 0x4a, 0x02, 0xad, 0x09, 0x6b, + 0xe7, 0x41, 0x9e, 0x93, 0x3d, 0x8d, 0x58, 0x38, 0x30, 0x14, 0xf4, 0x18, 0x4a, 0x71, 0xe8, 0x12, + 0x49, 0xed, 0x92, 0x26, 0xb7, 0xf2, 0xc8, 0x5f, 0x69, 0xc4, 0x2e, 0x67, 0x67, 0xbe, 0x87, 0x0d, + 0x1e, 0x1d, 0x40, 0x85, 0x51, 0xf9, 0x35, 0x17, 0xe7, 0x91, 0x5d, 0x6e, 0xad, 0x6d, 0x59, 0x3b, + 0x9f, 0xe6, 0x8a, 0x31, 0xc1, 0x74, 0xa5, 0x24, 0xce, 0x78, 0x42, 0x99, 0x4c, 0xdc, 0xf4, 0x56, + 0xed, 0x02, 0x9e, 0x3b, 0x40, 0x3f, 0x87, 0x0a, 0x65, 0x6e, 0xc8, 0x7d, 0x26, 0xed, 0xca, 0xf5, + 0x81, 0x0c, 0x0c, 0x46, 0x25, 0x13, 0xcf, 0x19, 0x8a, 0x2d, 0x78, 0x10, 0x9c, 0x12, 0xe7, 0xdc, + 0xae, 0xbe, 0xe7, 0x36, 0xe6, 0x8c, 0x5e, 0x09, 0x8a, 0x13, 0xee, 0xd2, 0xf6, 0x36, 0xdc, 0x7a, + 0x23, 0xd5, 0xa8, 0x01, 0x15, 0x93, 0xea, 0x44, 0x23, 0x45, 0x3c, 0x9f, 0xb7, 0x6f, 0xc2, 0xc6, + 0x52, 0x5a, 0xdb, 0x7f, 0x2f, 0x42, 0x25, 0x3d, 0x6b, 0xd4, 0x85, 0xaa, 0xc3, 0x99, 0x24, 0x3e, + 0xa3, 0xc2, 0xc8, 0x2b, 0xf7, 0x64, 0x76, 0x53, 0x90, 0x62, 0x3d, 0x5d, 0xc1, 0x0b, 0x16, 0xfa, + 0x35, 0x54, 0x05, 0x8d, 0x78, 0x2c, 0x1c, 0x1a, 0x19, 0x7d, 0x6d, 0xe5, 0x2b, 0x24, 0x01, 0x61, + 0xfa, 0x87, 0xd8, 0x17, 0x54, 0x65, 0x39, 0xc2, 0x0b, 0x2a, 0x7a, 0x02, 0x65, 0x41, 0x23, 0x49, + 0x84, 0x7c, 0x9b, 0x44, 0x70, 0x02, 0x19, 0xf2, 0xc0, 0x77, 0x66, 0x38, 0x65, 0xa0, 0x27, 0x50, + 0x0d, 0x03, 0xe2, 0x68, 0xaf, 0xf6, 0xba, 0xa6, 0x7f, 0x94, 0x47, 0x1f, 0xa6, 0x20, 0xbc, 0xc0, + 0xa3, 0xcf, 0x01, 0x02, 0xee, 0x8d, 0x5c, 0xe1, 0x4f, 0xa9, 0x30, 0x12, 0x6b, 0xe4, 0xb1, 0xfb, + 0x1a, 0x81, 0xab, 0x01, 0xf7, 0x92, 0x21, 0xda, 0xfb, 0x9f, 0xf4, 0x95, 0xd1, 0xd6, 0x01, 0x00, + 0x99, 0xaf, 0x1a, 0x75, 0x7d, 0xf2, 0x5e, 0xae, 0xcc, 0x89, 0x64, 0xe8, 0xe8, 0x01, 0xd4, 0xce, + 0xb8, 0x70, 0xe8, 0xc8, 0xdc, 0x9a, 0xaa, 0xd6, 0x84, 0xa5, 0x6d, 0x89, 0xbe, 0x50, 0x0f, 0xca, + 0x1e, 0x65, 0x54, 0xf8, 0x8e, 0x0d, 0xfa, 0x63, 0x8f, 0x72, 0x2f, 0x64, 0x02, 0xc1, 0x31, 0x93, + 0xfe, 0x84, 0x9a, 0x2f, 0xa5, 0xc4, 0x5e, 0x15, 0xca, 0x22, 0x59, 0x69, 0xff, 0x1e, 0xd0, 0x9b, + 0x58, 0x84, 0xa0, 0x78, 0xee, 0x33, 0x57, 0x0b, 0xab, 0x8a, 0xf5, 0x18, 0x75, 0xa0, 0x1c, 0x92, + 0x59, 0xc0, 0x89, 0x6b, 0xc4, 0x72, 0xbb, 0x93, 0xd4, 0xcb, 0x4e, 0x5a, 0x2f, 0x3b, 0x5d, 0x36, + 0xc3, 0x29, 0xa8, 0x7d, 0x00, 0x77, 0x72, 0xb7, 0x8c, 0x76, 0xa0, 0x36, 0x17, 0xe1, 0xc8, 0x37, + 0x1f, 0xe9, 0xdd, 0xbc, 0xba, 0xdc, 0xb4, 0xe6, 0x6a, 0xdd, 0xef, 0x63, 0x6b, 0x0e, 0xda, 0x77, + 0xdb, 0x7f, 0xaa, 0xc2, 0xc6, 0x92, 0x94, 0xd1, 0x6d, 0x58, 0xf7, 0x27, 0xc4, 0xa3, 0x26, 0xc6, + 0x64, 0x82, 0x06, 0x50, 0x0a, 0xc8, 0x29, 0x0d, 0x94, 0xa0, 0xd5, 0xa1, 0xfe, 0xe8, 0x9d, 0x77, + 0xa2, 0xf3, 0x5b, 0x8d, 0x1f, 0x30, 0x29, 0x66, 0xd8, 0x90, 0x91, 0x0d, 0x65, 0x87, 0x4f, 0x26, + 0x84, 0xa9, 0xa7, 0x73, 0x6d, 0xab, 0x8a, 0xd3, 0xa9, 0xca, 0x0c, 0x11, 0x5e, 0x64, 0x17, 0xb5, + 0x59, 0x8f, 0x51, 0x1d, 0xd6, 0x28, 0x9b, 0xda, 0xeb, 0xda, 0xa4, 0x86, 0xca, 0xe2, 0xfa, 0x89, + 0x22, 0xab, 0x58, 0x0d, 0x15, 0x2f, 0x8e, 0xa8, 0xb0, 0xcb, 0x49, 0x46, 0xd5, 0x18, 0xfd, 0x0c, + 0x4a, 0x13, 0x1e, 0x33, 0x19, 0xd9, 0x15, 0x1d, 0xec, 0xbd, 0xbc, 0x60, 0x0f, 0x15, 0xc2, 0x3c, + 0xed, 0x06, 0x8e, 0x06, 0x70, 0x2b, 0x92, 0x3c, 0x1c, 0x79, 0x82, 0x38, 0x74, 0x14, 0x52, 0xe1, + 0x73, 0xd7, 0x3c, 0x4d, 0xf7, 0xde, 0x38, 0x94, 0xbe, 0x69, 0x72, 0xf0, 0x4d, 0xc5, 0xd9, 0x53, + 0x94, 0xa1, 0x66, 0xa0, 0x21, 0xd4, 0xc2, 0x38, 0x08, 0x46, 0x3c, 0x4c, 0xaa, 0x54, 0xa2, 0xa7, + 0xf7, 0x48, 0xd9, 0x30, 0x0e, 0x82, 0x67, 0x09, 0x09, 0x5b, 0xe1, 0x62, 0x82, 0xee, 0x42, 0xc9, + 0x13, 0x3c, 0x0e, 0x23, 0xdb, 0xd2, 0xc9, 0x30, 0x33, 0xf4, 0x25, 0x94, 0x23, 0xea, 0x08, 0x2a, + 0x23, 0xbb, 0xa6, 0xb7, 0xfa, 0x71, 0xde, 0x47, 0x8e, 0x35, 0x04, 0xd3, 0x33, 0x2a, 0x28, 0x73, + 0x28, 0x4e, 0x39, 0xe8, 0x1e, 0xac, 0x49, 0x39, 0xb3, 0x37, 0x5a, 0x85, 0xad, 0x4a, 0xaf, 0x7c, + 0x75, 0xb9, 0xb9, 0x76, 0x72, 0xf2, 0x02, 0x2b, 0x9b, 0x7a, 0x41, 0xc7, 0x3c, 0x92, 0x8c, 0x4c, + 0xa8, 0x7d, 0x43, 0xe7, 0x76, 0x3e, 0x47, 0x2f, 0x00, 0x5c, 0x16, 0x8d, 0x1c, 0x7d, 0x65, 0xed, + 0x9b, 0x7a, 0x77, 0x9f, 0xbe, 0x7b, 0x77, 0xfd, 0xa3, 0x63, 0x53, 0x45, 0x36, 0xae, 0x2e, 0x37, + 0xab, 0xf3, 0x29, 0xae, 0xba, 0x2c, 0x4a, 0x86, 0xa8, 0x07, 0xd6, 0x98, 0x92, 0x40, 0x8e, 0x9d, + 0x31, 0x75, 0xce, 0xed, 0xfa, 0xf5, 0x65, 0xe1, 0xa9, 0x86, 0x19, 0x0f, 0x59, 0x92, 0x52, 0xb0, + 0x0a, 0x35, 0xb2, 0x6f, 0xe9, 0x5c, 0x25, 0x13, 0xf4, 0x11, 0x00, 0x0f, 0x29, 0x1b, 0x45, 0xd2, + 0xf5, 0x99, 0x8d, 0xd4, 0x96, 0x71, 0x55, 0x59, 0x8e, 0x95, 0x01, 0xdd, 0x57, 0x8f, 0x36, 0x71, + 0x47, 0x9c, 0x05, 0x33, 0xfb, 0x3b, 0x7a, 0xb5, 0xa2, 0x0c, 0xcf, 0x58, 0x30, 0x43, 0x9b, 0x60, + 0x69, 0x5d, 0x44, 0xbe, 0xc7, 0x48, 0x60, 0xdf, 0xd6, 0xf9, 0x00, 0x65, 0x3a, 0xd6, 0x16, 0x75, + 0x0e, 0x49, 0x36, 0x22, 0xfb, 0xce, 0xf5, 0xe7, 0x60, 0x82, 0x5d, 0x9c, 0x83, 0xe1, 0xa0, 0x5f, + 0x00, 0x84, 0xc2, 0x9f, 0xfa, 0x01, 0xf5, 0x68, 0x64, 0xdf, 0xd5, 0x9b, 0x6e, 0xe6, 0xbe, 0xd6, + 0x73, 0x14, 0xce, 0x30, 0x1a, 0x9f, 0x83, 0x95, 0xb9, 0x6d, 0xea, 0x96, 0x9c, 0xd3, 0x99, 0xb9, + 0xc0, 0x6a, 0xa8, 0x52, 0x32, 0x25, 0x41, 0x9c, 0x74, 0xc2, 0x55, 0x9c, 0x4c, 0xbe, 0x58, 0x7d, + 0x5c, 0x68, 0xec, 0x80, 0x95, 0x51, 0x1d, 0xfa, 0x18, 0x36, 0x04, 0xf5, 0xfc, 0x48, 0x8a, 0xd9, + 0x88, 0xc4, 0x72, 0x6c, 0xff, 0x4a, 0x13, 0x6a, 0xa9, 0xb1, 0x1b, 0xcb, 0x71, 0x63, 0x04, 0x8b, + 0xc3, 0x43, 0x2d, 0xb0, 0x94, 0x28, 0x22, 0x2a, 0xa6, 0x54, 0xa8, 0x6a, 0xab, 0x72, 0x9e, 0x35, + 0x29, 0xf1, 0x46, 0x94, 0x08, 0x67, 0xac, 0xdf, 0x8e, 0x2a, 0x36, 0x33, 0xf5, 0x18, 0xa4, 0x37, + 0xc4, 0x3c, 0x06, 0x66, 0xda, 0xfe, 0x57, 0x01, 0x6a, 0xd9, 0xa6, 0x01, 0xed, 0x26, 0xc5, 0x5e, + 0x6f, 0xe9, 0xc6, 0xce, 0xf6, 0xbb, 0x9a, 0x0c, 0x5d, 0x5a, 0x83, 0x58, 0x39, 0x3b, 0x54, 0xfd, + 0xbd, 0x26, 0xa3, 0x9f, 0xc2, 0x7a, 0xc8, 0x85, 0x4c, 0x9f, 0xb0, 0xfc, 0x04, 0x73, 0x91, 0x96, + 0xa2, 0x04, 0xdc, 0x1e, 0xc3, 0x8d, 0x65, 0x6f, 0xe8, 0x21, 0xac, 0x3d, 0xdf, 0x1f, 0xd6, 0x57, + 0x1a, 0xf7, 0x5f, 0x5e, 0xb4, 0xbe, 0xbb, 0xbc, 0xf8, 0xdc, 0x17, 0x32, 0x26, 0xc1, 0xfe, 0x10, + 0xfd, 0x10, 0xd6, 0xfb, 0x47, 0xc7, 0x18, 0xd7, 0x0b, 0x8d, 0xcd, 0x97, 0x17, 0xad, 0xfb, 0xcb, + 0x38, 0xb5, 0xc4, 0x63, 0xe6, 0x62, 0x7e, 0x3a, 0xef, 0x75, 0xff, 0xbd, 0x0a, 0x96, 0x79, 0xd9, + 0x3f, 0xf4, 0xef, 0xd0, 0x46, 0x52, 0xca, 0xd3, 0x2b, 0xbb, 0xfa, 0xce, 0x8a, 0x5e, 0x4b, 0x08, + 0xe6, 0x8c, 0x1f, 0x40, 0xcd, 0x0f, 0xa7, 0x9f, 0x8d, 0x28, 0x23, 0xa7, 0x81, 0x69, 0x7b, 0x2b, + 0xd8, 0x52, 0xb6, 0x41, 0x62, 0x52, 0xef, 0x85, 0xcf, 0x24, 0x15, 0xcc, 0x34, 0xb4, 0x15, 0x3c, + 0x9f, 0xa3, 0x2f, 0xa1, 0xe8, 0x87, 0x64, 0x62, 0xda, 0x90, 0xdc, 0x1d, 0xec, 0x0f, 0xbb, 0x87, + 0x46, 0x83, 0xbd, 0xca, 0xd5, 0xe5, 0x66, 0x51, 0x19, 0xb0, 0xa6, 0xa1, 0x66, 0xda, 0x09, 0xa8, + 0x2f, 0xe9, 0xb7, 0xbf, 0x82, 0x33, 0x16, 0xa5, 0x23, 0x9f, 0x79, 0x82, 0x46, 0x91, 0xae, 0x02, + 0x15, 0x9c, 0x4e, 0x51, 0x03, 0xca, 0xa6, 0x9f, 0xd0, 0x0d, 0x44, 0x55, 0xd5, 0x6a, 0x63, 0xe8, + 0x6d, 0x80, 0x95, 0x64, 0x63, 0x74, 0x26, 0xf8, 0xa4, 0xfd, 0x9f, 0x22, 0x58, 0xbb, 0x41, 0x1c, + 0x49, 0x53, 0x06, 0x3f, 0x58, 0xf2, 0x5f, 0xc0, 0x2d, 0xa2, 0x7f, 0xaf, 0x08, 0x53, 0x35, 0x45, + 0xb7, 0x69, 0xe6, 0x00, 0x1e, 0xe6, 0xba, 0x9b, 0x83, 0x93, 0x96, 0xae, 0x57, 0x52, 0x3e, 0xed, + 0x02, 0xae, 0x93, 0xd7, 0x56, 0xd0, 0x31, 0x6c, 0x70, 0xe1, 0x8c, 0x69, 0x24, 0x93, 0x4a, 0x64, + 0x7e, 0x47, 0x72, 0x7f, 0x54, 0x9f, 0x65, 0x81, 0xe6, 0x19, 0x4e, 0xa2, 0x5d, 0xf6, 0x81, 0x1e, + 0x43, 0x51, 0x90, 0xb3, 0xb4, 0xe5, 0xcc, 0xbd, 0x24, 0x98, 0x9c, 0xc9, 0x25, 0x17, 0x9a, 0x81, + 0x7e, 0x03, 0xe0, 0xfa, 0x51, 0x48, 0xa4, 0x33, 0xa6, 0xc2, 0x1c, 0x76, 0xee, 0x16, 0xfb, 0x73, + 0xd4, 0x92, 0x97, 0x0c, 0x1b, 0x1d, 0x40, 0xd5, 0x21, 0xa9, 0x5c, 0x4b, 0xd7, 0xff, 0xa3, 0xed, + 0x76, 0x8d, 0x8b, 0xba, 0x72, 0x71, 0x75, 0xb9, 0x59, 0x49, 0x2d, 0xb8, 0xe2, 0x10, 0x23, 0xdf, + 0x03, 0xd8, 0x50, 0xff, 0x6e, 0x23, 0x97, 0x9e, 0x91, 0x38, 0x90, 0x89, 0x4c, 0xae, 0x29, 0x2b, + 0xea, 0x47, 0xa0, 0x6f, 0x70, 0x26, 0xae, 0x9a, 0xcc, 0xd8, 0xd0, 0xef, 0xe0, 0x16, 0x65, 0x8e, + 0x98, 0x69, 0xb1, 0xa6, 0x11, 0x56, 0xae, 0xdf, 0xec, 0x60, 0x0e, 0x5e, 0xda, 0x6c, 0x9d, 0xbe, + 0x66, 0x6f, 0xff, 0xb5, 0x00, 0x90, 0x54, 0xea, 0x0f, 0x2b, 0x40, 0x04, 0x45, 0x97, 0x48, 0xa2, + 0x35, 0x57, 0xc3, 0x7a, 0x8c, 0xbe, 0x00, 0x90, 0x74, 0x12, 0x06, 0x44, 0xfa, 0xcc, 0x33, 0xb2, + 0x79, 0xdb, 0x73, 0x90, 0x41, 0xeb, 0x38, 0x93, 0x90, 0xff, 0xaf, 0xe3, 0xec, 0xd9, 0xaf, 0xbe, + 0x6d, 0xae, 0xfc, 0xe3, 0xdb, 0xe6, 0xca, 0x1f, 0xaf, 0x9a, 0x85, 0x57, 0x57, 0xcd, 0xc2, 0xdf, + 0xae, 0x9a, 0x85, 0x7f, 0x5e, 0x35, 0x0b, 0xa7, 0x25, 0xdd, 0xc3, 0xfd, 0xe4, 0xbf, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x06, 0x93, 0x6e, 0xba, 0xfc, 0x12, 0x00, 0x00, } diff --git a/vendor/github.com/docker/swarmkit/api/specs.proto b/vendor/github.com/docker/swarmkit/api/specs.proto index f7a4d18b2e..13b52d4105 100644 --- a/vendor/github.com/docker/swarmkit/api/specs.proto +++ b/vendor/github.com/docker/swarmkit/api/specs.proto @@ -386,6 +386,13 @@ message SecretSpec { // Data is the secret payload - the maximum size is 500KB (that is, 500*1024 bytes) bytes data = 2; + + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Driver templating = 3; } // ConfigSpec specifies user-provided configuration files. @@ -396,4 +403,11 @@ message ConfigSpec { // TODO(aaronl): Do we want to revise this to include multiple payloads in a single // ConfigSpec? Define this to be a tar? etc... bytes data = 2; + + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Driver templating = 3; } diff --git a/vendor/github.com/docker/swarmkit/ca/certificates.go b/vendor/github.com/docker/swarmkit/ca/certificates.go index 642c07772b..7a638fe136 100644 --- a/vendor/github.com/docker/swarmkit/ca/certificates.go +++ b/vendor/github.com/docker/swarmkit/ca/certificates.go @@ -126,6 +126,11 @@ type LocalSigner struct { cryptoSigner crypto.Signer } +type x509UnknownAuthError struct { + error + failedLeafCert *x509.Certificate +} + // RootCA is the representation of everything we need to sign certificates and/or to verify certificates // // RootCA.Cert: [CA cert1][CA cert2] @@ -275,6 +280,17 @@ func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWrit // Create an X509Cert so we can .Verify() // Check to see if this certificate was signed by our CA, and isn't expired parsedCerts, chains, err := ValidateCertChain(rca.Pool, signedCert, false) + // TODO(cyli): - right now we need the invalid certificate in order to determine whether or not we should + // download a new root, because we only want to do that in the case of workers. When we have a single + // codepath for updating the root CAs for both managers and workers, this snippet can go. + if _, ok := err.(x509.UnknownAuthorityError); ok { + if parsedCerts, parseErr := helpers.ParseCertificatesPEM(signedCert); parseErr == nil && len(parsedCerts) > 0 { + return nil, nil, x509UnknownAuthError{ + error: err, + failedLeafCert: parsedCerts[0], + } + } + } if err != nil { return nil, nil, err } diff --git a/vendor/github.com/docker/swarmkit/ca/config.go b/vendor/github.com/docker/swarmkit/ca/config.go index 8f16cc22b5..9dd84ecb36 100644 --- a/vendor/github.com/docker/swarmkit/ca/config.go +++ b/vendor/github.com/docker/swarmkit/ca/config.go @@ -492,9 +492,35 @@ func (rootCA RootCA) CreateSecurityConfig(ctx context.Context, krw *KeyReadWrite return secConfig, err } +// TODO(cyli): currently we have to only update if it's a worker role - if we have a single root CA update path for +// both managers and workers, we won't need to check any more. +func updateRootThenUpdateCert(ctx context.Context, s *SecurityConfig, connBroker *connectionbroker.Broker, rootPaths CertPaths, failedCert *x509.Certificate) (*tls.Certificate, *IssuerInfo, error) { + if len(failedCert.Subject.OrganizationalUnit) == 0 || failedCert.Subject.OrganizationalUnit[0] != WorkerRole { + return nil, nil, errors.New("cannot update root CA since this is not a worker") + } + // try downloading a new root CA if it's an unknown authority issue, in case there was a root rotation completion + // and we just didn't get the new root + rootCA, err := GetRemoteCA(ctx, "", connBroker) + if err != nil { + return nil, nil, err + } + // validate against the existing security config creds + if err := s.UpdateRootCA(&rootCA, rootCA.Pool); err != nil { + return nil, nil, err + } + if err := SaveRootCA(rootCA, rootPaths); err != nil { + return nil, nil, err + } + return rootCA.RequestAndSaveNewCertificates(ctx, s.KeyWriter(), + CertificateRequestConfig{ + ConnBroker: connBroker, + Credentials: s.ClientTLSCreds, + }) +} + // RenewTLSConfigNow gets a new TLS cert and key, and updates the security config if provided. This is similar to // RenewTLSConfig, except while that monitors for expiry, and periodically renews, this renews once and is blocking -func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *connectionbroker.Broker) error { +func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *connectionbroker.Broker, rootPaths CertPaths) error { s.renewalMu.Lock() defer s.renewalMu.Unlock() @@ -512,6 +538,15 @@ func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *conne ConnBroker: connBroker, Credentials: s.ClientTLSCreds, }) + if wrappedError, ok := err.(x509UnknownAuthError); ok { + var newErr error + tlsKeyPair, issuerInfo, newErr = updateRootThenUpdateCert(ctx, s, connBroker, rootPaths, wrappedError.failedLeafCert) + if newErr != nil { + err = wrappedError.error + } else { + err = nil + } + } if err != nil { log.WithError(err).Errorf("failed to renew the certificate") return err diff --git a/vendor/github.com/docker/swarmkit/ca/renewer.go b/vendor/github.com/docker/swarmkit/ca/renewer.go index 213a66a25b..6d0229bd1d 100644 --- a/vendor/github.com/docker/swarmkit/ca/renewer.go +++ b/vendor/github.com/docker/swarmkit/ca/renewer.go @@ -27,14 +27,16 @@ type TLSRenewer struct { connBroker *connectionbroker.Broker renew chan struct{} expectedRole string + rootPaths CertPaths } // NewTLSRenewer creates a new TLS renewer. It must be started with Start. -func NewTLSRenewer(s *SecurityConfig, connBroker *connectionbroker.Broker) *TLSRenewer { +func NewTLSRenewer(s *SecurityConfig, connBroker *connectionbroker.Broker, rootPaths CertPaths) *TLSRenewer { return &TLSRenewer{ s: s, connBroker: connBroker, renew: make(chan struct{}, 1), + rootPaths: rootPaths, } } @@ -135,7 +137,7 @@ func (t *TLSRenewer) Start(ctx context.Context) <-chan CertificateUpdate { // ignore errors - it will just try again later var certUpdate CertificateUpdate - if err := RenewTLSConfigNow(ctx, t.s, t.connBroker); err != nil { + if err := RenewTLSConfigNow(ctx, t.s, t.connBroker, t.rootPaths); err != nil { certUpdate.Err = err expBackoff.Failure(nil, nil) } else { diff --git a/vendor/github.com/docker/swarmkit/ca/server.go b/vendor/github.com/docker/swarmkit/ca/server.go index b4b0668049..cb3b6acdc1 100644 --- a/vendor/github.com/docker/swarmkit/ca/server.go +++ b/vendor/github.com/docker/swarmkit/ca/server.go @@ -624,10 +624,6 @@ func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) error { if err != nil { return errors.Wrap(err, "invalid Root CA object in cluster") } - if err := SaveRootCA(updatedRootCA, s.rootPaths); err != nil { - return errors.Wrap(err, "unable to save new root CA certificates") - } - externalCARootPool := updatedRootCA.Pool if rCA.RootRotation != nil { // the external CA has to trust the new CA cert @@ -640,6 +636,9 @@ func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) error { if err := s.securityConfig.UpdateRootCA(&updatedRootCA, externalCARootPool); err != nil { return errors.Wrap(err, "updating Root CA failed") } + if err := SaveRootCA(updatedRootCA, s.rootPaths); err != nil { + return errors.Wrap(err, "unable to save new root CA certificates") + } // only update the server cache if we've successfully updated the root CA logger.Debugf("Root CA %s successfully", setOrUpdate) s.lastSeenClusterRootCA = rCA diff --git a/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go b/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go index 6d9193b308..2cfc95130d 100644 --- a/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go +++ b/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go @@ -142,6 +142,10 @@ func (na *cnmNetworkAllocator) Allocate(n *api.Network) error { n.DriverState = &api.Driver{ Name: d.name, } + // In order to support backward compatibility with older daemon + // versions which assumes the network attachment to contains + // non nil IPAM attribute, passing an empty object + n.IPAM = &api.IPAMOptions{Driver: &api.Driver{}} } else { nw.pools, err = na.allocatePools(n) if err != nil { diff --git a/vendor/github.com/docker/swarmkit/manager/allocator/network.go b/vendor/github.com/docker/swarmkit/manager/allocator/network.go index 1675dbe249..c760ad53dc 100644 --- a/vendor/github.com/docker/swarmkit/manager/allocator/network.go +++ b/vendor/github.com/docker/swarmkit/manager/allocator/network.go @@ -59,6 +59,12 @@ type networkContext struct { // lastRetry is the last timestamp when unallocated // tasks/services/networks were retried. lastRetry time.Time + + // somethingWasDeallocated indicates that we just deallocated at + // least one service/task/network, so we should retry failed + // allocations (in we are experiencing IP exhaustion and an IP was + // released). + somethingWasDeallocated bool } func (a *Allocator) doNetworkInit(ctx context.Context) (err error) { @@ -226,6 +232,8 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) { // resources. if err := nc.nwkAllocator.Deallocate(n); err != nil { log.G(ctx).WithError(err).Errorf("Failed during network free for network %s", n.ID) + } else { + nc.somethingWasDeallocated = true } delete(nc.unallocatedNetworks, n.ID) @@ -292,6 +300,8 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) { if err := nc.nwkAllocator.DeallocateService(s); err != nil { log.G(ctx).WithError(err).Errorf("Failed deallocation during delete of service %s", s.ID) + } else { + nc.somethingWasDeallocated = true } // Remove it from unallocatedServices just in case @@ -304,11 +314,12 @@ func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) { case state.EventCommit: a.procTasksNetwork(ctx, false) - if time.Since(nc.lastRetry) > retryInterval { + if time.Since(nc.lastRetry) > retryInterval || nc.somethingWasDeallocated { a.procUnallocatedNetworks(ctx) a.procUnallocatedServices(ctx) a.procTasksNetwork(ctx, true) nc.lastRetry = time.Now() + nc.somethingWasDeallocated = false } // Any left over tasks are moved to the unallocated set @@ -353,6 +364,8 @@ func (a *Allocator) doNodeAlloc(ctx context.Context, ev events.Event) { if nc.nwkAllocator.IsNodeAllocated(node) { if err := nc.nwkAllocator.DeallocateNode(node); err != nil { log.G(ctx).WithError(err).Errorf("Failed freeing network resources for node %s", node.ID) + } else { + nc.somethingWasDeallocated = true } } return @@ -447,6 +460,8 @@ func (a *Allocator) deallocateNodes(ctx context.Context) error { if nc.nwkAllocator.IsNodeAllocated(node) { if err := nc.nwkAllocator.DeallocateNode(node); err != nil { log.G(ctx).WithError(err).Errorf("Failed freeing network resources for node %s", node.ID) + } else { + nc.somethingWasDeallocated = true } node.Attachment = nil if err := a.store.Batch(func(batch *store.Batch) error { @@ -695,12 +710,15 @@ func (a *Allocator) doTaskAlloc(ctx context.Context, ev events.Event) { if nc.nwkAllocator.IsTaskAllocated(t) { if err := nc.nwkAllocator.DeallocateTask(t); err != nil { log.G(ctx).WithError(err).Errorf("Failed freeing network resources for task %s", t.ID) + } else { + nc.somethingWasDeallocated = true } } // Cleanup any task references that might exist delete(nc.pendingTasks, t.ID) delete(nc.unallocatedTasks, t.ID) + return } @@ -835,6 +853,7 @@ func (a *Allocator) allocateService(ctx context.Context, s *api.Service) error { if err := nc.nwkAllocator.DeallocateService(s); err != nil { return err } + nc.somethingWasDeallocated = true } if err := nc.nwkAllocator.AllocateService(s); err != nil { @@ -887,7 +906,7 @@ func (a *Allocator) allocateNetwork(ctx context.Context, n *api.Network) error { if err := nc.nwkAllocator.Allocate(n); err != nil { nc.unallocatedNetworks[n.ID] = n - return errors.Wrapf(err, "failed during network allocation for network %s", n.ID) + return err } return nil @@ -954,7 +973,6 @@ func (a *Allocator) allocateTask(ctx context.Context, t *api.Task) (err error) { } if err = nc.nwkAllocator.AllocateTask(t); err != nil { - err = errors.Wrapf(err, "failed during network allocation for task %s", t.ID) return } if nc.nwkAllocator.IsTaskAllocated(t) { diff --git a/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go b/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go index 9832272a3f..7e9dea2ce5 100644 --- a/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go +++ b/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/vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go b/vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go index 4eeb4ccb10..33275f4c16 100644 --- a/vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go +++ b/vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go @@ -631,7 +631,7 @@ func (d *Dispatcher) processUpdates(ctx context.Context) { logger.WithError(err).Error("failed to update task status") return nil } - logger.Debug("task status updated") + logger.Debug("dispatcher committed status update to store") return nil }) if err != nil { diff --git a/vendor/github.com/docker/swarmkit/manager/manager.go b/vendor/github.com/docker/swarmkit/manager/manager.go index c29e9050b7..d17e8ec231 100644 --- a/vendor/github.com/docker/swarmkit/manager/manager.go +++ b/vendor/github.com/docker/swarmkit/manager/manager.go @@ -698,7 +698,7 @@ func (m *Manager) updateKEK(ctx context.Context, cluster *api.Cluster) error { connBroker := connectionbroker.New(remotes.NewRemotes()) connBroker.SetLocalConn(conn) - if err := ca.RenewTLSConfigNow(ctx, securityConfig, connBroker); err != nil { + if err := ca.RenewTLSConfigNow(ctx, securityConfig, connBroker, m.config.RootCAPaths); err != nil { logger.WithError(err).Error("failed to download new TLS certificate after locking the cluster") } }() @@ -945,18 +945,19 @@ func (m *Manager) becomeLeader(ctx context.Context) { if err := store.CreateNetwork(tx, newIngressNetwork()); err != nil { log.G(ctx).WithError(err).Error("failed to create default ingress network") } - // Create now the static predefined node-local networks which - // are known to be present in each cluster node. This is needed - // in order to allow running services on the predefined docker - // networks like `bridge` and `host`. - log.G(ctx).Info("Creating node-local predefined networks") - for _, p := range allocator.PredefinedNetworks() { + } + // Create now the static predefined if the store does not contain predefined + //networks like bridge/host node-local networks which + // are known to be present in each cluster node. This is needed + // in order to allow running services on the predefined docker + // networks like `bridge` and `host`. + for _, p := range allocator.PredefinedNetworks() { + if store.GetNetwork(tx, p.Name) == nil { if err := store.CreateNetwork(tx, newPredefinedNetwork(p.Name, p.Driver)); err != nil { log.G(ctx).WithError(err).Error("failed to create predefined network " + p.Name) } } } - return nil }) @@ -1033,7 +1034,7 @@ func (m *Manager) becomeLeader(ctx context.Context) { }(m.constraintEnforcer) go func(taskReaper *taskreaper.TaskReaper) { - taskReaper.Run() + taskReaper.Run(ctx) }(m.taskReaper) go func(orchestrator *replicated.Orchestrator) { diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go index e051155dff..edb771c699 100644 --- a/vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go +++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go @@ -4,7 +4,6 @@ import ( "sort" "time" - "github.com/docker/go-events" "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/log" "github.com/docker/swarmkit/manager/state" @@ -33,29 +32,28 @@ type TaskReaper struct { taskHistory int64 dirty map[instanceTuple]struct{} orphaned []string - watcher chan events.Event - cancelWatch func() stopChan chan struct{} doneChan chan struct{} } // New creates a new TaskReaper. func New(store *store.MemoryStore) *TaskReaper { - watcher, cancel := state.Watch(store.WatchQueue(), api.EventCreateTask{}, api.EventUpdateTask{}, api.EventUpdateCluster{}) - return &TaskReaper{ - store: store, - watcher: watcher, - cancelWatch: cancel, - dirty: make(map[instanceTuple]struct{}), - stopChan: make(chan struct{}), - doneChan: make(chan struct{}), + store: store, + dirty: make(map[instanceTuple]struct{}), + stopChan: make(chan struct{}), + doneChan: make(chan struct{}), } } // Run is the TaskReaper's main loop. -func (tr *TaskReaper) Run() { - defer close(tr.doneChan) +func (tr *TaskReaper) Run(ctx context.Context) { + watcher, watchCancel := state.Watch(tr.store.WatchQueue(), api.EventCreateTask{}, api.EventUpdateTask{}, api.EventUpdateCluster{}) + + defer func() { + close(tr.doneChan) + watchCancel() + }() var tasks []*api.Task tr.store.View(func(readTx store.ReadTx) { @@ -68,7 +66,7 @@ func (tr *TaskReaper) Run() { tasks, err = store.FindTasks(readTx, store.ByTaskState(api.TaskStateOrphaned)) if err != nil { - log.G(context.TODO()).WithError(err).Error("failed to find Orphaned tasks in task reaper init") + log.G(ctx).WithError(err).Error("failed to find Orphaned tasks in task reaper init") } }) @@ -91,7 +89,7 @@ func (tr *TaskReaper) Run() { for { select { - case event := <-tr.watcher: + case event := <-watcher: switch v := event.(type) { case api.EventCreateTask: t := v.Task @@ -218,7 +216,6 @@ func (tr *TaskReaper) tick() { // Stop stops the TaskReaper and waits for the main loop to exit. func (tr *TaskReaper) Stop() { - tr.cancelWatch() close(tr.stopChan) <-tr.doneChan } diff --git a/vendor/github.com/docker/swarmkit/manager/scheduler/filter.go b/vendor/github.com/docker/swarmkit/manager/scheduler/filter.go index 6ce3f2c8b8..36b601c4b4 100644 --- a/vendor/github.com/docker/swarmkit/manager/scheduler/filter.go +++ b/vendor/github.com/docker/swarmkit/manager/scheduler/filter.go @@ -128,7 +128,7 @@ func (f *PluginFilter) SetTask(t *api.Task) bool { } } - if (c != nil && volumeTemplates) || len(t.Networks) > 0 { + if (c != nil && volumeTemplates) || len(t.Networks) > 0 || t.Spec.LogDriver != nil { f.t = t return true } @@ -153,7 +153,7 @@ func (f *PluginFilter) Check(n *NodeInfo) bool { if container != nil { for _, mount := range container.Mounts { if referencesVolumePlugin(mount) { - if !f.pluginExistsOnNode("Volume", mount.VolumeOptions.DriverConfig.Name, nodePlugins) { + if _, exists := f.pluginExistsOnNode("Volume", mount.VolumeOptions.DriverConfig.Name, nodePlugins); !exists { return false } } @@ -163,22 +163,34 @@ func (f *PluginFilter) Check(n *NodeInfo) bool { // Check if all network plugins required by task are installed on node for _, tn := range f.t.Networks { if tn.Network != nil && tn.Network.DriverState != nil && tn.Network.DriverState.Name != "" { - if !f.pluginExistsOnNode("Network", tn.Network.DriverState.Name, nodePlugins) { + if _, exists := f.pluginExistsOnNode("Network", tn.Network.DriverState.Name, nodePlugins); !exists { return false } } } + + if f.t.Spec.LogDriver != nil { + // If there are no log driver types in the list at all, most likely this is + // an older daemon that did not report this information. In this case don't filter + if typeFound, exists := f.pluginExistsOnNode("Log", f.t.Spec.LogDriver.Name, nodePlugins); !exists && typeFound { + return false + } + } return true } // pluginExistsOnNode returns true if the (pluginName, pluginType) pair is present in nodePlugins -func (f *PluginFilter) pluginExistsOnNode(pluginType string, pluginName string, nodePlugins []api.PluginDescription) bool { +func (f *PluginFilter) pluginExistsOnNode(pluginType string, pluginName string, nodePlugins []api.PluginDescription) (bool, bool) { + var typeFound bool + for _, np := range nodePlugins { if pluginType != np.Type { continue } + typeFound = true + if pluginName == np.Name { - return true + return true, true } // This does not use the reference package to avoid the // overhead of parsing references as part of the scheduling @@ -186,10 +198,10 @@ func (f *PluginFilter) pluginExistsOnNode(pluginType string, pluginName string, // strict subset of the reference grammar that is always // name:tag. if strings.HasPrefix(np.Name, pluginName) && np.Name[len(pluginName):] == ":latest" { - return true + return true, true } } - return false + return typeFound, false } // Explain returns an explanation of a failure. diff --git a/vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go b/vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go index 51322a054d..a375ed9f5d 100644 --- a/vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go +++ b/vendor/github.com/docker/swarmkit/manager/scheduler/nodeinfo.go @@ -63,6 +63,15 @@ func (nodeInfo *NodeInfo) removeTask(t *api.Task) bool { nodeInfo.ActiveTasksCountByService[t.ServiceID]-- } + if t.Endpoint != nil { + for _, port := range t.Endpoint.Ports { + if port.PublishMode == api.PublishModeHost && port.PublishedPort != 0 { + portSpec := hostPortSpec{protocol: port.Protocol, publishedPort: port.PublishedPort} + delete(nodeInfo.usedHostPorts, portSpec) + } + } + } + reservations := taskReservations(t.Spec) resources := nodeInfo.AvailableResources @@ -79,15 +88,6 @@ func (nodeInfo *NodeInfo) removeTask(t *api.Task) bool { nodeRes := nodeInfo.Description.Resources.Generic genericresource.Reclaim(nodeAvailableResources, taskAssigned, nodeRes) - if t.Endpoint != nil { - for _, port := range t.Endpoint.Ports { - if port.PublishMode == api.PublishModeHost && port.PublishedPort != 0 { - portSpec := hostPortSpec{protocol: port.Protocol, publishedPort: port.PublishedPort} - delete(nodeInfo.usedHostPorts, portSpec) - } - } - } - return true } diff --git a/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go b/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go index 7f899d8b26..b83704a18d 100644 --- a/vendor/github.com/docker/swarmkit/manager/scheduler/nodeset.go +++ b/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/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go b/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go index 3e5bbd0870..07d9b0458c 100644 --- a/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go +++ b/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go @@ -31,8 +31,11 @@ type schedulingDecision struct { type Scheduler struct { store *store.MemoryStore unassignedTasks map[string]*api.Task - // preassignedTasks already have NodeID, need resource validation - preassignedTasks map[string]*api.Task + // pendingPreassignedTasks already have NodeID, need resource validation + pendingPreassignedTasks map[string]*api.Task + // preassignedTasks tracks tasks that were preassigned, including those + // past the pending state. + preassignedTasks map[string]struct{} nodeSet nodeSet allTasks map[string]*api.Task pipeline *Pipeline @@ -46,13 +49,14 @@ type Scheduler struct { // New creates a new scheduler. func New(store *store.MemoryStore) *Scheduler { return &Scheduler{ - store: store, - unassignedTasks: make(map[string]*api.Task), - preassignedTasks: make(map[string]*api.Task), - allTasks: make(map[string]*api.Task), - stopChan: make(chan struct{}), - doneChan: make(chan struct{}), - pipeline: NewPipeline(), + store: store, + unassignedTasks: make(map[string]*api.Task), + pendingPreassignedTasks: make(map[string]*api.Task), + preassignedTasks: make(map[string]struct{}), + allTasks: make(map[string]*api.Task), + stopChan: make(chan struct{}), + doneChan: make(chan struct{}), + pipeline: NewPipeline(), } } @@ -77,7 +81,8 @@ func (s *Scheduler) setupTasksList(tx store.ReadTx) error { } // preassigned tasks need to validate resource requirement on corresponding node if t.Status.State == api.TaskStatePending { - s.preassignedTasks[t.ID] = t + s.preassignedTasks[t.ID] = struct{}{} + s.pendingPreassignedTasks[t.ID] = t continue } @@ -129,7 +134,7 @@ func (s *Scheduler) Run(ctx context.Context) error { tickRequired := false schedule := func() { - if len(s.preassignedTasks) > 0 { + if len(s.pendingPreassignedTasks) > 0 { s.processPreassignedTasks(ctx) } if tickRequired { @@ -152,7 +157,7 @@ func (s *Scheduler) Run(ctx context.Context) error { tickRequired = true } case api.EventDeleteTask: - if s.deleteTask(ctx, v.Task) { + if s.deleteTask(v.Task) { // deleting tasks may free up node resource, pending tasks should be re-evaluated. tickRequired = true } @@ -216,7 +221,8 @@ func (s *Scheduler) createTask(ctx context.Context, t *api.Task) bool { } if t.Status.State == api.TaskStatePending { - s.preassignedTasks[t.ID] = t + s.preassignedTasks[t.ID] = struct{}{} + s.pendingPreassignedTasks[t.ID] = t // preassigned tasks do not contribute to running tasks count return false } @@ -244,22 +250,32 @@ func (s *Scheduler) updateTask(ctx context.Context, t *api.Task) bool { if oldTask == nil { return false } - s.deleteTask(ctx, oldTask) + if t.Status.State != oldTask.Status.State && (t.Status.State == api.TaskStateFailed || t.Status.State == api.TaskStateRejected) { - nodeInfo, err := s.nodeSet.nodeInfo(t.NodeID) - if err == nil { - nodeInfo.taskFailed(ctx, t.ServiceID) - s.nodeSet.updateNode(nodeInfo) + // Keep track of task failures, so other nodes can be preferred + // for scheduling this service if it looks like the service is + // failing in a loop on this node. However, skip this for + // preassigned tasks, because the scheduler does not choose + // which nodes those run on. + if _, wasPreassigned := s.preassignedTasks[t.ID]; !wasPreassigned { + nodeInfo, err := s.nodeSet.nodeInfo(t.NodeID) + if err == nil { + nodeInfo.taskFailed(ctx, t.ServiceID) + s.nodeSet.updateNode(nodeInfo) + } } } + + s.deleteTask(oldTask) + return true } if t.NodeID == "" { // unassigned task if oldTask != nil { - s.deleteTask(ctx, oldTask) + s.deleteTask(oldTask) } s.allTasks[t.ID] = t s.enqueue(t) @@ -268,10 +284,11 @@ func (s *Scheduler) updateTask(ctx context.Context, t *api.Task) bool { if t.Status.State == api.TaskStatePending { if oldTask != nil { - s.deleteTask(ctx, oldTask) + s.deleteTask(oldTask) } + s.preassignedTasks[t.ID] = struct{}{} s.allTasks[t.ID] = t - s.preassignedTasks[t.ID] = t + s.pendingPreassignedTasks[t.ID] = t // preassigned tasks do not contribute to running tasks count return false } @@ -285,9 +302,10 @@ func (s *Scheduler) updateTask(ctx context.Context, t *api.Task) bool { return false } -func (s *Scheduler) deleteTask(ctx context.Context, t *api.Task) bool { +func (s *Scheduler) deleteTask(t *api.Task) bool { delete(s.allTasks, t.ID) delete(s.preassignedTasks, t.ID) + delete(s.pendingPreassignedTasks, t.ID) nodeInfo, err := s.nodeSet.nodeInfo(t.NodeID) if err == nil && nodeInfo.removeTask(t) { s.nodeSet.updateNode(nodeInfo) @@ -297,31 +315,38 @@ 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.Copy() // reconcile resources by looping over all tasks in this node - for _, task := range nodeInfo.Tasks { - reservations := taskReservations(task.Spec) + if nodeInfoErr == nil { + for _, task := range nodeInfo.Tasks { + reservations := taskReservations(task.Spec) - resources.MemoryBytes -= reservations.MemoryBytes - resources.NanoCPUs -= reservations.NanoCPUs + resources.MemoryBytes -= reservations.MemoryBytes + resources.NanoCPUs -= reservations.NanoCPUs - genericresource.ConsumeNodeResources(&resources.Generic, - task.AssignedGenericResources) + genericresource.ConsumeNodeResources(&resources.Generic, + task.AssignedGenericResources) + } } } else { resources = &api.Resources{} } - 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) } func (s *Scheduler) processPreassignedTasks(ctx context.Context) { - schedulingDecisions := make(map[string]schedulingDecision, len(s.preassignedTasks)) - for _, t := range s.preassignedTasks { + schedulingDecisions := make(map[string]schedulingDecision, len(s.pendingPreassignedTasks)) + for _, t := range s.pendingPreassignedTasks { newT := s.taskFitNode(ctx, t, t.NodeID) if newT == nil { continue @@ -333,7 +358,7 @@ func (s *Scheduler) processPreassignedTasks(ctx context.Context) { for _, decision := range successful { if decision.new.Status.State == api.TaskStateAssigned { - delete(s.preassignedTasks, decision.old.ID) + delete(s.pendingPreassignedTasks, decision.old.ID) } } for _, decision := range failed { @@ -421,12 +446,7 @@ func (s *Scheduler) applySchedulingDecisions(ctx context.Context, schedulingDeci t := store.GetTask(tx, taskID) if t == nil { // Task no longer exists - nodeInfo, err := s.nodeSet.nodeInfo(decision.new.NodeID) - if err == nil && nodeInfo.removeTask(decision.new) { - s.nodeSet.updateNode(nodeInfo) - } - delete(s.allTasks, decision.old.ID) - + s.deleteTask(decision.new) continue } diff --git a/vendor/github.com/docker/swarmkit/node/node.go b/vendor/github.com/docker/swarmkit/node/node.go index ab8504c232..29badd06ed 100644 --- a/vendor/github.com/docker/swarmkit/node/node.go +++ b/vendor/github.com/docker/swarmkit/node/node.go @@ -281,7 +281,7 @@ func (n *Node) run(ctx context.Context) (err error) { return err } - renewer := ca.NewTLSRenewer(securityConfig, n.connBroker) + renewer := ca.NewTLSRenewer(securityConfig, n.connBroker, paths.RootCA) ctx = log.WithLogger(ctx, log.G(ctx).WithField("node.id", n.NodeID())) diff --git a/vendor/github.com/docker/swarmkit/template/context.go b/vendor/github.com/docker/swarmkit/template/context.go index e3c3aab113..d26e155be4 100644 --- a/vendor/github.com/docker/swarmkit/template/context.go +++ b/vendor/github.com/docker/swarmkit/template/context.go @@ -3,13 +3,22 @@ package template import ( "bytes" "fmt" + "strings" + "text/template" + "github.com/docker/swarmkit/agent/configs" + "github.com/docker/swarmkit/agent/exec" + "github.com/docker/swarmkit/agent/secrets" "github.com/docker/swarmkit/api" "github.com/docker/swarmkit/api/naming" + "github.com/pkg/errors" ) // Context defines the strict set of values that can be injected into a // template expression in SwarmKit data structure. +// NOTE: Be very careful adding any fields to this structure with types +// that have methods defined on them. The template would be able to +// invoke those methods. type Context struct { Service struct { ID string @@ -58,7 +67,118 @@ func NewContextFromTask(t *api.Task) (ctx Context) { // Expand treats the string s as a template and populates it with values from // the context. func (ctx *Context) Expand(s string) (string, error) { - tmpl, err := newTemplate(s) + tmpl, err := newTemplate(s, nil) + if err != nil { + return s, err + } + + var buf bytes.Buffer + if err := tmpl.Execute(&buf, ctx); err != nil { + return s, err + } + + return buf.String(), nil +} + +// PayloadContext provides a context for expanding a config or secret payload. +// NOTE: Be very careful adding any fields to this structure with types +// that have methods defined on them. The template would be able to +// invoke those methods. +type PayloadContext struct { + Context + + t *api.Task + restrictedSecrets exec.SecretGetter + restrictedConfigs exec.ConfigGetter +} + +func (ctx PayloadContext) secretGetter(target string) (string, error) { + if ctx.restrictedSecrets == nil { + return "", errors.New("secrets unavailable") + } + + container := ctx.t.Spec.GetContainer() + if container == nil { + return "", errors.New("task is not a container") + } + + for _, secretRef := range container.Secrets { + file := secretRef.GetFile() + if file != nil && file.Name == target { + secret, err := ctx.restrictedSecrets.Get(secretRef.SecretID) + if err != nil { + return "", err + } + return string(secret.Spec.Data), nil + } + } + + return "", errors.Errorf("secret target %s not found", target) +} + +func (ctx PayloadContext) configGetter(target string) (string, error) { + if ctx.restrictedConfigs == nil { + return "", errors.New("configs unavailable") + } + + container := ctx.t.Spec.GetContainer() + if container == nil { + return "", errors.New("task is not a container") + } + + for _, configRef := range container.Configs { + file := configRef.GetFile() + if file != nil && file.Name == target { + config, err := ctx.restrictedConfigs.Get(configRef.ConfigID) + if err != nil { + return "", err + } + return string(config.Spec.Data), nil + } + } + + return "", errors.Errorf("config target %s not found", target) +} + +func (ctx PayloadContext) envGetter(variable string) (string, error) { + container := ctx.t.Spec.GetContainer() + if container == nil { + return "", errors.New("task is not a container") + } + + for _, env := range container.Env { + parts := strings.SplitN(env, "=", 2) + + if len(parts) > 1 && parts[0] == variable { + return parts[1], nil + } + } + return "", nil +} + +// NewPayloadContextFromTask returns a new template context from the data +// available in the task. This context also provides access to the configs +// and secrets that the task has access to. The provided context can then +// be used to populate runtime values in a templated config or secret. +func NewPayloadContextFromTask(t *api.Task, dependencies exec.DependencyGetter) (ctx PayloadContext) { + return PayloadContext{ + Context: NewContextFromTask(t), + t: t, + restrictedSecrets: secrets.Restrict(dependencies.Secrets(), t), + restrictedConfigs: configs.Restrict(dependencies.Configs(), t), + } +} + +// Expand treats the string s as a template and populates it with values from +// the context. +func (ctx *PayloadContext) Expand(s string) (string, error) { + funcMap := template.FuncMap{ + "secret": ctx.secretGetter, + "config": ctx.configGetter, + "env": ctx.envGetter, + } + + tmpl, err := newTemplate(s, funcMap) if err != nil { return s, err } diff --git a/vendor/github.com/docker/swarmkit/template/expand.go b/vendor/github.com/docker/swarmkit/template/expand.go index 75fbc09aee..e45c36252d 100644 --- a/vendor/github.com/docker/swarmkit/template/expand.go +++ b/vendor/github.com/docker/swarmkit/template/expand.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/docker/swarmkit/agent/exec" "github.com/docker/swarmkit/api" "github.com/pkg/errors" ) @@ -116,3 +117,45 @@ func expandEnv(ctx Context, values []string) ([]string, error) { return result, nil } + +func expandPayload(ctx PayloadContext, payload []byte) ([]byte, error) { + result, err := ctx.Expand(string(payload)) + if err != nil { + return payload, err + } + return []byte(result), nil +} + +// ExpandSecretSpec expands the template inside the secret payload, if any. +// Templating is evaluated on the agent-side. +func ExpandSecretSpec(s *api.Secret, t *api.Task, dependencies exec.DependencyGetter) (*api.SecretSpec, error) { + if s.Spec.Templating == nil { + return &s.Spec, nil + } + if s.Spec.Templating.Name == "golang" { + ctx := NewPayloadContextFromTask(t, dependencies) + secretSpec := s.Spec.Copy() + + var err error + secretSpec.Data, err = expandPayload(ctx, secretSpec.Data) + return secretSpec, err + } + return &s.Spec, errors.New("unrecognized template type") +} + +// ExpandConfigSpec expands the template inside the config payload, if any. +// Templating is evaluated on the agent-side. +func ExpandConfigSpec(c *api.Config, t *api.Task, dependencies exec.DependencyGetter) (*api.ConfigSpec, error) { + if c.Spec.Templating == nil { + return &c.Spec, nil + } + if c.Spec.Templating.Name == "golang" { + ctx := NewPayloadContextFromTask(t, dependencies) + configSpec := c.Spec.Copy() + + var err error + configSpec.Data, err = expandPayload(ctx, configSpec.Data) + return configSpec, err + } + return &c.Spec, errors.New("unrecognized template type") +} diff --git a/vendor/github.com/docker/swarmkit/template/getter.go b/vendor/github.com/docker/swarmkit/template/getter.go new file mode 100644 index 0000000000..f06c438c25 --- /dev/null +++ b/vendor/github.com/docker/swarmkit/template/getter.go @@ -0,0 +1,98 @@ +package template + +import ( + "github.com/docker/swarmkit/agent/exec" + "github.com/docker/swarmkit/api" + "github.com/pkg/errors" +) + +type templatedSecretGetter struct { + dependencies exec.DependencyGetter + t *api.Task +} + +// NewTemplatedSecretGetter returns a SecretGetter that evaluates templates. +func NewTemplatedSecretGetter(dependencies exec.DependencyGetter, t *api.Task) exec.SecretGetter { + return templatedSecretGetter{dependencies: dependencies, t: t} +} + +func (t templatedSecretGetter) Get(secretID string) (*api.Secret, error) { + if t.dependencies == nil { + return nil, errors.New("no secret provider available") + } + + secrets := t.dependencies.Secrets() + if secrets == nil { + return nil, errors.New("no secret provider available") + } + + secret, err := secrets.Get(secretID) + if err != nil { + return secret, err + } + + newSpec, err := ExpandSecretSpec(secret, t.t, t.dependencies) + if err != nil { + return secret, errors.Wrapf(err, "failed to expand templated secret %s", secretID) + } + + secretCopy := *secret + secretCopy.Spec = *newSpec + return &secretCopy, nil +} + +type templatedConfigGetter struct { + dependencies exec.DependencyGetter + t *api.Task +} + +// NewTemplatedConfigGetter returns a ConfigGetter that evaluates templates. +func NewTemplatedConfigGetter(dependencies exec.DependencyGetter, t *api.Task) exec.ConfigGetter { + return templatedConfigGetter{dependencies: dependencies, t: t} +} + +func (t templatedConfigGetter) Get(configID string) (*api.Config, error) { + if t.dependencies == nil { + return nil, errors.New("no config provider available") + } + + configs := t.dependencies.Configs() + if configs == nil { + return nil, errors.New("no config provider available") + } + + config, err := configs.Get(configID) + if err != nil { + return config, err + } + + newSpec, err := ExpandConfigSpec(config, t.t, t.dependencies) + if err != nil { + return config, errors.Wrapf(err, "failed to expand templated config %s", configID) + } + + configCopy := *config + configCopy.Spec = *newSpec + return &configCopy, nil +} + +type templatedDependencyGetter struct { + secrets exec.SecretGetter + configs exec.ConfigGetter +} + +// NewTemplatedDependencyGetter returns a DependencyGetter that evaluates templates. +func NewTemplatedDependencyGetter(dependencies exec.DependencyGetter, t *api.Task) exec.DependencyGetter { + return templatedDependencyGetter{ + secrets: NewTemplatedSecretGetter(dependencies, t), + configs: NewTemplatedConfigGetter(dependencies, t), + } +} + +func (t templatedDependencyGetter) Secrets() exec.SecretGetter { + return t.secrets +} + +func (t templatedDependencyGetter) Configs() exec.ConfigGetter { + return t.configs +} diff --git a/vendor/github.com/docker/swarmkit/template/template.go b/vendor/github.com/docker/swarmkit/template/template.go index 9f1517c662..fc375b819c 100644 --- a/vendor/github.com/docker/swarmkit/template/template.go +++ b/vendor/github.com/docker/swarmkit/template/template.go @@ -13,6 +13,10 @@ var funcMap = template.FuncMap{ }, } -func newTemplate(s string) (*template.Template, error) { - return template.New("expansion").Option("missingkey=error").Funcs(funcMap).Parse(s) +func newTemplate(s string, extraFuncs template.FuncMap) (*template.Template, error) { + tmpl := template.New("expansion").Option("missingkey=error").Funcs(funcMap) + if len(extraFuncs) != 0 { + tmpl = tmpl.Funcs(extraFuncs) + } + return tmpl.Parse(s) } diff --git a/vendor/github.com/docker/swarmkit/vendor.conf b/vendor/github.com/docker/swarmkit/vendor.conf index 6e86d96796..4f5d293b8b 100644 --- a/vendor/github.com/docker/swarmkit/vendor.conf +++ b/vendor/github.com/docker/swarmkit/vendor.conf @@ -30,6 +30,14 @@ github.com/opencontainers/runc b6b70e53451794e8333e9b602cc096b47a20bd0f github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb github.com/opencontainers/image-spec f03dbe35d449c54915d235f1a3cf8f585a24babe +# containerd executor +github.com/containerd/containerd 7fc91b05917e93d474fab9465547d44eacd10ce3 +github.com/containerd/continuity f4ad4294c92f596c9241947c416d1297f9faf3ea +github.com/containerd/fifo 69b99525e472735860a5269b75af1970142b3062 +github.com/opencontainers/runtime-spec v1.0.0-rc5 +github.com/nightlyone/lockfile 1d49c987357a327b5b03aa84cbddd582c328615d +golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c + github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d github.com/Microsoft/go-winio f778f05015353be65d242f3fedc18695756153bb github.com/Sirupsen/logrus v0.11.0 diff --git a/vendor/github.com/spf13/cobra/doc/man_docs.go b/vendor/github.com/spf13/cobra/doc/man_docs.go deleted file mode 100644 index ae44aaac78..0000000000 --- a/vendor/github.com/spf13/cobra/doc/man_docs.go +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2015 Red Hat Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package doc - -import ( - "bytes" - "fmt" - "io" - "os" - "path/filepath" - "sort" - "strings" - "time" - - mangen "github.com/cpuguy83/go-md2man/md2man" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -// GenManTree will generate a man page for this command and all descendants -// in the directory given. The header may be nil. This function may not work -// correctly if your command names have - in them. If you have `cmd` with two -// subcmds, `sub` and `sub-third`. And `sub` has a subcommand called `third` -// it is undefined which help output will be in the file `cmd-sub-third.1`. -func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) error { - return GenManTreeFromOpts(cmd, GenManTreeOptions{ - Header: header, - Path: dir, - CommandSeparator: "_", - }) -} - -// GenManTreeFromOpts generates a man page for the command and all descendants. -// The pages are written to the opts.Path directory. -func GenManTreeFromOpts(cmd *cobra.Command, opts GenManTreeOptions) error { - header := opts.Header - if header == nil { - header = &GenManHeader{} - } - for _, c := range cmd.Commands() { - if !c.IsAvailableCommand() || c.IsHelpCommand() { - continue - } - if err := GenManTreeFromOpts(c, opts); err != nil { - return err - } - } - section := "1" - if header.Section != "" { - section = header.Section - } - - separator := "_" - if opts.CommandSeparator != "" { - separator = opts.CommandSeparator - } - basename := strings.Replace(cmd.CommandPath(), " ", separator, -1) - filename := filepath.Join(opts.Path, basename+"."+section) - f, err := os.Create(filename) - if err != nil { - return err - } - defer f.Close() - - headerCopy := *header - return GenMan(cmd, &headerCopy, f) -} - -type GenManTreeOptions struct { - Header *GenManHeader - Path string - CommandSeparator string -} - -// GenManHeader is a lot like the .TH header at the start of man pages. These -// include the title, section, date, source, and manual. We will use the -// current time if Date if unset and will use "Auto generated by spf13/cobra" -// if the Source is unset. -type GenManHeader struct { - Title string - Section string - Date *time.Time - date string - Source string - Manual string -} - -// GenMan will generate a man page for the given command and write it to -// w. The header argument may be nil, however obviously w may not. -func GenMan(cmd *cobra.Command, header *GenManHeader, w io.Writer) error { - if header == nil { - header = &GenManHeader{} - } - fillHeader(header, cmd.CommandPath()) - - b := genMan(cmd, header) - _, err := w.Write(mangen.Render(b)) - return err -} - -func fillHeader(header *GenManHeader, name string) { - if header.Title == "" { - header.Title = strings.ToUpper(strings.Replace(name, " ", "\\-", -1)) - } - if header.Section == "" { - header.Section = "1" - } - if header.Date == nil { - now := time.Now() - header.Date = &now - } - header.date = (*header.Date).Format("Jan 2006") - if header.Source == "" { - header.Source = "Auto generated by spf13/cobra" - } -} - -func manPreamble(out io.Writer, header *GenManHeader, cmd *cobra.Command, dashedName string) { - description := cmd.Long - if len(description) == 0 { - description = cmd.Short - } - - fmt.Fprintf(out, `%% %s(%s)%s -%% %s -%% %s -# NAME -`, header.Title, header.Section, header.date, header.Source, header.Manual) - fmt.Fprintf(out, "%s \\- %s\n\n", dashedName, cmd.Short) - fmt.Fprintf(out, "# SYNOPSIS\n") - fmt.Fprintf(out, "**%s**\n\n", cmd.UseLine()) - fmt.Fprintf(out, "# DESCRIPTION\n") - fmt.Fprintf(out, "%s\n\n", description) -} - -func manPrintFlags(out io.Writer, flags *pflag.FlagSet) { - flags.VisitAll(func(flag *pflag.Flag) { - if len(flag.Deprecated) > 0 || flag.Hidden { - return - } - format := "" - if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 { - format = fmt.Sprintf("**-%s**, **--%s**", flag.Shorthand, flag.Name) - } else { - format = fmt.Sprintf("**--%s**", flag.Name) - } - if len(flag.NoOptDefVal) > 0 { - format = format + "[" - } - if flag.Value.Type() == "string" { - // put quotes on the value - format = format + "=%q" - } else { - format = format + "=%s" - } - if len(flag.NoOptDefVal) > 0 { - format = format + "]" - } - format = format + "\n\t%s\n\n" - fmt.Fprintf(out, format, flag.DefValue, flag.Usage) - }) -} - -func manPrintOptions(out io.Writer, command *cobra.Command) { - flags := command.NonInheritedFlags() - if flags.HasFlags() { - fmt.Fprintf(out, "# OPTIONS\n") - manPrintFlags(out, flags) - fmt.Fprintf(out, "\n") - } - flags = command.InheritedFlags() - if flags.HasFlags() { - fmt.Fprintf(out, "# OPTIONS INHERITED FROM PARENT COMMANDS\n") - manPrintFlags(out, flags) - fmt.Fprintf(out, "\n") - } -} - -func genMan(cmd *cobra.Command, header *GenManHeader) []byte { - // something like `rootcmd-subcmd1-subcmd2` - dashCommandName := strings.Replace(cmd.CommandPath(), " ", "-", -1) - - buf := new(bytes.Buffer) - - manPreamble(buf, header, cmd, dashCommandName) - manPrintOptions(buf, cmd) - if len(cmd.Example) > 0 { - fmt.Fprintf(buf, "# EXAMPLE\n") - fmt.Fprintf(buf, "\n%s\n\n", cmd.Example) - } - if hasSeeAlso(cmd) { - fmt.Fprintf(buf, "# SEE ALSO\n") - seealsos := make([]string, 0) - if cmd.HasParent() { - parentPath := cmd.Parent().CommandPath() - dashParentPath := strings.Replace(parentPath, " ", "-", -1) - seealso := fmt.Sprintf("**%s(%s)**", dashParentPath, header.Section) - seealsos = append(seealsos, seealso) - cmd.VisitParents(func(c *cobra.Command) { - if c.DisableAutoGenTag { - cmd.DisableAutoGenTag = c.DisableAutoGenTag - } - }) - } - children := cmd.Commands() - sort.Sort(byName(children)) - for _, c := range children { - if !c.IsAvailableCommand() || c.IsHelpCommand() { - continue - } - seealso := fmt.Sprintf("**%s-%s(%s)**", dashCommandName, c.Name(), header.Section) - seealsos = append(seealsos, seealso) - } - fmt.Fprintf(buf, "%s\n", strings.Join(seealsos, ", ")) - } - if !cmd.DisableAutoGenTag { - fmt.Fprintf(buf, "# HISTORY\n%s Auto generated by spf13/cobra\n", header.Date.Format("2-Jan-2006")) - } - return buf.Bytes() -} diff --git a/vendor/github.com/spf13/cobra/doc/md_docs.go b/vendor/github.com/spf13/cobra/doc/md_docs.go deleted file mode 100644 index fa13631804..0000000000 --- a/vendor/github.com/spf13/cobra/doc/md_docs.go +++ /dev/null @@ -1,175 +0,0 @@ -//Copyright 2015 Red Hat Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package doc - -import ( - "fmt" - "io" - "os" - "path/filepath" - "sort" - "strings" - "time" - - "github.com/spf13/cobra" -) - -func printOptions(w io.Writer, cmd *cobra.Command, name string) error { - flags := cmd.NonInheritedFlags() - flags.SetOutput(w) - if flags.HasFlags() { - if _, err := fmt.Fprintf(w, "### Options\n\n```\n"); err != nil { - return err - } - flags.PrintDefaults() - if _, err := fmt.Fprintf(w, "```\n\n"); err != nil { - return err - } - } - - parentFlags := cmd.InheritedFlags() - parentFlags.SetOutput(w) - if parentFlags.HasFlags() { - if _, err := fmt.Fprintf(w, "### Options inherited from parent commands\n\n```\n"); err != nil { - return err - } - parentFlags.PrintDefaults() - if _, err := fmt.Fprintf(w, "```\n\n"); err != nil { - return err - } - } - return nil -} - -func GenMarkdown(cmd *cobra.Command, w io.Writer) error { - return GenMarkdownCustom(cmd, w, func(s string) string { return s }) -} - -func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error { - name := cmd.CommandPath() - - short := cmd.Short - long := cmd.Long - if len(long) == 0 { - long = short - } - - if _, err := fmt.Fprintf(w, "## %s\n\n", name); err != nil { - return err - } - if _, err := fmt.Fprintf(w, "%s\n\n", short); err != nil { - return err - } - if _, err := fmt.Fprintf(w, "### Synopsis\n\n"); err != nil { - return err - } - if _, err := fmt.Fprintf(w, "\n%s\n\n", long); err != nil { - return err - } - - if cmd.Runnable() { - if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.UseLine()); err != nil { - return err - } - } - - if len(cmd.Example) > 0 { - if _, err := fmt.Fprintf(w, "### Examples\n\n"); err != nil { - return err - } - if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.Example); err != nil { - return err - } - } - - if err := printOptions(w, cmd, name); err != nil { - return err - } - if hasSeeAlso(cmd) { - if _, err := fmt.Fprintf(w, "### SEE ALSO\n"); err != nil { - return err - } - if cmd.HasParent() { - parent := cmd.Parent() - pname := parent.CommandPath() - link := pname + ".md" - link = strings.Replace(link, " ", "_", -1) - if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short); err != nil { - return err - } - cmd.VisitParents(func(c *cobra.Command) { - if c.DisableAutoGenTag { - cmd.DisableAutoGenTag = c.DisableAutoGenTag - } - }) - } - - children := cmd.Commands() - sort.Sort(byName(children)) - - for _, child := range children { - if !child.IsAvailableCommand() || child.IsHelpCommand() { - continue - } - cname := name + " " + child.Name() - link := cname + ".md" - link = strings.Replace(link, " ", "_", -1) - if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short); err != nil { - return err - } - } - if _, err := fmt.Fprintf(w, "\n"); err != nil { - return err - } - } - if !cmd.DisableAutoGenTag { - if _, err := fmt.Fprintf(w, "###### Auto generated by spf13/cobra on %s\n", time.Now().Format("2-Jan-2006")); err != nil { - return err - } - } - return nil -} - -func GenMarkdownTree(cmd *cobra.Command, dir string) error { - identity := func(s string) string { return s } - emptyStr := func(s string) string { return "" } - return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity) -} - -func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error { - for _, c := range cmd.Commands() { - if !c.IsAvailableCommand() || c.IsHelpCommand() { - continue - } - if err := GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler); err != nil { - return err - } - } - - basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".md" - filename := filepath.Join(dir, basename) - f, err := os.Create(filename) - if err != nil { - return err - } - defer f.Close() - - if _, err := io.WriteString(f, filePrepender(filename)); err != nil { - return err - } - if err := GenMarkdownCustom(cmd, f, linkHandler); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/spf13/cobra/doc/util.go b/vendor/github.com/spf13/cobra/doc/util.go deleted file mode 100644 index a1c6b89ba6..0000000000 --- a/vendor/github.com/spf13/cobra/doc/util.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2015 Red Hat Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package doc - -import "github.com/spf13/cobra" - -// Test to see if we have a reason to print See Also information in docs -// Basically this is a test for a parent commend or a subcommand which is -// both not deprecated and not the autogenerated help command. -func hasSeeAlso(cmd *cobra.Command) bool { - if cmd.HasParent() { - return true - } - for _, c := range cmd.Commands() { - if !c.IsAvailableCommand() || c.IsHelpCommand() { - continue - } - return true - } - return false -} - -type byName []*cobra.Command - -func (s byName) Len() int { return len(s) } -func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }