vendor: update swarmkit in 8a761950f

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi 2016-08-17 22:43:33 -07:00
parent 3b374a25f2
commit ee030251f2
76 changed files with 1988 additions and 1603 deletions

View file

@ -139,7 +139,7 @@ clone git github.com/docker/docker-credential-helpers v0.3.0
clone git github.com/docker/containerd 0ac3cd1be170d180b2baed755e8f0da547ceb267
# cluster
clone git github.com/docker/swarmkit d5f249ec9a52ea48e875b5335a3a0c50f60db550
clone git github.com/docker/swarmkit 8a761950fb4d9251c335dc6149a8a02756cb3b10
clone git github.com/golang/mock bd3c8e81be01eef76d4b503f5e687d2d1354d2d9
clone git github.com/gogo/protobuf 43a2e0b1c32252bfbbdf81f7faa7a88fb3fa4028
clone git github.com/cloudflare/cfssl b895b0549c0ff676f92cf09ba971ae02bb41367b
@ -152,11 +152,11 @@ clone git github.com/hashicorp/go-immutable-radix 8e8ed81f8f0bf1bdd829593fdd5c29
clone git github.com/hashicorp/golang-lru a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
clone git github.com/coreos/pkg fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8
clone git github.com/pivotal-golang/clock 3fd3c1944c59d9742e1cd333672181cd1a6f9fa0
clone git github.com/prometheus/client_golang e51041b3fa41cece0dca035740ba6411905be473
clone git github.com/beorn7/perks b965b613227fddccbfffe13eae360ed3fa822f8d
clone git github.com/prometheus/client_golang 52437c81da6b127a9925d17eb3a382a2e5fd395e
clone git github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
clone git github.com/prometheus/client_model fa8ad6fec33561be4280a8f0514318c79d7f6cb6
clone git github.com/prometheus/common ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650
clone git github.com/prometheus/procfs 454a56f35412459b5e684fd5ec0f9211b94f002a
clone git github.com/prometheus/common ebdfc6da46522d58825777cf1f90490a5b1ef1d8
clone git github.com/prometheus/procfs abf152e5f3e97f2fafac028d2cc06c1feb87ffa5
clone hg bitbucket.org/ww/goautoneg 75cd24fc2f2c2a2088577d12123ddee5f54e0675
clone git github.com/matttproud/golang_protobuf_extensions fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a
clone git github.com/pkg/errors 01fa4104b9c248c8945d14d9f128454d5b28d595

View file

@ -1,13 +0,0 @@
include $(GOROOT)/src/Make.inc
TARG=bitbucket.org/ww/goautoneg
GOFILES=autoneg.go
include $(GOROOT)/src/Make.pkg
format:
gofmt -w *.go
docs:
gomake clean
godoc ${TARG} > README.txt

View file

@ -0,0 +1,20 @@
Copyright (C) 2013 Blake Mizerany
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -133,7 +133,7 @@ func (s *Stream) Query(q float64) float64 {
if l == 0 {
return 0
}
i := int(float64(l) * q)
i := int(math.Ceil(float64(l) * q))
if i > 0 {
i -= 1
}

View file

@ -136,7 +136,7 @@ func (a *Agent) run(ctx context.Context) {
var (
backoff time.Duration
session = newSession(ctx, a, backoff) // start the initial session
session = newSession(ctx, a, backoff, "") // start the initial session
registered = session.registered
ready = a.ready // first session ready
sessionq chan sessionOperation
@ -198,7 +198,7 @@ func (a *Agent) run(ctx context.Context) {
// select a session registration delay from backoff range.
delay := time.Duration(rand.Int63n(int64(backoff)))
session = newSession(ctx, a, delay)
session = newSession(ctx, a, delay, session.sessionID)
registered = session.registered
sessionq = a.sessionq
case <-a.stopped:

View file

@ -42,9 +42,10 @@ type session struct {
closed chan struct{}
}
func newSession(ctx context.Context, agent *Agent, delay time.Duration) *session {
func newSession(ctx context.Context, agent *Agent, delay time.Duration, sessionID string) *session {
s := &session{
agent: agent,
sessionID: sessionID,
errs: make(chan error, 1),
messages: make(chan *api.SessionMessage),
tasks: make(chan *api.TasksMessage),
@ -124,6 +125,7 @@ func (s *session) start(ctx context.Context) error {
stream, err = client.Session(sessionCtx, &api.SessionRequest{
Description: description,
SessionID: s.sessionID,
})
if err != nil {
errChan <- err

View file

@ -1656,36 +1656,36 @@ var (
)
var fileDescriptorCa = []byte{
// 490 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x94, 0xcf, 0x8e, 0xd3, 0x30,
0x10, 0xc6, 0x71, 0x0a, 0xdd, 0x65, 0xba, 0x2a, 0xc8, 0x14, 0xa9, 0x74, 0xb3, 0xdd, 0x95, 0x39,
0xc0, 0x29, 0xdd, 0x0d, 0x9c, 0x38, 0xd1, 0x06, 0x09, 0xf5, 0x00, 0x42, 0xee, 0x03, 0xa0, 0x6c,
0x6a, 0x4a, 0xd4, 0x6d, 0x1c, 0x62, 0x07, 0xc4, 0x0d, 0x09, 0xc4, 0x81, 0x3b, 0x82, 0x13, 0x8f,
0xc0, 0x73, 0xac, 0x38, 0x71, 0xe4, 0x84, 0xd8, 0x7d, 0x00, 0xc4, 0x23, 0x60, 0x3b, 0x29, 0xdd,
0x3f, 0x4e, 0x55, 0x0e, 0xa3, 0xc6, 0xe3, 0xf9, 0xbe, 0xfe, 0x32, 0x63, 0x07, 0xd6, 0xa3, 0xd0,
0x4b, 0x33, 0x2e, 0x39, 0xc6, 0x63, 0x1e, 0x4d, 0x59, 0xe6, 0x89, 0x57, 0x61, 0x36, 0x9b, 0xc6,
0xd2, 0x7b, 0xb9, 0xd7, 0x69, 0xc8, 0xd7, 0x29, 0x13, 0x45, 0x41, 0xa7, 0x21, 0x52, 0x16, 0xcd,
0x17, 0xad, 0x09, 0x9f, 0x70, 0xf3, 0xd8, 0xd3, 0x4f, 0x65, 0xf6, 0x5a, 0x7a, 0x90, 0x4f, 0xe2,
0xa4, 0x57, 0xfc, 0x14, 0x49, 0x12, 0x80, 0xfb, 0x98, 0x8f, 0x59, 0xc0, 0x32, 0x19, 0x3f, 0x8b,
0xa3, 0x50, 0xb2, 0x91, 0x0c, 0x65, 0x2e, 0x28, 0x7b, 0x91, 0x33, 0x21, 0xf1, 0x4d, 0x58, 0x4b,
0xd4, 0xfe, 0xd3, 0x78, 0xdc, 0x46, 0x3b, 0xe8, 0xf6, 0xe5, 0x01, 0x1c, 0xff, 0xdc, 0xae, 0x6b,
0xc9, 0xf0, 0x01, 0xad, 0xeb, 0xad, 0xe1, 0x98, 0x7c, 0x41, 0xb0, 0x55, 0xe1, 0x22, 0x52, 0x9e,
0x08, 0x86, 0xef, 0x41, 0x5d, 0x98, 0x8c, 0x71, 0x69, 0xf8, 0xc4, 0x3b, 0xff, 0x42, 0xde, 0x50,
0x88, 0x3c, 0x4c, 0xa2, 0xb9, 0xb6, 0x54, 0xe0, 0x3e, 0x34, 0xa2, 0x85, 0x71, 0xdb, 0x31, 0x06,
0xdb, 0x36, 0x83, 0x13, 0xff, 0x4f, 0x4f, 0x6a, 0xc8, 0x3b, 0x04, 0x9b, 0xda, 0x9d, 0x9d, 0xa1,
0x9c, 0xbf, 0xe5, 0x5d, 0xb8, 0x98, 0xf1, 0x03, 0x66, 0xe0, 0x9a, 0xbe, 0x6b, 0xf3, 0xd6, 0x4a,
0xaa, 0x6a, 0x06, 0x4e, 0x1b, 0x51, 0x53, 0x8d, 0x6f, 0x40, 0x2d, 0x12, 0x99, 0x01, 0xda, 0x18,
0xac, 0xa9, 0xbe, 0xd4, 0x82, 0x11, 0xa5, 0x3a, 0x87, 0x5b, 0x70, 0x49, 0xf2, 0x29, 0x4b, 0xda,
0x35, 0xdd, 0x34, 0x5a, 0x2c, 0xc8, 0x47, 0x04, 0xae, 0x1d, 0xa3, 0x6c, 0xd3, 0x2a, 0xdd, 0xc6,
0x4f, 0xe0, 0x8a, 0x29, 0x9a, 0xb1, 0xd9, 0x3e, 0xcb, 0xc4, 0xf3, 0x38, 0x35, 0x08, 0x4d, 0xff,
0x56, 0x15, 0xf7, 0x48, 0x9d, 0x0d, 0xef, 0xd1, 0xbf, 0x72, 0xda, 0xd4, 0xfa, 0xc5, 0x9a, 0x6c,
0xc1, 0xe6, 0x43, 0x26, 0x29, 0xe7, 0x32, 0xe8, 0x9f, 0xef, 0x0e, 0xb9, 0x0f, 0xae, 0x7d, 0xbb,
0xa4, 0xde, 0x39, 0x3d, 0x20, 0x4d, 0xbe, 0x71, 0xaa, 0xff, 0xfe, 0x07, 0x04, 0x4e, 0xd0, 0xc7,
0x6f, 0x11, 0xb4, 0x6c, 0x4e, 0xb8, 0x67, 0x23, 0x5f, 0x82, 0xd4, 0xd9, 0x5d, 0x5d, 0x50, 0x40,
0x92, 0xf5, 0x6f, 0x5f, 0x7f, 0x7f, 0x76, 0x9c, 0xab, 0xc8, 0xff, 0xe4, 0x80, 0x69, 0x69, 0x09,
0x64, 0x1b, 0x88, 0x1d, 0x68, 0xc9, 0x09, 0xb2, 0x03, 0x2d, 0x9b, 0xf5, 0x02, 0x08, 0xbf, 0x47,
0x70, 0xdd, 0x7a, 0x7d, 0xf0, 0x6e, 0xd5, 0x44, 0xab, 0xee, 0x6b, 0x67, 0xef, 0x3f, 0x14, 0x67,
0x41, 0x06, 0xee, 0xe1, 0x51, 0xf7, 0xc2, 0x0f, 0x15, 0x7f, 0x8e, 0xba, 0xe8, 0xcd, 0x71, 0x17,
0x1d, 0xaa, 0xf8, 0xae, 0xe2, 0x97, 0x8a, 0xfd, 0xba, 0xf9, 0x62, 0xdc, 0xf9, 0x1b, 0x00, 0x00,
0xff, 0xff, 0xb3, 0xf8, 0x41, 0xef, 0x96, 0x04, 0x00, 0x00,
// 493 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x94, 0xcf, 0x6e, 0xd3, 0x40,
0x10, 0xc6, 0xbb, 0x0e, 0xa4, 0x65, 0x52, 0x05, 0xb4, 0x04, 0x29, 0xa4, 0xa9, 0x53, 0x99, 0x03,
0x9c, 0x9c, 0xd6, 0x70, 0xe2, 0x44, 0x62, 0x24, 0x94, 0x03, 0x08, 0x6d, 0x1e, 0x00, 0xb9, 0xf6,
0x10, 0xac, 0x24, 0x5e, 0xe3, 0xdd, 0x80, 0xb8, 0x21, 0x81, 0x38, 0x70, 0x47, 0x70, 0xe2, 0x11,
0x78, 0x8e, 0x8a, 0x13, 0x47, 0x4e, 0x15, 0xf1, 0x03, 0x20, 0x1e, 0x01, 0xed, 0xda, 0x21, 0xfd,
0xb3, 0x89, 0xca, 0xc9, 0x3b, 0xb3, 0xf3, 0x7d, 0xfe, 0xed, 0x8c, 0xd7, 0xb0, 0x15, 0x06, 0x6e,
0x9a, 0x71, 0xc9, 0x29, 0x8d, 0x78, 0x38, 0xc6, 0xcc, 0x15, 0xaf, 0x83, 0x6c, 0x3a, 0x8e, 0xa5,
0xfb, 0xea, 0xa0, 0x55, 0x93, 0x6f, 0x52, 0x14, 0x45, 0x41, 0xab, 0x26, 0x52, 0x0c, 0x17, 0x41,
0x63, 0xc4, 0x47, 0x5c, 0x2f, 0xbb, 0x6a, 0x55, 0x66, 0xaf, 0xa7, 0x93, 0xd9, 0x28, 0x4e, 0xba,
0xc5, 0xa3, 0x48, 0x3a, 0x3e, 0xb4, 0x9f, 0xf0, 0x08, 0x7d, 0xcc, 0x64, 0xfc, 0x3c, 0x0e, 0x03,
0x89, 0x43, 0x19, 0xc8, 0x99, 0x60, 0xf8, 0x72, 0x86, 0x42, 0xd2, 0x5b, 0xb0, 0x99, 0xf0, 0x08,
0x9f, 0xc5, 0x51, 0x93, 0xec, 0x91, 0x3b, 0x57, 0xfa, 0x90, 0x1f, 0x77, 0xaa, 0x4a, 0x32, 0x78,
0xc8, 0xaa, 0x6a, 0x6b, 0x10, 0x39, 0x5f, 0x09, 0xec, 0xae, 0x70, 0x11, 0x29, 0x4f, 0x04, 0xd2,
0xfb, 0x50, 0x15, 0x3a, 0xa3, 0x5d, 0x6a, 0x9e, 0xe3, 0x9e, 0x3f, 0x90, 0x3b, 0x10, 0x62, 0x16,
0x24, 0xe1, 0x42, 0x5b, 0x2a, 0x68, 0x0f, 0x6a, 0xe1, 0xd2, 0xb8, 0x69, 0x69, 0x83, 0x8e, 0xc9,
0xe0, 0xc4, 0xfb, 0xd9, 0x49, 0x8d, 0xf3, 0x9e, 0xc0, 0x8e, 0x72, 0xc7, 0x33, 0x94, 0x8b, 0x53,
0xde, 0x83, 0x4b, 0x19, 0x9f, 0xa0, 0x86, 0xab, 0x7b, 0x6d, 0x93, 0xb7, 0x52, 0x32, 0x3e, 0xc1,
0xbe, 0xd5, 0x24, 0x4c, 0x57, 0xd3, 0x9b, 0x50, 0x09, 0x45, 0xa6, 0x81, 0xb6, 0xfb, 0x9b, 0xf9,
0x71, 0xa7, 0xe2, 0x0f, 0x19, 0x53, 0x39, 0xda, 0x80, 0xcb, 0x92, 0x8f, 0x31, 0x69, 0x56, 0x54,
0xd3, 0x58, 0x11, 0x38, 0x9f, 0x08, 0xb4, 0xcd, 0x18, 0x65, 0x9b, 0x2e, 0xd2, 0x6d, 0xfa, 0x14,
0xae, 0xea, 0xa2, 0x29, 0x4e, 0x0f, 0x31, 0x13, 0x2f, 0xe2, 0x54, 0x23, 0xd4, 0xbd, 0xdb, 0xab,
0xb8, 0x87, 0x29, 0x86, 0xee, 0xe3, 0x7f, 0xe5, 0xac, 0xae, 0xf4, 0xcb, 0xd8, 0xd9, 0x85, 0x9d,
0x47, 0x28, 0x19, 0xe7, 0xd2, 0xef, 0x9d, 0xef, 0x8e, 0xf3, 0x00, 0xda, 0xe6, 0xed, 0x92, 0x7a,
0xef, 0xf4, 0x80, 0x14, 0xf9, 0xf6, 0xa9, 0xfe, 0x7b, 0x1f, 0x09, 0x58, 0x7e, 0x8f, 0xbe, 0x23,
0xd0, 0x30, 0x39, 0xd1, 0xae, 0x89, 0x7c, 0x0d, 0x52, 0x6b, 0xff, 0xe2, 0x82, 0x02, 0xd2, 0xd9,
0xfa, 0xfe, 0xed, 0xf7, 0x17, 0xcb, 0xba, 0x46, 0xbc, 0xcf, 0x16, 0xe8, 0x96, 0x96, 0x40, 0xa6,
0x81, 0x98, 0x81, 0xd6, 0x7c, 0x41, 0x66, 0xa0, 0x75, 0xb3, 0x5e, 0x02, 0xd1, 0x0f, 0x04, 0x6e,
0x18, 0xaf, 0x0f, 0xdd, 0x5f, 0x35, 0xd1, 0x55, 0xf7, 0xb5, 0x75, 0xf0, 0x1f, 0x8a, 0xb3, 0x20,
0xfd, 0xf6, 0xd1, 0xdc, 0xde, 0xf8, 0x39, 0xb7, 0x37, 0xfe, 0xcc, 0x6d, 0xf2, 0x36, 0xb7, 0xc9,
0x51, 0x6e, 0x93, 0x1f, 0xb9, 0x4d, 0x7e, 0xe5, 0x36, 0x39, 0xac, 0xea, 0x3f, 0xc6, 0xdd, 0xbf,
0x01, 0x00, 0x00, 0xff, 0xff, 0xb3, 0xf8, 0x41, 0xef, 0x96, 0x04, 0x00, 0x00,
}

View file

@ -10805,100 +10805,101 @@ var (
)
var fileDescriptorControl = []byte{
// 1512 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x59, 0xcf, 0x6f, 0x1b, 0xc5,
0x17, 0xaf, 0x9d, 0x34, 0x8e, 0x9f, 0x6b, 0xb7, 0x9e, 0xba, 0xfa, 0x46, 0x6e, 0xbf, 0x0d, 0xda,
0xd2, 0x34, 0x91, 0x82, 0x03, 0x8e, 0x2a, 0x02, 0x48, 0x20, 0x9c, 0xd0, 0xca, 0xd0, 0x86, 0x6a,
0xd3, 0x02, 0xb7, 0xc8, 0xb1, 0x27, 0x61, 0xf1, 0x8f, 0x35, 0xbb, 0x9b, 0xb4, 0x11, 0x17, 0x38,
0x20, 0xf1, 0x27, 0x70, 0xe5, 0xca, 0x81, 0x7f, 0x81, 0x6b, 0xc4, 0x89, 0x0b, 0x12, 0xa7, 0x88,
0xf6, 0xc4, 0x09, 0xf1, 0x17, 0x20, 0xe6, 0xc7, 0x9b, 0xdd, 0xf5, 0x7a, 0x76, 0x6d, 0x27, 0x41,
0xe9, 0xc1, 0xca, 0xee, 0xcc, 0xe7, 0xcd, 0x7b, 0x33, 0x9f, 0xcf, 0xbc, 0x7d, 0x33, 0x81, 0x7c,
0xd3, 0xee, 0x79, 0x8e, 0xdd, 0xa9, 0xf4, 0x1d, 0xdb, 0xb3, 0x09, 0x69, 0xd9, 0xcd, 0x36, 0x75,
0x2a, 0xee, 0xd3, 0x86, 0xd3, 0x6d, 0x5b, 0x5e, 0xe5, 0xe0, 0x8d, 0x72, 0xce, 0xed, 0xd3, 0xa6,
0x2b, 0x01, 0xe5, 0xbc, 0xbd, 0xf3, 0x05, 0x6d, 0x7a, 0xea, 0x35, 0xe7, 0x1d, 0xf6, 0xa9, 0x7a,
0x29, 0xed, 0xd9, 0x7b, 0xb6, 0x78, 0x5c, 0xe1, 0x4f, 0xd8, 0x7a, 0xb5, 0xdf, 0xd9, 0xdf, 0xb3,
0x7a, 0x2b, 0xf2, 0x8f, 0x6c, 0x34, 0xee, 0x42, 0xe1, 0x3e, 0xf5, 0x36, 0xed, 0x16, 0x35, 0xe9,
0x97, 0xfb, 0xd4, 0xf5, 0xc8, 0x2d, 0xc8, 0xf4, 0xd8, 0xeb, 0xb6, 0xd5, 0x9a, 0x4b, 0xbd, 0x92,
0x5a, 0xcc, 0xd6, 0xe0, 0xc5, 0xf1, 0xfc, 0x0c, 0x47, 0xd4, 0x37, 0xcc, 0x19, 0xde, 0x55, 0x6f,
0x19, 0xef, 0xc1, 0x65, 0xdf, 0xcc, 0xed, 0xdb, 0x3d, 0x97, 0x92, 0x65, 0x98, 0xe6, 0x9d, 0xc2,
0x28, 0x57, 0x9d, 0xab, 0x0c, 0x4f, 0xa0, 0x22, 0xf0, 0x02, 0x65, 0x1c, 0x4f, 0xc1, 0x95, 0x07,
0x96, 0x2b, 0x86, 0x70, 0x95, 0xeb, 0x7b, 0x90, 0xd9, 0xb5, 0x3a, 0x1e, 0x75, 0x5c, 0x1c, 0x65,
0x59, 0x37, 0x4a, 0xd4, 0xac, 0x72, 0x4f, 0xda, 0x98, 0xca, 0xb8, 0xfc, 0xcd, 0x14, 0x64, 0xb0,
0x91, 0x94, 0xe0, 0x62, 0xaf, 0xd1, 0xa5, 0x7c, 0xc4, 0xa9, 0xc5, 0xac, 0x29, 0x5f, 0xc8, 0x0a,
0xe4, 0xac, 0xd6, 0x76, 0xdf, 0xa1, 0xbb, 0xd6, 0x33, 0xd6, 0x97, 0xe6, 0x7d, 0xb5, 0x02, 0x9b,
0x28, 0xd4, 0x37, 0x1e, 0x61, 0xab, 0x09, 0x56, 0x4b, 0x3d, 0x93, 0x47, 0x30, 0xd3, 0x69, 0xec,
0xd0, 0x8e, 0x3b, 0x37, 0xc5, 0xb0, 0xb9, 0xea, 0xda, 0x24, 0x91, 0x55, 0x1e, 0x08, 0xd3, 0x0f,
0x18, 0xc1, 0x87, 0x26, 0x8e, 0x43, 0xea, 0x90, 0xeb, 0xd2, 0xee, 0x0e, 0xeb, 0xfe, 0xdc, 0xea,
0xbb, 0x73, 0xd3, 0x6c, 0xd8, 0x42, 0xf5, 0x4e, 0xdc, 0xb2, 0x6d, 0x31, 0xea, 0x2b, 0x0f, 0x7d,
0xbc, 0x19, 0xb6, 0x25, 0x55, 0xb8, 0xc8, 0x94, 0xc3, 0xe6, 0x71, 0x51, 0x0c, 0x72, 0x23, 0x76,
0xed, 0x19, 0xc8, 0x94, 0x50, 0x46, 0x73, 0x9e, 0x2f, 0x45, 0xb0, 0x06, 0x33, 0x62, 0x7d, 0x2e,
0xf1, 0x46, 0x35, 0xeb, 0xf2, 0x5b, 0x90, 0x0b, 0x85, 0x4e, 0xae, 0xc0, 0x54, 0x9b, 0x1e, 0x4a,
0x59, 0x98, 0xfc, 0x91, 0xaf, 0xee, 0x41, 0xa3, 0xb3, 0x4f, 0xd9, 0x0a, 0xf2, 0x36, 0xf9, 0xf2,
0x76, 0x7a, 0x2d, 0x65, 0xac, 0x43, 0x31, 0xb4, 0x1c, 0xa8, 0x91, 0x0a, 0x23, 0x83, 0x37, 0x08,
0x32, 0x92, 0x44, 0x22, 0x61, 0xc6, 0x8f, 0x29, 0x28, 0x3e, 0xe9, 0xb7, 0x1a, 0x1e, 0x9d, 0x54,
0xa1, 0xe4, 0x5d, 0xb8, 0x24, 0x40, 0x07, 0x6c, 0x91, 0x2c, 0xbb, 0x27, 0x02, 0xcc, 0x55, 0xaf,
0xeb, 0x3c, 0x7e, 0x22, 0x21, 0x66, 0x8e, 0x1b, 0xe0, 0x0b, 0x79, 0x1d, 0xa6, 0xf9, 0x76, 0x63,
0x74, 0x73, 0xbb, 0x1b, 0x49, 0xbc, 0x98, 0x02, 0x69, 0xd4, 0x80, 0x84, 0x63, 0x3d, 0xd1, 0xb6,
0xd8, 0x84, 0xa2, 0x49, 0xbb, 0xf6, 0xc1, 0xe4, 0xf3, 0x65, 0x4c, 0xec, 0xda, 0x4e, 0x53, 0x32,
0x31, 0x6b, 0xca, 0x17, 0xa3, 0x04, 0x24, 0x3c, 0x9e, 0x8c, 0x09, 0x37, 0xfd, 0xe3, 0x86, 0xdb,
0x0e, 0xb9, 0xf0, 0xd8, 0x6b, 0xc4, 0x05, 0x47, 0x70, 0x17, 0xbc, 0xcb, 0xdf, 0xf4, 0xd2, 0x2c,
0x98, 0x1d, 0xef, 0x4c, 0x9a, 0x9d, 0xc0, 0x0b, 0x94, 0xb1, 0xa6, 0x66, 0x37, 0xb1, 0x6b, 0x7f,
0x1e, 0x61, 0xef, 0xc6, 0x3f, 0x98, 0x44, 0x78, 0xe3, 0x09, 0x92, 0x48, 0xd8, 0x6c, 0x38, 0x89,
0xfc, 0x70, 0x8e, 0x49, 0x44, 0x17, 0x99, 0x36, 0x89, 0xb0, 0x10, 0x5c, 0xea, 0x1c, 0x58, 0x4d,
0xae, 0x0e, 0x99, 0x44, 0x30, 0x84, 0x2d, 0xd9, 0x5c, 0xdf, 0x60, 0x21, 0x20, 0xa4, 0xde, 0x72,
0xc9, 0x02, 0xcc, 0xa2, 0x96, 0x64, 0xb6, 0xc8, 0xd6, 0x72, 0x0c, 0x9d, 0x91, 0x62, 0x62, 0xb3,
0x97, 0x6a, 0x72, 0xc9, 0x06, 0x14, 0xd8, 0x06, 0xb4, 0x1c, 0xda, 0xda, 0x76, 0x3d, 0xa6, 0x69,
0x99, 0x1f, 0x0a, 0xd5, 0xff, 0xc7, 0x51, 0xbc, 0xc5, 0x51, 0x66, 0x1e, 0x8d, 0xc4, 0x9b, 0x26,
0xc9, 0x64, 0xfe, 0x93, 0x24, 0x83, 0xcb, 0x15, 0x24, 0x19, 0xae, 0x9a, 0xc4, 0x24, 0x23, 0x64,
0x24, 0x61, 0xc6, 0x47, 0x50, 0x5a, 0x77, 0x28, 0x8b, 0x17, 0x97, 0x4c, 0x09, 0x69, 0x15, 0x33,
0x80, 0x54, 0xd1, 0xbc, 0x6e, 0x18, 0xb4, 0x08, 0x25, 0x81, 0x4d, 0xb8, 0x16, 0x19, 0x0c, 0xa3,
0xba, 0x0b, 0x19, 0xa4, 0x01, 0x07, 0xbc, 0x9e, 0x30, 0xa0, 0xa9, 0xb0, 0xc6, 0xfb, 0x50, 0x64,
0x7b, 0x2e, 0x12, 0xd9, 0x32, 0x40, 0xc0, 0x3a, 0xee, 0x9a, 0x3c, 0xa3, 0x31, 0xeb, 0x93, 0x6e,
0x66, 0x7d, 0xce, 0xd9, 0xfc, 0x48, 0x78, 0x88, 0xd3, 0xc5, 0xf3, 0x73, 0x0a, 0x4a, 0x32, 0xcb,
0x9d, 0x26, 0x26, 0x26, 0xaf, 0xcb, 0x0a, 0x3d, 0x41, 0x82, 0x2e, 0xa0, 0x8d, 0xca, 0xd1, 0xab,
0x03, 0x39, 0x7a, 0x7c, 0x86, 0x22, 0x13, 0x38, 0xdd, 0x8a, 0x6c, 0x40, 0x49, 0xa6, 0xa6, 0x53,
0x91, 0xf4, 0x3f, 0xb8, 0x16, 0x19, 0x05, 0x73, 0xdc, 0x9f, 0x69, 0xb8, 0xca, 0x35, 0x8e, 0xed,
0x7e, 0x9a, 0xab, 0x47, 0xd3, 0xdc, 0x4a, 0x5c, 0x32, 0x89, 0x58, 0x0e, 0x67, 0xba, 0x6f, 0xd3,
0x67, 0x9e, 0xe9, 0xb6, 0x22, 0x99, 0xee, 0x9d, 0x09, 0x83, 0xd3, 0x26, 0xbb, 0xa1, 0x6c, 0x32,
0x7d, 0xb6, 0xd9, 0xe4, 0x63, 0x28, 0x0d, 0x86, 0x84, 0xc2, 0x78, 0x13, 0x66, 0x91, 0x28, 0x95,
0x53, 0x12, 0x95, 0xe1, 0x83, 0x83, 0xcc, 0xb2, 0x49, 0xbd, 0xa7, 0xb6, 0xd3, 0x9e, 0x20, 0xb3,
0xa0, 0x85, 0x2e, 0xb3, 0xf8, 0x83, 0x05, 0xba, 0xed, 0xc9, 0xa6, 0x24, 0xdd, 0x2a, 0x2b, 0x85,
0x35, 0x9e, 0x88, 0xcc, 0x12, 0x89, 0x8c, 0xb0, 0x6a, 0x85, 0xad, 0x26, 0xae, 0x97, 0x78, 0xe6,
0x42, 0x46, 0x1b, 0x2e, 0xe4, 0x74, 0x20, 0x64, 0xb4, 0xe5, 0x42, 0x46, 0x80, 0x9f, 0x6d, 0xce,
0x28, 0xc6, 0xcf, 0xd4, 0xde, 0x3a, 0xf3, 0x30, 0xfd, 0xfd, 0x16, 0x89, 0xd4, 0xdf, 0x6f, 0xd8,
0x7e, 0x82, 0xfd, 0x16, 0xb1, 0x7c, 0xb9, 0xf6, 0x5b, 0x4c, 0x70, 0xe7, 0xb9, 0xdf, 0x82, 0x90,
0x82, 0xfd, 0x86, 0x44, 0x25, 0xee, 0x37, 0xc5, 0x9c, 0x0f, 0xc6, 0x8f, 0xe5, 0x7a, 0x67, 0xdf,
0x65, 0x73, 0x0a, 0xe5, 0xe1, 0xa6, 0x6c, 0x89, 0xe4, 0x61, 0xc4, 0x71, 0x5d, 0x20, 0xc0, 0x97,
0xaf, 0x3f, 0x44, 0x20, 0x5f, 0x84, 0x24, 0xc9, 0x57, 0x59, 0x29, 0xac, 0xaf, 0x25, 0xec, 0x38,
0x81, 0x96, 0x22, 0x96, 0x2f, 0x97, 0x96, 0x62, 0x82, 0x3b, 0x4f, 0x2d, 0x05, 0x21, 0x05, 0x5a,
0x42, 0x36, 0x12, 0xb5, 0xa4, 0xa8, 0xf3, 0xc1, 0xc6, 0x3e, 0x14, 0x3f, 0xb4, 0xad, 0xde, 0x63,
0xbb, 0x4d, 0x7b, 0xa6, 0xcd, 0xca, 0x59, 0x5e, 0x70, 0x54, 0xe0, 0xaa, 0xc3, 0x9f, 0xe9, 0x36,
0x17, 0x1c, 0x53, 0x94, 0xc7, 0xbb, 0x45, 0x84, 0xb3, 0x66, 0x51, 0x76, 0x7d, 0x2a, 0x7a, 0x84,
0x1d, 0x3b, 0x44, 0x96, 0x10, 0xdf, 0x6d, 0xf4, 0x1a, 0x7b, 0xbe, 0x81, 0x3c, 0xa3, 0x11, 0xd9,
0xf7, 0x50, 0x76, 0x09, 0x0b, 0xe3, 0xbb, 0xb4, 0xaa, 0xaf, 0x4e, 0x23, 0x63, 0x5e, 0x5f, 0x29,
0xf4, 0x24, 0xf5, 0x15, 0xda, 0x4c, 0x50, 0x5f, 0xa1, 0xf7, 0xe0, 0x3b, 0x45, 0xee, 0xc3, 0xac,
0x83, 0xeb, 0xc5, 0x48, 0xe6, 0x86, 0xb7, 0x75, 0x86, 0x43, 0x8b, 0x5b, 0x9b, 0x3e, 0x3a, 0x9e,
0xbf, 0x60, 0xfa, 0xc6, 0x41, 0xa1, 0x76, 0x36, 0xbb, 0xb1, 0xfa, 0x5b, 0x11, 0x32, 0xeb, 0xf2,
0x92, 0x8d, 0x58, 0x90, 0xc1, 0xfb, 0x2b, 0x62, 0xe8, 0x8c, 0x07, 0xef, 0xc4, 0xca, 0xb7, 0x12,
0x31, 0xf8, 0xe5, 0xb8, 0xf6, 0xcb, 0x4f, 0x7f, 0x7d, 0x9f, 0xbe, 0x0c, 0x79, 0x01, 0x7a, 0x0d,
0x19, 0x27, 0x36, 0x64, 0xfd, 0x8b, 0x10, 0xf2, 0xea, 0x38, 0xd7, 0x46, 0xe5, 0xdb, 0x23, 0x50,
0xc9, 0x0e, 0x1d, 0x80, 0xe0, 0x1e, 0x82, 0x68, 0xc7, 0x1a, 0xba, 0x53, 0x29, 0x2f, 0x8c, 0x82,
0x8d, 0xf4, 0x19, 0xdc, 0x33, 0xe8, 0x7d, 0x0e, 0xdd, 0x6b, 0xe8, 0x7d, 0x6a, 0xae, 0x2b, 0x62,
0x7c, 0x4a, 0x0e, 0xf9, 0x49, 0x2e, 0x96, 0xc3, 0xd0, 0x3d, 0x43, 0x2c, 0x87, 0x03, 0x37, 0x0a,
0xc9, 0x1c, 0x8a, 0x73, 0x66, 0x3c, 0x87, 0xe1, 0x53, 0x7b, 0x3c, 0x87, 0x03, 0x87, 0xd5, 0x91,
0xeb, 0x29, 0xa6, 0x97, 0xb0, 0x9e, 0xe1, 0x19, 0x2e, 0x8c, 0x82, 0x8d, 0xf4, 0x19, 0x9c, 0x13,
0xf5, 0x3e, 0x87, 0x8e, 0xa2, 0x7a, 0x9f, 0xc3, 0xc7, 0xcd, 0x38, 0x9f, 0xcf, 0xe0, 0x52, 0xb8,
0xe4, 0x26, 0x77, 0xc6, 0x3c, 0x27, 0x94, 0x17, 0x47, 0x03, 0x93, 0x3d, 0x7f, 0x05, 0xf9, 0x81,
0x83, 0x3a, 0xd1, 0x8e, 0xa8, 0xbb, 0x18, 0x28, 0x2f, 0x8d, 0x81, 0x1c, 0xe9, 0x7c, 0xe0, 0x0c,
0xaa, 0x77, 0xae, 0x3b, 0x67, 0xeb, 0x9d, 0x6b, 0x0f, 0xb4, 0x09, 0xce, 0x07, 0x8e, 0x9a, 0x7a,
0xe7, 0xba, 0x33, 0xad, 0xde, 0xb9, 0xfe, 0xdc, 0x9a, 0x28, 0x32, 0x2c, 0xdd, 0x62, 0x45, 0x36,
0x58, 0xee, 0xc7, 0x8a, 0x2c, 0x5a, 0xbb, 0x27, 0x8b, 0x4c, 0xd5, 0x99, 0xf1, 0x22, 0x8b, 0x14,
0xc7, 0xf1, 0x22, 0x8b, 0x96, 0xac, 0x23, 0x45, 0xa6, 0x26, 0x9c, 0x20, 0xb2, 0xc8, 0x9c, 0x97,
0xc6, 0x40, 0x8e, 0xc9, 0x73, 0xa2, 0x73, 0xdd, 0xf9, 0x2a, 0x89, 0xe7, 0x31, 0x9d, 0x4b, 0x9e,
0xf1, 0x1b, 0x1c, 0xcb, 0xf3, 0x60, 0x8d, 0x13, 0xcb, 0x73, 0xa4, 0x00, 0x18, 0xc1, 0xb3, 0xaa,
0x01, 0xe3, 0x79, 0x8e, 0x14, 0xae, 0xf1, 0x3c, 0x47, 0xcb, 0xc9, 0x91, 0xfb, 0x59, 0x4d, 0x38,
0x61, 0x3f, 0x47, 0xe6, 0xbc, 0x34, 0x06, 0x32, 0xd1, 0x79, 0xed, 0xc6, 0xd1, 0xf3, 0x9b, 0x17,
0x7e, 0x67, 0xbf, 0xbf, 0x9f, 0xdf, 0x4c, 0x7d, 0xfd, 0xe2, 0x66, 0xea, 0x88, 0xfd, 0x7e, 0x65,
0xbf, 0x3f, 0xd8, 0x6f, 0x67, 0x46, 0xfc, 0x9f, 0x6f, 0xf5, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff,
0xbb, 0x97, 0x43, 0x36, 0x60, 0x1c, 0x00, 0x00,
// 1521 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x59, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0xaf, 0xff, 0x24, 0x4e, 0x9e, 0xeb, 0xb4, 0x9e, 0xba, 0xc2, 0x72, 0x8b, 0x53, 0x6d, 0x69,
0x9b, 0x4a, 0xc5, 0x29, 0xae, 0x2a, 0x0a, 0x48, 0x20, 0x12, 0xd3, 0xca, 0xb4, 0x0d, 0xd5, 0xa6,
0x05, 0x6e, 0xd1, 0xc6, 0x9e, 0x86, 0xc5, 0x7f, 0xd6, 0xec, 0x6c, 0xd2, 0x56, 0x5c, 0xe0, 0x80,
0xc4, 0x47, 0xe0, 0xca, 0x95, 0x03, 0x5f, 0x81, 0x6b, 0xc5, 0x89, 0x0b, 0x12, 0x27, 0x8b, 0xfa,
0xc4, 0x09, 0xf1, 0x09, 0x10, 0x9a, 0x99, 0x37, 0xbb, 0xeb, 0xf5, 0xec, 0xda, 0x4e, 0x82, 0xda,
0x53, 0x76, 0x66, 0x7e, 0x6f, 0xde, 0x9b, 0x79, 0xbf, 0xf9, 0xf9, 0xcd, 0x04, 0x0a, 0x2d, 0xa7,
0xef, 0xb9, 0x4e, 0xb7, 0x36, 0x70, 0x1d, 0xcf, 0x21, 0xa4, 0xed, 0xb4, 0x3a, 0xd4, 0xad, 0xb1,
0x27, 0x96, 0xdb, 0xeb, 0xd8, 0x5e, 0xed, 0xe0, 0xad, 0x4a, 0x9e, 0x0d, 0x68, 0x8b, 0x49, 0x40,
0xa5, 0xe0, 0xec, 0x7e, 0x49, 0x5b, 0x9e, 0x6a, 0xe6, 0xbd, 0x67, 0x03, 0xaa, 0x1a, 0xa5, 0x3d,
0x67, 0xcf, 0x11, 0x9f, 0xeb, 0xfc, 0x0b, 0x7b, 0xcf, 0x0c, 0xba, 0xfb, 0x7b, 0x76, 0x7f, 0x5d,
0xfe, 0x91, 0x9d, 0xc6, 0x4d, 0x58, 0xb9, 0x43, 0xbd, 0x2d, 0xa7, 0x4d, 0x4d, 0xfa, 0xd5, 0x3e,
0x65, 0x1e, 0xb9, 0x08, 0xb9, 0xbe, 0xd3, 0xa6, 0x3b, 0x76, 0xbb, 0x9c, 0xba, 0x90, 0x5a, 0x5b,
0xde, 0x80, 0xd1, 0x70, 0x75, 0x91, 0x23, 0x9a, 0x0d, 0x73, 0x91, 0x0f, 0x35, 0xdb, 0xc6, 0x07,
0x70, 0xca, 0x37, 0x63, 0x03, 0xa7, 0xcf, 0x28, 0xb9, 0x06, 0x59, 0x3e, 0x28, 0x8c, 0xf2, 0xf5,
0x72, 0x6d, 0x72, 0x01, 0x35, 0x81, 0x17, 0x28, 0x63, 0x98, 0x81, 0xd3, 0xf7, 0x6c, 0x26, 0xa6,
0x60, 0xca, 0xf5, 0x6d, 0xc8, 0x3d, 0xb6, 0xbb, 0x1e, 0x75, 0x19, 0xce, 0x72, 0x4d, 0x37, 0x4b,
0xd4, 0xac, 0x76, 0x5b, 0xda, 0x98, 0xca, 0xb8, 0xf2, 0x6d, 0x06, 0x72, 0xd8, 0x49, 0x4a, 0xb0,
0xd0, 0xb7, 0x7a, 0x94, 0xcf, 0x98, 0x59, 0x5b, 0x36, 0x65, 0x83, 0xac, 0x43, 0xde, 0x6e, 0xef,
0x0c, 0x5c, 0xfa, 0xd8, 0x7e, 0x4a, 0x59, 0x39, 0xcd, 0xc7, 0x36, 0x56, 0x46, 0xc3, 0x55, 0x68,
0x36, 0x1e, 0x60, 0xaf, 0x09, 0x76, 0x5b, 0x7d, 0x93, 0x07, 0xb0, 0xd8, 0xb5, 0x76, 0x69, 0x97,
0x95, 0x33, 0x17, 0x32, 0x6b, 0xf9, 0xfa, 0xad, 0x79, 0x22, 0xab, 0xdd, 0x13, 0xa6, 0x1f, 0xf5,
0x3d, 0xf7, 0x99, 0x89, 0xf3, 0x90, 0x26, 0xe4, 0x7b, 0xb4, 0xb7, 0x4b, 0x5d, 0xf6, 0x85, 0x3d,
0x60, 0xe5, 0xec, 0x85, 0xcc, 0xda, 0x4a, 0xfd, 0x4a, 0xdc, 0xb6, 0x6d, 0x0f, 0x68, 0xab, 0x76,
0xdf, 0xc7, 0x9b, 0x61, 0x5b, 0x52, 0x87, 0x05, 0xd7, 0xe9, 0x52, 0x56, 0x5e, 0x10, 0x93, 0x9c,
0x8f, 0xdd, 0x7b, 0xa7, 0x4b, 0x4d, 0x09, 0x25, 0x17, 0xa1, 0xc0, 0xb7, 0x22, 0xd8, 0x83, 0x45,
0xb1, 0x3f, 0x27, 0x79, 0xa7, 0x5a, 0x75, 0xe5, 0x1d, 0xc8, 0x87, 0x42, 0x27, 0xa7, 0x21, 0xd3,
0xa1, 0xcf, 0x24, 0x2d, 0x4c, 0xfe, 0xc9, 0x77, 0xf7, 0xc0, 0xea, 0xee, 0xd3, 0x72, 0x5a, 0xf4,
0xc9, 0xc6, 0xbb, 0xe9, 0x5b, 0x29, 0x63, 0x13, 0x8a, 0xa1, 0xed, 0x40, 0x8e, 0xd4, 0x60, 0x81,
0x67, 0x5f, 0x26, 0x23, 0x89, 0x24, 0x12, 0x66, 0xfc, 0x94, 0x82, 0xe2, 0xa3, 0x41, 0xdb, 0xf2,
0xe8, 0xbc, 0x0c, 0x25, 0xef, 0xc3, 0x49, 0x01, 0x3a, 0xa0, 0x2e, 0xb3, 0x9d, 0xbe, 0x08, 0x30,
0x5f, 0x3f, 0xa7, 0xf3, 0xf8, 0xa9, 0x84, 0x98, 0x79, 0x6e, 0x80, 0x0d, 0x72, 0x1d, 0xb2, 0xfc,
0xb8, 0x95, 0x33, 0xc2, 0xee, 0x7c, 0x52, 0x5e, 0x4c, 0x81, 0x34, 0x36, 0x80, 0x84, 0x63, 0x3d,
0xd4, 0xb1, 0xd8, 0x82, 0xa2, 0x49, 0x7b, 0xce, 0xc1, 0xfc, 0xeb, 0x2d, 0xc1, 0xc2, 0x63, 0xc7,
0x6d, 0xc9, 0x4c, 0x2c, 0x99, 0xb2, 0x61, 0x94, 0x80, 0x84, 0xe7, 0x93, 0x31, 0xe1, 0xa1, 0x7f,
0x68, 0xb1, 0x4e, 0xc8, 0x85, 0x67, 0xb1, 0x4e, 0xc4, 0x05, 0x47, 0x70, 0x17, 0x7c, 0xc8, 0x3f,
0xf4, 0xd2, 0x2c, 0x58, 0x1d, 0x1f, 0x4c, 0x5a, 0x9d, 0xc0, 0x0b, 0x94, 0x71, 0x4b, 0xad, 0x6e,
0x6e, 0xd7, 0xfe, 0x3a, 0xc2, 0xde, 0x8d, 0x7f, 0x51, 0x44, 0x78, 0xe7, 0x21, 0x44, 0x24, 0x6c,
0x36, 0x29, 0x22, 0x3f, 0xbe, 0x44, 0x11, 0xd1, 0x45, 0xa6, 0x15, 0x91, 0x75, 0xc8, 0x33, 0xea,
0x1e, 0xd8, 0x2d, 0xce, 0x0e, 0x29, 0x22, 0x18, 0xc2, 0xb6, 0xec, 0x6e, 0x36, 0x98, 0x09, 0x08,
0x69, 0xb6, 0x19, 0xb9, 0x0c, 0x4b, 0xc8, 0x25, 0xa9, 0x16, 0xcb, 0x1b, 0xf9, 0xd1, 0x70, 0x35,
0x27, 0xc9, 0xc4, 0xcc, 0x9c, 0x64, 0x13, 0x23, 0x0d, 0x58, 0x69, 0x53, 0x66, 0xbb, 0xb4, 0xbd,
0xc3, 0x3c, 0xcb, 0x43, 0x7d, 0x58, 0xa9, 0xbf, 0x1e, 0x97, 0xe2, 0x6d, 0x8e, 0x32, 0x0b, 0x68,
0x24, 0x5a, 0x1a, 0x91, 0xc9, 0xfd, 0x2f, 0x22, 0x83, 0xdb, 0x15, 0x88, 0x0c, 0x67, 0x4d, 0xa2,
0xc8, 0x08, 0x1a, 0x49, 0x98, 0x71, 0x17, 0x4a, 0x9b, 0x2e, 0xb5, 0x3c, 0x8a, 0x5b, 0xa6, 0x88,
0x74, 0x03, 0x15, 0x40, 0xb2, 0x68, 0x55, 0x37, 0x0d, 0x5a, 0x84, 0x44, 0x60, 0x0b, 0xce, 0x46,
0x26, 0xc3, 0xa8, 0x6e, 0x42, 0x0e, 0xd3, 0x80, 0x13, 0x9e, 0x4b, 0x98, 0xd0, 0x54, 0x58, 0xe3,
0x43, 0x28, 0xde, 0xa1, 0x5e, 0x24, 0xb2, 0x6b, 0x00, 0x41, 0xd6, 0xf1, 0xd4, 0x14, 0x46, 0xc3,
0xd5, 0x65, 0x3f, 0xe9, 0xe6, 0xb2, 0x9f, 0x73, 0xe3, 0x2e, 0x90, 0xf0, 0x14, 0x47, 0x8b, 0xe7,
0x97, 0x14, 0x94, 0xa4, 0xca, 0x1d, 0x25, 0x26, 0xd2, 0x80, 0x53, 0x0a, 0x3d, 0x87, 0x40, 0xaf,
0xa0, 0x8d, 0xd2, 0xe8, 0x1b, 0x63, 0x1a, 0x3d, 0x7b, 0x86, 0x22, 0x0b, 0x38, 0xda, 0x8e, 0x34,
0xa0, 0x24, 0xa5, 0xe9, 0x48, 0x49, 0x7a, 0x0d, 0xce, 0x46, 0x66, 0x41, 0x8d, 0xfb, 0x2b, 0x0d,
0x67, 0x38, 0xc7, 0xb1, 0xdf, 0x97, 0xb9, 0x66, 0x54, 0xe6, 0xd6, 0xe3, 0xc4, 0x24, 0x62, 0x39,
0xa9, 0x74, 0xdf, 0xa5, 0x8f, 0x5d, 0xe9, 0xb6, 0x23, 0x4a, 0xf7, 0xde, 0x9c, 0xc1, 0x69, 0xc5,
0x6e, 0x42, 0x4d, 0xb2, 0xc7, 0xab, 0x26, 0x9f, 0x40, 0x69, 0x3c, 0x24, 0x24, 0xc6, 0xdb, 0xb0,
0x84, 0x89, 0x52, 0x9a, 0x92, 0xc8, 0x0c, 0x1f, 0x1c, 0x28, 0xcb, 0x16, 0xf5, 0x9e, 0x38, 0x6e,
0x67, 0x0e, 0x65, 0x41, 0x0b, 0x9d, 0xb2, 0xf8, 0x93, 0x05, 0xbc, 0xed, 0xcb, 0xae, 0x24, 0xde,
0x2a, 0x2b, 0x85, 0x35, 0x1e, 0x09, 0x65, 0x89, 0x44, 0x46, 0x20, 0xcb, 0x77, 0x13, 0xf7, 0x4b,
0x7c, 0x73, 0x22, 0xa3, 0x0d, 0x27, 0x72, 0x3a, 0x20, 0x32, 0xda, 0x72, 0x22, 0x23, 0xc0, 0x57,
0x9b, 0x63, 0x8a, 0xf1, 0x73, 0x75, 0xb6, 0x8e, 0x3d, 0x4c, 0xff, 0xbc, 0x45, 0x22, 0xf5, 0xcf,
0x1b, 0xf6, 0x1f, 0xe2, 0xbc, 0x45, 0x2c, 0x5f, 0xad, 0xf3, 0x16, 0x13, 0xdc, 0xcb, 0x3c, 0x6f,
0x41, 0x48, 0xc1, 0x79, 0xc3, 0x44, 0x25, 0x9e, 0x37, 0x95, 0x39, 0x1f, 0x8c, 0x3f, 0x96, 0x9b,
0xdd, 0x7d, 0xe6, 0x51, 0x37, 0xa4, 0xc3, 0x2d, 0xd9, 0x13, 0xd1, 0x61, 0xc4, 0x71, 0x5e, 0x20,
0xc0, 0xa7, 0xaf, 0x3f, 0x45, 0x40, 0x5f, 0x84, 0x24, 0xd1, 0x57, 0x59, 0x29, 0xac, 0xcf, 0x25,
0x1c, 0x38, 0x04, 0x97, 0x22, 0x96, 0xaf, 0x16, 0x97, 0x62, 0x82, 0x7b, 0x99, 0x5c, 0x0a, 0x42,
0x0a, 0xb8, 0x84, 0xd9, 0x48, 0xe4, 0x92, 0x4a, 0x9d, 0x0f, 0x36, 0xf6, 0xa1, 0xf8, 0xb1, 0x63,
0xf7, 0x1f, 0x3a, 0x1d, 0xda, 0x37, 0x1d, 0xcf, 0xf2, 0x78, 0xc1, 0x51, 0x83, 0x33, 0x2e, 0xff,
0xa6, 0x3b, 0x9c, 0x70, 0xd4, 0xdd, 0xf1, 0xf8, 0xb0, 0x88, 0x70, 0xc9, 0x2c, 0xca, 0xa1, 0xcf,
0xc4, 0x88, 0xb0, 0x23, 0xd7, 0xa1, 0x84, 0xf8, 0x9e, 0xd5, 0xb7, 0xf6, 0x7c, 0x03, 0x79, 0x47,
0x23, 0x72, 0xec, 0xbe, 0x1c, 0x12, 0x16, 0xc6, 0xf7, 0x69, 0x55, 0x5f, 0x1d, 0x85, 0xc6, 0xbc,
0xbe, 0x52, 0xe8, 0x79, 0xea, 0x2b, 0xb4, 0x99, 0xa3, 0xbe, 0x42, 0xef, 0xc1, 0xef, 0x14, 0xb9,
0x03, 0x4b, 0x2e, 0xee, 0x57, 0x39, 0x2b, 0x0c, 0x2f, 0xe9, 0x0c, 0x27, 0x36, 0x77, 0x23, 0xfb,
0x7c, 0xb8, 0x7a, 0xc2, 0xf4, 0x8d, 0x83, 0x42, 0xed, 0x78, 0x4e, 0x63, 0xfd, 0xf7, 0x22, 0xe4,
0x36, 0xe5, 0x23, 0x1b, 0xb1, 0x21, 0x87, 0xef, 0x57, 0xc4, 0xd0, 0x19, 0x8f, 0xbf, 0x89, 0x55,
0x2e, 0x26, 0x62, 0xf0, 0x97, 0xe3, 0xec, 0xaf, 0x3f, 0xff, 0xfd, 0x43, 0xfa, 0x14, 0x14, 0x04,
0xe8, 0x4d, 0xcc, 0x38, 0x71, 0x60, 0xd9, 0x7f, 0x08, 0x21, 0x6f, 0xcc, 0xf2, 0x6c, 0x54, 0xb9,
0x34, 0x05, 0x95, 0xec, 0xd0, 0x05, 0x08, 0xde, 0x21, 0x88, 0x76, 0xae, 0x89, 0x37, 0x95, 0xca,
0xe5, 0x69, 0xb0, 0xa9, 0x3e, 0x83, 0x77, 0x06, 0xbd, 0xcf, 0x89, 0x77, 0x0d, 0xbd, 0x4f, 0xcd,
0x73, 0x45, 0x8c, 0x4f, 0x99, 0x43, 0x7e, 0x93, 0x8b, 0xcd, 0x61, 0xe8, 0x9d, 0x21, 0x36, 0x87,
0x63, 0x2f, 0x0a, 0xc9, 0x39, 0x14, 0xf7, 0xcc, 0xf8, 0x1c, 0x86, 0x6f, 0xed, 0xf1, 0x39, 0x1c,
0xbb, 0xac, 0x4e, 0xdd, 0x4f, 0xb1, 0xbc, 0x84, 0xfd, 0x0c, 0xaf, 0xf0, 0xf2, 0x34, 0xd8, 0x54,
0x9f, 0xc1, 0x3d, 0x51, 0xef, 0x73, 0xe2, 0x2a, 0xaa, 0xf7, 0x39, 0x79, 0xdd, 0x8c, 0xf3, 0xf9,
0x14, 0x4e, 0x86, 0x4b, 0x6e, 0x72, 0x65, 0xc6, 0x7b, 0x42, 0x65, 0x6d, 0x3a, 0x30, 0xd9, 0xf3,
0xd7, 0x50, 0x18, 0xbb, 0xa8, 0x13, 0xed, 0x8c, 0xba, 0x87, 0x81, 0xca, 0xd5, 0x19, 0x90, 0x53,
0x9d, 0x8f, 0xdd, 0x41, 0xf5, 0xce, 0x75, 0xf7, 0x6c, 0xbd, 0x73, 0xed, 0x85, 0x36, 0xc1, 0xf9,
0xd8, 0x55, 0x53, 0xef, 0x5c, 0x77, 0xa7, 0xd5, 0x3b, 0xd7, 0xdf, 0x5b, 0x13, 0x49, 0x86, 0xa5,
0x5b, 0x2c, 0xc9, 0xc6, 0xcb, 0xfd, 0x58, 0x92, 0x45, 0x6b, 0xf7, 0x64, 0x92, 0xa9, 0x3a, 0x33,
0x9e, 0x64, 0x91, 0xe2, 0x38, 0x9e, 0x64, 0xd1, 0x92, 0x75, 0x2a, 0xc9, 0xd4, 0x82, 0x13, 0x48,
0x16, 0x59, 0xf3, 0xd5, 0x19, 0x90, 0x33, 0xe6, 0x39, 0xd1, 0xb9, 0xee, 0x7e, 0x95, 0x94, 0xe7,
0x19, 0x9d, 0xcb, 0x3c, 0xe3, 0x6f, 0x70, 0x6c, 0x9e, 0xc7, 0x6b, 0x9c, 0xd8, 0x3c, 0x47, 0x0a,
0x80, 0x29, 0x79, 0x56, 0x35, 0x60, 0x7c, 0x9e, 0x23, 0x85, 0x6b, 0x7c, 0x9e, 0xa3, 0xe5, 0xe4,
0xd4, 0xf3, 0xac, 0x16, 0x9c, 0x70, 0x9e, 0x23, 0x6b, 0xbe, 0x3a, 0x03, 0x32, 0xd1, 0xf9, 0xc6,
0xf9, 0xe7, 0x2f, 0xaa, 0x27, 0xfe, 0x78, 0x51, 0x3d, 0xf1, 0xcf, 0x8b, 0x6a, 0xea, 0x9b, 0x51,
0x35, 0xf5, 0x7c, 0x54, 0x4d, 0xfd, 0x36, 0xaa, 0xa6, 0xfe, 0x1c, 0x55, 0x53, 0xbb, 0x8b, 0xe2,
0xff, 0x7c, 0x37, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xbb, 0x97, 0x43, 0x36, 0x60, 0x1c, 0x00,
0x00,
}

View file

@ -37,6 +37,11 @@ var _ = math.Inf
// SessionRequest starts a session.
type SessionRequest struct {
Description *NodeDescription `protobuf:"bytes,1,opt,name=description" json:"description,omitempty"`
// SessionID can be provided to attempt resuming an exising session. If the
// SessionID is empty or invalid, a new SessionID will be assigned.
//
// See SessionMessage.SessionID for details.
SessionID string `protobuf:"bytes,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
}
func (m *SessionRequest) Reset() { *m = SessionRequest{} }
@ -238,6 +243,7 @@ func (m *SessionRequest) Copy() *SessionRequest {
o := &SessionRequest{
Description: m.Description.Copy(),
SessionID: m.SessionID,
}
return o
@ -369,11 +375,12 @@ func (this *SessionRequest) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 5)
s := make([]string, 0, 6)
s = append(s, "&api.SessionRequest{")
if this.Description != nil {
s = append(s, "Description: "+fmt.Sprintf("%#v", this.Description)+",\n")
}
s = append(s, "SessionID: "+fmt.Sprintf("%#v", this.SessionID)+",\n")
s = append(s, "}")
return strings.Join(s, "")
}
@ -789,6 +796,12 @@ func (m *SessionRequest) MarshalTo(data []byte) (int, error) {
}
i += n1
}
if len(m.SessionID) > 0 {
data[i] = 0x12
i++
i = encodeVarintDispatcher(data, i, uint64(len(m.SessionID)))
i += copy(data[i:], m.SessionID)
}
return i, nil
}
@ -1274,6 +1287,10 @@ func (m *SessionRequest) Size() (n int) {
l = m.Description.Size()
n += 1 + l + sovDispatcher(uint64(l))
}
l = len(m.SessionID)
if l > 0 {
n += 1 + l + sovDispatcher(uint64(l))
}
return n
}
@ -1398,6 +1415,7 @@ func (this *SessionRequest) String() string {
}
s := strings.Join([]string{`&SessionRequest{`,
`Description:` + strings.Replace(fmt.Sprintf("%v", this.Description), "NodeDescription", "NodeDescription", 1) + `,`,
`SessionID:` + fmt.Sprintf("%v", this.SessionID) + `,`,
`}`,
}, "")
return s
@ -1556,6 +1574,35 @@ func (m *SessionRequest) Unmarshal(data []byte) error {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field SessionID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowDispatcher
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthDispatcher
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.SessionID = string(data[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipDispatcher(data[iNdEx:])
@ -2448,45 +2495,46 @@ var (
)
var fileDescriptorDispatcher = []byte{
// 626 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x54, 0xdf, 0x6e, 0x12, 0x4f,
0x14, 0xee, 0x02, 0x85, 0x1f, 0x87, 0xf2, 0x0b, 0x8e, 0x8d, 0xdd, 0x6c, 0x2a, 0xc5, 0x45, 0x13,
0x13, 0xeb, 0xa2, 0x35, 0xf1, 0xc2, 0x10, 0x63, 0x08, 0x4d, 0x6c, 0x8c, 0x7f, 0xb2, 0x55, 0xb9,
0x24, 0x0b, 0x3b, 0xa1, 0x2b, 0x76, 0x67, 0x9d, 0x19, 0xac, 0x5c, 0x98, 0x98, 0x78, 0x6f, 0x8c,
0x57, 0x3e, 0x85, 0xcf, 0x41, 0xbc, 0xf2, 0xd2, 0xab, 0xc6, 0xf6, 0x01, 0x8c, 0x8f, 0xe0, 0xec,
0xec, 0x2c, 0x20, 0x5d, 0xb4, 0xf4, 0x62, 0xc2, 0xcc, 0x99, 0xef, 0xfb, 0xce, 0xc7, 0x39, 0x67,
0x16, 0x4a, 0xae, 0xc7, 0x02, 0x87, 0x77, 0xf7, 0x30, 0xb5, 0x02, 0x4a, 0x38, 0x41, 0xc8, 0x25,
0xdd, 0xbe, 0x38, 0xb1, 0x03, 0x87, 0xee, 0xf7, 0x3d, 0x6e, 0xbd, 0xbe, 0x69, 0x14, 0xf8, 0x30,
0xc0, 0x2c, 0x02, 0x18, 0x45, 0xd2, 0x79, 0x81, 0xbb, 0x3c, 0x3e, 0xae, 0xf6, 0x48, 0x8f, 0xc8,
0x6d, 0x2d, 0xdc, 0xa9, 0xe8, 0xf9, 0xe0, 0xe5, 0xa0, 0xe7, 0xf9, 0xb5, 0xe8, 0x47, 0x05, 0xd7,
0xdc, 0x01, 0x75, 0xb8, 0x47, 0xfc, 0x5a, 0xbc, 0x89, 0x2e, 0xcc, 0x16, 0xfc, 0xbf, 0x8b, 0x19,
0x13, 0x01, 0x1b, 0xbf, 0x1a, 0x60, 0xc6, 0xd1, 0x36, 0x14, 0x5c, 0xcc, 0xba, 0xd4, 0x0b, 0x42,
0x98, 0xae, 0x55, 0xb4, 0xab, 0x85, 0xad, 0xaa, 0x75, 0xd2, 0x9b, 0xf5, 0x88, 0xb8, 0xb8, 0x39,
0x81, 0xda, 0xd3, 0x3c, 0xf3, 0x7d, 0x6a, 0xac, 0xfc, 0x50, 0xfc, 0x38, 0x3d, 0x8c, 0x36, 0x01,
0x58, 0x14, 0x69, 0x7b, 0xae, 0x14, 0xce, 0x37, 0x8a, 0xc7, 0x87, 0x1b, 0x79, 0x85, 0xdb, 0x69,
0xda, 0x79, 0x05, 0xd8, 0x71, 0x05, 0x3a, 0xe3, 0x8b, 0x04, 0x7a, 0x4a, 0x1a, 0xd0, 0xe7, 0x19,
0xb0, 0x25, 0x0a, 0xd5, 0xe1, 0xbf, 0x7d, 0xc7, 0x17, 0x59, 0x28, 0xd3, 0xd3, 0x95, 0xb4, 0x60,
0x54, 0x92, 0x18, 0x2d, 0xec, 0xf5, 0xf6, 0x38, 0x76, 0x9f, 0x60, 0x4c, 0xed, 0x31, 0x03, 0xb5,
0xe0, 0x82, 0x8f, 0xf9, 0x01, 0xa1, 0xfd, 0x76, 0x87, 0x10, 0xce, 0x38, 0x75, 0x82, 0x76, 0x1f,
0x0f, 0x99, 0x9e, 0x91, 0x5a, 0x97, 0x92, 0xb4, 0xb6, 0xfd, 0x2e, 0x1d, 0xca, 0x3f, 0xfb, 0x00,
0x0f, 0xed, 0x55, 0x25, 0xd0, 0x88, 0xf9, 0x22, 0xc8, 0xcc, 0x7b, 0x50, 0xba, 0x8f, 0x1d, 0xca,
0x3b, 0xd8, 0xe1, 0x71, 0x81, 0x17, 0x2a, 0x83, 0xf9, 0x18, 0xce, 0x4d, 0x29, 0xb0, 0x80, 0xf8,
0x0c, 0xa3, 0x3b, 0x90, 0x0d, 0x30, 0xf5, 0x88, 0xab, 0xda, 0xb3, 0x9e, 0xe4, 0xaf, 0xa9, 0x3a,
0xdd, 0xc8, 0x8c, 0x0e, 0x37, 0x96, 0x6c, 0xc5, 0x30, 0x3f, 0xa6, 0x60, 0xed, 0x59, 0xe0, 0x3a,
0x1c, 0x3f, 0x75, 0x58, 0x7f, 0x97, 0x3b, 0x7c, 0xc0, 0xce, 0x64, 0x0d, 0x3d, 0x87, 0xdc, 0x40,
0x0a, 0xc5, 0x25, 0xaf, 0x27, 0xd9, 0x98, 0x93, 0xcb, 0x9a, 0x44, 0x22, 0x84, 0x1d, 0x8b, 0x19,
0x04, 0x4a, 0xb3, 0x97, 0xa8, 0x0a, 0x39, 0x2e, 0x62, 0x13, 0x5b, 0x20, 0x6c, 0x65, 0x43, 0x98,
0xf0, 0x94, 0x0d, 0xaf, 0x84, 0xa1, 0xdb, 0x90, 0x65, 0x92, 0xa4, 0x86, 0xa6, 0x9c, 0xe4, 0x67,
0xca, 0x89, 0x42, 0x9b, 0x06, 0xe8, 0x27, 0x5d, 0x46, 0xa5, 0x36, 0xeb, 0xb0, 0x12, 0x46, 0xcf,
0x56, 0x22, 0xf3, 0xae, 0x62, 0xc7, 0x4f, 0xc0, 0x82, 0xe5, 0xd0, 0x2b, 0x13, 0xc4, 0xf4, 0xbc,
0xa9, 0x0e, 0x09, 0x76, 0x04, 0xdb, 0xfa, 0x90, 0x01, 0x68, 0x8e, 0xbf, 0x13, 0xe8, 0x0d, 0xe4,
0x54, 0x1a, 0x64, 0x26, 0x51, 0xff, 0x7c, 0xca, 0xc6, 0xdf, 0x30, 0xca, 0x91, 0x59, 0xfd, 0xfa,
0xe5, 0xe7, 0xe7, 0xd4, 0x45, 0x58, 0x91, 0x98, 0xeb, 0xe1, 0x08, 0x63, 0x0a, 0xc5, 0xe8, 0xa4,
0x1e, 0xc8, 0x0d, 0x0d, 0xbd, 0x85, 0xfc, 0x78, 0x0c, 0xd1, 0xe5, 0x24, 0xdd, 0xd9, 0x39, 0x37,
0xae, 0xfc, 0x03, 0xa5, 0x0a, 0x7c, 0x1a, 0x03, 0xe8, 0x93, 0x06, 0xa5, 0xd9, 0x16, 0xa1, 0x6b,
0x0b, 0x8c, 0x9b, 0xb1, 0x79, 0x3a, 0xf0, 0x22, 0xa6, 0x28, 0x2c, 0xcb, 0xe6, 0xa2, 0xca, 0xbc,
0x36, 0x8e, 0xb3, 0xcf, 0x47, 0x2c, 0xd6, 0x87, 0xc6, 0xfa, 0xe8, 0xa8, 0xbc, 0xf4, 0x5d, 0xac,
0x5f, 0x47, 0x65, 0xed, 0xdd, 0x71, 0x59, 0x1b, 0x89, 0xf5, 0x4d, 0xac, 0x1f, 0x62, 0x75, 0xb2,
0xf2, 0xa3, 0x7e, 0xeb, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x41, 0x8f, 0x02, 0x5c, 0x06,
0x00, 0x00,
// 645 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x95, 0xdf, 0x6a, 0x13, 0x4f,
0x14, 0xc7, 0x3b, 0x69, 0x9a, 0xfe, 0x72, 0xd2, 0xfe, 0x88, 0x63, 0xb1, 0xcb, 0x52, 0xb7, 0x71,
0xab, 0x50, 0xb0, 0x6e, 0x35, 0x82, 0x17, 0x52, 0x44, 0x42, 0x0a, 0x86, 0xe2, 0x1f, 0xb6, 0x6a,
0x2f, 0xcb, 0x24, 0x7b, 0x48, 0xd7, 0xd8, 0x9d, 0x75, 0x66, 0x62, 0xcd, 0x85, 0x20, 0x88, 0xb7,
0x22, 0x5e, 0xf9, 0x14, 0x3e, 0x47, 0xf1, 0xca, 0x4b, 0xaf, 0x8a, 0xcd, 0x03, 0x88, 0x8f, 0x20,
0xbb, 0x3b, 0x9b, 0xd6, 0x74, 0x53, 0x9b, 0x5e, 0x65, 0xfe, 0x7c, 0xcf, 0xf7, 0x7c, 0x38, 0xe7,
0x4c, 0x16, 0xca, 0x9e, 0x2f, 0x43, 0xa6, 0x5a, 0x3b, 0x28, 0x9c, 0x50, 0x70, 0xc5, 0x29, 0xf5,
0x78, 0xab, 0x83, 0xc2, 0x91, 0x7b, 0x4c, 0xec, 0x76, 0x7c, 0xe5, 0xbc, 0xbe, 0x65, 0x96, 0x54,
0x2f, 0x44, 0x99, 0x08, 0xcc, 0x59, 0xde, 0x7c, 0x81, 0x2d, 0x95, 0x6e, 0xe7, 0xda, 0xbc, 0xcd,
0xe3, 0xe5, 0x6a, 0xb4, 0xd2, 0xa7, 0x17, 0xc3, 0x97, 0xdd, 0xb6, 0x1f, 0xac, 0x26, 0x3f, 0xfa,
0x70, 0xde, 0xeb, 0x0a, 0xa6, 0x7c, 0x1e, 0xac, 0xa6, 0x8b, 0xe4, 0xc2, 0xfe, 0x40, 0xe0, 0xff,
0x4d, 0x94, 0xd2, 0xe7, 0x81, 0x8b, 0xaf, 0xba, 0x28, 0x15, 0x5d, 0x87, 0x92, 0x87, 0xb2, 0x25,
0xfc, 0x30, 0xd2, 0x19, 0xa4, 0x42, 0x96, 0x4b, 0xd5, 0x25, 0xe7, 0x24, 0x9c, 0xf3, 0x88, 0x7b,
0x58, 0x3f, 0x92, 0xba, 0xc7, 0xe3, 0xe8, 0x0a, 0x80, 0x4c, 0x8c, 0xb7, 0x7d, 0xcf, 0xc8, 0x55,
0xc8, 0x72, 0xb1, 0x36, 0xdb, 0x3f, 0x58, 0x2c, 0xea, 0x74, 0x8d, 0xba, 0x5b, 0xd4, 0x82, 0x86,
0x67, 0xbf, 0xcf, 0x0d, 0x38, 0x1e, 0xa2, 0x94, 0xac, 0x8d, 0x43, 0x06, 0xe4, 0x74, 0x03, 0xba,
0x02, 0xf9, 0x80, 0x7b, 0x18, 0x27, 0x2a, 0x55, 0x8d, 0x51, 0xb8, 0x6e, 0xac, 0xa2, 0x6b, 0xf0,
0xdf, 0x2e, 0x0b, 0x58, 0x1b, 0x85, 0x34, 0x26, 0x2b, 0x93, 0xcb, 0xa5, 0x6a, 0x25, 0x2b, 0x62,
0x0b, 0xfd, 0xf6, 0x8e, 0x42, 0xef, 0x09, 0xa2, 0x70, 0x07, 0x11, 0x74, 0x0b, 0x2e, 0x05, 0xa8,
0xf6, 0xb8, 0xe8, 0x6c, 0x37, 0x39, 0x57, 0x52, 0x09, 0x16, 0x6e, 0x77, 0xb0, 0x27, 0x8d, 0x7c,
0xec, 0x75, 0x25, 0xcb, 0x6b, 0x3d, 0x68, 0x89, 0x5e, 0x5c, 0x9a, 0x0d, 0xec, 0xb9, 0x73, 0xda,
0xa0, 0x96, 0xc6, 0x6f, 0x60, 0x4f, 0xda, 0xf7, 0xa1, 0xfc, 0x00, 0x99, 0x50, 0x4d, 0x64, 0x2a,
0x6d, 0xc7, 0x58, 0x65, 0xb0, 0x1f, 0xc3, 0x85, 0x63, 0x0e, 0x32, 0xe4, 0x81, 0x44, 0x7a, 0x17,
0x0a, 0x21, 0x0a, 0x9f, 0x7b, 0xba, 0x99, 0x0b, 0x59, 0x7c, 0x75, 0x3d, 0x18, 0xb5, 0xfc, 0xfe,
0xc1, 0xe2, 0x84, 0xab, 0x23, 0xec, 0x4f, 0x39, 0x98, 0x7f, 0x16, 0x7a, 0x4c, 0xe1, 0x53, 0x26,
0x3b, 0x9b, 0x8a, 0xa9, 0xae, 0x3c, 0x17, 0x1a, 0x7d, 0x0e, 0xd3, 0xdd, 0xd8, 0x28, 0x2d, 0xf9,
0x5a, 0x16, 0xc6, 0x88, 0x5c, 0xce, 0xd1, 0x49, 0xa2, 0x70, 0x53, 0x33, 0x93, 0x43, 0x79, 0xf8,
0x92, 0x2e, 0xc1, 0xb4, 0x62, 0xb2, 0x73, 0x84, 0x05, 0xfd, 0x83, 0xc5, 0x42, 0x24, 0x6b, 0xd4,
0xdd, 0x42, 0x74, 0xd5, 0xf0, 0xe8, 0x1d, 0x28, 0xc8, 0x38, 0x48, 0x0f, 0x8d, 0x95, 0xc5, 0x73,
0x8c, 0x44, 0xab, 0x6d, 0x13, 0x8c, 0x93, 0x94, 0x49, 0xa9, 0xed, 0x35, 0x98, 0x89, 0x4e, 0xcf,
0x57, 0x22, 0xfb, 0x9e, 0x8e, 0x4e, 0x9f, 0x80, 0x03, 0x53, 0x11, 0xab, 0x34, 0x48, 0x5c, 0x30,
0x63, 0x14, 0xa0, 0x9b, 0xc8, 0xaa, 0x1f, 0xf3, 0x00, 0xf5, 0xc1, 0xdf, 0x0a, 0x7d, 0x03, 0xd3,
0x3a, 0x0d, 0xb5, 0xb3, 0x42, 0xff, 0x7e, 0xf8, 0xe6, 0x69, 0x1a, 0x4d, 0x64, 0x2f, 0x7d, 0xfb,
0xfa, 0xeb, 0x4b, 0xee, 0x32, 0xcc, 0xc4, 0x9a, 0x1b, 0xd1, 0x08, 0xa3, 0x80, 0xd9, 0x64, 0xa7,
0x1f, 0xc8, 0x4d, 0x42, 0xdf, 0x42, 0x71, 0x30, 0x86, 0xf4, 0x6a, 0x96, 0xef, 0xf0, 0x9c, 0x9b,
0xd7, 0xfe, 0xa1, 0xd2, 0x05, 0x3e, 0x0b, 0x00, 0xfd, 0x4c, 0xa0, 0x3c, 0xdc, 0x22, 0x7a, 0x7d,
0x8c, 0x71, 0x33, 0x57, 0xce, 0x26, 0x1e, 0x07, 0x4a, 0xc0, 0x54, 0xdc, 0x5c, 0x5a, 0x19, 0xd5,
0xc6, 0x41, 0xf6, 0xd1, 0x8a, 0xf1, 0xfa, 0x50, 0x5b, 0xd8, 0x3f, 0xb4, 0x26, 0x7e, 0x1c, 0x5a,
0x13, 0xbf, 0x0f, 0x2d, 0xf2, 0xae, 0x6f, 0x91, 0xfd, 0xbe, 0x45, 0xbe, 0xf7, 0x2d, 0xf2, 0xb3,
0x6f, 0x91, 0x66, 0x21, 0xfe, 0x06, 0xdc, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0xa3, 0xfc, 0x50,
0xc8, 0x8b, 0x06, 0x00, 0x00,
}

View file

@ -53,6 +53,11 @@ service Dispatcher { // maybe dispatch, al likes this
// SessionRequest starts a session.
message SessionRequest {
NodeDescription description = 1;
// SessionID can be provided to attempt resuming an exising session. If the
// SessionID is empty or invalid, a new SessionID will be assigned.
//
// See SessionMessage.SessionID for details.
string session_id = 2 [(gogoproto.customname) = "SessionID"];
}
// SessionMessage instructs an agent on various actions as part of the current

View file

@ -439,18 +439,18 @@ var (
)
var fileDescriptorDuration = []byte{
// 193 bytes of a gzipped FileDescriptorProto
// 201 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0x29, 0x2d, 0x4a,
0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xc9, 0x4f, 0xce,
0x4e, 0x2d, 0xd2, 0x2b, 0x2e, 0x4f, 0x2c, 0xca, 0xcd, 0xce, 0x2c, 0xd1, 0x2b, 0x33, 0x54, 0xb2,
0xe2, 0xe2, 0x70, 0x81, 0xaa, 0x12, 0x92, 0xe0, 0x62, 0x2f, 0x4e, 0x4d, 0xce, 0xcf, 0x4b, 0x29,
0x96, 0x60, 0x54, 0x60, 0xd4, 0x60, 0x0e, 0x82, 0x71, 0x85, 0x44, 0xb8, 0x58, 0xf3, 0x12, 0xf3,
0xf2, 0x8b, 0x25, 0x98, 0x80, 0xe2, 0xac, 0x41, 0x10, 0x8e, 0x53, 0xce, 0x89, 0x87, 0x72, 0x0c,
0x37, 0x80, 0xf8, 0xc3, 0x43, 0x39, 0xc6, 0x86, 0x47, 0x72, 0x8c, 0x27, 0x80, 0xf8, 0x02, 0x10,
0x3f, 0x00, 0x62, 0x2e, 0xe1, 0xe4, 0xfc, 0x5c, 0xbd, 0xf4, 0xfc, 0xfc, 0xf4, 0x9c, 0x54, 0x88,
0xfd, 0x49, 0xa5, 0x69, 0x4e, 0xbc, 0x30, 0xcb, 0x02, 0x40, 0x22, 0x01, 0x8c, 0x0b, 0x18, 0x19,
0x17, 0x31, 0x31, 0xbb, 0x07, 0x38, 0xad, 0x62, 0x92, 0x73, 0x87, 0xa8, 0x0d, 0x80, 0xaa, 0xd5,
0x0b, 0x4f, 0xcd, 0xc9, 0xf1, 0xce, 0xcb, 0x2f, 0xcf, 0x0b, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62,
0x03, 0x1b, 0x62, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x66, 0x02, 0x1a, 0xa4, 0xd6, 0x00, 0x00,
0x00,
0xf2, 0x8b, 0x25, 0x98, 0x14, 0x18, 0x35, 0x58, 0x83, 0x20, 0x1c, 0xa7, 0x9c, 0x13, 0x0f, 0xe5,
0x18, 0x6e, 0x3c, 0x94, 0x63, 0xf8, 0xf0, 0x50, 0x8e, 0xb1, 0xe1, 0x91, 0x1c, 0xe3, 0x89, 0x47,
0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0xc8, 0x25, 0x9c, 0x9c, 0x9f, 0xab,
0x97, 0x9e, 0x9f, 0x9f, 0x9e, 0x93, 0x0a, 0xb1, 0x3f, 0xa9, 0x34, 0xcd, 0x89, 0x17, 0x66, 0x59,
0x00, 0x48, 0x24, 0x80, 0x71, 0x01, 0x23, 0xe3, 0x22, 0x26, 0x66, 0xf7, 0x00, 0xa7, 0x55, 0x4c,
0x72, 0xee, 0x10, 0xb5, 0x01, 0x50, 0xb5, 0x7a, 0xe1, 0xa9, 0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5,
0x79, 0x21, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, 0x43, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff,
0xff, 0x66, 0x02, 0x1a, 0xa4, 0xd6, 0x00, 0x00, 0x00,
}

View file

@ -705,7 +705,7 @@ var (
)
var fileDescriptorHealth = []byte{
// 284 bytes of a gzipped FileDescriptorProto
// 291 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0xc9, 0x48, 0x4d, 0xcc,
0x29, 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xc9, 0x4f, 0xce, 0x4e, 0x2d,
0xd2, 0x2b, 0x2e, 0x4f, 0x2c, 0xca, 0xcd, 0xce, 0x2c, 0xd1, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf,
@ -721,7 +721,8 @@ var fileDescriptorHealth = []byte{
0xc4, 0xc3, 0x04, 0x98, 0x8c, 0x2a, 0xb9, 0xd8, 0x20, 0x16, 0x09, 0xe5, 0x73, 0xb1, 0x82, 0x2d,
0x13, 0x52, 0x23, 0xe8, 0x1a, 0xb0, 0xbf, 0xa5, 0xd4, 0x89, 0x74, 0xb5, 0x92, 0xe8, 0xa9, 0x75,
0xef, 0x66, 0x30, 0xf1, 0x73, 0xf1, 0x82, 0x15, 0xea, 0xe6, 0x26, 0xe6, 0x25, 0xa6, 0xa7, 0x16,
0x39, 0xc9, 0x9c, 0x78, 0x28, 0xc7, 0x70, 0x03, 0x88, 0x3f, 0x3c, 0x94, 0x63, 0x6c, 0x78, 0x24,
0xc7, 0x78, 0x02, 0x88, 0x2f, 0x00, 0xf1, 0x03, 0x20, 0x4e, 0x62, 0x03, 0x07, 0xb9, 0x31, 0x20,
0x00, 0x00, 0xff, 0xff, 0xf7, 0x14, 0x7c, 0x23, 0xc1, 0x01, 0x00, 0x00,
0x39, 0xc9, 0x9c, 0x78, 0x28, 0xc7, 0x70, 0xe3, 0xa1, 0x1c, 0xc3, 0x87, 0x87, 0x72, 0x8c, 0x0d,
0x8f, 0xe4, 0x18, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6,
0x24, 0x36, 0x70, 0x90, 0x1b, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x14, 0x7c, 0x23, 0xc1,
0x01, 0x00, 0x00,
}

View file

@ -3582,68 +3582,69 @@ var (
)
var fileDescriptorObjects = []byte{
// 1000 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x56, 0x4d, 0x6f, 0x1b, 0x45,
0x18, 0xae, 0x93, 0x8d, 0xed, 0x7d, 0x1d, 0x47, 0x62, 0xa8, 0xaa, 0x6d, 0x08, 0x49, 0x71, 0x05,
0xe2, 0x80, 0x5c, 0x51, 0x0a, 0xa2, 0x82, 0x0a, 0xd9, 0x4e, 0x04, 0x16, 0x04, 0xa2, 0x69, 0x09,
0xc7, 0xd5, 0x64, 0x77, 0x6a, 0x16, 0xdb, 0xbb, 0xab, 0x99, 0x71, 0xaa, 0xdc, 0x10, 0x3f, 0x00,
0x89, 0x3f, 0xc0, 0x5f, 0xe1, 0x9a, 0x03, 0x07, 0x8e, 0x9c, 0x2a, 0xda, 0x1b, 0x27, 0xf8, 0x09,
0xbc, 0xf3, 0xb1, 0xf6, 0x46, 0x5e, 0x87, 0x56, 0xaa, 0x72, 0x58, 0x69, 0x3e, 0x9e, 0xe7, 0x99,
0xf7, 0x6b, 0xde, 0x59, 0x68, 0x67, 0x27, 0x3f, 0xf0, 0x48, 0xc9, 0x6e, 0x2e, 0x32, 0x95, 0x11,
0x12, 0x67, 0xd1, 0x98, 0x8b, 0xae, 0x7c, 0xc2, 0xc4, 0x74, 0x9c, 0xa8, 0xee, 0xe9, 0xfb, 0xdb,
0x2d, 0x75, 0x96, 0x73, 0x07, 0xd8, 0x6e, 0xc9, 0x9c, 0x47, 0xc5, 0xe4, 0xa6, 0x4a, 0xa6, 0x5c,
0x2a, 0x36, 0xcd, 0xef, 0xcc, 0x47, 0x6e, 0xeb, 0xfa, 0x28, 0x1b, 0x65, 0x66, 0x78, 0x47, 0x8f,
0xec, 0x6a, 0xe7, 0xb7, 0x1a, 0x78, 0x87, 0x5c, 0x31, 0xf2, 0x09, 0x34, 0x4e, 0xb9, 0x90, 0x49,
0x96, 0x06, 0xb5, 0x5b, 0xb5, 0x77, 0x5b, 0x77, 0xdf, 0xe8, 0x2e, 0x9f, 0xdc, 0x3d, 0xb6, 0x90,
0xbe, 0x77, 0xfe, 0x74, 0xef, 0x1a, 0x2d, 0x18, 0xe4, 0x53, 0x80, 0x48, 0x70, 0xa6, 0x78, 0x1c,
0x32, 0x15, 0xac, 0x19, 0xfe, 0x9b, 0x55, 0xfc, 0x47, 0x85, 0x51, 0xd4, 0x77, 0x84, 0x9e, 0xd2,
0xec, 0x59, 0x1e, 0x17, 0xec, 0xf5, 0x17, 0x62, 0x3b, 0x42, 0x4f, 0x75, 0xfe, 0x5e, 0x07, 0xef,
0xeb, 0x2c, 0xe6, 0xe4, 0x06, 0xac, 0x25, 0xb1, 0x31, 0xde, 0xef, 0xd7, 0x9f, 0x3f, 0xdd, 0x5b,
0x1b, 0xee, 0x53, 0x5c, 0x21, 0x77, 0xc1, 0x9b, 0xa2, 0x87, 0xce, 0xac, 0xa0, 0x4a, 0x58, 0x47,
0xc0, 0xf9, 0x64, 0xb0, 0xe4, 0x23, 0xf0, 0x74, 0x58, 0x9d, 0x31, 0x3b, 0x55, 0x1c, 0x7d, 0xe6,
0x43, 0xc4, 0x14, 0x3c, 0x8d, 0x27, 0x07, 0xd0, 0x8a, 0xb9, 0x8c, 0x44, 0x92, 0x2b, 0x1d, 0x49,
0xcf, 0xd0, 0x6f, 0xaf, 0xa2, 0xef, 0x2f, 0xa0, 0xb4, 0xcc, 0xc3, 0x88, 0xd4, 0xd1, 0x4f, 0x35,
0x93, 0xc1, 0x86, 0x51, 0xd8, 0x5d, 0x69, 0x80, 0x41, 0x39, 0x13, 0x1c, 0x87, 0x7c, 0x01, 0x5b,
0x53, 0x96, 0xb2, 0x11, 0x17, 0xa1, 0x53, 0xa9, 0x1b, 0x95, 0xb7, 0x2a, 0x5d, 0xb7, 0x48, 0x2b,
0x44, 0xdb, 0xd3, 0xf2, 0x14, 0xdd, 0x01, 0xa6, 0x14, 0x8b, 0xbe, 0x9f, 0xf2, 0x54, 0x05, 0x0d,
0xa3, 0xf2, 0x76, 0xa5, 0x2d, 0x5c, 0x3d, 0xc9, 0xc4, 0xb8, 0x37, 0x07, 0xd3, 0x12, 0x91, 0x7c,
0x0e, 0xad, 0x88, 0x0b, 0x95, 0x3c, 0x4e, 0x22, 0x4c, 0x5a, 0xd0, 0x34, 0x3a, 0x7b, 0x55, 0x3a,
0x83, 0x05, 0xcc, 0x39, 0x55, 0x66, 0x76, 0x7e, 0x59, 0x83, 0xc6, 0x43, 0x2e, 0x4e, 0x93, 0xe8,
0xd5, 0xa6, 0xfb, 0xfe, 0x85, 0x74, 0x57, 0x5a, 0xe6, 0x8e, 0x5d, 0xca, 0xf8, 0xc7, 0xd0, 0xe4,
0x69, 0x9c, 0x67, 0x09, 0x06, 0xc8, 0x5b, 0x5d, 0x2d, 0x07, 0x0e, 0x43, 0xe7, 0x68, 0x0c, 0x6e,
0xdb, 0x56, 0x71, 0x78, 0x21, 0xd7, 0xb7, 0xaa, 0xe8, 0xdf, 0x1a, 0xa0, 0x4b, 0xd2, 0xe6, 0xac,
0x34, 0xeb, 0xfc, 0xba, 0x06, 0xcd, 0x42, 0x9d, 0xdc, 0x73, 0x8e, 0xd4, 0x56, 0x4b, 0x15, 0x58,
0xed, 0x89, 0xf3, 0xe1, 0x1e, 0x6c, 0xe4, 0x99, 0x50, 0x12, 0x63, 0xb6, 0xbe, 0xaa, 0xda, 0x8e,
0x10, 0x30, 0xc8, 0xd2, 0xc7, 0xc9, 0x88, 0x5a, 0x30, 0xf9, 0x0e, 0x5a, 0xa7, 0x89, 0x50, 0x33,
0x36, 0x09, 0x93, 0x5c, 0x62, 0xec, 0x34, 0xf7, 0x9d, 0xcb, 0x8e, 0xec, 0x1e, 0x5b, 0xfc, 0xf0,
0xa8, 0xbf, 0x85, 0x19, 0x83, 0xf9, 0x54, 0x52, 0x70, 0x52, 0xc3, 0x5c, 0x6e, 0x1f, 0x82, 0x3f,
0xdf, 0x21, 0xef, 0x01, 0xa4, 0xb6, 0xb8, 0xc2, 0x79, 0xba, 0xdb, 0x48, 0xf6, 0x5d, 0xc9, 0x61,
0xd6, 0x7d, 0x07, 0x18, 0xc6, 0x84, 0x80, 0xc7, 0xe2, 0x58, 0x98, 0xe4, 0xfb, 0xd4, 0x8c, 0x3b,
0xbf, 0x6f, 0x80, 0xf7, 0x88, 0xc9, 0xf1, 0x55, 0x37, 0x08, 0x7d, 0xe6, 0x52, 0xb9, 0xa0, 0x3b,
0xd2, 0x56, 0x92, 0x76, 0xc7, 0x5b, 0xb8, 0xe3, 0xea, 0x4b, 0xbb, 0xe3, 0x00, 0xd6, 0x1d, 0x39,
0xc9, 0x94, 0xa9, 0x0c, 0x8f, 0x9a, 0x31, 0xb9, 0x0d, 0x8d, 0x14, 0x6f, 0xbe, 0xa6, 0xd7, 0x0d,
0x1d, 0x90, 0x5e, 0xd7, 0xcd, 0x00, 0xb9, 0x75, 0xbd, 0x85, 0x44, 0xbc, 0x71, 0x2c, 0x4d, 0x33,
0xac, 0x10, 0x6c, 0x27, 0xd2, 0xdd, 0xdc, 0xca, 0xba, 0xee, 0x2d, 0x60, 0xc5, 0x8d, 0x2b, 0x31,
0xc9, 0x31, 0xbc, 0x5e, 0xd8, 0x5b, 0x16, 0x6c, 0xbe, 0x8c, 0x20, 0x71, 0x0a, 0xa5, 0x9d, 0x52,
0x87, 0xf3, 0x57, 0x77, 0x38, 0x13, 0xc1, 0xaa, 0x0e, 0xd7, 0x87, 0x36, 0xb6, 0xcb, 0x44, 0xe0,
0x8b, 0xa1, 0x57, 0x78, 0x00, 0x28, 0xb2, 0xb5, 0xe2, 0xd1, 0x70, 0x22, 0x9c, 0x6e, 0x3a, 0x8e,
0x99, 0x91, 0x1e, 0x34, 0x5d, 0xdd, 0xc8, 0xa0, 0x65, 0x6a, 0xf7, 0x05, 0x3b, 0xdb, 0x9c, 0x76,
0xe1, 0xee, 0x6f, 0xbe, 0xd4, 0xdd, 0xbf, 0x0f, 0x30, 0xc9, 0x46, 0x61, 0x2c, 0x12, 0x7c, 0x42,
0x83, 0xb6, 0xe1, 0x6e, 0x57, 0x71, 0xf7, 0x0d, 0x82, 0xfa, 0x88, 0xb6, 0xc3, 0xce, 0x4f, 0x35,
0x78, 0x6d, 0xc9, 0x28, 0xf2, 0x21, 0x56, 0x85, 0x5d, 0xbc, 0xec, 0xf9, 0x76, 0x3c, 0x5a, 0x60,
0xc9, 0x0e, 0xf8, 0xfa, 0x8e, 0x70, 0x29, 0xb9, 0xbd, 0xfd, 0x3e, 0x5d, 0x2c, 0x90, 0x00, 0x1a,
0x6c, 0x92, 0x30, 0xbd, 0xb7, 0x6e, 0xf6, 0x8a, 0x69, 0xe7, 0x67, 0x6c, 0xc4, 0x4e, 0xec, 0xaa,
0x1b, 0xb1, 0x3b, 0x76, 0xe9, 0x66, 0x3d, 0x80, 0x4d, 0x1b, 0x4e, 0x57, 0x12, 0xde, 0xff, 0x06,
0xb5, 0x65, 0xf1, 0xb6, 0x1c, 0x1e, 0x80, 0x97, 0xe4, 0x6c, 0xea, 0x9a, 0x70, 0xe5, 0xc9, 0xc3,
0xa3, 0xde, 0xe1, 0x37, 0xb9, 0xad, 0xec, 0x26, 0x3a, 0xea, 0xe9, 0x05, 0x6a, 0x68, 0x9d, 0x7f,
0x30, 0x20, 0x83, 0xc9, 0x4c, 0x2a, 0x2e, 0xae, 0x3a, 0x20, 0xee, 0xd8, 0xa5, 0x80, 0x0c, 0xa0,
0x21, 0xb2, 0x4c, 0x85, 0x11, 0xbb, 0x2c, 0x16, 0x14, 0x21, 0x83, 0x5e, 0x7f, 0x4b, 0x13, 0x75,
0x23, 0xb1, 0x73, 0x5a, 0xd7, 0xd4, 0x01, 0xc3, 0x26, 0x7f, 0xa3, 0x68, 0xbf, 0x27, 0xb8, 0x22,
0x95, 0x60, 0x79, 0x38, 0xe6, 0x67, 0xfa, 0xb5, 0x5a, 0x5f, 0xf5, 0x4f, 0x71, 0x90, 0x46, 0xe2,
0xcc, 0x04, 0xea, 0x4b, 0x7e, 0x46, 0xaf, 0x3b, 0x81, 0x7e, 0xc1, 0xc7, 0x45, 0x49, 0x3e, 0x83,
0x1d, 0x3e, 0x87, 0x69, 0xc5, 0x70, 0x82, 0x3f, 0x76, 0xf8, 0xb0, 0x84, 0xd1, 0x04, 0x15, 0x4d,
0x6f, 0xf3, 0xe8, 0x4d, 0x5e, 0x96, 0xfa, 0xca, 0x22, 0x06, 0x1a, 0xd0, 0xdf, 0x39, 0x7f, 0xb6,
0x7b, 0xed, 0x4f, 0xfc, 0xfe, 0x7d, 0xb6, 0x5b, 0xfb, 0xf1, 0xf9, 0x6e, 0xed, 0x1c, 0xbf, 0x3f,
0xf0, 0xfb, 0x0b, 0xbf, 0x93, 0xba, 0xf9, 0xbd, 0xfd, 0xe0, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff,
0x56, 0x49, 0xe6, 0x55, 0x4e, 0x0b, 0x00, 0x00,
// 1009 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x6e, 0x1b, 0x45,
0x1c, 0xce, 0xda, 0x1b, 0xdb, 0xfb, 0x73, 0x1c, 0x89, 0xa1, 0xaa, 0xb6, 0x21, 0xd8, 0xc1, 0x15,
0xa8, 0x87, 0xca, 0x15, 0xa5, 0x20, 0x2a, 0x5a, 0x21, 0xff, 0x13, 0x58, 0x25, 0x10, 0x4d, 0x4b,
0x7a, 0x5c, 0x4d, 0x76, 0xa7, 0x66, 0xb1, 0xbd, 0xb3, 0x9a, 0x19, 0xbb, 0xf2, 0x0d, 0xf1, 0x00,
0x48, 0xbc, 0x00, 0xaf, 0xc2, 0x35, 0x07, 0x0e, 0x1c, 0x39, 0x59, 0xc4, 0x37, 0x4e, 0xf0, 0x08,
0x68, 0x66, 0x67, 0xed, 0x8d, 0xbc, 0x0e, 0x8d, 0x84, 0x72, 0x9b, 0xd9, 0xf9, 0xbe, 0x6f, 0x7e,
0xff, 0x67, 0xa1, 0xc6, 0xce, 0xbe, 0xa7, 0xbe, 0x14, 0xad, 0x98, 0x33, 0xc9, 0x10, 0x0a, 0x98,
0x3f, 0xa2, 0xbc, 0x25, 0x5e, 0x13, 0x3e, 0x19, 0x85, 0xb2, 0x35, 0xfb, 0xf0, 0xa0, 0x2a, 0xe7,
0x31, 0x35, 0x80, 0x83, 0xaa, 0x88, 0xa9, 0x9f, 0x6e, 0xee, 0xc8, 0x70, 0x42, 0x85, 0x24, 0x93,
0xf8, 0xc1, 0x6a, 0x65, 0x8e, 0x6e, 0x0d, 0xd9, 0x90, 0xe9, 0xe5, 0x03, 0xb5, 0x4a, 0xbe, 0x36,
0x7f, 0xb5, 0xc0, 0x3e, 0xa6, 0x92, 0xa0, 0xcf, 0xa0, 0x3c, 0xa3, 0x5c, 0x84, 0x2c, 0x72, 0xad,
0x23, 0xeb, 0x5e, 0xf5, 0xe1, 0x3b, 0xad, 0xcd, 0x9b, 0x5b, 0xa7, 0x09, 0xa4, 0x63, 0x9f, 0x2f,
0x1a, 0x3b, 0x38, 0x65, 0xa0, 0x27, 0x00, 0x3e, 0xa7, 0x44, 0xd2, 0xc0, 0x23, 0xd2, 0x2d, 0x68,
0xfe, 0xbb, 0x79, 0xfc, 0x17, 0xa9, 0x51, 0xd8, 0x31, 0x84, 0xb6, 0x54, 0xec, 0x69, 0x1c, 0xa4,
0xec, 0xe2, 0x1b, 0xb1, 0x0d, 0xa1, 0x2d, 0x9b, 0x7f, 0x15, 0xc1, 0xfe, 0x9a, 0x05, 0x14, 0xdd,
0x86, 0x42, 0x18, 0x68, 0xe3, 0x9d, 0x4e, 0x69, 0xb9, 0x68, 0x14, 0x06, 0x3d, 0x5c, 0x08, 0x03,
0xf4, 0x10, 0xec, 0x09, 0x95, 0xc4, 0x98, 0xe5, 0xe6, 0x09, 0xab, 0x08, 0x18, 0x9f, 0x34, 0x16,
0x7d, 0x02, 0xb6, 0x0a, 0xab, 0x31, 0xe6, 0x30, 0x8f, 0xa3, 0xee, 0x7c, 0x1e, 0x53, 0x3f, 0xe5,
0x29, 0x3c, 0xea, 0x43, 0x35, 0xa0, 0xc2, 0xe7, 0x61, 0x2c, 0x55, 0x24, 0x6d, 0x4d, 0xbf, 0xbb,
0x8d, 0xde, 0x5b, 0x43, 0x71, 0x96, 0x87, 0x9e, 0x40, 0x49, 0x48, 0x22, 0xa7, 0xc2, 0xdd, 0xd5,
0x0a, 0xf5, 0xad, 0x06, 0x68, 0x94, 0x31, 0xc1, 0x70, 0xd0, 0x97, 0xb0, 0x3f, 0x21, 0x11, 0x19,
0x52, 0xee, 0x19, 0x95, 0x92, 0x56, 0x79, 0x2f, 0xd7, 0xf5, 0x04, 0x99, 0x08, 0xe1, 0xda, 0x24,
0xbb, 0x45, 0x7d, 0x00, 0x22, 0x25, 0xf1, 0xbf, 0x9b, 0xd0, 0x48, 0xba, 0x65, 0xad, 0xf2, 0x7e,
0xae, 0x2d, 0x54, 0xbe, 0x66, 0x7c, 0xd4, 0x5e, 0x81, 0x71, 0x86, 0x88, 0xbe, 0x80, 0xaa, 0x4f,
0xb9, 0x0c, 0x5f, 0x85, 0x3e, 0x91, 0xd4, 0xad, 0x68, 0x9d, 0x46, 0x9e, 0x4e, 0x77, 0x0d, 0x33,
0x4e, 0x65, 0x99, 0xcd, 0x9f, 0x0b, 0x50, 0x7e, 0x4e, 0xf9, 0x2c, 0xf4, 0xff, 0xdf, 0x74, 0x3f,
0xbe, 0x94, 0xee, 0x5c, 0xcb, 0xcc, 0xb5, 0x1b, 0x19, 0xff, 0x14, 0x2a, 0x34, 0x0a, 0x62, 0x16,
0x46, 0xd2, 0xa4, 0x3b, 0xb7, 0x5a, 0xfa, 0x06, 0x83, 0x57, 0x68, 0xd4, 0x87, 0x5a, 0x52, 0xc5,
0xde, 0xa5, 0x5c, 0x1f, 0xe5, 0xd1, 0xbf, 0xd5, 0x40, 0x93, 0xa4, 0xbd, 0x69, 0x66, 0xd7, 0xfc,
0xa5, 0x00, 0x95, 0x54, 0x1d, 0x3d, 0x32, 0x8e, 0x58, 0xdb, 0xa5, 0x52, 0xac, 0xf2, 0xc4, 0xf8,
0xf0, 0x08, 0x76, 0x63, 0xc6, 0xa5, 0x70, 0x0b, 0x47, 0xc5, 0x6d, 0xd5, 0x76, 0xc2, 0xb8, 0xec,
0xb2, 0xe8, 0x55, 0x38, 0xc4, 0x09, 0x18, 0xbd, 0x84, 0xea, 0x2c, 0xe4, 0x72, 0x4a, 0xc6, 0x5e,
0x18, 0x0b, 0xb7, 0xa8, 0xb9, 0x1f, 0x5c, 0x75, 0x65, 0xeb, 0x34, 0xc1, 0x0f, 0x4e, 0x3a, 0xfb,
0xcb, 0x45, 0x03, 0x56, 0x5b, 0x81, 0xc1, 0x48, 0x0d, 0x62, 0x71, 0x70, 0x0c, 0xce, 0xea, 0x04,
0xdd, 0x07, 0x88, 0x92, 0xe2, 0xf2, 0x56, 0xe9, 0xae, 0x2d, 0x17, 0x0d, 0xc7, 0x94, 0xdc, 0xa0,
0x87, 0x1d, 0x03, 0x18, 0x04, 0x08, 0x81, 0x4d, 0x82, 0x80, 0xeb, 0xe4, 0x3b, 0x58, 0xaf, 0x9b,
0xbf, 0xed, 0x82, 0xfd, 0x82, 0x88, 0xd1, 0x4d, 0x0f, 0x08, 0x75, 0xe7, 0x46, 0xb9, 0xdc, 0x07,
0x10, 0x49, 0x25, 0x29, 0x77, 0xec, 0xb5, 0x3b, 0xa6, 0xbe, 0x94, 0x3b, 0x06, 0x90, 0xb8, 0x23,
0xc6, 0x4c, 0xea, 0xca, 0xb0, 0xb1, 0x5e, 0xa3, 0xbb, 0x50, 0x8e, 0x58, 0xa0, 0xe9, 0x25, 0x4d,
0x87, 0xe5, 0xa2, 0x51, 0x52, 0xc3, 0x60, 0xd0, 0xc3, 0x25, 0x75, 0x34, 0x08, 0x54, 0xc7, 0x91,
0x28, 0x62, 0x92, 0xa8, 0x71, 0x22, 0x4c, 0xe7, 0xe6, 0xd6, 0x75, 0x7b, 0x0d, 0x4b, 0x3b, 0x2e,
0xc3, 0x44, 0xa7, 0xf0, 0x76, 0x6a, 0x6f, 0x56, 0xb0, 0x72, 0x1d, 0x41, 0x64, 0x14, 0x32, 0x27,
0x99, 0x09, 0xe7, 0x6c, 0x9f, 0x70, 0x3a, 0x82, 0x79, 0x13, 0xae, 0x03, 0xb5, 0x80, 0x8a, 0x90,
0xd3, 0x40, 0xf7, 0x0e, 0x75, 0xe1, 0xc8, 0xba, 0xb7, 0xbf, 0xe5, 0xd1, 0x30, 0x22, 0x14, 0xef,
0x19, 0x8e, 0xde, 0xa1, 0x36, 0x54, 0x4c, 0xdd, 0x08, 0xb7, 0xaa, 0x6b, 0xf7, 0x0d, 0x27, 0xdb,
0x8a, 0x76, 0xa9, 0xf7, 0xf7, 0xae, 0xd5, 0xfb, 0x8f, 0x01, 0xc6, 0x6c, 0xe8, 0x05, 0x3c, 0x9c,
0x51, 0xee, 0xd6, 0x34, 0xf7, 0x20, 0x8f, 0xdb, 0xd3, 0x08, 0xec, 0x8c, 0xd9, 0x30, 0x59, 0x36,
0x7f, 0xb4, 0xe0, 0xad, 0x0d, 0xa3, 0xd0, 0xc7, 0x50, 0x36, 0x66, 0x5d, 0xf5, 0x7c, 0x1b, 0x1e,
0x4e, 0xb1, 0xe8, 0x10, 0x1c, 0xd5, 0x23, 0x54, 0x08, 0x9a, 0x74, 0xbf, 0x83, 0xd7, 0x1f, 0x90,
0x0b, 0x65, 0x32, 0x0e, 0x89, 0x3a, 0x2b, 0xea, 0xb3, 0x74, 0xdb, 0xfc, 0xa9, 0x00, 0x65, 0x23,
0x76, 0xd3, 0x83, 0xd8, 0x5c, 0xbb, 0xd1, 0x59, 0x4f, 0x61, 0x2f, 0x09, 0xa7, 0x29, 0x09, 0xfb,
0x3f, 0x83, 0x5a, 0x4d, 0xf0, 0x49, 0x39, 0x3c, 0x05, 0x3b, 0x8c, 0xc9, 0xc4, 0x0c, 0xe1, 0xdc,
0x9b, 0x07, 0x27, 0xed, 0xe3, 0x6f, 0xe2, 0xa4, 0xb2, 0x2b, 0xcb, 0x45, 0xc3, 0x56, 0x1f, 0xb0,
0xa6, 0x35, 0xff, 0x2e, 0x40, 0xb9, 0x3b, 0x9e, 0x0a, 0x49, 0xf9, 0x4d, 0x07, 0xc4, 0x5c, 0xbb,
0x11, 0x90, 0x2e, 0x94, 0x39, 0x63, 0xd2, 0xf3, 0xc9, 0x55, 0xb1, 0xc0, 0x8c, 0xc9, 0x6e, 0xbb,
0xb3, 0xaf, 0x88, 0x6a, 0x90, 0x24, 0x7b, 0x5c, 0x52, 0xd4, 0x2e, 0x41, 0x2f, 0xe1, 0x76, 0x3a,
0x7e, 0xcf, 0x18, 0x93, 0x42, 0x72, 0x12, 0x7b, 0x23, 0x3a, 0x57, 0xaf, 0x55, 0x71, 0xdb, 0x3f,
0x45, 0x3f, 0xf2, 0xf9, 0x5c, 0x07, 0xea, 0x19, 0x9d, 0xe3, 0x5b, 0x46, 0xa0, 0x93, 0xf2, 0x9f,
0xd1, 0xb9, 0x40, 0x9f, 0xc3, 0x21, 0x5d, 0xc1, 0x94, 0xa2, 0x37, 0x26, 0x13, 0xf5, 0xb0, 0x78,
0xfe, 0x98, 0xf9, 0x23, 0x3d, 0xdb, 0x6c, 0x7c, 0x87, 0x66, 0xa5, 0xbe, 0x4a, 0x10, 0x5d, 0x05,
0xe8, 0x1c, 0x9e, 0x5f, 0xd4, 0x77, 0xfe, 0xb8, 0xa8, 0xef, 0xfc, 0x73, 0x51, 0xb7, 0x7e, 0x58,
0xd6, 0xad, 0xf3, 0x65, 0xdd, 0xfa, 0x7d, 0x59, 0xb7, 0xfe, 0x5c, 0xd6, 0xad, 0xb3, 0x92, 0xfe,
0xbd, 0xfd, 0xe8, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x56, 0x49, 0xe6, 0x55, 0x4e, 0x0b, 0x00,
0x00,
}

View file

@ -3206,59 +3206,60 @@ var (
)
var fileDescriptorRaft = []byte{
// 852 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x95, 0x4f, 0x53, 0x23, 0x45,
0x18, 0xc6, 0x33, 0x93, 0x61, 0xa2, 0x1d, 0x20, 0x54, 0x23, 0x18, 0x46, 0x2a, 0xc0, 0x60, 0x95,
0x42, 0xc9, 0xa4, 0x8c, 0x07, 0x2d, 0xf5, 0x92, 0x84, 0x54, 0x19, 0x81, 0x84, 0x1a, 0x12, 0xe5,
0x16, 0x27, 0x33, 0x4d, 0x18, 0x93, 0x4c, 0xc7, 0xe9, 0x4e, 0x28, 0x2f, 0x16, 0x47, 0x8b, 0xab,
0x55, 0xea, 0xc5, 0x93, 0x9e, 0xf9, 0x00, 0x7e, 0x02, 0x6a, 0x4f, 0x7b, 0xdb, 0x3d, 0xb1, 0x0b,
0x1f, 0x60, 0x77, 0x3f, 0xc2, 0x76, 0xcf, 0x9f, 0xc0, 0x86, 0x49, 0xc8, 0xa1, 0xa1, 0x79, 0xfb,
0xf7, 0xbc, 0x4f, 0xf7, 0xdb, 0xf3, 0x36, 0x00, 0xb8, 0xc6, 0x09, 0xd5, 0x7a, 0x2e, 0xa6, 0x18,
0x42, 0x0b, 0x9b, 0x6d, 0xe4, 0x6a, 0xe4, 0xcc, 0x70, 0xbb, 0x6d, 0x9b, 0x6a, 0x83, 0xcf, 0x95,
0x39, 0xdc, 0xfc, 0x19, 0x99, 0x94, 0xf8, 0x88, 0x92, 0xa4, 0xbf, 0xf6, 0x50, 0xf8, 0xc7, 0x4e,
0xcb, 0xa6, 0xa7, 0xfd, 0xa6, 0x66, 0xe2, 0x6e, 0xd6, 0xc4, 0x2e, 0xc2, 0x24, 0x8b, 0xa8, 0x69,
0x65, 0x79, 0x4a, 0xef, 0x47, 0xaf, 0x99, 0xbd, 0x4b, 0xaf, 0x7c, 0xd0, 0xc2, 0x2d, 0xec, 0x4d,
0xb3, 0x7c, 0x16, 0x44, 0x17, 0x7b, 0x9d, 0x7e, 0xcb, 0x76, 0xb2, 0xfe, 0x2f, 0x3f, 0xa8, 0x5e,
0x0a, 0x00, 0xe8, 0x4c, 0x79, 0x80, 0xba, 0x4d, 0xe4, 0xc2, 0x4d, 0x90, 0xe0, 0x79, 0x1a, 0xb6,
0x95, 0x16, 0xd6, 0x85, 0x4f, 0xa5, 0x02, 0xb8, 0xbd, 0x5e, 0x93, 0x39, 0x50, 0xde, 0xd5, 0x65,
0xbe, 0x54, 0xb6, 0x38, 0xe4, 0x60, 0x0b, 0x71, 0x48, 0x64, 0xd0, 0xfb, 0x3e, 0x54, 0x61, 0x21,
0x0e, 0xf1, 0x25, 0x06, 0x41, 0x20, 0x19, 0x96, 0xe5, 0xa6, 0xe3, 0x9c, 0xd0, 0xbd, 0x39, 0x2c,
0x00, 0x99, 0x50, 0x83, 0xf6, 0x49, 0x5a, 0x62, 0xd1, 0x64, 0xee, 0x63, 0xed, 0x61, 0x1d, 0xb4,
0xbb, 0xdd, 0x1c, 0x79, 0x6c, 0x41, 0xba, 0xba, 0x5e, 0x8b, 0xe9, 0x81, 0x52, 0xdd, 0x00, 0xc9,
0xef, 0xb1, 0xed, 0xe8, 0xe8, 0x97, 0x3e, 0x22, 0x74, 0x68, 0x23, 0xdc, 0xd9, 0xa8, 0x7f, 0x0a,
0x60, 0xd6, 0x67, 0x48, 0x0f, 0x3b, 0x04, 0x4d, 0x77, 0xaa, 0xaf, 0x40, 0xa2, 0xeb, 0xd9, 0x12,
0x76, 0xaa, 0x38, 0xdb, 0x5d, 0x66, 0xf2, 0xee, 0xf4, 0x10, 0x87, 0x9f, 0x80, 0x94, 0x8b, 0xba,
0x78, 0x80, 0xac, 0x46, 0x98, 0x21, 0xce, 0x32, 0x48, 0xfa, 0x7c, 0x10, 0xf6, 0x05, 0x44, 0x2d,
0x80, 0xd9, 0x7d, 0x64, 0x0c, 0x50, 0xb8, 0xf9, 0x1c, 0x90, 0x78, 0xb5, 0xbc, 0x4d, 0x3d, 0xee,
0xe7, 0xb1, 0x6a, 0x0a, 0xcc, 0x05, 0x39, 0xfc, 0xc3, 0xa9, 0xfb, 0x60, 0xe5, 0xd0, 0xc5, 0x26,
0x22, 0xc4, 0x67, 0x09, 0x31, 0x5a, 0x43, 0x87, 0x2d, 0x7e, 0x28, 0x2f, 0x12, 0x98, 0xa4, 0x34,
0xff, 0x73, 0xd1, 0x42, 0x30, 0x5c, 0xff, 0x5a, 0x3a, 0xff, 0x4b, 0x8d, 0xa9, 0xab, 0x40, 0x89,
0xca, 0x16, 0x78, 0x7d, 0x0b, 0x96, 0xd8, 0x1c, 0x77, 0x06, 0x28, 0xcf, 0x0a, 0xcd, 0xa1, 0xc0,
0x67, 0x9a, 0x0a, 0xab, 0x9f, 0x81, 0xe5, 0x51, 0x75, 0x70, 0x41, 0x51, 0xb7, 0x78, 0x02, 0x16,
0xcb, 0x0e, 0x45, 0xae, 0x63, 0x74, 0x78, 0x9e, 0xd0, 0x69, 0x19, 0x88, 0x43, 0x13, 0x99, 0x99,
0x88, 0xcc, 0x80, 0x45, 0xe0, 0x97, 0x40, 0x36, 0x4c, 0x6a, 0x63, 0x27, 0xb8, 0xbd, 0xb5, 0xa8,
0x6a, 0x1e, 0x51, 0xd6, 0x3c, 0x79, 0x0f, 0xd3, 0x03, 0x5c, 0x7d, 0x21, 0x82, 0xe4, 0xbd, 0x38,
0xfc, 0x66, 0x98, 0x88, 0x9b, 0xcc, 0xe7, 0x36, 0x1f, 0x49, 0xb4, 0x67, 0x3b, 0x56, 0x98, 0x0c,
0x6a, 0xc1, 0x8d, 0x8a, 0x5e, 0xb1, 0xd3, 0x51, 0x52, 0xde, 0x27, 0xdf, 0xc5, 0xfc, 0xdb, 0x64,
0xbb, 0x4e, 0x10, 0xe4, 0x0e, 0x6c, 0x13, 0x79, 0x8d, 0x92, 0xcc, 0x7d, 0x14, 0xe9, 0xe6, 0x23,
0x4c, 0x15, 0xd2, 0xdc, 0x88, 0x1a, 0xa4, 0x1d, 0x34, 0x52, 0xa4, 0x51, 0x8d, 0xad, 0x73, 0x23,
0xce, 0x71, 0x23, 0x07, 0xd1, 0x33, 0xec, 0xb6, 0xd3, 0x33, 0xe3, 0x8d, 0x2a, 0x3e, 0xc2, 0x8d,
0x02, 0x9a, 0x0b, 0xcd, 0x4e, 0x9f, 0xb0, 0x8b, 0x48, 0xcb, 0xe3, 0x85, 0x45, 0x1f, 0xe1, 0xc2,
0x80, 0x2e, 0xbc, 0x07, 0x64, 0x6a, 0xb8, 0x2d, 0x44, 0xb7, 0x5f, 0x0b, 0x20, 0x35, 0x52, 0x30,
0xd6, 0x33, 0x89, 0x7a, 0x65, 0xaf, 0x52, 0xfd, 0xb1, 0xb2, 0x10, 0x53, 0x94, 0x8b, 0x7f, 0xd6,
0x97, 0x47, 0x88, 0xba, 0xd3, 0x76, 0xf0, 0x99, 0xc3, 0x7a, 0x64, 0xf1, 0xa8, 0x56, 0xd5, 0x4b,
0x8d, 0x7c, 0xb1, 0x56, 0xae, 0x56, 0x1a, 0x45, 0xbd, 0x94, 0xaf, 0x95, 0x16, 0x04, 0x65, 0x85,
0x89, 0x96, 0x46, 0x44, 0x45, 0x17, 0x19, 0x14, 0x3d, 0xd0, 0xd4, 0x0f, 0x77, 0xb9, 0x46, 0x8c,
0xd4, 0xd4, 0x7b, 0x56, 0x94, 0x46, 0x2f, 0x1d, 0x54, 0x7f, 0x28, 0x2d, 0xc4, 0x23, 0x35, 0xba,
0xd7, 0xd7, 0xca, 0x87, 0xbf, 0xff, 0x9b, 0x89, 0xfd, 0xff, 0x5f, 0x66, 0xf4, 0x74, 0xb9, 0x3f,
0x44, 0x20, 0xf1, 0x8f, 0x16, 0x5e, 0x08, 0x00, 0x3e, 0xec, 0x27, 0xb8, 0x13, 0x55, 0xc3, 0xb1,
0x5d, 0xac, 0x68, 0xd3, 0xe2, 0x41, 0x9b, 0x2e, 0x3d, 0xb9, 0x7c, 0xf5, 0xb7, 0xc8, 0x5e, 0x0a,
0x8f, 0xdf, 0xe9, 0x1a, 0x0e, 0x5b, 0x75, 0xe1, 0x6f, 0x60, 0xfe, 0xdd, 0xfe, 0x83, 0x5b, 0x91,
0x4f, 0x4e, 0x54, 0x87, 0x2b, 0xdb, 0xd3, 0xa0, 0x13, 0xfd, 0x73, 0xcf, 0x04, 0xb6, 0x81, 0xe1,
0x7b, 0x46, 0x4e, 0xed, 0x1e, 0xfc, 0x09, 0x48, 0xfc, 0xa5, 0x86, 0x91, 0xdd, 0x7a, 0xef, 0x9d,
0x57, 0xd6, 0xc7, 0x03, 0x93, 0x0f, 0x6d, 0x82, 0x19, 0xef, 0xbd, 0x84, 0x91, 0x19, 0xee, 0x3f,
0xc7, 0xca, 0xc6, 0x04, 0x62, 0xa2, 0x49, 0x61, 0xf5, 0xea, 0x26, 0x13, 0x7b, 0xce, 0xc6, 0x9b,
0x9b, 0x8c, 0x70, 0x7e, 0x9b, 0x11, 0xae, 0xd8, 0x78, 0xca, 0xc6, 0x4b, 0x36, 0x8e, 0xe3, 0xc7,
0x52, 0x53, 0xf6, 0xfe, 0xdd, 0x7e, 0xf1, 0x36, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x61, 0x3c, 0x43,
// 868 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x95, 0x4f, 0x73, 0xdb, 0x44,
0x18, 0xc6, 0xb5, 0xb2, 0xaa, 0xc0, 0xeb, 0x26, 0xce, 0x6c, 0x48, 0x70, 0x45, 0x47, 0x51, 0x55,
0x66, 0xea, 0x76, 0x88, 0x3c, 0x88, 0x43, 0x19, 0xe0, 0x12, 0x27, 0x9e, 0xa9, 0x69, 0xeb, 0x74,
0x94, 0x04, 0x7a, 0x0b, 0xb2, 0xb4, 0x71, 0x85, 0x63, 0xad, 0xd9, 0x5d, 0x3b, 0xc3, 0x85, 0xe9,
0x91, 0xc9, 0x95, 0x19, 0xe0, 0xd2, 0x13, 0x9c, 0xfb, 0x01, 0xf8, 0x04, 0x19, 0x4e, 0xdc, 0xe0,
0x14, 0x88, 0x3f, 0x00, 0xf0, 0x11, 0x98, 0xd5, 0x9f, 0x24, 0x38, 0x8a, 0xe3, 0x8b, 0x2d, 0xef,
0xfe, 0x9e, 0xe7, 0xd9, 0x7d, 0x57, 0xef, 0x1a, 0x80, 0xf9, 0xfb, 0xc2, 0x19, 0x30, 0x2a, 0x28,
0xc6, 0x21, 0x0d, 0x7a, 0x84, 0x39, 0xfc, 0xd0, 0x67, 0xfd, 0x5e, 0x24, 0x9c, 0xd1, 0xfb, 0xc6,
0x3c, 0xed, 0x7c, 0x49, 0x02, 0xc1, 0x53, 0xc4, 0x28, 0x8b, 0xaf, 0x07, 0x24, 0xff, 0xb1, 0xd6,
0x8d, 0xc4, 0x8b, 0x61, 0xc7, 0x09, 0x68, 0xbf, 0x1e, 0x50, 0x46, 0x28, 0xaf, 0x13, 0x11, 0x84,
0x75, 0x69, 0x99, 0x7c, 0x0c, 0x3a, 0xf5, 0x73, 0x7b, 0xe3, 0xad, 0x2e, 0xed, 0xd2, 0xe4, 0xb1,
0x2e, 0x9f, 0xb2, 0xd1, 0xa5, 0xc1, 0xc1, 0xb0, 0x1b, 0xc5, 0xf5, 0xf4, 0x2b, 0x1d, 0xb4, 0x5f,
0x23, 0x00, 0xcf, 0xdf, 0x17, 0x4f, 0x49, 0xbf, 0x43, 0x18, 0xbe, 0x0b, 0x73, 0xd2, 0x67, 0x2f,
0x0a, 0xab, 0xc8, 0x42, 0x35, 0xad, 0x01, 0xe3, 0x93, 0x55, 0x5d, 0x02, 0xad, 0x4d, 0x4f, 0x97,
0x53, 0xad, 0x50, 0x42, 0x31, 0x0d, 0x89, 0x84, 0x54, 0x0b, 0xd5, 0xde, 0x4c, 0xa1, 0x36, 0x0d,
0x89, 0x84, 0xe4, 0x54, 0x2b, 0xc4, 0x18, 0x34, 0x3f, 0x0c, 0x59, 0xb5, 0x24, 0x09, 0x2f, 0x79,
0xc6, 0x0d, 0xd0, 0xb9, 0xf0, 0xc5, 0x90, 0x57, 0x35, 0x0b, 0xd5, 0xca, 0xee, 0xbb, 0xce, 0xe5,
0x3a, 0x38, 0xe7, 0xab, 0xd9, 0x4e, 0xd8, 0x86, 0x76, 0x7c, 0xb2, 0xaa, 0x78, 0x99, 0xd2, 0xbe,
0x03, 0xe5, 0x4f, 0x69, 0x14, 0x7b, 0xe4, 0xab, 0x21, 0xe1, 0xe2, 0x2c, 0x06, 0x9d, 0xc7, 0xd8,
0xdf, 0x23, 0xb8, 0x99, 0x32, 0x7c, 0x40, 0x63, 0x4e, 0x66, 0xdb, 0xd5, 0x87, 0x30, 0xd7, 0x4f,
0x62, 0x79, 0x55, 0xb5, 0x4a, 0xb5, 0xb2, 0x6b, 0x4e, 0x5f, 0x9d, 0x97, 0xe3, 0xf8, 0x1e, 0x54,
0x18, 0xe9, 0xd3, 0x11, 0x09, 0xf7, 0x72, 0x87, 0x92, 0x55, 0xaa, 0x69, 0xde, 0x42, 0x36, 0x9c,
0x0a, 0xb8, 0xdd, 0x80, 0x9b, 0x4f, 0x88, 0x3f, 0x22, 0xf9, 0xe2, 0x5d, 0xd0, 0x64, 0xb5, 0x92,
0x45, 0x5d, 0x9f, 0x97, 0xb0, 0x76, 0x05, 0xe6, 0x33, 0x8f, 0x74, 0x73, 0xf6, 0x13, 0xb8, 0xf5,
0x8c, 0xd1, 0x80, 0x70, 0x9e, 0xb2, 0x9c, 0xfb, 0xdd, 0xb3, 0x84, 0xfb, 0x72, 0x53, 0xc9, 0x48,
0x16, 0x52, 0x71, 0xd2, 0xd7, 0xc5, 0xc9, 0xc1, 0x7c, 0xfe, 0x23, 0xed, 0xe5, 0x0f, 0xb6, 0x62,
0xdf, 0x06, 0xa3, 0xc8, 0x2d, 0xcb, 0xfa, 0x04, 0x96, 0x3d, 0xc2, 0xe9, 0xc1, 0x88, 0xac, 0x87,
0x21, 0x93, 0x50, 0x96, 0x33, 0x4b, 0x85, 0xed, 0xf7, 0x60, 0x65, 0x52, 0x9d, 0x1d, 0x50, 0xd1,
0x29, 0xee, 0xc3, 0x52, 0x2b, 0x16, 0x84, 0xc5, 0xfe, 0x81, 0xf4, 0xc9, 0x93, 0x56, 0x40, 0x3d,
0x0b, 0xd1, 0xc7, 0x27, 0xab, 0x6a, 0x6b, 0xd3, 0x53, 0xa3, 0x10, 0x3f, 0x04, 0xdd, 0x0f, 0x44,
0x44, 0xe3, 0xec, 0xf4, 0x56, 0x8b, 0xaa, 0xb9, 0x2d, 0x28, 0x23, 0xeb, 0x09, 0xe6, 0x65, 0xb8,
0xfd, 0xa7, 0x0a, 0xe5, 0x0b, 0xe3, 0xf8, 0xe3, 0x33, 0x23, 0x19, 0xb2, 0xe0, 0xde, 0xbd, 0xc6,
0xe8, 0x71, 0x14, 0x87, 0xb9, 0x19, 0x76, 0xb2, 0x13, 0x55, 0x93, 0x62, 0x57, 0x8b, 0xa4, 0xb2,
0x4f, 0x1e, 0x29, 0xe9, 0x69, 0xe2, 0x87, 0x30, 0xc7, 0x09, 0x1b, 0x45, 0x01, 0x49, 0x1a, 0xa5,
0xec, 0xbe, 0x53, 0x98, 0x96, 0x22, 0x8f, 0x14, 0x2f, 0xa7, 0x65, 0x90, 0xf0, 0x79, 0x2f, 0x6b,
0xa4, 0xc2, 0xa0, 0x1d, 0x9f, 0xf7, 0x64, 0x90, 0xe4, 0x64, 0x50, 0x4c, 0xc4, 0x21, 0x65, 0xbd,
0xea, 0x8d, 0xab, 0x83, 0xda, 0x29, 0x22, 0x83, 0x32, 0x5a, 0x0a, 0x83, 0x83, 0x21, 0x17, 0x84,
0x55, 0xf5, 0xab, 0x85, 0x1b, 0x29, 0x22, 0x85, 0x19, 0xdd, 0x78, 0x03, 0x74, 0xe1, 0xb3, 0x2e,
0x11, 0x0f, 0xfe, 0x41, 0x50, 0x99, 0x28, 0x18, 0xbe, 0x07, 0x73, 0xbb, 0xed, 0xc7, 0xed, 0xad,
0xcf, 0xdb, 0x8b, 0x8a, 0x61, 0x1c, 0xbd, 0xb2, 0x56, 0x26, 0x88, 0xdd, 0xb8, 0x17, 0xd3, 0xc3,
0x18, 0xbb, 0xb0, 0xb4, 0xbd, 0xb3, 0xe5, 0x35, 0xf7, 0xd6, 0x37, 0x76, 0x5a, 0x5b, 0xed, 0xbd,
0x0d, 0xaf, 0xb9, 0xbe, 0xd3, 0x5c, 0x44, 0xc6, 0xad, 0xa3, 0x57, 0xd6, 0xf2, 0x84, 0x68, 0x83,
0x11, 0x5f, 0x90, 0x4b, 0x9a, 0xdd, 0x67, 0x9b, 0x52, 0xa3, 0x16, 0x6a, 0x76, 0x07, 0x61, 0x91,
0xc6, 0x6b, 0x3e, 0xdd, 0xfa, 0xac, 0xb9, 0x58, 0x2a, 0xd4, 0x78, 0x49, 0x5f, 0x1b, 0x6f, 0x7f,
0xfb, 0x93, 0xa9, 0xfc, 0xf2, 0xb3, 0x39, 0xb9, 0x3b, 0xf7, 0x3b, 0x15, 0x34, 0xf9, 0xd2, 0xe2,
0x23, 0x04, 0xf8, 0x72, 0x3f, 0xe1, 0xb5, 0xa2, 0x1a, 0x5e, 0xd9, 0xc5, 0x86, 0x33, 0x2b, 0x9e,
0xb5, 0xe9, 0xf2, 0xaf, 0xaf, 0xff, 0xfe, 0x51, 0xad, 0xc0, 0x7c, 0xc2, 0xaf, 0xf5, 0xfd, 0xd8,
0xef, 0x12, 0x86, 0xbf, 0x81, 0x85, 0xff, 0xf7, 0x1f, 0xbe, 0x5f, 0x78, 0xe5, 0x14, 0x75, 0xb8,
0xf1, 0x60, 0x16, 0x74, 0x6a, 0xbe, 0xfb, 0x3b, 0x82, 0x85, 0xf3, 0xfb, 0x8c, 0xbf, 0x88, 0x06,
0xf8, 0x0b, 0xd0, 0xe4, 0x4d, 0x8d, 0x0b, 0xbb, 0xf5, 0xc2, 0x3d, 0x6f, 0x58, 0x57, 0x03, 0xd3,
0x37, 0x1d, 0xc0, 0x8d, 0xe4, 0xbe, 0xc4, 0x85, 0x0e, 0x17, 0xaf, 0x63, 0xe3, 0xce, 0x14, 0x62,
0x6a, 0x48, 0xe3, 0xf6, 0xf1, 0xa9, 0xa9, 0xfc, 0x71, 0x6a, 0x2a, 0xff, 0x9e, 0x9a, 0xe8, 0xe5,
0xd8, 0x44, 0xc7, 0x63, 0x13, 0xfd, 0x36, 0x36, 0xd1, 0x5f, 0x63, 0x13, 0x3d, 0x2f, 0x3d, 0xd7,
0x3a, 0x7a, 0xf2, 0x77, 0xfb, 0xc1, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x61, 0x3c, 0x43,
0x06, 0x08, 0x00, 0x00,
}

View file

@ -1086,30 +1086,30 @@ var (
)
var fileDescriptorSnapshot = []byte{
// 386 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x92, 0xbf, 0x4e, 0xf3, 0x30,
0x14, 0xc5, 0x9b, 0xf4, 0x4f, 0xaa, 0xfb, 0xa9, 0xfd, 0xc0, 0x62, 0x88, 0x0a, 0x0a, 0x10, 0x18,
0x3a, 0x05, 0x28, 0x03, 0x2c, 0x30, 0x94, 0x89, 0x81, 0x0e, 0x2e, 0xaa, 0x58, 0xd3, 0xd4, 0xb4,
0xa1, 0x24, 0xae, 0x6c, 0x93, 0xae, 0x3c, 0x07, 0x4f, 0xd4, 0x91, 0x91, 0x09, 0x51, 0x16, 0x56,
0x1e, 0x01, 0x27, 0x4e, 0xa2, 0x4a, 0xa4, 0x0c, 0x57, 0x72, 0xac, 0xdf, 0x39, 0xe7, 0xe6, 0xfa,
0x42, 0x93, 0x87, 0xee, 0x8c, 0x4f, 0xa8, 0x70, 0x66, 0x8c, 0x0a, 0x8a, 0xd0, 0x88, 0x7a, 0x53,
0xc2, 0x1c, 0x3e, 0x77, 0x59, 0x30, 0xf5, 0x85, 0x13, 0x9d, 0xb4, 0x1a, 0x74, 0xf8, 0x40, 0x3c,
0xc1, 0x15, 0xd2, 0x02, 0xe6, 0xde, 0xa7, 0x78, 0x6b, 0x6b, 0x4c, 0xc7, 0x34, 0x39, 0x1e, 0xc5,
0x27, 0x75, 0x6b, 0xbf, 0xe8, 0xd0, 0xe8, 0x0b, 0xca, 0x48, 0x3f, 0x35, 0x47, 0x0e, 0x54, 0x43,
0x3a, 0x22, 0xdc, 0xd4, 0xf6, 0xca, 0xed, 0x7f, 0x1d, 0xd3, 0xf9, 0x1d, 0xe3, 0xf4, 0x24, 0x80,
0x15, 0x86, 0xce, 0xa0, 0xce, 0x09, 0x8b, 0x7c, 0x4f, 0x4a, 0xf4, 0x44, 0xb2, 0x5d, 0x24, 0xe9,
0x2b, 0x06, 0xe7, 0x70, 0x2c, 0x0c, 0x89, 0x98, 0x53, 0x36, 0xe5, 0x66, 0x79, 0xbd, 0xb0, 0xa7,
0x18, 0x9c, 0xc3, 0x71, 0x87, 0xc2, 0xe5, 0x52, 0x55, 0x59, 0xdf, 0xe1, 0xad, 0x04, 0xb0, 0xc2,
0xe2, 0x20, 0xef, 0xf1, 0x89, 0x0b, 0xc2, 0xb8, 0x59, 0x5d, 0x1f, 0x74, 0xa5, 0x18, 0x9c, 0xc3,
0x36, 0x81, 0xff, 0xe9, 0x65, 0x3e, 0x9d, 0x73, 0x30, 0x02, 0x12, 0x0c, 0x63, 0x2b, 0x35, 0x1f,
0xab, 0xc8, 0x0a, 0xcb, 0xb1, 0xdf, 0x24, 0x18, 0xce, 0x70, 0x64, 0x82, 0xc1, 0x48, 0x40, 0x23,
0x32, 0x4a, 0xc6, 0x54, 0xc1, 0xd9, 0xa7, 0xfd, 0xa5, 0x41, 0x3d, 0x0f, 0xb8, 0x04, 0x23, 0x92,
0xb8, 0x4f, 0x43, 0x19, 0xa0, 0xb5, 0x9b, 0x9d, 0xc3, 0xc2, 0x69, 0x66, 0xab, 0x30, 0x50, 0x2c,
0xce, 0x44, 0xe8, 0x1a, 0x20, 0x4d, 0x9c, 0xf8, 0x33, 0x99, 0xa4, 0xc9, 0x1e, 0x0f, 0xfe, 0xf8,
0xdd, 0xcc, 0xa9, 0x5b, 0x59, 0xbc, 0xef, 0x96, 0xf0, 0x8a, 0x18, 0x5d, 0x40, 0x95, 0xc7, 0xab,
0x21, 0x5f, 0x27, 0x76, 0xd9, 0x2f, 0x6c, 0x64, 0x75, 0x77, 0x52, 0x0f, 0xa5, 0xb2, 0x37, 0xc1,
0x48, 0xbb, 0x43, 0x35, 0xd0, 0x07, 0xc7, 0x1b, 0xa5, 0xee, 0xce, 0x62, 0x69, 0x95, 0xde, 0x64,
0x7d, 0x2f, 0x2d, 0xed, 0xf9, 0xd3, 0xd2, 0x16, 0xb2, 0x5e, 0x65, 0x7d, 0xc8, 0xba, 0xd3, 0x87,
0xb5, 0x64, 0x29, 0x4f, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc9, 0xd9, 0x1a, 0xd9, 0xeb, 0x02,
0x00, 0x00,
// 396 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x7c, 0x92, 0xbd, 0x6e, 0xdb, 0x30,
0x14, 0x85, 0x45, 0xf9, 0x47, 0x06, 0x0d, 0xbb, 0x2d, 0xd1, 0x81, 0x70, 0x0b, 0xd6, 0x55, 0x3b,
0x78, 0x52, 0x5b, 0x77, 0x68, 0x97, 0x76, 0x70, 0xa6, 0x0c, 0xf1, 0x40, 0x07, 0x46, 0x56, 0x59,
0xa2, 0x6d, 0x45, 0x91, 0x68, 0x90, 0x8c, 0xbc, 0xe6, 0x39, 0xf2, 0x44, 0x1e, 0x33, 0x66, 0x0a,
0x62, 0x2d, 0x59, 0xf3, 0x08, 0x81, 0x44, 0x49, 0x30, 0x10, 0x39, 0x1b, 0x75, 0xf1, 0x9d, 0x73,
0xae, 0x2e, 0x0e, 0xec, 0xcb, 0xd8, 0xdd, 0xc8, 0x35, 0x57, 0xce, 0x46, 0x70, 0xc5, 0x11, 0xf2,
0xb9, 0x17, 0x32, 0xe1, 0xc8, 0xad, 0x2b, 0xa2, 0x30, 0x50, 0x4e, 0xf2, 0x6b, 0xd0, 0xe3, 0x8b,
0x4b, 0xe6, 0x29, 0xa9, 0x91, 0x01, 0x14, 0xee, 0xb2, 0xc0, 0x07, 0x1f, 0x57, 0x7c, 0xc5, 0xf3,
0xe7, 0x8f, 0xec, 0xa5, 0xa7, 0xf6, 0xad, 0x09, 0x7b, 0x33, 0xc5, 0x05, 0x9b, 0x15, 0xe6, 0xc8,
0x81, 0xad, 0x98, 0xfb, 0x4c, 0x62, 0x30, 0x6c, 0x8c, 0xba, 0x63, 0xec, 0xbc, 0x8e, 0x71, 0xa6,
0xdc, 0x67, 0x54, 0x63, 0xe8, 0x0f, 0xec, 0x48, 0x26, 0x92, 0xc0, 0x63, 0x12, 0x9b, 0xb9, 0xe4,
0x53, 0x9d, 0x64, 0xa6, 0x19, 0x5a, 0xc1, 0x99, 0x30, 0x66, 0x6a, 0xcb, 0x45, 0x28, 0x71, 0xe3,
0xb8, 0x70, 0xaa, 0x19, 0x5a, 0xc1, 0xd9, 0x86, 0xca, 0x95, 0xa1, 0xc4, 0xcd, 0xe3, 0x1b, 0x9e,
0xbb, 0x32, 0xa4, 0x1a, 0xcb, 0x82, 0xbc, 0xab, 0x6b, 0xa9, 0x98, 0x90, 0xb8, 0x75, 0x3c, 0xe8,
0x44, 0x33, 0xb4, 0x82, 0x6d, 0x06, 0xdf, 0x15, 0xc3, 0xea, 0x3a, 0x7f, 0xa1, 0x15, 0xb1, 0x68,
0x91, 0x59, 0xe9, 0xfb, 0x90, 0x3a, 0x2b, 0xea, 0x2e, 0xd5, 0x59, 0x8e, 0xd1, 0x12, 0x47, 0x18,
0x5a, 0x82, 0x45, 0x3c, 0x61, 0x7e, 0x7e, 0xa6, 0x26, 0x2d, 0x3f, 0xed, 0x27, 0x00, 0x3b, 0x55,
0xc0, 0x7f, 0x68, 0x25, 0x4c, 0xc8, 0x80, 0xc7, 0x18, 0x0c, 0xc1, 0xa8, 0x3f, 0xfe, 0x5e, 0x7b,
0xcd, 0xb2, 0x0a, 0x73, 0xcd, 0xd2, 0x52, 0x84, 0x4e, 0x21, 0x2c, 0x12, 0xd7, 0xc1, 0x06, 0x9b,
0x43, 0x30, 0xea, 0x8e, 0xbf, 0xbd, 0xf1, 0xbb, 0xa5, 0xd3, 0xa4, 0xb9, 0x7b, 0xf8, 0x62, 0xd0,
0x03, 0x31, 0xfa, 0x07, 0x5b, 0x32, 0xab, 0x06, 0x6e, 0xe4, 0x2e, 0x5f, 0x6b, 0x17, 0x39, 0xec,
0x4e, 0xe1, 0xa1, 0x55, 0xf6, 0x07, 0x68, 0x15, 0xdb, 0xa1, 0x36, 0x34, 0xe7, 0x3f, 0xdf, 0x1b,
0x93, 0xcf, 0xbb, 0x3d, 0x31, 0xee, 0xf7, 0xc4, 0x78, 0xde, 0x13, 0x70, 0x93, 0x12, 0xb0, 0x4b,
0x09, 0xb8, 0x4b, 0x09, 0x78, 0x4c, 0x09, 0xb8, 0x30, 0x17, 0xed, 0xbc, 0x94, 0xbf, 0x5f, 0x02,
0x00, 0x00, 0xff, 0xff, 0xc9, 0xd9, 0x1a, 0xd9, 0xeb, 0x02, 0x00, 0x00,
}

View file

@ -4188,89 +4188,91 @@ var (
)
var fileDescriptorSpecs = []byte{
// 1344 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0x8f, 0x93, 0x8d, 0xe3, 0xbc, 0x75, 0xda, 0x74, 0x54, 0x5a, 0xd7, 0x2d, 0x49, 0x6a, 0x0a,
0x14, 0x24, 0x1c, 0x30, 0xa8, 0x7f, 0xf8, 0x23, 0x70, 0x6c, 0x93, 0x86, 0x92, 0xd4, 0x9a, 0xb4,
0x95, 0x38, 0x59, 0x93, 0xf5, 0xd4, 0x59, 0x65, 0xbd, 0xb3, 0xcc, 0xce, 0xba, 0xca, 0x8d, 0x63,
0xc5, 0x81, 0x1b, 0x47, 0x4e, 0x48, 0x1c, 0x39, 0xf2, 0x19, 0x7a, 0xe4, 0x82, 0xc4, 0xa9, 0xa2,
0xfd, 0x04, 0x48, 0x7c, 0x01, 0xde, 0xcc, 0x8e, 0xed, 0x35, 0xdd, 0xb4, 0x1c, 0x7a, 0xb0, 0x34,
0x7f, 0x7e, 0xbf, 0xf7, 0x66, 0xdf, 0xfb, 0xcd, 0x7b, 0x63, 0x70, 0xe3, 0x88, 0x7b, 0x71, 0x3d,
0x92, 0x42, 0x09, 0x42, 0xfa, 0xc2, 0x3b, 0xe2, 0xb2, 0x1e, 0x3f, 0x64, 0x72, 0x78, 0xe4, 0xab,
0xfa, 0xe8, 0x83, 0xaa, 0xab, 0x8e, 0x23, 0x6e, 0x01, 0xd5, 0xb3, 0x03, 0x31, 0x10, 0x66, 0xb8,
0xa9, 0x47, 0x76, 0xf5, 0x7c, 0x3f, 0x91, 0x4c, 0xf9, 0x22, 0xdc, 0x1c, 0x0f, 0xd2, 0x8d, 0xda,
0x0f, 0x0e, 0x94, 0xf6, 0x44, 0x9f, 0xef, 0xa3, 0x0f, 0xb2, 0x0d, 0x2e, 0x0b, 0x43, 0xa1, 0x0c,
0x20, 0xae, 0x14, 0x36, 0x0a, 0x57, 0xdd, 0xc6, 0x7a, 0xfd, 0x79, 0x97, 0xf5, 0xe6, 0x14, 0xb6,
0xe5, 0x3c, 0x7e, 0xb2, 0x3e, 0x47, 0xb3, 0x4c, 0xf2, 0x3e, 0x38, 0x52, 0x04, 0xbc, 0x32, 0x8f,
0x16, 0x4e, 0x35, 0x2e, 0xe5, 0x59, 0xd0, 0x4e, 0x29, 0x62, 0xa8, 0x41, 0xa2, 0x6b, 0x18, 0xf2,
0xe1, 0x01, 0x97, 0xf1, 0xa1, 0x1f, 0x55, 0x16, 0x0c, 0xef, 0xed, 0x93, 0x78, 0xfa, 0xb0, 0xf5,
0xdd, 0x09, 0x9c, 0x66, 0xa8, 0x64, 0x17, 0xca, 0x6c, 0xc4, 0xfc, 0x80, 0x1d, 0xf8, 0x81, 0xaf,
0x8e, 0x2b, 0x8e, 0x31, 0xf5, 0xce, 0x0b, 0x4d, 0x35, 0x33, 0x04, 0x3a, 0x43, 0xaf, 0xf5, 0x01,
0xa6, 0x8e, 0xc8, 0x5b, 0xb0, 0xd4, 0xed, 0xec, 0xb5, 0x77, 0xf6, 0xb6, 0x57, 0xe7, 0xaa, 0x17,
0xbe, 0xff, 0x69, 0xe3, 0x35, 0x6d, 0x63, 0x0a, 0xe8, 0xf2, 0xb0, 0xef, 0x87, 0x03, 0x72, 0x15,
0x4a, 0xcd, 0x56, 0xab, 0xd3, 0xbd, 0xdb, 0x69, 0xaf, 0x16, 0xaa, 0x55, 0x04, 0x9e, 0x9b, 0x05,
0x36, 0x3d, 0x8f, 0x47, 0x8a, 0xf7, 0xab, 0xce, 0xa3, 0x9f, 0xd7, 0xe6, 0x6a, 0x8f, 0x0a, 0x50,
0xce, 0x1e, 0x02, 0x1d, 0x15, 0x9b, 0xad, 0xbb, 0x3b, 0xf7, 0x3b, 0xe8, 0x67, 0x42, 0xcf, 0x22,
0x9a, 0x9e, 0xf2, 0x47, 0x9c, 0x5c, 0x81, 0xc5, 0x6e, 0xf3, 0xde, 0x7e, 0x07, 0xbd, 0x4c, 0x8e,
0x93, 0x85, 0x75, 0x59, 0x12, 0x1b, 0x54, 0x9b, 0x36, 0x77, 0xf6, 0x56, 0xe7, 0xf3, 0x51, 0x6d,
0xc9, 0xfc, 0xd0, 0x1e, 0xe5, 0x37, 0x07, 0xdc, 0x7d, 0x2e, 0x47, 0xbe, 0xf7, 0x8a, 0x35, 0x71,
0x0d, 0x1c, 0xc5, 0xe2, 0x23, 0xa3, 0x09, 0x37, 0x5f, 0x13, 0x77, 0x71, 0x5f, 0x3b, 0xb5, 0x74,
0x83, 0xd7, 0xca, 0x90, 0x3c, 0x0a, 0x7c, 0x8f, 0x61, 0xbc, 0x8c, 0x32, 0xdc, 0xc6, 0x9b, 0x79,
0x6c, 0x3a, 0x41, 0xd9, 0xf3, 0xdf, 0x9a, 0xa3, 0x19, 0x2a, 0xf9, 0x04, 0x8a, 0x83, 0x40, 0x1c,
0xb0, 0xc0, 0x68, 0xc2, 0x6d, 0x5c, 0xce, 0x33, 0xb2, 0x6d, 0x10, 0x53, 0x03, 0x96, 0x42, 0x6e,
0x40, 0x31, 0x89, 0xfa, 0x68, 0xa7, 0x52, 0x34, 0xe4, 0x8d, 0x3c, 0xf2, 0x3d, 0x83, 0x68, 0x89,
0xf0, 0x81, 0x3f, 0xa0, 0x16, 0x4f, 0xf6, 0xa1, 0x14, 0x72, 0xf5, 0x50, 0xc8, 0xa3, 0xb8, 0xb2,
0xb4, 0xb1, 0x80, 0xdc, 0xeb, 0x79, 0xdc, 0x4c, 0xcc, 0xeb, 0x7b, 0x29, 0xbe, 0xa9, 0x14, 0xf3,
0x0e, 0x87, 0x3c, 0x54, 0xd6, 0xe4, 0xc4, 0x10, 0xf9, 0x14, 0x4a, 0x28, 0xb5, 0x48, 0xf8, 0xa1,
0xaa, 0x94, 0x4e, 0x3e, 0x50, 0xc7, 0x62, 0xb4, 0x55, 0x3a, 0x61, 0x54, 0x6f, 0xc3, 0xf9, 0x13,
0x5c, 0x90, 0x73, 0x50, 0x54, 0x4c, 0x0e, 0xb8, 0x32, 0x99, 0x5e, 0xa6, 0x76, 0x46, 0x2a, 0xb0,
0xc4, 0x02, 0x9f, 0xc5, 0x3c, 0xc6, 0x04, 0x2e, 0xe0, 0xc6, 0x78, 0xba, 0x55, 0x04, 0x67, 0x88,
0x7a, 0xaa, 0x6d, 0xc2, 0x99, 0xe7, 0x32, 0x40, 0xaa, 0x50, 0xb2, 0x19, 0x48, 0xa5, 0xe3, 0xd0,
0xc9, 0xbc, 0x76, 0x1a, 0x56, 0x66, 0xa2, 0x5d, 0xfb, 0x63, 0x1e, 0x4a, 0x63, 0x09, 0x90, 0x26,
0x2c, 0x7b, 0x22, 0x54, 0x28, 0x4c, 0x2e, 0xad, 0xea, 0x72, 0x13, 0xd6, 0x1a, 0x83, 0x34, 0x0b,
0x13, 0x36, 0x65, 0x91, 0x2f, 0x61, 0x59, 0xf2, 0x58, 0x24, 0xd2, 0x33, 0xa7, 0xd6, 0x26, 0xae,
0xe6, 0x0b, 0x27, 0x05, 0x51, 0xfe, 0x6d, 0xe2, 0x4b, 0xae, 0xa3, 0x11, 0xd3, 0x29, 0x15, 0x85,
0xb3, 0x84, 0x13, 0x0c, 0x84, 0x7a, 0x91, 0x72, 0x68, 0x0a, 0xe9, 0x0a, 0xfc, 0xba, 0x63, 0x3a,
0x66, 0x20, 0x79, 0x39, 0x0a, 0x98, 0x67, 0xac, 0x56, 0x16, 0x0d, 0xfd, 0xf5, 0x3c, 0x7a, 0x77,
0x0c, 0xa2, 0x53, 0x3c, 0xb9, 0x09, 0x10, 0x88, 0x41, 0xaf, 0x2f, 0xf1, 0xae, 0x4b, 0xab, 0xbc,
0x6a, 0x1e, 0xbb, 0x6d, 0x10, 0x74, 0x19, 0xd1, 0xe9, 0x70, 0x6b, 0x19, 0x0f, 0x9d, 0x84, 0xca,
0x1f, 0xf2, 0xda, 0xaf, 0x0e, 0xac, 0xcc, 0x84, 0x89, 0x9c, 0x85, 0x45, 0x7f, 0xc8, 0x06, 0xdc,
0x26, 0x39, 0x9d, 0x90, 0x0e, 0x14, 0xb1, 0x22, 0xf0, 0x20, 0x4d, 0xb1, 0xdb, 0x78, 0xef, 0xa5,
0xf1, 0xae, 0x7f, 0x6d, 0xf0, 0x9d, 0x50, 0xc9, 0x63, 0x6a, 0xc9, 0x5a, 0x2a, 0x9e, 0x18, 0x0e,
0x59, 0xa8, 0x6f, 0xab, 0x91, 0x8a, 0x9d, 0x12, 0x02, 0x0e, 0xaa, 0x29, 0xc6, 0x28, 0xea, 0x65,
0x33, 0x26, 0xab, 0xb0, 0xc0, 0xc3, 0x11, 0x46, 0x46, 0x2f, 0xe9, 0xa1, 0x5e, 0xe9, 0xfb, 0xe9,
0xd7, 0xe2, 0x0a, 0x0e, 0x35, 0x0f, 0xcb, 0x98, 0xc4, 0xeb, 0xa3, 0x97, 0xcc, 0x98, 0x5c, 0x87,
0xe2, 0x50, 0xe0, 0x07, 0xc6, 0xa8, 0x7f, 0x7d, 0xd8, 0x0b, 0x79, 0x87, 0xdd, 0xd5, 0x08, 0x5b,
0x4d, 0x2c, 0x9c, 0xdc, 0x82, 0x33, 0xb1, 0x12, 0x51, 0x6f, 0x20, 0x31, 0xca, 0xbd, 0x88, 0x4b,
0x5f, 0xf4, 0x2b, 0xcb, 0x27, 0x17, 0xa5, 0xb6, 0x6d, 0x98, 0xf4, 0xb4, 0xa6, 0x6d, 0x6b, 0x56,
0xd7, 0x90, 0x48, 0x17, 0xca, 0x51, 0x12, 0x04, 0x3d, 0x11, 0xa5, 0xb5, 0x11, 0x8c, 0x91, 0xff,
0x11, 0xb5, 0x2e, 0xb2, 0xee, 0xa4, 0x24, 0xea, 0x46, 0xd3, 0x89, 0xbe, 0x7d, 0x03, 0x29, 0x92,
0x28, 0xae, 0xb8, 0x26, 0x1e, 0x76, 0x56, 0xbd, 0x09, 0x6e, 0x26, 0xd2, 0x3a, 0x42, 0x47, 0xfc,
0xd8, 0x26, 0x4f, 0x0f, 0x75, 0x42, 0x47, 0x2c, 0x48, 0xd2, 0x8e, 0x8b, 0x09, 0x35, 0x93, 0x8f,
0xe7, 0x6f, 0x14, 0xaa, 0x0d, 0x70, 0x33, 0xee, 0xc8, 0x1b, 0xb0, 0x22, 0xf9, 0xc0, 0x8f, 0xd1,
0x4c, 0x8f, 0x25, 0xea, 0xb0, 0xf2, 0x85, 0x21, 0x94, 0xc7, 0x8b, 0x4d, 0x5c, 0xab, 0xfd, 0x83,
0xed, 0x28, 0x5b, 0x3a, 0x48, 0x2b, 0xbd, 0xe3, 0xc6, 0xe3, 0xa9, 0xc6, 0xe6, 0xcb, 0x4a, 0x8d,
0xb9, 0x51, 0x41, 0xa2, 0x3d, 0xee, 0xea, 0x36, 0x6f, 0xc8, 0xe4, 0x23, 0x58, 0x8c, 0x84, 0x54,
0x63, 0x75, 0xad, 0xe5, 0xde, 0x02, 0x04, 0xd8, 0x62, 0x97, 0x82, 0x6b, 0x87, 0x70, 0x6a, 0xd6,
0x1a, 0x76, 0xb3, 0x85, 0xfb, 0x3b, 0x5d, 0x6c, 0x8c, 0x17, 0xb1, 0x97, 0x9d, 0x9f, 0xdd, 0xbc,
0xef, 0x4b, 0x95, 0xb0, 0x60, 0xa7, 0x4b, 0xde, 0xc5, 0x9e, 0xb7, 0xb7, 0x4f, 0x29, 0x76, 0xc6,
0x75, 0xc4, 0x5d, 0x9c, 0xc5, 0xe9, 0x2d, 0x94, 0x43, 0x9f, 0x8a, 0x83, 0x49, 0xe7, 0xfb, 0x71,
0x1e, 0x5c, 0x5b, 0x16, 0x5f, 0x6d, 0xe7, 0xfb, 0x1c, 0x56, 0xd2, 0x1b, 0xdc, 0xf3, 0xcc, 0xa7,
0xd9, 0x5a, 0xf4, 0xa2, 0x8b, 0x5c, 0x4e, 0x09, 0xb6, 0x28, 0x5f, 0x86, 0xb2, 0x1f, 0x8d, 0xae,
0xf5, 0x78, 0xc8, 0x0e, 0x02, 0xdb, 0x04, 0x4b, 0xd4, 0xd5, 0x6b, 0x9d, 0x74, 0x49, 0x17, 0x5a,
0x0c, 0x3e, 0x97, 0xa1, 0x6d, 0x6f, 0x25, 0x3a, 0x99, 0x93, 0xcf, 0xc0, 0xf1, 0x23, 0x36, 0xb4,
0xd5, 0x27, 0xf7, 0x0b, 0x76, 0xba, 0xcd, 0x5d, 0x2b, 0x91, 0xad, 0xd2, 0xb3, 0x27, 0xeb, 0x8e,
0x5e, 0xa0, 0x86, 0x56, 0xfb, 0x05, 0x5f, 0x04, 0xad, 0x20, 0x89, 0x95, 0x2d, 0x1e, 0xaf, 0x2c,
0x2e, 0xdf, 0xc0, 0x19, 0x66, 0xde, 0x41, 0x2c, 0xd4, 0x37, 0xd1, 0x14, 0x4e, 0x1b, 0x9b, 0x2b,
0xb9, 0xe6, 0x26, 0xe0, 0xb4, 0xc8, 0x6e, 0x15, 0xb5, 0xcd, 0x4a, 0x81, 0xae, 0xb2, 0xff, 0xec,
0x60, 0xd3, 0x5d, 0x11, 0xd2, 0x3b, 0xc4, 0x1a, 0x9c, 0x5e, 0x5e, 0xfb, 0x6e, 0xc8, 0x7d, 0x51,
0xde, 0xc9, 0x02, 0xd3, 0x88, 0xdb, 0xd3, 0xce, 0xda, 0xc0, 0x37, 0x80, 0x23, 0xd9, 0x83, 0x71,
0x13, 0xc8, 0xd5, 0x2f, 0xc5, 0xfd, 0x19, 0x13, 0x86, 0x41, 0xbe, 0x02, 0xe8, 0xfb, 0x71, 0xc4,
0x14, 0x9a, 0x93, 0x36, 0x0f, 0xb9, 0x9f, 0xd8, 0x9e, 0xa0, 0x66, 0xac, 0x64, 0xd8, 0xe4, 0x36,
0x36, 0x46, 0x36, 0x56, 0x52, 0xf1, 0xe4, 0xba, 0xd5, 0x6a, 0x5a, 0x13, 0xab, 0xda, 0x04, 0xe6,
0xb4, 0x34, 0x5e, 0xa1, 0x25, 0x8f, 0x59, 0x65, 0xdd, 0x86, 0x15, 0xfd, 0xc8, 0xea, 0xf5, 0xf9,
0x03, 0x96, 0x04, 0x2a, 0x36, 0x25, 0xf6, 0x84, 0xc7, 0x84, 0x6e, 0xcd, 0x6d, 0x8b, 0xb3, 0xe7,
0x2a, 0xab, 0xec, 0xda, 0xa5, 0xc7, 0x4f, 0xd7, 0xe6, 0xfe, 0xc4, 0xdf, 0xdf, 0x4f, 0xd7, 0x0a,
0xdf, 0x3d, 0x5b, 0x2b, 0x3c, 0xc6, 0xdf, 0xef, 0xf8, 0xfb, 0x0b, 0x7f, 0x07, 0x45, 0xf3, 0x87,
0xe3, 0xc3, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xa4, 0x46, 0x7c, 0xf6, 0xcf, 0x0c, 0x00, 0x00,
// 1361 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x57, 0x4d, 0x6f, 0x1b, 0xb7,
0x16, 0xd5, 0xd8, 0x63, 0x59, 0xba, 0x23, 0x27, 0x0a, 0x91, 0x97, 0x4c, 0x94, 0x3c, 0x59, 0xd1,
0xcb, 0x4b, 0xdd, 0x02, 0x95, 0x5b, 0xb5, 0xc8, 0x47, 0xd3, 0xa2, 0x95, 0x25, 0xd5, 0x71, 0x53,
0x3b, 0x02, 0x9d, 0x04, 0xe8, 0x4a, 0xa0, 0x67, 0x68, 0x99, 0xf0, 0x68, 0x38, 0xe5, 0x70, 0x14,
0x78, 0xd7, 0x65, 0xe0, 0x45, 0x77, 0x5d, 0x7a, 0x55, 0xa0, 0xcb, 0x2e, 0xfb, 0x1b, 0xb2, 0xec,
0xa6, 0x40, 0x57, 0x41, 0xe3, 0x5f, 0x50, 0xa0, 0x7f, 0xa0, 0x20, 0x87, 0xfa, 0x6a, 0xc6, 0x49,
0x17, 0xd9, 0x91, 0x57, 0xe7, 0x1c, 0xde, 0xb9, 0x3c, 0xbc, 0xa4, 0xc0, 0x89, 0x23, 0xea, 0xc5,
0x8d, 0x48, 0x70, 0xc9, 0x11, 0xf2, 0xb9, 0x77, 0x48, 0x45, 0x23, 0x7e, 0x4a, 0xc4, 0xf0, 0x90,
0xc9, 0xc6, 0xe8, 0xc3, 0x8a, 0x23, 0x8f, 0x22, 0x6a, 0x00, 0x95, 0x8b, 0x03, 0x3e, 0xe0, 0x7a,
0xb8, 0xae, 0x46, 0x26, 0x7a, 0xd9, 0x4f, 0x04, 0x91, 0x8c, 0x87, 0xeb, 0xe3, 0x41, 0xfa, 0x43,
0xfd, 0x7b, 0x1b, 0x0a, 0x3b, 0xdc, 0xa7, 0xbb, 0x11, 0xf5, 0xd0, 0x26, 0x38, 0x24, 0x0c, 0xb9,
0xd4, 0x80, 0xd8, 0xb5, 0x6a, 0xd6, 0x9a, 0xd3, 0x5c, 0x6d, 0xbc, 0xba, 0x64, 0xa3, 0x35, 0x85,
0x6d, 0xd8, 0xcf, 0x5f, 0xac, 0xe6, 0xf0, 0x2c, 0x13, 0x7d, 0x00, 0xb6, 0xe0, 0x01, 0x75, 0x17,
0x6a, 0xd6, 0xda, 0xb9, 0xe6, 0xb5, 0x2c, 0x05, 0xb5, 0x28, 0xe6, 0x01, 0xc5, 0x1a, 0x89, 0x36,
0x01, 0x86, 0x74, 0xb8, 0x47, 0x45, 0x7c, 0xc0, 0x22, 0x77, 0x51, 0xf3, 0xde, 0x39, 0x8b, 0xa7,
0x92, 0x6d, 0x6c, 0x4f, 0xe0, 0x78, 0x86, 0x8a, 0xb6, 0xa1, 0x44, 0x46, 0x84, 0x05, 0x64, 0x8f,
0x05, 0x4c, 0x1e, 0xb9, 0xb6, 0x96, 0x7a, 0xf7, 0xb5, 0x52, 0xad, 0x19, 0x02, 0x9e, 0xa3, 0xd7,
0x7d, 0x80, 0xe9, 0x42, 0xe8, 0x26, 0x2c, 0xf7, 0xba, 0x3b, 0x9d, 0xad, 0x9d, 0xcd, 0x72, 0xae,
0x72, 0xe5, 0xf8, 0xa4, 0xf6, 0x1f, 0xa5, 0x31, 0x05, 0xf4, 0x68, 0xe8, 0xb3, 0x70, 0x80, 0xd6,
0xa0, 0xd0, 0x6a, 0xb7, 0xbb, 0xbd, 0x47, 0xdd, 0x4e, 0xd9, 0xaa, 0x54, 0x8e, 0x4f, 0x6a, 0x97,
0xe6, 0x81, 0x2d, 0xcf, 0xa3, 0x91, 0xa4, 0x7e, 0xc5, 0x7e, 0xf6, 0x63, 0x35, 0x57, 0x7f, 0x66,
0x41, 0x69, 0x36, 0x09, 0x74, 0x13, 0xf2, 0xad, 0xf6, 0xa3, 0xad, 0x27, 0xdd, 0x72, 0x6e, 0x4a,
0x9f, 0x45, 0xb4, 0x3c, 0xc9, 0x46, 0x14, 0xdd, 0x80, 0xa5, 0x5e, 0xeb, 0xf1, 0x6e, 0xb7, 0x6c,
0x4d, 0xd3, 0x99, 0x85, 0xf5, 0x48, 0x12, 0x6b, 0x54, 0x07, 0xb7, 0xb6, 0x76, 0xca, 0x0b, 0xd9,
0xa8, 0x8e, 0x20, 0x2c, 0x34, 0xa9, 0xfc, 0x62, 0x83, 0xb3, 0x4b, 0xc5, 0x88, 0x79, 0x6f, 0xd9,
0x13, 0xb7, 0xc0, 0x96, 0x24, 0x3e, 0xd4, 0x9e, 0x70, 0xb2, 0x3d, 0xf1, 0x88, 0xc4, 0x87, 0x6a,
0x51, 0x43, 0xd7, 0x78, 0xe5, 0x0c, 0x41, 0xa3, 0x80, 0x79, 0x44, 0x52, 0x5f, 0x3b, 0xc3, 0x69,
0xfe, 0x3f, 0x8b, 0x8d, 0x27, 0x28, 0x93, 0xff, 0xfd, 0x1c, 0x9e, 0xa1, 0xa2, 0x7b, 0x90, 0x1f,
0x04, 0x7c, 0x8f, 0x04, 0xda, 0x13, 0x4e, 0xf3, 0x7a, 0x96, 0xc8, 0xa6, 0x46, 0x4c, 0x05, 0x0c,
0x05, 0xdd, 0x81, 0x7c, 0x12, 0xf9, 0x44, 0x52, 0x37, 0xaf, 0xc9, 0xb5, 0x2c, 0xf2, 0x63, 0x8d,
0x68, 0xf3, 0x70, 0x9f, 0x0d, 0xb0, 0xc1, 0xa3, 0x5d, 0x28, 0x84, 0x54, 0x3e, 0xe5, 0xe2, 0x30,
0x76, 0x97, 0x6b, 0x8b, 0x6b, 0x4e, 0xf3, 0x76, 0x16, 0x77, 0xa6, 0xe6, 0x8d, 0x9d, 0x14, 0xdf,
0x92, 0x92, 0x78, 0x07, 0x43, 0x1a, 0x4a, 0x23, 0x39, 0x11, 0x42, 0x9f, 0x42, 0x81, 0x86, 0x7e,
0xc4, 0x59, 0x28, 0xdd, 0xc2, 0xd9, 0x09, 0x75, 0x0d, 0x46, 0xa9, 0xe2, 0x09, 0xa3, 0xf2, 0x00,
0x2e, 0x9f, 0xb1, 0x04, 0xba, 0x04, 0x79, 0x49, 0xc4, 0x80, 0x4a, 0xbd, 0xd3, 0x45, 0x6c, 0x66,
0xc8, 0x85, 0x65, 0x12, 0x30, 0x12, 0xd3, 0xd8, 0x5d, 0xa8, 0x2d, 0xae, 0x15, 0xf1, 0x78, 0xba,
0x91, 0x07, 0x7b, 0xc8, 0x7d, 0x5a, 0x5f, 0x87, 0x0b, 0xaf, 0xec, 0x00, 0xaa, 0x40, 0xc1, 0xec,
0x40, 0x6a, 0x1d, 0x1b, 0x4f, 0xe6, 0xf5, 0xf3, 0xb0, 0x32, 0x57, 0xed, 0xfa, 0x6f, 0x0b, 0x50,
0x18, 0x5b, 0x00, 0xb5, 0xa0, 0xe8, 0xf1, 0x50, 0x12, 0x16, 0x52, 0x61, 0x5c, 0x97, 0xb9, 0x61,
0xed, 0x31, 0x48, 0xb1, 0xee, 0xe7, 0xf0, 0x94, 0x85, 0xbe, 0x84, 0xa2, 0xa0, 0x31, 0x4f, 0x84,
0xa7, 0xb3, 0x56, 0x12, 0x6b, 0xd9, 0xc6, 0x49, 0x41, 0x98, 0x7e, 0x9b, 0x30, 0x41, 0x55, 0x35,
0x62, 0x3c, 0xa5, 0xa2, 0x7b, 0xb0, 0x2c, 0x68, 0x2c, 0x89, 0x90, 0xaf, 0x73, 0x0e, 0x4e, 0x21,
0x3d, 0x1e, 0x30, 0xef, 0x08, 0x8f, 0x19, 0xe8, 0x1e, 0x14, 0xa3, 0x80, 0x78, 0x5a, 0xd5, 0x5d,
0xd2, 0xf4, 0xff, 0x66, 0xd1, 0x7b, 0x63, 0x10, 0x9e, 0xe2, 0xd1, 0x5d, 0x80, 0x80, 0x0f, 0xfa,
0xbe, 0x60, 0x23, 0x2a, 0x8c, 0xf3, 0x2a, 0x59, 0xec, 0x8e, 0x46, 0xe0, 0x62, 0xc0, 0x07, 0xe9,
0x70, 0xa3, 0x08, 0xcb, 0x22, 0x09, 0x25, 0x1b, 0xd2, 0xfa, 0xcf, 0x36, 0xac, 0xcc, 0x95, 0x09,
0x5d, 0x84, 0x25, 0x36, 0x24, 0x03, 0x6a, 0x36, 0x39, 0x9d, 0xa0, 0x2e, 0xe4, 0x03, 0xb2, 0x47,
0x83, 0x74, 0x8b, 0x9d, 0xe6, 0xfb, 0x6f, 0xac, 0x77, 0xe3, 0x6b, 0x8d, 0xef, 0x86, 0x52, 0x1c,
0x61, 0x43, 0x56, 0x56, 0xf1, 0xf8, 0x70, 0x48, 0x42, 0x75, 0x5a, 0xb5, 0x55, 0xcc, 0x14, 0x21,
0xb0, 0x89, 0x18, 0xc4, 0xae, 0xad, 0xc3, 0x7a, 0x8c, 0xca, 0xb0, 0x48, 0xc3, 0x91, 0xbb, 0xa4,
0x43, 0x6a, 0xa8, 0x22, 0x3e, 0x4b, 0xbf, 0xb6, 0x88, 0xd5, 0x50, 0xf1, 0x92, 0x98, 0x0a, 0x77,
0x59, 0x87, 0xf4, 0x18, 0xdd, 0x86, 0xfc, 0x90, 0x27, 0xa1, 0x8c, 0xdd, 0x82, 0x4e, 0xf6, 0x4a,
0x56, 0xb2, 0xdb, 0x0a, 0x61, 0xba, 0x89, 0x81, 0xa3, 0xfb, 0x70, 0x21, 0x96, 0x3c, 0xea, 0x0f,
0x04, 0xf1, 0x68, 0x3f, 0xa2, 0x82, 0x71, 0xdf, 0x2d, 0x9e, 0xdd, 0x94, 0x3a, 0xe6, 0xc2, 0xc4,
0xe7, 0x15, 0x6d, 0x53, 0xb1, 0x7a, 0x9a, 0x84, 0x7a, 0x50, 0x8a, 0x92, 0x20, 0xe8, 0xf3, 0x28,
0xed, 0x8d, 0xa0, 0x45, 0xfe, 0x45, 0xd5, 0x7a, 0x49, 0x10, 0x3c, 0x4c, 0x49, 0xd8, 0x89, 0xa6,
0x13, 0x75, 0xfa, 0x06, 0x82, 0x27, 0x51, 0xec, 0x3a, 0xba, 0x1e, 0x66, 0x56, 0xb9, 0x0b, 0xce,
0x4c, 0xa5, 0x55, 0x85, 0x0e, 0xe9, 0x91, 0xd9, 0x3c, 0x35, 0x54, 0x1b, 0x3a, 0x22, 0x41, 0x92,
0xde, 0xb8, 0x45, 0x9c, 0x4e, 0x3e, 0x59, 0xb8, 0x63, 0x55, 0x9a, 0xe0, 0xcc, 0x2c, 0x87, 0xfe,
0x07, 0x2b, 0x82, 0x0e, 0x58, 0x2c, 0xc5, 0x51, 0x9f, 0x24, 0xf2, 0xc0, 0xfd, 0x42, 0x13, 0x4a,
0xe3, 0x60, 0x2b, 0x91, 0x07, 0xf5, 0xbf, 0x2c, 0x28, 0xcd, 0xb6, 0x0e, 0xd4, 0x4e, 0xcf, 0xb8,
0x5e, 0xf1, 0x5c, 0x73, 0xfd, 0x4d, 0xad, 0x46, 0x9f, 0xa8, 0x20, 0x51, 0x2b, 0x6e, 0xab, 0x6b,
0x5e, 0x93, 0xd1, 0xc7, 0xb0, 0x14, 0x71, 0x21, 0xc7, 0xee, 0xaa, 0x66, 0x9e, 0x02, 0x2e, 0xc6,
0xcd, 0x2e, 0x05, 0xd7, 0x0f, 0xe0, 0xdc, 0xbc, 0x1a, 0xba, 0x01, 0x8b, 0x4f, 0xb6, 0x7a, 0xe5,
0x5c, 0xe5, 0xea, 0xf1, 0x49, 0xed, 0xf2, 0xfc, 0x8f, 0x4f, 0x98, 0x90, 0x09, 0x09, 0xb6, 0x7a,
0xe8, 0x3d, 0x58, 0xea, 0xec, 0xec, 0x62, 0x5c, 0xb6, 0x2a, 0xab, 0xc7, 0x27, 0xb5, 0xab, 0xf3,
0x38, 0xf5, 0x13, 0x4f, 0x42, 0x1f, 0xf3, 0xbd, 0xc9, 0xcd, 0xf7, 0xc3, 0x02, 0x38, 0xa6, 0x2d,
0xbe, 0xdd, 0x9b, 0xef, 0x73, 0x58, 0x49, 0x4f, 0x70, 0xdf, 0xd3, 0x9f, 0x66, 0x7a, 0xd1, 0xeb,
0x0e, 0x72, 0x29, 0x25, 0x98, 0xa6, 0x7c, 0x1d, 0x4a, 0x2c, 0x1a, 0xdd, 0xea, 0xd3, 0x90, 0xec,
0x05, 0xe6, 0x12, 0x2c, 0x60, 0x47, 0xc5, 0xba, 0x69, 0x48, 0x35, 0x5a, 0x16, 0x4a, 0x2a, 0x42,
0x73, 0xbd, 0x15, 0xf0, 0x64, 0x8e, 0x3e, 0x03, 0x9b, 0x45, 0x64, 0x68, 0xba, 0x4f, 0xe6, 0x17,
0x6c, 0xf5, 0x5a, 0xdb, 0xc6, 0x22, 0x1b, 0x85, 0xd3, 0x17, 0xab, 0xb6, 0x0a, 0x60, 0x4d, 0xab,
0xff, 0x64, 0x83, 0xd3, 0x0e, 0x92, 0x58, 0x9a, 0xe6, 0xf1, 0xd6, 0xea, 0xf2, 0x0d, 0x5c, 0x20,
0xfa, 0x1d, 0x44, 0x42, 0x75, 0x12, 0x75, 0xe3, 0x34, 0xb5, 0xb9, 0x91, 0x29, 0x37, 0x01, 0xa7,
0x4d, 0x76, 0x23, 0xaf, 0x34, 0x5d, 0x0b, 0x97, 0xc9, 0x3f, 0x7e, 0x41, 0xbb, 0xb0, 0xc2, 0x85,
0x77, 0x40, 0x63, 0x99, 0x1e, 0x5e, 0xf3, 0x6e, 0xc8, 0x7c, 0x51, 0x3e, 0x9c, 0x05, 0xa6, 0x15,
0x37, 0xd9, 0xce, 0x6b, 0xa0, 0x3b, 0x60, 0x0b, 0xb2, 0x3f, 0xbe, 0x04, 0x32, 0xfd, 0x8b, 0xc9,
0xbe, 0x9c, 0x93, 0xd0, 0x0c, 0xf4, 0x15, 0x80, 0xcf, 0xe2, 0x88, 0x48, 0xef, 0x80, 0x0a, 0xb3,
0x0f, 0x99, 0x9f, 0xd8, 0x99, 0xa0, 0xe6, 0x54, 0x66, 0xd8, 0xe8, 0x01, 0x14, 0x3d, 0x32, 0x76,
0x52, 0xfe, 0xec, 0xbe, 0xd5, 0x6e, 0x19, 0x89, 0xb2, 0x92, 0x38, 0x7d, 0xb1, 0x5a, 0x18, 0x47,
0x70, 0xc1, 0x23, 0xc6, 0x59, 0x0f, 0x60, 0x45, 0x3d, 0xb2, 0xfa, 0x3e, 0xdd, 0x27, 0x49, 0x20,
0x63, 0xdd, 0x62, 0xcf, 0x78, 0x4c, 0xa8, 0xab, 0xb9, 0x63, 0x70, 0x26, 0xaf, 0x92, 0x9c, 0x8d,
0x5d, 0x7b, 0xfe, 0xb2, 0x9a, 0xfb, 0xfd, 0x65, 0x35, 0xf7, 0xe7, 0xcb, 0xaa, 0xf5, 0xdd, 0x69,
0xd5, 0x7a, 0x7e, 0x5a, 0xb5, 0x7e, 0x3d, 0xad, 0x5a, 0x7f, 0x9c, 0x56, 0xad, 0xbd, 0xbc, 0xfe,
0xc3, 0xf1, 0xd1, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa4, 0x46, 0x7c, 0xf6, 0xcf, 0x0c, 0x00,
0x00,
}

View file

@ -452,18 +452,18 @@ var (
)
var fileDescriptorTimestamp = []byte{
// 197 bytes of a gzipped FileDescriptorProto
// 205 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0xc9, 0xcc, 0x4d,
0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xc9, 0x4f,
0xce, 0x4e, 0x2d, 0xd2, 0x2b, 0x2e, 0x4f, 0x2c, 0xca, 0xcd, 0xce, 0x2c, 0xd1, 0x2b, 0x33, 0x54,
0xb2, 0xe6, 0xe2, 0x0c, 0x81, 0x29, 0x13, 0x92, 0xe0, 0x62, 0x2f, 0x4e, 0x4d, 0xce, 0xcf, 0x4b,
0x29, 0x96, 0x60, 0x54, 0x60, 0xd4, 0x60, 0x0e, 0x82, 0x71, 0x85, 0x44, 0xb8, 0x58, 0xf3, 0x12,
0xf3, 0xf2, 0x8b, 0x25, 0x98, 0x80, 0xe2, 0xac, 0x41, 0x10, 0x8e, 0x53, 0xc1, 0x89, 0x87, 0x72,
0x0c, 0x37, 0x80, 0xf8, 0xc3, 0x43, 0x39, 0xc6, 0x86, 0x47, 0x72, 0x8c, 0x27, 0x80, 0xf8, 0x02,
0x10, 0x3f, 0x00, 0x62, 0x2e, 0xe1, 0xe4, 0xfc, 0x5c, 0xbd, 0xf4, 0xfc, 0xfc, 0xf4, 0x9c, 0x54,
0x88, 0x03, 0x92, 0x4a, 0xd3, 0x9c, 0xf8, 0xe0, 0xb6, 0x05, 0x80, 0x84, 0x02, 0x18, 0x17, 0x30,
0x32, 0xfe, 0x60, 0x64, 0x5c, 0xc4, 0xc4, 0xec, 0x1e, 0xe0, 0xb4, 0x8a, 0x49, 0xce, 0x1d, 0xa2,
0x3e, 0x00, 0xaa, 0x5e, 0x2f, 0x3c, 0x35, 0x27, 0xc7, 0x3b, 0x2f, 0xbf, 0x3c, 0x2f, 0xa4, 0xb2,
0x20, 0xb5, 0x38, 0x89, 0x0d, 0x6c, 0x90, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x26, 0xaa, 0x11,
0xd7, 0xdc, 0x00, 0x00, 0x00,
0xf3, 0xf2, 0x8b, 0x25, 0x98, 0x14, 0x18, 0x35, 0x58, 0x83, 0x20, 0x1c, 0xa7, 0x82, 0x13, 0x0f,
0xe5, 0x18, 0x6e, 0x3c, 0x94, 0x63, 0xf8, 0xf0, 0x50, 0x8e, 0xb1, 0xe1, 0x91, 0x1c, 0xe3, 0x89,
0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0xc8, 0x25, 0x9c, 0x9c, 0x9f,
0xab, 0x97, 0x9e, 0x9f, 0x9f, 0x9e, 0x93, 0x0a, 0x71, 0x40, 0x52, 0x69, 0x9a, 0x13, 0x1f, 0xdc,
0xb6, 0x00, 0x90, 0x50, 0x00, 0xe3, 0x02, 0x46, 0xc6, 0x1f, 0x8c, 0x8c, 0x8b, 0x98, 0x98, 0xdd,
0x03, 0x9c, 0x56, 0x31, 0xc9, 0xb9, 0x43, 0xd4, 0x07, 0x40, 0xd5, 0xeb, 0x85, 0xa7, 0xe6, 0xe4,
0x78, 0xe7, 0xe5, 0x97, 0xe7, 0x85, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x0d, 0x32, 0x06,
0x04, 0x00, 0x00, 0xff, 0xff, 0x26, 0xaa, 0x11, 0xd7, 0xdc, 0x00, 0x00, 0x00,
}

View file

@ -11256,215 +11256,218 @@ var (
)
var fileDescriptorTypes = []byte{
// 3349 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x59, 0x4d, 0x6c, 0x1b, 0xd7,
0x11, 0x36, 0x7f, 0x45, 0x0e, 0x49, 0x99, 0x5e, 0x3b, 0x8e, 0xcc, 0x38, 0xb2, 0xb3, 0x89, 0x13,
0xe7, 0xa7, 0x4c, 0xac, 0xa4, 0x85, 0x93, 0xb4, 0x71, 0x96, 0x3f, 0xb2, 0x19, 0x4b, 0x14, 0xf1,
0x28, 0xca, 0x08, 0x0a, 0x94, 0x58, 0x91, 0x4f, 0xe2, 0x46, 0xcb, 0x5d, 0x76, 0x77, 0x29, 0x99,
0x2d, 0x0a, 0xb8, 0xbd, 0xb4, 0xc8, 0xa9, 0xf7, 0x22, 0x08, 0x8a, 0x16, 0xbd, 0xf5, 0xd0, 0x53,
0x81, 0x9e, 0x7c, 0xf4, 0x31, 0x45, 0x81, 0x22, 0x68, 0x81, 0xa0, 0x49, 0x8f, 0xbd, 0x04, 0xe8,
0x21, 0x87, 0xf6, 0xd0, 0x79, 0x3f, 0xfb, 0x43, 0x7a, 0xad, 0x28, 0x4d, 0x0e, 0x82, 0xf6, 0xcd,
0xfb, 0x66, 0xde, 0xdf, 0xbc, 0x99, 0x6f, 0x1e, 0xa1, 0xe0, 0xcd, 0x26, 0xd4, 0xad, 0x4e, 0x1c,
0xdb, 0xb3, 0x15, 0x65, 0x68, 0x0f, 0x0e, 0xa8, 0x53, 0x75, 0x8f, 0x74, 0x67, 0x7c, 0x60, 0x78,
0xd5, 0xc3, 0x6b, 0x95, 0x0b, 0x9e, 0x31, 0xa6, 0xae, 0xa7, 0x8f, 0x27, 0x2f, 0x07, 0x5f, 0x02,
0x5e, 0x79, 0x7c, 0x38, 0x75, 0x74, 0xcf, 0xb0, 0xad, 0x97, 0xfd, 0x0f, 0xd9, 0x71, 0x6e, 0xdf,
0xde, 0xb7, 0xf9, 0xe7, 0xcb, 0xec, 0x4b, 0x48, 0xd5, 0x4b, 0xb0, 0xb4, 0x43, 0x1d, 0x17, 0x61,
0xca, 0x39, 0xc8, 0x18, 0xd6, 0x90, 0xde, 0x5d, 0x49, 0x5c, 0x4e, 0x5c, 0x4d, 0x13, 0xd1, 0x50,
0x7f, 0x9d, 0x80, 0x82, 0x66, 0x59, 0xb6, 0xc7, 0x6d, 0xb9, 0x8a, 0x02, 0x69, 0x4b, 0x1f, 0x53,
0x0e, 0xca, 0x13, 0xfe, 0xad, 0xd4, 0x21, 0x6b, 0xea, 0xbb, 0xd4, 0x74, 0x57, 0x92, 0x97, 0x53,
0x57, 0x0b, 0x6b, 0x2f, 0x56, 0x1f, 0x9e, 0x73, 0x35, 0x62, 0xa4, 0xba, 0xc1, 0xd1, 0x4d, 0xcb,
0x73, 0x66, 0x44, 0xaa, 0x56, 0x5e, 0x87, 0x42, 0x44, 0xac, 0x94, 0x21, 0x75, 0x40, 0x67, 0x72,
0x18, 0xf6, 0xc9, 0xe6, 0x77, 0xa8, 0x9b, 0x53, 0x8a, 0x83, 0x30, 0x99, 0x68, 0xbc, 0x91, 0xbc,
0x9e, 0x50, 0xdf, 0x85, 0x3c, 0xa1, 0xae, 0x3d, 0x75, 0x06, 0xd4, 0x55, 0x9e, 0x87, 0xbc, 0xa5,
0x5b, 0x76, 0x7f, 0x30, 0x99, 0xba, 0x5c, 0x3d, 0x55, 0x2b, 0x7e, 0xf6, 0xc9, 0xa5, 0x5c, 0x1b,
0x85, 0xf5, 0x4e, 0xcf, 0x25, 0x39, 0xd6, 0x5d, 0xc7, 0x5e, 0xe5, 0x29, 0x28, 0x8e, 0xe9, 0xd8,
0x76, 0x66, 0xfd, 0xdd, 0x99, 0x47, 0x5d, 0x6e, 0x38, 0x45, 0x0a, 0x42, 0x56, 0x63, 0x22, 0xf5,
0x97, 0x09, 0x38, 0xe7, 0xdb, 0x26, 0xf4, 0x87, 0x53, 0xc3, 0xa1, 0x63, 0x6a, 0x79, 0xae, 0xf2,
0x6d, 0x5c, 0xb3, 0x31, 0x36, 0x3c, 0x31, 0x46, 0x61, 0xed, 0xc9, 0xb8, 0x35, 0x07, 0xb3, 0x22,
0x12, 0xac, 0x68, 0x50, 0x74, 0xa8, 0x4b, 0x9d, 0x43, 0xb1, 0x13, 0x7c, 0xc8, 0x2f, 0x55, 0x9e,
0x53, 0x51, 0xd7, 0x21, 0xd7, 0x31, 0x75, 0x6f, 0xcf, 0x76, 0xc6, 0x8a, 0x0a, 0x45, 0xdd, 0x19,
0x8c, 0x0c, 0x8f, 0x0e, 0xbc, 0xa9, 0xe3, 0x9f, 0xca, 0x9c, 0x4c, 0x39, 0x0f, 0x49, 0x5b, 0x0c,
0x94, 0xaf, 0x65, 0x71, 0x27, 0x92, 0x5b, 0x5d, 0x82, 0x12, 0xf5, 0x4d, 0x38, 0xd3, 0x31, 0xa7,
0xfb, 0x86, 0xd5, 0xa0, 0xee, 0xc0, 0x31, 0x26, 0xcc, 0x3a, 0x3b, 0x5e, 0xe6, 0x7c, 0xfe, 0xf1,
0xb2, 0xef, 0xe0, 0xc8, 0x93, 0xe1, 0x91, 0xab, 0x3f, 0x4f, 0xc2, 0x99, 0xa6, 0x85, 0xca, 0x34,
0xaa, 0x7d, 0x05, 0x96, 0x29, 0x17, 0xf6, 0x0f, 0x85, 0x53, 0x49, 0x3b, 0x25, 0x21, 0xf5, 0x3d,
0xad, 0xb5, 0xe0, 0x2f, 0xd7, 0xe2, 0x96, 0xff, 0x90, 0xf5, 0x38, 0xaf, 0x51, 0x9a, 0xb0, 0x34,
0xe1, 0x8b, 0x70, 0x57, 0x52, 0xdc, 0xd6, 0x95, 0x38, 0x5b, 0x0f, 0xad, 0xb3, 0x96, 0x7e, 0xf0,
0xc9, 0xa5, 0x53, 0xc4, 0xd7, 0xfd, 0x3a, 0xce, 0xf7, 0xcf, 0x04, 0x9c, 0x6e, 0xdb, 0xc3, 0xb9,
0x7d, 0xa8, 0x40, 0x6e, 0x64, 0xbb, 0x5e, 0xe4, 0xa2, 0x04, 0x6d, 0xe5, 0x3a, 0xe4, 0x26, 0xf2,
0xf8, 0xe4, 0xe9, 0x5f, 0x8c, 0x9f, 0xb2, 0xc0, 0x90, 0x00, 0xad, 0xbc, 0x09, 0x79, 0xc7, 0xf7,
0x09, 0x5c, 0xed, 0x09, 0x1c, 0x27, 0xc4, 0x2b, 0xdf, 0x83, 0xac, 0x38, 0x84, 0x95, 0x34, 0xd7,
0xbc, 0x72, 0xa2, 0x3d, 0x27, 0x52, 0x49, 0xfd, 0x38, 0x01, 0x65, 0xa2, 0xef, 0x79, 0x9b, 0x74,
0xbc, 0x4b, 0x9d, 0x2e, 0x5e, 0x64, 0xbc, 0x3f, 0xe7, 0xf1, 0x1c, 0xa9, 0x3e, 0xa4, 0x0e, 0x5f,
0x64, 0x8e, 0xc8, 0x96, 0xd2, 0x63, 0x4e, 0xae, 0x0f, 0x46, 0xfa, 0xae, 0x61, 0x1a, 0xde, 0x8c,
0x2f, 0x73, 0x39, 0xfe, 0x94, 0x17, 0x6d, 0xe2, 0xe4, 0x43, 0x45, 0x32, 0x67, 0x46, 0x59, 0x81,
0x25, 0x8c, 0x75, 0xae, 0xbe, 0x4f, 0xf9, 0xea, 0xf3, 0xc4, 0x6f, 0xa2, 0x2b, 0x17, 0xa3, 0x7a,
0x4a, 0x01, 0x96, 0x7a, 0xed, 0xdb, 0xed, 0xad, 0x3b, 0xed, 0xf2, 0x29, 0xe5, 0x34, 0x14, 0x7a,
0x6d, 0xd2, 0xd4, 0xea, 0xb7, 0xb4, 0xda, 0x46, 0xb3, 0x9c, 0x50, 0x4a, 0x18, 0x2e, 0x82, 0x66,
0x52, 0xfd, 0x30, 0x01, 0xc0, 0x0e, 0x50, 0x2e, 0xea, 0x0d, 0xc8, 0x60, 0x3c, 0xf5, 0xc4, 0xc1,
0x2d, 0xaf, 0x3d, 0x13, 0x37, 0xeb, 0x10, 0x5e, 0x65, 0xff, 0x28, 0x11, 0x2a, 0xd1, 0x19, 0x26,
0x17, 0x67, 0x98, 0xe1, 0xc8, 0xf9, 0xa9, 0xe5, 0x20, 0xdd, 0x60, 0x5f, 0x09, 0x25, 0x0f, 0x19,
0x9c, 0x53, 0xe3, 0xdd, 0x72, 0x12, 0x9d, 0xaf, 0xd8, 0x68, 0x75, 0xeb, 0x5b, 0xed, 0x76, 0xb3,
0xbe, 0xdd, 0x6c, 0x94, 0x53, 0xea, 0x15, 0xc8, 0xb4, 0xc6, 0x68, 0x45, 0xb9, 0xc8, 0x3c, 0x60,
0x8f, 0x3a, 0xd4, 0x1a, 0xf8, 0x8e, 0x15, 0x0a, 0xd4, 0x8f, 0xd0, 0xc8, 0xa6, 0x3d, 0xb5, 0x3c,
0x65, 0x2d, 0x72, 0x8b, 0x97, 0xd7, 0x56, 0xe3, 0x96, 0xc0, 0x81, 0xd5, 0x6d, 0x44, 0xc9, 0x5b,
0x8e, 0x87, 0x29, 0x7c, 0x45, 0x4e, 0x5d, 0xb6, 0x98, 0xdc, 0xd3, 0x9d, 0x7d, 0xea, 0xc9, 0x4d,
0x97, 0x2d, 0xe5, 0x2a, 0xe4, 0xf0, 0x74, 0x86, 0xb6, 0x65, 0xce, 0xb8, 0x4b, 0xe5, 0x44, 0x98,
0xc5, 0x73, 0x18, 0x6e, 0xa1, 0x8c, 0x04, 0xbd, 0xca, 0x2d, 0x28, 0xee, 0x62, 0x32, 0xe9, 0xdb,
0x13, 0x11, 0xf3, 0x32, 0x8f, 0x76, 0x40, 0x31, 0xab, 0x1a, 0xa2, 0xb7, 0x04, 0x98, 0x14, 0x76,
0xc3, 0x86, 0xd2, 0x86, 0xe5, 0x43, 0xdb, 0x9c, 0x8e, 0x69, 0x60, 0x2b, 0xcb, 0x6d, 0x3d, 0xf7,
0x68, 0x5b, 0x3b, 0x1c, 0xef, 0x5b, 0x2b, 0x1d, 0x46, 0x9b, 0xca, 0x6d, 0x28, 0x79, 0xe3, 0xc9,
0x9e, 0x1b, 0x98, 0x5b, 0xe2, 0xe6, 0x9e, 0x3d, 0x66, 0xc3, 0x18, 0xdc, 0xb7, 0x56, 0xf4, 0x22,
0xad, 0xca, 0xcf, 0x52, 0x50, 0x88, 0xcc, 0x5c, 0xe9, 0x42, 0x01, 0x73, 0xec, 0x44, 0xdf, 0xe7,
0x71, 0x5b, 0x9e, 0xc5, 0xb5, 0x13, 0xad, 0xba, 0xda, 0x09, 0x15, 0x49, 0xd4, 0x8a, 0xfa, 0x41,
0x12, 0x0a, 0x91, 0x4e, 0xe5, 0x05, 0xc8, 0x91, 0x0e, 0x69, 0xed, 0x68, 0xdb, 0xcd, 0xf2, 0xa9,
0xca, 0xc5, 0xf7, 0x3f, 0xb8, 0xbc, 0xc2, 0xad, 0x45, 0x0d, 0x74, 0x1c, 0xe3, 0x90, 0xb9, 0xde,
0x55, 0x58, 0xf2, 0xa1, 0x89, 0xca, 0x13, 0x08, 0x7d, 0x7c, 0x11, 0x1a, 0x41, 0x92, 0xee, 0x2d,
0x8d, 0xa0, 0xf7, 0x25, 0xe3, 0x91, 0xa4, 0x3b, 0xd2, 0x1d, 0x3a, 0x54, 0x9e, 0x85, 0xac, 0x04,
0xa6, 0x2a, 0x15, 0x04, 0x9e, 0x5f, 0x04, 0x86, 0x38, 0xd2, 0xdd, 0xd0, 0x76, 0x9a, 0xe5, 0x74,
0x3c, 0x8e, 0x74, 0x4d, 0xfd, 0x90, 0x2a, 0xcf, 0xe0, 0x3d, 0xe1, 0xb0, 0x4c, 0xe5, 0x02, 0xc2,
0x1e, 0x7b, 0xc8, 0x1c, 0x43, 0x55, 0x56, 0x7e, 0xf1, 0x9b, 0xd5, 0x53, 0x7f, 0xfa, 0xed, 0x6a,
0x79, 0xb1, 0xbb, 0xf2, 0xdf, 0x04, 0x94, 0xe6, 0x8e, 0x1c, 0x53, 0x64, 0xd6, 0xb2, 0x07, 0xf6,
0x44, 0x84, 0xf3, 0x5c, 0x0d, 0xd0, 0x4b, 0xb3, 0x6d, 0xbb, 0x8e, 0x12, 0x22, 0x7b, 0xd0, 0x0f,
0xe6, 0x13, 0xd2, 0xab, 0x27, 0xf4, 0xa7, 0xd8, 0x94, 0x74, 0x03, 0x4a, 0x43, 0xdc, 0x47, 0xea,
0xf4, 0x07, 0xb6, 0xb5, 0x67, 0xec, 0xcb, 0x50, 0x5d, 0x89, 0xb3, 0xd9, 0xe0, 0x40, 0x52, 0x14,
0x0a, 0x75, 0x8e, 0xff, 0x1a, 0xc9, 0xa8, 0xb2, 0x03, 0xc5, 0xa8, 0x87, 0x2a, 0x4f, 0x02, 0xb8,
0xc6, 0x8f, 0xa8, 0xe4, 0x37, 0x9c, 0x0d, 0x91, 0x3c, 0x93, 0x70, 0x76, 0xa3, 0x3c, 0x07, 0xe9,
0x31, 0x86, 0x32, 0x6e, 0x27, 0x53, 0x3b, 0xcb, 0x72, 0xe2, 0xdf, 0x3e, 0xb9, 0x54, 0xb0, 0xdd,
0xea, 0xba, 0x61, 0xd2, 0x4d, 0xec, 0x22, 0x1c, 0xa0, 0x1e, 0x42, 0x9a, 0x85, 0x0a, 0xe5, 0x09,
0x48, 0xd7, 0x5a, 0xed, 0x06, 0xba, 0xda, 0x19, 0x3c, 0x9d, 0x12, 0xdf, 0x12, 0xd6, 0xc1, 0x7c,
0x57, 0xb9, 0x04, 0xd9, 0x9d, 0xad, 0x8d, 0xde, 0x26, 0x73, 0xaf, 0xb3, 0xd8, 0x7d, 0x3a, 0xe8,
0x16, 0x9b, 0x86, 0xb3, 0xc9, 0x6c, 0x6f, 0x76, 0xd6, 0xbb, 0xe8, 0x54, 0x0a, 0xf6, 0x2f, 0x07,
0xfd, 0x7c, 0xce, 0x95, 0x33, 0xf2, 0x54, 0xf3, 0x81, 0x5c, 0xfd, 0x4f, 0x12, 0x4a, 0x84, 0xf1,
0x5b, 0xc7, 0xeb, 0xd8, 0xa6, 0x31, 0x98, 0x29, 0x1d, 0xc8, 0xe3, 0xb6, 0x0e, 0x8d, 0xc8, 0x9d,
0x5a, 0x7b, 0x44, 0x12, 0x0c, 0xb5, 0xfc, 0x56, 0xdd, 0xd7, 0x24, 0xa1, 0x11, 0x0c, 0x96, 0x99,
0x21, 0x35, 0xf5, 0xd9, 0x71, 0xd9, 0xb8, 0x21, 0xb9, 0x34, 0x11, 0x50, 0xce, 0x1c, 0xf5, 0xbb,
0x7d, 0xdd, 0xf3, 0xe8, 0x78, 0xe2, 0x89, 0x6c, 0x9c, 0x46, 0xe6, 0xa8, 0xdf, 0xd5, 0xa4, 0x48,
0x79, 0x0d, 0xb2, 0x47, 0xb8, 0x2b, 0xf6, 0x91, 0x4c, 0xb8, 0xc7, 0xdb, 0x95, 0x58, 0xf5, 0x7d,
0x96, 0x67, 0x17, 0x26, 0xcb, 0x76, 0xbd, 0xbd, 0xd5, 0x6e, 0xfa, 0xbb, 0x2e, 0xfb, 0xb7, 0xac,
0xb6, 0x6d, 0xb1, 0x1b, 0x03, 0x5b, 0xed, 0xfe, 0xba, 0xd6, 0xda, 0xe8, 0x11, 0xb6, 0xf3, 0xe7,
0x10, 0x52, 0x0e, 0x20, 0xeb, 0xba, 0x61, 0x32, 0x12, 0x78, 0x01, 0x52, 0x5a, 0x1b, 0xb3, 0x4b,
0xa5, 0x8c, 0xdd, 0xc5, 0xa0, 0x5b, 0xb3, 0x66, 0xe1, 0x65, 0x5a, 0x1c, 0x57, 0xfd, 0x57, 0x02,
0x8a, 0xbd, 0xc9, 0x10, 0x23, 0x82, 0xf0, 0x4c, 0xe5, 0x32, 0x86, 0x34, 0xdd, 0xd1, 0x4d, 0x93,
0x9a, 0x86, 0x3b, 0x96, 0x85, 0x42, 0x54, 0x84, 0xec, 0xe6, 0xe4, 0x9b, 0x29, 0x49, 0x98, 0xdc,
0xd2, 0x1e, 0x2c, 0xef, 0x89, 0xc9, 0xf6, 0xf5, 0x01, 0x3f, 0xdd, 0x14, 0x3f, 0xdd, 0x6a, 0x9c,
0x89, 0xe8, 0xac, 0xaa, 0x72, 0x8d, 0x1a, 0xd7, 0x22, 0xa5, 0xbd, 0x68, 0x53, 0xbd, 0x0a, 0xa5,
0xb9, 0x7e, 0x96, 0x69, 0x3b, 0x5a, 0xaf, 0x8b, 0xbb, 0xa9, 0x14, 0x21, 0x87, 0x69, 0x76, 0xbb,
0xd5, 0xee, 0xe1, 0xc6, 0xa9, 0x7f, 0x48, 0xfa, 0xab, 0x95, 0x4c, 0xa0, 0x36, 0xcf, 0x04, 0x5e,
0x7a, 0xf4, 0x44, 0x24, 0x17, 0x08, 0x1b, 0x01, 0x23, 0xf8, 0x2e, 0x5e, 0x40, 0xb6, 0xa9, 0x74,
0x88, 0xce, 0x72, 0x1c, 0xdb, 0xdf, 0xf6, 0xeb, 0x38, 0xbc, 0x9f, 0x42, 0x41, 0xf3, 0x94, 0xb7,
0xa1, 0x38, 0xb0, 0xc7, 0x13, 0x93, 0x4a, 0xfd, 0xd4, 0x49, 0xf4, 0x0b, 0x81, 0x0a, 0x5a, 0x88,
0x30, 0x92, 0xf4, 0x3c, 0x23, 0xa9, 0x23, 0x2d, 0x0a, 0xe7, 0x3b, 0xcf, 0x4b, 0x70, 0x63, 0x7a,
0x9d, 0x86, 0x86, 0x3b, 0x73, 0x13, 0xb9, 0x09, 0x40, 0x96, 0xef, 0x18, 0x26, 0x03, 0xc6, 0x9d,
0xea, 0x5b, 0x9b, 0x9d, 0x8d, 0xa6, 0x60, 0x26, 0x3f, 0x81, 0xd3, 0x78, 0x08, 0x9e, 0x8e, 0x14,
0xd1, 0x27, 0x85, 0x6b, 0x6c, 0xce, 0x52, 0xd4, 0x37, 0x86, 0x22, 0x6e, 0xd5, 0x4e, 0x63, 0xd4,
0x2d, 0x04, 0xd0, 0x56, 0x83, 0xcd, 0xd2, 0x6f, 0x0c, 0x99, 0x77, 0x4e, 0x10, 0x2a, 0xc2, 0xd0,
0x12, 0x42, 0x53, 0x1d, 0x84, 0x30, 0x19, 0xfa, 0x7e, 0x9e, 0xde, 0x35, 0x3c, 0x8c, 0xa5, 0x43,
0x41, 0xfb, 0x32, 0x24, 0xc7, 0x04, 0x75, 0x16, 0x96, 0x7e, 0x9a, 0x04, 0xd8, 0xd6, 0xdd, 0x03,
0x39, 0x34, 0x12, 0xe4, 0xa0, 0x1c, 0x3e, 0xae, 0x2c, 0x8b, 0xec, 0x75, 0x80, 0x57, 0x5e, 0xf5,
0x4f, 0x5b, 0xb0, 0xd5, 0x78, 0x45, 0x39, 0x56, 0x1c, 0xe1, 0x9b, 0xa7, 0xa4, 0x2c, 0x6a, 0x53,
0xc7, 0x91, 0x9b, 0xce, 0x3e, 0xb1, 0x4a, 0xce, 0x07, 0x6b, 0x96, 0x1c, 0xe8, 0xe9, 0xb8, 0x41,
0x16, 0x36, 0xf4, 0xd6, 0x29, 0x12, 0xea, 0xd5, 0xca, 0xb0, 0xec, 0x60, 0x70, 0xc4, 0x59, 0xf7,
0x5d, 0xde, 0xad, 0xfe, 0x05, 0xf7, 0xa0, 0xd5, 0xd1, 0x36, 0xe5, 0x15, 0x6d, 0x40, 0x76, 0x4f,
0x1f, 0x1b, 0xe6, 0xec, 0x38, 0xaf, 0x0d, 0xf1, 0x55, 0x6d, 0x38, 0xc4, 0x22, 0xc1, 0x5d, 0xe7,
0x3a, 0x44, 0xea, 0x72, 0x32, 0x38, 0xdd, 0xb5, 0xa8, 0x17, 0x90, 0x41, 0xde, 0x62, 0x99, 0xc7,
0xd1, 0xad, 0x60, 0xb5, 0xa2, 0xc1, 0x76, 0x01, 0xd3, 0x2f, 0x3d, 0xd2, 0x67, 0xbe, 0x93, 0xc9,
0x26, 0x52, 0xbf, 0x9c, 0xa8, 0x5d, 0xe9, 0x10, 0x97, 0xcc, 0x52, 0xeb, 0x97, 0xcd, 0x87, 0x48,
0xb8, 0xc8, 0xa9, 0x81, 0x76, 0xe5, 0x4d, 0x9e, 0x08, 0xc2, 0xae, 0xaf, 0x54, 0xa3, 0xbd, 0x02,
0xa5, 0xb9, 0x75, 0x3e, 0xc4, 0xc2, 0x5b, 0x9d, 0x9d, 0xd7, 0xca, 0x69, 0xf9, 0xf5, 0x9d, 0x72,
0x56, 0xfd, 0x37, 0x16, 0x05, 0x1d, 0x9b, 0x07, 0x43, 0xb6, 0xab, 0xf1, 0xaf, 0x1e, 0x39, 0xfe,
0x86, 0x32, 0xb0, 0x4d, 0xe9, 0x33, 0xb1, 0x34, 0x34, 0xb4, 0xc2, 0x58, 0x1d, 0x87, 0x93, 0x40,
0x11, 0x73, 0x66, 0x41, 0xf0, 0xe9, 0xfe, 0x04, 0x71, 0x7c, 0x5b, 0x4b, 0x04, 0x84, 0x88, 0x69,
0xb2, 0x92, 0x7a, 0x32, 0xdd, 0xc5, 0xd8, 0x3a, 0xc2, 0x10, 0xc0, 0x31, 0x69, 0x8e, 0x29, 0x05,
0x52, 0x06, 0x53, 0x1b, 0x90, 0xf3, 0xad, 0xe3, 0x71, 0xa4, 0xb6, 0xeb, 0x1d, 0xcc, 0x16, 0xa7,
0x31, 0xd6, 0x17, 0x7c, 0x31, 0x8a, 0x58, 0x4f, 0xaf, 0xd1, 0xc1, 0x24, 0x31, 0xd7, 0x83, 0xa2,
0x4a, 0x9a, 0x25, 0x01, 0xf5, 0x57, 0x09, 0xc8, 0x0a, 0x4a, 0x12, 0xbb, 0x62, 0x0d, 0x96, 0x7c,
0xa2, 0x2c, 0x78, 0xd2, 0x73, 0x8f, 0xe6, 0x34, 0x55, 0x49, 0x41, 0xc4, 0x39, 0xfa, 0x7a, 0x95,
0x37, 0xa0, 0x18, 0xed, 0xf8, 0x4a, 0xa7, 0xf8, 0x63, 0x28, 0x30, 0x47, 0xf1, 0xb9, 0xcd, 0x1a,
0x64, 0x05, 0x6d, 0x92, 0x57, 0xfd, 0x38, 0x82, 0x25, 0x91, 0x98, 0x9e, 0x96, 0x04, 0x29, 0xf3,
0x9f, 0x0b, 0x56, 0x8f, 0x77, 0x47, 0xe2, 0xc3, 0xd5, 0x1b, 0x90, 0xee, 0x50, 0xb4, 0xf0, 0x34,
0x2c, 0x59, 0x18, 0x7a, 0xc2, 0xc8, 0x26, 0xf9, 0xe4, 0x90, 0x62, 0xc4, 0xca, 0xb2, 0x2e, 0x8c,
0x67, 0xb8, 0x79, 0x3a, 0xfa, 0x9b, 0xff, 0x62, 0xc2, 0xbe, 0xd5, 0x6d, 0x28, 0xde, 0xa1, 0xc6,
0xfe, 0x08, 0xe3, 0x32, 0x37, 0xf4, 0x12, 0xa4, 0x27, 0x34, 0x98, 0xfc, 0x4a, 0xac, 0xeb, 0x60,
0x3f, 0xe1, 0x28, 0x76, 0x21, 0x8f, 0xb8, 0xb6, 0x7c, 0xa4, 0x92, 0x2d, 0xf5, 0xf7, 0x49, 0x58,
0x6e, 0xb9, 0xee, 0x54, 0xc7, 0x02, 0x50, 0x46, 0xc1, 0xb7, 0xe6, 0xd3, 0xd6, 0xd5, 0xd8, 0x15,
0xce, 0xa9, 0xcc, 0x17, 0xb1, 0x32, 0x72, 0x25, 0x83, 0xc8, 0xa5, 0x3e, 0x48, 0xf8, 0xd5, 0xeb,
0x95, 0xc8, 0xbd, 0xa9, 0xac, 0xa0, 0x13, 0x9d, 0x8b, 0x5a, 0xa2, 0x3d, 0xeb, 0xc0, 0xb2, 0x8f,
0x2c, 0xa4, 0x47, 0x58, 0xcd, 0xb6, 0x9b, 0x77, 0xd0, 0xd3, 0xce, 0x23, 0x48, 0x99, 0x03, 0x11,
0x6a, 0xd1, 0x23, 0x66, 0xa9, 0xd3, 0x6c, 0x37, 0x58, 0x86, 0x49, 0xc6, 0x58, 0xea, 0x50, 0x24,
0x21, 0xd6, 0x3e, 0x6e, 0x77, 0xb6, 0xd5, 0xed, 0xf6, 0x78, 0x7d, 0xf1, 0x38, 0xa2, 0xce, 0xce,
0xa1, 0x58, 0x03, 0x8b, 0x0b, 0x04, 0x31, 0xfe, 0x83, 0xa0, 0x74, 0x0c, 0x88, 0xa5, 0x7f, 0x0c,
0x20, 0xc2, 0xc3, 0xff, 0x9e, 0x84, 0xb2, 0x36, 0x18, 0xd0, 0x89, 0xc7, 0xfa, 0x25, 0xa7, 0xdc,
0xc6, 0x9b, 0xcc, 0xbe, 0x0c, 0xce, 0x91, 0x99, 0x5b, 0x5c, 0x8f, 0x7d, 0xc1, 0x5c, 0xd0, 0xab,
0x12, 0xdb, 0xa4, 0xda, 0x70, 0x6c, 0xb8, 0xec, 0x55, 0x4b, 0xc8, 0x48, 0x60, 0xa9, 0xf2, 0x79,
0x02, 0xce, 0xc6, 0x20, 0x94, 0x57, 0x20, 0xed, 0xa0, 0x58, 0x1e, 0xcf, 0xc5, 0x47, 0xbd, 0x2f,
0x30, 0x55, 0xc2, 0x91, 0xca, 0x2a, 0x80, 0x3e, 0xf5, 0x6c, 0x9d, 0x8f, 0xcf, 0x0f, 0x26, 0x47,
0x22, 0x12, 0xe5, 0x0e, 0x46, 0x6b, 0x3a, 0x70, 0xa8, 0x4f, 0x10, 0x6e, 0xfc, 0xbf, 0xb3, 0xaf,
0x76, 0xb9, 0x19, 0x22, 0xcd, 0x55, 0xaa, 0x58, 0xdd, 0xf1, 0x2f, 0xe6, 0xd1, 0xc8, 0x15, 0x74,
0x3e, 0xe9, 0x22, 0xe1, 0xdf, 0xcc, 0x51, 0x74, 0x73, 0xdf, 0x77, 0x14, 0xfc, 0x54, 0x3f, 0xc4,
0x5c, 0xd4, 0xbc, 0xeb, 0x51, 0xc7, 0xd2, 0xcd, 0xba, 0xa6, 0x34, 0x23, 0x11, 0x52, 0xac, 0xf6,
0xf9, 0xd8, 0x57, 0xa7, 0x40, 0xa3, 0x5a, 0xd7, 0x62, 0x62, 0x24, 0xb2, 0x83, 0xa9, 0x63, 0xca,
0x17, 0x4c, 0xce, 0x0e, 0x7a, 0x64, 0x83, 0x30, 0x19, 0x7b, 0xfe, 0xf3, 0x23, 0x52, 0xea, 0xd1,
0x4f, 0xcf, 0x91, 0x01, 0xbe, 0xf9, 0xa8, 0xf4, 0x12, 0x40, 0x38, 0x6b, 0x3c, 0xaa, 0x4c, 0x7d,
0xbd, 0xdb, 0xdd, 0xc0, 0xeb, 0xc1, 0x4b, 0xa0, 0xb0, 0x8b, 0x8b, 0xd5, 0xdf, 0x25, 0x90, 0x73,
0x6a, 0x32, 0xab, 0xac, 0x43, 0x99, 0xc7, 0x92, 0x01, 0x75, 0xbc, 0x3e, 0xbd, 0x3b, 0x31, 0x9c,
0x99, 0x0c, 0x07, 0xc7, 0x17, 0x0b, 0xcb, 0x4c, 0xab, 0x8e, 0x4a, 0x4d, 0xae, 0xa3, 0x10, 0x28,
0x52, 0xb9, 0xc4, 0xfe, 0x40, 0xf7, 0x83, 0xf3, 0xea, 0xf1, 0x5b, 0x21, 0x28, 0x59, 0xd8, 0x76,
0x49, 0xc1, 0x37, 0x52, 0xd7, 0x5d, 0x75, 0x07, 0xce, 0x6e, 0x39, 0x83, 0x11, 0x92, 0x23, 0x31,
0xa8, 0x9c, 0xf2, 0x0d, 0xb8, 0xe8, 0x21, 0x09, 0xea, 0x8f, 0x0c, 0xd7, 0x63, 0x0f, 0xe7, 0xe8,
0x1b, 0xd4, 0x62, 0xfd, 0x7d, 0xfe, 0xc0, 0x2d, 0x4b, 0xcc, 0x0b, 0x0c, 0x73, 0x4b, 0x40, 0x88,
0x8f, 0xd8, 0x60, 0x00, 0xb5, 0x85, 0x15, 0x2a, 0x76, 0x36, 0xe8, 0x9e, 0x3e, 0x35, 0xb1, 0x4c,
0x7a, 0x1d, 0xc0, 0xb4, 0xf7, 0xfb, 0x27, 0x8e, 0xe4, 0x79, 0x44, 0x8b, 0x4f, 0xf5, 0xfb, 0x50,
0x6e, 0x18, 0xee, 0x44, 0xf7, 0x70, 0x9a, 0xb2, 0x76, 0x56, 0x6e, 0x42, 0x79, 0x44, 0x91, 0x3e,
0xef, 0x52, 0x1d, 0x53, 0x2a, 0x75, 0x0c, 0x7b, 0x78, 0xa2, 0x2d, 0x3d, 0x1d, 0x68, 0x75, 0xb8,
0x92, 0xfa, 0x05, 0x12, 0x00, 0xf6, 0x38, 0x29, 0xed, 0xbe, 0x08, 0x67, 0x5c, 0x4b, 0x9f, 0xb8,
0x23, 0xdb, 0xeb, 0x1b, 0x96, 0xc7, 0x5e, 0xe3, 0x4d, 0x59, 0xff, 0x94, 0xfd, 0x8e, 0x96, 0x94,
0x63, 0x68, 0x57, 0x0e, 0x28, 0x9d, 0xf4, 0x6d, 0x73, 0xd8, 0xf7, 0x3b, 0xc5, 0x0b, 0x3c, 0xa2,
0x59, 0xcf, 0x96, 0x39, 0xec, 0xfa, 0x72, 0x2c, 0x33, 0x56, 0xd9, 0x0e, 0xe0, 0x26, 0x39, 0x18,
0x36, 0xfa, 0x7b, 0xb6, 0xd3, 0x77, 0x4d, 0xfb, 0x08, 0x3f, 0x4c, 0xfc, 0x47, 0x1d, 0xbf, 0xba,
0xac, 0x20, 0xaa, 0x29, 0x40, 0xeb, 0xb6, 0xd3, 0xc5, 0xbe, 0x75, 0x1f, 0xc1, 0x58, 0x42, 0xb8,
0x6c, 0xcf, 0x18, 0x1c, 0xf8, 0x2c, 0x21, 0x90, 0x6e, 0xa3, 0x10, 0x03, 0x65, 0x89, 0x9a, 0x94,
0xd7, 0x41, 0x02, 0x95, 0xe1, 0xa8, 0xa2, 0x2f, 0x64, 0x20, 0xf5, 0x5b, 0x90, 0xef, 0x98, 0xfa,
0x80, 0xff, 0xce, 0xc1, 0x2a, 0x3e, 0xcc, 0x80, 0xcc, 0x09, 0x70, 0xd5, 0x22, 0x3a, 0xe6, 0x49,
0x54, 0xa4, 0xbe, 0x05, 0xf0, 0x8e, 0x6d, 0x58, 0xdb, 0xf6, 0x01, 0xb5, 0xf8, 0x93, 0xf0, 0x91,
0xed, 0x1c, 0xc8, 0xa3, 0x44, 0xe2, 0x28, 0x5a, 0x9c, 0x28, 0xeb, 0x16, 0x12, 0x63, 0x27, 0x78,
0x19, 0x15, 0x4d, 0x96, 0x5c, 0xb2, 0xc4, 0xb6, 0x3d, 0x8c, 0x17, 0x97, 0x21, 0x3b, 0xd0, 0xfb,
0xfe, 0xcd, 0x2b, 0xd6, 0xf2, 0xe8, 0xa1, 0x99, 0xba, 0x76, 0x9b, 0xce, 0x48, 0x66, 0xa0, 0xe3,
0x3f, 0x96, 0x7d, 0x11, 0xc1, 0xee, 0x0b, 0x37, 0x53, 0x14, 0xd9, 0x17, 0x2f, 0x14, 0x4a, 0x08,
0x2a, 0xb3, 0xff, 0x18, 0x60, 0x8b, 0x12, 0xd4, 0x1f, 0xe9, 0xee, 0x48, 0x70, 0xd5, 0xda, 0x32,
0x22, 0x41, 0x20, 0x6f, 0xa1, 0x94, 0x80, 0x40, 0xb3, 0x6f, 0x0c, 0x23, 0x85, 0xf7, 0x70, 0x0d,
0x7d, 0x8f, 0x2f, 0x42, 0x16, 0xec, 0xb1, 0xf7, 0x27, 0x5c, 0xaa, 0xac, 0x5e, 0xe1, 0xbd, 0x40,
0xa2, 0xfe, 0x35, 0x01, 0x05, 0x66, 0xd3, 0xd8, 0x33, 0x06, 0x2c, 0x5b, 0x7e, 0xf5, 0x48, 0x8f,
0xa1, 0x6e, 0xe0, 0x3a, 0x72, 0x6d, 0x3c, 0xd4, 0xd5, 0xbb, 0x84, 0x30, 0x19, 0xd6, 0x82, 0x59,
0xc1, 0xf8, 0x65, 0x90, 0x57, 0xbf, 0x3c, 0xaf, 0xcb, 0x29, 0x4a, 0x3d, 0x7e, 0x96, 0xe1, 0xec,
0xf8, 0x2a, 0x8b, 0x24, 0x2a, 0x62, 0x3f, 0x15, 0x0d, 0x2c, 0xee, 0x14, 0xf2, 0xa7, 0xa2, 0x7a,
0x9b, 0xa0, 0x44, 0xfd, 0x73, 0x02, 0x4a, 0x4d, 0x6b, 0xe0, 0xcc, 0x78, 0x90, 0x64, 0x07, 0x71,
0x11, 0xf2, 0x58, 0x12, 0xb8, 0x33, 0xd7, 0xa3, 0x63, 0xff, 0x25, 0x3a, 0x10, 0x28, 0x2d, 0xc8,
0x63, 0x3a, 0xb0, 0x1d, 0xc3, 0x1b, 0x8d, 0x25, 0x37, 0x8e, 0x0f, 0xcc, 0x51, 0x9b, 0x55, 0xcd,
0x57, 0x21, 0xa1, 0xb6, 0x1f, 0x8a, 0x53, 0x7c, 0xb2, 0x3c, 0x14, 0x3f, 0x05, 0x45, 0x13, 0x0b,
0x36, 0x64, 0xbd, 0x7d, 0x56, 0x07, 0xf1, 0x75, 0xa4, 0x49, 0x41, 0xca, 0x58, 0x6d, 0xa7, 0xaa,
0x90, 0x0f, 0x8c, 0xb1, 0xf7, 0x7f, 0xad, 0xd9, 0xed, 0x5f, 0x5b, 0xbb, 0xde, 0xbf, 0x59, 0xdf,
0xc4, 0xc0, 0x2c, 0x98, 0xc0, 0x1f, 0x71, 0x4d, 0x9b, 0xc2, 0x07, 0x25, 0x71, 0x42, 0xe7, 0x72,
0xf0, 0xc6, 0xfb, 0xd4, 0x2e, 0x2d, 0x9c, 0x8b, 0x05, 0x01, 0x46, 0xed, 0x58, 0x57, 0x3c, 0xb5,
0x8b, 0xfc, 0x0e, 0x92, 0x3a, 0xf6, 0x77, 0x90, 0xf4, 0x37, 0xf2, 0x3b, 0xc8, 0x0b, 0x5f, 0xa4,
0x20, 0x1f, 0x54, 0xa2, 0xcc, 0x65, 0x18, 0xd3, 0x3a, 0x25, 0x5e, 0x76, 0x02, 0x79, 0x9b, 0x73,
0xac, 0xbc, 0xb6, 0xb1, 0xb1, 0x55, 0xd7, 0x58, 0xb1, 0xfe, 0xb6, 0xa0, 0x62, 0x01, 0x40, 0xc3,
0xd8, 0xc1, 0x0e, 0x7d, 0xa8, 0xa8, 0x21, 0x15, 0xbb, 0x27, 0xdf, 0x8f, 0x02, 0x94, 0xcf, 0xc3,
0x9e, 0x81, 0x9c, 0xd6, 0xed, 0xb6, 0x6e, 0xb6, 0xd1, 0xd2, 0xfd, 0x44, 0xe5, 0x31, 0x04, 0x9d,
0x09, 0x4d, 0x21, 0x85, 0xd8, 0xb7, 0xd0, 0x12, 0x43, 0xd5, 0xeb, 0xcd, 0x0e, 0x1b, 0xef, 0x5e,
0x72, 0x11, 0xc5, 0x09, 0x08, 0x7f, 0x0b, 0xce, 0x77, 0x48, 0xb3, 0xa3, 0x11, 0x36, 0xe2, 0xfd,
0xe4, 0xc2, 0xbc, 0x3a, 0x0e, 0x9d, 0xe8, 0x0e, 0x1b, 0x73, 0xd5, 0xff, 0x4d, 0xe4, 0x5e, 0x4a,
0xbc, 0x17, 0x86, 0xe5, 0x37, 0xee, 0xef, 0x8c, 0x8d, 0xd6, 0xdd, 0xd6, 0x08, 0x7f, 0xa5, 0xb8,
0x9f, 0x5a, 0x18, 0xad, 0xcb, 0x1e, 0x51, 0x98, 0x15, 0x5c, 0x1d, 0xe9, 0xb5, 0xdb, 0x7c, 0x75,
0xe9, 0x85, 0xd5, 0x91, 0xa9, 0x65, 0x31, 0xcc, 0x15, 0xf6, 0x10, 0x24, 0x5e, 0x35, 0xca, 0xf7,
0xd3, 0x0b, 0x13, 0xaa, 0xfb, 0xcf, 0x29, 0x7c, 0xc0, 0x5b, 0xbd, 0x6d, 0xfe, 0x93, 0xcd, 0xbd,
0xcc, 0xe2, 0x80, 0xa3, 0xa9, 0x37, 0x64, 0xe4, 0xf7, 0x72, 0xc0, 0x46, 0xef, 0x67, 0x04, 0x09,
0x08, 0x30, 0x82, 0x8a, 0x32, 0x3b, 0xa4, 0xf9, 0x8e, 0xf8, 0x75, 0xe7, 0x5e, 0x76, 0xc1, 0x0e,
0xa1, 0xef, 0x61, 0x30, 0x46, 0xc2, 0x1a, 0x3c, 0x87, 0x06, 0x5d, 0x2f, 0xfc, 0x00, 0x72, 0x7e,
0xc0, 0xc0, 0xdd, 0xc9, 0xde, 0xd9, 0x22, 0xb7, 0x9b, 0x04, 0x8f, 0x9e, 0xef, 0x8e, 0xdf, 0x73,
0x47, 0x44, 0xdc, 0xcb, 0xb0, 0xb4, 0xa9, 0xb5, 0xb5, 0x9b, 0x08, 0x90, 0xcf, 0xb1, 0x3e, 0x40,
0x7a, 0x7d, 0xa5, 0x2c, 0x07, 0x08, 0x6c, 0xd6, 0x2e, 0x3e, 0xf8, 0x74, 0xf5, 0xd4, 0xc7, 0xf8,
0xf7, 0xf9, 0xa7, 0xab, 0x89, 0x7b, 0x9f, 0xad, 0x26, 0x1e, 0xe0, 0xdf, 0x47, 0xf8, 0xf7, 0x0f,
0xfc, 0xdb, 0xcd, 0x72, 0x46, 0xf6, 0xea, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x84, 0x8b, 0x50,
0xe8, 0x9f, 0x20, 0x00, 0x00,
// 3398 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x59, 0x4d, 0x6c, 0x1b, 0x49,
0x76, 0x16, 0x7f, 0x45, 0x3e, 0x52, 0x72, 0xbb, 0xec, 0xf5, 0xc8, 0x1c, 0x8f, 0xc4, 0x69, 0x8f,
0x77, 0xbc, 0xb3, 0x13, 0xce, 0x8c, 0x66, 0x13, 0x78, 0xc7, 0xc9, 0xce, 0xb4, 0x48, 0xca, 0xe6,
0x5a, 0xa2, 0x88, 0xa2, 0x68, 0x63, 0x10, 0x20, 0x44, 0xa9, 0xbb, 0x44, 0xf5, 0xa8, 0xd9, 0xc5,
0x74, 0x17, 0x25, 0x33, 0x41, 0x00, 0x27, 0x97, 0x04, 0x3a, 0xe5, 0x1e, 0x08, 0x8b, 0x20, 0x41,
0x6e, 0x39, 0xe4, 0x14, 0x20, 0x27, 0x1f, 0xe7, 0xb8, 0x41, 0x80, 0x60, 0x91, 0x00, 0x42, 0x46,
0x39, 0xe6, 0xb2, 0x40, 0x0e, 0x7b, 0x48, 0x0e, 0x41, 0xfd, 0x74, 0xb3, 0x49, 0xd3, 0x1a, 0x4f,
0x76, 0x4f, 0xec, 0x7a, 0xf5, 0xbd, 0x57, 0xef, 0x55, 0xbd, 0x7a, 0xf5, 0x55, 0x11, 0x4a, 0x7c,
0x32, 0xa2, 0x61, 0x6d, 0x14, 0x30, 0xce, 0x10, 0x72, 0x98, 0x7d, 0x4c, 0x83, 0x5a, 0x78, 0x4a,
0x82, 0xe1, 0xb1, 0xcb, 0x6b, 0x27, 0x9f, 0x54, 0x6e, 0x73, 0x77, 0x48, 0x43, 0x4e, 0x86, 0xa3,
0x8f, 0xe2, 0x2f, 0x05, 0xaf, 0xbc, 0xe5, 0x8c, 0x03, 0xc2, 0x5d, 0xe6, 0x7f, 0x14, 0x7d, 0xe8,
0x8e, 0x9b, 0x03, 0x36, 0x60, 0xf2, 0xf3, 0x23, 0xf1, 0xa5, 0xa4, 0xe6, 0x06, 0x2c, 0x3f, 0xa5,
0x41, 0xe8, 0x32, 0x1f, 0xdd, 0x84, 0x9c, 0xeb, 0x3b, 0xf4, 0xf9, 0x5a, 0xaa, 0x9a, 0xba, 0x9f,
0xc5, 0xaa, 0x61, 0xfe, 0x75, 0x0a, 0x4a, 0x96, 0xef, 0x33, 0x2e, 0x6d, 0x85, 0x08, 0x41, 0xd6,
0x27, 0x43, 0x2a, 0x41, 0x45, 0x2c, 0xbf, 0x51, 0x1d, 0xf2, 0x1e, 0x39, 0xa0, 0x5e, 0xb8, 0x96,
0xae, 0x66, 0xee, 0x97, 0x36, 0x7f, 0x58, 0x7b, 0xd5, 0xe7, 0x5a, 0xc2, 0x48, 0x6d, 0x47, 0xa2,
0x9b, 0x3e, 0x0f, 0x26, 0x58, 0xab, 0x56, 0x7e, 0x0c, 0xa5, 0x84, 0x18, 0x19, 0x90, 0x39, 0xa6,
0x13, 0x3d, 0x8c, 0xf8, 0x14, 0xfe, 0x9d, 0x10, 0x6f, 0x4c, 0xd7, 0xd2, 0x52, 0xa6, 0x1a, 0x9f,
0xa5, 0x1f, 0xa4, 0xcc, 0x2f, 0xa1, 0x88, 0x69, 0xc8, 0xc6, 0x81, 0x4d, 0x43, 0xf4, 0x03, 0x28,
0xfa, 0xc4, 0x67, 0x7d, 0x7b, 0x34, 0x0e, 0xa5, 0x7a, 0x66, 0xab, 0x7c, 0x79, 0xb1, 0x51, 0x68,
0x13, 0x9f, 0xd5, 0x3b, 0xbd, 0x10, 0x17, 0x44, 0x77, 0x7d, 0x34, 0x0e, 0xd1, 0xbb, 0x50, 0x1e,
0xd2, 0x21, 0x0b, 0x26, 0xfd, 0x83, 0x09, 0xa7, 0xa1, 0x34, 0x9c, 0xc1, 0x25, 0x25, 0xdb, 0x12,
0x22, 0xf3, 0x2f, 0x53, 0x70, 0x33, 0xb2, 0x8d, 0xe9, 0x1f, 0x8e, 0xdd, 0x80, 0x0e, 0xa9, 0xcf,
0x43, 0xf4, 0xdb, 0x90, 0xf7, 0xdc, 0xa1, 0xcb, 0xd5, 0x18, 0xa5, 0xcd, 0x77, 0x16, 0xc5, 0x1c,
0x7b, 0x85, 0x35, 0x18, 0x59, 0x50, 0x0e, 0x68, 0x48, 0x83, 0x13, 0x35, 0x13, 0x72, 0xc8, 0x6f,
0x55, 0x9e, 0x51, 0x31, 0xb7, 0xa1, 0xd0, 0xf1, 0x08, 0x3f, 0x64, 0xc1, 0x10, 0x99, 0x50, 0x26,
0x81, 0x7d, 0xe4, 0x72, 0x6a, 0xf3, 0x71, 0x10, 0xad, 0xca, 0x8c, 0x0c, 0xdd, 0x82, 0x34, 0x53,
0x03, 0x15, 0xb7, 0xf2, 0x97, 0x17, 0x1b, 0xe9, 0xbd, 0x2e, 0x4e, 0xb3, 0xd0, 0x7c, 0x08, 0xd7,
0x3b, 0xde, 0x78, 0xe0, 0xfa, 0x0d, 0x1a, 0xda, 0x81, 0x3b, 0x12, 0xd6, 0xc5, 0xf2, 0x8a, 0xe4,
0x8b, 0x96, 0x57, 0x7c, 0xc7, 0x4b, 0x9e, 0x9e, 0x2e, 0xb9, 0xf9, 0xe7, 0x69, 0xb8, 0xde, 0xf4,
0x07, 0xae, 0x4f, 0x93, 0xda, 0xf7, 0x60, 0x95, 0x4a, 0x61, 0xff, 0x44, 0x25, 0x95, 0xb6, 0xb3,
0xa2, 0xa4, 0x51, 0xa6, 0xb5, 0xe6, 0xf2, 0xe5, 0x93, 0x45, 0xe1, 0xbf, 0x62, 0x7d, 0x51, 0xd6,
0xa0, 0x26, 0x2c, 0x8f, 0x64, 0x10, 0xe1, 0x5a, 0x46, 0xda, 0xba, 0xb7, 0xc8, 0xd6, 0x2b, 0x71,
0x6e, 0x65, 0xbf, 0xbe, 0xd8, 0x58, 0xc2, 0x91, 0xee, 0xaf, 0x93, 0x7c, 0xff, 0x99, 0x82, 0x6b,
0x6d, 0xe6, 0xcc, 0xcc, 0x43, 0x05, 0x0a, 0x47, 0x2c, 0xe4, 0x89, 0x8d, 0x12, 0xb7, 0xd1, 0x03,
0x28, 0x8c, 0xf4, 0xf2, 0xe9, 0xd5, 0xbf, 0xb3, 0xd8, 0x65, 0x85, 0xc1, 0x31, 0x1a, 0x3d, 0x84,
0x62, 0x10, 0xe5, 0xc4, 0x5a, 0xe6, 0x4d, 0x12, 0x67, 0x8a, 0x47, 0xbf, 0x07, 0x79, 0xb5, 0x08,
0x6b, 0x59, 0xa9, 0x79, 0xef, 0x8d, 0xe6, 0x1c, 0x6b, 0x25, 0xf3, 0x17, 0x29, 0x30, 0x30, 0x39,
0xe4, 0xbb, 0x74, 0x78, 0x40, 0x83, 0x2e, 0x27, 0x7c, 0x1c, 0xa2, 0x5b, 0x90, 0xf7, 0x28, 0x71,
0x68, 0x20, 0x83, 0x2c, 0x60, 0xdd, 0x42, 0x3d, 0x91, 0xe4, 0xc4, 0x3e, 0x22, 0x07, 0xae, 0xe7,
0xf2, 0x89, 0x0c, 0x73, 0x75, 0xf1, 0x2a, 0xcf, 0xdb, 0xac, 0xe1, 0x84, 0x22, 0x9e, 0x31, 0x83,
0xd6, 0x60, 0x79, 0x48, 0xc3, 0x90, 0x0c, 0xa8, 0x8c, 0xbe, 0x88, 0xa3, 0xa6, 0xf9, 0x10, 0xca,
0x49, 0x3d, 0x54, 0x82, 0xe5, 0x5e, 0xfb, 0x49, 0x7b, 0xef, 0x59, 0xdb, 0x58, 0x42, 0xd7, 0xa0,
0xd4, 0x6b, 0xe3, 0xa6, 0x55, 0x7f, 0x6c, 0x6d, 0xed, 0x34, 0x8d, 0x14, 0x5a, 0x81, 0xe2, 0xb4,
0x99, 0x36, 0x7f, 0x96, 0x02, 0x10, 0x0b, 0xa8, 0x83, 0xfa, 0x0c, 0x72, 0x21, 0x27, 0x5c, 0x2d,
0xdc, 0xea, 0xe6, 0x7b, 0x8b, 0xbc, 0x9e, 0xc2, 0x6b, 0xe2, 0x87, 0x62, 0xa5, 0x92, 0xf4, 0x30,
0x3d, 0xef, 0x61, 0x4e, 0x22, 0x67, 0x5d, 0x2b, 0x40, 0xb6, 0x21, 0xbe, 0x52, 0xa8, 0x08, 0x39,
0xdc, 0xb4, 0x1a, 0x5f, 0x1a, 0x69, 0x64, 0x40, 0xb9, 0xd1, 0xea, 0xd6, 0xf7, 0xda, 0xed, 0x66,
0x7d, 0xbf, 0xd9, 0x30, 0x32, 0xe6, 0x3d, 0xc8, 0xb5, 0x86, 0x64, 0x40, 0xd1, 0x1d, 0x91, 0x01,
0x87, 0x34, 0xa0, 0xbe, 0x1d, 0x25, 0xd6, 0x54, 0x60, 0xfe, 0xbc, 0x08, 0xb9, 0x5d, 0x36, 0xf6,
0x39, 0xda, 0x4c, 0xec, 0xe2, 0xd5, 0xcd, 0xf5, 0x45, 0x21, 0x48, 0x60, 0x6d, 0x7f, 0x32, 0xa2,
0x7a, 0x97, 0xdf, 0x82, 0xbc, 0xca, 0x15, 0xed, 0xba, 0x6e, 0x09, 0x39, 0x27, 0xc1, 0x80, 0x72,
0x3d, 0xe9, 0xba, 0x85, 0xee, 0x43, 0x21, 0xa0, 0xc4, 0x61, 0xbe, 0x37, 0x91, 0x29, 0x55, 0x50,
0x65, 0x16, 0x53, 0xe2, 0xec, 0xf9, 0xde, 0x04, 0xc7, 0xbd, 0xe8, 0x31, 0x94, 0x0f, 0x5c, 0xdf,
0xe9, 0xb3, 0x91, 0xaa, 0x79, 0xb9, 0xd7, 0x27, 0xa0, 0xf2, 0x6a, 0xcb, 0xf5, 0x9d, 0x3d, 0x05,
0xc6, 0xa5, 0x83, 0x69, 0x03, 0xb5, 0x61, 0xf5, 0x84, 0x79, 0xe3, 0x21, 0x8d, 0x6d, 0xe5, 0xa5,
0xad, 0xf7, 0x5f, 0x6f, 0xeb, 0xa9, 0xc4, 0x47, 0xd6, 0x56, 0x4e, 0x92, 0x4d, 0xf4, 0x04, 0x56,
0xf8, 0x70, 0x74, 0x18, 0xc6, 0xe6, 0x96, 0xa5, 0xb9, 0xef, 0x5f, 0x31, 0x61, 0x02, 0x1e, 0x59,
0x2b, 0xf3, 0x44, 0xab, 0xf2, 0x67, 0x19, 0x28, 0x25, 0x3c, 0x47, 0x5d, 0x28, 0x8d, 0x02, 0x36,
0x22, 0x03, 0x59, 0xb7, 0xf5, 0x5a, 0x7c, 0xf2, 0x46, 0x51, 0xd7, 0x3a, 0x53, 0x45, 0x9c, 0xb4,
0x62, 0x9e, 0xa7, 0xa1, 0x94, 0xe8, 0x44, 0x1f, 0x40, 0x01, 0x77, 0x70, 0xeb, 0xa9, 0xb5, 0xdf,
0x34, 0x96, 0x2a, 0x77, 0xce, 0xce, 0xab, 0x6b, 0xd2, 0x5a, 0xd2, 0x40, 0x27, 0x70, 0x4f, 0x44,
0xea, 0xdd, 0x87, 0xe5, 0x08, 0x9a, 0xaa, 0xbc, 0x7d, 0x76, 0x5e, 0x7d, 0x6b, 0x1e, 0x9a, 0x40,
0xe2, 0xee, 0x63, 0x0b, 0x37, 0x1b, 0x46, 0x7a, 0x31, 0x12, 0x77, 0x8f, 0x48, 0x40, 0x1d, 0xf4,
0x7d, 0xc8, 0x6b, 0x60, 0xa6, 0x52, 0x39, 0x3b, 0xaf, 0xde, 0x9a, 0x07, 0x4e, 0x71, 0xb8, 0xbb,
0x63, 0x3d, 0x6d, 0x1a, 0xd9, 0xc5, 0x38, 0xdc, 0xf5, 0xc8, 0x09, 0x45, 0xef, 0x41, 0x4e, 0xc1,
0x72, 0x95, 0xdb, 0x67, 0xe7, 0xd5, 0xef, 0xbd, 0x62, 0x4e, 0xa0, 0x2a, 0x6b, 0x7f, 0xf1, 0x37,
0xeb, 0x4b, 0xff, 0xf4, 0xb7, 0xeb, 0xc6, 0x7c, 0x77, 0xe5, 0x7f, 0x53, 0xb0, 0x32, 0xb3, 0xe4,
0xc8, 0x84, 0xbc, 0xcf, 0x6c, 0x36, 0x52, 0xe5, 0xbc, 0xb0, 0x05, 0x97, 0x17, 0x1b, 0xf9, 0x36,
0xab, 0xb3, 0xd1, 0x04, 0xeb, 0x1e, 0xf4, 0x64, 0xee, 0x40, 0xfa, 0xf4, 0x0d, 0xf3, 0x69, 0xe1,
0x91, 0xf4, 0x39, 0xac, 0x38, 0x81, 0x7b, 0x42, 0x83, 0xbe, 0xcd, 0xfc, 0x43, 0x77, 0xa0, 0x4b,
0x75, 0x65, 0x91, 0xcd, 0x86, 0x04, 0xe2, 0xb2, 0x52, 0xa8, 0x4b, 0xfc, 0xaf, 0x71, 0x18, 0x55,
0x9e, 0x42, 0x39, 0x99, 0xa1, 0xe8, 0x1d, 0x80, 0xd0, 0xfd, 0x23, 0xaa, 0xf9, 0x8d, 0x64, 0x43,
0xb8, 0x28, 0x24, 0x92, 0xdd, 0xa0, 0xf7, 0x21, 0x3b, 0x64, 0x8e, 0xb2, 0x93, 0xdb, 0xba, 0x21,
0xce, 0xc4, 0x7f, 0xbb, 0xd8, 0x28, 0xb1, 0xb0, 0xb6, 0xed, 0x7a, 0x74, 0x97, 0x39, 0x14, 0x4b,
0x80, 0x79, 0x02, 0x59, 0x51, 0x2a, 0xd0, 0xdb, 0x90, 0xdd, 0x6a, 0xb5, 0x1b, 0xc6, 0x52, 0xe5,
0xfa, 0xd9, 0x79, 0x75, 0x45, 0x4e, 0x89, 0xe8, 0x10, 0xb9, 0x8b, 0x36, 0x20, 0xff, 0x74, 0x6f,
0xa7, 0xb7, 0x2b, 0xd2, 0xeb, 0xc6, 0xd9, 0x79, 0xf5, 0x5a, 0xdc, 0xad, 0x26, 0x0d, 0xbd, 0x03,
0xb9, 0xfd, 0xdd, 0xce, 0x76, 0xd7, 0x48, 0x57, 0xd0, 0xd9, 0x79, 0x75, 0x35, 0xee, 0x97, 0x3e,
0x57, 0xae, 0xeb, 0x55, 0x2d, 0xc6, 0x72, 0xf3, 0x7f, 0xd2, 0xb0, 0x82, 0x05, 0xbf, 0x0d, 0x78,
0x87, 0x79, 0xae, 0x3d, 0x41, 0x1d, 0x28, 0xda, 0xcc, 0x77, 0xdc, 0xc4, 0x9e, 0xda, 0x7c, 0xcd,
0x21, 0x38, 0xd5, 0x8a, 0x5a, 0xf5, 0x48, 0x13, 0x4f, 0x8d, 0xa0, 0x4d, 0xc8, 0x39, 0xd4, 0x23,
0x93, 0xab, 0x4e, 0xe3, 0x86, 0xe6, 0xd2, 0x58, 0x41, 0x25, 0x73, 0x24, 0xcf, 0xfb, 0x84, 0x73,
0x3a, 0x1c, 0x71, 0x75, 0x1a, 0x67, 0x71, 0x69, 0x48, 0x9e, 0x5b, 0x5a, 0x84, 0x7e, 0x04, 0xf9,
0x53, 0xd7, 0x77, 0xd8, 0xa9, 0x3e, 0x70, 0xaf, 0xb6, 0xab, 0xb1, 0xe6, 0x99, 0x38, 0x67, 0xe7,
0x9c, 0x15, 0xb3, 0xde, 0xde, 0x6b, 0x37, 0xa3, 0x59, 0xd7, 0xfd, 0x7b, 0x7e, 0x9b, 0xf9, 0x62,
0xc7, 0xc0, 0x5e, 0xbb, 0xbf, 0x6d, 0xb5, 0x76, 0x7a, 0x58, 0xcc, 0xfc, 0xcd, 0xb3, 0xf3, 0xaa,
0x11, 0x43, 0xb6, 0x89, 0xeb, 0x09, 0x12, 0x78, 0x1b, 0x32, 0x56, 0xfb, 0x4b, 0x23, 0x5d, 0x31,
0xce, 0xce, 0xab, 0xe5, 0xb8, 0xdb, 0xf2, 0x27, 0xd3, 0xcd, 0x34, 0x3f, 0xae, 0xf9, 0x5f, 0x29,
0x28, 0xf7, 0x46, 0x0e, 0xe1, 0x54, 0x65, 0x26, 0xaa, 0x42, 0x69, 0x44, 0x02, 0xe2, 0x79, 0xd4,
0x73, 0xc3, 0xa1, 0xbe, 0x28, 0x24, 0x45, 0xe8, 0xc1, 0x77, 0x98, 0x4c, 0x4d, 0xc2, 0xf4, 0x94,
0xf6, 0x60, 0xf5, 0x50, 0x39, 0xdb, 0x27, 0xb6, 0x5c, 0xdd, 0x8c, 0x5c, 0xdd, 0xda, 0x22, 0x13,
0x49, 0xaf, 0x6a, 0x3a, 0x46, 0x4b, 0x6a, 0xe1, 0x95, 0xc3, 0x64, 0xd3, 0xbc, 0x0f, 0x2b, 0x33,
0xfd, 0xe2, 0xa4, 0xed, 0x58, 0xbd, 0x6e, 0xd3, 0x58, 0x42, 0x65, 0x28, 0xd4, 0xf7, 0xda, 0xfb,
0xad, 0x76, 0xaf, 0x69, 0xa4, 0xcc, 0x7f, 0x48, 0x47, 0xd1, 0x6a, 0x26, 0xb0, 0x35, 0xcb, 0x04,
0x3e, 0x7c, 0xbd, 0x23, 0x9a, 0x0b, 0x4c, 0x1b, 0x31, 0x23, 0xf8, 0x5d, 0x00, 0x39, 0xa9, 0xd4,
0xe9, 0x13, 0x7e, 0x15, 0xdb, 0xdf, 0x8f, 0xee, 0x71, 0xb8, 0xa8, 0x15, 0x2c, 0x8e, 0xbe, 0x80,
0xb2, 0xcd, 0x86, 0x23, 0x8f, 0x6a, 0xfd, 0xcc, 0x9b, 0xe8, 0x97, 0x62, 0x15, 0x8b, 0x27, 0x19,
0x49, 0x76, 0x96, 0x91, 0xd4, 0xa1, 0x94, 0xf0, 0x77, 0x96, 0x97, 0x94, 0xa1, 0xd0, 0xeb, 0x34,
0xac, 0xfd, 0x56, 0xfb, 0x91, 0x91, 0x42, 0x00, 0x79, 0x39, 0x63, 0x0d, 0x23, 0x2d, 0xb8, 0x53,
0x7d, 0x6f, 0xb7, 0xb3, 0xd3, 0x54, 0xcc, 0xe4, 0x4f, 0xe0, 0x5a, 0x9d, 0xf9, 0x9c, 0xb8, 0x7e,
0x4c, 0x0a, 0x37, 0x85, 0xcf, 0x5a, 0xd4, 0x77, 0x1d, 0x55, 0xb7, 0xb6, 0xae, 0x5d, 0x5e, 0x6c,
0x94, 0x62, 0x68, 0xab, 0x21, 0xbc, 0x8c, 0x1a, 0x8e, 0xc8, 0xce, 0x91, 0xeb, 0xe8, 0x32, 0xb4,
0x7c, 0x79, 0xb1, 0x91, 0xe9, 0xb4, 0x1a, 0x58, 0xc8, 0xd0, 0xdb, 0x50, 0xa4, 0xcf, 0x5d, 0xde,
0xb7, 0x45, 0x9d, 0x12, 0xf1, 0xe7, 0x70, 0x41, 0x08, 0xea, 0xa2, 0x2c, 0xfd, 0x69, 0x1a, 0x60,
0x9f, 0x84, 0xc7, 0x7a, 0xe8, 0x87, 0x50, 0x8c, 0xaf, 0xc3, 0x57, 0x5d, 0xcb, 0x12, 0x73, 0x1d,
0xe3, 0xd1, 0xa7, 0xd1, 0x6a, 0x2b, 0xb6, 0xba, 0x58, 0x51, 0x8f, 0xb5, 0x88, 0xf0, 0xcd, 0x52,
0x52, 0x51, 0xb5, 0x69, 0x10, 0xe8, 0x49, 0x17, 0x9f, 0xa8, 0x2e, 0x2b, 0x97, 0x8a, 0x59, 0x73,
0xa0, 0xbb, 0x8b, 0x06, 0x99, 0x9b, 0xd0, 0xc7, 0x4b, 0x78, 0xaa, 0xb7, 0x65, 0xc0, 0x6a, 0x30,
0xf6, 0x85, 0xd7, 0xfd, 0x50, 0x76, 0x9b, 0xff, 0x92, 0x06, 0x68, 0x75, 0xac, 0x5d, 0xbd, 0x45,
0x1b, 0x90, 0x3f, 0x24, 0x43, 0xd7, 0x9b, 0x5c, 0x95, 0xb5, 0x53, 0x7c, 0xcd, 0x72, 0x9c, 0x80,
0x86, 0xe1, 0xb6, 0xd4, 0xc1, 0x5a, 0x57, 0x92, 0xc1, 0xf1, 0x81, 0x4f, 0x79, 0x4c, 0x06, 0x65,
0x4b, 0x9c, 0x3c, 0x01, 0xf1, 0xe3, 0x68, 0x55, 0x43, 0xcc, 0xc2, 0x80, 0x70, 0x7a, 0x4a, 0x26,
0x51, 0x92, 0xe9, 0x26, 0x7a, 0x2c, 0x48, 0xa2, 0xb8, 0xbb, 0x52, 0x67, 0x2d, 0x27, 0x8f, 0xd6,
0x6f, 0xf3, 0x07, 0x6b, 0xb8, 0x3a, 0x53, 0x63, 0xed, 0xca, 0x43, 0x79, 0x10, 0x4c, 0xbb, 0xbe,
0xd3, 0x1d, 0xed, 0x63, 0x58, 0x99, 0x89, 0xf3, 0x15, 0x16, 0xde, 0xea, 0x3c, 0xfd, 0x91, 0x91,
0xd5, 0x5f, 0xbf, 0x63, 0xe4, 0xcd, 0xff, 0x4e, 0x01, 0x74, 0x98, 0x2c, 0x86, 0x62, 0x56, 0x17,
0xbf, 0x7a, 0x14, 0xe4, 0x1b, 0x8a, 0xcd, 0x3c, 0x9d, 0x33, 0x0b, 0x69, 0xe8, 0xd4, 0x8a, 0x60,
0x75, 0x12, 0x8e, 0x63, 0x45, 0xb4, 0x01, 0x25, 0xc5, 0xa7, 0xfb, 0x23, 0x16, 0xa8, 0x0d, 0xbe,
0x82, 0x41, 0x89, 0x84, 0xa6, 0xb8, 0x52, 0x8f, 0xc6, 0x07, 0x9e, 0x1b, 0x1e, 0x51, 0x47, 0x61,
0xb2, 0x12, 0xb3, 0x12, 0x4b, 0x05, 0xcc, 0x6c, 0x40, 0x21, 0xb2, 0x8e, 0xd6, 0x20, 0xb3, 0x5f,
0xef, 0x18, 0x4b, 0x95, 0x6b, 0x67, 0xe7, 0xd5, 0x52, 0x24, 0xde, 0xaf, 0x77, 0x44, 0x4f, 0xaf,
0xd1, 0x31, 0x52, 0xb3, 0x3d, 0xbd, 0x46, 0xa7, 0x92, 0x15, 0x87, 0x80, 0xf9, 0x57, 0x29, 0xc8,
0x2b, 0x4a, 0xb2, 0x30, 0x62, 0x0b, 0x96, 0x23, 0xa2, 0xac, 0x78, 0xd2, 0xfb, 0xaf, 0xe7, 0x34,
0x35, 0x4d, 0x41, 0xd4, 0x3a, 0x46, 0x7a, 0x95, 0xcf, 0xa0, 0x9c, 0xec, 0xf8, 0x4e, 0xab, 0xf8,
0xc7, 0x50, 0x12, 0x89, 0x12, 0x71, 0x9b, 0x4d, 0xc8, 0x2b, 0xda, 0xa4, 0xb7, 0xfa, 0x55, 0x04,
0x4b, 0x23, 0xd1, 0x03, 0x58, 0x56, 0xa4, 0x2c, 0x7a, 0x2e, 0x58, 0xbf, 0x3a, 0x1d, 0x71, 0x04,
0x37, 0x3f, 0x87, 0x6c, 0x87, 0xd2, 0x00, 0xdd, 0x85, 0x65, 0x9f, 0x39, 0x74, 0x5a, 0xd9, 0x34,
0x9f, 0x74, 0x68, 0xab, 0x21, 0xf8, 0xa4, 0x43, 0x5b, 0x8e, 0x98, 0x3c, 0xe2, 0x38, 0x41, 0xf4,
0x62, 0x22, 0xbe, 0xcd, 0x7d, 0x28, 0x3f, 0xa3, 0xee, 0xe0, 0x88, 0x53, 0x47, 0x1a, 0xfa, 0x10,
0xb2, 0x23, 0x1a, 0x3b, 0xbf, 0xb6, 0x30, 0x75, 0x28, 0x0d, 0xb0, 0x44, 0x89, 0x0d, 0x79, 0x2a,
0xb5, 0xf5, 0x23, 0x95, 0x6e, 0x99, 0x7f, 0x9f, 0x86, 0xd5, 0x56, 0x18, 0x8e, 0x89, 0x6f, 0x47,
0xc7, 0xd6, 0x4f, 0x66, 0x8f, 0xad, 0xfb, 0x0b, 0x23, 0x9c, 0x51, 0x99, 0xbd, 0xc4, 0xea, 0xca,
0x95, 0x8e, 0x2b, 0x97, 0xf9, 0x75, 0x2a, 0xba, 0xbd, 0xde, 0x4b, 0xec, 0x9b, 0xca, 0xda, 0xd9,
0x79, 0xf5, 0x66, 0xd2, 0x12, 0xed, 0xf9, 0xc7, 0x3e, 0x3b, 0xf5, 0xd1, 0xbb, 0xe2, 0x36, 0xdb,
0x6e, 0x3e, 0x33, 0x52, 0x95, 0x5b, 0x67, 0xe7, 0x55, 0x34, 0x03, 0xc2, 0xd4, 0xa7, 0xa7, 0xc2,
0x52, 0xa7, 0xd9, 0x6e, 0x88, 0x13, 0x26, 0xbd, 0xc0, 0x52, 0x87, 0xfa, 0x8e, 0xeb, 0x0f, 0xd0,
0x5d, 0xc8, 0xb7, 0xba, 0xdd, 0x9e, 0xbc, 0x5f, 0xbc, 0x75, 0x76, 0x5e, 0xbd, 0x31, 0x83, 0x12,
0x0d, 0xea, 0x08, 0x90, 0xe0, 0x3f, 0xcd, 0x86, 0x91, 0x5d, 0x00, 0x12, 0xc7, 0x3f, 0x75, 0x74,
0x86, 0xff, 0x7b, 0x1a, 0x0c, 0xcb, 0xb6, 0xe9, 0x88, 0x8b, 0x7e, 0xcd, 0x29, 0xf7, 0xa1, 0x30,
0x12, 0x5f, 0xae, 0xe4, 0xc8, 0x22, 0x2d, 0x1e, 0x2c, 0x7c, 0xc1, 0x9c, 0xd3, 0xab, 0x61, 0xe6,
0x51, 0xcb, 0x19, 0xba, 0x61, 0x28, 0xee, 0x4e, 0x52, 0x86, 0x63, 0x4b, 0x95, 0x5f, 0xa6, 0xe0,
0xc6, 0x02, 0x04, 0xfa, 0x18, 0xb2, 0x01, 0xf3, 0xa2, 0xe5, 0xb9, 0xf3, 0xba, 0xf7, 0x05, 0xa1,
0x8a, 0x25, 0x12, 0xad, 0x03, 0x90, 0x31, 0x67, 0x44, 0x8e, 0x2f, 0x17, 0xa6, 0x80, 0x13, 0x12,
0xf4, 0x0c, 0xf2, 0x21, 0xb5, 0x03, 0x1a, 0x11, 0x84, 0xcf, 0xff, 0xbf, 0xde, 0xd7, 0xba, 0xd2,
0x0c, 0xd6, 0xe6, 0x2a, 0x35, 0xc8, 0x2b, 0x89, 0xc8, 0x68, 0x87, 0x70, 0x22, 0x9d, 0x2e, 0x63,
0xf9, 0x2d, 0x12, 0x85, 0x78, 0x83, 0x28, 0x51, 0x88, 0x37, 0x30, 0x7f, 0x96, 0x06, 0x68, 0x3e,
0xe7, 0x34, 0xf0, 0x89, 0x57, 0xb7, 0x50, 0x33, 0x51, 0x21, 0x55, 0xb4, 0x3f, 0x58, 0xf8, 0xea,
0x14, 0x6b, 0xd4, 0xea, 0xd6, 0x82, 0x1a, 0x79, 0x1b, 0x32, 0xe3, 0xc0, 0xd3, 0x2f, 0x98, 0x92,
0x1d, 0xf4, 0xf0, 0x0e, 0x16, 0x32, 0xd4, 0x9c, 0x56, 0xa4, 0xcc, 0xeb, 0x9f, 0x9e, 0x13, 0x03,
0xfc, 0xe6, 0xab, 0xd2, 0x87, 0x00, 0x53, 0xaf, 0xd1, 0x3a, 0xe4, 0xea, 0xdb, 0xdd, 0xee, 0x8e,
0xb1, 0xa4, 0xae, 0x40, 0xd3, 0x2e, 0x29, 0x36, 0xff, 0x2e, 0x05, 0x85, 0xba, 0xa5, 0x4f, 0x95,
0x6d, 0x30, 0x64, 0x2d, 0xb1, 0x69, 0xc0, 0xfb, 0xf4, 0xf9, 0xc8, 0x0d, 0x26, 0xba, 0x1c, 0x5c,
0x7d, 0x59, 0x58, 0x15, 0x5a, 0x75, 0x1a, 0xf0, 0xa6, 0xd4, 0x41, 0x18, 0xca, 0x54, 0x87, 0xd8,
0xb7, 0x49, 0x54, 0x9c, 0xd7, 0xaf, 0x9e, 0x0a, 0x45, 0xc9, 0xa6, 0xed, 0x10, 0x97, 0x22, 0x23,
0x75, 0x12, 0x9a, 0x4f, 0xe1, 0xc6, 0x5e, 0x60, 0x1f, 0xd1, 0x90, 0xab, 0x41, 0xb5, 0xcb, 0x9f,
0xc3, 0x1d, 0x4e, 0xc2, 0xe3, 0xfe, 0x91, 0x1b, 0x72, 0x16, 0x4c, 0xfa, 0x01, 0xe5, 0xd4, 0x17,
0xfd, 0x7d, 0xf9, 0xc0, 0xad, 0xaf, 0x98, 0xb7, 0x05, 0xe6, 0xb1, 0x82, 0xe0, 0x08, 0xb1, 0x23,
0x00, 0x66, 0x0b, 0xca, 0x82, 0x45, 0x35, 0xe8, 0x21, 0x19, 0x7b, 0x3c, 0x44, 0x3f, 0x06, 0xf0,
0xd8, 0xa0, 0xff, 0xc6, 0x95, 0xbc, 0xe8, 0xb1, 0x81, 0xfa, 0x34, 0x7f, 0x1f, 0x8c, 0x86, 0x1b,
0x8e, 0x08, 0xb7, 0x8f, 0xa2, 0xbb, 0x33, 0x7a, 0x04, 0xc6, 0x11, 0x25, 0x01, 0x3f, 0xa0, 0x84,
0xf7, 0x47, 0x34, 0x70, 0x99, 0xf3, 0x46, 0x53, 0x7a, 0x2d, 0xd6, 0xea, 0x48, 0x25, 0xf3, 0x57,
0x29, 0x00, 0x4c, 0x0e, 0x23, 0x02, 0xf0, 0x43, 0xb8, 0x1e, 0xfa, 0x64, 0x14, 0x1e, 0x31, 0xde,
0x77, 0x7d, 0x4e, 0x83, 0x13, 0xe2, 0xe9, 0xfb, 0x8f, 0x11, 0x75, 0xb4, 0xb4, 0x1c, 0x7d, 0x08,
0xe8, 0x98, 0xd2, 0x51, 0x9f, 0x79, 0x4e, 0x3f, 0xea, 0x54, 0x2f, 0xf0, 0x59, 0x6c, 0x88, 0x9e,
0x3d, 0xcf, 0xe9, 0x46, 0x72, 0xb4, 0x05, 0xeb, 0x62, 0x06, 0xa8, 0xcf, 0x03, 0x97, 0x86, 0xfd,
0x43, 0x16, 0xf4, 0x43, 0x8f, 0x9d, 0xf6, 0x0f, 0x99, 0xe7, 0xb1, 0x53, 0x1a, 0x44, 0xb7, 0xcb,
0x8a, 0xc7, 0x06, 0x4d, 0x05, 0xda, 0x66, 0x41, 0xd7, 0x63, 0xa7, 0xdb, 0x11, 0x42, 0xb0, 0x84,
0x69, 0xd8, 0xdc, 0xb5, 0x8f, 0x23, 0x96, 0x10, 0x4b, 0xf7, 0x5d, 0xfb, 0x18, 0xdd, 0x85, 0x15,
0xea, 0x51, 0x79, 0x0f, 0x52, 0xa8, 0x9c, 0x44, 0x95, 0x23, 0xa1, 0x00, 0x99, 0xbf, 0x05, 0xc5,
0x8e, 0x47, 0x6c, 0xf9, 0x3f, 0x87, 0xb8, 0xf1, 0xd9, 0xcc, 0x17, 0x49, 0xe0, 0xfa, 0x5c, 0x55,
0xc7, 0x22, 0x4e, 0x8a, 0xcc, 0x9f, 0x00, 0xfc, 0x94, 0xb9, 0xfe, 0x3e, 0x3b, 0xa6, 0xbe, 0x7c,
0x12, 0x3e, 0x65, 0xc1, 0xb1, 0x5e, 0xca, 0x22, 0xd6, 0x2d, 0x49, 0x94, 0x89, 0x4f, 0x06, 0x34,
0x88, 0x5f, 0x46, 0x55, 0x53, 0x1c, 0x2e, 0x79, 0xcc, 0x18, 0xaf, 0x5b, 0xa8, 0x0a, 0x79, 0x9b,
0xf4, 0xa3, 0x9d, 0x57, 0xde, 0x2a, 0x5e, 0x5e, 0x6c, 0xe4, 0xea, 0xd6, 0x13, 0x3a, 0xc1, 0x39,
0x9b, 0x3c, 0xa1, 0x13, 0x71, 0xfa, 0xda, 0x44, 0xee, 0x17, 0x69, 0xa6, 0xac, 0x4e, 0xdf, 0xba,
0x25, 0x36, 0x03, 0xce, 0xdb, 0x44, 0xfc, 0xa2, 0x8f, 0xa1, 0xac, 0x41, 0xfd, 0x23, 0x12, 0x1e,
0x29, 0xae, 0xba, 0xb5, 0x7a, 0x79, 0xb1, 0x01, 0x0a, 0xf9, 0x98, 0x84, 0x47, 0x18, 0x14, 0x5a,
0x7c, 0xa3, 0x26, 0x94, 0xbe, 0x62, 0xae, 0xdf, 0xe7, 0x32, 0x08, 0x7d, 0x61, 0x5f, 0xb8, 0x7f,
0xa6, 0xa1, 0xea, 0xdb, 0x2b, 0x7c, 0x15, 0x4b, 0xcc, 0x7f, 0x4d, 0x41, 0x49, 0xd8, 0x74, 0x0f,
0x5d, 0x5b, 0x9c, 0x96, 0xdf, 0xbd, 0xd2, 0xdf, 0x86, 0x8c, 0x1d, 0x06, 0x3a, 0x36, 0x59, 0xea,
0xea, 0x5d, 0x8c, 0x85, 0x0c, 0x7d, 0x01, 0x79, 0xc5, 0xf8, 0x75, 0x91, 0x37, 0xbf, 0xfd, 0x5c,
0xd7, 0x2e, 0x6a, 0x3d, 0xb9, 0x96, 0x53, 0xef, 0x64, 0x94, 0x65, 0x9c, 0x14, 0xa1, 0x5b, 0x90,
0xb6, 0x7d, 0x99, 0x14, 0xfa, 0xaf, 0xa2, 0x7a, 0x1b, 0xa7, 0x6d, 0xdf, 0xfc, 0xe7, 0x14, 0xac,
0x34, 0x7d, 0x3b, 0x98, 0xc8, 0x22, 0x29, 0x16, 0xe2, 0x0e, 0x14, 0xc3, 0xf1, 0x41, 0x38, 0x09,
0x39, 0x1d, 0x46, 0x2f, 0xd1, 0xb1, 0x00, 0xb5, 0xa0, 0x48, 0xbc, 0x01, 0x0b, 0x5c, 0x7e, 0x34,
0xd4, 0xdc, 0x78, 0x71, 0x61, 0x4e, 0xda, 0xac, 0x59, 0x91, 0x0a, 0x9e, 0x6a, 0x47, 0xa5, 0x38,
0x23, 0x9d, 0x95, 0xa5, 0xf8, 0x5d, 0x28, 0x7b, 0x64, 0x28, 0xa8, 0x70, 0x5f, 0xdc, 0x83, 0x64,
0x1c, 0x59, 0x5c, 0xd2, 0x32, 0x71, 0xb7, 0x33, 0x4d, 0x28, 0xc6, 0xc6, 0xd0, 0x35, 0x28, 0x59,
0xcd, 0x6e, 0xff, 0x93, 0xcd, 0x07, 0xfd, 0x47, 0xf5, 0x5d, 0x63, 0x49, 0x33, 0x81, 0x7f, 0x4c,
0xc1, 0xca, 0xae, 0xca, 0x41, 0x4d, 0x9c, 0xee, 0xc2, 0x72, 0x40, 0x0e, 0x79, 0x44, 0xed, 0xb2,
0x2a, 0xb9, 0x44, 0x11, 0x10, 0xd4, 0x4e, 0x74, 0x2d, 0xa6, 0x76, 0x89, 0xff, 0x41, 0x32, 0x57,
0xfe, 0x0f, 0x92, 0xfd, 0x8d, 0xfc, 0x0f, 0xf2, 0xc1, 0xaf, 0x32, 0x50, 0x8c, 0x6f, 0xa2, 0x22,
0x65, 0x04, 0xd3, 0x5a, 0x52, 0x2f, 0x3b, 0xb1, 0xbc, 0x2d, 0x39, 0x56, 0xd1, 0xda, 0xd9, 0xd9,
0xab, 0x5b, 0xe2, 0xb2, 0xfe, 0x85, 0xa2, 0x62, 0x31, 0xc0, 0xf2, 0x3c, 0x26, 0x16, 0xdd, 0x41,
0xe6, 0x94, 0x8a, 0xbd, 0xd0, 0xef, 0x47, 0x31, 0x2a, 0xe2, 0x61, 0xef, 0x41, 0xc1, 0xea, 0x76,
0x5b, 0x8f, 0xda, 0xcd, 0x86, 0xf1, 0x32, 0x55, 0xf9, 0xde, 0xd9, 0x79, 0xf5, 0xfa, 0xd4, 0x54,
0x18, 0xba, 0x03, 0x9f, 0x3a, 0x12, 0x55, 0xaf, 0x37, 0x3b, 0x62, 0xbc, 0x17, 0xe9, 0x79, 0x94,
0x24, 0x20, 0xf2, 0x2d, 0xb8, 0xd8, 0xc1, 0xcd, 0x8e, 0x85, 0xc5, 0x88, 0x2f, 0xd3, 0x73, 0x7e,
0x75, 0x02, 0x3a, 0x22, 0x81, 0x18, 0x73, 0x3d, 0xfa, 0x4f, 0xe4, 0x45, 0x46, 0xbd, 0x17, 0x4e,
0xaf, 0xdf, 0x94, 0x38, 0x13, 0x31, 0x5a, 0x77, 0xdf, 0xc2, 0xf2, 0x95, 0xe2, 0x65, 0x66, 0x6e,
0xb4, 0x2e, 0x27, 0x01, 0x17, 0x56, 0x4c, 0x58, 0xc6, 0xbd, 0x76, 0x5b, 0x46, 0x97, 0x9d, 0x8b,
0x0e, 0x8f, 0x7d, 0x5f, 0x60, 0xee, 0x41, 0x21, 0x7a, 0xd5, 0x30, 0x5e, 0x66, 0xe7, 0x1c, 0xaa,
0x47, 0xcf, 0x29, 0x72, 0xc0, 0xc7, 0xbd, 0x7d, 0xf9, 0x97, 0xcd, 0x8b, 0xdc, 0xfc, 0x80, 0x47,
0x63, 0xee, 0x08, 0xf2, 0x5b, 0x8d, 0xd9, 0xe8, 0xcb, 0x9c, 0x22, 0x01, 0x31, 0x46, 0x51, 0x51,
0x61, 0x07, 0x37, 0x7f, 0xaa, 0xfe, 0xdd, 0x79, 0x91, 0x9f, 0xb3, 0x83, 0xe9, 0x57, 0xd4, 0xe6,
0xd4, 0x99, 0x3e, 0x87, 0xc6, 0x5d, 0x1f, 0xfc, 0x01, 0x14, 0xa2, 0x82, 0x81, 0xd6, 0x21, 0xff,
0x6c, 0x0f, 0x3f, 0x69, 0x62, 0x63, 0x49, 0xcd, 0x4e, 0xd4, 0xf3, 0x4c, 0x55, 0xdc, 0x2a, 0x2c,
0xef, 0x5a, 0x6d, 0xeb, 0x51, 0x13, 0x47, 0xcf, 0xb1, 0x11, 0x40, 0x67, 0x7d, 0xc5, 0xd0, 0x03,
0xc4, 0x36, 0xb7, 0xee, 0x7c, 0xfd, 0xcd, 0xfa, 0xd2, 0x2f, 0xbe, 0x59, 0x5f, 0xfa, 0xe5, 0x37,
0xeb, 0xa9, 0x17, 0x97, 0xeb, 0xa9, 0xaf, 0x2f, 0xd7, 0x53, 0x3f, 0xbf, 0x5c, 0x4f, 0xfd, 0xc7,
0xe5, 0x7a, 0xea, 0x20, 0x2f, 0x19, 0xd9, 0xa7, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x84, 0x8b,
0x50, 0xe8, 0x9f, 0x20, 0x00, 0x00,
}

View file

@ -37,13 +37,14 @@ import (
const (
// Security Strength Equivalence
//-----------------------------------
//| Key-type | ECC | DH/DSA/RSA |
//| Node | 256 | 3072 |
//| Root | 384 | 7680 |
//| ECC | DH/DSA/RSA |
//| 256 | 3072 |
//| 384 | 7680 |
//-----------------------------------
// RootKeySize is the default size of the root CA key
RootKeySize = 384
// It would be ideal for the root key to use P-384, but in P-384 is not optimized in go yet :(
RootKeySize = 256
// RootKeyAlgo defines the default algorithm for the root CA Key
RootKeyAlgo = "ecdsa"
// PassphraseENVVar defines the environment variable to look for the

View file

@ -1,6 +1,8 @@
package controlapi
import (
"fmt"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/manager/state/store"
"golang.org/x/net/context"
@ -104,10 +106,22 @@ func (s *Server) ListTasks(ctx context.Context, request *api.ListTasksRequest) (
if request.Filters != nil {
tasks = filterTasks(tasks,
func(e *api.Task) bool {
return filterContains(e.ServiceAnnotations.Name, request.Filters.Names)
name := e.Annotations.Name
if name == "" {
// If Task name is not assigned then calculated name is used like before.
// This might be removed in the future.
name = fmt.Sprintf("%v.%v.%v", e.ServiceAnnotations.Name, e.Slot, e.ID)
}
return filterContains(name, request.Filters.Names)
},
func(e *api.Task) bool {
return filterContainsPrefix(e.ServiceAnnotations.Name, request.Filters.NamePrefixes)
name := e.Annotations.Name
if name == "" {
// If Task name is not assigned then calculated name is used like before
// This might be removed in the future.
name = fmt.Sprintf("%v.%v.%v", e.ServiceAnnotations.Name, e.Slot, e.ID)
}
return filterContainsPrefix(name, request.Filters.NamePrefixes)
},
func(e *api.Task) bool {
return filterContainsPrefix(e.ID, request.Filters.IDPrefixes)

View file

@ -3,8 +3,6 @@ package dispatcher
import (
"errors"
"fmt"
"reflect"
"sort"
"sync"
"time"
@ -13,6 +11,7 @@ import (
"google.golang.org/grpc/transport"
"github.com/Sirupsen/logrus"
"github.com/docker/go-events"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/api/equality"
"github.com/docker/swarmkit/ca"
@ -83,6 +82,7 @@ func DefaultConfig() *Config {
// is implements it. This interface needed only for easier unit-testing.
type Cluster interface {
GetMemberlist() map[uint64]*api.RaftMember
SubscribePeers() (chan events.Event, func())
MemoryStore() *store.MemoryStore
}
@ -120,15 +120,6 @@ type Dispatcher struct {
processUpdatesCond *sync.Cond
}
// weightedPeerByNodeID is a sort wrapper for []*api.WeightedPeer
type weightedPeerByNodeID []*api.WeightedPeer
func (b weightedPeerByNodeID) Less(i, j int) bool { return b[i].Peer.NodeID < b[j].Peer.NodeID }
func (b weightedPeerByNodeID) Len() int { return len(b) }
func (b weightedPeerByNodeID) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
// New returns Dispatcher with cluster interface(usually raft.Node).
// NOTE: each handler which does something with raft must add to Dispatcher.wg
func New(cluster Cluster, c *Config) *Dispatcher {
@ -136,8 +127,8 @@ func New(cluster Cluster, c *Config) *Dispatcher {
nodes: newNodeStore(c.HeartbeatPeriod, c.HeartbeatEpsilon, c.GracePeriodMultiplier, c.RateLimitPeriod),
store: cluster.MemoryStore(),
cluster: cluster,
mgrQueue: watch.NewQueue(16),
keyMgrQueue: watch.NewQueue(16),
mgrQueue: watch.NewQueue(),
keyMgrQueue: watch.NewQueue(),
taskUpdates: make(map[string]*api.TaskStatus),
nodeUpdates: make(map[string]nodeUpdate),
processUpdatesTrigger: make(chan struct{}, 1),
@ -204,34 +195,36 @@ func (d *Dispatcher) Run(ctx context.Context) error {
d.mu.Unlock()
return err
}
peerWatcher, peerCancel := d.cluster.SubscribePeers()
defer peerCancel()
d.lastSeenManagers = getWeightedPeers(d.cluster)
defer cancel()
d.ctx, d.cancel = context.WithCancel(ctx)
d.mu.Unlock()
publishManagers := func() {
mgrs := getWeightedPeers(d.cluster)
sort.Sort(weightedPeerByNodeID(mgrs))
d.mu.Lock()
if reflect.DeepEqual(mgrs, d.lastSeenManagers) {
d.mu.Unlock()
return
publishManagers := func(peers []*api.Peer) {
var mgrs []*api.WeightedPeer
for _, p := range peers {
mgrs = append(mgrs, &api.WeightedPeer{
Peer: p,
Weight: picker.DefaultObservationWeight,
})
}
d.mu.Lock()
d.lastSeenManagers = mgrs
d.mu.Unlock()
d.mgrQueue.Publish(mgrs)
}
publishManagers()
publishTicker := time.NewTicker(1 * time.Second)
defer publishTicker.Stop()
batchTimer := time.NewTimer(maxBatchInterval)
defer batchTimer.Stop()
for {
select {
case <-publishTicker.C:
publishManagers()
case ev := <-peerWatcher:
publishManagers(ev.([]*api.Peer))
case <-d.processUpdatesTrigger:
d.processUpdates()
batchTimer.Reset(maxBatchInterval)
@ -252,7 +245,7 @@ func (d *Dispatcher) Run(ctx context.Context) error {
}
d.networkBootstrapKeys = cluster.Cluster.NetworkBootstrapKeys
d.mu.Unlock()
d.keyMgrQueue.Publish(struct{}{})
d.keyMgrQueue.Publish(cluster.Cluster.NetworkBootstrapKeys)
case <-d.ctx.Done():
return nil
}
@ -277,6 +270,9 @@ func (d *Dispatcher) Stop() error {
d.processUpdatesCond.Broadcast()
d.processUpdatesLock.Unlock()
d.mgrQueue.Close()
d.keyMgrQueue.Close()
return nil
}
@ -760,6 +756,12 @@ func (d *Dispatcher) getManagers() []*api.WeightedPeer {
return d.lastSeenManagers
}
func (d *Dispatcher) getNetworkBootstrapKeys() []*api.EncryptionKey {
d.mu.Lock()
defer d.mu.Unlock()
return d.networkBootstrapKeys
}
// Session is a stream which controls agent connection.
// Each message contains list of backup Managers with weights. Also there is
// a special boolean field Disconnect which if true indicates that node should
@ -776,10 +778,15 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
return err
}
// register the node.
sessionID, err := d.register(stream.Context(), nodeID, r.Description)
if err != nil {
return err
var sessionID string
if _, err := d.nodes.GetWithSession(nodeID, r.SessionID); err != nil {
// register the node.
sessionID, err = d.register(stream.Context(), nodeID, r.Description)
if err != nil {
return err
}
} else {
sessionID = r.SessionID
}
fields := logrus.Fields{
@ -815,7 +822,7 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
SessionID: sessionID,
Node: nodeObj,
Managers: d.getManagers(),
NetworkBootstrapKeys: d.networkBootstrapKeys,
NetworkBootstrapKeys: d.getNetworkBootstrapKeys(),
}); err != nil {
return err
}
@ -854,9 +861,11 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
return err
}
var mgrs []*api.WeightedPeer
var disconnect bool
var (
disconnect bool
mgrs []*api.WeightedPeer
netKeys []*api.EncryptionKey
)
select {
case ev := <-managerUpdates:
@ -869,17 +878,21 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
disconnect = true
case <-d.ctx.Done():
disconnect = true
case <-keyMgrUpdates:
case ev := <-keyMgrUpdates:
netKeys = ev.([]*api.EncryptionKey)
}
if mgrs == nil {
mgrs = d.getManagers()
}
if netKeys == nil {
netKeys = d.getNetworkBootstrapKeys()
}
if err := stream.Send(&api.SessionMessage{
SessionID: sessionID,
Node: nodeObj,
Managers: mgrs,
NetworkBootstrapKeys: d.networkBootstrapKeys,
NetworkBootstrapKeys: netKeys,
}); err != nil {
return err
}

View file

@ -12,6 +12,7 @@ import (
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/go-events"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/ca"
"github.com/docker/swarmkit/log"
@ -230,9 +231,6 @@ func New(config *Config) (*Manager, error) {
// Run starts all manager sub-systems and the gRPC server at the configured
// address.
// The call never returns unless an error occurs or `Stop()` is called.
//
// TODO(aluzzardi): /!\ This function is *way* too complex. /!\
// It needs to be split into smaller manageable functions.
func (m *Manager) Run(parent context.Context) error {
ctx, ctxCancel := context.WithCancel(parent)
defer ctxCancel()
@ -249,191 +247,7 @@ func (m *Manager) Run(parent context.Context) error {
leadershipCh, cancel := m.RaftNode.SubscribeLeadership()
defer cancel()
go func() {
for leadershipEvent := range leadershipCh {
// read out and discard all of the messages when we've stopped
// don't acquire the mutex yet. if stopped is closed, we don't need
// this stops this loop from starving Run()'s attempt to Lock
select {
case <-m.stopped:
continue
default:
// do nothing, we're not stopped
}
// we're not stopping so NOW acquire the mutex
m.mu.Lock()
newState := leadershipEvent.(raft.LeadershipState)
if newState == raft.IsLeader {
s := m.RaftNode.MemoryStore()
rootCA := m.config.SecurityConfig.RootCA()
nodeID := m.config.SecurityConfig.ClientTLSCreds.NodeID()
raftCfg := raft.DefaultRaftConfig()
raftCfg.ElectionTick = uint32(m.RaftNode.Config.ElectionTick)
raftCfg.HeartbeatTick = uint32(m.RaftNode.Config.HeartbeatTick)
clusterID := m.config.SecurityConfig.ClientTLSCreds.Organization()
initialCAConfig := ca.DefaultCAConfig()
initialCAConfig.ExternalCAs = m.config.ExternalCAs
s.Update(func(tx store.Tx) error {
// Add a default cluster object to the
// store. Don't check the error because
// we expect this to fail unless this
// is a brand new cluster.
store.CreateCluster(tx, &api.Cluster{
ID: clusterID,
Spec: api.ClusterSpec{
Annotations: api.Annotations{
Name: store.DefaultClusterName,
},
Orchestration: api.OrchestrationConfig{
TaskHistoryRetentionLimit: defaultTaskHistoryRetentionLimit,
},
Dispatcher: api.DispatcherConfig{
HeartbeatPeriod: ptypes.DurationProto(dispatcher.DefaultHeartBeatPeriod),
},
Raft: raftCfg,
CAConfig: initialCAConfig,
},
RootCA: api.RootCA{
CAKey: rootCA.Key,
CACert: rootCA.Cert,
CACertHash: rootCA.Digest.String(),
JoinTokens: api.JoinTokens{
Worker: ca.GenerateJoinToken(rootCA),
Manager: ca.GenerateJoinToken(rootCA),
},
},
})
// Add Node entry for ourself, if one
// doesn't exist already.
store.CreateNode(tx, &api.Node{
ID: nodeID,
Certificate: api.Certificate{
CN: nodeID,
Role: api.NodeRoleManager,
Status: api.IssuanceStatus{
State: api.IssuanceStateIssued,
},
},
Spec: api.NodeSpec{
Role: api.NodeRoleManager,
Membership: api.NodeMembershipAccepted,
},
})
return nil
})
// Attempt to rotate the key-encrypting-key of the root CA key-material
err := m.rotateRootCAKEK(ctx, clusterID)
if err != nil {
log.G(ctx).WithError(err).Error("root key-encrypting-key rotation failed")
}
m.replicatedOrchestrator = orchestrator.NewReplicatedOrchestrator(s)
m.globalOrchestrator = orchestrator.NewGlobalOrchestrator(s)
m.taskReaper = orchestrator.NewTaskReaper(s)
m.scheduler = scheduler.New(s)
m.keyManager = keymanager.New(m.RaftNode.MemoryStore(), keymanager.DefaultConfig())
// TODO(stevvooe): Allocate a context that can be used to
// shutdown underlying manager processes when leadership is
// lost.
m.allocator, err = allocator.New(s)
if err != nil {
log.G(ctx).WithError(err).Error("failed to create allocator")
// TODO(stevvooe): It doesn't seem correct here to fail
// creating the allocator but then use it anyway.
}
if m.keyManager != nil {
go func(keyManager *keymanager.KeyManager) {
if err := keyManager.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("keymanager failed with an error")
}
}(m.keyManager)
}
go func(d *dispatcher.Dispatcher) {
if err := d.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("Dispatcher exited with an error")
}
}(m.Dispatcher)
go func(server *ca.Server) {
if err := server.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("CA signer exited with an error")
}
}(m.caserver)
// Start all sub-components in separate goroutines.
// TODO(aluzzardi): This should have some kind of error handling so that
// any component that goes down would bring the entire manager down.
if m.allocator != nil {
go func(allocator *allocator.Allocator) {
if err := allocator.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("allocator exited with an error")
}
}(m.allocator)
}
go func(scheduler *scheduler.Scheduler) {
if err := scheduler.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("scheduler exited with an error")
}
}(m.scheduler)
go func(taskReaper *orchestrator.TaskReaper) {
taskReaper.Run()
}(m.taskReaper)
go func(orchestrator *orchestrator.ReplicatedOrchestrator) {
if err := orchestrator.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("replicated orchestrator exited with an error")
}
}(m.replicatedOrchestrator)
go func(globalOrchestrator *orchestrator.GlobalOrchestrator) {
if err := globalOrchestrator.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("global orchestrator exited with an error")
}
}(m.globalOrchestrator)
} else if newState == raft.IsFollower {
m.Dispatcher.Stop()
m.caserver.Stop()
if m.allocator != nil {
m.allocator.Stop()
m.allocator = nil
}
m.replicatedOrchestrator.Stop()
m.replicatedOrchestrator = nil
m.globalOrchestrator.Stop()
m.globalOrchestrator = nil
m.taskReaper.Stop()
m.taskReaper = nil
m.scheduler.Stop()
m.scheduler = nil
if m.keyManager != nil {
m.keyManager.Stop()
m.keyManager = nil
}
}
m.mu.Unlock()
}
}()
go m.handleLeadershipEvents(ctx, leadershipCh)
proxyOpts := []grpc.DialOption{
grpc.WithTimeout(5 * time.Second),
@ -498,22 +312,7 @@ func (m *Manager) Run(parent context.Context) error {
errServe := make(chan error, 2)
for proto, l := range m.listeners {
go func(proto string, lis net.Listener) {
ctx := log.WithLogger(ctx, log.G(ctx).WithFields(
logrus.Fields{
"proto": lis.Addr().Network(),
"addr": lis.Addr().String()}))
if proto == "unix" {
log.G(ctx).Info("Listening for local connections")
// we need to disallow double closes because UnixListener.Close
// can delete unix-socket file of newer listener. grpc calls
// Close twice indeed: in Serve and in Stop.
errServe <- m.localserver.Serve(&closeOnceListener{Listener: lis})
} else {
log.G(ctx).Info("Listening for connections")
errServe <- m.server.Serve(lis)
}
}(proto, l)
go m.serveListener(ctx, errServe, proto, l)
}
// Set the raft server as serving for the health server
@ -727,3 +526,228 @@ func (m *Manager) rotateRootCAKEK(ctx context.Context, clusterID string) error {
})
}
// handleLeadershipEvents reads out and discards all of the messages when the manager is stopped,
// otherwise it handles the is leader event or is follower event.
func (m *Manager) handleLeadershipEvents(ctx context.Context, leadershipCh chan events.Event) {
for leadershipEvent := range leadershipCh {
// read out and discard all of the messages when we've stopped
// don't acquire the mutex yet. if stopped is closed, we don't need
// this stops this loop from starving Run()'s attempt to Lock
select {
case <-m.stopped:
continue
default:
// do nothing, we're not stopped
}
// we're not stopping so NOW acquire the mutex
m.mu.Lock()
newState := leadershipEvent.(raft.LeadershipState)
if newState == raft.IsLeader {
m.becomeLeader(ctx)
} else if newState == raft.IsFollower {
m.becomeFollower()
}
m.mu.Unlock()
}
}
// serveListener serves a listener for local and non local connections.
func (m *Manager) serveListener(ctx context.Context, errServe chan error, proto string, lis net.Listener) {
ctx = log.WithLogger(ctx, log.G(ctx).WithFields(
logrus.Fields{
"proto": lis.Addr().Network(),
"addr": lis.Addr().String()}))
if proto == "unix" {
log.G(ctx).Info("Listening for local connections")
// we need to disallow double closes because UnixListener.Close
// can delete unix-socket file of newer listener. grpc calls
// Close twice indeed: in Serve and in Stop.
errServe <- m.localserver.Serve(&closeOnceListener{Listener: lis})
} else {
log.G(ctx).Info("Listening for connections")
errServe <- m.server.Serve(lis)
}
}
// becomeLeader starts the subsystems that are run on the leader.
func (m *Manager) becomeLeader(ctx context.Context) {
s := m.RaftNode.MemoryStore()
rootCA := m.config.SecurityConfig.RootCA()
nodeID := m.config.SecurityConfig.ClientTLSCreds.NodeID()
raftCfg := raft.DefaultRaftConfig()
raftCfg.ElectionTick = uint32(m.RaftNode.Config.ElectionTick)
raftCfg.HeartbeatTick = uint32(m.RaftNode.Config.HeartbeatTick)
clusterID := m.config.SecurityConfig.ClientTLSCreds.Organization()
initialCAConfig := ca.DefaultCAConfig()
initialCAConfig.ExternalCAs = m.config.ExternalCAs
s.Update(func(tx store.Tx) error {
// Add a default cluster object to the
// store. Don't check the error because
// we expect this to fail unless this
// is a brand new cluster.
store.CreateCluster(tx, defaultClusterObject(clusterID, initialCAConfig, raftCfg, rootCA))
// Add Node entry for ourself, if one
// doesn't exist already.
store.CreateNode(tx, managerNode(nodeID))
return nil
})
// Attempt to rotate the key-encrypting-key of the root CA key-material
err := m.rotateRootCAKEK(ctx, clusterID)
if err != nil {
log.G(ctx).WithError(err).Error("root key-encrypting-key rotation failed")
}
m.replicatedOrchestrator = orchestrator.NewReplicatedOrchestrator(s)
m.globalOrchestrator = orchestrator.NewGlobalOrchestrator(s)
m.taskReaper = orchestrator.NewTaskReaper(s)
m.scheduler = scheduler.New(s)
m.keyManager = keymanager.New(m.RaftNode.MemoryStore(), keymanager.DefaultConfig())
// TODO(stevvooe): Allocate a context that can be used to
// shutdown underlying manager processes when leadership is
// lost.
m.allocator, err = allocator.New(s)
if err != nil {
log.G(ctx).WithError(err).Error("failed to create allocator")
// TODO(stevvooe): It doesn't seem correct here to fail
// creating the allocator but then use it anyway.
}
if m.keyManager != nil {
go func(keyManager *keymanager.KeyManager) {
if err := keyManager.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("keymanager failed with an error")
}
}(m.keyManager)
}
go func(d *dispatcher.Dispatcher) {
if err := d.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("Dispatcher exited with an error")
}
}(m.Dispatcher)
go func(server *ca.Server) {
if err := server.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("CA signer exited with an error")
}
}(m.caserver)
// Start all sub-components in separate goroutines.
// TODO(aluzzardi): This should have some kind of error handling so that
// any component that goes down would bring the entire manager down.
if m.allocator != nil {
go func(allocator *allocator.Allocator) {
if err := allocator.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("allocator exited with an error")
}
}(m.allocator)
}
go func(scheduler *scheduler.Scheduler) {
if err := scheduler.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("scheduler exited with an error")
}
}(m.scheduler)
go func(taskReaper *orchestrator.TaskReaper) {
taskReaper.Run()
}(m.taskReaper)
go func(orchestrator *orchestrator.ReplicatedOrchestrator) {
if err := orchestrator.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("replicated orchestrator exited with an error")
}
}(m.replicatedOrchestrator)
go func(globalOrchestrator *orchestrator.GlobalOrchestrator) {
if err := globalOrchestrator.Run(ctx); err != nil {
log.G(ctx).WithError(err).Error("global orchestrator exited with an error")
}
}(m.globalOrchestrator)
}
// becomeFollower shuts down the subsystems that are only run by the leader.
func (m *Manager) becomeFollower() {
m.Dispatcher.Stop()
m.caserver.Stop()
if m.allocator != nil {
m.allocator.Stop()
m.allocator = nil
}
m.replicatedOrchestrator.Stop()
m.replicatedOrchestrator = nil
m.globalOrchestrator.Stop()
m.globalOrchestrator = nil
m.taskReaper.Stop()
m.taskReaper = nil
m.scheduler.Stop()
m.scheduler = nil
if m.keyManager != nil {
m.keyManager.Stop()
m.keyManager = nil
}
}
// defaultClusterObject creates a default cluster.
func defaultClusterObject(clusterID string, initialCAConfig api.CAConfig, raftCfg api.RaftConfig, rootCA *ca.RootCA) *api.Cluster {
return &api.Cluster{
ID: clusterID,
Spec: api.ClusterSpec{
Annotations: api.Annotations{
Name: store.DefaultClusterName,
},
Orchestration: api.OrchestrationConfig{
TaskHistoryRetentionLimit: defaultTaskHistoryRetentionLimit,
},
Dispatcher: api.DispatcherConfig{
HeartbeatPeriod: ptypes.DurationProto(dispatcher.DefaultHeartBeatPeriod),
},
Raft: raftCfg,
CAConfig: initialCAConfig,
},
RootCA: api.RootCA{
CAKey: rootCA.Key,
CACert: rootCA.Cert,
CACertHash: rootCA.Digest.String(),
JoinTokens: api.JoinTokens{
Worker: ca.GenerateJoinToken(rootCA),
Manager: ca.GenerateJoinToken(rootCA),
},
},
}
}
// managerNode creates a new node with NodeRoleManager role.
func managerNode(nodeID string) *api.Node {
return &api.Node{
ID: nodeID,
Certificate: api.Certificate{
CN: nodeID,
Role: api.NodeRoleManager,
Status: api.IssuanceStatus{
State: api.IssuanceStateIssued,
},
},
Spec: api.NodeSpec{
Role: api.NodeRoleManager,
Membership: api.NodeMembershipAccepted,
},
}
}

View file

@ -226,7 +226,7 @@ func (g *GlobalOrchestrator) reconcileOneService(ctx context.Context, service *a
}
_, err = g.store.Batch(func(batch *store.Batch) error {
var updateTasks []*api.Task
var updateTasks []slot
for nodeID := range g.nodes {
ntasks := nodeTasks[nodeID]
// if restart policy considers this node has finished its task
@ -239,8 +239,7 @@ func (g *GlobalOrchestrator) reconcileOneService(ctx context.Context, service *a
if len(ntasks) == 0 {
g.addTask(ctx, batch, service, nodeID)
} else {
updateTasks = append(updateTasks, ntasks[0])
g.removeTasks(ctx, batch, service, ntasks[1:])
updateTasks = append(updateTasks, ntasks)
}
}
if len(updateTasks) > 0 {
@ -327,11 +326,8 @@ func (g *GlobalOrchestrator) reconcileServiceOneNode(ctx context.Context, servic
g.removeTasks(ctx, batch, service, tasks)
return nil
}
// this node needs to run 1 copy of the task
if len(tasks) == 0 {
g.addTask(ctx, batch, service, nodeID)
} else {
g.removeTasks(ctx, batch, service, tasks[1:])
}
return nil
})
@ -365,7 +361,7 @@ func (g *GlobalOrchestrator) removeTask(ctx context.Context, batch *store.Batch,
// TODO(aaronl): optimistic update?
err := batch.Update(func(tx store.Tx) error {
t = store.GetTask(tx, t.ID)
if t != nil {
if t != nil && t.DesiredState < api.TaskStateShutdown {
t.DesiredState = api.TaskStateShutdown
return store.UpdateTask(tx, t)
}

View file

@ -1,6 +1,7 @@
package orchestrator
import (
"fmt"
"time"
"github.com/docker/swarmkit/api"
@ -110,7 +111,7 @@ func (r *ReplicatedOrchestrator) tick(ctx context.Context) {
r.tickServices(ctx)
}
func newTask(cluster *api.Cluster, service *api.Service, instance uint64) *api.Task {
func newTask(cluster *api.Cluster, service *api.Service, slot uint64) *api.Task {
var logDriver *api.Driver
if service.Spec.Task.LogDriver != nil {
// use the log driver specific to the task, if we have it.
@ -120,15 +121,18 @@ func newTask(cluster *api.Cluster, service *api.Service, instance uint64) *api.T
logDriver = cluster.Spec.TaskDefaults.LogDriver // nil is okay here.
}
// NOTE(stevvooe): For now, we don't override the container naming and
// labeling scheme in the agent. If we decide to do this in the future,
// they should be overridden here.
taskID := identity.NewID()
// We use the following scheme to assign Task names to Annotations:
// Annotations.Name := <ServiceAnnotations.Name>.<Slot>.<TaskID>
name := fmt.Sprintf("%v.%v.%v", service.Spec.Annotations.Name, slot, taskID)
return &api.Task{
ID: identity.NewID(),
ID: taskID,
Annotations: api.Annotations{Name: name},
ServiceAnnotations: service.Spec.Annotations,
Spec: service.Spec.Task,
ServiceID: service.ID,
Slot: instance,
Slot: slot,
Status: api.TaskStatus{
State: api.TaskStateNew,
Timestamp: ptypes.MustTimestampProto(time.Now()),

View file

@ -85,81 +85,39 @@ func (r *ReplicatedOrchestrator) resolveService(ctx context.Context, task *api.T
return service
}
type tasksByRunningState []*api.Task
func (ts tasksByRunningState) Len() int { return len(ts) }
func (ts tasksByRunningState) Swap(i, j int) { ts[i], ts[j] = ts[j], ts[i] }
func (ts tasksByRunningState) Less(i, j int) bool {
return ts[i].Status.State == api.TaskStateRunning && ts[j].Status.State != api.TaskStateRunning
}
type taskWithIndex struct {
task *api.Task
// index is a counter that counts this task as the nth instance of
// the service on its node. This is used for sorting the tasks so that
// when scaling down we leave tasks more evenly balanced.
index int
}
type tasksByIndex []taskWithIndex
func (ts tasksByIndex) Len() int { return len(ts) }
func (ts tasksByIndex) Swap(i, j int) { ts[i], ts[j] = ts[j], ts[i] }
func (ts tasksByIndex) Less(i, j int) bool {
if ts[i].index < 0 {
return false
}
return ts[i].index < ts[j].index
}
func (r *ReplicatedOrchestrator) reconcile(ctx context.Context, service *api.Service) {
var (
tasks []*api.Task
err error
)
r.store.View(func(tx store.ReadTx) {
tasks, err = store.FindTasks(tx, store.ByServiceID(service.ID))
})
runningSlots, err := getRunnableSlots(r.store, service.ID)
if err != nil {
log.G(ctx).WithError(err).Errorf("reconcile failed finding tasks")
return
}
runningTasks := make([]*api.Task, 0, len(tasks))
runningInstances := make(map[uint64]struct{}) // this could be a bitfield...
for _, t := range tasks {
// Technically the check below could just be
// t.DesiredState <= api.TaskStateRunning, but ignoring tasks
// with DesiredState == NEW simplifies the drainer unit tests.
if t.DesiredState > api.TaskStateNew && t.DesiredState <= api.TaskStateRunning {
runningTasks = append(runningTasks, t)
runningInstances[t.Slot] = struct{}{}
}
numSlots := len(runningSlots)
slotsSlice := make([]slot, 0, numSlots)
for _, slot := range runningSlots {
slotsSlice = append(slotsSlice, slot)
}
numTasks := len(runningTasks)
deploy := service.Spec.GetMode().(*api.ServiceSpec_Replicated)
specifiedInstances := int(deploy.Replicated.Replicas)
specifiedSlots := int(deploy.Replicated.Replicas)
switch {
case specifiedInstances > numTasks:
log.G(ctx).Debugf("Service %s was scaled up from %d to %d instances", service.ID, numTasks, specifiedInstances)
case specifiedSlots > numSlots:
log.G(ctx).Debugf("Service %s was scaled up from %d to %d instances", service.ID, numSlots, specifiedSlots)
// Update all current tasks then add missing tasks
r.updater.Update(ctx, r.cluster, service, runningTasks)
r.updater.Update(ctx, r.cluster, service, slotsSlice)
_, err = r.store.Batch(func(batch *store.Batch) error {
r.addTasks(ctx, batch, service, runningInstances, specifiedInstances-numTasks)
r.addTasks(ctx, batch, service, runningSlots, specifiedSlots-numSlots)
return nil
})
if err != nil {
log.G(ctx).WithError(err).Errorf("reconcile batch failed")
}
case specifiedInstances < numTasks:
case specifiedSlots < numSlots:
// Update up to N tasks then remove the extra
log.G(ctx).Debugf("Service %s was scaled down from %d to %d instances", service.ID, numTasks, specifiedInstances)
log.G(ctx).Debugf("Service %s was scaled down from %d to %d instances", service.ID, numSlots, specifiedSlots)
// Preferentially remove tasks on the nodes that have the most
// copies of this service, to leave a more balanced result.
@ -169,59 +127,59 @@ func (r *ReplicatedOrchestrator) reconcile(ctx context.Context, service *api.Ser
// This will cause us to prefer to remove non-running tasks, all
// other things being equal in terms of node balance.
sort.Sort(tasksByRunningState(runningTasks))
sort.Sort(slotsByRunningState(slotsSlice))
// Assign each task an index that counts it as the nth copy of
// of the service on its node (1, 2, 3, ...), and sort the
// tasks by this counter value.
instancesByNode := make(map[string]int)
tasksWithIndices := make(tasksByIndex, 0, numTasks)
slotsByNode := make(map[string]int)
slotsWithIndices := make(slotsByIndex, 0, numSlots)
for _, t := range runningTasks {
if t.NodeID != "" {
instancesByNode[t.NodeID]++
tasksWithIndices = append(tasksWithIndices, taskWithIndex{task: t, index: instancesByNode[t.NodeID]})
for _, slot := range slotsSlice {
if len(slot) == 1 && slot[0].NodeID != "" {
slotsByNode[slot[0].NodeID]++
slotsWithIndices = append(slotsWithIndices, slotWithIndex{slot: slot, index: slotsByNode[slot[0].NodeID]})
} else {
tasksWithIndices = append(tasksWithIndices, taskWithIndex{task: t, index: -1})
slotsWithIndices = append(slotsWithIndices, slotWithIndex{slot: slot, index: -1})
}
}
sort.Sort(tasksWithIndices)
sort.Sort(slotsWithIndices)
sortedTasks := make([]*api.Task, 0, numTasks)
for _, t := range tasksWithIndices {
sortedTasks = append(sortedTasks, t.task)
sortedSlots := make([]slot, 0, numSlots)
for _, slot := range slotsWithIndices {
sortedSlots = append(sortedSlots, slot.slot)
}
r.updater.Update(ctx, r.cluster, service, sortedTasks[:specifiedInstances])
r.updater.Update(ctx, r.cluster, service, sortedSlots[:specifiedSlots])
_, err = r.store.Batch(func(batch *store.Batch) error {
r.removeTasks(ctx, batch, service, sortedTasks[specifiedInstances:])
r.removeTasks(ctx, batch, service, sortedSlots[specifiedSlots:])
return nil
})
if err != nil {
log.G(ctx).WithError(err).Errorf("reconcile batch failed")
}
case specifiedInstances == numTasks:
case specifiedSlots == numSlots:
// Simple update, no scaling - update all tasks.
r.updater.Update(ctx, r.cluster, service, runningTasks)
r.updater.Update(ctx, r.cluster, service, slotsSlice)
}
}
func (r *ReplicatedOrchestrator) addTasks(ctx context.Context, batch *store.Batch, service *api.Service, runningInstances map[uint64]struct{}, count int) {
instance := uint64(0)
func (r *ReplicatedOrchestrator) addTasks(ctx context.Context, batch *store.Batch, service *api.Service, runningSlots map[uint64]slot, count int) {
slot := uint64(0)
for i := 0; i < count; i++ {
// Find an instance number that is missing a running task
// Find an slot number that is missing a running task
for {
instance++
if _, ok := runningInstances[instance]; !ok {
slot++
if _, ok := runningSlots[slot]; !ok {
break
}
}
err := batch.Update(func(tx store.Tx) error {
return store.CreateTask(tx, newTask(r.cluster, service, instance))
return store.CreateTask(tx, newTask(r.cluster, service, slot))
})
if err != nil {
log.G(ctx).Errorf("Failed to create task: %v", err)
@ -229,19 +187,48 @@ func (r *ReplicatedOrchestrator) addTasks(ctx context.Context, batch *store.Batc
}
}
func (r *ReplicatedOrchestrator) removeTasks(ctx context.Context, batch *store.Batch, service *api.Service, tasks []*api.Task) {
for _, t := range tasks {
err := batch.Update(func(tx store.Tx) error {
// TODO(aaronl): optimistic update?
t = store.GetTask(tx, t.ID)
if t != nil {
t.DesiredState = api.TaskStateShutdown
return store.UpdateTask(tx, t)
func (r *ReplicatedOrchestrator) removeTasks(ctx context.Context, batch *store.Batch, service *api.Service, slots []slot) {
for _, slot := range slots {
for _, t := range slot {
err := batch.Update(func(tx store.Tx) error {
// TODO(aaronl): optimistic update?
t = store.GetTask(tx, t.ID)
if t != nil && t.DesiredState < api.TaskStateShutdown {
t.DesiredState = api.TaskStateShutdown
return store.UpdateTask(tx, t)
}
return nil
})
if err != nil {
log.G(ctx).WithError(err).Errorf("removing task %s failed", t.ID)
}
return nil
})
if err != nil {
log.G(ctx).WithError(err).Errorf("removing task %s failed", t.ID)
}
}
}
// getRunnableSlots returns a map of slots that have at least one task with
// a desired state above NEW and lesser or equal to RUNNING.
func getRunnableSlots(s *store.MemoryStore, serviceID string) (map[uint64]slot, error) {
var (
tasks []*api.Task
err error
)
s.View(func(tx store.ReadTx) {
tasks, err = store.FindTasks(tx, store.ByServiceID(serviceID))
})
if err != nil {
return nil, err
}
runningSlots := make(map[uint64]slot)
for _, t := range tasks {
// Technically the check below could just be
// t.DesiredState <= api.TaskStateRunning, but ignoring tasks
// with DesiredState == NEW simplifies the drainer unit tests.
if t.DesiredState > api.TaskStateNew && t.DesiredState <= api.TaskStateRunning {
runningSlots[t.Slot] = append(runningSlots[t.Slot], t)
}
}
return runningSlots, nil
}

View file

@ -0,0 +1,61 @@
package orchestrator
import (
"github.com/docker/swarmkit/api"
)
// slot is a list of the running tasks occupying a certain slot. Generally this
// will only be one task, but some rolling update situations involve
// temporarily having two running tasks in the same slot. Note that this use of
// "slot" is more generic than the Slot number for replicated services - a node
// is also considered a slot for global services.
type slot []*api.Task
type slotsByRunningState []slot
func (is slotsByRunningState) Len() int { return len(is) }
func (is slotsByRunningState) Swap(i, j int) { is[i], is[j] = is[j], is[i] }
func (is slotsByRunningState) Less(i, j int) bool {
iRunning := false
jRunning := false
for _, ii := range is[i] {
if ii.Status.State == api.TaskStateRunning {
iRunning = true
break
}
}
for _, ij := range is[j] {
if ij.Status.State == api.TaskStateRunning {
jRunning = true
break
}
}
return iRunning && !jRunning
}
type slotWithIndex struct {
slot slot
// index is a counter that counts this task as the nth instance of
// the service on its node. This is used for sorting the tasks so that
// when scaling down we leave tasks more evenly balanced.
index int
}
type slotsByIndex []slotWithIndex
func (is slotsByIndex) Len() int { return len(is) }
func (is slotsByIndex) Swap(i, j int) { is[i], is[j] = is[j], is[i] }
func (is slotsByIndex) Less(i, j int) bool {
if is[i].index < 0 && is[j].index >= 0 {
return false
}
if is[j].index < 0 && is[i].index >= 0 {
return true
}
return is[i].index < is[j].index
}

View file

@ -13,6 +13,8 @@ import (
const (
// maxDirty is the size threshold for running a task pruning operation.
maxDirty = 1000
// reaperBatchingInterval is how often to prune old tasks.
reaperBatchingInterval = 250 * time.Millisecond
)
type instanceTuple struct {
@ -59,8 +61,7 @@ func (tr *TaskReaper) Run() {
}
})
ticker := time.NewTicker(250 * time.Millisecond)
defer ticker.Stop()
timer := time.NewTimer(reaperBatchingInterval)
for {
select {
@ -74,14 +75,19 @@ func (tr *TaskReaper) Run() {
nodeID: t.NodeID,
}] = struct{}{}
if len(tr.dirty) > maxDirty {
timer.Stop()
tr.tick()
} else {
timer.Reset(reaperBatchingInterval)
}
case state.EventUpdateCluster:
tr.taskHistory = v.Cluster.Spec.Orchestration.TaskHistoryRetentionLimit
}
case <-ticker.C:
case <-timer.C:
timer.Stop()
tr.tick()
case <-tr.stopChan:
timer.Stop()
return
}
}

View file

@ -35,9 +35,14 @@ func NewUpdateSupervisor(store *store.MemoryStore, restartSupervisor *RestartSup
}
}
// Update starts an Update of `tasks` belonging to `service` in the background and returns immediately.
// If an update for that service was already in progress, it will be cancelled before the new one starts.
func (u *UpdateSupervisor) Update(ctx context.Context, cluster *api.Cluster, service *api.Service, tasks []*api.Task) {
// Update starts an Update of `slots` belonging to `service` in the background
// and returns immediately. Each slot contains a group of one or more tasks
// occupying the same slot (replicated service) or node (global service). There
// may be more than one task per slot in cases where an update is in progress
// and the new task was started before the old one was shut down. If an update
// for that service was already in progress, it will be cancelled before the
// new one starts.
func (u *UpdateSupervisor) Update(ctx context.Context, cluster *api.Cluster, service *api.Service, slots []slot) {
u.l.Lock()
defer u.l.Unlock()
@ -54,7 +59,7 @@ func (u *UpdateSupervisor) Update(ctx context.Context, cluster *api.Cluster, ser
update := NewUpdater(u.store, u.restarts, cluster, service)
u.updates[id] = update
go func() {
update.Run(ctx, tasks)
update.Run(ctx, slots)
u.l.Lock()
if u.updates[id] == update {
delete(u.updates, id)
@ -108,7 +113,7 @@ func (u *Updater) Cancel() {
}
// Run starts the update and returns only once its complete or cancelled.
func (u *Updater) Run(ctx context.Context, tasks []*api.Task) {
func (u *Updater) Run(ctx context.Context, slots []slot) {
defer close(u.doneChan)
service := u.newService
@ -118,14 +123,14 @@ func (u *Updater) Run(ctx context.Context, tasks []*api.Task) {
return
}
dirtyTasks := []*api.Task{}
for _, t := range tasks {
if u.isTaskDirty(t) {
dirtyTasks = append(dirtyTasks, t)
var dirtySlots []slot
for _, slot := range slots {
if u.isSlotDirty(slot) {
dirtySlots = append(dirtySlots, slot)
}
}
// Abort immediately if all tasks are clean.
if len(dirtyTasks) == 0 {
if len(dirtySlots) == 0 {
if service.UpdateStatus != nil && service.UpdateStatus.State == api.UpdateStatus_UPDATING {
u.completeUpdate(ctx, service.ID)
}
@ -144,16 +149,16 @@ func (u *Updater) Run(ctx context.Context, tasks []*api.Task) {
if parallelism == 0 {
// TODO(aluzzardi): We could try to optimize unlimited parallelism by performing updates in a single
// goroutine using a batch transaction.
parallelism = len(dirtyTasks)
parallelism = len(dirtySlots)
}
// Start the workers.
taskQueue := make(chan *api.Task)
slotQueue := make(chan slot)
wg := sync.WaitGroup{}
wg.Add(parallelism)
for i := 0; i < parallelism; i++ {
go func() {
u.worker(ctx, taskQueue)
u.worker(ctx, slotQueue)
wg.Done()
}()
}
@ -174,15 +179,15 @@ func (u *Updater) Run(ctx context.Context, tasks []*api.Task) {
stopped := false
taskLoop:
for _, t := range dirtyTasks {
slotsLoop:
for _, slot := range dirtySlots {
retryLoop:
for {
// Wait for a worker to pick up the task or abort the update, whichever comes first.
select {
case <-u.stopChan:
stopped = true
break taskLoop
break slotsLoop
case ev := <-failedTaskWatch:
failedTask := ev.(state.EventUpdateTask).Task
@ -193,15 +198,15 @@ taskLoop:
stopped = true
message := fmt.Sprintf("update paused due to failure or early termination of task %s", failedTask.ID)
u.pauseUpdate(ctx, service.ID, message)
break taskLoop
break slotsLoop
}
case taskQueue <- t:
case slotQueue <- slot:
break retryLoop
}
}
}
close(taskQueue)
close(slotQueue)
wg.Wait()
if !stopped {
@ -209,16 +214,42 @@ taskLoop:
}
}
func (u *Updater) worker(ctx context.Context, queue <-chan *api.Task) {
for t := range queue {
updated := newTask(u.cluster, u.newService, t.Slot)
updated.DesiredState = api.TaskStateReady
if isGlobalService(u.newService) {
updated.NodeID = t.NodeID
func (u *Updater) worker(ctx context.Context, queue <-chan slot) {
for slot := range queue {
// Do we have a task with the new spec in desired state = RUNNING?
// If so, all we have to do to complete the update is remove the
// other tasks. Or if we have a task with the new spec that has
// desired state < RUNNING, advance it to running and remove the
// other tasks.
var (
runningTask *api.Task
cleanTask *api.Task
)
for _, t := range slot {
if !u.isTaskDirty(t) {
if t.DesiredState == api.TaskStateRunning {
runningTask = t
break
}
if t.DesiredState < api.TaskStateRunning {
cleanTask = t
}
}
}
if runningTask != nil {
u.useExistingTask(ctx, slot, runningTask)
} else if cleanTask != nil {
u.useExistingTask(ctx, slot, cleanTask)
} else {
updated := newTask(u.cluster, u.newService, slot[0].Slot)
updated.DesiredState = api.TaskStateReady
if isGlobalService(u.newService) {
updated.NodeID = slot[0].NodeID
}
if err := u.updateTask(ctx, t, updated); err != nil {
log.G(ctx).WithError(err).WithField("task.id", t.ID).Error("update failed")
if err := u.updateTask(ctx, slot, updated); err != nil {
log.G(ctx).WithError(err).WithField("task.id", updated.ID).Error("update failed")
}
}
if u.newService.Spec.Update != nil && (u.newService.Spec.Update.Delay.Seconds != 0 || u.newService.Spec.Update.Delay.Nanos != 0) {
@ -236,8 +267,7 @@ func (u *Updater) worker(ctx context.Context, queue <-chan *api.Task) {
}
}
func (u *Updater) updateTask(ctx context.Context, original, updated *api.Task) error {
log.G(ctx).Debugf("replacing %s with %s", original.ID, updated.ID)
func (u *Updater) updateTask(ctx context.Context, slot slot, updated *api.Task) error {
// Kick off the watch before even creating the updated task. This is in order to avoid missing any event.
taskUpdates, cancel := state.Watch(u.watchQueue, state.EventUpdateTask{
Task: &api.Task{ID: updated.ID},
@ -247,26 +277,27 @@ func (u *Updater) updateTask(ctx context.Context, original, updated *api.Task) e
var delayStartCh <-chan struct{}
// Atomically create the updated task and bring down the old one.
err := u.store.Update(func(tx store.Tx) error {
t := store.GetTask(tx, original.ID)
if t == nil {
return fmt.Errorf("task %s not found while trying to update it", original.ID)
}
if t.DesiredState > api.TaskStateRunning {
return fmt.Errorf("task %s was already shut down when reached by updater", original.ID)
}
t.DesiredState = api.TaskStateShutdown
if err := store.UpdateTask(tx, t); err != nil {
_, err := u.store.Batch(func(batch *store.Batch) error {
err := batch.Update(func(tx store.Tx) error {
if err := store.CreateTask(tx, updated); err != nil {
return err
}
return nil
})
if err != nil {
return err
}
if err := store.CreateTask(tx, updated); err != nil {
return err
}
u.removeOldTasks(ctx, batch, slot)
// Wait for the old task to stop or time out, and then set the new one
// to RUNNING.
delayStartCh = u.restarts.DelayStart(ctx, tx, original, updated.ID, 0, true)
for _, t := range slot {
if t.DesiredState == api.TaskStateRunning {
// Wait for the old task to stop or time out, and then set the new one
// to RUNNING.
delayStartCh = u.restarts.DelayStart(ctx, nil, t, updated.ID, 0, true)
break
}
}
return nil
@ -275,7 +306,9 @@ func (u *Updater) updateTask(ctx context.Context, original, updated *api.Task) e
return err
}
<-delayStartCh
if delayStartCh != nil {
<-delayStartCh
}
// Wait for the new task to come up.
// TODO(aluzzardi): Consider adding a timeout here.
@ -292,6 +325,60 @@ func (u *Updater) updateTask(ctx context.Context, original, updated *api.Task) e
}
}
func (u *Updater) useExistingTask(ctx context.Context, slot slot, existing *api.Task) {
var removeTasks []*api.Task
for _, t := range slot {
if t != existing {
removeTasks = append(removeTasks, t)
}
}
if len(removeTasks) != 0 || existing.DesiredState != api.TaskStateRunning {
_, err := u.store.Batch(func(batch *store.Batch) error {
u.removeOldTasks(ctx, batch, removeTasks)
if existing.DesiredState != api.TaskStateRunning {
err := batch.Update(func(tx store.Tx) error {
t := store.GetTask(tx, existing.ID)
if t == nil {
return fmt.Errorf("task %s not found while trying to start it", existing.ID)
}
if t.DesiredState >= api.TaskStateRunning {
return fmt.Errorf("task %s was already started when reached by updater", existing.ID)
}
t.DesiredState = api.TaskStateRunning
return store.UpdateTask(tx, t)
})
if err != nil {
log.G(ctx).WithError(err).Errorf("starting task %s failed", existing.ID)
}
}
return nil
})
if err != nil {
log.G(ctx).WithError(err).Error("updater batch transaction failed")
}
}
}
func (u *Updater) removeOldTasks(ctx context.Context, batch *store.Batch, removeTasks []*api.Task) {
for _, original := range removeTasks {
err := batch.Update(func(tx store.Tx) error {
t := store.GetTask(tx, original.ID)
if t == nil {
return fmt.Errorf("task %s not found while trying to shut it down", original.ID)
}
if t.DesiredState > api.TaskStateRunning {
return fmt.Errorf("task %s was already shut down when reached by updater", original.ID)
}
t.DesiredState = api.TaskStateShutdown
return store.UpdateTask(tx, t)
})
if err != nil {
log.G(ctx).WithError(err).Errorf("shutting down stale task %s failed", original.ID)
}
}
}
func (u *Updater) isTaskDirty(t *api.Task) bool {
return !reflect.DeepEqual(u.newService.Spec.Task, t.Spec) ||
(t.Endpoint != nil && !reflect.DeepEqual(u.newService.Spec.Endpoint, t.Endpoint.Spec))
@ -302,6 +389,10 @@ func (u *Updater) isServiceDirty(service *api.Service) bool {
!reflect.DeepEqual(u.newService.Spec.Endpoint, service.Spec.Endpoint)
}
func (u *Updater) isSlotDirty(slot slot) bool {
return len(slot) > 1 || (len(slot) == 1 && u.isTaskDirty(slot[0]))
}
func (u *Updater) startUpdate(ctx context.Context, serviceID string) {
err := u.store.Update(func(tx store.Tx) error {
service := store.GetService(tx, serviceID)

View file

@ -8,6 +8,7 @@ import (
"github.com/coreos/etcd/raft/raftpb"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/manager/state/watch"
"github.com/gogo/protobuf/proto"
)
@ -33,6 +34,8 @@ type Cluster struct {
// removed contains the list of removed Members,
// those ids cannot be reused
removed map[uint64]bool
PeersBroadcast *watch.Queue
}
// Member represents a raft Cluster Member
@ -49,8 +52,9 @@ func NewCluster() *Cluster {
// TODO(abronan): generate Cluster ID for federation
return &Cluster{
members: make(map[uint64]*Member),
removed: make(map[uint64]bool),
members: make(map[uint64]*Member),
removed: make(map[uint64]bool),
PeersBroadcast: watch.NewQueue(),
}
}
@ -83,6 +87,17 @@ func (c *Cluster) GetMember(id uint64) *Member {
return c.members[id]
}
func (c *Cluster) broadcastUpdate() {
peers := make([]*api.Peer, 0, len(c.members))
for _, m := range c.members {
peers = append(peers, &api.Peer{
NodeID: m.NodeID,
Addr: m.Addr,
})
}
c.PeersBroadcast.Publish(peers)
}
// AddMember adds a node to the Cluster Memberlist.
func (c *Cluster) AddMember(member *Member) error {
c.mu.Lock()
@ -93,6 +108,7 @@ func (c *Cluster) AddMember(member *Member) error {
}
c.members[member.RaftID] = member
c.broadcastUpdate()
return nil
}
@ -110,6 +126,7 @@ func (c *Cluster) RemoveMember(id uint64) error {
}
c.removed[id] = true
c.broadcastUpdate()
return nil
}

View file

@ -28,6 +28,7 @@ import (
"github.com/docker/swarmkit/log"
"github.com/docker/swarmkit/manager/state/raft/membership"
"github.com/docker/swarmkit/manager/state/store"
"github.com/docker/swarmkit/manager/state/watch"
"github.com/gogo/protobuf/proto"
"github.com/pivotal-golang/clock"
)
@ -115,7 +116,7 @@ type Node struct {
// removeRaftCh notifies about node deletion from raft cluster
removeRaftCh chan struct{}
removeRaftFunc func()
leadershipBroadcast *events.Broadcaster
leadershipBroadcast *watch.Queue
// used to coordinate shutdown
stopMu sync.RWMutex
@ -194,7 +195,7 @@ func NewNode(ctx context.Context, opts NewNodeOptions) *Node {
StateDir: opts.StateDir,
joinAddr: opts.JoinAddr,
sendTimeout: 2 * time.Second,
leadershipBroadcast: events.NewBroadcaster(),
leadershipBroadcast: watch.NewQueue(),
}
n.memoryStore = store.NewMemoryStore(n)
@ -400,7 +401,7 @@ func (n *Node) Run(ctx context.Context) error {
n.wait.cancelAll()
if atomic.LoadUint32(&n.signalledLeadership) == 1 {
atomic.StoreUint32(&n.signalledLeadership, 0)
n.leadershipBroadcast.Write(IsFollower)
n.leadershipBroadcast.Publish(IsFollower)
}
} else if !wasLeader && rd.SoftState.RaftState == raft.StateLeader {
wasLeader = true
@ -412,7 +413,7 @@ func (n *Node) Run(ctx context.Context) error {
// committed, broadcast our leadership status.
if n.caughtUp() {
atomic.StoreUint32(&n.signalledLeadership, 1)
n.leadershipBroadcast.Write(IsLeader)
n.leadershipBroadcast.Publish(IsLeader)
}
}
@ -452,6 +453,9 @@ func (n *Node) Run(ctx context.Context) error {
return ErrMemberRemoved
case <-n.stopCh:
n.stop()
n.leadershipBroadcast.Close()
n.cluster.PeersBroadcast.Close()
n.memoryStore.Close()
return nil
}
}
@ -814,6 +818,8 @@ func (n *Node) LeaderAddr() (string, error) {
if err := WaitForLeader(ctx, n); err != nil {
return "", ErrNoClusterLeader
}
n.stopMu.RLock()
defer n.stopMu.RUnlock()
if !n.IsMember() {
return "", ErrNoRaftMember
}
@ -907,6 +913,12 @@ func (n *Node) GetVersion() *api.Version {
return &api.Version{Index: status.Commit}
}
// SubscribePeers subscribes to peer updates in cluster. It sends always full
// list of peers.
func (n *Node) SubscribePeers() (q chan events.Event, cancel func()) {
return n.cluster.PeersBroadcast.Watch()
}
// GetMemberlist returns the current list of raft members in the cluster.
func (n *Node) GetMemberlist() map[uint64]*api.RaftMember {
memberlist := make(map[uint64]*api.RaftMember)
@ -1344,14 +1356,7 @@ func (n *Node) ConnectToMember(addr string, timeout time.Duration) (*membership.
// will be sent in form of raft.LeadershipState. Also cancel func is returned -
// it should be called when listener is no longer interested in events.
func (n *Node) SubscribeLeadership() (q chan events.Event, cancel func()) {
ch := events.NewChannel(0)
sink := events.Sink(events.NewQueue(ch))
n.leadershipBroadcast.Add(sink)
return ch.C, func() {
n.leadershipBroadcast.Remove(sink)
ch.Close()
sink.Close()
}
return n.leadershipBroadcast.Watch()
}
// createConfigChangeEnts creates a series of Raft entries (i.e.

View file

@ -96,11 +96,16 @@ func NewMemoryStore(proposer state.Proposer) *MemoryStore {
return &MemoryStore{
memDB: memDB,
queue: watch.NewQueue(0),
queue: watch.NewQueue(),
proposer: proposer,
}
}
// Close closes the memory store and frees its associated resources.
func (s *MemoryStore) Close() error {
return s.queue.Close()
}
func fromArgs(args ...interface{}) ([]byte, error) {
if len(args) != 1 {
return nil, fmt.Errorf("must provide only a single argument")

View file

@ -1,6 +1,7 @@
package store
import (
"fmt"
"strconv"
"strings"
@ -224,8 +225,15 @@ func (ti taskIndexerByName) FromObject(obj interface{}) (bool, []byte, error) {
panic("unexpected type passed to FromObject")
}
name := t.Annotations.Name
if name == "" {
// If Task name is not assigned then calculated name is used like before.
// This might be removed in the future.
name = fmt.Sprintf("%v.%v.%v", t.ServiceAnnotations.Name, t.Slot, t.Task.ID)
}
// Add the null character as a terminator
return true, []byte(strings.ToLower(t.ServiceAnnotations.Name) + "\x00"), nil
return true, []byte(strings.ToLower(name) + "\x00"), nil
}
func (ti taskIndexerByName) PrefixFromArgs(args ...interface{}) ([]byte, error) {

View file

@ -1,18 +1,25 @@
package watch
import "github.com/docker/go-events"
import (
"sync"
"github.com/docker/go-events"
)
// Queue is the structure used to publish events and watch for them.
type Queue struct {
broadcast *events.Broadcaster
mu sync.Mutex
broadcast *events.Broadcaster
cancelFuncs map[*events.Channel]func()
}
// NewQueue creates a new publish/subscribe queue which supports watchers.
// The channels that it will create for subscriptions will have the buffer
// size specified by buffer.
func NewQueue(buffer int) *Queue {
func NewQueue() *Queue {
return &Queue{
broadcast: events.NewBroadcaster(),
broadcast: events.NewBroadcaster(),
cancelFuncs: make(map[*events.Channel]func()),
}
}
@ -35,14 +42,43 @@ func (q *Queue) CallbackWatch(matcher events.Matcher) (eventq chan events.Event,
}
q.broadcast.Add(sink)
return ch.C, func() {
cancelFunc := func() {
q.broadcast.Remove(sink)
ch.Close()
sink.Close()
}
q.mu.Lock()
q.cancelFuncs[ch] = cancelFunc
q.mu.Unlock()
return ch.C, func() {
q.mu.Lock()
cancelFunc := q.cancelFuncs[ch]
delete(q.cancelFuncs, ch)
q.mu.Unlock()
if cancelFunc != nil {
cancelFunc()
}
}
}
// Publish adds an item to the queue.
func (q *Queue) Publish(item events.Event) {
q.broadcast.Write(item)
}
// Close closes the queue and frees the associated resources.
func (q *Queue) Close() error {
// Make sure all watchers have been closed to avoid a deadlock when
// closing the broadcaster.
q.mu.Lock()
for _, cancelFunc := range q.cancelFuncs {
cancelFunc()
}
q.cancelFuncs = make(map[*events.Channel]func())
q.mu.Unlock()
return q.broadcast.Close()
}

View file

@ -444,7 +444,7 @@ var (
)
var fileDescriptorPlugin = []byte{
// 249 bytes of a gzipped FileDescriptorProto
// 259 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d,
0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4b, 0xc9, 0x4f, 0xce, 0x4e, 0x2d,
0x82, 0xf0, 0x92, 0x4a, 0xd3, 0xf4, 0x20, 0xb2, 0x52, 0x0a, 0xe9, 0xf9, 0xf9, 0xe9, 0x39, 0xa9,
@ -456,9 +456,10 @@ var fileDescriptorPlugin = []byte{
0x2d, 0x48, 0xce, 0x2f, 0xa8, 0x14, 0x92, 0xd7, 0x83, 0x58, 0x8a, 0x70, 0x8c, 0x6f, 0x6a, 0x71,
0x71, 0x62, 0x7a, 0xaa, 0x7f, 0x01, 0xc8, 0xf4, 0x62, 0x89, 0x0f, 0x8b, 0x58, 0x40, 0xda, 0xad,
0x58, 0x4a, 0x8a, 0x4a, 0x53, 0x83, 0xe0, 0x1a, 0xad, 0x2a, 0xb8, 0x04, 0x4b, 0x72, 0x8a, 0xe3,
0x13, 0x51, 0xdc, 0x22, 0x87, 0xc5, 0x34, 0xa0, 0x7c, 0x0a, 0xcc, 0xb0, 0x97, 0x4f, 0x7b, 0x95,
0x81, 0xa6, 0x71, 0x1b, 0x69, 0xe8, 0x61, 0x0f, 0x03, 0x3d, 0x74, 0xef, 0x05, 0x09, 0x00, 0x6d,
0x41, 0x11, 0x71, 0x92, 0x39, 0xf1, 0x50, 0x8e, 0xe1, 0x06, 0x10, 0x7f, 0x78, 0x28, 0xc7, 0xd8,
0xf0, 0x48, 0x8e, 0xf1, 0x04, 0x10, 0x5f, 0x00, 0xe2, 0x07, 0x40, 0x0c, 0x08, 0x00, 0x00, 0xff,
0xff, 0x04, 0x4e, 0xf8, 0x38, 0x6b, 0x01, 0x00, 0x00,
0x13, 0x51, 0xdc, 0x22, 0x87, 0xc5, 0xb4, 0x92, 0x8c, 0xfc, 0x14, 0x98, 0x61, 0x2f, 0x9f, 0xf6,
0x2a, 0x2b, 0x30, 0x6a, 0x70, 0x1b, 0x69, 0xe8, 0x61, 0x0f, 0x03, 0x3d, 0x74, 0xef, 0x05, 0x09,
0x94, 0xe4, 0x14, 0xa3, 0x88, 0x38, 0xc9, 0x9c, 0x78, 0x28, 0xc7, 0x70, 0xe3, 0xa1, 0x1c, 0xc3,
0x87, 0x87, 0x72, 0x8c, 0x0d, 0x8f, 0xe4, 0x18, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e,
0xf1, 0xc1, 0x23, 0x39, 0x46, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x04, 0x4e, 0xf8, 0x38, 0x6b,
0x01, 0x00, 0x00,
}

View file

@ -15,7 +15,6 @@ package prometheus
import (
"errors"
"hash/fnv"
)
// Counter is a Metric that represents a single numerical value that only ever
@ -97,7 +96,6 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
MetricVec: MetricVec{
children: map[uint64]Metric{},
desc: desc,
hash: fnv.New64a(),
newMetric: func(lvs ...string) Metric {
result := &counter{value: value{
desc: desc,

View file

@ -1,10 +1,8 @@
package prometheus
import (
"bytes"
"errors"
"fmt"
"hash/fnv"
"regexp"
"sort"
"strings"
@ -131,31 +129,24 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
d.err = errors.New("duplicate label names")
return d
}
h := fnv.New64a()
var b bytes.Buffer // To copy string contents into, avoiding []byte allocations.
vh := hashNew()
for _, val := range labelValues {
b.Reset()
b.WriteString(val)
b.WriteByte(separatorByte)
h.Write(b.Bytes())
vh = hashAdd(vh, val)
vh = hashAddByte(vh, separatorByte)
}
d.id = h.Sum64()
d.id = vh
// Sort labelNames so that order doesn't matter for the hash.
sort.Strings(labelNames)
// Now hash together (in this order) the help string and the sorted
// label names.
h.Reset()
b.Reset()
b.WriteString(help)
b.WriteByte(separatorByte)
h.Write(b.Bytes())
lh := hashNew()
lh = hashAdd(lh, help)
lh = hashAddByte(lh, separatorByte)
for _, labelName := range labelNames {
b.Reset()
b.WriteString(labelName)
b.WriteByte(separatorByte)
h.Write(b.Bytes())
lh = hashAdd(lh, labelName)
lh = hashAddByte(lh, separatorByte)
}
d.dimHash = h.Sum64()
d.dimHash = lh
d.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels))
for n, v := range constLabels {

View file

@ -61,7 +61,9 @@
// It also exports some stats about the HTTP usage of the /metrics
// endpoint. (See the Handler function for more detail.)
//
// Two more advanced metric types are the Summary and Histogram.
// Two more advanced metric types are the Summary and Histogram. A more
// thorough description of metric types can be found in the prometheus docs:
// https://prometheus.io/docs/concepts/metric_types/
//
// In addition to the fundamental metric types Gauge, Counter, Summary, and
// Histogram, a very important part of the Prometheus data model is the

View file

@ -0,0 +1,29 @@
package prometheus
// Inline and byte-free variant of hash/fnv's fnv64a.
const (
offset64 = 14695981039346656037
prime64 = 1099511628211
)
// hashNew initializies a new fnv64a hash value.
func hashNew() uint64 {
return offset64
}
// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
func hashAdd(h uint64, s string) uint64 {
for i := 0; i < len(s); i++ {
h ^= uint64(s[i])
h *= prime64
}
return h
}
// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
func hashAddByte(h uint64, b byte) uint64 {
h ^= uint64(b)
h *= prime64
return h
}

View file

@ -13,8 +13,6 @@
package prometheus
import "hash/fnv"
// Gauge is a Metric that represents a single numerical value that can
// arbitrarily go up and down.
//
@ -77,7 +75,6 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
MetricVec: MetricVec{
children: map[uint64]Metric{},
desc: desc,
hash: fnv.New64a(),
newMetric: func(lvs ...string) Metric {
return newValue(desc, GaugeValue, 0, lvs...)
},

View file

@ -211,7 +211,7 @@ func NewGoCollector() *goCollector {
"Number of seconds since 1970 of last garbage collection.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.LastGC*10 ^ 9) },
eval: func(ms *runtime.MemStats) float64 { return float64(ms.LastGC) / 1e9 },
valType: GaugeValue,
},
},

View file

@ -15,7 +15,6 @@ package prometheus
import (
"fmt"
"hash/fnv"
"math"
"sort"
"sync/atomic"
@ -305,7 +304,6 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
MetricVec: MetricVec{
children: map[uint64]Metric{},
desc: desc,
hash: fnv.New64a(),
newMetric: func(lvs ...string) Metric {
return newHistogram(desc, opts, lvs...)
},

View file

@ -57,12 +57,31 @@ func nowSeries(t ...time.Time) nower {
// has a constant label named "handler" with the provided handlerName as
// value. http_requests_total is a metric vector partitioned by HTTP method
// (label name "method") and HTTP status code (label name "code").
//
// Note that InstrumentHandler has several issues:
//
// - It uses Summaries rather than Histograms. Summaries are not useful if
// aggregation across multiple instances is required.
//
// - It uses microseconds as unit, which is deprecated and should be replaced by
// seconds.
//
// - The size of the request is calculated in a separate goroutine. Since this
// calculator requires access to the request header, it creates a race with
// any writes to the header performed during request handling.
// httputil.ReverseProxy is a prominent example for a handler
// performing such writes.
//
// Upcoming versions of this package will provide ways of instrumenting HTTP
// handlers that are more flexible and have fewer issues. Consider this function
// DEPRECATED and prefer direct instrumentation in the meantime.
func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc {
return InstrumentHandlerFunc(handlerName, handler.ServeHTTP)
}
// InstrumentHandlerFunc wraps the given function for instrumentation. It
// otherwise works in the same way as InstrumentHandler.
// otherwise works in the same way as InstrumentHandler (and shares the same
// issues).
func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
return InstrumentHandlerFuncWithOpts(
SummaryOpts{
@ -73,13 +92,13 @@ func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWri
)
}
// InstrumentHandlerWithOpts works like InstrumentHandler but provides more
// flexibility (at the cost of a more complex call syntax). As
// InstrumentHandler, this function registers four metric collectors, but it
// uses the provided SummaryOpts to create them. However, the fields "Name" and
// "Help" in the SummaryOpts are ignored. "Name" is replaced by
// "requests_total", "request_duration_microseconds", "request_size_bytes", and
// "response_size_bytes", respectively. "Help" is replaced by an appropriate
// InstrumentHandlerWithOpts works like InstrumentHandler (and shares the same
// issues) but provides more flexibility (at the cost of a more complex call
// syntax). As InstrumentHandler, this function registers four metric
// collectors, but it uses the provided SummaryOpts to create them. However, the
// fields "Name" and "Help" in the SummaryOpts are ignored. "Name" is replaced
// by "requests_total", "request_duration_microseconds", "request_size_bytes",
// and "response_size_bytes", respectively. "Help" is replaced by an appropriate
// help string. The names of the variable labels of the http_requests_total
// CounterVec are "method" (get, post, etc.), and "code" (HTTP status code).
//
@ -102,9 +121,10 @@ func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.Hand
return InstrumentHandlerFuncWithOpts(opts, handler.ServeHTTP)
}
// InstrumentHandlerFuncWithOpts works like InstrumentHandlerFunc but provides
// more flexibility (at the cost of a more complex call syntax). See
// InstrumentHandlerWithOpts for details how the provided SummaryOpts are used.
// InstrumentHandlerFuncWithOpts works like InstrumentHandlerFunc (and shares
// the same issues) but provides more flexibility (at the cost of a more complex
// call syntax). See InstrumentHandlerWithOpts for details how the provided
// SummaryOpts are used.
func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
reqCnt := NewCounterVec(
CounterOpts{

View file

@ -20,7 +20,7 @@
package prometheus
// Push triggers a metric collection by the default registry and pushes all
// collected metrics to the Pushgateway specified by addr. See the Pushgateway
// collected metrics to the Pushgateway specified by url. See the Pushgateway
// documentation for detailed implications of the job and instance
// parameter. instance can be left empty. You can use just host:port or ip:port
// as url, in which case 'http://' is added automatically. You can also include

View file

@ -24,7 +24,6 @@ import (
"compress/gzip"
"errors"
"fmt"
"hash/fnv"
"io"
"net/http"
"net/url"
@ -85,6 +84,9 @@ const (
// Handler returns the HTTP handler for the global Prometheus registry. It is
// already instrumented with InstrumentHandler (using "prometheus" as handler
// name). Usually the handler is used to handle the "/metrics" endpoint.
//
// Please note the issues described in the doc comment of InstrumentHandler. You
// might want to consider using UninstrumentedHandler instead.
func Handler() http.Handler {
return InstrumentHandler("prometheus", defRegistry)
}
@ -113,11 +115,13 @@ func Register(m Collector) error {
}
// MustRegister works like Register but panics where Register would have
// returned an error.
func MustRegister(m Collector) {
err := Register(m)
if err != nil {
panic(err)
// returned an error. MustRegister is also Variadic, where Register only
// accepts a single Collector to register.
func MustRegister(m ...Collector) {
for i := range m {
if err := Register(m[i]); err != nil {
panic(err)
}
}
}
@ -134,8 +138,8 @@ func RegisterOrGet(m Collector) (Collector, error) {
return defRegistry.RegisterOrGet(m)
}
// MustRegisterOrGet works like Register but panics where RegisterOrGet would
// have returned an error.
// MustRegisterOrGet works like RegisterOrGet but panics where RegisterOrGet
// would have returned an error.
func MustRegisterOrGet(m Collector) Collector {
existing, err := RegisterOrGet(m)
if err != nil {
@ -337,6 +341,9 @@ func (r *registry) Push(job, instance, pushURL, method string) error {
if !strings.Contains(pushURL, "://") {
pushURL = "http://" + pushURL
}
if strings.HasSuffix(pushURL, "/") {
pushURL = pushURL[:len(pushURL)-1]
}
pushURL = fmt.Sprintf("%s/metrics/jobs/%s", pushURL, url.QueryEscape(job))
if instance != "" {
pushURL += "/instances/" + url.QueryEscape(instance)
@ -528,30 +535,25 @@ func (r *registry) checkConsistency(metricFamily *dto.MetricFamily, dtoMetric *d
}
// Is the metric unique (i.e. no other metric with the same name and the same label values)?
h := fnv.New64a()
var buf bytes.Buffer
buf.WriteString(metricFamily.GetName())
buf.WriteByte(separatorByte)
h.Write(buf.Bytes())
h := hashNew()
h = hashAdd(h, metricFamily.GetName())
h = hashAddByte(h, separatorByte)
// Make sure label pairs are sorted. We depend on it for the consistency
// check. Label pairs must be sorted by contract. But the point of this
// method is to check for contract violations. So we better do the sort
// now.
sort.Sort(LabelPairSorter(dtoMetric.Label))
for _, lp := range dtoMetric.Label {
buf.Reset()
buf.WriteString(lp.GetValue())
buf.WriteByte(separatorByte)
h.Write(buf.Bytes())
h = hashAdd(h, lp.GetValue())
h = hashAddByte(h, separatorByte)
}
metricHash := h.Sum64()
if _, exists := metricHashes[metricHash]; exists {
if _, exists := metricHashes[h]; exists {
return fmt.Errorf(
"collected metric %s %s was collected before with the same name and label values",
metricFamily.GetName(), dtoMetric,
)
}
metricHashes[metricHash] = struct{}{}
metricHashes[h] = struct{}{}
if desc == nil {
return nil // Nothing left to check if we have no desc.
@ -722,5 +724,18 @@ func (s metricSorter) Less(i, j int) bool {
return vi < vj
}
}
return true
// We should never arrive here. Multiple metrics with the same
// label set in the same scrape will lead to undefined ingestion
// behavior. However, as above, we have to provide stable sorting
// here, even for inconsistent metrics. So sort equal metrics
// by their timestamp, with missing timestamps (implying "now")
// coming last.
if s[i].TimestampMs == nil {
return false
}
if s[j].TimestampMs == nil {
return true
}
return s[i].GetTimestampMs() < s[j].GetTimestampMs()
}

View file

@ -15,7 +15,6 @@ package prometheus
import (
"fmt"
"hash/fnv"
"math"
"sort"
"sync"
@ -408,7 +407,6 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
MetricVec: MetricVec{
children: map[uint64]Metric{},
desc: desc,
hash: fnv.New64a(),
newMetric: func(lvs ...string) Metric {
return newSummary(desc, opts, lvs...)
},

View file

@ -13,8 +13,6 @@
package prometheus
import "hash/fnv"
// Untyped is a Metric that represents a single numerical value that can
// arbitrarily go up and down.
//
@ -75,7 +73,6 @@ func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec {
MetricVec: MetricVec{
children: map[uint64]Metric{},
desc: desc,
hash: fnv.New64a(),
newMetric: func(lvs ...string) Metric {
return newValue(desc, UntypedValue, 0, lvs...)
},

View file

@ -14,9 +14,7 @@
package prometheus
import (
"bytes"
"fmt"
"hash"
"sync"
)
@ -26,16 +24,10 @@ import (
// type. GaugeVec, CounterVec, SummaryVec, and UntypedVec are examples already
// provided in this package.
type MetricVec struct {
mtx sync.RWMutex // Protects not only children, but also hash and buf.
mtx sync.RWMutex // Protects the children.
children map[uint64]Metric
desc *Desc
// hash is our own hash instance to avoid repeated allocations.
hash hash.Hash64
// buf is used to copy string contents into it for hashing,
// again to avoid allocations.
buf bytes.Buffer
newMetric func(labelValues ...string) Metric
}
@ -80,13 +72,20 @@ func (m *MetricVec) Collect(ch chan<- Metric) {
// with a performance overhead (for creating and processing the Labels map).
// See also the GaugeVec example.
func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
h, err := m.hashLabelValues(lvs)
if err != nil {
return nil, err
}
m.mtx.RLock()
metric, ok := m.children[h]
m.mtx.RUnlock()
if ok {
return metric, nil
}
m.mtx.Lock()
defer m.mtx.Unlock()
return m.getOrCreateMetric(h, lvs...), nil
}
@ -103,17 +102,24 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
// GetMetricWithLabelValues(...string). See there for pros and cons of the two
// methods.
func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
m.mtx.Lock()
defer m.mtx.Unlock()
h, err := m.hashLabels(labels)
if err != nil {
return nil, err
}
m.mtx.RLock()
metric, ok := m.children[h]
m.mtx.RUnlock()
if ok {
return metric, nil
}
lvs := make([]string, len(labels))
for i, label := range m.desc.variableLabels {
lvs[i] = labels[label]
}
m.mtx.Lock()
defer m.mtx.Unlock()
return m.getOrCreateMetric(h, lvs...), nil
}
@ -162,7 +168,7 @@ func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
if err != nil {
return false
}
if _, has := m.children[h]; !has {
if _, ok := m.children[h]; !ok {
return false
}
delete(m.children, h)
@ -187,7 +193,7 @@ func (m *MetricVec) Delete(labels Labels) bool {
if err != nil {
return false
}
if _, has := m.children[h]; !has {
if _, ok := m.children[h]; !ok {
return false
}
delete(m.children, h)
@ -208,30 +214,26 @@ func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
if len(vals) != len(m.desc.variableLabels) {
return 0, errInconsistentCardinality
}
m.hash.Reset()
h := hashNew()
for _, val := range vals {
m.buf.Reset()
m.buf.WriteString(val)
m.hash.Write(m.buf.Bytes())
h = hashAdd(h, val)
}
return m.hash.Sum64(), nil
return h, nil
}
func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
if len(labels) != len(m.desc.variableLabels) {
return 0, errInconsistentCardinality
}
m.hash.Reset()
h := hashNew()
for _, label := range m.desc.variableLabels {
val, ok := labels[label]
if !ok {
return 0, fmt.Errorf("label name %q missing in label map", label)
}
m.buf.Reset()
m.buf.WriteString(val)
m.hash.Write(m.buf.Bytes())
h = hashAdd(h, val)
}
return m.hash.Sum64(), nil
return h, nil
}
func (m *MetricVec) getOrCreateMetric(hash uint64, labelValues ...string) Metric {

View file

@ -46,10 +46,7 @@ func ResponseFormat(h http.Header) Format {
return FmtUnknown
}
const (
textType = "text/plain"
jsonType = "application/json"
)
const textType = "text/plain"
switch mediatype {
case ProtoType:
@ -66,22 +63,6 @@ func ResponseFormat(h http.Header) Format {
return FmtUnknown
}
return FmtText
case jsonType:
var prometheusAPIVersion string
if params["schema"] == "prometheus/telemetry" && params["version"] != "" {
prometheusAPIVersion = params["version"]
} else {
prometheusAPIVersion = h.Get("X-Prometheus-API-Version")
}
switch prometheusAPIVersion {
case "0.0.2", "":
return fmtJSON2
default:
return FmtUnknown
}
}
return FmtUnknown
@ -93,8 +74,6 @@ func NewDecoder(r io.Reader, format Format) Decoder {
switch format {
case FmtProtoDelim:
return &protoDecoder{r: r}
case fmtJSON2:
return newJSON2Decoder(r)
}
return &textDecoder{r: r}
}
@ -107,10 +86,32 @@ type protoDecoder struct {
// Decode implements the Decoder interface.
func (d *protoDecoder) Decode(v *dto.MetricFamily) error {
_, err := pbutil.ReadDelimited(d.r, v)
return err
if err != nil {
return err
}
if !model.IsValidMetricName(model.LabelValue(v.GetName())) {
return fmt.Errorf("invalid metric name %q", v.GetName())
}
for _, m := range v.GetMetric() {
if m == nil {
continue
}
for _, l := range m.GetLabel() {
if l == nil {
continue
}
if !model.LabelValue(l.GetValue()).IsValid() {
return fmt.Errorf("invalid label value %q", l.GetValue())
}
if !model.LabelName(l.GetName()).IsValid() {
return fmt.Errorf("invalid label name %q", l.GetName())
}
}
}
return nil
}
// textDecoder implements the Decoder interface for the text protcol.
// textDecoder implements the Decoder interface for the text protocol.
type textDecoder struct {
r io.Reader
p TextParser

View file

@ -18,9 +18,9 @@ import (
"io"
"net/http"
"bitbucket.org/ww/goautoneg"
"github.com/golang/protobuf/proto"
"github.com/matttproud/golang_protobuf_extensions/pbutil"
"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg"
dto "github.com/prometheus/client_model/go"
)

View file

@ -20,8 +20,8 @@ import "bytes"
// Fuzz text metric parser with with github.com/dvyukov/go-fuzz:
//
// go-fuzz-build github.com/prometheus/client_golang/text
// go-fuzz -bin text-fuzz.zip -workdir fuzz
// go-fuzz-build github.com/prometheus/common/expfmt
// go-fuzz -bin expfmt-fuzz.zip -workdir fuzz
//
// Further input samples should go in the folder fuzz/corpus.
func Fuzz(in []byte) int {

View file

@ -1,162 +0,0 @@
// Copyright 2015 The Prometheus Authors
// 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 expfmt
import (
"encoding/json"
"fmt"
"io"
"sort"
"github.com/golang/protobuf/proto"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/model"
)
type json2Decoder struct {
dec *json.Decoder
fams []*dto.MetricFamily
}
func newJSON2Decoder(r io.Reader) Decoder {
return &json2Decoder{
dec: json.NewDecoder(r),
}
}
type histogram002 struct {
Labels model.LabelSet `json:"labels"`
Values map[string]float64 `json:"value"`
}
type counter002 struct {
Labels model.LabelSet `json:"labels"`
Value float64 `json:"value"`
}
func protoLabelSet(base, ext model.LabelSet) []*dto.LabelPair {
labels := base.Clone().Merge(ext)
delete(labels, model.MetricNameLabel)
names := make([]string, 0, len(labels))
for ln := range labels {
names = append(names, string(ln))
}
sort.Strings(names)
pairs := make([]*dto.LabelPair, 0, len(labels))
for _, ln := range names {
lv := labels[model.LabelName(ln)]
pairs = append(pairs, &dto.LabelPair{
Name: proto.String(ln),
Value: proto.String(string(lv)),
})
}
return pairs
}
func (d *json2Decoder) more() error {
var entities []struct {
BaseLabels model.LabelSet `json:"baseLabels"`
Docstring string `json:"docstring"`
Metric struct {
Type string `json:"type"`
Values json.RawMessage `json:"value"`
} `json:"metric"`
}
if err := d.dec.Decode(&entities); err != nil {
return err
}
for _, e := range entities {
f := &dto.MetricFamily{
Name: proto.String(string(e.BaseLabels[model.MetricNameLabel])),
Help: proto.String(e.Docstring),
Type: dto.MetricType_UNTYPED.Enum(),
Metric: []*dto.Metric{},
}
d.fams = append(d.fams, f)
switch e.Metric.Type {
case "counter", "gauge":
var values []counter002
if err := json.Unmarshal(e.Metric.Values, &values); err != nil {
return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err)
}
for _, ctr := range values {
f.Metric = append(f.Metric, &dto.Metric{
Label: protoLabelSet(e.BaseLabels, ctr.Labels),
Untyped: &dto.Untyped{
Value: proto.Float64(ctr.Value),
},
})
}
case "histogram":
var values []histogram002
if err := json.Unmarshal(e.Metric.Values, &values); err != nil {
return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err)
}
for _, hist := range values {
quants := make([]string, 0, len(values))
for q := range hist.Values {
quants = append(quants, q)
}
sort.Strings(quants)
for _, q := range quants {
value := hist.Values[q]
// The correct label is "quantile" but to not break old expressions
// this remains "percentile"
hist.Labels["percentile"] = model.LabelValue(q)
f.Metric = append(f.Metric, &dto.Metric{
Label: protoLabelSet(e.BaseLabels, hist.Labels),
Untyped: &dto.Untyped{
Value: proto.Float64(value),
},
})
}
}
default:
return fmt.Errorf("unknown metric type %q", e.Metric.Type)
}
}
return nil
}
// Decode implements the Decoder interface.
func (d *json2Decoder) Decode(v *dto.MetricFamily) error {
if len(d.fams) == 0 {
if err := d.more(); err != nil {
return err
}
}
*v = *d.fams[0]
d.fams = d.fams[1:]
return nil
}

View file

@ -14,7 +14,6 @@
package expfmt
import (
"bytes"
"fmt"
"io"
"math"
@ -285,21 +284,17 @@ func labelPairsToText(
return written, nil
}
var (
escape = strings.NewReplacer("\\", `\\`, "\n", `\n`)
escapeWithDoubleQuote = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`)
)
// escapeString replaces '\' by '\\', new line character by '\n', and - if
// includeDoubleQuote is true - '"' by '\"'.
func escapeString(v string, includeDoubleQuote bool) string {
result := bytes.NewBuffer(make([]byte, 0, len(v)))
for _, c := range v {
switch {
case c == '\\':
result.WriteString(`\\`)
case includeDoubleQuote && c == '"':
result.WriteString(`\"`)
case c == '\n':
result.WriteString(`\n`)
default:
result.WriteRune(c)
}
if includeDoubleQuote {
return escapeWithDoubleQuote.Replace(v)
}
return result.String()
return escape.Replace(v)
}

View file

@ -108,6 +108,13 @@ func (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricF
delete(p.metricFamiliesByName, k)
}
}
// If p.err is io.EOF now, we have run into a premature end of the input
// stream. Turn this error into something nicer and more
// meaningful. (io.EOF is often used as a signal for the legitimate end
// of an input stream.)
if p.err == io.EOF {
p.parseError("unexpected end of input stream")
}
return p.metricFamiliesByName, p.err
}

View file

@ -35,8 +35,9 @@ type Alert struct {
Annotations LabelSet `json:"annotations"`
// The known time range for this alert. Both ends are optional.
StartsAt time.Time `json:"startsAt,omitempty"`
EndsAt time.Time `json:"endsAt,omitempty"`
StartsAt time.Time `json:"startsAt,omitempty"`
EndsAt time.Time `json:"endsAt,omitempty"`
GeneratorURL string `json:"generatorURL"`
}
// Name returns the name of the alert. It is equivalent to the "alertname" label.
@ -60,10 +61,16 @@ func (a *Alert) String() string {
// Resolved returns true iff the activity interval ended in the past.
func (a *Alert) Resolved() bool {
return a.ResolvedAt(time.Now())
}
// ResolvedAt returns true off the activity interval ended before
// the given timestamp.
func (a *Alert) ResolvedAt(ts time.Time) bool {
if a.EndsAt.IsZero() {
return false
}
return !a.EndsAt.After(time.Now())
return !a.EndsAt.After(ts)
}
// Status returns the status of the alert.
@ -74,6 +81,26 @@ func (a *Alert) Status() AlertStatus {
return AlertFiring
}
// Validate checks whether the alert data is inconsistent.
func (a *Alert) Validate() error {
if a.StartsAt.IsZero() {
return fmt.Errorf("start time missing")
}
if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) {
return fmt.Errorf("start time must be before end time")
}
if err := a.Labels.Validate(); err != nil {
return fmt.Errorf("invalid label set: %s", err)
}
if len(a.Labels) == 0 {
return fmt.Errorf("at least one label pair required")
}
if err := a.Annotations.Validate(); err != nil {
return fmt.Errorf("invalid annotations: %s", err)
}
return nil
}
// Alert is a list of alerts that can be sorted in chronological order.
type Alerts []*Alert

View file

@ -0,0 +1,42 @@
// Copyright 2015 The Prometheus Authors
// 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 model
// Inline and byte-free variant of hash/fnv's fnv64a.
const (
offset64 = 14695981039346656037
prime64 = 1099511628211
)
// hashNew initializies a new fnv64a hash value.
func hashNew() uint64 {
return offset64
}
// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
func hashAdd(h uint64, s string) uint64 {
for i := 0; i < len(s); i++ {
h ^= uint64(s[i])
h *= prime64
}
return h
}
// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
func hashAddByte(h uint64, b byte) uint64 {
h ^= uint64(b)
h *= prime64
return h
}

View file

@ -17,8 +17,8 @@ import (
"encoding/json"
"fmt"
"regexp"
"sort"
"strings"
"unicode/utf8"
)
const (
@ -87,6 +87,19 @@ var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
// therewith.
type LabelName string
// IsValid is true iff the label name matches the pattern of LabelNameRE.
func (ln LabelName) IsValid() bool {
if len(ln) == 0 {
return false
}
for i, b := range ln {
if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) {
return false
}
}
return true
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error {
var s string
@ -139,6 +152,11 @@ func (l LabelNames) String() string {
// A LabelValue is an associated value for a LabelName.
type LabelValue string
// IsValid returns true iff the string is a valid UTF8.
func (lv LabelValue) IsValid() bool {
return utf8.ValidString(string(lv))
}
// LabelValues is a sortable LabelValue slice. It implements sort.Interface.
type LabelValues []LabelValue
@ -147,7 +165,7 @@ func (l LabelValues) Len() int {
}
func (l LabelValues) Less(i, j int) bool {
return sort.StringsAreSorted([]string{string(l[i]), string(l[j])})
return string(l[i]) < string(l[j])
}
func (l LabelValues) Swap(i, j int) {

View file

@ -27,6 +27,21 @@ import (
// match.
type LabelSet map[LabelName]LabelValue
// Validate checks whether all names and values in the label set
// are valid.
func (ls LabelSet) Validate() error {
for ln, lv := range ls {
if !ln.IsValid() {
return fmt.Errorf("invalid name %q", ln)
}
if !lv.IsValid() {
return fmt.Errorf("invalid value %q", lv)
}
}
return nil
}
// Equal returns true iff both label sets have exactly the same key/value pairs.
func (ls LabelSet) Equal(o LabelSet) bool {
if len(ls) != len(o) {
return false
@ -90,6 +105,7 @@ func (ls LabelSet) Before(o LabelSet) bool {
return false
}
// Clone returns a copy of the label set.
func (ls LabelSet) Clone() LabelSet {
lsn := make(LabelSet, len(ls))
for ln, lv := range ls {

View file

@ -15,11 +15,15 @@ package model
import (
"fmt"
"regexp"
"sort"
"strings"
)
var separator = []byte{0}
var (
separator = []byte{0}
MetricNameRE = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_:]*$`)
)
// A Metric is similar to a LabelSet, but the key difference is that a Metric is
// a singleton and refers to one and only one stream of samples.
@ -79,3 +83,16 @@ func (m Metric) Fingerprint() Fingerprint {
func (m Metric) FastFingerprint() Fingerprint {
return LabelSet(m).FastFingerprint()
}
// IsValidMetricName returns true iff name matches the pattern of MetricNameRE.
func IsValidMetricName(n LabelValue) bool {
if len(n) == 0 {
return false
}
for i, b := range n {
if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)) {
return false
}
}
return true
}

View file

@ -12,5 +12,5 @@
// limitations under the License.
// Package model contains common data structures that are shared across
// Prometheus componenets and libraries.
// Prometheus components and libraries.
package model

View file

@ -14,11 +14,7 @@
package model
import (
"bytes"
"hash"
"hash/fnv"
"sort"
"sync"
)
// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is
@ -28,30 +24,9 @@ const SeparatorByte byte = 255
var (
// cache the signature of an empty label set.
emptyLabelSignature = fnv.New64a().Sum64()
hashAndBufPool sync.Pool
emptyLabelSignature = hashNew()
)
type hashAndBuf struct {
h hash.Hash64
b bytes.Buffer
}
func getHashAndBuf() *hashAndBuf {
hb := hashAndBufPool.Get()
if hb == nil {
return &hashAndBuf{h: fnv.New64a()}
}
return hb.(*hashAndBuf)
}
func putHashAndBuf(hb *hashAndBuf) {
hb.h.Reset()
hb.b.Reset()
hashAndBufPool.Put(hb)
}
// LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a
// given label set. (Collisions are possible but unlikely if the number of label
// sets the function is applied to is small.)
@ -66,18 +41,14 @@ func LabelsToSignature(labels map[string]string) uint64 {
}
sort.Strings(labelNames)
hb := getHashAndBuf()
defer putHashAndBuf(hb)
sum := hashNew()
for _, labelName := range labelNames {
hb.b.WriteString(labelName)
hb.b.WriteByte(SeparatorByte)
hb.b.WriteString(labels[labelName])
hb.b.WriteByte(SeparatorByte)
hb.h.Write(hb.b.Bytes())
hb.b.Reset()
sum = hashAdd(sum, labelName)
sum = hashAddByte(sum, SeparatorByte)
sum = hashAdd(sum, labels[labelName])
sum = hashAddByte(sum, SeparatorByte)
}
return hb.h.Sum64()
return sum
}
// labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as
@ -93,18 +64,14 @@ func labelSetToFingerprint(ls LabelSet) Fingerprint {
}
sort.Sort(labelNames)
hb := getHashAndBuf()
defer putHashAndBuf(hb)
sum := hashNew()
for _, labelName := range labelNames {
hb.b.WriteString(string(labelName))
hb.b.WriteByte(SeparatorByte)
hb.b.WriteString(string(ls[labelName]))
hb.b.WriteByte(SeparatorByte)
hb.h.Write(hb.b.Bytes())
hb.b.Reset()
sum = hashAdd(sum, string(labelName))
sum = hashAddByte(sum, SeparatorByte)
sum = hashAdd(sum, string(ls[labelName]))
sum = hashAddByte(sum, SeparatorByte)
}
return Fingerprint(hb.h.Sum64())
return Fingerprint(sum)
}
// labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a
@ -116,17 +83,12 @@ func labelSetToFastFingerprint(ls LabelSet) Fingerprint {
}
var result uint64
hb := getHashAndBuf()
defer putHashAndBuf(hb)
for labelName, labelValue := range ls {
hb.b.WriteString(string(labelName))
hb.b.WriteByte(SeparatorByte)
hb.b.WriteString(string(labelValue))
hb.h.Write(hb.b.Bytes())
result ^= hb.h.Sum64()
hb.h.Reset()
hb.b.Reset()
sum := hashNew()
sum = hashAdd(sum, string(labelName))
sum = hashAddByte(sum, SeparatorByte)
sum = hashAdd(sum, string(labelValue))
result ^= sum
}
return Fingerprint(result)
}
@ -136,24 +98,20 @@ func labelSetToFastFingerprint(ls LabelSet) Fingerprint {
// specified LabelNames into the signature calculation. The labels passed in
// will be sorted by this function.
func SignatureForLabels(m Metric, labels ...LabelName) uint64 {
if len(m) == 0 || len(labels) == 0 {
if len(labels) == 0 {
return emptyLabelSignature
}
sort.Sort(LabelNames(labels))
hb := getHashAndBuf()
defer putHashAndBuf(hb)
sum := hashNew()
for _, label := range labels {
hb.b.WriteString(string(label))
hb.b.WriteByte(SeparatorByte)
hb.b.WriteString(string(m[label]))
hb.b.WriteByte(SeparatorByte)
hb.h.Write(hb.b.Bytes())
hb.b.Reset()
sum = hashAdd(sum, string(label))
sum = hashAddByte(sum, SeparatorByte)
sum = hashAdd(sum, string(m[label]))
sum = hashAddByte(sum, SeparatorByte)
}
return hb.h.Sum64()
return sum
}
// SignatureWithoutLabels works like LabelsToSignature but takes a Metric as
@ -175,16 +133,12 @@ func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 {
}
sort.Sort(labelNames)
hb := getHashAndBuf()
defer putHashAndBuf(hb)
sum := hashNew()
for _, labelName := range labelNames {
hb.b.WriteString(string(labelName))
hb.b.WriteByte(SeparatorByte)
hb.b.WriteString(string(m[labelName]))
hb.b.WriteByte(SeparatorByte)
hb.h.Write(hb.b.Bytes())
hb.b.Reset()
sum = hashAdd(sum, string(labelName))
sum = hashAddByte(sum, SeparatorByte)
sum = hashAdd(sum, string(m[labelName]))
sum = hashAddByte(sum, SeparatorByte)
}
return hb.h.Sum64()
return sum
}

View file

@ -44,6 +44,21 @@ func (m *Matcher) UnmarshalJSON(b []byte) error {
return nil
}
// Validate returns true iff all fields of the matcher have valid values.
func (m *Matcher) Validate() error {
if !m.Name.IsValid() {
return fmt.Errorf("invalid name %q", m.Name)
}
if m.IsRegex {
if _, err := regexp.Compile(m.Value); err != nil {
return fmt.Errorf("invalid regular expression %q", m.Value)
}
} else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 {
return fmt.Errorf("invalid value %q", m.Value)
}
return nil
}
// Silence defines the representation of a silence definiton
// in the Prometheus eco-system.
type Silence struct {
@ -58,3 +73,34 @@ type Silence struct {
CreatedBy string `json:"createdBy"`
Comment string `json:"comment,omitempty"`
}
// Validate returns true iff all fields of the silence have valid values.
func (s *Silence) Validate() error {
if len(s.Matchers) == 0 {
return fmt.Errorf("at least one matcher required")
}
for _, m := range s.Matchers {
if err := m.Validate(); err != nil {
return fmt.Errorf("invalid matcher: %s", err)
}
}
if s.StartsAt.IsZero() {
return fmt.Errorf("start time missing")
}
if s.EndsAt.IsZero() {
return fmt.Errorf("end time missing")
}
if s.EndsAt.Before(s.StartsAt) {
return fmt.Errorf("start time must be before end time")
}
if s.CreatedBy == "" {
return fmt.Errorf("creator information missing")
}
if s.Comment == "" {
return fmt.Errorf("comment missing")
}
if s.CreatedAt.IsZero() {
return fmt.Errorf("creation timestamp missing")
}
return nil
}

View file

@ -163,51 +163,70 @@ func (t *Time) UnmarshalJSON(b []byte) error {
// This type should not propagate beyond the scope of input/output processing.
type Duration time.Duration
var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$")
// StringToDuration parses a string into a time.Duration, assuming that a year
// a day always has 24h.
// always has 365d, a week always has 7d, and a day always has 24h.
func ParseDuration(durationStr string) (Duration, error) {
matches := durationRE.FindStringSubmatch(durationStr)
if len(matches) != 3 {
return 0, fmt.Errorf("not a valid duration string: %q", durationStr)
}
durSeconds, _ := strconv.Atoi(matches[1])
dur := time.Duration(durSeconds) * time.Second
unit := matches[2]
switch unit {
var (
n, _ = strconv.Atoi(matches[1])
dur = time.Duration(n) * time.Millisecond
)
switch unit := matches[2]; unit {
case "y":
dur *= 1000 * 60 * 60 * 24 * 365
case "w":
dur *= 1000 * 60 * 60 * 24 * 7
case "d":
dur *= 60 * 60 * 24
dur *= 1000 * 60 * 60 * 24
case "h":
dur *= 60 * 60
dur *= 1000 * 60 * 60
case "m":
dur *= 60
dur *= 1000 * 60
case "s":
dur *= 1
dur *= 1000
case "ms":
// Value already correct
default:
return 0, fmt.Errorf("invalid time unit in duration string: %q", unit)
}
return Duration(dur), nil
}
var durationRE = regexp.MustCompile("^([0-9]+)([ywdhms]+)$")
func (d Duration) String() string {
seconds := int64(time.Duration(d) / time.Second)
var (
ms = int64(time.Duration(d) / time.Millisecond)
unit = "ms"
)
factors := map[string]int64{
"d": 60 * 60 * 24,
"h": 60 * 60,
"m": 60,
"s": 1,
"y": 1000 * 60 * 60 * 24 * 365,
"w": 1000 * 60 * 60 * 24 * 7,
"d": 1000 * 60 * 60 * 24,
"h": 1000 * 60 * 60,
"m": 1000 * 60,
"s": 1000,
"ms": 1,
}
unit := "s"
switch int64(0) {
case seconds % factors["d"]:
case ms % factors["y"]:
unit = "y"
case ms % factors["w"]:
unit = "w"
case ms % factors["d"]:
unit = "d"
case seconds % factors["h"]:
case ms % factors["h"]:
unit = "h"
case seconds % factors["m"]:
case ms % factors["m"]:
unit = "m"
case ms % factors["s"]:
unit = "s"
}
return fmt.Sprintf("%v%v", seconds/factors[unit], unit)
return fmt.Sprintf("%v%v", ms/factors[unit], unit)
}
// MarshalYAML implements the yaml.Marshaler interface.

View file

@ -16,6 +16,7 @@ package model
import (
"encoding/json"
"fmt"
"math"
"sort"
"strconv"
"strings"
@ -43,8 +44,14 @@ func (v *SampleValue) UnmarshalJSON(b []byte) error {
return nil
}
// Equal returns true if the value of v and o is equal or if both are NaN. Note
// that v==o is false if both are NaN. If you want the conventional float
// behavior, use == to compare two SampleValues.
func (v SampleValue) Equal(o SampleValue) bool {
return v == o
if v == o {
return true
}
return math.IsNaN(float64(v)) && math.IsNaN(float64(o))
}
func (v SampleValue) String() string {
@ -77,9 +84,9 @@ func (s *SamplePair) UnmarshalJSON(b []byte) error {
}
// Equal returns true if this SamplePair and o have equal Values and equal
// Timestamps.
// Timestamps. The sematics of Value equality is defined by SampleValue.Equal.
func (s *SamplePair) Equal(o *SamplePair) bool {
return s == o || (s.Value == o.Value && s.Timestamp.Equal(o.Timestamp))
return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
}
func (s SamplePair) String() string {
@ -93,7 +100,8 @@ type Sample struct {
Timestamp Time `json:"timestamp"`
}
// Equal compares first the metrics, then the timestamp, then the value.
// Equal compares first the metrics, then the timestamp, then the value. The
// sematics of value equality is defined by SampleValue.Equal.
func (s *Sample) Equal(o *Sample) bool {
if s == o {
return true
@ -105,7 +113,7 @@ func (s *Sample) Equal(o *Sample) bool {
if !s.Timestamp.Equal(o.Timestamp) {
return false
}
if s.Value != o.Value {
if s.Value.Equal(o.Value) {
return false
}

View file

@ -1,7 +1,5 @@
sudo: false
language: go
go:
- 1.3
- 1.4
- 1.5
- tip
- 1.6

View file

@ -13,7 +13,7 @@ The following individuals have contributed code to this repository
* David Cournapeau <cournape@gmail.com>
* Ji-Hoon, Seol <jihoon.seol@gmail.com>
* Jonas Große Sundrup <cherti@letopolis.de>
* Julius Volz <julius@soundcloud.com>
* Julius Volz <julius.volz@gmail.com>
* Matthias Rampke <mr@soundcloud.com>
* Nicky Gerritsen <nicky@streamone.nl>
* Rémi Audebert <contact@halfr.net>

View file

@ -1,5 +1,5 @@
ci:
go fmt
! gofmt -l *.go | read nothing
go vet
go test -v ./...
go get github.com/golang/lint/golint

View file

@ -27,14 +27,7 @@ func NewFS(mountPoint string) (FS, error) {
return FS(mountPoint), nil
}
func (fs FS) stat(p string) (os.FileInfo, error) {
return os.Stat(path.Join(string(fs), p))
}
func (fs FS) open(p string) (*os.File, error) {
return os.Open(path.Join(string(fs), p))
}
func (fs FS) readlink(p string) (string, error) {
return os.Readlink(path.Join(string(fs), p))
// Path returns the path of the given subsystem relative to the procfs root.
func (fs FS) Path(p ...string) string {
return path.Join(append([]string{string(fs)}, p...)...)
}

View file

@ -8,6 +8,7 @@ import (
"io"
"io/ioutil"
"net"
"os"
"strconv"
"strings"
)
@ -58,7 +59,7 @@ func NewIPVSStats() (IPVSStats, error) {
// NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem.
func (fs FS) NewIPVSStats() (IPVSStats, error) {
file, err := fs.open("net/ip_vs_stats")
file, err := os.Open(fs.Path("net/ip_vs_stats"))
if err != nil {
return IPVSStats{}, err
}
@ -127,7 +128,7 @@ func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
file, err := fs.open("net/ip_vs")
file, err := os.Open(fs.Path("net/ip_vs"))
if err != nil {
return nil, err
}

View file

@ -3,7 +3,6 @@ package procfs
import (
"fmt"
"io/ioutil"
"path"
"regexp"
"strconv"
"strings"
@ -32,36 +31,22 @@ type MDStat struct {
// ParseMDStat parses an mdstat-file and returns a struct with the relevant infos.
func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
mdStatusFilePath := path.Join(string(fs), "mdstat")
mdStatusFilePath := fs.Path("mdstat")
content, err := ioutil.ReadFile(mdStatusFilePath)
if err != nil {
return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
}
mdStatusFile := string(content)
lines := strings.Split(mdStatusFile, "\n")
var currentMD string
// Each md has at least the deviceline, statusline and one empty line afterwards
// so we will have probably something of the order len(lines)/3 devices
// so we use that for preallocation.
estimateMDs := len(lines) / 3
mdStates := make([]MDStat, 0, estimateMDs)
mdStates := []MDStat{}
lines := strings.Split(string(content), "\n")
for i, l := range lines {
if l == "" {
// Skip entirely empty lines.
continue
}
if l[0] == ' ' {
// Those lines are not the beginning of a md-section.
continue
}
if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") {
// We aren't interested in lines with general info.
continue
}
@ -69,32 +54,30 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
if len(mainLine) < 3 {
return mdStates, fmt.Errorf("error parsing mdline: %s", l)
}
currentMD = mainLine[0] // name of md-device
activityState := mainLine[2] // activity status of said md-device
mdName := mainLine[0]
activityState := mainLine[2]
if len(lines) <= i+3 {
return mdStates, fmt.Errorf("error parsing %s: entry for %s has fewer lines than expected", mdStatusFilePath, currentMD)
return mdStates, fmt.Errorf(
"error parsing %s: too few lines for md device %s",
mdStatusFilePath,
mdName,
)
}
active, total, size, err := evalStatusline(lines[i+1]) // parse statusline, always present
active, total, size, err := evalStatusline(lines[i+1])
if err != nil {
return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
}
//
// Now get the number of synced blocks.
//
// Get the line number of the syncing-line.
var j int
if strings.Contains(lines[i+2], "bitmap") { // then skip the bitmap line
// j is the line number of the syncing-line.
j := i + 2
if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line
j = i + 3
} else {
j = i + 2
}
// If device is syncing at the moment, get the number of currently synced bytes,
// otherwise that number equals the size of the device.
// If device is syncing at the moment, get the number of currently
// synced bytes, otherwise that number equals the size of the device.
syncedBlocks := size
if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") {
syncedBlocks, err = evalBuildline(lines[j])
@ -103,8 +86,14 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
}
}
mdStates = append(mdStates, MDStat{currentMD, activityState, active, total, size, syncedBlocks})
mdStates = append(mdStates, MDStat{
Name: mdName,
ActivityState: activityState,
DisksActive: active,
DisksTotal: total,
BlocksTotal: size,
BlocksSynced: syncedBlocks,
})
}
return mdStates, nil
@ -112,47 +101,38 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
func evalStatusline(statusline string) (active, total, size int64, err error) {
matches := statuslineRE.FindStringSubmatch(statusline)
// +1 to make it more obvious that the whole string containing the info is also returned as matches[0].
if len(matches) != 3+1 {
return 0, 0, 0, fmt.Errorf("unexpected number matches found in statusline: %s", statusline)
if len(matches) != 4 {
return 0, 0, 0, fmt.Errorf("unexpected statusline: %s", statusline)
}
size, err = strconv.ParseInt(matches[1], 10, 64)
if err != nil {
return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline)
return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
}
total, err = strconv.ParseInt(matches[2], 10, 64)
if err != nil {
return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline)
return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
}
active, err = strconv.ParseInt(matches[3], 10, 64)
if err != nil {
return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline)
return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
}
return active, total, size, nil
}
// Gets the size that has already been synced out of the sync-line.
func evalBuildline(buildline string) (int64, error) {
func evalBuildline(buildline string) (syncedBlocks int64, err error) {
matches := buildlineRE.FindStringSubmatch(buildline)
// +1 to make it more obvious that the whole string containing the info is also returned as matches[0].
if len(matches) < 1+1 {
return 0, fmt.Errorf("too few matches found in buildline: %s", buildline)
if len(matches) != 2 {
return 0, fmt.Errorf("unexpected buildline: %s", buildline)
}
if len(matches) > 1+1 {
return 0, fmt.Errorf("too many matches found in buildline: %s", buildline)
}
syncedSize, err := strconv.ParseInt(matches[1], 10, 64)
syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64)
if err != nil {
return 0, fmt.Errorf("%s in buildline: %s", err, buildline)
}
return syncedSize, nil
return syncedBlocks, nil
}

View file

@ -4,7 +4,6 @@ import (
"fmt"
"io/ioutil"
"os"
"path"
"strconv"
"strings"
)
@ -42,7 +41,7 @@ func NewProc(pid int) (Proc, error) {
return fs.NewProc(pid)
}
// AllProcs returns a list of all currently avaible processes under /proc.
// AllProcs returns a list of all currently available processes under /proc.
func AllProcs() (Procs, error) {
fs, err := NewFS(DefaultMountPoint)
if err != nil {
@ -53,7 +52,7 @@ func AllProcs() (Procs, error) {
// Self returns a process for the current process.
func (fs FS) Self() (Proc, error) {
p, err := fs.readlink("self")
p, err := os.Readlink(fs.Path("self"))
if err != nil {
return Proc{}, err
}
@ -66,15 +65,15 @@ func (fs FS) Self() (Proc, error) {
// NewProc returns a process for the given pid.
func (fs FS) NewProc(pid int) (Proc, error) {
if _, err := fs.stat(strconv.Itoa(pid)); err != nil {
if _, err := os.Stat(fs.Path(strconv.Itoa(pid))); err != nil {
return Proc{}, err
}
return Proc{PID: pid, fs: fs}, nil
}
// AllProcs returns a list of all currently avaible processes.
// AllProcs returns a list of all currently available processes.
func (fs FS) AllProcs() (Procs, error) {
d, err := fs.open("")
d, err := os.Open(fs.Path())
if err != nil {
return Procs{}, err
}
@ -99,7 +98,7 @@ func (fs FS) AllProcs() (Procs, error) {
// CmdLine returns the command line of a process.
func (p Proc) CmdLine() ([]string, error) {
f, err := p.open("cmdline")
f, err := os.Open(p.path("cmdline"))
if err != nil {
return nil, err
}
@ -117,10 +116,25 @@ func (p Proc) CmdLine() ([]string, error) {
return strings.Split(string(data[:len(data)-1]), string(byte(0))), nil
}
// Comm returns the command name of a process.
func (p Proc) Comm() (string, error) {
f, err := os.Open(p.path("comm"))
if err != nil {
return "", err
}
defer f.Close()
data, err := ioutil.ReadAll(f)
if err != nil {
return "", err
}
return strings.TrimSpace(string(data)), nil
}
// Executable returns the absolute path of the executable command of a process.
func (p Proc) Executable() (string, error) {
exe, err := p.readlink("exe")
exe, err := os.Readlink(p.path("exe"))
if os.IsNotExist(err) {
return "", nil
}
@ -158,7 +172,7 @@ func (p Proc) FileDescriptorTargets() ([]string, error) {
targets := make([]string, len(names))
for i, name := range names {
target, err := p.readlink("fd/" + name)
target, err := os.Readlink(p.path("fd", name))
if err == nil {
targets[i] = target
}
@ -179,7 +193,7 @@ func (p Proc) FileDescriptorsLen() (int, error) {
}
func (p Proc) fileDescriptors() ([]string, error) {
d, err := p.open("fd")
d, err := os.Open(p.path("fd"))
if err != nil {
return nil, err
}
@ -193,10 +207,6 @@ func (p Proc) fileDescriptors() ([]string, error) {
return names, nil
}
func (p Proc) open(pa string) (*os.File, error) {
return p.fs.open(path.Join(strconv.Itoa(p.PID), pa))
}
func (p Proc) readlink(pa string) (string, error) {
return p.fs.readlink(path.Join(strconv.Itoa(p.PID), pa))
func (p Proc) path(pa ...string) string {
return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...)
}

View file

@ -3,6 +3,7 @@ package procfs
import (
"fmt"
"io/ioutil"
"os"
)
// ProcIO models the content of /proc/<pid>/io.
@ -29,7 +30,7 @@ type ProcIO struct {
func (p Proc) NewIO() (ProcIO, error) {
pio := ProcIO{}
f, err := p.open("io")
f, err := os.Open(p.path("io"))
if err != nil {
return pio, err
}

View file

@ -3,29 +3,56 @@ package procfs
import (
"bufio"
"fmt"
"os"
"regexp"
"strconv"
)
// ProcLimits represents the soft limits for each of the process's resource
// limits.
// limits. For more information see getrlimit(2):
// http://man7.org/linux/man-pages/man2/getrlimit.2.html.
type ProcLimits struct {
CPUTime int
FileSize int
DataSize int
StackSize int
CoreFileSize int
ResidentSet int
Processes int
OpenFiles int
LockedMemory int
AddressSpace int
FileLocks int
PendingSignals int
MsqqueueSize int
NicePriority int
// CPU time limit in seconds.
CPUTime int
// Maximum size of files that the process may create.
FileSize int
// Maximum size of the process's data segment (initialized data,
// uninitialized data, and heap).
DataSize int
// Maximum size of the process stack in bytes.
StackSize int
// Maximum size of a core file.
CoreFileSize int
// Limit of the process's resident set in pages.
ResidentSet int
// Maximum number of processes that can be created for the real user ID of
// the calling process.
Processes int
// Value one greater than the maximum file descriptor number that can be
// opened by this process.
OpenFiles int
// Maximum number of bytes of memory that may be locked into RAM.
LockedMemory int
// Maximum size of the process's virtual memory address space in bytes.
AddressSpace int
// Limit on the combined number of flock(2) locks and fcntl(2) leases that
// this process may establish.
FileLocks int
// Limit of signals that may be queued for the real user ID of the calling
// process.
PendingSignals int
// Limit on the number of bytes that can be allocated for POSIX message
// queues for the real user ID of the calling process.
MsqqueueSize int
// Limit of the nice priority set using setpriority(2) or nice(2).
NicePriority int
// Limit of the real-time priority set using sched_setscheduler(2) or
// sched_setparam(2).
RealtimePriority int
RealtimeTimeout int
// Limit (in microseconds) on the amount of CPU time that a process
// scheduled under a real-time scheduling policy may consume without making
// a blocking system call.
RealtimeTimeout int
}
const (
@ -39,7 +66,7 @@ var (
// NewLimits returns the current soft limits of the process.
func (p Proc) NewLimits() (ProcLimits, error) {
f, err := p.open("limits")
f, err := os.Open(p.path("limits"))
if err != nil {
return ProcLimits{}, err
}
@ -60,7 +87,7 @@ func (p Proc) NewLimits() (ProcLimits, error) {
case "Max cpu time":
l.CPUTime, err = parseInt(fields[1])
case "Max file size":
l.FileLocks, err = parseInt(fields[1])
l.FileSize, err = parseInt(fields[1])
case "Max data size":
l.DataSize, err = parseInt(fields[1])
case "Max stack size":
@ -90,7 +117,6 @@ func (p Proc) NewLimits() (ProcLimits, error) {
case "Max realtime timeout":
l.RealtimeTimeout, err = parseInt(fields[1])
}
if err != nil {
return ProcLimits{}, err
}

View file

@ -7,15 +7,15 @@ import (
"os"
)
// Originally, this USER_HZ value was dynamically retrieved via a sysconf call which
// required cgo. However, that caused a lot of problems regarding
// Originally, this USER_HZ value was dynamically retrieved via a sysconf call
// which required cgo. However, that caused a lot of problems regarding
// cross-compilation. Alternatives such as running a binary to determine the
// value, or trying to derive it in some other way were all problematic.
// After much research it was determined that USER_HZ is actually hardcoded to
// 100 on all Go-supported platforms as of the time of this writing. This is
// why we decided to hardcode it here as well. It is not impossible that there
// could be systems with exceptions, but they should be very exotic edge cases,
// and in that case, the worst outcome will be two misreported metrics.
// value, or trying to derive it in some other way were all problematic. After
// much research it was determined that USER_HZ is actually hardcoded to 100 on
// all Go-supported platforms as of the time of this writing. This is why we
// decided to hardcode it here as well. It is not impossible that there could
// be systems with exceptions, but they should be very exotic edge cases, and
// in that case, the worst outcome will be two misreported metrics.
//
// See also the following discussions:
//
@ -91,7 +91,7 @@ type ProcStat struct {
// NewStat returns the current status information of the process.
func (p Proc) NewStat() (ProcStat, error) {
f, err := p.open("stat")
f, err := os.Open(p.path("stat"))
if err != nil {
return ProcStat{}, err
}

View file

@ -3,6 +3,7 @@ package procfs
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
@ -25,7 +26,7 @@ func NewStat() (Stat, error) {
// NewStat returns an information about current kernel/system statistics.
func (fs FS) NewStat() (Stat, error) {
f, err := fs.open("stat")
f, err := os.Open(fs.Path("stat"))
if err != nil {
return Stat{}, err
}