Merge pull request #33773 from aaronlehmann/vendor-swarmkit-79381d0

Vendor swarmkit 79381d0
This commit is contained in:
Sebastiaan van Stijn 2017-06-22 16:26:34 -07:00 committed by GitHub
commit 4d0c01ac17
28 changed files with 755 additions and 251 deletions

View file

@ -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")

View file

@ -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")

View file

@ -106,7 +106,7 @@ github.com/stevvooe/continuity cd7a8e21e2b6f84799f5dd4b65faf49c8d3ee02d
github.com/tonistiigi/fsutil 0ac4c11b053b9c5c7c47558f81f96c7100ce50fb
# 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

View file

@ -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)

View file

@ -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.

View file

@ -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)

View file

@ -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,
}

View file

@ -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;
}

View file

@ -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
}

View file

@ -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

View file

@ -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 {

View file

@ -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

View file

@ -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 {

View file

@ -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) {

View file

@ -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

View file

@ -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 {

View file

@ -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) {

View file

@ -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
}

View file

@ -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.

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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()))

View file

@ -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
}

View file

@ -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")
}

98
vendor/github.com/docker/swarmkit/template/getter.go generated vendored Normal file
View file

@ -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
}

View file

@ -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)
}

View file

@ -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