From 65ef46ebddfd818f13ebd9f3d757c10c53b5e53b Mon Sep 17 00:00:00 2001 From: Boaz Shuster Date: Wed, 21 Jun 2017 13:20:02 +0300 Subject: [PATCH 01/62] Update the cp command docs to include archive Signed-off-by: Boaz Shuster Upstream-commit: e4c70d390de72bfa9bbb6d016a47a08141295bf3 Component: cli --- components/cli/docs/reference/commandline/cp.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/cli/docs/reference/commandline/cp.md b/components/cli/docs/reference/commandline/cp.md index 5cbbee25ae..8b067f22cd 100644 --- a/components/cli/docs/reference/commandline/cp.md +++ b/components/cli/docs/reference/commandline/cp.md @@ -28,6 +28,7 @@ container source to stdout. Options: -L, --follow-link Always follow symbol link in SRC_PATH + -a, --archive Archive mode (copy all uid/gid information) --help Print usage ``` @@ -53,7 +54,9 @@ copied recursively with permissions preserved if possible. Ownership is set to the user and primary group at the destination. For example, files copied to a container are created with `UID:GID` of the root user. Files copied to the local machine are created with the `UID:GID` of the user which invoked the `docker cp` -command. If you specify the `-L` option, `docker cp` follows any symbolic link +command. However, if you specify the `-a` option, `docker cp` sets the ownership +to the user and primary group at the source. +If you specify the `-L` option, `docker cp` follows any symbolic link in the `SRC_PATH`. `docker cp` does *not* create parent directories for `DEST_PATH` if they do not exist. From 68bbc40c7ac21b7f6e6ea3c5c4ef1c4099091ee2 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Mon, 3 Jul 2017 10:38:00 +0200 Subject: [PATCH 02/62] Add bash completion for `build --iidfile` This adds bash completion for https://github.com/moby/moby/pull/32406. Signed-off-by: Harald Albers Upstream-commit: 1f8720717d58597cb4474e70fa6d534db132229b Component: cli --- components/cli/contrib/completion/bash/docker | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 33ada275b1..469e18fb42 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -2221,6 +2221,7 @@ _docker_image_build() { --cpu-period --cpu-quota --file -f + --iidfile --label --memory -m --memory-swap @@ -2265,7 +2266,7 @@ _docker_image_build() { __docker_complete_image_repos_and_tags return ;; - --file|-f) + --file|-f|--iidfile) _filedir return ;; From 53d008d01f15f43dbdae1d092f0d32364c3f61e2 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Mon, 3 Jul 2017 11:04:26 +0200 Subject: [PATCH 03/62] Add bash completion for awslogs multiline log driver options This adds bash completion for https://github.com/moby/moby/pull/30891. Signed-off-by: Harald Albers Upstream-commit: 1d21a3dd7c4ffff80c093c005b910a131e7fc05a Component: cli --- components/cli/contrib/completion/bash/docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 33ada275b1..4756cecc6b 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -754,7 +754,7 @@ __docker_complete_log_options() { local common_options2="env env-regex labels" # awslogs does not implement the $common_options2. - local awslogs_options="$common_options1 awslogs-create-group awslogs-group awslogs-region awslogs-stream tag" + local awslogs_options="$common_options1 awslogs-create-group awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag" local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries tag" local gcplogs_options="$common_options1 $common_options2 gcp-log-cmd gcp-meta-id gcp-meta-name gcp-meta-zone gcp-project" From a1db9ae74337421c379d65f44cf4f011d27af522 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Mon, 3 Jul 2017 11:30:24 +0200 Subject: [PATCH 04/62] Add metric plugins to bash completion for `plugin ls --filter capability` This adds bash completion for https://github.com/moby/moby/pull/32874. Signed-off-by: Harald Albers Upstream-commit: 2caf425f02363a5894b5790dcde47a11808d23e1 Component: cli --- components/cli/contrib/completion/bash/docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 33ada275b1..c0fa29f40d 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -3762,7 +3762,7 @@ _docker_plugin_ls() { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in capability) - COMPREPLY=( $( compgen -W "authz ipamdriver networkdriver volumedriver" -- "${cur##*=}" ) ) + COMPREPLY=( $( compgen -W "authz ipamdriver logdriver metricscollector networkdriver volumedriver" -- "${cur##*=}" ) ) return ;; enabled) From 31ba47d5fe46f7a5ee171dff31d021f885eb67da Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Mon, 3 Jul 2017 17:33:03 +0200 Subject: [PATCH 05/62] Improve bash completion for `service create|update --detach` bash completion usually completes boolean options that default to `true` with the `=false` suffix because that is the only syntax that really changes behavior. For this option, I implemented completion falsely. Signed-off-by: Harald Albers Upstream-commit: fc0dafbbd11130ac24f8905f697b71e99f32d4e6 Component: cli --- components/cli/contrib/completion/bash/docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 33ada275b1..d689935b35 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -3081,7 +3081,7 @@ _docker_service_update_and_create() { " local boolean_options=" - --detach -d + --detach=false -d=false --help --no-healthcheck --read-only From 9ee14880db9f8c5d6caadc08e894a1243322152d Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 1 Jul 2017 22:24:01 -0700 Subject: [PATCH 06/62] Bump SwarmKit to 79381d0840be27f8b3f5c667b348a4467d866eeb Signed-off-by: Sebastiaan van Stijn Upstream-commit: 585e099a9a896bd84b8f1a243a9dddeb5ad281a1 Component: cli --- components/cli/vendor.conf | 2 +- .../docker/swarmkit/api/objects.pb.go | 248 ++- .../docker/swarmkit/api/objects.proto | 2 + .../docker/swarmkit/api/specs.pb.go | 554 ++++-- .../docker/swarmkit/api/specs.proto | 26 +- .../docker/swarmkit/api/types.pb.go | 1714 ++++++++++++----- .../docker/swarmkit/api/types.proto | 20 + .../github.com/docker/swarmkit/vendor.conf | 20 +- 8 files changed, 1870 insertions(+), 716 deletions(-) diff --git a/components/cli/vendor.conf b/components/cli/vendor.conf index 9e7742e658..a9a8f3ddb6 100755 --- a/components/cli/vendor.conf +++ b/components/cli/vendor.conf @@ -15,7 +15,7 @@ github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a github.com/docker/notary v0.4.2 -github.com/docker/swarmkit 1a3e510517be82d18ac04380b5f71eddf06c2fc0 +github.com/docker/swarmkit 79381d0840be27f8b3f5c667b348a4467d866eeb github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff github.com/gogo/protobuf 7efa791bd276fd4db00867cbd982b552627c24cb github.com/golang/protobuf 8ee79997227bf9b34611aee7946ae64735e6fd93 diff --git a/components/cli/vendor/github.com/docker/swarmkit/api/objects.pb.go b/components/cli/vendor/github.com/docker/swarmkit/api/objects.pb.go index e9c2438502..b6a9389a6d 100644 --- a/components/cli/vendor/github.com/docker/swarmkit/api/objects.pb.go +++ b/components/cli/vendor/github.com/docker/swarmkit/api/objects.pb.go @@ -198,7 +198,8 @@ type Task struct { // such a cluster default or policy-based value. // // If not present, the daemon's default will be used. - LogDriver *Driver `protobuf:"bytes,13,opt,name=log_driver,json=logDriver" json:"log_driver,omitempty"` + LogDriver *Driver `protobuf:"bytes,13,opt,name=log_driver,json=logDriver" json:"log_driver,omitempty"` + AssignedGenericResources []*GenericResource `protobuf:"bytes,15,rep,name=assigned_generic_resources,json=assignedGenericResources" json:"assigned_generic_resources,omitempty"` } func (m *Task) Reset() { *m = Task{} } @@ -529,6 +530,14 @@ func (m *Task) CopyFrom(src interface{}) { m.LogDriver = &Driver{} github_com_docker_swarmkit_api_deepcopy.Copy(m.LogDriver, o.LogDriver) } + if o.AssignedGenericResources != nil { + m.AssignedGenericResources = make([]*GenericResource, len(o.AssignedGenericResources)) + for i := range m.AssignedGenericResources { + m.AssignedGenericResources[i] = &GenericResource{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.AssignedGenericResources[i], o.AssignedGenericResources[i]) + } + } + } func (m *NetworkAttachment) Copy() *NetworkAttachment { @@ -1140,6 +1149,18 @@ func (m *Task) MarshalTo(dAtA []byte) (int, error) { } i += n26 } + if len(m.AssignedGenericResources) > 0 { + for _, msg := range m.AssignedGenericResources { + dAtA[i] = 0x7a + i++ + i = encodeVarintObjects(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -1771,6 +1792,12 @@ func (m *Task) Size() (n int) { l = m.SpecVersion.Size() n += 1 + l + sovObjects(uint64(l)) } + if len(m.AssignedGenericResources) > 0 { + for _, e := range m.AssignedGenericResources { + l = e.Size() + n += 1 + l + sovObjects(uint64(l)) + } + } return n } @@ -4419,6 +4446,7 @@ func (this *Task) String() string { `Endpoint:` + strings.Replace(fmt.Sprintf("%v", this.Endpoint), "Endpoint", "Endpoint", 1) + `,`, `LogDriver:` + strings.Replace(fmt.Sprintf("%v", this.LogDriver), "Driver", "Driver", 1) + `,`, `SpecVersion:` + strings.Replace(fmt.Sprintf("%v", this.SpecVersion), "Version", "Version", 1) + `,`, + `AssignedGenericResources:` + strings.Replace(fmt.Sprintf("%v", this.AssignedGenericResources), "GenericResource", "GenericResource", 1) + `,`, `}`, }, "") return s @@ -6001,6 +6029,37 @@ func (m *Task) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssignedGenericResources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowObjects + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthObjects + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssignedGenericResources = append(m.AssignedGenericResources, &GenericResource{}) + if err := m.AssignedGenericResources[len(m.AssignedGenericResources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipObjects(dAtA[iNdEx:]) @@ -7630,96 +7689,99 @@ var ( func init() { proto.RegisterFile("objects.proto", fileDescriptorObjects) } var fileDescriptorObjects = []byte{ - // 1451 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6f, 0x1b, 0x45, - 0x14, 0xef, 0xda, 0x1b, 0x7f, 0x3c, 0x27, 0x56, 0x98, 0x86, 0xe0, 0x9a, 0x60, 0x07, 0x57, 0xa0, - 0x0a, 0x55, 0x4e, 0x09, 0x05, 0xa5, 0x81, 0xd2, 0xda, 0x49, 0xd4, 0x5a, 0xa5, 0x34, 0x9a, 0x96, - 0x96, 0x9b, 0x99, 0xec, 0x4e, 0xdd, 0xc5, 0xeb, 0x9d, 0xd5, 0xce, 0xd8, 0xc5, 0x37, 0xce, 0xf9, - 0x07, 0x72, 0xe3, 0xd0, 0x13, 0x77, 0xb8, 0x70, 0xe1, 0xc0, 0xa9, 0x47, 0x4e, 0x88, 0x53, 0x44, - 0xfd, 0x5f, 0x20, 0x71, 0x40, 0x33, 0x3b, 0x6b, 0x6f, 0xea, 0x75, 0x92, 0xa2, 0x2a, 0xe2, 0xe4, - 0xf9, 0xf8, 0xfd, 0xde, 0xd7, 0xbc, 0xf7, 0x66, 0xd6, 0xb0, 0xc0, 0xf6, 0xbe, 0xa5, 0x96, 0xe0, - 0x75, 0x3f, 0x60, 0x82, 0x21, 0x64, 0x33, 0xab, 0x4b, 0x83, 0x3a, 0x7f, 0x4a, 0x82, 0x5e, 0xd7, - 0x11, 0xf5, 0xc1, 0x87, 0xe5, 0x82, 0x18, 0xfa, 0x54, 0x03, 0xca, 0x05, 0xee, 0x53, 0x2b, 0x9a, - 0x54, 0x3b, 0x8c, 0x75, 0x5c, 0xba, 0xa6, 0x66, 0x7b, 0xfd, 0xc7, 0x6b, 0xc2, 0xe9, 0x51, 0x2e, - 0x48, 0xcf, 0xd7, 0x80, 0xa5, 0x0e, 0xeb, 0x30, 0x35, 0x5c, 0x93, 0x23, 0xbd, 0x7a, 0xe1, 0x65, - 0x1a, 0xf1, 0x86, 0x7a, 0xeb, 0xbc, 0xef, 0xf6, 0x3b, 0x8e, 0xb7, 0x16, 0xfe, 0x84, 0x8b, 0xb5, - 0x5f, 0x0c, 0x30, 0xef, 0x52, 0x41, 0xd0, 0xa7, 0x90, 0x1d, 0xd0, 0x80, 0x3b, 0xcc, 0x2b, 0x19, - 0xab, 0xc6, 0xa5, 0xc2, 0xfa, 0xdb, 0xf5, 0x69, 0x7b, 0xeb, 0x0f, 0x43, 0x48, 0xd3, 0x7c, 0x7e, - 0x58, 0x3d, 0x87, 0x23, 0x06, 0xba, 0x06, 0x60, 0x05, 0x94, 0x08, 0x6a, 0xb7, 0x89, 0x28, 0xa5, - 0x14, 0xbf, 0x5c, 0x0f, 0x4d, 0xa9, 0x47, 0xa6, 0xd4, 0x1f, 0x44, 0x1e, 0xe0, 0xbc, 0x46, 0x37, - 0x84, 0xa4, 0xf6, 0x7d, 0x3b, 0xa2, 0xa6, 0x4f, 0xa6, 0x6a, 0x74, 0x43, 0xd4, 0x7e, 0x32, 0xc1, - 0xfc, 0x92, 0xd9, 0x14, 0x2d, 0x43, 0xca, 0xb1, 0x95, 0xd9, 0xf9, 0x66, 0x66, 0x74, 0x58, 0x4d, - 0xb5, 0xb6, 0x71, 0xca, 0xb1, 0xd1, 0x3a, 0x98, 0x3d, 0x2a, 0x88, 0x36, 0xa8, 0x94, 0xe4, 0x90, - 0xf4, 0x5d, 0x7b, 0xa3, 0xb0, 0xe8, 0x13, 0x30, 0xe5, 0x31, 0x68, 0x4b, 0x56, 0x92, 0x38, 0x52, - 0xe7, 0x7d, 0x9f, 0x5a, 0x11, 0x4f, 0xe2, 0xd1, 0x0e, 0x14, 0x6c, 0xca, 0xad, 0xc0, 0xf1, 0x85, - 0x8c, 0xa1, 0xa9, 0xe8, 0x17, 0x67, 0xd1, 0xb7, 0x27, 0x50, 0x1c, 0xe7, 0xa1, 0xcf, 0x20, 0xc3, - 0x05, 0x11, 0x7d, 0x5e, 0x9a, 0x53, 0x12, 0x2a, 0x33, 0x0d, 0x50, 0x28, 0x6d, 0x82, 0xe6, 0xa0, - 0xdb, 0x50, 0xec, 0x11, 0x8f, 0x74, 0x68, 0xd0, 0xd6, 0x52, 0x32, 0x4a, 0xca, 0xbb, 0x89, 0xae, - 0x87, 0xc8, 0x50, 0x10, 0x5e, 0xe8, 0xc5, 0xa7, 0x68, 0x07, 0x80, 0x08, 0x41, 0xac, 0x27, 0x3d, - 0xea, 0x89, 0x52, 0x56, 0x49, 0x79, 0x2f, 0xd1, 0x16, 0x2a, 0x9e, 0xb2, 0xa0, 0xdb, 0x18, 0x83, - 0x71, 0x8c, 0x88, 0x6e, 0x41, 0xc1, 0xa2, 0x81, 0x70, 0x1e, 0x3b, 0x16, 0x11, 0xb4, 0x94, 0x53, - 0x72, 0xaa, 0x49, 0x72, 0xb6, 0x26, 0x30, 0xed, 0x54, 0x9c, 0x89, 0xae, 0x80, 0x19, 0x30, 0x97, - 0x96, 0xf2, 0xab, 0xc6, 0xa5, 0xe2, 0xec, 0x63, 0xc1, 0xcc, 0xa5, 0x58, 0x21, 0x37, 0x97, 0xf7, - 0x0f, 0x6a, 0x08, 0x16, 0x73, 0xc6, 0xa2, 0xa1, 0x52, 0xc3, 0xb8, 0x62, 0x7c, 0x6d, 0x7c, 0x63, - 0xd4, 0xfe, 0x49, 0x43, 0xf6, 0x3e, 0x0d, 0x06, 0x8e, 0xf5, 0x7a, 0x13, 0xe7, 0xda, 0x91, 0xc4, - 0x49, 0xf4, 0x51, 0xab, 0x9d, 0xca, 0x9d, 0x0d, 0xc8, 0x51, 0xcf, 0xf6, 0x99, 0xe3, 0x09, 0x9d, - 0x38, 0x89, 0x0e, 0xee, 0x68, 0x0c, 0x1e, 0xa3, 0xd1, 0x0e, 0x2c, 0x84, 0xf5, 0xd0, 0x3e, 0x92, - 0x35, 0xab, 0x49, 0xf4, 0xaf, 0x14, 0x50, 0x1f, 0xf7, 0x7c, 0x3f, 0x36, 0x43, 0xdb, 0xb0, 0xe0, - 0x07, 0x74, 0xe0, 0xb0, 0x3e, 0x6f, 0x2b, 0x27, 0x32, 0xa7, 0x72, 0x02, 0xcf, 0x47, 0x2c, 0x39, - 0x43, 0x9f, 0xc3, 0xbc, 0x24, 0xb7, 0xa3, 0x3e, 0x02, 0x27, 0xf6, 0x11, 0xac, 0x5a, 0x9e, 0x9e, - 0xa0, 0x7b, 0xf0, 0xe6, 0x11, 0x2b, 0xc6, 0x82, 0x0a, 0x27, 0x0b, 0x3a, 0x1f, 0xb7, 0x44, 0x2f, - 0x6e, 0xa2, 0xfd, 0x83, 0x5a, 0x11, 0xe6, 0xe3, 0x29, 0x50, 0xfb, 0x21, 0x05, 0xb9, 0x28, 0x90, - 0xe8, 0xaa, 0x3e, 0x33, 0x63, 0x76, 0xd4, 0x22, 0xac, 0xf2, 0x37, 0x3c, 0xae, 0xab, 0x30, 0xe7, - 0xb3, 0x40, 0xf0, 0x52, 0x6a, 0x35, 0x3d, 0xab, 0x44, 0x77, 0x59, 0x20, 0xb6, 0x98, 0xf7, 0xd8, - 0xe9, 0xe0, 0x10, 0x8c, 0x1e, 0x41, 0x61, 0xe0, 0x04, 0xa2, 0x4f, 0xdc, 0xb6, 0xe3, 0xf3, 0x52, - 0x5a, 0x71, 0xdf, 0x3f, 0x4e, 0x65, 0xfd, 0x61, 0x88, 0x6f, 0xed, 0x36, 0x8b, 0xa3, 0xc3, 0x2a, - 0x8c, 0xa7, 0x1c, 0x83, 0x16, 0xd5, 0xf2, 0x79, 0xf9, 0x2e, 0xe4, 0xc7, 0x3b, 0xe8, 0x32, 0x80, - 0x17, 0x56, 0x64, 0x7b, 0x9c, 0xd9, 0x0b, 0xa3, 0xc3, 0x6a, 0x5e, 0xd7, 0x69, 0x6b, 0x1b, 0xe7, - 0x35, 0xa0, 0x65, 0x23, 0x04, 0x26, 0xb1, 0xed, 0x40, 0xe5, 0x79, 0x1e, 0xab, 0x71, 0xed, 0xc7, - 0x0c, 0x98, 0x0f, 0x08, 0xef, 0x9e, 0x75, 0x57, 0x95, 0x3a, 0xa7, 0x2a, 0xe3, 0x32, 0x00, 0x0f, - 0xf3, 0x4d, 0xba, 0x63, 0x4e, 0xdc, 0xd1, 0x59, 0x28, 0xdd, 0xd1, 0x80, 0xd0, 0x1d, 0xee, 0x32, - 0xa1, 0x8a, 0xc0, 0xc4, 0x6a, 0x8c, 0x2e, 0x42, 0xd6, 0x63, 0xb6, 0xa2, 0x67, 0x14, 0x1d, 0x46, - 0x87, 0xd5, 0x8c, 0xec, 0x15, 0xad, 0x6d, 0x9c, 0x91, 0x5b, 0x2d, 0x5b, 0xb6, 0x29, 0xe2, 0x79, - 0x4c, 0x10, 0xd9, 0x83, 0xb9, 0x6e, 0x77, 0x89, 0xd9, 0xdf, 0x98, 0xc0, 0xa2, 0x36, 0x15, 0x63, - 0xa2, 0x87, 0x70, 0x3e, 0xb2, 0x37, 0x2e, 0x30, 0xf7, 0x2a, 0x02, 0x91, 0x96, 0x10, 0xdb, 0x89, - 0x5d, 0x0b, 0xf9, 0xd9, 0xd7, 0x82, 0x8a, 0x60, 0xd2, 0xb5, 0xd0, 0x84, 0x05, 0x9b, 0x72, 0x27, - 0xa0, 0xb6, 0x6a, 0x13, 0x54, 0x55, 0x66, 0x71, 0xfd, 0x9d, 0xe3, 0x84, 0x50, 0x3c, 0xaf, 0x39, - 0x6a, 0x86, 0x1a, 0x90, 0xd3, 0x79, 0xc3, 0x4b, 0x05, 0x95, 0xbb, 0xa7, 0xbc, 0x0e, 0xc6, 0xb4, - 0x23, 0x6d, 0x6e, 0xfe, 0x95, 0xda, 0xdc, 0x35, 0x00, 0x97, 0x75, 0xda, 0x76, 0xe0, 0x0c, 0x68, - 0x50, 0x5a, 0xd0, 0x8f, 0x84, 0x04, 0xee, 0xb6, 0x42, 0xe0, 0xbc, 0xcb, 0x3a, 0xe1, 0x70, 0xaa, - 0x29, 0x15, 0x5f, 0xad, 0x29, 0x6d, 0x96, 0xf7, 0x0f, 0x6a, 0xcb, 0xb0, 0x14, 0xef, 0x21, 0x1b, - 0xc6, 0x4d, 0xe3, 0xb6, 0xb1, 0x6b, 0xd4, 0x7e, 0x4b, 0xc1, 0x1b, 0x53, 0x0e, 0xa3, 0x8f, 0x21, - 0xab, 0x5d, 0x3e, 0xee, 0x25, 0xa5, 0x79, 0x38, 0xc2, 0xa2, 0x15, 0xc8, 0xcb, 0xfa, 0xa3, 0x9c, - 0xd3, 0xb0, 0xb3, 0xe4, 0xf1, 0x64, 0x01, 0x95, 0x20, 0x4b, 0x5c, 0x87, 0xc8, 0xbd, 0xb4, 0xda, - 0x8b, 0xa6, 0xa8, 0x0f, 0xcb, 0x61, 0x5c, 0xda, 0x93, 0x7b, 0xb7, 0xcd, 0x7c, 0xc1, 0x4b, 0xa6, - 0x3a, 0xa6, 0x1b, 0xa7, 0x3a, 0x26, 0x1d, 0xb9, 0xc9, 0xc2, 0x3d, 0x5f, 0xf0, 0x1d, 0x4f, 0x04, - 0x43, 0xbc, 0x64, 0x27, 0x6c, 0x95, 0x6f, 0xc1, 0x85, 0x99, 0x14, 0xb4, 0x08, 0xe9, 0x2e, 0x1d, - 0x86, 0xbd, 0x03, 0xcb, 0x21, 0x5a, 0x82, 0xb9, 0x01, 0x71, 0xfb, 0x54, 0xb7, 0x9a, 0x70, 0xb2, - 0x99, 0xda, 0x30, 0x6a, 0xcf, 0x52, 0x90, 0xd5, 0xe6, 0x9c, 0xf5, 0x7d, 0xac, 0xd5, 0x4e, 0x75, - 0x9d, 0xeb, 0x30, 0xaf, 0x43, 0x1a, 0x96, 0x8b, 0x79, 0x62, 0xc2, 0x15, 0x42, 0x7c, 0x58, 0x2a, - 0xd7, 0xc1, 0x74, 0x7c, 0xd2, 0xd3, 0x77, 0x71, 0xa2, 0xe6, 0xd6, 0x6e, 0xe3, 0xee, 0x3d, 0x3f, - 0xac, 0xfa, 0xdc, 0xe8, 0xb0, 0x6a, 0xca, 0x05, 0xac, 0x68, 0x89, 0xb7, 0xd6, 0xcf, 0x73, 0x90, - 0xdd, 0x72, 0xfb, 0x5c, 0xd0, 0xe0, 0xac, 0x83, 0xa4, 0xd5, 0x4e, 0x05, 0x69, 0x0b, 0xb2, 0x01, - 0x63, 0xa2, 0x6d, 0x91, 0xe3, 0xe2, 0x83, 0x19, 0x13, 0x5b, 0x8d, 0x66, 0x51, 0x12, 0x65, 0xe3, - 0x0d, 0xe7, 0x38, 0x23, 0xa9, 0x5b, 0x04, 0x3d, 0x82, 0xe5, 0xe8, 0xba, 0xda, 0x63, 0x4c, 0x70, - 0x11, 0x10, 0xbf, 0xdd, 0xa5, 0x43, 0xf9, 0x90, 0x49, 0xcf, 0x7a, 0xb8, 0xee, 0x78, 0x56, 0x30, - 0x54, 0xc1, 0xbb, 0x43, 0x87, 0x78, 0x49, 0x0b, 0x68, 0x46, 0xfc, 0x3b, 0x74, 0xc8, 0xd1, 0x0d, - 0x58, 0xa1, 0x63, 0x98, 0x94, 0xd8, 0x76, 0x49, 0x4f, 0x5e, 0xc4, 0x6d, 0xcb, 0x65, 0x56, 0x57, - 0xdd, 0x05, 0x26, 0xbe, 0x40, 0xe3, 0xa2, 0xbe, 0x08, 0x11, 0x5b, 0x12, 0x80, 0x38, 0x94, 0xf6, - 0x5c, 0x62, 0x75, 0x5d, 0x87, 0xcb, 0x6f, 0x93, 0xd8, 0x5b, 0x54, 0xb6, 0x73, 0x69, 0xdb, 0xc6, - 0x31, 0xd1, 0xaa, 0x37, 0x27, 0xdc, 0xd8, 0xcb, 0x56, 0x57, 0xd4, 0x5b, 0x7b, 0xc9, 0xbb, 0xa8, - 0x09, 0x85, 0xbe, 0x27, 0xd5, 0x87, 0x31, 0xc8, 0x9f, 0x36, 0x06, 0x10, 0xb2, 0xa4, 0xe7, 0xe5, - 0x01, 0xac, 0x1c, 0xa7, 0x3c, 0xa1, 0x36, 0x6f, 0xc6, 0x6b, 0xb3, 0xb0, 0xfe, 0x41, 0x92, 0xbe, - 0x64, 0x91, 0xb1, 0x3a, 0x4e, 0x4c, 0xdb, 0x5f, 0x0d, 0xc8, 0xdc, 0xa7, 0x56, 0x40, 0xc5, 0x6b, - 0xcd, 0xda, 0x8d, 0x23, 0x59, 0x5b, 0x49, 0x7e, 0xa5, 0x4a, 0xad, 0x53, 0x49, 0x5b, 0x86, 0x9c, - 0xe3, 0x09, 0x1a, 0x78, 0xc4, 0x55, 0x59, 0x9b, 0xc3, 0xe3, 0x79, 0xa2, 0x03, 0xcf, 0x0c, 0xc8, - 0x84, 0xcf, 0xb8, 0xb3, 0x76, 0x20, 0xd4, 0xfa, 0xb2, 0x03, 0x89, 0x46, 0xfe, 0x6d, 0x40, 0x0e, - 0x53, 0xce, 0xfa, 0xc1, 0x6b, 0xfe, 0xa4, 0x79, 0xe9, 0x59, 0x94, 0xfe, 0xcf, 0xcf, 0x22, 0x04, - 0x66, 0xd7, 0xf1, 0xf4, 0x03, 0x0e, 0xab, 0x31, 0xaa, 0x43, 0xd6, 0x27, 0x43, 0x97, 0x11, 0x5b, - 0x37, 0xca, 0xa5, 0xa9, 0xaf, 0xfe, 0x86, 0x37, 0xc4, 0x11, 0x68, 0x73, 0x69, 0xff, 0xa0, 0xb6, - 0x08, 0xc5, 0xb8, 0xe7, 0x4f, 0x8c, 0xda, 0x1f, 0x06, 0xe4, 0x77, 0xbe, 0x13, 0xd4, 0x53, 0x5f, - 0x10, 0xff, 0x4b, 0xe7, 0x57, 0xa7, 0xff, 0x19, 0xc8, 0x1f, 0xf9, 0xe8, 0x4f, 0x3a, 0xd4, 0x66, - 0xe9, 0xf9, 0x8b, 0xca, 0xb9, 0x3f, 0x5f, 0x54, 0xce, 0x7d, 0x3f, 0xaa, 0x18, 0xcf, 0x47, 0x15, - 0xe3, 0xf7, 0x51, 0xc5, 0xf8, 0x6b, 0x54, 0x31, 0xf6, 0x32, 0x2a, 0x3e, 0x1f, 0xfd, 0x1b, 0x00, - 0x00, 0xff, 0xff, 0x1b, 0x47, 0x17, 0xba, 0x5f, 0x12, 0x00, 0x00, + // 1491 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcf, 0x6f, 0x1b, 0x4f, + 0x15, 0xef, 0xda, 0x1b, 0xff, 0x78, 0x4e, 0x4c, 0x98, 0x86, 0xb0, 0x35, 0xc1, 0x0e, 0xae, 0x40, + 0x15, 0xaa, 0x9c, 0x12, 0x0a, 0x4a, 0x03, 0xa5, 0xb5, 0x93, 0xa8, 0xb5, 0x4a, 0x69, 0x34, 0x2d, + 0x2d, 0xb7, 0x65, 0xb2, 0x3b, 0x75, 0x17, 0xaf, 0x77, 0x56, 0x3b, 0x63, 0x17, 0xdf, 0x38, 0x87, + 0x3f, 0x20, 0x37, 0x0e, 0xfd, 0x17, 0xe0, 0xc2, 0x85, 0x03, 0xa7, 0x1e, 0x39, 0x21, 0x4e, 0x11, + 0xf5, 0x7f, 0x81, 0xc4, 0xe1, 0xab, 0x99, 0x9d, 0xb5, 0x37, 0xf1, 0x3a, 0x49, 0xbf, 0xaa, 0xa2, + 0xef, 0x29, 0x33, 0x3b, 0x9f, 0xcf, 0x9b, 0xf7, 0xde, 0xbc, 0x5f, 0x31, 0xac, 0xb0, 0xa3, 0x3f, + 0x50, 0x47, 0xf0, 0x56, 0x18, 0x31, 0xc1, 0x10, 0x72, 0x99, 0xd3, 0xa7, 0x51, 0x8b, 0xbf, 0x27, + 0xd1, 0xa0, 0xef, 0x89, 0xd6, 0xe8, 0x27, 0xb5, 0x8a, 0x18, 0x87, 0x54, 0x03, 0x6a, 0x15, 0x1e, + 0x52, 0x27, 0xd9, 0x34, 0x7a, 0x8c, 0xf5, 0x7c, 0xba, 0xa5, 0x76, 0x47, 0xc3, 0xb7, 0x5b, 0xc2, + 0x1b, 0x50, 0x2e, 0xc8, 0x20, 0xd4, 0x80, 0xb5, 0x1e, 0xeb, 0x31, 0xb5, 0xdc, 0x92, 0x2b, 0xfd, + 0xf5, 0xd6, 0x79, 0x1a, 0x09, 0xc6, 0xfa, 0xe8, 0x66, 0xe8, 0x0f, 0x7b, 0x5e, 0xb0, 0x15, 0xff, + 0x89, 0x3f, 0x36, 0xff, 0x6e, 0x80, 0xf9, 0x9c, 0x0a, 0x82, 0x7e, 0x01, 0xc5, 0x11, 0x8d, 0xb8, + 0xc7, 0x02, 0xcb, 0xd8, 0x34, 0xee, 0x54, 0xb6, 0xbf, 0xd7, 0x9a, 0xd7, 0xb7, 0xf5, 0x3a, 0x86, + 0x74, 0xcc, 0x8f, 0xa7, 0x8d, 0x1b, 0x38, 0x61, 0xa0, 0x07, 0x00, 0x4e, 0x44, 0x89, 0xa0, 0xae, + 0x4d, 0x84, 0x95, 0x53, 0xfc, 0x5a, 0x2b, 0x56, 0xa5, 0x95, 0xa8, 0xd2, 0x7a, 0x95, 0x58, 0x80, + 0xcb, 0x1a, 0xdd, 0x16, 0x92, 0x3a, 0x0c, 0xdd, 0x84, 0x9a, 0xbf, 0x9c, 0xaa, 0xd1, 0x6d, 0xd1, + 0xfc, 0xab, 0x09, 0xe6, 0x6f, 0x98, 0x4b, 0xd1, 0x3a, 0xe4, 0x3c, 0x57, 0xa9, 0x5d, 0xee, 0x14, + 0x26, 0xa7, 0x8d, 0x5c, 0x77, 0x1f, 0xe7, 0x3c, 0x17, 0x6d, 0x83, 0x39, 0xa0, 0x82, 0x68, 0x85, + 0xac, 0x2c, 0x83, 0xa4, 0xed, 0xda, 0x1a, 0x85, 0x45, 0x3f, 0x07, 0x53, 0x3e, 0x83, 0xd6, 0x64, + 0x23, 0x8b, 0x23, 0xef, 0x7c, 0x19, 0x52, 0x27, 0xe1, 0x49, 0x3c, 0x3a, 0x80, 0x8a, 0x4b, 0xb9, + 0x13, 0x79, 0xa1, 0x90, 0x3e, 0x34, 0x15, 0xfd, 0xf6, 0x22, 0xfa, 0xfe, 0x0c, 0x8a, 0xd3, 0x3c, + 0xf4, 0x4b, 0x28, 0x70, 0x41, 0xc4, 0x90, 0x5b, 0x4b, 0x4a, 0x42, 0x7d, 0xa1, 0x02, 0x0a, 0xa5, + 0x55, 0xd0, 0x1c, 0xf4, 0x14, 0xaa, 0x03, 0x12, 0x90, 0x1e, 0x8d, 0x6c, 0x2d, 0xa5, 0xa0, 0xa4, + 0xfc, 0x20, 0xd3, 0xf4, 0x18, 0x19, 0x0b, 0xc2, 0x2b, 0x83, 0xf4, 0x16, 0x1d, 0x00, 0x10, 0x21, + 0x88, 0xf3, 0x6e, 0x40, 0x03, 0x61, 0x15, 0x95, 0x94, 0x1f, 0x66, 0xea, 0x42, 0xc5, 0x7b, 0x16, + 0xf5, 0xdb, 0x53, 0x30, 0x4e, 0x11, 0xd1, 0x13, 0xa8, 0x38, 0x34, 0x12, 0xde, 0x5b, 0xcf, 0x21, + 0x82, 0x5a, 0x25, 0x25, 0xa7, 0x91, 0x25, 0x67, 0x6f, 0x06, 0xd3, 0x46, 0xa5, 0x99, 0xe8, 0x1e, + 0x98, 0x11, 0xf3, 0xa9, 0x55, 0xde, 0x34, 0xee, 0x54, 0x17, 0x3f, 0x0b, 0x66, 0x3e, 0xc5, 0x0a, + 0xb9, 0xbb, 0x7e, 0x7c, 0xd2, 0x44, 0xb0, 0x5a, 0x32, 0x56, 0x0d, 0x15, 0x1a, 0xc6, 0x3d, 0xe3, + 0x77, 0xc6, 0xef, 0x8d, 0xe6, 0xff, 0xf3, 0x50, 0x7c, 0x49, 0xa3, 0x91, 0xe7, 0x7c, 0xd9, 0xc0, + 0x79, 0x70, 0x26, 0x70, 0x32, 0x6d, 0xd4, 0xd7, 0xce, 0xc5, 0xce, 0x0e, 0x94, 0x68, 0xe0, 0x86, + 0xcc, 0x0b, 0x84, 0x0e, 0x9c, 0x4c, 0x03, 0x0f, 0x34, 0x06, 0x4f, 0xd1, 0xe8, 0x00, 0x56, 0xe2, + 0x7c, 0xb0, 0xcf, 0x44, 0xcd, 0x66, 0x16, 0xfd, 0xb7, 0x0a, 0xa8, 0x9f, 0x7b, 0x79, 0x98, 0xda, + 0xa1, 0x7d, 0x58, 0x09, 0x23, 0x3a, 0xf2, 0xd8, 0x90, 0xdb, 0xca, 0x88, 0xc2, 0x95, 0x8c, 0xc0, + 0xcb, 0x09, 0x4b, 0xee, 0xd0, 0xaf, 0x60, 0x59, 0x92, 0xed, 0xa4, 0x8e, 0xc0, 0xa5, 0x75, 0x04, + 0xab, 0x92, 0xa7, 0x37, 0xe8, 0x05, 0x7c, 0xe7, 0x8c, 0x16, 0x53, 0x41, 0x95, 0xcb, 0x05, 0xdd, + 0x4c, 0x6b, 0xa2, 0x3f, 0xee, 0xa2, 0xe3, 0x93, 0x66, 0x15, 0x96, 0xd3, 0x21, 0xd0, 0xfc, 0x4b, + 0x0e, 0x4a, 0x89, 0x23, 0xd1, 0x7d, 0xfd, 0x66, 0xc6, 0x62, 0xaf, 0x25, 0x58, 0x65, 0x6f, 0xfc, + 0x5c, 0xf7, 0x61, 0x29, 0x64, 0x91, 0xe0, 0x56, 0x6e, 0x33, 0xbf, 0x28, 0x45, 0x0f, 0x59, 0x24, + 0xf6, 0x58, 0xf0, 0xd6, 0xeb, 0xe1, 0x18, 0x8c, 0xde, 0x40, 0x65, 0xe4, 0x45, 0x62, 0x48, 0x7c, + 0xdb, 0x0b, 0xb9, 0x95, 0x57, 0xdc, 0x1f, 0x5d, 0x74, 0x65, 0xeb, 0x75, 0x8c, 0xef, 0x1e, 0x76, + 0xaa, 0x93, 0xd3, 0x06, 0x4c, 0xb7, 0x1c, 0x83, 0x16, 0xd5, 0x0d, 0x79, 0xed, 0x39, 0x94, 0xa7, + 0x27, 0xe8, 0x2e, 0x40, 0x10, 0x67, 0xa4, 0x3d, 0x8d, 0xec, 0x95, 0xc9, 0x69, 0xa3, 0xac, 0xf3, + 0xb4, 0xbb, 0x8f, 0xcb, 0x1a, 0xd0, 0x75, 0x11, 0x02, 0x93, 0xb8, 0x6e, 0xa4, 0xe2, 0xbc, 0x8c, + 0xd5, 0xba, 0xf9, 0xe7, 0x22, 0x98, 0xaf, 0x08, 0xef, 0x5f, 0x77, 0x55, 0x95, 0x77, 0xce, 0x65, + 0xc6, 0x5d, 0x00, 0x1e, 0xc7, 0x9b, 0x34, 0xc7, 0x9c, 0x99, 0xa3, 0xa3, 0x50, 0x9a, 0xa3, 0x01, + 0xb1, 0x39, 0xdc, 0x67, 0x42, 0x25, 0x81, 0x89, 0xd5, 0x1a, 0xdd, 0x86, 0x62, 0xc0, 0x5c, 0x45, + 0x2f, 0x28, 0x3a, 0x4c, 0x4e, 0x1b, 0x05, 0x59, 0x2b, 0xba, 0xfb, 0xb8, 0x20, 0x8f, 0xba, 0xae, + 0x2c, 0x53, 0x24, 0x08, 0x98, 0x20, 0xb2, 0x06, 0x73, 0x5d, 0xee, 0x32, 0xa3, 0xbf, 0x3d, 0x83, + 0x25, 0x65, 0x2a, 0xc5, 0x44, 0xaf, 0xe1, 0x66, 0xa2, 0x6f, 0x5a, 0x60, 0xe9, 0x73, 0x04, 0x22, + 0x2d, 0x21, 0x75, 0x92, 0x6a, 0x0b, 0xe5, 0xc5, 0x6d, 0x41, 0x79, 0x30, 0xab, 0x2d, 0x74, 0x60, + 0xc5, 0xa5, 0xdc, 0x8b, 0xa8, 0xab, 0xca, 0x04, 0x55, 0x99, 0x59, 0xdd, 0xfe, 0xfe, 0x45, 0x42, + 0x28, 0x5e, 0xd6, 0x1c, 0xb5, 0x43, 0x6d, 0x28, 0xe9, 0xb8, 0xe1, 0x56, 0x45, 0xc5, 0xee, 0x15, + 0xdb, 0xc1, 0x94, 0x76, 0xa6, 0xcc, 0x2d, 0x7f, 0x56, 0x99, 0x7b, 0x00, 0xe0, 0xb3, 0x9e, 0xed, + 0x46, 0xde, 0x88, 0x46, 0xd6, 0x8a, 0x1e, 0x12, 0x32, 0xb8, 0xfb, 0x0a, 0x81, 0xcb, 0x3e, 0xeb, + 0xc5, 0xcb, 0xb9, 0xa2, 0x54, 0xfd, 0xcc, 0xa2, 0x44, 0xa0, 0x46, 0x38, 0xf7, 0x7a, 0x01, 0x75, + 0xed, 0x1e, 0x0d, 0x68, 0xe4, 0x39, 0x76, 0x44, 0x39, 0x1b, 0x46, 0x0e, 0xe5, 0xd6, 0xb7, 0x94, + 0x27, 0x32, 0xdb, 0xfc, 0x93, 0x18, 0x8c, 0x35, 0x16, 0x5b, 0x89, 0x98, 0x73, 0x07, 0x7c, 0xb7, + 0x76, 0x7c, 0xd2, 0x5c, 0x87, 0xb5, 0x74, 0x99, 0xda, 0x31, 0x1e, 0x1b, 0x4f, 0x8d, 0x43, 0xa3, + 0xf9, 0xcf, 0x1c, 0x7c, 0x7b, 0xce, 0xa7, 0xe8, 0x67, 0x50, 0xd4, 0x5e, 0xbd, 0x68, 0x58, 0xd3, + 0x3c, 0x9c, 0x60, 0xd1, 0x06, 0x94, 0x65, 0x8a, 0x53, 0xce, 0x69, 0x5c, 0xbc, 0xca, 0x78, 0xf6, + 0x01, 0x59, 0x50, 0x24, 0xbe, 0x47, 0xe4, 0x59, 0x5e, 0x9d, 0x25, 0x5b, 0x34, 0x84, 0xf5, 0xd8, + 0xf5, 0xf6, 0xac, 0xb5, 0xdb, 0x2c, 0x14, 0xdc, 0x32, 0x95, 0xfd, 0x8f, 0xae, 0x14, 0x09, 0xfa, + 0x71, 0x66, 0x1f, 0x5e, 0x84, 0x82, 0x1f, 0x04, 0x22, 0x1a, 0xe3, 0x35, 0x37, 0xe3, 0xa8, 0xf6, + 0x04, 0x6e, 0x2d, 0xa4, 0xa0, 0x55, 0xc8, 0xf7, 0xe9, 0x38, 0x2e, 0x4f, 0x58, 0x2e, 0xd1, 0x1a, + 0x2c, 0x8d, 0x88, 0x3f, 0xa4, 0xba, 0x9a, 0xc5, 0x9b, 0xdd, 0xdc, 0x8e, 0xd1, 0xfc, 0x90, 0x83, + 0xa2, 0x56, 0xe7, 0xba, 0x5b, 0xbe, 0xbe, 0x76, 0xae, 0xb0, 0x3d, 0x84, 0x65, 0xed, 0xd2, 0x38, + 0x23, 0xcd, 0x4b, 0x63, 0xba, 0x12, 0xe3, 0xe3, 0x6c, 0x7c, 0x08, 0xa6, 0x17, 0x92, 0x81, 0x6e, + 0xf7, 0x99, 0x37, 0x77, 0x0f, 0xdb, 0xcf, 0x5f, 0x84, 0x71, 0x61, 0x29, 0x4d, 0x4e, 0x1b, 0xa6, + 0xfc, 0x80, 0x15, 0x2d, 0xb3, 0x31, 0xfe, 0x6d, 0x09, 0x8a, 0x7b, 0xfe, 0x90, 0x0b, 0x1a, 0x5d, + 0xb7, 0x93, 0xf4, 0xb5, 0x73, 0x4e, 0xda, 0x83, 0x62, 0xc4, 0x98, 0xb0, 0x1d, 0x72, 0x91, 0x7f, + 0x30, 0x63, 0x62, 0xaf, 0xdd, 0xa9, 0x4a, 0xa2, 0xac, 0xed, 0xf1, 0x1e, 0x17, 0x24, 0x75, 0x8f, + 0xa0, 0x37, 0xb0, 0x9e, 0x74, 0xc4, 0x23, 0xc6, 0x04, 0x17, 0x11, 0x09, 0xed, 0x3e, 0x1d, 0xcb, + 0x59, 0x29, 0xbf, 0x68, 0x36, 0x3e, 0x08, 0x9c, 0x68, 0xac, 0x9c, 0xf7, 0x8c, 0x8e, 0xf1, 0x9a, + 0x16, 0xd0, 0x49, 0xf8, 0xcf, 0xe8, 0x98, 0xa3, 0x47, 0xb0, 0x41, 0xa7, 0x30, 0x29, 0xd1, 0xf6, + 0xc9, 0x40, 0xf6, 0x7a, 0xdb, 0xf1, 0x99, 0xd3, 0x57, 0xed, 0xc6, 0xc4, 0xb7, 0x68, 0x5a, 0xd4, + 0xaf, 0x63, 0xc4, 0x9e, 0x04, 0x20, 0x0e, 0xd6, 0x91, 0x4f, 0x9c, 0xbe, 0xef, 0x71, 0xf9, 0xef, + 0x4f, 0x6a, 0xdc, 0x95, 0x1d, 0x43, 0xea, 0xb6, 0x73, 0x81, 0xb7, 0x5a, 0x9d, 0x19, 0x37, 0x35, + 0x3c, 0xeb, 0x8c, 0xfa, 0xee, 0x51, 0xf6, 0x29, 0xea, 0x40, 0x65, 0x18, 0xc8, 0xeb, 0x63, 0x1f, + 0x94, 0xaf, 0xea, 0x03, 0x88, 0x59, 0xd2, 0xf2, 0xda, 0x08, 0x36, 0x2e, 0xba, 0x3c, 0x23, 0x37, + 0x1f, 0xa7, 0x73, 0xb3, 0xb2, 0xfd, 0xe3, 0xac, 0xfb, 0xb2, 0x45, 0xa6, 0xf2, 0x38, 0x33, 0x6c, + 0xff, 0x61, 0x40, 0xe1, 0x25, 0x75, 0x22, 0x2a, 0xbe, 0x68, 0xd4, 0xee, 0x9c, 0x89, 0xda, 0x7a, + 0xf6, 0x20, 0x2c, 0x6f, 0x9d, 0x0b, 0xda, 0x1a, 0x94, 0xbc, 0x40, 0xd0, 0x28, 0x20, 0xbe, 0x8a, + 0xda, 0x12, 0x9e, 0xee, 0x33, 0x0d, 0xf8, 0x60, 0x40, 0x21, 0x9e, 0x14, 0xaf, 0xdb, 0x80, 0xf8, + 0xd6, 0xf3, 0x06, 0x64, 0x2a, 0xf9, 0x3f, 0x03, 0x4a, 0x49, 0xc3, 0xfa, 0xa2, 0x6a, 0x9e, 0x9b, + 0xbc, 0xf2, 0x5f, 0x7b, 0xf2, 0x42, 0x60, 0xf6, 0xbd, 0x40, 0xcf, 0x88, 0x58, 0xad, 0x51, 0x0b, + 0x8a, 0x21, 0x19, 0xfb, 0x8c, 0xb8, 0xba, 0x50, 0xae, 0xcd, 0xfd, 0xb0, 0xd0, 0x0e, 0xc6, 0x38, + 0x01, 0xed, 0xae, 0x1d, 0x9f, 0x34, 0x57, 0xa1, 0x9a, 0xb6, 0xfc, 0x9d, 0xd1, 0xfc, 0xb7, 0x01, + 0xe5, 0x83, 0x3f, 0x0a, 0x1a, 0xa8, 0x79, 0xe0, 0x1b, 0x69, 0xfc, 0xe6, 0xfc, 0x8f, 0x0f, 0xe5, + 0x33, 0xbf, 0x2b, 0x64, 0x3d, 0x6a, 0xc7, 0xfa, 0xf8, 0xa9, 0x7e, 0xe3, 0x3f, 0x9f, 0xea, 0x37, + 0xfe, 0x34, 0xa9, 0x1b, 0x1f, 0x27, 0x75, 0xe3, 0x5f, 0x93, 0xba, 0xf1, 0xdf, 0x49, 0xdd, 0x38, + 0x2a, 0x28, 0xff, 0xfc, 0xf4, 0xab, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x48, 0xcb, 0x39, 0xc2, + 0x12, 0x00, 0x00, } diff --git a/components/cli/vendor/github.com/docker/swarmkit/api/objects.proto b/components/cli/vendor/github.com/docker/swarmkit/api/objects.proto index 5f7cf26b7f..311c1f2fb6 100644 --- a/components/cli/vendor/github.com/docker/swarmkit/api/objects.proto +++ b/components/cli/vendor/github.com/docker/swarmkit/api/objects.proto @@ -239,6 +239,8 @@ message Task { // // If not present, the daemon's default will be used. Driver log_driver = 13; + + repeated GenericResource assigned_generic_resources = 15; } // NetworkAttachment specifies the network parameters of attachment to diff --git a/components/cli/vendor/github.com/docker/swarmkit/api/specs.pb.go b/components/cli/vendor/github.com/docker/swarmkit/api/specs.pb.go index c9ea260466..8578cf3849 100644 --- a/components/cli/vendor/github.com/docker/swarmkit/api/specs.pb.go +++ b/components/cli/vendor/github.com/docker/swarmkit/api/specs.pb.go @@ -642,16 +642,94 @@ type NetworkSpec struct { // swarm internally created only and it was identified by the name // "ingress" and the label "com.docker.swarm.internal": "true". Ingress bool `protobuf:"varint,7,opt,name=ingress,proto3" json:"ingress,omitempty"` - // ConfigFrom indicates that the network specific configuration - // for this network will be provided via another network, locally - // on the node where this network is being plumbed. - ConfigFrom string `protobuf:"bytes,8,opt,name=config_from,json=configFrom,proto3" json:"config_from,omitempty"` + // ConfigFrom is the source of the configuration for this network. + // + // Types that are valid to be assigned to ConfigFrom: + // *NetworkSpec_Network + ConfigFrom isNetworkSpec_ConfigFrom `protobuf_oneof:"config_from"` } func (m *NetworkSpec) Reset() { *m = NetworkSpec{} } func (*NetworkSpec) ProtoMessage() {} func (*NetworkSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{9} } +type isNetworkSpec_ConfigFrom interface { + isNetworkSpec_ConfigFrom() + MarshalTo([]byte) (int, error) + Size() int +} + +type NetworkSpec_Network struct { + Network string `protobuf:"bytes,8,opt,name=network,proto3,oneof"` +} + +func (*NetworkSpec_Network) isNetworkSpec_ConfigFrom() {} + +func (m *NetworkSpec) GetConfigFrom() isNetworkSpec_ConfigFrom { + if m != nil { + return m.ConfigFrom + } + return nil +} + +func (m *NetworkSpec) GetNetwork() string { + if x, ok := m.GetConfigFrom().(*NetworkSpec_Network); ok { + return x.Network + } + return "" +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*NetworkSpec) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _NetworkSpec_OneofMarshaler, _NetworkSpec_OneofUnmarshaler, _NetworkSpec_OneofSizer, []interface{}{ + (*NetworkSpec_Network)(nil), + } +} + +func _NetworkSpec_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*NetworkSpec) + // config_from + switch x := m.ConfigFrom.(type) { + case *NetworkSpec_Network: + _ = b.EncodeVarint(8<<3 | proto.WireBytes) + _ = b.EncodeStringBytes(x.Network) + case nil: + default: + return fmt.Errorf("NetworkSpec.ConfigFrom has unexpected type %T", x) + } + return nil +} + +func _NetworkSpec_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*NetworkSpec) + switch tag { + case 8: // config_from.network + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.ConfigFrom = &NetworkSpec_Network{x} + return true, err + default: + return false, nil + } +} + +func _NetworkSpec_OneofSizer(msg proto.Message) (n int) { + m := msg.(*NetworkSpec) + // config_from + switch x := m.ConfigFrom.(type) { + case *NetworkSpec_Network: + n += proto.SizeVarint(8<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Network))) + n += len(x.Network) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + // ClusterSpec specifies global cluster settings. type ClusterSpec struct { Annotations Annotations `protobuf:"bytes,1,opt,name=annotations" json:"annotations"` @@ -682,6 +760,12 @@ type SecretSpec struct { Annotations Annotations `protobuf:"bytes,1,opt,name=annotations" json:"annotations"` // Data is the secret payload - the maximum size is 500KB (that is, 500*1024 bytes) Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Templating *Driver `protobuf:"bytes,3,opt,name=templating" json:"templating,omitempty"` } func (m *SecretSpec) Reset() { *m = SecretSpec{} } @@ -695,6 +779,12 @@ type ConfigSpec struct { // TODO(aaronl): Do we want to revise this to include multiple payloads in a single // ConfigSpec? Define this to be a tar? etc... Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Templating *Driver `protobuf:"bytes,3,opt,name=templating" json:"templating,omitempty"` } func (m *ConfigSpec) Reset() { *m = ConfigSpec{} } @@ -1093,6 +1183,16 @@ func (m *NetworkSpec) CopyFrom(src interface{}) { m.IPAM = &IPAMOptions{} github_com_docker_swarmkit_api_deepcopy.Copy(m.IPAM, o.IPAM) } + if o.ConfigFrom != nil { + switch o.ConfigFrom.(type) { + case *NetworkSpec_Network: + v := NetworkSpec_Network{ + Network: o.GetNetwork(), + } + m.ConfigFrom = &v + } + } + } func (m *ClusterSpec) Copy() *ClusterSpec { @@ -1136,6 +1236,10 @@ func (m *SecretSpec) CopyFrom(src interface{}) { m.Data = make([]byte, len(o.Data)) copy(m.Data, o.Data) } + if o.Templating != nil { + m.Templating = &Driver{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Templating, o.Templating) + } } func (m *ConfigSpec) Copy() *ConfigSpec { @@ -1156,6 +1260,10 @@ func (m *ConfigSpec) CopyFrom(src interface{}) { m.Data = make([]byte, len(o.Data)) copy(m.Data, o.Data) } + if o.Templating != nil { + m.Templating = &Driver{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Templating, o.Templating) + } } func (m *NodeSpec) Marshal() (dAtA []byte, err error) { @@ -2010,15 +2118,24 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) { } i++ } - if len(m.ConfigFrom) > 0 { - dAtA[i] = 0x42 - i++ - i = encodeVarintSpecs(dAtA, i, uint64(len(m.ConfigFrom))) - i += copy(dAtA[i:], m.ConfigFrom) + if m.ConfigFrom != nil { + nn27, err := m.ConfigFrom.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += nn27 } return i, nil } +func (m *NetworkSpec_Network) MarshalTo(dAtA []byte) (int, error) { + i := 0 + dAtA[i] = 0x42 + i++ + i = encodeVarintSpecs(dAtA, i, uint64(len(m.Network))) + i += copy(dAtA[i:], m.Network) + return i, nil +} func (m *ClusterSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2037,67 +2154,67 @@ func (m *ClusterSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size())) - n27, err := m.Annotations.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n27 - dAtA[i] = 0x12 - i++ - i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size())) - n28, err := m.AcceptancePolicy.MarshalTo(dAtA[i:]) + n28, err := m.Annotations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n28 - dAtA[i] = 0x1a + dAtA[i] = 0x12 i++ - i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size())) - n29, err := m.Orchestration.MarshalTo(dAtA[i:]) + i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size())) + n29, err := m.AcceptancePolicy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n29 - dAtA[i] = 0x22 + dAtA[i] = 0x1a i++ - i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size())) - n30, err := m.Raft.MarshalTo(dAtA[i:]) + i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size())) + n30, err := m.Orchestration.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n30 - dAtA[i] = 0x2a + dAtA[i] = 0x22 i++ - i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size())) - n31, err := m.Dispatcher.MarshalTo(dAtA[i:]) + i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size())) + n31, err := m.Raft.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n31 - dAtA[i] = 0x32 + dAtA[i] = 0x2a i++ - i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size())) - n32, err := m.CAConfig.MarshalTo(dAtA[i:]) + i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size())) + n32, err := m.Dispatcher.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n32 - dAtA[i] = 0x3a + dAtA[i] = 0x32 i++ - i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size())) - n33, err := m.TaskDefaults.MarshalTo(dAtA[i:]) + i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size())) + n33, err := m.CAConfig.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n33 - dAtA[i] = 0x42 + dAtA[i] = 0x3a i++ - i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size())) - n34, err := m.EncryptionConfig.MarshalTo(dAtA[i:]) + i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size())) + n34, err := m.TaskDefaults.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n34 + dAtA[i] = 0x42 + i++ + i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size())) + n35, err := m.EncryptionConfig.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n35 return i, nil } @@ -2119,17 +2236,27 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size())) - n35, err := m.Annotations.MarshalTo(dAtA[i:]) + n36, err := m.Annotations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n36 if len(m.Data) > 0 { dAtA[i] = 0x12 i++ i = encodeVarintSpecs(dAtA, i, uint64(len(m.Data))) i += copy(dAtA[i:], m.Data) } + if m.Templating != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size())) + n37, err := m.Templating.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n37 + } return i, nil } @@ -2151,17 +2278,27 @@ func (m *ConfigSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size())) - n36, err := m.Annotations.MarshalTo(dAtA[i:]) + n38, err := m.Annotations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n38 if len(m.Data) > 0 { dAtA[i] = 0x12 i++ i = encodeVarintSpecs(dAtA, i, uint64(len(m.Data))) i += copy(dAtA[i:], m.Data) } + if m.Templating != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size())) + n39, err := m.Templating.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n39 + } return i, nil } @@ -2544,13 +2681,19 @@ func (m *NetworkSpec) Size() (n int) { if m.Ingress { n += 2 } - l = len(m.ConfigFrom) - if l > 0 { - n += 1 + l + sovSpecs(uint64(l)) + if m.ConfigFrom != nil { + n += m.ConfigFrom.Size() } return n } +func (m *NetworkSpec_Network) Size() (n int) { + var l int + _ = l + l = len(m.Network) + n += 1 + l + sovSpecs(uint64(l)) + return n +} func (m *ClusterSpec) Size() (n int) { var l int _ = l @@ -2582,6 +2725,10 @@ func (m *SecretSpec) Size() (n int) { if l > 0 { n += 1 + l + sovSpecs(uint64(l)) } + if m.Templating != nil { + l = m.Templating.Size() + n += 1 + l + sovSpecs(uint64(l)) + } return n } @@ -2594,6 +2741,10 @@ func (m *ConfigSpec) Size() (n int) { if l > 0 { n += 1 + l + sovSpecs(uint64(l)) } + if m.Templating != nil { + l = m.Templating.Size() + n += 1 + l + sovSpecs(uint64(l)) + } return n } @@ -2836,6 +2987,16 @@ func (this *NetworkSpec) String() string { }, "") return s } +func (this *NetworkSpec_Network) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NetworkSpec_Network{`, + `Network:` + fmt.Sprintf("%v", this.Network) + `,`, + `}`, + }, "") + return s +} func (this *ClusterSpec) String() string { if this == nil { return "nil" @@ -2860,6 +3021,7 @@ func (this *SecretSpec) String() string { s := strings.Join([]string{`&SecretSpec{`, `Annotations:` + strings.Replace(strings.Replace(this.Annotations.String(), "Annotations", "Annotations", 1), `&`, ``, 1) + `,`, `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `Templating:` + strings.Replace(fmt.Sprintf("%v", this.Templating), "Driver", "Driver", 1) + `,`, `}`, }, "") return s @@ -2871,6 +3033,7 @@ func (this *ConfigSpec) String() string { s := strings.Join([]string{`&ConfigSpec{`, `Annotations:` + strings.Replace(strings.Replace(this.Annotations.String(), "Annotations", "Annotations", 1), `&`, ``, 1) + `,`, `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `Templating:` + strings.Replace(fmt.Sprintf("%v", this.Templating), "Driver", "Driver", 1) + `,`, `}`, }, "") return s @@ -5259,7 +5422,7 @@ func (m *NetworkSpec) Unmarshal(dAtA []byte) error { m.Ingress = bool(v != 0) case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConfigFrom", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Network", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -5284,7 +5447,7 @@ func (m *NetworkSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ConfigFrom = string(dAtA[iNdEx:postIndex]) + m.ConfigFrom = &NetworkSpec_Network{string(dAtA[iNdEx:postIndex])} iNdEx = postIndex default: iNdEx = preIndex @@ -5687,6 +5850,39 @@ func (m *SecretSpec) Unmarshal(dAtA []byte) error { m.Data = []byte{} } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Templating", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Templating == nil { + m.Templating = &Driver{} + } + if err := m.Templating.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSpecs(dAtA[iNdEx:]) @@ -5798,6 +5994,39 @@ func (m *ConfigSpec) Unmarshal(dAtA []byte) error { m.Data = []byte{} } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Templating", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Templating == nil { + m.Templating = &Driver{} + } + if err := m.Templating.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSpecs(dAtA[iNdEx:]) @@ -5927,121 +6156,122 @@ var ( func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) } var fileDescriptorSpecs = []byte{ - // 1844 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x4f, 0x73, 0x1b, 0x49, - 0x15, 0xb7, 0x6c, 0x59, 0x7f, 0xde, 0xc8, 0x89, 0xdc, 0x24, 0x61, 0xac, 0xb0, 0xb2, 0xa2, 0x0d, - 0xc1, 0xcb, 0x16, 0x72, 0x61, 0xa8, 0x25, 0x4b, 0x58, 0x40, 0xb2, 0xb4, 0x8e, 0x31, 0x76, 0x54, - 0x6d, 0x6f, 0x20, 0x27, 0x55, 0x7b, 0xa6, 0x2d, 0x4d, 0x79, 0xd4, 0x3d, 0xf4, 0xf4, 0x68, 0x4b, - 0x37, 0x8e, 0x5b, 0xb9, 0x72, 0x76, 0x71, 0xe0, 0xcb, 0xe4, 0x48, 0x71, 0xe2, 0xe4, 0x62, 0xf5, - 0x09, 0xa8, 0xe2, 0x03, 0x40, 0x75, 0x4f, 0x8f, 0x34, 0x4a, 0xc6, 0x49, 0xaa, 0xc8, 0xde, 0xba, - 0xdf, 0xfc, 0x7e, 0xaf, 0x5f, 0xbf, 0xfe, 0x75, 0xbf, 0x37, 0x60, 0x85, 0x01, 0x75, 0xc2, 0x56, - 0x20, 0xb8, 0xe4, 0x08, 0xb9, 0xdc, 0xb9, 0xa4, 0xa2, 0x15, 0x7e, 0x4d, 0xc4, 0xf8, 0xd2, 0x93, - 0xad, 0xc9, 0x4f, 0x6b, 0x96, 0x9c, 0x06, 0xd4, 0x00, 0x6a, 0x77, 0x86, 0x7c, 0xc8, 0xf5, 0x70, - 0x57, 0x8d, 0x8c, 0xb5, 0x3e, 0xe4, 0x7c, 0xe8, 0xd3, 0x5d, 0x3d, 0x3b, 0x8f, 0x2e, 0x76, 0xdd, - 0x48, 0x10, 0xe9, 0x71, 0x66, 0xbe, 0x6f, 0xbd, 0xfe, 0x9d, 0xb0, 0x69, 0xfc, 0xa9, 0x79, 0x95, - 0x87, 0xd2, 0x09, 0x77, 0xe9, 0x69, 0x40, 0x1d, 0x74, 0x00, 0x16, 0x61, 0x8c, 0x4b, 0xcd, 0x0d, - 0xed, 0x5c, 0x23, 0xb7, 0x63, 0xed, 0x6d, 0xb7, 0xde, 0x0c, 0xaa, 0xd5, 0x5e, 0xc0, 0x3a, 0xf9, - 0x57, 0xd7, 0xdb, 0x2b, 0x38, 0xcd, 0x44, 0xbf, 0x81, 0x8a, 0x4b, 0x43, 0x4f, 0x50, 0x77, 0x20, - 0xb8, 0x4f, 0xed, 0xd5, 0x46, 0x6e, 0xe7, 0xd6, 0xde, 0x0f, 0xb2, 0x3c, 0xa9, 0xc5, 0x31, 0xf7, - 0x29, 0xb6, 0x0c, 0x43, 0x4d, 0xd0, 0x01, 0xc0, 0x98, 0x8e, 0xcf, 0xa9, 0x08, 0x47, 0x5e, 0x60, - 0xaf, 0x69, 0xfa, 0x8f, 0x6e, 0xa2, 0xab, 0xd8, 0x5b, 0xc7, 0x73, 0x38, 0x4e, 0x51, 0xd1, 0x31, - 0x54, 0xc8, 0x84, 0x78, 0x3e, 0x39, 0xf7, 0x7c, 0x4f, 0x4e, 0xed, 0xbc, 0x76, 0xf5, 0xc9, 0x5b, - 0x5d, 0xb5, 0x53, 0x04, 0xbc, 0x44, 0x6f, 0xba, 0x00, 0x8b, 0x85, 0xd0, 0x23, 0x28, 0xf6, 0x7b, - 0x27, 0xdd, 0xc3, 0x93, 0x83, 0xea, 0x4a, 0x6d, 0xeb, 0xe5, 0x55, 0xe3, 0xae, 0xf2, 0xb1, 0x00, - 0xf4, 0x29, 0x73, 0x3d, 0x36, 0x44, 0x3b, 0x50, 0x6a, 0xef, 0xef, 0xf7, 0xfa, 0x67, 0xbd, 0x6e, - 0x35, 0x57, 0xab, 0xbd, 0xbc, 0x6a, 0xdc, 0x5b, 0x06, 0xb6, 0x1d, 0x87, 0x06, 0x92, 0xba, 0xb5, - 0xfc, 0x37, 0x7f, 0xab, 0xaf, 0x34, 0xbf, 0xc9, 0x41, 0x25, 0x1d, 0x04, 0x7a, 0x04, 0x85, 0xf6, - 0xfe, 0xd9, 0xe1, 0xf3, 0x5e, 0x75, 0x65, 0x41, 0x4f, 0x23, 0xda, 0x8e, 0xf4, 0x26, 0x14, 0x3d, - 0x84, 0xf5, 0x7e, 0xfb, 0xab, 0xd3, 0x5e, 0x35, 0xb7, 0x08, 0x27, 0x0d, 0xeb, 0x93, 0x28, 0xd4, - 0xa8, 0x2e, 0x6e, 0x1f, 0x9e, 0x54, 0x57, 0xb3, 0x51, 0x5d, 0x41, 0x3c, 0x66, 0x42, 0xf9, 0x6b, - 0x1e, 0xac, 0x53, 0x2a, 0x26, 0x9e, 0xf3, 0x81, 0x25, 0xf2, 0x19, 0xe4, 0x25, 0x09, 0x2f, 0xb5, - 0x34, 0xac, 0x6c, 0x69, 0x9c, 0x91, 0xf0, 0x52, 0x2d, 0x6a, 0xe8, 0x1a, 0xaf, 0x94, 0x21, 0x68, - 0xe0, 0x7b, 0x0e, 0x91, 0xd4, 0xd5, 0xca, 0xb0, 0xf6, 0x7e, 0x98, 0xc5, 0xc6, 0x73, 0x94, 0x89, - 0xff, 0xe9, 0x0a, 0x4e, 0x51, 0xd1, 0x13, 0x28, 0x0c, 0x7d, 0x7e, 0x4e, 0x7c, 0xad, 0x09, 0x6b, - 0xef, 0x41, 0x96, 0x93, 0x03, 0x8d, 0x58, 0x38, 0x30, 0x14, 0xf4, 0x18, 0x0a, 0x51, 0xe0, 0x12, - 0x49, 0xed, 0x82, 0x26, 0x37, 0xb2, 0xc8, 0x5f, 0x69, 0xc4, 0x3e, 0x67, 0x17, 0xde, 0x10, 0x1b, - 0x3c, 0x3a, 0x82, 0x12, 0xa3, 0xf2, 0x6b, 0x2e, 0x2e, 0x43, 0xbb, 0xd8, 0x58, 0xdb, 0xb1, 0xf6, - 0x3e, 0xcd, 0x14, 0x63, 0x8c, 0x69, 0x4b, 0x49, 0x9c, 0xd1, 0x98, 0x32, 0x19, 0xbb, 0xe9, 0xac, - 0xda, 0x39, 0x3c, 0x77, 0x80, 0x7e, 0x05, 0x25, 0xca, 0xdc, 0x80, 0x7b, 0x4c, 0xda, 0xa5, 0x9b, - 0x03, 0xe9, 0x19, 0x8c, 0x4a, 0x26, 0x9e, 0x33, 0x14, 0x5b, 0x70, 0xdf, 0x3f, 0x27, 0xce, 0xa5, - 0x5d, 0x7e, 0xcf, 0x6d, 0xcc, 0x19, 0x9d, 0x02, 0xe4, 0xc7, 0xdc, 0xa5, 0xcd, 0x5d, 0xd8, 0x7c, - 0x23, 0xd5, 0xa8, 0x06, 0x25, 0x93, 0xea, 0x58, 0x23, 0x79, 0x3c, 0x9f, 0x37, 0x6f, 0xc3, 0xc6, - 0x52, 0x5a, 0x9b, 0xff, 0xc8, 0x43, 0x29, 0x39, 0x6b, 0xd4, 0x86, 0xb2, 0xc3, 0x99, 0x24, 0x1e, - 0xa3, 0xc2, 0xc8, 0x2b, 0xf3, 0x64, 0xf6, 0x13, 0x90, 0x62, 0x3d, 0x5d, 0xc1, 0x0b, 0x16, 0xfa, - 0x12, 0xca, 0x82, 0x86, 0x3c, 0x12, 0x0e, 0x0d, 0x8d, 0xbe, 0x76, 0xb2, 0x15, 0x12, 0x83, 0x30, - 0xfd, 0x53, 0xe4, 0x09, 0xaa, 0xb2, 0x1c, 0xe2, 0x05, 0x15, 0x3d, 0x81, 0xa2, 0xa0, 0xa1, 0x24, - 0x42, 0xbe, 0x4d, 0x22, 0x38, 0x86, 0xf4, 0xb9, 0xef, 0x39, 0x53, 0x9c, 0x30, 0xd0, 0x13, 0x28, - 0x07, 0x3e, 0x71, 0xb4, 0x57, 0x7b, 0x5d, 0xd3, 0x3f, 0xca, 0xa2, 0xf7, 0x13, 0x10, 0x5e, 0xe0, - 0xd1, 0xe7, 0x00, 0x3e, 0x1f, 0x0e, 0x5c, 0xe1, 0x4d, 0xa8, 0x30, 0x12, 0xab, 0x65, 0xb1, 0xbb, - 0x1a, 0x81, 0xcb, 0x3e, 0x1f, 0xc6, 0x43, 0x74, 0xf0, 0x7f, 0xe9, 0x2b, 0xa5, 0xad, 0x23, 0x00, - 0x32, 0xff, 0x6a, 0xd4, 0xf5, 0xc9, 0x7b, 0xb9, 0x32, 0x27, 0x92, 0xa2, 0xa3, 0x07, 0x50, 0xb9, - 0xe0, 0xc2, 0xa1, 0x03, 0x73, 0x6b, 0xca, 0x5a, 0x13, 0x96, 0xb6, 0xc5, 0xfa, 0x42, 0x1d, 0x28, - 0x0e, 0x29, 0xa3, 0xc2, 0x73, 0x6c, 0xd0, 0x8b, 0x3d, 0xca, 0xbc, 0x90, 0x31, 0x04, 0x47, 0x4c, - 0x7a, 0x63, 0x6a, 0x56, 0x4a, 0x88, 0x9d, 0x32, 0x14, 0x45, 0xfc, 0xa5, 0xf9, 0x47, 0x40, 0x6f, - 0x62, 0x11, 0x82, 0xfc, 0xa5, 0xc7, 0x5c, 0x2d, 0xac, 0x32, 0xd6, 0x63, 0xd4, 0x82, 0x62, 0x40, - 0xa6, 0x3e, 0x27, 0xae, 0x11, 0xcb, 0x9d, 0x56, 0x5c, 0x2f, 0x5b, 0x49, 0xbd, 0x6c, 0xb5, 0xd9, - 0x14, 0x27, 0xa0, 0xe6, 0x11, 0xdc, 0xcd, 0xdc, 0x32, 0xda, 0x83, 0xca, 0x5c, 0x84, 0x03, 0xcf, - 0x2c, 0xd2, 0xb9, 0x3d, 0xbb, 0xde, 0xb6, 0xe6, 0x6a, 0x3d, 0xec, 0x62, 0x6b, 0x0e, 0x3a, 0x74, - 0x9b, 0x7f, 0x29, 0xc3, 0xc6, 0x92, 0x94, 0xd1, 0x1d, 0x58, 0xf7, 0xc6, 0x64, 0x48, 0x4d, 0x8c, - 0xf1, 0x04, 0xf5, 0xa0, 0xe0, 0x93, 0x73, 0xea, 0x2b, 0x41, 0xab, 0x43, 0xfd, 0xc9, 0x3b, 0xef, - 0x44, 0xeb, 0xf7, 0x1a, 0xdf, 0x63, 0x52, 0x4c, 0xb1, 0x21, 0x23, 0x1b, 0x8a, 0x0e, 0x1f, 0x8f, - 0x09, 0x53, 0x4f, 0xe7, 0xda, 0x4e, 0x19, 0x27, 0x53, 0x95, 0x19, 0x22, 0x86, 0xa1, 0x9d, 0xd7, - 0x66, 0x3d, 0x46, 0x55, 0x58, 0xa3, 0x6c, 0x62, 0xaf, 0x6b, 0x93, 0x1a, 0x2a, 0x8b, 0xeb, 0xc5, - 0x8a, 0x2c, 0x63, 0x35, 0x54, 0xbc, 0x28, 0xa4, 0xc2, 0x2e, 0xc6, 0x19, 0x55, 0x63, 0xf4, 0x0b, - 0x28, 0x8c, 0x79, 0xc4, 0x64, 0x68, 0x97, 0x74, 0xb0, 0x5b, 0x59, 0xc1, 0x1e, 0x2b, 0x84, 0x79, - 0xda, 0x0d, 0x1c, 0xf5, 0x60, 0x33, 0x94, 0x3c, 0x18, 0x0c, 0x05, 0x71, 0xe8, 0x20, 0xa0, 0xc2, - 0xe3, 0xae, 0x79, 0x9a, 0xb6, 0xde, 0x38, 0x94, 0xae, 0x69, 0x72, 0xf0, 0x6d, 0xc5, 0x39, 0x50, - 0x94, 0xbe, 0x66, 0xa0, 0x3e, 0x54, 0x82, 0xc8, 0xf7, 0x07, 0x3c, 0x88, 0xab, 0x54, 0xac, 0xa7, - 0xf7, 0x48, 0x59, 0x3f, 0xf2, 0xfd, 0x67, 0x31, 0x09, 0x5b, 0xc1, 0x62, 0x82, 0xee, 0x41, 0x61, - 0x28, 0x78, 0x14, 0x84, 0xb6, 0xa5, 0x93, 0x61, 0x66, 0xe8, 0x0b, 0x28, 0x86, 0xd4, 0x11, 0x54, - 0x86, 0x76, 0x45, 0x6f, 0xf5, 0xe3, 0xac, 0x45, 0x4e, 0x35, 0x04, 0xd3, 0x0b, 0x2a, 0x28, 0x73, - 0x28, 0x4e, 0x38, 0x68, 0x0b, 0xd6, 0xa4, 0x9c, 0xda, 0x1b, 0x8d, 0xdc, 0x4e, 0xa9, 0x53, 0x9c, - 0x5d, 0x6f, 0xaf, 0x9d, 0x9d, 0xbd, 0xc0, 0xca, 0xa6, 0x5e, 0xd0, 0x11, 0x0f, 0x25, 0x23, 0x63, - 0x6a, 0xdf, 0xd2, 0xb9, 0x9d, 0xcf, 0xd1, 0x0b, 0x00, 0x97, 0x85, 0x03, 0x47, 0x5f, 0x59, 0xfb, - 0xb6, 0xde, 0xdd, 0xa7, 0xef, 0xde, 0x5d, 0xf7, 0xe4, 0xd4, 0x54, 0x91, 0x8d, 0xd9, 0xf5, 0x76, - 0x79, 0x3e, 0xc5, 0x65, 0x97, 0x85, 0xf1, 0x10, 0x75, 0xc0, 0x1a, 0x51, 0xe2, 0xcb, 0x91, 0x33, - 0xa2, 0xce, 0xa5, 0x5d, 0xbd, 0xb9, 0x2c, 0x3c, 0xd5, 0x30, 0xe3, 0x21, 0x4d, 0x52, 0x0a, 0x56, - 0xa1, 0x86, 0xf6, 0xa6, 0xce, 0x55, 0x3c, 0x41, 0x1f, 0x01, 0xf0, 0x80, 0xb2, 0x41, 0x28, 0x5d, - 0x8f, 0xd9, 0x48, 0x6d, 0x19, 0x97, 0x95, 0xe5, 0x54, 0x19, 0xd0, 0x7d, 0xf5, 0x68, 0x13, 0x77, - 0xc0, 0x99, 0x3f, 0xb5, 0xbf, 0xa7, 0xbf, 0x96, 0x94, 0xe1, 0x19, 0xf3, 0xa7, 0x68, 0x1b, 0x2c, - 0xad, 0x8b, 0xd0, 0x1b, 0x32, 0xe2, 0xdb, 0x77, 0x74, 0x3e, 0x40, 0x99, 0x4e, 0xb5, 0x45, 0x9d, - 0x43, 0x9c, 0x8d, 0xd0, 0xbe, 0x7b, 0xf3, 0x39, 0x98, 0x60, 0x17, 0xe7, 0x60, 0x38, 0xe8, 0xd7, - 0x00, 0x81, 0xf0, 0x26, 0x9e, 0x4f, 0x87, 0x34, 0xb4, 0xef, 0xe9, 0x4d, 0xd7, 0x33, 0x5f, 0xeb, - 0x39, 0x0a, 0xa7, 0x18, 0xb5, 0xcf, 0xc1, 0x4a, 0xdd, 0x36, 0x75, 0x4b, 0x2e, 0xe9, 0xd4, 0x5c, - 0x60, 0x35, 0x54, 0x29, 0x99, 0x10, 0x3f, 0x8a, 0x3b, 0xe1, 0x32, 0x8e, 0x27, 0xbf, 0x5c, 0x7d, - 0x9c, 0xab, 0xed, 0x81, 0x95, 0x52, 0x1d, 0xfa, 0x18, 0x36, 0x04, 0x1d, 0x7a, 0xa1, 0x14, 0xd3, - 0x01, 0x89, 0xe4, 0xc8, 0xfe, 0xad, 0x26, 0x54, 0x12, 0x63, 0x3b, 0x92, 0xa3, 0xda, 0x00, 0x16, - 0x87, 0x87, 0x1a, 0x60, 0x29, 0x51, 0x84, 0x54, 0x4c, 0xa8, 0x50, 0xd5, 0x56, 0xe5, 0x3c, 0x6d, - 0x52, 0xe2, 0x0d, 0x29, 0x11, 0xce, 0x48, 0xbf, 0x1d, 0x65, 0x6c, 0x66, 0xea, 0x31, 0x48, 0x6e, - 0x88, 0x79, 0x0c, 0xcc, 0xb4, 0xf9, 0x9f, 0x1c, 0x54, 0xd2, 0x4d, 0x03, 0xda, 0x8f, 0x8b, 0xbd, - 0xde, 0xd2, 0xad, 0xbd, 0xdd, 0x77, 0x35, 0x19, 0xba, 0xb4, 0xfa, 0x91, 0x72, 0x76, 0xac, 0xfa, - 0x7b, 0x4d, 0x46, 0x3f, 0x87, 0xf5, 0x80, 0x0b, 0x99, 0x3c, 0x61, 0xd9, 0x09, 0xe6, 0x22, 0x29, - 0x45, 0x31, 0xb8, 0x39, 0x82, 0x5b, 0xcb, 0xde, 0xd0, 0x43, 0x58, 0x7b, 0x7e, 0xd8, 0xaf, 0xae, - 0xd4, 0xee, 0xbf, 0xbc, 0x6a, 0x7c, 0x7f, 0xf9, 0xe3, 0x73, 0x4f, 0xc8, 0x88, 0xf8, 0x87, 0x7d, - 0xf4, 0x63, 0x58, 0xef, 0x9e, 0x9c, 0x62, 0x5c, 0xcd, 0xd5, 0xb6, 0x5f, 0x5e, 0x35, 0xee, 0x2f, - 0xe3, 0xd4, 0x27, 0x1e, 0x31, 0x17, 0xf3, 0xf3, 0x79, 0xaf, 0xfb, 0xef, 0x55, 0xb0, 0xcc, 0xcb, - 0xfe, 0xa1, 0x7f, 0x87, 0x36, 0xe2, 0x52, 0x9e, 0x5c, 0xd9, 0xd5, 0x77, 0x56, 0xf4, 0x4a, 0x4c, - 0x30, 0x67, 0xfc, 0x00, 0x2a, 0x5e, 0x30, 0xf9, 0x6c, 0x40, 0x19, 0x39, 0xf7, 0x4d, 0xdb, 0x5b, - 0xc2, 0x96, 0xb2, 0xf5, 0x62, 0x93, 0x7a, 0x2f, 0x3c, 0x26, 0xa9, 0x60, 0xa6, 0xa1, 0x2d, 0xe1, - 0xf9, 0x1c, 0x7d, 0x01, 0x79, 0x2f, 0x20, 0x63, 0xd3, 0x86, 0x64, 0xee, 0xe0, 0xb0, 0xdf, 0x3e, - 0x36, 0x1a, 0xec, 0x94, 0x66, 0xd7, 0xdb, 0x79, 0x65, 0xc0, 0x9a, 0x86, 0xea, 0x49, 0x27, 0xa0, - 0x56, 0xd2, 0x6f, 0x7f, 0x09, 0xa7, 0x2c, 0x4a, 0x47, 0x1e, 0x1b, 0x0a, 0x1a, 0x86, 0xba, 0x0a, - 0x94, 0x70, 0x32, 0x55, 0xf7, 0x36, 0xde, 0xf1, 0xe0, 0x42, 0xf0, 0xb1, 0x6e, 0x22, 0xca, 0x18, - 0x62, 0xd3, 0x97, 0x82, 0x8f, 0x9b, 0xff, 0xcd, 0x83, 0xb5, 0xef, 0x47, 0xa1, 0x34, 0xc5, 0xef, - 0x83, 0xa5, 0xfc, 0x05, 0x6c, 0x12, 0xfd, 0x53, 0x45, 0x98, 0xaa, 0x24, 0xba, 0x39, 0x33, 0x69, - 0x7f, 0x98, 0xe9, 0x6e, 0x0e, 0x8e, 0x1b, 0xb9, 0x4e, 0x41, 0xf9, 0xb4, 0x73, 0xb8, 0x4a, 0x5e, - 0xfb, 0x82, 0x4e, 0x61, 0x83, 0x0b, 0x67, 0x44, 0x43, 0x19, 0xd7, 0x1f, 0xf3, 0x13, 0x92, 0xf9, - 0x7b, 0xfa, 0x2c, 0x0d, 0x34, 0x8f, 0x6f, 0x1c, 0xed, 0xb2, 0x0f, 0xf4, 0x18, 0xf2, 0x82, 0x5c, - 0x24, 0x8d, 0x66, 0xe6, 0xd5, 0xc0, 0xe4, 0x42, 0x2e, 0xb9, 0xd0, 0x0c, 0xf4, 0x3b, 0x00, 0xd7, - 0x0b, 0x03, 0x22, 0x9d, 0x11, 0x15, 0xe6, 0x88, 0x33, 0xb7, 0xd8, 0x9d, 0xa3, 0x96, 0xbc, 0xa4, - 0xd8, 0xe8, 0x08, 0xca, 0x0e, 0x49, 0x44, 0x5a, 0xb8, 0xf9, 0xcf, 0x6c, 0xbf, 0x6d, 0x5c, 0x54, - 0x95, 0x8b, 0xd9, 0xf5, 0x76, 0x29, 0xb1, 0xe0, 0x92, 0x43, 0x8c, 0x68, 0x8f, 0x60, 0x43, 0xfd, - 0xb1, 0x0d, 0x5c, 0x7a, 0x41, 0x22, 0x5f, 0xc6, 0xe2, 0xb8, 0xa1, 0x98, 0xa8, 0xf6, 0xbf, 0x6b, - 0x70, 0x26, 0xae, 0x8a, 0x4c, 0xd9, 0xd0, 0x1f, 0x60, 0x93, 0x32, 0x47, 0x4c, 0xb5, 0x44, 0x93, - 0x08, 0x4b, 0x37, 0x6f, 0xb6, 0x37, 0x07, 0x2f, 0x6d, 0xb6, 0x4a, 0x5f, 0xb3, 0x37, 0x3d, 0x80, - 0xb8, 0x3c, 0x7f, 0x58, 0xfd, 0x21, 0xc8, 0xbb, 0x44, 0x12, 0x2d, 0xb9, 0x0a, 0xd6, 0x63, 0xb5, - 0x54, 0xbc, 0xe8, 0x77, 0xbe, 0x54, 0xc7, 0x7e, 0xf5, 0x6d, 0x7d, 0xe5, 0x9f, 0xdf, 0xd6, 0x57, - 0xfe, 0x3c, 0xab, 0xe7, 0x5e, 0xcd, 0xea, 0xb9, 0xbf, 0xcf, 0xea, 0xb9, 0x7f, 0xcd, 0xea, 0xb9, - 0xf3, 0x82, 0xee, 0x9f, 0x7e, 0xf6, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0xb7, 0x5c, 0xc9, - 0x78, 0x12, 0x00, 0x00, + // 1867 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x73, 0x1b, 0x49, + 0x15, 0xb6, 0x6c, 0x59, 0x3f, 0xde, 0xc8, 0x89, 0xd2, 0x24, 0x61, 0xa2, 0xb0, 0xb2, 0xa2, 0x0d, + 0xc1, 0xcb, 0x16, 0x72, 0x61, 0xa8, 0x25, 0xbb, 0x61, 0x01, 0xc9, 0x12, 0x8e, 0x31, 0x76, 0x54, + 0x6d, 0x6f, 0x20, 0x27, 0x55, 0x7b, 0xa6, 0x3d, 0x9a, 0xf2, 0xa8, 0x7b, 0xe8, 0xe9, 0xd1, 0x96, + 0x6e, 0x1c, 0xb7, 0x72, 0xe5, 0xec, 0xe2, 0x40, 0xf1, 0xbf, 0xe4, 0x48, 0x71, 0xe2, 0xe4, 0x62, + 0xfd, 0x2f, 0x70, 0xe3, 0x02, 0xd5, 0x3d, 0x3d, 0xd2, 0x28, 0x19, 0x27, 0xa9, 0x22, 0x07, 0x6e, + 0xdd, 0xaf, 0xbf, 0xef, 0xcd, 0xeb, 0xd7, 0x5f, 0xf7, 0x7b, 0x03, 0x56, 0x14, 0x52, 0x27, 0xea, + 0x84, 0x82, 0x4b, 0x8e, 0x90, 0xcb, 0x9d, 0x73, 0x2a, 0x3a, 0xd1, 0xd7, 0x44, 0x4c, 0xce, 0x7d, + 0xd9, 0x99, 0xfe, 0xb8, 0x61, 0xc9, 0x59, 0x48, 0x0d, 0xa0, 0x71, 0xdb, 0xe3, 0x1e, 0xd7, 0xc3, + 0x6d, 0x35, 0x32, 0xd6, 0xa6, 0xc7, 0xb9, 0x17, 0xd0, 0x6d, 0x3d, 0x3b, 0x8d, 0xcf, 0xb6, 0xdd, + 0x58, 0x10, 0xe9, 0x73, 0x66, 0xd6, 0xef, 0xbd, 0xbe, 0x4e, 0xd8, 0x2c, 0x59, 0x6a, 0x5f, 0x14, + 0xa1, 0x72, 0xc4, 0x5d, 0x7a, 0x1c, 0x52, 0x07, 0xed, 0x81, 0x45, 0x18, 0xe3, 0x52, 0x73, 0x23, + 0xbb, 0xd0, 0x2a, 0x6c, 0x59, 0x3b, 0x9b, 0x9d, 0x37, 0x83, 0xea, 0x74, 0x17, 0xb0, 0x5e, 0xf1, + 0xd5, 0xe5, 0xe6, 0x0a, 0xce, 0x32, 0xd1, 0x2f, 0xa1, 0xe6, 0xd2, 0xc8, 0x17, 0xd4, 0x1d, 0x09, + 0x1e, 0x50, 0x7b, 0xb5, 0x55, 0xd8, 0xba, 0xb1, 0xf3, 0xbd, 0x3c, 0x4f, 0xea, 0xe3, 0x98, 0x07, + 0x14, 0x5b, 0x86, 0xa1, 0x26, 0x68, 0x0f, 0x60, 0x42, 0x27, 0xa7, 0x54, 0x44, 0x63, 0x3f, 0xb4, + 0xd7, 0x34, 0xfd, 0x07, 0xd7, 0xd1, 0x55, 0xec, 0x9d, 0xc3, 0x39, 0x1c, 0x67, 0xa8, 0xe8, 0x10, + 0x6a, 0x64, 0x4a, 0xfc, 0x80, 0x9c, 0xfa, 0x81, 0x2f, 0x67, 0x76, 0x51, 0xbb, 0xfa, 0xe4, 0xad, + 0xae, 0xba, 0x19, 0x02, 0x5e, 0xa2, 0xb7, 0x5d, 0x80, 0xc5, 0x87, 0xd0, 0x23, 0x28, 0x0f, 0x07, + 0x47, 0xfd, 0xfd, 0xa3, 0xbd, 0xfa, 0x4a, 0xe3, 0xde, 0xcb, 0x8b, 0xd6, 0x1d, 0xe5, 0x63, 0x01, + 0x18, 0x52, 0xe6, 0xfa, 0xcc, 0x43, 0x5b, 0x50, 0xe9, 0xee, 0xee, 0x0e, 0x86, 0x27, 0x83, 0x7e, + 0xbd, 0xd0, 0x68, 0xbc, 0xbc, 0x68, 0xdd, 0x5d, 0x06, 0x76, 0x1d, 0x87, 0x86, 0x92, 0xba, 0x8d, + 0xe2, 0x37, 0x7f, 0x69, 0xae, 0xb4, 0xbf, 0x29, 0x40, 0x2d, 0x1b, 0x04, 0x7a, 0x04, 0xa5, 0xee, + 0xee, 0xc9, 0xfe, 0xf3, 0x41, 0x7d, 0x65, 0x41, 0xcf, 0x22, 0xba, 0x8e, 0xf4, 0xa7, 0x14, 0x3d, + 0x84, 0xf5, 0x61, 0xf7, 0xab, 0xe3, 0x41, 0xbd, 0xb0, 0x08, 0x27, 0x0b, 0x1b, 0x92, 0x38, 0xd2, + 0xa8, 0x3e, 0xee, 0xee, 0x1f, 0xd5, 0x57, 0xf3, 0x51, 0x7d, 0x41, 0x7c, 0x66, 0x42, 0xf9, 0x73, + 0x11, 0xac, 0x63, 0x2a, 0xa6, 0xbe, 0xf3, 0x81, 0x25, 0xf2, 0x19, 0x14, 0x25, 0x89, 0xce, 0xb5, + 0x34, 0xac, 0x7c, 0x69, 0x9c, 0x90, 0xe8, 0x5c, 0x7d, 0xd4, 0xd0, 0x35, 0x5e, 0x29, 0x43, 0xd0, + 0x30, 0xf0, 0x1d, 0x22, 0xa9, 0xab, 0x95, 0x61, 0xed, 0x7c, 0x3f, 0x8f, 0x8d, 0xe7, 0x28, 0x13, + 0xff, 0xd3, 0x15, 0x9c, 0xa1, 0xa2, 0x27, 0x50, 0xf2, 0x02, 0x7e, 0x4a, 0x02, 0xad, 0x09, 0x6b, + 0xe7, 0x41, 0x9e, 0x93, 0x3d, 0x8d, 0x58, 0x38, 0x30, 0x14, 0xf4, 0x18, 0x4a, 0x71, 0xe8, 0x12, + 0x49, 0xed, 0x92, 0x26, 0xb7, 0xf2, 0xc8, 0x5f, 0x69, 0xc4, 0x2e, 0x67, 0x67, 0xbe, 0x87, 0x0d, + 0x1e, 0x1d, 0x40, 0x85, 0x51, 0xf9, 0x35, 0x17, 0xe7, 0x91, 0x5d, 0x6e, 0xad, 0x6d, 0x59, 0x3b, + 0x9f, 0xe6, 0x8a, 0x31, 0xc1, 0x74, 0xa5, 0x24, 0xce, 0x78, 0x42, 0x99, 0x4c, 0xdc, 0xf4, 0x56, + 0xed, 0x02, 0x9e, 0x3b, 0x40, 0x3f, 0x87, 0x0a, 0x65, 0x6e, 0xc8, 0x7d, 0x26, 0xed, 0xca, 0xf5, + 0x81, 0x0c, 0x0c, 0x46, 0x25, 0x13, 0xcf, 0x19, 0x8a, 0x2d, 0x78, 0x10, 0x9c, 0x12, 0xe7, 0xdc, + 0xae, 0xbe, 0xe7, 0x36, 0xe6, 0x8c, 0x5e, 0x09, 0x8a, 0x13, 0xee, 0xd2, 0xf6, 0x36, 0xdc, 0x7a, + 0x23, 0xd5, 0xa8, 0x01, 0x15, 0x93, 0xea, 0x44, 0x23, 0x45, 0x3c, 0x9f, 0xb7, 0x6f, 0xc2, 0xc6, + 0x52, 0x5a, 0xdb, 0x7f, 0x2f, 0x42, 0x25, 0x3d, 0x6b, 0xd4, 0x85, 0xaa, 0xc3, 0x99, 0x24, 0x3e, + 0xa3, 0xc2, 0xc8, 0x2b, 0xf7, 0x64, 0x76, 0x53, 0x90, 0x62, 0x3d, 0x5d, 0xc1, 0x0b, 0x16, 0xfa, + 0x35, 0x54, 0x05, 0x8d, 0x78, 0x2c, 0x1c, 0x1a, 0x19, 0x7d, 0x6d, 0xe5, 0x2b, 0x24, 0x01, 0x61, + 0xfa, 0x87, 0xd8, 0x17, 0x54, 0x65, 0x39, 0xc2, 0x0b, 0x2a, 0x7a, 0x02, 0x65, 0x41, 0x23, 0x49, + 0x84, 0x7c, 0x9b, 0x44, 0x70, 0x02, 0x19, 0xf2, 0xc0, 0x77, 0x66, 0x38, 0x65, 0xa0, 0x27, 0x50, + 0x0d, 0x03, 0xe2, 0x68, 0xaf, 0xf6, 0xba, 0xa6, 0x7f, 0x94, 0x47, 0x1f, 0xa6, 0x20, 0xbc, 0xc0, + 0xa3, 0xcf, 0x01, 0x02, 0xee, 0x8d, 0x5c, 0xe1, 0x4f, 0xa9, 0x30, 0x12, 0x6b, 0xe4, 0xb1, 0xfb, + 0x1a, 0x81, 0xab, 0x01, 0xf7, 0x92, 0x21, 0xda, 0xfb, 0x9f, 0xf4, 0x95, 0xd1, 0xd6, 0x01, 0x00, + 0x99, 0xaf, 0x1a, 0x75, 0x7d, 0xf2, 0x5e, 0xae, 0xcc, 0x89, 0x64, 0xe8, 0xe8, 0x01, 0xd4, 0xce, + 0xb8, 0x70, 0xe8, 0xc8, 0xdc, 0x9a, 0xaa, 0xd6, 0x84, 0xa5, 0x6d, 0x89, 0xbe, 0x50, 0x0f, 0xca, + 0x1e, 0x65, 0x54, 0xf8, 0x8e, 0x0d, 0xfa, 0x63, 0x8f, 0x72, 0x2f, 0x64, 0x02, 0xc1, 0x31, 0x93, + 0xfe, 0x84, 0x9a, 0x2f, 0xa5, 0xc4, 0x5e, 0x15, 0xca, 0x22, 0x59, 0x69, 0xff, 0x1e, 0xd0, 0x9b, + 0x58, 0x84, 0xa0, 0x78, 0xee, 0x33, 0x57, 0x0b, 0xab, 0x8a, 0xf5, 0x18, 0x75, 0xa0, 0x1c, 0x92, + 0x59, 0xc0, 0x89, 0x6b, 0xc4, 0x72, 0xbb, 0x93, 0xd4, 0xcb, 0x4e, 0x5a, 0x2f, 0x3b, 0x5d, 0x36, + 0xc3, 0x29, 0xa8, 0x7d, 0x00, 0x77, 0x72, 0xb7, 0x8c, 0x76, 0xa0, 0x36, 0x17, 0xe1, 0xc8, 0x37, + 0x1f, 0xe9, 0xdd, 0xbc, 0xba, 0xdc, 0xb4, 0xe6, 0x6a, 0xdd, 0xef, 0x63, 0x6b, 0x0e, 0xda, 0x77, + 0xdb, 0x7f, 0xaa, 0xc2, 0xc6, 0x92, 0x94, 0xd1, 0x6d, 0x58, 0xf7, 0x27, 0xc4, 0xa3, 0x26, 0xc6, + 0x64, 0x82, 0x06, 0x50, 0x0a, 0xc8, 0x29, 0x0d, 0x94, 0xa0, 0xd5, 0xa1, 0xfe, 0xe8, 0x9d, 0x77, + 0xa2, 0xf3, 0x5b, 0x8d, 0x1f, 0x30, 0x29, 0x66, 0xd8, 0x90, 0x91, 0x0d, 0x65, 0x87, 0x4f, 0x26, + 0x84, 0xa9, 0xa7, 0x73, 0x6d, 0xab, 0x8a, 0xd3, 0xa9, 0xca, 0x0c, 0x11, 0x5e, 0x64, 0x17, 0xb5, + 0x59, 0x8f, 0x51, 0x1d, 0xd6, 0x28, 0x9b, 0xda, 0xeb, 0xda, 0xa4, 0x86, 0xca, 0xe2, 0xfa, 0x89, + 0x22, 0xab, 0x58, 0x0d, 0x15, 0x2f, 0x8e, 0xa8, 0xb0, 0xcb, 0x49, 0x46, 0xd5, 0x18, 0xfd, 0x0c, + 0x4a, 0x13, 0x1e, 0x33, 0x19, 0xd9, 0x15, 0x1d, 0xec, 0xbd, 0xbc, 0x60, 0x0f, 0x15, 0xc2, 0x3c, + 0xed, 0x06, 0x8e, 0x06, 0x70, 0x2b, 0x92, 0x3c, 0x1c, 0x79, 0x82, 0x38, 0x74, 0x14, 0x52, 0xe1, + 0x73, 0xd7, 0x3c, 0x4d, 0xf7, 0xde, 0x38, 0x94, 0xbe, 0x69, 0x72, 0xf0, 0x4d, 0xc5, 0xd9, 0x53, + 0x94, 0xa1, 0x66, 0xa0, 0x21, 0xd4, 0xc2, 0x38, 0x08, 0x46, 0x3c, 0x4c, 0xaa, 0x54, 0xa2, 0xa7, + 0xf7, 0x48, 0xd9, 0x30, 0x0e, 0x82, 0x67, 0x09, 0x09, 0x5b, 0xe1, 0x62, 0x82, 0xee, 0x42, 0xc9, + 0x13, 0x3c, 0x0e, 0x23, 0xdb, 0xd2, 0xc9, 0x30, 0x33, 0xf4, 0x25, 0x94, 0x23, 0xea, 0x08, 0x2a, + 0x23, 0xbb, 0xa6, 0xb7, 0xfa, 0x71, 0xde, 0x47, 0x8e, 0x35, 0x04, 0xd3, 0x33, 0x2a, 0x28, 0x73, + 0x28, 0x4e, 0x39, 0xe8, 0x1e, 0xac, 0x49, 0x39, 0xb3, 0x37, 0x5a, 0x85, 0xad, 0x4a, 0xaf, 0x7c, + 0x75, 0xb9, 0xb9, 0x76, 0x72, 0xf2, 0x02, 0x2b, 0x9b, 0x7a, 0x41, 0xc7, 0x3c, 0x92, 0x8c, 0x4c, + 0xa8, 0x7d, 0x43, 0xe7, 0x76, 0x3e, 0x47, 0x2f, 0x00, 0x5c, 0x16, 0x8d, 0x1c, 0x7d, 0x65, 0xed, + 0x9b, 0x7a, 0x77, 0x9f, 0xbe, 0x7b, 0x77, 0xfd, 0xa3, 0x63, 0x53, 0x45, 0x36, 0xae, 0x2e, 0x37, + 0xab, 0xf3, 0x29, 0xae, 0xba, 0x2c, 0x4a, 0x86, 0xa8, 0x07, 0xd6, 0x98, 0x92, 0x40, 0x8e, 0x9d, + 0x31, 0x75, 0xce, 0xed, 0xfa, 0xf5, 0x65, 0xe1, 0xa9, 0x86, 0x19, 0x0f, 0x59, 0x92, 0x52, 0xb0, + 0x0a, 0x35, 0xb2, 0x6f, 0xe9, 0x5c, 0x25, 0x13, 0xf4, 0x11, 0x00, 0x0f, 0x29, 0x1b, 0x45, 0xd2, + 0xf5, 0x99, 0x8d, 0xd4, 0x96, 0x71, 0x55, 0x59, 0x8e, 0x95, 0x01, 0xdd, 0x57, 0x8f, 0x36, 0x71, + 0x47, 0x9c, 0x05, 0x33, 0xfb, 0x3b, 0x7a, 0xb5, 0xa2, 0x0c, 0xcf, 0x58, 0x30, 0x43, 0x9b, 0x60, + 0x69, 0x5d, 0x44, 0xbe, 0xc7, 0x48, 0x60, 0xdf, 0xd6, 0xf9, 0x00, 0x65, 0x3a, 0xd6, 0x16, 0x75, + 0x0e, 0x49, 0x36, 0x22, 0xfb, 0xce, 0xf5, 0xe7, 0x60, 0x82, 0x5d, 0x9c, 0x83, 0xe1, 0xa0, 0x5f, + 0x00, 0x84, 0xc2, 0x9f, 0xfa, 0x01, 0xf5, 0x68, 0x64, 0xdf, 0xd5, 0x9b, 0x6e, 0xe6, 0xbe, 0xd6, + 0x73, 0x14, 0xce, 0x30, 0x1a, 0x9f, 0x83, 0x95, 0xb9, 0x6d, 0xea, 0x96, 0x9c, 0xd3, 0x99, 0xb9, + 0xc0, 0x6a, 0xa8, 0x52, 0x32, 0x25, 0x41, 0x9c, 0x74, 0xc2, 0x55, 0x9c, 0x4c, 0xbe, 0x58, 0x7d, + 0x5c, 0x68, 0xec, 0x80, 0x95, 0x51, 0x1d, 0xfa, 0x18, 0x36, 0x04, 0xf5, 0xfc, 0x48, 0x8a, 0xd9, + 0x88, 0xc4, 0x72, 0x6c, 0xff, 0x4a, 0x13, 0x6a, 0xa9, 0xb1, 0x1b, 0xcb, 0x71, 0x63, 0x04, 0x8b, + 0xc3, 0x43, 0x2d, 0xb0, 0x94, 0x28, 0x22, 0x2a, 0xa6, 0x54, 0xa8, 0x6a, 0xab, 0x72, 0x9e, 0x35, + 0x29, 0xf1, 0x46, 0x94, 0x08, 0x67, 0xac, 0xdf, 0x8e, 0x2a, 0x36, 0x33, 0xf5, 0x18, 0xa4, 0x37, + 0xc4, 0x3c, 0x06, 0x66, 0xda, 0xfe, 0x57, 0x01, 0x6a, 0xd9, 0xa6, 0x01, 0xed, 0x26, 0xc5, 0x5e, + 0x6f, 0xe9, 0xc6, 0xce, 0xf6, 0xbb, 0x9a, 0x0c, 0x5d, 0x5a, 0x83, 0x58, 0x39, 0x3b, 0x54, 0xfd, + 0xbd, 0x26, 0xa3, 0x9f, 0xc2, 0x7a, 0xc8, 0x85, 0x4c, 0x9f, 0xb0, 0xfc, 0x04, 0x73, 0x91, 0x96, + 0xa2, 0x04, 0xdc, 0x1e, 0xc3, 0x8d, 0x65, 0x6f, 0xe8, 0x21, 0xac, 0x3d, 0xdf, 0x1f, 0xd6, 0x57, + 0x1a, 0xf7, 0x5f, 0x5e, 0xb4, 0xbe, 0xbb, 0xbc, 0xf8, 0xdc, 0x17, 0x32, 0x26, 0xc1, 0xfe, 0x10, + 0xfd, 0x10, 0xd6, 0xfb, 0x47, 0xc7, 0x18, 0xd7, 0x0b, 0x8d, 0xcd, 0x97, 0x17, 0xad, 0xfb, 0xcb, + 0x38, 0xb5, 0xc4, 0x63, 0xe6, 0x62, 0x7e, 0x3a, 0xef, 0x75, 0xff, 0xbd, 0x0a, 0x96, 0x79, 0xd9, + 0x3f, 0xf4, 0xef, 0xd0, 0x46, 0x52, 0xca, 0xd3, 0x2b, 0xbb, 0xfa, 0xce, 0x8a, 0x5e, 0x4b, 0x08, + 0xe6, 0x8c, 0x1f, 0x40, 0xcd, 0x0f, 0xa7, 0x9f, 0x8d, 0x28, 0x23, 0xa7, 0x81, 0x69, 0x7b, 0x2b, + 0xd8, 0x52, 0xb6, 0x41, 0x62, 0x52, 0xef, 0x85, 0xcf, 0x24, 0x15, 0xcc, 0x34, 0xb4, 0x15, 0x3c, + 0x9f, 0xa3, 0x2f, 0xa1, 0xe8, 0x87, 0x64, 0x62, 0xda, 0x90, 0xdc, 0x1d, 0xec, 0x0f, 0xbb, 0x87, + 0x46, 0x83, 0xbd, 0xca, 0xd5, 0xe5, 0x66, 0x51, 0x19, 0xb0, 0xa6, 0xa1, 0x66, 0xda, 0x09, 0xa8, + 0x2f, 0xe9, 0xb7, 0xbf, 0x82, 0x33, 0x16, 0xa5, 0x23, 0x9f, 0x79, 0x82, 0x46, 0x91, 0xae, 0x02, + 0x15, 0x9c, 0x4e, 0x51, 0x03, 0xca, 0xa6, 0x9f, 0xd0, 0x0d, 0x44, 0x55, 0xd5, 0x6a, 0x63, 0xe8, + 0x6d, 0x80, 0x95, 0x64, 0x63, 0x74, 0x26, 0xf8, 0xa4, 0xfd, 0x9f, 0x22, 0x58, 0xbb, 0x41, 0x1c, + 0x49, 0x53, 0x06, 0x3f, 0x58, 0xf2, 0x5f, 0xc0, 0x2d, 0xa2, 0x7f, 0xaf, 0x08, 0x53, 0x35, 0x45, + 0xb7, 0x69, 0xe6, 0x00, 0x1e, 0xe6, 0xba, 0x9b, 0x83, 0x93, 0x96, 0xae, 0x57, 0x52, 0x3e, 0xed, + 0x02, 0xae, 0x93, 0xd7, 0x56, 0xd0, 0x31, 0x6c, 0x70, 0xe1, 0x8c, 0x69, 0x24, 0x93, 0x4a, 0x64, + 0x7e, 0x47, 0x72, 0x7f, 0x54, 0x9f, 0x65, 0x81, 0xe6, 0x19, 0x4e, 0xa2, 0x5d, 0xf6, 0x81, 0x1e, + 0x43, 0x51, 0x90, 0xb3, 0xb4, 0xe5, 0xcc, 0xbd, 0x24, 0x98, 0x9c, 0xc9, 0x25, 0x17, 0x9a, 0x81, + 0x7e, 0x03, 0xe0, 0xfa, 0x51, 0x48, 0xa4, 0x33, 0xa6, 0xc2, 0x1c, 0x76, 0xee, 0x16, 0xfb, 0x73, + 0xd4, 0x92, 0x97, 0x0c, 0x1b, 0x1d, 0x40, 0xd5, 0x21, 0xa9, 0x5c, 0x4b, 0xd7, 0xff, 0xa3, 0xed, + 0x76, 0x8d, 0x8b, 0xba, 0x72, 0x71, 0x75, 0xb9, 0x59, 0x49, 0x2d, 0xb8, 0xe2, 0x10, 0x23, 0xdf, + 0x03, 0xd8, 0x50, 0xff, 0x6e, 0x23, 0x97, 0x9e, 0x91, 0x38, 0x90, 0x89, 0x4c, 0xae, 0x29, 0x2b, + 0xea, 0x47, 0xa0, 0x6f, 0x70, 0x26, 0xae, 0x9a, 0xcc, 0xd8, 0xd0, 0xef, 0xe0, 0x16, 0x65, 0x8e, + 0x98, 0x69, 0xb1, 0xa6, 0x11, 0x56, 0xae, 0xdf, 0xec, 0x60, 0x0e, 0x5e, 0xda, 0x6c, 0x9d, 0xbe, + 0x66, 0x6f, 0xff, 0xb5, 0x00, 0x90, 0x54, 0xea, 0x0f, 0x2b, 0x40, 0x04, 0x45, 0x97, 0x48, 0xa2, + 0x35, 0x57, 0xc3, 0x7a, 0x8c, 0xbe, 0x00, 0x90, 0x74, 0x12, 0x06, 0x44, 0xfa, 0xcc, 0x33, 0xb2, + 0x79, 0xdb, 0x73, 0x90, 0x41, 0xeb, 0x38, 0x93, 0x90, 0xff, 0xaf, 0xe3, 0xec, 0xd9, 0xaf, 0xbe, + 0x6d, 0xae, 0xfc, 0xe3, 0xdb, 0xe6, 0xca, 0x1f, 0xaf, 0x9a, 0x85, 0x57, 0x57, 0xcd, 0xc2, 0xdf, + 0xae, 0x9a, 0x85, 0x7f, 0x5e, 0x35, 0x0b, 0xa7, 0x25, 0xdd, 0xc3, 0xfd, 0xe4, 0xbf, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x06, 0x93, 0x6e, 0xba, 0xfc, 0x12, 0x00, 0x00, } diff --git a/components/cli/vendor/github.com/docker/swarmkit/api/specs.proto b/components/cli/vendor/github.com/docker/swarmkit/api/specs.proto index ba842660f2..13b52d4105 100644 --- a/components/cli/vendor/github.com/docker/swarmkit/api/specs.proto +++ b/components/cli/vendor/github.com/docker/swarmkit/api/specs.proto @@ -342,10 +342,14 @@ message NetworkSpec { // "ingress" and the label "com.docker.swarm.internal": "true". bool ingress = 7; - // ConfigFrom indicates that the network specific configuration - // for this network will be provided via another network, locally - // on the node where this network is being plumbed. - string config_from = 8; + // ConfigFrom is the source of the configuration for this network. + oneof config_from { + // Network is the name of a network that provides the network + // specific configuration for this network, locally on the node + // where this network is being plumbed. + string network = 8; + } + } // ClusterSpec specifies global cluster settings. @@ -382,6 +386,13 @@ message SecretSpec { // Data is the secret payload - the maximum size is 500KB (that is, 500*1024 bytes) bytes data = 2; + + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Driver templating = 3; } // ConfigSpec specifies user-provided configuration files. @@ -392,4 +403,11 @@ message ConfigSpec { // TODO(aaronl): Do we want to revise this to include multiple payloads in a single // ConfigSpec? Define this to be a tar? etc... bytes data = 2; + + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Driver templating = 3; } diff --git a/components/cli/vendor/github.com/docker/swarmkit/api/types.pb.go b/components/cli/vendor/github.com/docker/swarmkit/api/types.pb.go index 7ff65e47ca..2befc03577 100644 --- a/components/cli/vendor/github.com/docker/swarmkit/api/types.pb.go +++ b/components/cli/vendor/github.com/docker/swarmkit/api/types.pb.go @@ -23,6 +23,9 @@ Version IndexEntry Annotations + GenericString + GenericDiscrete + GenericResource Resources ResourceRequirements Platform @@ -354,7 +357,7 @@ func (x RaftMemberStatus_Reachability) String() string { return proto.EnumName(RaftMemberStatus_Reachability_name, int32(x)) } func (RaftMemberStatus_Reachability) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{10, 0} + return fileDescriptorTypes, []int{13, 0} } // TODO(aluzzardi) These should be using `gogoproto.enumvalue_customname`. @@ -387,7 +390,7 @@ var NodeStatus_State_value = map[string]int32{ func (x NodeStatus_State) String() string { return proto.EnumName(NodeStatus_State_name, int32(x)) } -func (NodeStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11, 0} } +func (NodeStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14, 0} } type Mount_MountType int32 @@ -411,7 +414,7 @@ var Mount_MountType_value = map[string]int32{ func (x Mount_MountType) String() string { return proto.EnumName(Mount_MountType_name, int32(x)) } -func (Mount_MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 0} } +func (Mount_MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 0} } type Mount_BindOptions_MountPropagation int32 @@ -445,7 +448,7 @@ func (x Mount_BindOptions_MountPropagation) String() string { return proto.EnumName(Mount_BindOptions_MountPropagation_name, int32(x)) } func (Mount_BindOptions_MountPropagation) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{13, 0, 0} + return fileDescriptorTypes, []int{16, 0, 0} } type RestartPolicy_RestartCondition int32 @@ -471,7 +474,7 @@ func (x RestartPolicy_RestartCondition) String() string { return proto.EnumName(RestartPolicy_RestartCondition_name, int32(x)) } func (RestartPolicy_RestartCondition) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{14, 0} + return fileDescriptorTypes, []int{17, 0} } type UpdateConfig_FailureAction int32 @@ -497,7 +500,7 @@ func (x UpdateConfig_FailureAction) String() string { return proto.EnumName(UpdateConfig_FailureAction_name, int32(x)) } func (UpdateConfig_FailureAction) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{15, 0} + return fileDescriptorTypes, []int{18, 0} } // UpdateOrder controls the order of operations when rolling out an @@ -524,7 +527,7 @@ func (x UpdateConfig_UpdateOrder) String() string { return proto.EnumName(UpdateConfig_UpdateOrder_name, int32(x)) } func (UpdateConfig_UpdateOrder) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{15, 1} + return fileDescriptorTypes, []int{18, 1} } type UpdateStatus_UpdateState int32 @@ -562,7 +565,7 @@ func (x UpdateStatus_UpdateState) String() string { return proto.EnumName(UpdateStatus_UpdateState_name, int32(x)) } func (UpdateStatus_UpdateState) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{16, 0} + return fileDescriptorTypes, []int{19, 0} } // AddressFamily specifies the network address family that @@ -590,7 +593,7 @@ func (x IPAMConfig_AddressFamily) String() string { return proto.EnumName(IPAMConfig_AddressFamily_name, int32(x)) } func (IPAMConfig_AddressFamily) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{21, 0} + return fileDescriptorTypes, []int{24, 0} } type PortConfig_Protocol int32 @@ -612,7 +615,7 @@ var PortConfig_Protocol_value = map[string]int32{ func (x PortConfig_Protocol) String() string { return proto.EnumName(PortConfig_Protocol_name, int32(x)) } -func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22, 0} } +func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25, 0} } // PublishMode controls how ports are published on the swarm. type PortConfig_PublishMode int32 @@ -640,7 +643,7 @@ func (x PortConfig_PublishMode) String() string { return proto.EnumName(PortConfig_PublishMode_name, int32(x)) } func (PortConfig_PublishMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{22, 1} + return fileDescriptorTypes, []int{25, 1} } type IssuanceStatus_State int32 @@ -680,7 +683,7 @@ var IssuanceStatus_State_value = map[string]int32{ func (x IssuanceStatus_State) String() string { return proto.EnumName(IssuanceStatus_State_name, int32(x)) } -func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27, 0} } +func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30, 0} } type ExternalCA_CAProtocol int32 @@ -699,7 +702,7 @@ func (x ExternalCA_CAProtocol) String() string { return proto.EnumName(ExternalCA_CAProtocol_name, int32(x)) } func (ExternalCA_CAProtocol) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{29, 0} + return fileDescriptorTypes, []int{32, 0} } // Encryption algorithm that can implemented using this key @@ -720,7 +723,7 @@ func (x EncryptionKey_Algorithm) String() string { return proto.EnumName(EncryptionKey_Algorithm_name, int32(x)) } func (EncryptionKey_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{42, 0} + return fileDescriptorTypes, []int{45, 0} } type MaybeEncryptedRecord_Algorithm int32 @@ -743,7 +746,7 @@ func (x MaybeEncryptedRecord_Algorithm) String() string { return proto.EnumName(MaybeEncryptedRecord_Algorithm_name, int32(x)) } func (MaybeEncryptedRecord_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{49, 0} + return fileDescriptorTypes, []int{52, 0} } // Version tracks the last time an object in the store was updated. @@ -778,16 +781,158 @@ func (m *Annotations) Reset() { *m = Annotations{} } func (*Annotations) ProtoMessage() {} func (*Annotations) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{2} } +type GenericString struct { + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *GenericString) Reset() { *m = GenericString{} } +func (*GenericString) ProtoMessage() {} +func (*GenericString) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{3} } + +type GenericDiscrete struct { + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *GenericDiscrete) Reset() { *m = GenericDiscrete{} } +func (*GenericDiscrete) ProtoMessage() {} +func (*GenericDiscrete) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{4} } + +type GenericResource struct { + // Types that are valid to be assigned to Resource: + // *GenericResource_Str + // *GenericResource_Discrete + Resource isGenericResource_Resource `protobuf_oneof:"resource"` +} + +func (m *GenericResource) Reset() { *m = GenericResource{} } +func (*GenericResource) ProtoMessage() {} +func (*GenericResource) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{5} } + +type isGenericResource_Resource interface { + isGenericResource_Resource() + MarshalTo([]byte) (int, error) + Size() int +} + +type GenericResource_Str struct { + Str *GenericString `protobuf:"bytes,1,opt,name=str,oneof"` +} +type GenericResource_Discrete struct { + Discrete *GenericDiscrete `protobuf:"bytes,2,opt,name=discrete,oneof"` +} + +func (*GenericResource_Str) isGenericResource_Resource() {} +func (*GenericResource_Discrete) isGenericResource_Resource() {} + +func (m *GenericResource) GetResource() isGenericResource_Resource { + if m != nil { + return m.Resource + } + return nil +} + +func (m *GenericResource) GetStr() *GenericString { + if x, ok := m.GetResource().(*GenericResource_Str); ok { + return x.Str + } + return nil +} + +func (m *GenericResource) GetDiscrete() *GenericDiscrete { + if x, ok := m.GetResource().(*GenericResource_Discrete); ok { + return x.Discrete + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*GenericResource) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _GenericResource_OneofMarshaler, _GenericResource_OneofUnmarshaler, _GenericResource_OneofSizer, []interface{}{ + (*GenericResource_Str)(nil), + (*GenericResource_Discrete)(nil), + } +} + +func _GenericResource_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*GenericResource) + // resource + switch x := m.Resource.(type) { + case *GenericResource_Str: + _ = b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Str); err != nil { + return err + } + case *GenericResource_Discrete: + _ = b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Discrete); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("GenericResource.Resource has unexpected type %T", x) + } + return nil +} + +func _GenericResource_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*GenericResource) + switch tag { + case 1: // resource.str + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(GenericString) + err := b.DecodeMessage(msg) + m.Resource = &GenericResource_Str{msg} + return true, err + case 2: // resource.discrete + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(GenericDiscrete) + err := b.DecodeMessage(msg) + m.Resource = &GenericResource_Discrete{msg} + return true, err + default: + return false, nil + } +} + +func _GenericResource_OneofSizer(msg proto.Message) (n int) { + m := msg.(*GenericResource) + // resource + switch x := m.Resource.(type) { + case *GenericResource_Str: + s := proto.Size(x.Str) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *GenericResource_Discrete: + s := proto.Size(x.Discrete) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + type Resources struct { // Amount of CPUs (e.g. 2000000000 = 2 CPU cores) NanoCPUs int64 `protobuf:"varint,1,opt,name=nano_cpus,json=nanoCpus,proto3" json:"nano_cpus,omitempty"` // Amount of memory in bytes. MemoryBytes int64 `protobuf:"varint,2,opt,name=memory_bytes,json=memoryBytes,proto3" json:"memory_bytes,omitempty"` + // User specified resource (e.g: bananas=2;apple={red,yellow,green}) + Generic []*GenericResource `protobuf:"bytes,3,rep,name=generic" json:"generic,omitempty"` } func (m *Resources) Reset() { *m = Resources{} } func (*Resources) ProtoMessage() {} -func (*Resources) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{3} } +func (*Resources) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{6} } type ResourceRequirements struct { Limits *Resources `protobuf:"bytes,1,opt,name=limits" json:"limits,omitempty"` @@ -796,7 +941,7 @@ type ResourceRequirements struct { func (m *ResourceRequirements) Reset() { *m = ResourceRequirements{} } func (*ResourceRequirements) ProtoMessage() {} -func (*ResourceRequirements) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{4} } +func (*ResourceRequirements) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{7} } type Platform struct { // Architecture (e.g. x86_64) @@ -807,7 +952,7 @@ type Platform struct { func (m *Platform) Reset() { *m = Platform{} } func (*Platform) ProtoMessage() {} -func (*Platform) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{5} } +func (*Platform) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{8} } // PluginDescription describes an engine plugin. type PluginDescription struct { @@ -821,7 +966,7 @@ type PluginDescription struct { func (m *PluginDescription) Reset() { *m = PluginDescription{} } func (*PluginDescription) ProtoMessage() {} -func (*PluginDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{6} } +func (*PluginDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{9} } type EngineDescription struct { // Docker daemon version running on the node. @@ -834,7 +979,7 @@ type EngineDescription struct { func (m *EngineDescription) Reset() { *m = EngineDescription{} } func (*EngineDescription) ProtoMessage() {} -func (*EngineDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{7} } +func (*EngineDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10} } type NodeDescription struct { // Hostname of the node as reported by the agent. @@ -852,7 +997,7 @@ type NodeDescription struct { func (m *NodeDescription) Reset() { *m = NodeDescription{} } func (*NodeDescription) ProtoMessage() {} -func (*NodeDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{8} } +func (*NodeDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11} } type NodeTLSInfo struct { // Information about which root certs the node trusts @@ -864,7 +1009,7 @@ type NodeTLSInfo struct { func (m *NodeTLSInfo) Reset() { *m = NodeTLSInfo{} } func (*NodeTLSInfo) ProtoMessage() {} -func (*NodeTLSInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{9} } +func (*NodeTLSInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12} } type RaftMemberStatus struct { Leader bool `protobuf:"varint,1,opt,name=leader,proto3" json:"leader,omitempty"` @@ -874,7 +1019,7 @@ type RaftMemberStatus struct { func (m *RaftMemberStatus) Reset() { *m = RaftMemberStatus{} } func (*RaftMemberStatus) ProtoMessage() {} -func (*RaftMemberStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10} } +func (*RaftMemberStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13} } type NodeStatus struct { State NodeStatus_State `protobuf:"varint,1,opt,name=state,proto3,enum=docker.swarmkit.v1.NodeStatus_State" json:"state,omitempty"` @@ -885,7 +1030,7 @@ type NodeStatus struct { func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (*NodeStatus) ProtoMessage() {} -func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11} } +func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14} } type Image struct { // reference is a docker image reference. This can include a rpository, tag @@ -896,7 +1041,7 @@ type Image struct { func (m *Image) Reset() { *m = Image{} } func (*Image) ProtoMessage() {} -func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12} } +func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{15} } // Mount describes volume mounts for a container. // @@ -931,7 +1076,7 @@ type Mount struct { func (m *Mount) Reset() { *m = Mount{} } func (*Mount) ProtoMessage() {} -func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13} } +func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16} } // BindOptions specifies options that are specific to a bind mount. type Mount_BindOptions struct { @@ -941,7 +1086,7 @@ type Mount_BindOptions struct { func (m *Mount_BindOptions) Reset() { *m = Mount_BindOptions{} } func (*Mount_BindOptions) ProtoMessage() {} -func (*Mount_BindOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 0} } +func (*Mount_BindOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 0} } // VolumeOptions contains parameters for mounting the volume. type Mount_VolumeOptions struct { @@ -958,7 +1103,7 @@ type Mount_VolumeOptions struct { func (m *Mount_VolumeOptions) Reset() { *m = Mount_VolumeOptions{} } func (*Mount_VolumeOptions) ProtoMessage() {} -func (*Mount_VolumeOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 1} } +func (*Mount_VolumeOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 1} } type Mount_TmpfsOptions struct { // Size sets the size of the tmpfs, in bytes. @@ -976,7 +1121,7 @@ type Mount_TmpfsOptions struct { func (m *Mount_TmpfsOptions) Reset() { *m = Mount_TmpfsOptions{} } func (*Mount_TmpfsOptions) ProtoMessage() {} -func (*Mount_TmpfsOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 2} } +func (*Mount_TmpfsOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 2} } type RestartPolicy struct { Condition RestartPolicy_RestartCondition `protobuf:"varint,1,opt,name=condition,proto3,enum=docker.swarmkit.v1.RestartPolicy_RestartCondition" json:"condition,omitempty"` @@ -994,7 +1139,7 @@ type RestartPolicy struct { func (m *RestartPolicy) Reset() { *m = RestartPolicy{} } func (*RestartPolicy) ProtoMessage() {} -func (*RestartPolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14} } +func (*RestartPolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} } // UpdateConfig specifies the rate and policy of updates. // TODO(aluzzardi): Consider making this a oneof with RollingStrategy and LockstepStrategy. @@ -1034,7 +1179,7 @@ type UpdateConfig struct { func (m *UpdateConfig) Reset() { *m = UpdateConfig{} } func (*UpdateConfig) ProtoMessage() {} -func (*UpdateConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{15} } +func (*UpdateConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} } // UpdateStatus is the status of an update in progress. type UpdateStatus struct { @@ -1058,7 +1203,7 @@ type UpdateStatus struct { func (m *UpdateStatus) Reset() { *m = UpdateStatus{} } func (*UpdateStatus) ProtoMessage() {} -func (*UpdateStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16} } +func (*UpdateStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} } // Container specific status. type ContainerStatus struct { @@ -1069,7 +1214,7 @@ type ContainerStatus struct { func (m *ContainerStatus) Reset() { *m = ContainerStatus{} } func (*ContainerStatus) ProtoMessage() {} -func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} } +func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} } // PortStatus specifies the actual allocated runtime state of a list // of port configs. @@ -1079,7 +1224,7 @@ type PortStatus struct { func (m *PortStatus) Reset() { *m = PortStatus{} } func (*PortStatus) ProtoMessage() {} -func (*PortStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} } +func (*PortStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} } type TaskStatus struct { // Note: can't use stdtime because this field is nullable. @@ -1116,7 +1261,7 @@ type TaskStatus struct { func (m *TaskStatus) Reset() { *m = TaskStatus{} } func (*TaskStatus) ProtoMessage() {} -func (*TaskStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} } +func (*TaskStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} } type isTaskStatus_RuntimeStatus interface { isTaskStatus_RuntimeStatus() @@ -1220,7 +1365,7 @@ type NetworkAttachmentConfig struct { func (m *NetworkAttachmentConfig) Reset() { *m = NetworkAttachmentConfig{} } func (*NetworkAttachmentConfig) ProtoMessage() {} -func (*NetworkAttachmentConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} } +func (*NetworkAttachmentConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } // IPAMConfig specifies parameters for IP Address Management. type IPAMConfig struct { @@ -1241,7 +1386,7 @@ type IPAMConfig struct { func (m *IPAMConfig) Reset() { *m = IPAMConfig{} } func (*IPAMConfig) ProtoMessage() {} -func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} } +func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} } // PortConfig specifies an exposed port which can be // addressed using the given name. This can be later queried @@ -1267,7 +1412,7 @@ type PortConfig struct { func (m *PortConfig) Reset() { *m = PortConfig{} } func (*PortConfig) ProtoMessage() {} -func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} } +func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} } // Driver is a generic driver type to be used throughout the API. For now, a // driver is simply a name and set of options. The field contents depend on the @@ -1280,7 +1425,7 @@ type Driver struct { func (m *Driver) Reset() { *m = Driver{} } func (*Driver) ProtoMessage() {} -func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } +func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} } type IPAMOptions struct { Driver *Driver `protobuf:"bytes,1,opt,name=driver" json:"driver,omitempty"` @@ -1289,7 +1434,7 @@ type IPAMOptions struct { func (m *IPAMOptions) Reset() { *m = IPAMOptions{} } func (*IPAMOptions) ProtoMessage() {} -func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} } +func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} } // Peer should be used anywhere where we are describing a remote peer. type Peer struct { @@ -1299,7 +1444,7 @@ type Peer struct { func (m *Peer) Reset() { *m = Peer{} } func (*Peer) ProtoMessage() {} -func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} } +func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} } // WeightedPeer should be used anywhere where we are describing a remote peer // with a weight. @@ -1310,7 +1455,7 @@ type WeightedPeer struct { func (m *WeightedPeer) Reset() { *m = WeightedPeer{} } func (*WeightedPeer) ProtoMessage() {} -func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} } +func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } type IssuanceStatus struct { State IssuanceStatus_State `protobuf:"varint,1,opt,name=state,proto3,enum=docker.swarmkit.v1.IssuanceStatus_State" json:"state,omitempty"` @@ -1322,7 +1467,7 @@ type IssuanceStatus struct { func (m *IssuanceStatus) Reset() { *m = IssuanceStatus{} } func (*IssuanceStatus) ProtoMessage() {} -func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} } +func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} } type AcceptancePolicy struct { Policies []*AcceptancePolicy_RoleAdmissionPolicy `protobuf:"bytes,1,rep,name=policies" json:"policies,omitempty"` @@ -1330,7 +1475,7 @@ type AcceptancePolicy struct { func (m *AcceptancePolicy) Reset() { *m = AcceptancePolicy{} } func (*AcceptancePolicy) ProtoMessage() {} -func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} } +func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} } type AcceptancePolicy_RoleAdmissionPolicy struct { Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"` @@ -1345,7 +1490,7 @@ type AcceptancePolicy_RoleAdmissionPolicy struct { func (m *AcceptancePolicy_RoleAdmissionPolicy) Reset() { *m = AcceptancePolicy_RoleAdmissionPolicy{} } func (*AcceptancePolicy_RoleAdmissionPolicy) ProtoMessage() {} func (*AcceptancePolicy_RoleAdmissionPolicy) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{28, 0} + return fileDescriptorTypes, []int{31, 0} } type AcceptancePolicy_RoleAdmissionPolicy_Secret struct { @@ -1360,7 +1505,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Reset() { } func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) ProtoMessage() {} func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{28, 0, 0} + return fileDescriptorTypes, []int{31, 0, 0} } type ExternalCA struct { @@ -1377,7 +1522,7 @@ type ExternalCA struct { func (m *ExternalCA) Reset() { *m = ExternalCA{} } func (*ExternalCA) ProtoMessage() {} -func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } +func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} } type CAConfig struct { // NodeCertExpiry is the duration certificates should be issued for @@ -1402,7 +1547,7 @@ type CAConfig struct { func (m *CAConfig) Reset() { *m = CAConfig{} } func (*CAConfig) ProtoMessage() {} -func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} } +func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} } // OrchestrationConfig defines cluster-level orchestration settings. type OrchestrationConfig struct { @@ -1413,7 +1558,7 @@ type OrchestrationConfig struct { func (m *OrchestrationConfig) Reset() { *m = OrchestrationConfig{} } func (*OrchestrationConfig) ProtoMessage() {} -func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} } +func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } // TaskDefaults specifies default values for task creation. type TaskDefaults struct { @@ -1427,7 +1572,7 @@ type TaskDefaults struct { func (m *TaskDefaults) Reset() { *m = TaskDefaults{} } func (*TaskDefaults) ProtoMessage() {} -func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} } +func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } // DispatcherConfig defines cluster-level dispatcher settings. type DispatcherConfig struct { @@ -1439,7 +1584,7 @@ type DispatcherConfig struct { func (m *DispatcherConfig) Reset() { *m = DispatcherConfig{} } func (*DispatcherConfig) ProtoMessage() {} -func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} } +func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } // RaftConfig defines raft settings for the cluster. type RaftConfig struct { @@ -1461,7 +1606,7 @@ type RaftConfig struct { func (m *RaftConfig) Reset() { *m = RaftConfig{} } func (*RaftConfig) ProtoMessage() {} -func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } +func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} } type EncryptionConfig struct { // AutoLockManagers specifies whether or not managers TLS keys and raft data @@ -1472,7 +1617,7 @@ type EncryptionConfig struct { func (m *EncryptionConfig) Reset() { *m = EncryptionConfig{} } func (*EncryptionConfig) ProtoMessage() {} -func (*EncryptionConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } +func (*EncryptionConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} } type SpreadOver struct { SpreadDescriptor string `protobuf:"bytes,1,opt,name=spread_descriptor,json=spreadDescriptor,proto3" json:"spread_descriptor,omitempty"` @@ -1480,7 +1625,7 @@ type SpreadOver struct { func (m *SpreadOver) Reset() { *m = SpreadOver{} } func (*SpreadOver) ProtoMessage() {} -func (*SpreadOver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } +func (*SpreadOver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} } type PlacementPreference struct { // Types that are valid to be assigned to Preference: @@ -1490,7 +1635,7 @@ type PlacementPreference struct { func (m *PlacementPreference) Reset() { *m = PlacementPreference{} } func (*PlacementPreference) ProtoMessage() {} -func (*PlacementPreference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} } +func (*PlacementPreference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} } type isPlacementPreference_Preference interface { isPlacementPreference_Preference() @@ -1589,7 +1734,7 @@ type Placement struct { func (m *Placement) Reset() { *m = Placement{} } func (*Placement) ProtoMessage() {} -func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} } +func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} } // JoinToken contains the join tokens for workers and managers. type JoinTokens struct { @@ -1601,7 +1746,7 @@ type JoinTokens struct { func (m *JoinTokens) Reset() { *m = JoinTokens{} } func (*JoinTokens) ProtoMessage() {} -func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} } +func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} } type RootCA struct { // CAKey is the root CA private key. @@ -1622,7 +1767,7 @@ type RootCA struct { func (m *RootCA) Reset() { *m = RootCA{} } func (*RootCA) ProtoMessage() {} -func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} } +func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} } type Certificate struct { Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"` @@ -1635,7 +1780,7 @@ type Certificate struct { func (m *Certificate) Reset() { *m = Certificate{} } func (*Certificate) ProtoMessage() {} -func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} } +func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{44} } // Symmetric keys to encrypt inter-agent communication. type EncryptionKey struct { @@ -1651,7 +1796,7 @@ type EncryptionKey struct { func (m *EncryptionKey) Reset() { *m = EncryptionKey{} } func (*EncryptionKey) ProtoMessage() {} -func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} } +func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{45} } // ManagerStatus provides informations about the state of a manager in the cluster. type ManagerStatus struct { @@ -1668,7 +1813,7 @@ type ManagerStatus struct { func (m *ManagerStatus) Reset() { *m = ManagerStatus{} } func (*ManagerStatus) ProtoMessage() {} -func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} } +func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{46} } // FileTarget represents a specific target that is backed by a file type FileTarget struct { @@ -1684,7 +1829,7 @@ type FileTarget struct { func (m *FileTarget) Reset() { *m = FileTarget{} } func (*FileTarget) ProtoMessage() {} -func (*FileTarget) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{44} } +func (*FileTarget) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{47} } // SecretReference is the linkage between a service and a secret that it uses. type SecretReference struct { @@ -1704,7 +1849,7 @@ type SecretReference struct { func (m *SecretReference) Reset() { *m = SecretReference{} } func (*SecretReference) ProtoMessage() {} -func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{45} } +func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{48} } type isSecretReference_Target interface { isSecretReference_Target() @@ -1804,7 +1949,7 @@ type ConfigReference struct { func (m *ConfigReference) Reset() { *m = ConfigReference{} } func (*ConfigReference) ProtoMessage() {} -func (*ConfigReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{46} } +func (*ConfigReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{49} } type isConfigReference_Target interface { isConfigReference_Target() @@ -1898,7 +2043,7 @@ type BlacklistedCertificate struct { func (m *BlacklistedCertificate) Reset() { *m = BlacklistedCertificate{} } func (*BlacklistedCertificate) ProtoMessage() {} -func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{47} } +func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{50} } // HealthConfig holds configuration settings for the HEALTHCHECK feature. type HealthConfig struct { @@ -1928,7 +2073,7 @@ type HealthConfig struct { func (m *HealthConfig) Reset() { *m = HealthConfig{} } func (*HealthConfig) ProtoMessage() {} -func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{48} } +func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{51} } type MaybeEncryptedRecord struct { Algorithm MaybeEncryptedRecord_Algorithm `protobuf:"varint,1,opt,name=algorithm,proto3,enum=docker.swarmkit.v1.MaybeEncryptedRecord_Algorithm" json:"algorithm,omitempty"` @@ -1938,7 +2083,7 @@ type MaybeEncryptedRecord struct { func (m *MaybeEncryptedRecord) Reset() { *m = MaybeEncryptedRecord{} } func (*MaybeEncryptedRecord) ProtoMessage() {} -func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{49} } +func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{52} } type RootRotation struct { CACert []byte `protobuf:"bytes,1,opt,name=ca_cert,json=caCert,proto3" json:"ca_cert,omitempty"` @@ -1949,7 +2094,7 @@ type RootRotation struct { func (m *RootRotation) Reset() { *m = RootRotation{} } func (*RootRotation) ProtoMessage() {} -func (*RootRotation) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{50} } +func (*RootRotation) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{53} } // Privileges specifies security configuration/permissions. type Privileges struct { @@ -1959,7 +2104,7 @@ type Privileges struct { func (m *Privileges) Reset() { *m = Privileges{} } func (*Privileges) ProtoMessage() {} -func (*Privileges) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{51} } +func (*Privileges) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{54} } // CredentialSpec for managed service account (Windows only). type Privileges_CredentialSpec struct { @@ -1972,7 +2117,7 @@ type Privileges_CredentialSpec struct { func (m *Privileges_CredentialSpec) Reset() { *m = Privileges_CredentialSpec{} } func (*Privileges_CredentialSpec) ProtoMessage() {} func (*Privileges_CredentialSpec) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{51, 0} + return fileDescriptorTypes, []int{54, 0} } type isPrivileges_CredentialSpec_Source interface { @@ -2090,13 +2235,16 @@ type Privileges_SELinuxContext struct { func (m *Privileges_SELinuxContext) Reset() { *m = Privileges_SELinuxContext{} } func (*Privileges_SELinuxContext) ProtoMessage() {} func (*Privileges_SELinuxContext) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{51, 1} + return fileDescriptorTypes, []int{54, 1} } func init() { proto.RegisterType((*Version)(nil), "docker.swarmkit.v1.Version") proto.RegisterType((*IndexEntry)(nil), "docker.swarmkit.v1.IndexEntry") proto.RegisterType((*Annotations)(nil), "docker.swarmkit.v1.Annotations") + proto.RegisterType((*GenericString)(nil), "docker.swarmkit.v1.GenericString") + proto.RegisterType((*GenericDiscrete)(nil), "docker.swarmkit.v1.GenericDiscrete") + proto.RegisterType((*GenericResource)(nil), "docker.swarmkit.v1.GenericResource") proto.RegisterType((*Resources)(nil), "docker.swarmkit.v1.Resources") proto.RegisterType((*ResourceRequirements)(nil), "docker.swarmkit.v1.ResourceRequirements") proto.RegisterType((*Platform)(nil), "docker.swarmkit.v1.Platform") @@ -2231,6 +2379,68 @@ func (m *Annotations) CopyFrom(src interface{}) { } +func (m *GenericString) Copy() *GenericString { + if m == nil { + return nil + } + o := &GenericString{} + o.CopyFrom(m) + return o +} + +func (m *GenericString) CopyFrom(src interface{}) { + + o := src.(*GenericString) + *m = *o +} + +func (m *GenericDiscrete) Copy() *GenericDiscrete { + if m == nil { + return nil + } + o := &GenericDiscrete{} + o.CopyFrom(m) + return o +} + +func (m *GenericDiscrete) CopyFrom(src interface{}) { + + o := src.(*GenericDiscrete) + *m = *o +} + +func (m *GenericResource) Copy() *GenericResource { + if m == nil { + return nil + } + o := &GenericResource{} + o.CopyFrom(m) + return o +} + +func (m *GenericResource) CopyFrom(src interface{}) { + + o := src.(*GenericResource) + *m = *o + if o.Resource != nil { + switch o.Resource.(type) { + case *GenericResource_Str: + v := GenericResource_Str{ + Str: &GenericString{}, + } + github_com_docker_swarmkit_api_deepcopy.Copy(v.Str, o.GetStr()) + m.Resource = &v + case *GenericResource_Discrete: + v := GenericResource_Discrete{ + Discrete: &GenericDiscrete{}, + } + github_com_docker_swarmkit_api_deepcopy.Copy(v.Discrete, o.GetDiscrete()) + m.Resource = &v + } + } + +} + func (m *Resources) Copy() *Resources { if m == nil { return nil @@ -2244,6 +2454,14 @@ func (m *Resources) CopyFrom(src interface{}) { o := src.(*Resources) *m = *o + if o.Generic != nil { + m.Generic = make([]*GenericResource, len(o.Generic)) + for i := range m.Generic { + m.Generic[i] = &GenericResource{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Generic[i], o.Generic[i]) + } + } + } func (m *ResourceRequirements) Copy() *ResourceRequirements { @@ -3544,6 +3762,118 @@ func (m *Annotations) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *GenericString) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenericString) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Kind) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Kind))) + i += copy(dAtA[i:], m.Kind) + } + if len(m.Value) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + return i, nil +} + +func (m *GenericDiscrete) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenericDiscrete) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Kind) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Kind))) + i += copy(dAtA[i:], m.Kind) + } + if m.Value != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Value)) + } + return i, nil +} + +func (m *GenericResource) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenericResource) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Resource != nil { + nn1, err := m.Resource.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += nn1 + } + return i, nil +} + +func (m *GenericResource_Str) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.Str != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Str.Size())) + n2, err := m.Str.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + return i, nil +} +func (m *GenericResource_Discrete) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.Discrete != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Discrete.Size())) + n3, err := m.Discrete.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + return i, nil +} func (m *Resources) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3569,6 +3899,18 @@ func (m *Resources) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintTypes(dAtA, i, uint64(m.MemoryBytes)) } + if len(m.Generic) > 0 { + for _, msg := range m.Generic { + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -3591,21 +3933,21 @@ func (m *ResourceRequirements) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Limits.Size())) - n1, err := m.Limits.MarshalTo(dAtA[i:]) + n4, err := m.Limits.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n1 + i += n4 } if m.Reservations != nil { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Reservations.Size())) - n2, err := m.Reservations.MarshalTo(dAtA[i:]) + n5, err := m.Reservations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n2 + i += n5 } return i, nil } @@ -3748,41 +4090,41 @@ func (m *NodeDescription) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Platform.Size())) - n3, err := m.Platform.MarshalTo(dAtA[i:]) + n6, err := m.Platform.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n3 + i += n6 } if m.Resources != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Resources.Size())) - n4, err := m.Resources.MarshalTo(dAtA[i:]) + n7, err := m.Resources.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n4 + i += n7 } if m.Engine != nil { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Engine.Size())) - n5, err := m.Engine.MarshalTo(dAtA[i:]) + n8, err := m.Engine.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n5 + i += n8 } if m.TLSInfo != nil { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.TLSInfo.Size())) - n6, err := m.TLSInfo.MarshalTo(dAtA[i:]) + n9, err := m.TLSInfo.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n6 + i += n9 } return i, nil } @@ -3967,31 +4309,31 @@ func (m *Mount) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.BindOptions.Size())) - n7, err := m.BindOptions.MarshalTo(dAtA[i:]) + n10, err := m.BindOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n7 + i += n10 } if m.VolumeOptions != nil { dAtA[i] = 0x32 i++ i = encodeVarintTypes(dAtA, i, uint64(m.VolumeOptions.Size())) - n8, err := m.VolumeOptions.MarshalTo(dAtA[i:]) + n11, err := m.VolumeOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n11 } if m.TmpfsOptions != nil { dAtA[i] = 0x3a i++ i = encodeVarintTypes(dAtA, i, uint64(m.TmpfsOptions.Size())) - n9, err := m.TmpfsOptions.MarshalTo(dAtA[i:]) + n12, err := m.TmpfsOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 + i += n12 } return i, nil } @@ -4065,11 +4407,11 @@ func (m *Mount_VolumeOptions) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.DriverConfig.Size())) - n10, err := m.DriverConfig.MarshalTo(dAtA[i:]) + n13, err := m.DriverConfig.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n13 } return i, nil } @@ -4126,11 +4468,11 @@ func (m *RestartPolicy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Delay.Size())) - n11, err := m.Delay.MarshalTo(dAtA[i:]) + n14, err := m.Delay.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n14 } if m.MaxAttempts != 0 { dAtA[i] = 0x18 @@ -4141,11 +4483,11 @@ func (m *RestartPolicy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Window.Size())) - n12, err := m.Window.MarshalTo(dAtA[i:]) + n15, err := m.Window.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n15 } return i, nil } @@ -4173,11 +4515,11 @@ func (m *UpdateConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(m.Delay))) - n13, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Delay, dAtA[i:]) + n16, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Delay, dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n16 if m.FailureAction != 0 { dAtA[i] = 0x18 i++ @@ -4187,11 +4529,11 @@ func (m *UpdateConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Monitor.Size())) - n14, err := m.Monitor.MarshalTo(dAtA[i:]) + n17, err := m.Monitor.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n17 } if m.MaxFailureRatio != 0 { dAtA[i] = 0x2d @@ -4230,21 +4572,21 @@ func (m *UpdateStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.StartedAt.Size())) - n15, err := m.StartedAt.MarshalTo(dAtA[i:]) + n18, err := m.StartedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n18 } if m.CompletedAt != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.CompletedAt.Size())) - n16, err := m.CompletedAt.MarshalTo(dAtA[i:]) + n19, err := m.CompletedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n19 } if len(m.Message) > 0 { dAtA[i] = 0x22 @@ -4338,11 +4680,11 @@ func (m *TaskStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Timestamp.Size())) - n17, err := m.Timestamp.MarshalTo(dAtA[i:]) + n20, err := m.Timestamp.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n20 } if m.State != 0 { dAtA[i] = 0x10 @@ -4362,21 +4704,21 @@ func (m *TaskStatus) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.Err) } if m.RuntimeStatus != nil { - nn18, err := m.RuntimeStatus.MarshalTo(dAtA[i:]) + nn21, err := m.RuntimeStatus.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn18 + i += nn21 } if m.PortStatus != nil { dAtA[i] = 0x32 i++ i = encodeVarintTypes(dAtA, i, uint64(m.PortStatus.Size())) - n19, err := m.PortStatus.MarshalTo(dAtA[i:]) + n22, err := m.PortStatus.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n22 } return i, nil } @@ -4387,11 +4729,11 @@ func (m *TaskStatus_Container) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Container.Size())) - n20, err := m.Container.MarshalTo(dAtA[i:]) + n23, err := m.Container.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n23 } return i, nil } @@ -4628,11 +4970,11 @@ func (m *IPAMOptions) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Driver.Size())) - n21, err := m.Driver.MarshalTo(dAtA[i:]) + n24, err := m.Driver.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n24 } if len(m.Configs) > 0 { for _, msg := range m.Configs { @@ -4698,11 +5040,11 @@ func (m *WeightedPeer) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Peer.Size())) - n22, err := m.Peer.MarshalTo(dAtA[i:]) + n25, err := m.Peer.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n25 } if m.Weight != 0 { dAtA[i] = 0x10 @@ -4805,11 +5147,11 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy) MarshalTo(dAtA []byte) (int, erro dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Secret.Size())) - n23, err := m.Secret.MarshalTo(dAtA[i:]) + n26, err := m.Secret.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n26 } return i, nil } @@ -4915,11 +5257,11 @@ func (m *CAConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.NodeCertExpiry.Size())) - n24, err := m.NodeCertExpiry.MarshalTo(dAtA[i:]) + n27, err := m.NodeCertExpiry.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n27 } if len(m.ExternalCAs) > 0 { for _, msg := range m.ExternalCAs { @@ -4995,11 +5337,11 @@ func (m *TaskDefaults) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.LogDriver.Size())) - n25, err := m.LogDriver.MarshalTo(dAtA[i:]) + n28, err := m.LogDriver.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n28 } return i, nil } @@ -5023,11 +5365,11 @@ func (m *DispatcherConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.HeartbeatPeriod.Size())) - n26, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:]) + n29, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n29 } return i, nil } @@ -5143,11 +5485,11 @@ func (m *PlacementPreference) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.Preference != nil { - nn27, err := m.Preference.MarshalTo(dAtA[i:]) + nn30, err := m.Preference.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn27 + i += nn30 } return i, nil } @@ -5158,11 +5500,11 @@ func (m *PlacementPreference_Spread) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Spread.Size())) - n28, err := m.Spread.MarshalTo(dAtA[i:]) + n31, err := m.Spread.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n31 } return i, nil } @@ -5289,20 +5631,20 @@ func (m *RootCA) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.JoinTokens.Size())) - n29, err := m.JoinTokens.MarshalTo(dAtA[i:]) + n32, err := m.JoinTokens.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n32 if m.RootRotation != nil { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.RootRotation.Size())) - n30, err := m.RootRotation.MarshalTo(dAtA[i:]) + n33, err := m.RootRotation.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n33 } if m.LastForcedRotation != 0 { dAtA[i] = 0x30 @@ -5341,11 +5683,11 @@ func (m *Certificate) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Status.Size())) - n31, err := m.Status.MarshalTo(dAtA[i:]) + n34, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n34 if len(m.Certificate) > 0 { dAtA[i] = 0x22 i++ @@ -5514,11 +5856,11 @@ func (m *SecretReference) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.SecretName) } if m.Target != nil { - nn32, err := m.Target.MarshalTo(dAtA[i:]) + nn35, err := m.Target.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn32 + i += nn35 } return i, nil } @@ -5529,11 +5871,11 @@ func (m *SecretReference_File) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.File.Size())) - n33, err := m.File.MarshalTo(dAtA[i:]) + n36, err := m.File.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n33 + i += n36 } return i, nil } @@ -5565,11 +5907,11 @@ func (m *ConfigReference) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.ConfigName) } if m.Target != nil { - nn34, err := m.Target.MarshalTo(dAtA[i:]) + nn37, err := m.Target.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn34 + i += nn37 } return i, nil } @@ -5580,11 +5922,11 @@ func (m *ConfigReference_File) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.File.Size())) - n35, err := m.File.MarshalTo(dAtA[i:]) + n38, err := m.File.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n38 } return i, nil } @@ -5607,11 +5949,11 @@ func (m *BlacklistedCertificate) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Expiry.Size())) - n36, err := m.Expiry.MarshalTo(dAtA[i:]) + n39, err := m.Expiry.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n39 } return i, nil } @@ -5650,21 +5992,21 @@ func (m *HealthConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Interval.Size())) - n37, err := m.Interval.MarshalTo(dAtA[i:]) + n40, err := m.Interval.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n40 } if m.Timeout != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Timeout.Size())) - n38, err := m.Timeout.MarshalTo(dAtA[i:]) + n41, err := m.Timeout.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n41 } if m.Retries != 0 { dAtA[i] = 0x20 @@ -5675,11 +6017,11 @@ func (m *HealthConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.StartPeriod.Size())) - n39, err := m.StartPeriod.MarshalTo(dAtA[i:]) + n42, err := m.StartPeriod.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n42 } return i, nil } @@ -5774,21 +6116,21 @@ func (m *Privileges) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.CredentialSpec.Size())) - n40, err := m.CredentialSpec.MarshalTo(dAtA[i:]) + n43, err := m.CredentialSpec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n40 + i += n43 } if m.SELinuxContext != nil { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.SELinuxContext.Size())) - n41, err := m.SELinuxContext.MarshalTo(dAtA[i:]) + n44, err := m.SELinuxContext.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n41 + i += n44 } return i, nil } @@ -5809,11 +6151,11 @@ func (m *Privileges_CredentialSpec) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.Source != nil { - nn42, err := m.Source.MarshalTo(dAtA[i:]) + nn45, err := m.Source.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn42 + i += nn45 } return i, nil } @@ -5961,6 +6303,60 @@ func (m *Annotations) Size() (n int) { return n } +func (m *GenericString) Size() (n int) { + var l int + _ = l + l = len(m.Kind) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *GenericDiscrete) Size() (n int) { + var l int + _ = l + l = len(m.Kind) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.Value != 0 { + n += 1 + sovTypes(uint64(m.Value)) + } + return n +} + +func (m *GenericResource) Size() (n int) { + var l int + _ = l + if m.Resource != nil { + n += m.Resource.Size() + } + return n +} + +func (m *GenericResource_Str) Size() (n int) { + var l int + _ = l + if m.Str != nil { + l = m.Str.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} +func (m *GenericResource_Discrete) Size() (n int) { + var l int + _ = l + if m.Discrete != nil { + l = m.Discrete.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} func (m *Resources) Size() (n int) { var l int _ = l @@ -5970,6 +6366,12 @@ func (m *Resources) Size() (n int) { if m.MemoryBytes != 0 { n += 1 + sovTypes(uint64(m.MemoryBytes)) } + if len(m.Generic) > 0 { + for _, e := range m.Generic { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } return n } @@ -7056,6 +7458,58 @@ func (this *Annotations) String() string { }, "") return s } +func (this *GenericString) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericString{`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *GenericDiscrete) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericDiscrete{`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *GenericResource) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericResource{`, + `Resource:` + fmt.Sprintf("%v", this.Resource) + `,`, + `}`, + }, "") + return s +} +func (this *GenericResource_Str) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericResource_Str{`, + `Str:` + strings.Replace(fmt.Sprintf("%v", this.Str), "GenericString", "GenericString", 1) + `,`, + `}`, + }, "") + return s +} +func (this *GenericResource_Discrete) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericResource_Discrete{`, + `Discrete:` + strings.Replace(fmt.Sprintf("%v", this.Discrete), "GenericDiscrete", "GenericDiscrete", 1) + `,`, + `}`, + }, "") + return s +} func (this *Resources) String() string { if this == nil { return "nil" @@ -7063,6 +7517,7 @@ func (this *Resources) String() string { s := strings.Join([]string{`&Resources{`, `NanoCPUs:` + fmt.Sprintf("%v", this.NanoCPUs) + `,`, `MemoryBytes:` + fmt.Sprintf("%v", this.MemoryBytes) + `,`, + `Generic:` + strings.Replace(fmt.Sprintf("%v", this.Generic), "GenericResource", "GenericResource", 1) + `,`, `}`, }, "") return s @@ -8258,6 +8713,326 @@ func (m *Annotations) Unmarshal(dAtA []byte) error { } return nil } +func (m *GenericString) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenericString: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenericString: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + 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 ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + 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 ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenericDiscrete) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenericDiscrete: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenericDiscrete: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + 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 ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + m.Value = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Value |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenericResource) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenericResource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenericResource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Str", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &GenericString{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &GenericResource_Str{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Discrete", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &GenericDiscrete{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &GenericResource_Discrete{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Resources) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -8325,6 +9100,37 @@ func (m *Resources) Unmarshal(dAtA []byte) error { break } } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Generic", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Generic = append(m.Generic, &GenericResource{}) + if err := m.Generic[len(m.Generic)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -16245,300 +17051,306 @@ var ( func init() { proto.RegisterFile("types.proto", fileDescriptorTypes) } var fileDescriptorTypes = []byte{ - // 4705 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x7a, 0x4d, 0x6c, 0x24, 0xd7, - 0x56, 0xbf, 0xfb, 0xd3, 0xdd, 0xa7, 0xdb, 0x76, 0xf9, 0x8e, 0x33, 0xf1, 0x74, 0x26, 0x76, 0xa7, - 0x92, 0x79, 0xf9, 0x78, 0xf9, 0x77, 0x66, 0x3c, 0x49, 0x34, 0x49, 0xfe, 0x2f, 0x49, 0x7f, 0x79, - 0xdc, 0x6f, 0xec, 0xee, 0xd6, 0xed, 0xf6, 0xcc, 0xcb, 0x02, 0x4a, 0xe5, 0xaa, 0xeb, 0x76, 0xc5, - 0xd5, 0x75, 0x9b, 0xaa, 0x6a, 0x7b, 0x9a, 0x07, 0x62, 0xc4, 0x02, 0x90, 0x57, 0xb0, 0x43, 0x42, - 0x66, 0x03, 0x2b, 0x84, 0xc4, 0x02, 0x24, 0x04, 0x1b, 0x82, 0xc4, 0x22, 0x3b, 0x1e, 0x20, 0xa1, - 0x27, 0x90, 0x0c, 0xf1, 0x82, 0x1d, 0x82, 0xcd, 0x13, 0x1b, 0x90, 0xd0, 0xfd, 0xa8, 0xea, 0x6a, - 0x4f, 0xd9, 0x9e, 0x90, 0xb7, 0xb1, 0xeb, 0x9e, 0xf3, 0x3b, 0xe7, 0xde, 0x7b, 0xee, 0xb9, 0xe7, - 0x9e, 0x73, 0x6f, 0x43, 0xc1, 0x9f, 0x8c, 0x88, 0x57, 0x19, 0xb9, 0xd4, 0xa7, 0x08, 0x99, 0xd4, - 0x38, 0x24, 0x6e, 0xc5, 0x3b, 0xd6, 0xdd, 0xe1, 0xa1, 0xe5, 0x57, 0x8e, 0xee, 0x95, 0xd6, 0x07, - 0x94, 0x0e, 0x6c, 0xf2, 0x1e, 0x47, 0xec, 0x8d, 0xf7, 0xdf, 0xf3, 0xad, 0x21, 0xf1, 0x7c, 0x7d, - 0x38, 0x12, 0x42, 0xa5, 0xb5, 0x8b, 0x00, 0x73, 0xec, 0xea, 0xbe, 0x45, 0x1d, 0xc9, 0x5f, 0x19, - 0xd0, 0x01, 0xe5, 0x9f, 0xef, 0xb1, 0x2f, 0x41, 0x55, 0xd7, 0x61, 0xfe, 0x31, 0x71, 0x3d, 0x8b, - 0x3a, 0x68, 0x05, 0x32, 0x96, 0x63, 0x92, 0xa7, 0xab, 0x89, 0x72, 0xe2, 0xad, 0x34, 0x16, 0x0d, - 0xf5, 0x2e, 0x40, 0x8b, 0x7d, 0x34, 0x1d, 0xdf, 0x9d, 0x20, 0x05, 0x52, 0x87, 0x64, 0xc2, 0x11, - 0x79, 0xcc, 0x3e, 0x19, 0xe5, 0x48, 0xb7, 0x57, 0x93, 0x82, 0x72, 0xa4, 0xdb, 0xea, 0x37, 0x09, - 0x28, 0x54, 0x1d, 0x87, 0xfa, 0xbc, 0x77, 0x0f, 0x21, 0x48, 0x3b, 0xfa, 0x90, 0x48, 0x21, 0xfe, - 0x8d, 0xea, 0x90, 0xb5, 0xf5, 0x3d, 0x62, 0x7b, 0xab, 0xc9, 0x72, 0xea, 0xad, 0xc2, 0xc6, 0xf7, - 0x2b, 0xcf, 0x4f, 0xb9, 0x12, 0x51, 0x52, 0xd9, 0xe6, 0x68, 0x3e, 0x08, 0x2c, 0x45, 0xd1, 0xa7, - 0x30, 0x6f, 0x39, 0xa6, 0x65, 0x10, 0x6f, 0x35, 0xcd, 0xb5, 0xac, 0xc5, 0x69, 0x99, 0x8e, 0xbe, - 0x96, 0xfe, 0xfa, 0x6c, 0x7d, 0x0e, 0x07, 0x42, 0xa5, 0x8f, 0xa0, 0x10, 0x51, 0x1b, 0x33, 0xb7, - 0x15, 0xc8, 0x1c, 0xe9, 0xf6, 0x98, 0xc8, 0xd9, 0x89, 0xc6, 0xc7, 0xc9, 0x07, 0x09, 0xf5, 0x0b, - 0xc8, 0x63, 0xe2, 0xd1, 0xb1, 0x6b, 0x10, 0x0f, 0xbd, 0x0d, 0x79, 0x47, 0x77, 0xa8, 0x66, 0x8c, - 0xc6, 0x1e, 0x17, 0x4f, 0xd5, 0x8a, 0xe7, 0x67, 0xeb, 0xb9, 0xb6, 0xee, 0xd0, 0x7a, 0x77, 0xd7, - 0xc3, 0x39, 0xc6, 0xae, 0x8f, 0xc6, 0x1e, 0x7a, 0x0d, 0x8a, 0x43, 0x32, 0xa4, 0xee, 0x44, 0xdb, - 0x9b, 0xf8, 0xc4, 0xe3, 0x8a, 0x53, 0xb8, 0x20, 0x68, 0x35, 0x46, 0x52, 0x7f, 0x3b, 0x01, 0x2b, - 0x81, 0x6e, 0x4c, 0x7e, 0x69, 0x6c, 0xb9, 0x64, 0x48, 0x1c, 0xdf, 0x43, 0x1f, 0x40, 0xd6, 0xb6, - 0x86, 0x96, 0x2f, 0xfa, 0x28, 0x6c, 0xbc, 0x1a, 0x37, 0xdb, 0x70, 0x54, 0x58, 0x82, 0x51, 0x15, - 0x8a, 0x2e, 0xf1, 0x88, 0x7b, 0x24, 0x2c, 0xc9, 0xbb, 0xbc, 0x56, 0x78, 0x46, 0x44, 0xdd, 0x84, - 0x5c, 0xd7, 0xd6, 0xfd, 0x7d, 0xea, 0x0e, 0x91, 0x0a, 0x45, 0xdd, 0x35, 0x0e, 0x2c, 0x9f, 0x18, - 0xfe, 0xd8, 0x0d, 0x56, 0x75, 0x86, 0x86, 0x6e, 0x42, 0x92, 0x8a, 0x8e, 0xf2, 0xb5, 0xec, 0xf9, - 0xd9, 0x7a, 0xb2, 0xd3, 0xc3, 0x49, 0xea, 0xa9, 0x9f, 0xc0, 0x72, 0xd7, 0x1e, 0x0f, 0x2c, 0xa7, - 0x41, 0x3c, 0xc3, 0xb5, 0x46, 0x4c, 0x3b, 0x73, 0x0f, 0xe6, 0xfb, 0x81, 0x7b, 0xb0, 0xef, 0xd0, - 0x65, 0x92, 0x53, 0x97, 0x51, 0x7f, 0x33, 0x09, 0xcb, 0x4d, 0x67, 0x60, 0x39, 0x24, 0x2a, 0x7d, - 0x07, 0x16, 0x09, 0x27, 0x6a, 0x47, 0xc2, 0x8d, 0xa5, 0x9e, 0x05, 0x41, 0x0d, 0x7c, 0xbb, 0x75, - 0xc1, 0xdf, 0xee, 0xc5, 0x4d, 0xff, 0x39, 0xed, 0xb1, 0x5e, 0xd7, 0x84, 0xf9, 0x11, 0x9f, 0x84, - 0xb7, 0x9a, 0xe2, 0xba, 0xee, 0xc4, 0xe9, 0x7a, 0x6e, 0x9e, 0x81, 0xf3, 0x49, 0xd9, 0xef, 0xe2, - 0x7c, 0x7f, 0x9c, 0x84, 0xa5, 0x36, 0x35, 0x67, 0xec, 0x50, 0x82, 0xdc, 0x01, 0xf5, 0xfc, 0xc8, - 0x46, 0x0b, 0xdb, 0xe8, 0x01, 0xe4, 0x46, 0x72, 0xf9, 0xe4, 0xea, 0xdf, 0x8e, 0x1f, 0xb2, 0xc0, - 0xe0, 0x10, 0x8d, 0x3e, 0x81, 0xbc, 0x1b, 0xf8, 0xc4, 0x6a, 0xea, 0x45, 0x1c, 0x67, 0x8a, 0x47, - 0x3f, 0x80, 0xac, 0x58, 0x84, 0xd5, 0x34, 0x97, 0xbc, 0xf3, 0x42, 0x36, 0xc7, 0x52, 0x08, 0x3d, - 0x84, 0x9c, 0x6f, 0x7b, 0x9a, 0xe5, 0xec, 0xd3, 0xd5, 0x0c, 0x57, 0xb0, 0x1e, 0xa7, 0x80, 0x19, - 0xa2, 0xbf, 0xdd, 0x6b, 0x39, 0xfb, 0xb4, 0x56, 0x38, 0x3f, 0x5b, 0x9f, 0x97, 0x0d, 0x3c, 0xef, - 0xdb, 0x1e, 0xfb, 0x50, 0x7f, 0x27, 0x01, 0x85, 0x08, 0x0a, 0xbd, 0x0a, 0xe0, 0xbb, 0x63, 0xcf, - 0xd7, 0x5c, 0x4a, 0x7d, 0x6e, 0xac, 0x22, 0xce, 0x73, 0x0a, 0xa6, 0xd4, 0x47, 0x15, 0xb8, 0x61, - 0x10, 0xd7, 0xd7, 0x2c, 0xcf, 0x1b, 0x13, 0x57, 0xf3, 0xc6, 0x7b, 0x5f, 0x12, 0xc3, 0xe7, 0x86, - 0x2b, 0xe2, 0x65, 0xc6, 0x6a, 0x71, 0x4e, 0x4f, 0x30, 0xd0, 0x7d, 0xb8, 0x19, 0xc5, 0x8f, 0xc6, - 0x7b, 0xb6, 0x65, 0x68, 0x6c, 0x31, 0x53, 0x5c, 0xe4, 0xc6, 0x54, 0xa4, 0xcb, 0x79, 0x8f, 0xc8, - 0x44, 0xfd, 0x69, 0x02, 0x14, 0xac, 0xef, 0xfb, 0x3b, 0x64, 0xb8, 0x47, 0xdc, 0x9e, 0xaf, 0xfb, - 0x63, 0x0f, 0xdd, 0x84, 0xac, 0x4d, 0x74, 0x93, 0xb8, 0x7c, 0x50, 0x39, 0x2c, 0x5b, 0x68, 0x97, - 0xed, 0x60, 0xdd, 0x38, 0xd0, 0xf7, 0x2c, 0xdb, 0xf2, 0x27, 0x7c, 0x28, 0x8b, 0xf1, 0x2e, 0x7c, - 0x51, 0x67, 0x05, 0x47, 0x04, 0xf1, 0x8c, 0x1a, 0xb4, 0x0a, 0xf3, 0x43, 0xe2, 0x79, 0xfa, 0x80, - 0xf0, 0x91, 0xe6, 0x71, 0xd0, 0x54, 0x3f, 0x81, 0x62, 0x54, 0x0e, 0x15, 0x60, 0x7e, 0xb7, 0xfd, - 0xa8, 0xdd, 0x79, 0xd2, 0x56, 0xe6, 0xd0, 0x12, 0x14, 0x76, 0xdb, 0xb8, 0x59, 0xad, 0x6f, 0x55, - 0x6b, 0xdb, 0x4d, 0x25, 0x81, 0x16, 0x20, 0x3f, 0x6d, 0x26, 0xd5, 0x3f, 0x4d, 0x00, 0x30, 0x73, - 0xcb, 0x49, 0x7d, 0x0c, 0x19, 0xcf, 0xd7, 0x7d, 0xe1, 0x95, 0x8b, 0x1b, 0x6f, 0x5c, 0xb6, 0x86, - 0x72, 0xbc, 0xec, 0x1f, 0xc1, 0x42, 0x24, 0x3a, 0xc2, 0xe4, 0xcc, 0x08, 0x59, 0x80, 0xd0, 0x4d, - 0xd3, 0x95, 0x03, 0xe7, 0xdf, 0xea, 0x27, 0x90, 0xe1, 0xd2, 0xb3, 0xc3, 0xcd, 0x41, 0xba, 0xc1, - 0xbe, 0x12, 0x28, 0x0f, 0x19, 0xdc, 0xac, 0x36, 0xbe, 0x50, 0x92, 0x48, 0x81, 0x62, 0xa3, 0xd5, - 0xab, 0x77, 0xda, 0xed, 0x66, 0xbd, 0xdf, 0x6c, 0x28, 0x29, 0xf5, 0x0e, 0x64, 0x5a, 0x43, 0xa6, - 0xf9, 0x36, 0x73, 0xf9, 0x7d, 0xe2, 0x12, 0xc7, 0x08, 0x76, 0xd2, 0x94, 0xa0, 0xfe, 0x24, 0x0f, - 0x99, 0x1d, 0x3a, 0x76, 0x7c, 0xb4, 0x11, 0x09, 0x5b, 0x8b, 0xf1, 0x27, 0x0f, 0x07, 0x56, 0xfa, - 0x93, 0x11, 0x91, 0x61, 0xed, 0x26, 0x64, 0xc5, 0xe6, 0x90, 0xd3, 0x91, 0x2d, 0x46, 0xf7, 0x75, - 0x77, 0x40, 0x7c, 0x39, 0x1f, 0xd9, 0x42, 0x6f, 0x41, 0xce, 0x25, 0xba, 0x49, 0x1d, 0x7b, 0xc2, - 0xf7, 0x50, 0x4e, 0x9c, 0x2b, 0x98, 0xe8, 0x66, 0xc7, 0xb1, 0x27, 0x38, 0xe4, 0xa2, 0x2d, 0x28, - 0xee, 0x59, 0x8e, 0xa9, 0xd1, 0x91, 0x08, 0xf2, 0x99, 0xcb, 0x77, 0x9c, 0x18, 0x55, 0xcd, 0x72, - 0xcc, 0x8e, 0x00, 0xe3, 0xc2, 0xde, 0xb4, 0x81, 0xda, 0xb0, 0x78, 0x44, 0xed, 0xf1, 0x90, 0x84, - 0xba, 0xb2, 0x5c, 0xd7, 0x9b, 0x97, 0xeb, 0x7a, 0xcc, 0xf1, 0x81, 0xb6, 0x85, 0xa3, 0x68, 0x13, - 0x3d, 0x82, 0x05, 0x7f, 0x38, 0xda, 0xf7, 0x42, 0x75, 0xf3, 0x5c, 0xdd, 0xf7, 0xae, 0x30, 0x18, - 0x83, 0x07, 0xda, 0x8a, 0x7e, 0xa4, 0x55, 0xfa, 0xf5, 0x14, 0x14, 0x22, 0x23, 0x47, 0x3d, 0x28, - 0x8c, 0x5c, 0x3a, 0xd2, 0x07, 0xfc, 0xa0, 0x92, 0x6b, 0x71, 0xef, 0x85, 0x66, 0x5d, 0xe9, 0x4e, - 0x05, 0x71, 0x54, 0x8b, 0x7a, 0x9a, 0x84, 0x42, 0x84, 0x89, 0xde, 0x81, 0x1c, 0xee, 0xe2, 0xd6, - 0xe3, 0x6a, 0xbf, 0xa9, 0xcc, 0x95, 0x6e, 0x9f, 0x9c, 0x96, 0x57, 0xb9, 0xb6, 0xa8, 0x82, 0xae, - 0x6b, 0x1d, 0x31, 0xd7, 0x7b, 0x0b, 0xe6, 0x03, 0x68, 0xa2, 0xf4, 0xca, 0xc9, 0x69, 0xf9, 0xe5, - 0x8b, 0xd0, 0x08, 0x12, 0xf7, 0xb6, 0xaa, 0xb8, 0xd9, 0x50, 0x92, 0xf1, 0x48, 0xdc, 0x3b, 0xd0, - 0x5d, 0x62, 0xa2, 0xef, 0x41, 0x56, 0x02, 0x53, 0xa5, 0xd2, 0xc9, 0x69, 0xf9, 0xe6, 0x45, 0xe0, - 0x14, 0x87, 0x7b, 0xdb, 0xd5, 0xc7, 0x4d, 0x25, 0x1d, 0x8f, 0xc3, 0x3d, 0x5b, 0x3f, 0x22, 0xe8, - 0x0d, 0xc8, 0x08, 0x58, 0xa6, 0x74, 0xeb, 0xe4, 0xb4, 0xfc, 0xd2, 0x73, 0xea, 0x18, 0xaa, 0xb4, - 0xfa, 0x5b, 0x7f, 0xb0, 0x36, 0xf7, 0x97, 0x7f, 0xb8, 0xa6, 0x5c, 0x64, 0x97, 0xfe, 0x3b, 0x01, - 0x0b, 0x33, 0x4b, 0x8e, 0x54, 0xc8, 0x3a, 0xd4, 0xa0, 0x23, 0x71, 0x7e, 0xe5, 0x6a, 0x70, 0x7e, - 0xb6, 0x9e, 0x6d, 0xd3, 0x3a, 0x1d, 0x4d, 0xb0, 0xe4, 0xa0, 0x47, 0x17, 0x4e, 0xe0, 0xfb, 0x2f, - 0xe8, 0x4f, 0xb1, 0x67, 0xf0, 0x67, 0xb0, 0x60, 0xba, 0xd6, 0x11, 0x71, 0x35, 0x83, 0x3a, 0xfb, - 0xd6, 0x40, 0x9e, 0x4d, 0xa5, 0x38, 0x9d, 0x0d, 0x0e, 0xc4, 0x45, 0x21, 0x50, 0xe7, 0xf8, 0xef, - 0x70, 0xfa, 0x96, 0x1e, 0x43, 0x31, 0xea, 0xa1, 0xec, 0x38, 0xf1, 0xac, 0x5f, 0x26, 0x32, 0xa1, - 0xe3, 0xe9, 0x1f, 0xce, 0x33, 0x0a, 0x4f, 0xe7, 0xd0, 0x9b, 0x90, 0x1e, 0x52, 0x53, 0xe8, 0x59, - 0xa8, 0xdd, 0x60, 0x49, 0xc0, 0x3f, 0x9d, 0xad, 0x17, 0xa8, 0x57, 0xd9, 0xb4, 0x6c, 0xb2, 0x43, - 0x4d, 0x82, 0x39, 0x40, 0x3d, 0x82, 0x34, 0x0b, 0x15, 0xe8, 0x15, 0x48, 0xd7, 0x5a, 0xed, 0x86, - 0x32, 0x57, 0x5a, 0x3e, 0x39, 0x2d, 0x2f, 0x70, 0x93, 0x30, 0x06, 0xf3, 0x5d, 0xb4, 0x0e, 0xd9, - 0xc7, 0x9d, 0xed, 0xdd, 0x1d, 0xe6, 0x5e, 0x37, 0x4e, 0x4e, 0xcb, 0x4b, 0x21, 0x5b, 0x18, 0x0d, - 0xbd, 0x0a, 0x99, 0xfe, 0x4e, 0x77, 0xb3, 0xa7, 0x24, 0x4b, 0xe8, 0xe4, 0xb4, 0xbc, 0x18, 0xf2, - 0xf9, 0x98, 0x4b, 0xcb, 0x72, 0x55, 0xf3, 0x21, 0x5d, 0xfd, 0x59, 0x12, 0x16, 0x30, 0xab, 0x24, - 0x5c, 0xbf, 0x4b, 0x6d, 0xcb, 0x98, 0xa0, 0x2e, 0xe4, 0x0d, 0xea, 0x98, 0x56, 0x64, 0x4f, 0x6d, - 0x5c, 0x72, 0xea, 0x4f, 0xa5, 0x82, 0x56, 0x3d, 0x90, 0xc4, 0x53, 0x25, 0xe8, 0x3d, 0xc8, 0x98, - 0xc4, 0xd6, 0x27, 0x32, 0xfd, 0xb8, 0x55, 0x11, 0xb5, 0x4a, 0x25, 0xa8, 0x55, 0x2a, 0x0d, 0x59, - 0xab, 0x60, 0x81, 0xe3, 0x79, 0xb2, 0xfe, 0x54, 0xd3, 0x7d, 0x9f, 0x0c, 0x47, 0xbe, 0xc8, 0x3d, - 0xd2, 0xb8, 0x30, 0xd4, 0x9f, 0x56, 0x25, 0x09, 0xdd, 0x83, 0xec, 0xb1, 0xe5, 0x98, 0xf4, 0x58, - 0xa6, 0x17, 0x57, 0x28, 0x95, 0x40, 0xf5, 0x84, 0x9d, 0xba, 0x17, 0x86, 0xc9, 0xec, 0xdd, 0xee, - 0xb4, 0x9b, 0x81, 0xbd, 0x25, 0xbf, 0xe3, 0xb4, 0xa9, 0xc3, 0xf6, 0x0a, 0x74, 0xda, 0xda, 0x66, - 0xb5, 0xb5, 0xbd, 0x8b, 0x99, 0xcd, 0x57, 0x4e, 0x4e, 0xcb, 0x4a, 0x08, 0xd9, 0xd4, 0x2d, 0x9b, - 0xe5, 0xbb, 0xb7, 0x20, 0x55, 0x6d, 0x7f, 0xa1, 0x24, 0x4b, 0xca, 0xc9, 0x69, 0xb9, 0x18, 0xb2, - 0xab, 0xce, 0x64, 0xba, 0x8d, 0x2e, 0xf6, 0xab, 0xfe, 0x6d, 0x0a, 0x8a, 0xbb, 0x23, 0x53, 0xf7, - 0x89, 0xf0, 0x49, 0x54, 0x86, 0xc2, 0x48, 0x77, 0x75, 0xdb, 0x26, 0xb6, 0xe5, 0x0d, 0x65, 0x15, - 0x16, 0x25, 0xa1, 0x8f, 0x5e, 0xd4, 0x8c, 0xb5, 0x1c, 0xf3, 0xb3, 0xdf, 0xfd, 0x97, 0xf5, 0x44, - 0x60, 0xd0, 0x5d, 0x58, 0xdc, 0x17, 0xa3, 0xd5, 0x74, 0x83, 0x2f, 0x6c, 0x8a, 0x2f, 0x6c, 0x25, - 0x6e, 0x61, 0xa3, 0xc3, 0xaa, 0xc8, 0x49, 0x56, 0xb9, 0x14, 0x5e, 0xd8, 0x8f, 0x36, 0xd1, 0x7d, - 0x98, 0x1f, 0x52, 0xc7, 0xf2, 0xa9, 0x7b, 0xfd, 0x2a, 0x04, 0x48, 0xf4, 0x0e, 0x2c, 0xb3, 0xc5, - 0x0d, 0xc6, 0xc3, 0xd9, 0xfc, 0xc4, 0x4a, 0xe2, 0xa5, 0xa1, 0xfe, 0x54, 0x76, 0x88, 0x19, 0x19, - 0xd5, 0x20, 0x43, 0x5d, 0x96, 0x12, 0x65, 0xf9, 0x70, 0xdf, 0xbd, 0x76, 0xb8, 0xa2, 0xd1, 0x61, - 0x32, 0x58, 0x88, 0xaa, 0x1f, 0xc2, 0xc2, 0xcc, 0x24, 0x58, 0x26, 0xd0, 0xad, 0xee, 0xf6, 0x9a, - 0xca, 0x1c, 0x2a, 0x42, 0xae, 0xde, 0x69, 0xf7, 0x5b, 0xed, 0x5d, 0x96, 0xca, 0x14, 0x21, 0x87, - 0x3b, 0xdb, 0xdb, 0xb5, 0x6a, 0xfd, 0x91, 0x92, 0x54, 0x2b, 0x50, 0x88, 0x68, 0x43, 0x8b, 0x00, - 0xbd, 0x7e, 0xa7, 0xab, 0x6d, 0xb6, 0x70, 0xaf, 0x2f, 0x12, 0xa1, 0x5e, 0xbf, 0x8a, 0xfb, 0x92, - 0x90, 0x50, 0xff, 0x23, 0x19, 0xac, 0xa8, 0xcc, 0x7d, 0x6a, 0xb3, 0xb9, 0xcf, 0x15, 0x83, 0x97, - 0xd9, 0xcf, 0xb4, 0x11, 0xe6, 0x40, 0x1f, 0x01, 0x70, 0xc7, 0x21, 0xa6, 0xa6, 0xfb, 0x72, 0xe1, - 0x4b, 0xcf, 0x19, 0xb9, 0x1f, 0x5c, 0x06, 0xe0, 0xbc, 0x44, 0x57, 0x7d, 0xf4, 0x03, 0x28, 0x1a, - 0x74, 0x38, 0xb2, 0x89, 0x14, 0x4e, 0x5d, 0x2b, 0x5c, 0x08, 0xf1, 0x55, 0x3f, 0x9a, 0x7d, 0xa5, - 0x67, 0xf3, 0xc3, 0xdf, 0x48, 0x04, 0x96, 0x89, 0x49, 0xb8, 0x8a, 0x90, 0xdb, 0xed, 0x36, 0xaa, - 0xfd, 0x56, 0xfb, 0xa1, 0x92, 0x40, 0x00, 0x59, 0x6e, 0xea, 0x86, 0x92, 0x64, 0x89, 0x62, 0xbd, - 0xb3, 0xd3, 0xdd, 0x6e, 0xf2, 0x94, 0x0b, 0xad, 0x80, 0x12, 0x18, 0x5b, 0xe3, 0x86, 0x6c, 0x36, - 0x94, 0x34, 0xba, 0x01, 0x4b, 0x21, 0x55, 0x4a, 0x66, 0xd0, 0x4d, 0x40, 0x21, 0x71, 0xaa, 0x22, - 0xab, 0xfe, 0x2a, 0x2c, 0xd5, 0xa9, 0xe3, 0xeb, 0x96, 0x13, 0x26, 0xd1, 0x1b, 0x6c, 0xd2, 0x92, - 0xa4, 0x59, 0xa6, 0x88, 0xe9, 0xb5, 0xa5, 0xf3, 0xb3, 0xf5, 0x42, 0x08, 0x6d, 0x35, 0xd8, 0x4c, - 0x83, 0x86, 0xc9, 0xf6, 0xef, 0xc8, 0x32, 0xb9, 0x71, 0x33, 0xb5, 0xf9, 0xf3, 0xb3, 0xf5, 0x54, - 0xb7, 0xd5, 0xc0, 0x8c, 0x86, 0x5e, 0x81, 0x3c, 0x79, 0x6a, 0xf9, 0x9a, 0xc1, 0x62, 0x38, 0x33, - 0x60, 0x06, 0xe7, 0x18, 0xa1, 0xce, 0x42, 0x76, 0x0d, 0xa0, 0x4b, 0x5d, 0x5f, 0xf6, 0xfc, 0x3e, - 0x64, 0x46, 0xd4, 0xe5, 0xe5, 0xf9, 0xa5, 0x97, 0x11, 0x0c, 0x2e, 0x1c, 0x15, 0x0b, 0xb0, 0xfa, - 0x57, 0x49, 0x80, 0xbe, 0xee, 0x1d, 0x4a, 0x25, 0x0f, 0x20, 0x1f, 0x5e, 0xec, 0xc8, 0x3a, 0xff, - 0xca, 0xd5, 0x0e, 0xc1, 0xe8, 0x7e, 0xe0, 0x6c, 0xa2, 0x3c, 0x88, 0xad, 0xd3, 0x82, 0x8e, 0xe2, - 0x32, 0xec, 0xd9, 0x1a, 0x80, 0x1d, 0x89, 0xc4, 0x75, 0xe5, 0xca, 0xb3, 0x4f, 0x54, 0xe7, 0xc7, - 0x82, 0x30, 0x9a, 0x4c, 0x30, 0x5f, 0x8f, 0xeb, 0xe4, 0xc2, 0x8a, 0x6c, 0xcd, 0xe1, 0xa9, 0x1c, - 0xfa, 0x0c, 0x0a, 0x6c, 0xde, 0x9a, 0xc7, 0x79, 0x32, 0xb7, 0xbc, 0xd4, 0x54, 0x42, 0x03, 0x86, - 0x51, 0xf8, 0x5d, 0x53, 0x60, 0xd1, 0x1d, 0x3b, 0x6c, 0xda, 0x52, 0x87, 0xfa, 0x27, 0x49, 0x78, - 0xb9, 0x4d, 0xfc, 0x63, 0xea, 0x1e, 0x56, 0x7d, 0x5f, 0x37, 0x0e, 0x86, 0xc4, 0x91, 0x46, 0x8e, - 0x64, 0xd6, 0x89, 0x99, 0xcc, 0x7a, 0x15, 0xe6, 0x75, 0xdb, 0xd2, 0x3d, 0x22, 0xd2, 0x91, 0x3c, - 0x0e, 0x9a, 0x2c, 0xff, 0x67, 0xd5, 0x04, 0xf1, 0x3c, 0x22, 0x0a, 0xfc, 0x3c, 0x9e, 0x12, 0xd0, - 0x8f, 0xe1, 0xa6, 0x4c, 0x3c, 0xf4, 0xb0, 0x2b, 0x96, 0xd9, 0x06, 0x37, 0x50, 0xcd, 0xd8, 0xf2, - 0x26, 0x7e, 0x70, 0x32, 0x33, 0x99, 0x92, 0x3b, 0x23, 0x5f, 0xe6, 0x39, 0x2b, 0x66, 0x0c, 0xab, - 0xf4, 0x10, 0x6e, 0x5d, 0x2a, 0xf2, 0xad, 0x2e, 0x10, 0xfe, 0x21, 0x09, 0xd0, 0xea, 0x56, 0x77, - 0xa4, 0x91, 0x1a, 0x90, 0xdd, 0xd7, 0x87, 0x96, 0x3d, 0xb9, 0x2a, 0x4e, 0x4d, 0xf1, 0x95, 0xaa, - 0x30, 0xc7, 0x26, 0x97, 0xc1, 0x52, 0x96, 0x17, 0x37, 0xe3, 0x3d, 0x87, 0xf8, 0x61, 0x71, 0xc3, - 0x5b, 0x6c, 0x18, 0xae, 0xee, 0x84, 0x0e, 0x26, 0x1a, 0x6c, 0x01, 0x06, 0xba, 0x4f, 0x8e, 0xf5, - 0x49, 0x10, 0x5c, 0x64, 0x13, 0x6d, 0xb1, 0xa2, 0xc7, 0x23, 0xee, 0x11, 0x31, 0x57, 0x33, 0xdc, - 0xa8, 0xd7, 0x8d, 0x07, 0x4b, 0xb8, 0xb0, 0x5d, 0x28, 0x5d, 0xfa, 0x84, 0x27, 0x36, 0x53, 0xd6, - 0xb7, 0xb2, 0xd1, 0x5d, 0x58, 0x98, 0x99, 0xe7, 0x73, 0x55, 0x65, 0xab, 0xfb, 0xf8, 0x7d, 0x25, - 0x2d, 0xbf, 0x3e, 0x54, 0xb2, 0xea, 0x1f, 0xa5, 0x44, 0x38, 0x90, 0x56, 0x8d, 0xbf, 0xf6, 0xcc, - 0xf1, 0x4d, 0x6c, 0x50, 0x5b, 0x6e, 0xd3, 0x37, 0xaf, 0x8e, 0x12, 0xac, 0x4a, 0xe1, 0x70, 0x1c, - 0x0a, 0xa2, 0x75, 0x28, 0x08, 0x2f, 0xd6, 0xd8, 0xb6, 0xe0, 0x66, 0x5d, 0xc0, 0x20, 0x48, 0x4c, - 0x12, 0xdd, 0x81, 0x45, 0x7e, 0x0b, 0xe1, 0x1d, 0x10, 0x53, 0x60, 0xd2, 0x1c, 0xb3, 0x10, 0x52, - 0x39, 0x6c, 0x07, 0x8a, 0x92, 0xa0, 0xf1, 0x0c, 0x35, 0xc3, 0x07, 0xf4, 0xce, 0x75, 0x03, 0x12, - 0x22, 0x3c, 0x71, 0x2d, 0x8c, 0xa6, 0x0d, 0xb5, 0x01, 0xb9, 0x60, 0xb0, 0x68, 0x15, 0x52, 0xfd, - 0x7a, 0x57, 0x99, 0x2b, 0x2d, 0x9d, 0x9c, 0x96, 0x0b, 0x01, 0xb9, 0x5f, 0xef, 0x32, 0xce, 0x6e, - 0xa3, 0xab, 0x24, 0x66, 0x39, 0xbb, 0x8d, 0x6e, 0x29, 0xcd, 0x32, 0x25, 0x75, 0x1f, 0x0a, 0x91, - 0x1e, 0xd0, 0xeb, 0x30, 0xdf, 0x6a, 0x3f, 0xc4, 0xcd, 0x5e, 0x4f, 0x99, 0x2b, 0xdd, 0x3c, 0x39, - 0x2d, 0xa3, 0x08, 0xb7, 0xe5, 0x0c, 0xd8, 0xfa, 0xa0, 0x57, 0x21, 0xbd, 0xd5, 0x61, 0x27, 0xb0, - 0x48, 0x89, 0x23, 0x88, 0x2d, 0xea, 0xf9, 0xa5, 0x1b, 0x32, 0x05, 0x8b, 0x2a, 0x56, 0x7f, 0x2f, - 0x01, 0x59, 0xb1, 0x99, 0x62, 0x17, 0xaa, 0x0a, 0xf3, 0x41, 0xbd, 0x2a, 0xca, 0x95, 0x37, 0x2f, - 0x2f, 0x2d, 0x2a, 0xb2, 0x12, 0x10, 0xee, 0x17, 0xc8, 0x95, 0x3e, 0x86, 0x62, 0x94, 0xf1, 0xad, - 0x9c, 0xef, 0xc7, 0x50, 0x60, 0xfe, 0x1d, 0x94, 0x18, 0x1b, 0x90, 0x15, 0x01, 0x21, 0x3c, 0x11, - 0x2e, 0xaf, 0x73, 0x24, 0x12, 0x3d, 0x80, 0x79, 0x51, 0x1b, 0x05, 0xd7, 0x94, 0x6b, 0x57, 0xef, - 0x22, 0x1c, 0xc0, 0xd5, 0xcf, 0x20, 0xdd, 0x25, 0xc4, 0x65, 0xb6, 0x77, 0xa8, 0x49, 0xa6, 0x87, - 0xa8, 0x2c, 0xeb, 0x4c, 0xd2, 0x6a, 0xb0, 0xb2, 0xce, 0x24, 0x2d, 0x33, 0xbc, 0x88, 0x49, 0x46, - 0x2e, 0x62, 0xfa, 0x50, 0x7c, 0x42, 0xac, 0xc1, 0x81, 0x4f, 0x4c, 0xae, 0xe8, 0x5d, 0x48, 0x8f, - 0x48, 0x38, 0xf8, 0xd5, 0x58, 0x07, 0x23, 0xc4, 0xc5, 0x1c, 0xc5, 0xe2, 0xc8, 0x31, 0x97, 0x96, - 0x97, 0xe3, 0xb2, 0xa5, 0xfe, 0x7d, 0x12, 0x16, 0x5b, 0x9e, 0x37, 0xd6, 0x1d, 0x23, 0xc8, 0xaf, - 0x3e, 0x9d, 0xcd, 0xaf, 0xde, 0x8a, 0x9d, 0xe1, 0x8c, 0xc8, 0xec, 0xfd, 0x92, 0x3c, 0xe3, 0x92, - 0xe1, 0x19, 0xa7, 0xfe, 0x7b, 0x22, 0xb8, 0x44, 0xba, 0x13, 0xd9, 0xee, 0xa5, 0xd5, 0x93, 0xd3, - 0xf2, 0x4a, 0x54, 0x13, 0xd9, 0x75, 0x0e, 0x1d, 0x7a, 0xec, 0xa0, 0xd7, 0x20, 0x83, 0x9b, 0xed, - 0xe6, 0x13, 0x25, 0x21, 0xdc, 0x73, 0x06, 0x84, 0x89, 0x43, 0x8e, 0x99, 0xa6, 0x6e, 0xb3, 0xdd, - 0x60, 0xf9, 0x50, 0x32, 0x46, 0x53, 0x97, 0x38, 0xa6, 0xe5, 0x0c, 0xd0, 0xeb, 0x90, 0x6d, 0xf5, - 0x7a, 0xbb, 0xbc, 0xcc, 0x7f, 0xf9, 0xe4, 0xb4, 0x7c, 0x63, 0x06, 0xc5, 0x2f, 0x10, 0x4d, 0x06, - 0x62, 0xc5, 0x08, 0xcb, 0x94, 0x62, 0x40, 0x2c, 0xcb, 0x15, 0x20, 0xdc, 0xe9, 0x57, 0xfb, 0xac, - 0xc2, 0x7f, 0x1e, 0x84, 0x29, 0xfb, 0x2b, 0xb7, 0xdb, 0x3f, 0x27, 0x41, 0xa9, 0x1a, 0x06, 0x19, - 0xf9, 0x8c, 0x2f, 0xeb, 0xbf, 0x3e, 0xe4, 0x46, 0xec, 0xcb, 0x22, 0x41, 0x2e, 0xf3, 0x20, 0xf6, - 0x79, 0xe6, 0x82, 0x5c, 0x05, 0x53, 0x9b, 0x54, 0xcd, 0xa1, 0xe5, 0x79, 0x16, 0x75, 0x04, 0x0d, - 0x87, 0x9a, 0x4a, 0xff, 0x99, 0x80, 0x1b, 0x31, 0x08, 0x74, 0x17, 0xd2, 0x2e, 0xb5, 0x83, 0x35, - 0xbc, 0x7d, 0xd9, 0xfd, 0x20, 0x13, 0xc5, 0x1c, 0x89, 0xd6, 0x00, 0xf4, 0xb1, 0x4f, 0x75, 0xde, - 0x3f, 0x5f, 0xbd, 0x1c, 0x8e, 0x50, 0xd0, 0x13, 0xc8, 0x7a, 0xc4, 0x70, 0x49, 0x90, 0xf1, 0x7e, - 0xf6, 0x7f, 0x1d, 0x7d, 0xa5, 0xc7, 0xd5, 0x60, 0xa9, 0xae, 0x54, 0x81, 0xac, 0xa0, 0x30, 0xb7, - 0x37, 0x75, 0x5f, 0x97, 0xb7, 0xc7, 0xfc, 0x9b, 0x79, 0x93, 0x6e, 0x0f, 0x02, 0x6f, 0xd2, 0xed, - 0x81, 0xfa, 0x37, 0x49, 0x80, 0xe6, 0x53, 0x9f, 0xb8, 0x8e, 0x6e, 0xd7, 0xab, 0xa8, 0x19, 0x89, - 0xfe, 0x62, 0xb6, 0x6f, 0xc7, 0x5e, 0x89, 0x87, 0x12, 0x95, 0x7a, 0x35, 0x26, 0xfe, 0xdf, 0x82, - 0xd4, 0xd8, 0x95, 0x2f, 0x6e, 0x22, 0x5b, 0xdd, 0xc5, 0xdb, 0x98, 0xd1, 0x50, 0x73, 0x1a, 0xb6, - 0x52, 0x97, 0xbf, 0xab, 0x45, 0x3a, 0x88, 0x0d, 0x5d, 0x6c, 0xe7, 0x1b, 0xba, 0x66, 0x10, 0x79, - 0x72, 0x14, 0xc5, 0xce, 0xaf, 0x57, 0xeb, 0xc4, 0xf5, 0x71, 0xd6, 0xd0, 0xd9, 0xff, 0xef, 0x14, - 0xdf, 0xde, 0x05, 0x98, 0x4e, 0x0d, 0xad, 0x41, 0xa6, 0xbe, 0xd9, 0xeb, 0x6d, 0x2b, 0x73, 0x22, - 0x80, 0x4f, 0x59, 0x9c, 0xac, 0xfe, 0x45, 0x12, 0x72, 0xf5, 0xaa, 0x3c, 0x56, 0xeb, 0xa0, 0xf0, - 0xa8, 0xc4, 0xef, 0xdc, 0xc9, 0xd3, 0x91, 0xe5, 0x4e, 0x64, 0x60, 0xb9, 0xa2, 0xf4, 0x5c, 0x64, - 0x22, 0x6c, 0xd4, 0x4d, 0x2e, 0x80, 0x30, 0x14, 0x89, 0x34, 0x82, 0x66, 0xe8, 0x41, 0x8c, 0x5f, - 0xbb, 0xda, 0x58, 0xa2, 0x88, 0x98, 0xb6, 0x3d, 0x5c, 0x08, 0x94, 0xd4, 0x75, 0x0f, 0x7d, 0x04, - 0x4b, 0x9e, 0x35, 0x70, 0x2c, 0x67, 0xa0, 0x05, 0xc6, 0xe3, 0x0f, 0x00, 0xb5, 0xe5, 0xf3, 0xb3, - 0xf5, 0x85, 0x9e, 0x60, 0x49, 0x1b, 0x2e, 0x48, 0x64, 0x9d, 0x9b, 0x12, 0x7d, 0x08, 0x8b, 0x11, - 0x51, 0x66, 0x45, 0x61, 0x76, 0xe5, 0xfc, 0x6c, 0xbd, 0x18, 0x4a, 0x3e, 0x22, 0x13, 0x5c, 0x0c, - 0x05, 0x1f, 0x11, 0x7e, 0x4b, 0xb2, 0x4f, 0x5d, 0x83, 0x68, 0x2e, 0xdf, 0xd3, 0xfc, 0x04, 0x4f, - 0xe3, 0x02, 0xa7, 0x89, 0x6d, 0xae, 0x3e, 0x86, 0x1b, 0x1d, 0xd7, 0x38, 0x20, 0x9e, 0x2f, 0x4c, - 0x21, 0xad, 0xf8, 0x19, 0xdc, 0xf6, 0x75, 0xef, 0x50, 0x3b, 0xb0, 0x3c, 0x9f, 0xba, 0x13, 0xcd, - 0x25, 0x3e, 0x71, 0x18, 0x5f, 0xe3, 0xaf, 0x86, 0xf2, 0x1a, 0xeb, 0x16, 0xc3, 0x6c, 0x09, 0x08, - 0x0e, 0x10, 0xdb, 0x0c, 0xa0, 0xb6, 0xa0, 0xc8, 0x8a, 0x89, 0x06, 0xd9, 0xd7, 0xc7, 0xb6, 0xcf, - 0x66, 0x0f, 0x36, 0x1d, 0x68, 0x2f, 0x7c, 0x4c, 0xe5, 0x6d, 0x3a, 0x10, 0x9f, 0xea, 0x8f, 0x40, - 0x69, 0x58, 0xde, 0x48, 0xf7, 0x8d, 0x83, 0xe0, 0x7e, 0x0e, 0x35, 0x40, 0x39, 0x20, 0xba, 0xeb, - 0xef, 0x11, 0xdd, 0xd7, 0x46, 0xc4, 0xb5, 0xa8, 0x79, 0xfd, 0x2a, 0x2f, 0x85, 0x22, 0x5d, 0x2e, - 0xa1, 0xfe, 0x57, 0x02, 0x00, 0xeb, 0xfb, 0x41, 0x46, 0xf6, 0x7d, 0x58, 0xf6, 0x1c, 0x7d, 0xe4, - 0x1d, 0x50, 0x5f, 0xb3, 0x1c, 0x9f, 0xb8, 0x47, 0xba, 0x2d, 0xaf, 0x59, 0x94, 0x80, 0xd1, 0x92, - 0x74, 0xf4, 0x2e, 0xa0, 0x43, 0x42, 0x46, 0x1a, 0xb5, 0x4d, 0x2d, 0x60, 0x8a, 0x37, 0xcd, 0x34, - 0x56, 0x18, 0xa7, 0x63, 0x9b, 0xbd, 0x80, 0x8e, 0x6a, 0xb0, 0xc6, 0xa6, 0x4f, 0x1c, 0xdf, 0xb5, - 0x88, 0xa7, 0xed, 0x53, 0x57, 0xf3, 0x6c, 0x7a, 0xac, 0xed, 0x53, 0xdb, 0xa6, 0xc7, 0xc4, 0x0d, - 0x6e, 0xb0, 0x4a, 0x36, 0x1d, 0x34, 0x05, 0x68, 0x93, 0xba, 0x3d, 0x9b, 0x1e, 0x6f, 0x06, 0x08, - 0x96, 0xb6, 0x4d, 0xe7, 0xec, 0x5b, 0xc6, 0x61, 0x90, 0xb6, 0x85, 0xd4, 0xbe, 0x65, 0x1c, 0xa2, - 0xd7, 0x61, 0x81, 0xd8, 0x84, 0x5f, 0x64, 0x08, 0x54, 0x86, 0xa3, 0x8a, 0x01, 0x91, 0x81, 0xd4, - 0xcf, 0x41, 0x69, 0x3a, 0x86, 0x3b, 0x19, 0x45, 0xd6, 0xfc, 0x5d, 0x40, 0x2c, 0x48, 0x6a, 0x36, - 0x35, 0x0e, 0xb5, 0xa1, 0xee, 0xe8, 0x03, 0x36, 0x2e, 0xf1, 0xd4, 0xa4, 0x30, 0xce, 0x36, 0x35, - 0x0e, 0x77, 0x24, 0x5d, 0xfd, 0x08, 0xa0, 0x37, 0x72, 0x89, 0x6e, 0x76, 0x58, 0x36, 0xc1, 0x4c, - 0xc7, 0x5b, 0x9a, 0x29, 0x9f, 0xea, 0xa8, 0x2b, 0xb7, 0xba, 0x22, 0x18, 0x8d, 0x90, 0xae, 0xfe, - 0x02, 0xdc, 0xe8, 0xda, 0xba, 0xc1, 0x9f, 0xad, 0xbb, 0xe1, 0xdb, 0x09, 0x7a, 0x00, 0x59, 0x01, - 0x95, 0x2b, 0x19, 0xbb, 0xdd, 0xa6, 0x7d, 0x6e, 0xcd, 0x61, 0x89, 0xaf, 0x15, 0x01, 0xa6, 0x7a, - 0xd4, 0x3f, 0x4b, 0x40, 0x3e, 0xd4, 0x8f, 0xca, 0xc0, 0x4a, 0x79, 0xe6, 0xde, 0x96, 0x23, 0x6b, - 0xef, 0x3c, 0x8e, 0x92, 0x50, 0x0b, 0x0a, 0xa3, 0x50, 0xfa, 0xca, 0x7c, 0x2e, 0x66, 0xd4, 0x38, - 0x2a, 0x8b, 0x3e, 0x86, 0x7c, 0xf0, 0x36, 0x1a, 0x44, 0xd8, 0xab, 0x9f, 0x52, 0xa7, 0x70, 0xf5, - 0x53, 0x80, 0x1f, 0x52, 0xcb, 0xe9, 0xd3, 0x43, 0xe2, 0xf0, 0xb7, 0x3e, 0x56, 0x13, 0x92, 0xc0, - 0x8a, 0xb2, 0xc5, 0x0b, 0x72, 0xb1, 0x04, 0xe1, 0x93, 0x97, 0x68, 0xaa, 0x7f, 0x9d, 0x84, 0x2c, - 0xa6, 0xd4, 0xaf, 0x57, 0x51, 0x19, 0xb2, 0x32, 0x4e, 0xf0, 0xf3, 0xa7, 0x96, 0x3f, 0x3f, 0x5b, - 0xcf, 0x88, 0x00, 0x91, 0x31, 0x78, 0x64, 0x88, 0x44, 0xf0, 0xe4, 0x65, 0x11, 0x1c, 0xdd, 0x85, - 0xa2, 0x04, 0x69, 0x07, 0xba, 0x77, 0x20, 0x0a, 0xb4, 0xda, 0xe2, 0xf9, 0xd9, 0x3a, 0x08, 0xe4, - 0x96, 0xee, 0x1d, 0x60, 0x10, 0x68, 0xf6, 0x8d, 0x9a, 0x50, 0xf8, 0x92, 0x5a, 0x8e, 0xe6, 0xf3, - 0x49, 0xc8, 0x2b, 0xbf, 0xd8, 0x75, 0x9c, 0x4e, 0x55, 0x3e, 0x7c, 0xc3, 0x97, 0xd3, 0xc9, 0x37, - 0x61, 0xc1, 0xa5, 0xd4, 0x17, 0x61, 0xcb, 0xa2, 0x8e, 0xbc, 0x4d, 0x28, 0xc7, 0x5e, 0x32, 0x53, - 0xea, 0x63, 0x89, 0xc3, 0x45, 0x37, 0xd2, 0x42, 0x77, 0x61, 0xc5, 0xd6, 0x3d, 0x5f, 0xe3, 0xf1, - 0xce, 0x9c, 0x6a, 0xcb, 0xf2, 0xad, 0x86, 0x18, 0x6f, 0x93, 0xb3, 0x02, 0x09, 0xf5, 0x1f, 0x13, - 0x50, 0x60, 0x93, 0xb1, 0xf6, 0x2d, 0x83, 0x25, 0x79, 0xdf, 0x3e, 0xf7, 0xb8, 0x05, 0x29, 0xc3, - 0x73, 0xa5, 0x51, 0xf9, 0xe1, 0x5b, 0xef, 0x61, 0xcc, 0x68, 0xe8, 0x73, 0xc8, 0xca, 0x5b, 0x0d, - 0x91, 0x76, 0xa8, 0xd7, 0xa7, 0xa3, 0xd2, 0x36, 0x52, 0x8e, 0xfb, 0xf2, 0x74, 0x74, 0xe2, 0x10, - 0xc0, 0x51, 0x12, 0xba, 0x09, 0x49, 0x43, 0x98, 0x4b, 0xfe, 0xb2, 0xa2, 0xde, 0xc6, 0x49, 0xc3, - 0x51, 0xff, 0x2e, 0x01, 0x0b, 0xd3, 0x0d, 0xcf, 0x3c, 0xe0, 0x36, 0xe4, 0xbd, 0xf1, 0x9e, 0x37, - 0xf1, 0x7c, 0x32, 0x0c, 0xde, 0x31, 0x43, 0x02, 0x6a, 0x41, 0x5e, 0xb7, 0x07, 0xd4, 0xb5, 0xfc, - 0x83, 0xa1, 0xac, 0x44, 0xe3, 0x53, 0x85, 0xa8, 0xce, 0x4a, 0x35, 0x10, 0xc1, 0x53, 0xe9, 0xe0, - 0xdc, 0x17, 0x8f, 0xdd, 0xfc, 0xdc, 0x7f, 0x0d, 0x8a, 0xb6, 0x3e, 0xe4, 0xd7, 0x3c, 0xbe, 0x35, - 0x14, 0xf3, 0x48, 0xe3, 0x82, 0xa4, 0xf5, 0xad, 0x21, 0x51, 0x55, 0xc8, 0x87, 0xca, 0xd0, 0x12, - 0x14, 0xaa, 0xcd, 0x9e, 0x76, 0x6f, 0xe3, 0x81, 0xf6, 0xb0, 0xbe, 0xa3, 0xcc, 0xc9, 0xdc, 0xf4, - 0xcf, 0x13, 0xb0, 0x20, 0xc3, 0x91, 0xcc, 0xf7, 0x5f, 0x87, 0x79, 0x57, 0xdf, 0xf7, 0x83, 0x8a, - 0x24, 0x2d, 0xbc, 0x9a, 0x45, 0x78, 0x56, 0x91, 0x30, 0x56, 0x7c, 0x45, 0x12, 0x79, 0x59, 0x4f, - 0x5d, 0xf9, 0xb2, 0x9e, 0xfe, 0xb9, 0xbc, 0xac, 0xab, 0xbf, 0x06, 0xb0, 0x69, 0xd9, 0xa4, 0x2f, - 0xee, 0x9a, 0xe2, 0xea, 0x4b, 0x96, 0xc3, 0xc9, 0x1b, 0xc7, 0x20, 0x87, 0x6b, 0x35, 0x30, 0xa3, - 0x31, 0xd6, 0xc0, 0x32, 0xe5, 0x66, 0xe4, 0xac, 0x87, 0x8c, 0x35, 0xb0, 0xcc, 0xf0, 0x2d, 0x29, - 0x7d, 0xdd, 0x5b, 0xd2, 0x69, 0x02, 0x96, 0x64, 0xee, 0x1a, 0x86, 0xdf, 0xb7, 0x21, 0x2f, 0xd2, - 0xd8, 0x69, 0x41, 0xc7, 0x5f, 0x93, 0x05, 0xae, 0xd5, 0xc0, 0x39, 0xc1, 0x6e, 0x99, 0x68, 0x1d, - 0x0a, 0x12, 0x1a, 0xf9, 0x15, 0x0e, 0x08, 0x52, 0x9b, 0x0d, 0xff, 0x7d, 0x48, 0xef, 0x5b, 0x36, - 0x91, 0x8e, 0x1e, 0x1b, 0x00, 0xa6, 0x06, 0xd8, 0x9a, 0xc3, 0x1c, 0x5d, 0xcb, 0x05, 0x97, 0x71, - 0x7c, 0x7c, 0xb2, 0xec, 0x8c, 0x8e, 0x4f, 0x54, 0xa0, 0x17, 0xc6, 0x27, 0x70, 0x6c, 0x7c, 0x82, - 0x2d, 0xc6, 0x27, 0xa1, 0xd1, 0xf1, 0x09, 0xd2, 0xcf, 0x65, 0x7c, 0xdb, 0x70, 0xb3, 0x66, 0xeb, - 0xc6, 0xa1, 0x6d, 0x79, 0x3e, 0x31, 0xa3, 0x11, 0x63, 0x03, 0xb2, 0x33, 0x49, 0xe7, 0x55, 0x97, - 0xb3, 0x12, 0xa9, 0xfe, 0x5b, 0x02, 0x8a, 0x5b, 0x44, 0xb7, 0xfd, 0x83, 0xe9, 0xd5, 0x90, 0x4f, - 0x3c, 0x5f, 0x1e, 0x56, 0xfc, 0x1b, 0x7d, 0x00, 0xb9, 0x30, 0x27, 0xb9, 0xf6, 0x95, 0x2c, 0x84, - 0xa2, 0xfb, 0x30, 0xcf, 0xf6, 0x18, 0x1d, 0x07, 0xc5, 0xce, 0x55, 0x0f, 0x30, 0x12, 0xc9, 0x0e, - 0x19, 0x97, 0xf0, 0x24, 0x84, 0xbb, 0x52, 0x06, 0x07, 0x4d, 0xf4, 0xff, 0xa1, 0xc8, 0xdf, 0x0f, - 0x82, 0x9c, 0x2b, 0x73, 0x9d, 0xce, 0x82, 0x78, 0x02, 0x14, 0xf9, 0xd6, 0xff, 0x24, 0x60, 0x65, - 0x47, 0x9f, 0xec, 0x11, 0x19, 0x36, 0x88, 0x89, 0x89, 0x41, 0x5d, 0x13, 0x75, 0xa3, 0xe1, 0xe6, - 0x8a, 0x17, 0xc5, 0x38, 0xe1, 0xf8, 0xa8, 0x13, 0x14, 0x60, 0xc9, 0x48, 0x01, 0xb6, 0x02, 0x19, - 0x87, 0x3a, 0x06, 0x91, 0xb1, 0x48, 0x34, 0x54, 0x2b, 0x1a, 0x6a, 0x4a, 0xe1, 0x63, 0x1f, 0x7f, - 0xaa, 0x6b, 0x53, 0x3f, 0xec, 0x0d, 0x7d, 0x0e, 0xa5, 0x5e, 0xb3, 0x8e, 0x9b, 0xfd, 0x5a, 0xe7, - 0x47, 0x5a, 0xaf, 0xba, 0xdd, 0xab, 0x6e, 0xdc, 0xd5, 0xba, 0x9d, 0xed, 0x2f, 0xee, 0xdd, 0xbf, - 0xfb, 0x81, 0x92, 0x28, 0x95, 0x4f, 0x4e, 0xcb, 0xb7, 0xdb, 0xd5, 0xfa, 0xb6, 0xd8, 0x31, 0x7b, - 0xf4, 0x69, 0x4f, 0xb7, 0x3d, 0x7d, 0xe3, 0x6e, 0x97, 0xda, 0x13, 0x86, 0x61, 0x6e, 0x5d, 0x8c, - 0x9e, 0x57, 0xd1, 0x63, 0x38, 0x71, 0xe9, 0x31, 0x3c, 0x3d, 0xcd, 0x93, 0x97, 0x9c, 0xe6, 0x9b, - 0xb0, 0x62, 0xb8, 0xd4, 0xf3, 0x34, 0x96, 0xfd, 0x13, 0xf3, 0x42, 0x7d, 0xf1, 0xd2, 0xf9, 0xd9, - 0xfa, 0x72, 0x9d, 0xf1, 0x7b, 0x9c, 0x2d, 0xd5, 0x2f, 0x1b, 0x11, 0x12, 0xef, 0x49, 0xfd, 0xfd, - 0x14, 0x4b, 0xa4, 0xac, 0x23, 0xcb, 0x26, 0x03, 0xe2, 0xa1, 0xc7, 0xb0, 0x64, 0xb8, 0xc4, 0x64, - 0x69, 0xbd, 0x6e, 0x6b, 0xde, 0x88, 0x18, 0xd2, 0xa9, 0xff, 0x5f, 0x6c, 0x4e, 0x13, 0x0a, 0x56, - 0xea, 0xa1, 0x54, 0x6f, 0x44, 0x0c, 0xbc, 0x68, 0xcc, 0xb4, 0xd1, 0x97, 0xb0, 0xe4, 0x11, 0xdb, - 0x72, 0xc6, 0x4f, 0x35, 0x83, 0x3a, 0x3e, 0x79, 0x1a, 0xbc, 0x5b, 0x5d, 0xa7, 0xb7, 0xd7, 0xdc, - 0x66, 0x52, 0x75, 0x21, 0x54, 0x43, 0xe7, 0x67, 0xeb, 0x8b, 0xb3, 0x34, 0xbc, 0x28, 0x35, 0xcb, - 0x76, 0xa9, 0x0d, 0x8b, 0xb3, 0xa3, 0x41, 0x2b, 0x72, 0xef, 0xf3, 0x10, 0x12, 0xec, 0x6d, 0x74, - 0x1b, 0x72, 0x2e, 0x19, 0x58, 0x9e, 0xef, 0x0a, 0x33, 0x33, 0x4e, 0x48, 0x61, 0x3b, 0x5f, 0xfc, - 0x14, 0xa7, 0xf4, 0x2b, 0x70, 0xa1, 0x47, 0xb6, 0x59, 0x4c, 0xcb, 0xd3, 0xf7, 0xa4, 0xca, 0x1c, - 0x0e, 0x9a, 0xcc, 0x07, 0xc7, 0x5e, 0x98, 0xa8, 0xf1, 0x6f, 0x46, 0xe3, 0x19, 0x85, 0xfc, 0x61, - 0x12, 0xcf, 0x19, 0x82, 0x5f, 0x38, 0xa6, 0x23, 0xbf, 0x70, 0x5c, 0x81, 0x8c, 0x4d, 0x8e, 0x88, - 0x2d, 0xce, 0x72, 0x2c, 0x1a, 0xef, 0xfc, 0x2c, 0x05, 0xf9, 0xf0, 0x8d, 0x86, 0x9d, 0x04, 0xed, - 0xe6, 0x93, 0xc0, 0x57, 0x43, 0x7a, 0x9b, 0x1c, 0xa3, 0xd7, 0xa6, 0x77, 0x4a, 0x9f, 0x8b, 0x47, - 0xe9, 0x90, 0x1d, 0xdc, 0x27, 0xbd, 0x01, 0xb9, 0x6a, 0xaf, 0xd7, 0x7a, 0xd8, 0x6e, 0x36, 0x94, - 0xaf, 0x12, 0xa5, 0x97, 0x4e, 0x4e, 0xcb, 0xcb, 0x21, 0xa8, 0xea, 0x09, 0x57, 0xe2, 0xa8, 0x7a, - 0xbd, 0xd9, 0xed, 0x37, 0x1b, 0xca, 0xb3, 0xe4, 0x45, 0x14, 0xbf, 0x23, 0xe1, 0x3f, 0x2d, 0xc9, - 0x77, 0x71, 0xb3, 0x5b, 0xc5, 0xac, 0xc3, 0xaf, 0x92, 0xe2, 0xaa, 0x6b, 0xda, 0xa3, 0x4b, 0x46, - 0xba, 0xcb, 0xfa, 0x5c, 0x0b, 0x7e, 0x62, 0xf5, 0x2c, 0x25, 0x7e, 0x7e, 0x30, 0x7d, 0x70, 0x22, - 0xba, 0x39, 0x61, 0xbd, 0xf1, 0x97, 0x3e, 0xae, 0x26, 0x75, 0xa1, 0xb7, 0x1e, 0x8b, 0x24, 0x4c, - 0x8b, 0x0a, 0xf3, 0x78, 0xb7, 0xdd, 0x66, 0xa0, 0x67, 0xe9, 0x0b, 0xb3, 0xc3, 0x63, 0x87, 0xd5, - 0xbf, 0xe8, 0x0e, 0xe4, 0x82, 0x87, 0x40, 0xe5, 0xab, 0xf4, 0x85, 0x01, 0xd5, 0x83, 0x57, 0x4c, - 0xde, 0xe1, 0xd6, 0x6e, 0x9f, 0xff, 0x02, 0xec, 0x59, 0xe6, 0x62, 0x87, 0x07, 0x63, 0xdf, 0xa4, - 0xc7, 0x0e, 0xdb, 0x81, 0xf2, 0x56, 0xed, 0xab, 0x8c, 0xb8, 0x82, 0x08, 0x31, 0xf2, 0x4a, 0xed, - 0x0d, 0xc8, 0xe1, 0xe6, 0x0f, 0xc5, 0x8f, 0xc5, 0x9e, 0x65, 0x2f, 0xe8, 0xc1, 0xe4, 0x4b, 0x62, - 0xc8, 0xde, 0x3a, 0xb8, 0xbb, 0x55, 0xe5, 0x26, 0xbf, 0x88, 0xea, 0xb8, 0xa3, 0x03, 0xdd, 0x21, - 0xe6, 0xf4, 0x37, 0x18, 0x21, 0xeb, 0x9d, 0x5f, 0x84, 0x5c, 0x90, 0x67, 0xa2, 0x35, 0xc8, 0x3e, - 0xe9, 0xe0, 0x47, 0x4d, 0xac, 0xcc, 0x09, 0x1b, 0x06, 0x9c, 0x27, 0xa2, 0x42, 0x28, 0xc3, 0xfc, - 0x4e, 0xb5, 0x5d, 0x7d, 0xd8, 0xc4, 0xc1, 0x85, 0x77, 0x00, 0x90, 0xc9, 0x52, 0x49, 0x91, 0x1d, - 0x84, 0x3a, 0x6b, 0xab, 0x5f, 0x7f, 0xb3, 0x36, 0xf7, 0xd3, 0x6f, 0xd6, 0xe6, 0x9e, 0x9d, 0xaf, - 0x25, 0xbe, 0x3e, 0x5f, 0x4b, 0xfc, 0xe4, 0x7c, 0x2d, 0xf1, 0xaf, 0xe7, 0x6b, 0x89, 0xbd, 0x2c, - 0x0f, 0xe9, 0xf7, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x62, 0x46, 0x73, 0x55, 0x80, 0x2e, 0x00, - 0x00, + // 4808 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x7a, 0x4d, 0x6c, 0x24, 0x49, + 0x56, 0xbf, 0xeb, 0xd3, 0x55, 0xaf, 0xca, 0x76, 0x76, 0xb4, 0xb7, 0xd7, 0x5d, 0xd3, 0x63, 0xd7, + 0xe4, 0x4c, 0xef, 0x7c, 0xec, 0xfc, 0x6b, 0xba, 0xdd, 0x33, 0xa3, 0xee, 0xe9, 0xff, 0x7c, 0xd4, + 0x97, 0xdb, 0xb5, 0x6d, 0x57, 0x95, 0xa2, 0xca, 0xdd, 0x3b, 0x07, 0x48, 0xa5, 0x33, 0xc3, 0xe5, + 0x1c, 0x67, 0x65, 0x14, 0x99, 0x59, 0x76, 0x17, 0x0b, 0xa2, 0xc5, 0x01, 0x90, 0x4f, 0x70, 0x62, + 0x25, 0x64, 0x2e, 0x70, 0x42, 0x48, 0x1c, 0x40, 0x42, 0x70, 0x61, 0x90, 0x38, 0xcc, 0x8d, 0x05, + 0x24, 0xb4, 0x02, 0xc9, 0x30, 0x3e, 0x70, 0x43, 0x70, 0x59, 0x71, 0x01, 0x09, 0xc5, 0x47, 0x66, + 0x65, 0xb9, 0xd3, 0x76, 0x0f, 0xb3, 0x17, 0x3b, 0xe3, 0xbd, 0xdf, 0x7b, 0xf1, 0xe2, 0x45, 0xc4, + 0x8b, 0xf7, 0x22, 0x0a, 0x0a, 0xfe, 0x64, 0x44, 0xbc, 0xca, 0xc8, 0xa5, 0x3e, 0x45, 0xc8, 0xa4, + 0xc6, 0x01, 0x71, 0x2b, 0xde, 0x91, 0xee, 0x0e, 0x0f, 0x2c, 0xbf, 0x72, 0x78, 0xb7, 0xb4, 0x36, + 0xa0, 0x74, 0x60, 0x93, 0xf7, 0x38, 0x62, 0x77, 0xbc, 0xf7, 0x9e, 0x6f, 0x0d, 0x89, 0xe7, 0xeb, + 0xc3, 0x91, 0x10, 0x2a, 0xad, 0x9e, 0x07, 0x98, 0x63, 0x57, 0xf7, 0x2d, 0xea, 0x48, 0xfe, 0xf2, + 0x80, 0x0e, 0x28, 0xff, 0x7c, 0x8f, 0x7d, 0x09, 0xaa, 0xba, 0x06, 0xf3, 0x4f, 0x88, 0xeb, 0x59, + 0xd4, 0x41, 0xcb, 0x90, 0xb1, 0x1c, 0x93, 0x3c, 0x5b, 0x49, 0x94, 0x13, 0x6f, 0xa5, 0xb1, 0x68, + 0xa8, 0x77, 0x00, 0x5a, 0xec, 0xa3, 0xe9, 0xf8, 0xee, 0x04, 0x29, 0x90, 0x3a, 0x20, 0x13, 0x8e, + 0xc8, 0x63, 0xf6, 0xc9, 0x28, 0x87, 0xba, 0xbd, 0x92, 0x14, 0x94, 0x43, 0xdd, 0x56, 0xbf, 0x4e, + 0x40, 0xa1, 0xea, 0x38, 0xd4, 0xe7, 0xbd, 0x7b, 0x08, 0x41, 0xda, 0xd1, 0x87, 0x44, 0x0a, 0xf1, + 0x6f, 0x54, 0x87, 0xac, 0xad, 0xef, 0x12, 0xdb, 0x5b, 0x49, 0x96, 0x53, 0x6f, 0x15, 0xd6, 0xbf, + 0x5f, 0x79, 0x71, 0xc8, 0x95, 0x88, 0x92, 0xca, 0x16, 0x47, 0x73, 0x23, 0xb0, 0x14, 0x45, 0x9f, + 0xc0, 0xbc, 0xe5, 0x98, 0x96, 0x41, 0xbc, 0x95, 0x34, 0xd7, 0xb2, 0x1a, 0xa7, 0x65, 0x6a, 0x7d, + 0x2d, 0xfd, 0xd5, 0xe9, 0xda, 0x1c, 0x0e, 0x84, 0x4a, 0x0f, 0xa0, 0x10, 0x51, 0x1b, 0x33, 0xb6, + 0x65, 0xc8, 0x1c, 0xea, 0xf6, 0x98, 0xc8, 0xd1, 0x89, 0xc6, 0x47, 0xc9, 0xfb, 0x09, 0xf5, 0x01, + 0x2c, 0x3c, 0x22, 0x0e, 0x71, 0x2d, 0xa3, 0xe7, 0xbb, 0x96, 0x33, 0x60, 0x83, 0x3c, 0xb0, 0x1c, + 0x33, 0x18, 0x24, 0xfb, 0x8e, 0x17, 0x57, 0x1f, 0xc2, 0x92, 0x14, 0x6d, 0x58, 0x9e, 0xe1, 0x12, + 0x9f, 0x5c, 0x2d, 0x9c, 0x0a, 0x84, 0x7f, 0x37, 0x11, 0x4a, 0x63, 0xe2, 0xd1, 0xb1, 0x6b, 0x10, + 0xf4, 0x01, 0xa4, 0x3c, 0xdf, 0xe5, 0xc2, 0x85, 0xf5, 0xd7, 0xe2, 0x5c, 0x30, 0x63, 0xea, 0xe6, + 0x1c, 0x66, 0x78, 0x54, 0x85, 0x9c, 0x29, 0x0d, 0xe0, 0x7d, 0x14, 0xd6, 0x5f, 0xbf, 0x44, 0x36, + 0xb0, 0x75, 0x73, 0x0e, 0x87, 0x62, 0x35, 0x80, 0x9c, 0x2b, 0xad, 0x50, 0x7f, 0x9c, 0x80, 0x7c, + 0x60, 0x92, 0x87, 0xde, 0x86, 0xbc, 0xa3, 0x3b, 0x54, 0x33, 0x46, 0x63, 0x8f, 0x5b, 0x96, 0xaa, + 0x15, 0xcf, 0x4e, 0xd7, 0x72, 0x6d, 0xdd, 0xa1, 0xf5, 0xee, 0x8e, 0x87, 0x73, 0x8c, 0x5d, 0x1f, + 0x8d, 0x3d, 0xf4, 0x1a, 0x14, 0x87, 0x64, 0x48, 0xdd, 0x89, 0xb6, 0x3b, 0xf1, 0x89, 0x27, 0xc7, + 0x5b, 0x10, 0xb4, 0x1a, 0x23, 0xa1, 0x8f, 0x61, 0x7e, 0x20, 0xcc, 0x58, 0x49, 0xf1, 0x89, 0xbe, + 0xcc, 0xd2, 0xc0, 0x08, 0x1c, 0xc8, 0xa8, 0xbf, 0x9d, 0x80, 0xe5, 0x90, 0x4a, 0x7e, 0x69, 0x6c, + 0xb9, 0x64, 0x48, 0x1c, 0xdf, 0x43, 0x1f, 0x40, 0xd6, 0xb6, 0x86, 0x96, 0xef, 0x49, 0xe7, 0xbd, + 0x1a, 0xa7, 0x36, 0x1c, 0x14, 0x96, 0x60, 0x54, 0x85, 0xa2, 0x4b, 0x3c, 0xe2, 0x1e, 0x8a, 0xb5, + 0x29, 0xbd, 0x77, 0x85, 0xf0, 0x8c, 0x88, 0xba, 0x01, 0xb9, 0xae, 0xad, 0xfb, 0x7b, 0xd4, 0x1d, + 0x22, 0x15, 0x8a, 0xba, 0x6b, 0xec, 0x5b, 0x3e, 0x31, 0xfc, 0xb1, 0x1b, 0xec, 0x93, 0x19, 0x1a, + 0xba, 0x01, 0x49, 0x2a, 0x3a, 0xca, 0xd7, 0xb2, 0x67, 0xa7, 0x6b, 0xc9, 0x4e, 0x0f, 0x27, 0xa9, + 0xa7, 0x3e, 0x84, 0x6b, 0x5d, 0x7b, 0x3c, 0xb0, 0x9c, 0x06, 0xf1, 0x0c, 0xd7, 0x1a, 0x31, 0xed, + 0x6c, 0x39, 0xb1, 0x68, 0x12, 0x2c, 0x27, 0xf6, 0x1d, 0x6e, 0xc2, 0xe4, 0x74, 0x13, 0xaa, 0xbf, + 0x99, 0x84, 0x6b, 0x4d, 0x67, 0x60, 0x39, 0x24, 0x2a, 0x7d, 0x1b, 0x16, 0x09, 0x27, 0x6a, 0x87, + 0x22, 0x30, 0x48, 0x3d, 0x0b, 0x82, 0x1a, 0x44, 0x8b, 0xd6, 0xb9, 0x1d, 0x7c, 0x37, 0x6e, 0xf8, + 0x2f, 0x68, 0x8f, 0xdd, 0xc7, 0x4d, 0x98, 0x1f, 0xf1, 0x41, 0x78, 0x72, 0x7a, 0x6f, 0xc7, 0xe9, + 0x7a, 0x61, 0x9c, 0xc1, 0x76, 0x96, 0xb2, 0xdf, 0x66, 0x3b, 0xff, 0x71, 0x12, 0x96, 0xda, 0xd4, + 0x9c, 0xf1, 0x43, 0x09, 0x72, 0xfb, 0xd4, 0xf3, 0x23, 0xa1, 0x2b, 0x6c, 0xa3, 0xfb, 0x90, 0x1b, + 0xc9, 0xe9, 0x93, 0xb3, 0x7f, 0x2b, 0xde, 0x64, 0x81, 0xc1, 0x21, 0x1a, 0x3d, 0x84, 0x7c, 0xb0, + 0x65, 0xd8, 0x68, 0x5f, 0x62, 0xe1, 0x4c, 0xf1, 0xe8, 0x63, 0xc8, 0x8a, 0x49, 0x58, 0x49, 0x73, + 0xc9, 0xdb, 0x2f, 0xe5, 0x73, 0x2c, 0x85, 0xd0, 0x23, 0xc8, 0xf9, 0xb6, 0xa7, 0x59, 0xce, 0x1e, + 0x5d, 0xc9, 0x70, 0x05, 0x6b, 0x71, 0x0a, 0x98, 0x23, 0xfa, 0x5b, 0xbd, 0x96, 0xb3, 0x47, 0x6b, + 0x85, 0xb3, 0xd3, 0xb5, 0x79, 0xd9, 0xc0, 0xf3, 0xbe, 0xed, 0xb1, 0x0f, 0xf5, 0x77, 0x12, 0x50, + 0x88, 0xa0, 0xd0, 0xab, 0x00, 0xbe, 0x3b, 0xf6, 0x7c, 0xcd, 0xa5, 0xd4, 0xe7, 0xce, 0x2a, 0xe2, + 0x3c, 0xa7, 0x60, 0x4a, 0x7d, 0x54, 0x81, 0xeb, 0x06, 0x71, 0x7d, 0xcd, 0xf2, 0xbc, 0x31, 0x71, + 0x35, 0x6f, 0xbc, 0xfb, 0x05, 0x31, 0x7c, 0xee, 0xb8, 0x22, 0xbe, 0xc6, 0x58, 0x2d, 0xce, 0xe9, + 0x09, 0x06, 0xba, 0x07, 0x37, 0xa2, 0xf8, 0xd1, 0x78, 0xd7, 0xb6, 0x0c, 0x8d, 0x4d, 0x66, 0x8a, + 0x8b, 0x5c, 0x9f, 0x8a, 0x74, 0x39, 0xef, 0x31, 0x99, 0xa8, 0x3f, 0x4d, 0x80, 0x82, 0xf5, 0x3d, + 0x7f, 0x9b, 0x0c, 0x77, 0x89, 0xdb, 0xf3, 0x75, 0x7f, 0xec, 0xa1, 0x1b, 0x90, 0xb5, 0x89, 0x6e, + 0x12, 0x11, 0x1d, 0x73, 0x58, 0xb6, 0xd0, 0x0e, 0xdb, 0xc1, 0xba, 0xb1, 0xaf, 0xef, 0x5a, 0xb6, + 0xe5, 0x4f, 0xb8, 0x29, 0x8b, 0xf1, 0x4b, 0xf8, 0xbc, 0xce, 0x0a, 0x8e, 0x08, 0xe2, 0x19, 0x35, + 0x68, 0x05, 0xe6, 0x87, 0xc4, 0xf3, 0xf4, 0x01, 0xe1, 0x96, 0xe6, 0x71, 0xd0, 0x54, 0x1f, 0x42, + 0x31, 0x2a, 0x87, 0x0a, 0x30, 0xbf, 0xd3, 0x7e, 0xdc, 0xee, 0x3c, 0x6d, 0x2b, 0x73, 0x68, 0x09, + 0x0a, 0x3b, 0x6d, 0xdc, 0xac, 0xd6, 0x37, 0xab, 0xb5, 0xad, 0xa6, 0x92, 0x40, 0x0b, 0x90, 0x9f, + 0x36, 0x93, 0xea, 0x9f, 0x26, 0x00, 0x98, 0xbb, 0xe5, 0xa0, 0x3e, 0x82, 0x8c, 0xe7, 0xeb, 0xbe, + 0x58, 0x95, 0x8b, 0xeb, 0x6f, 0x5c, 0x34, 0x87, 0xd2, 0x5e, 0xf6, 0x8f, 0x60, 0x21, 0x12, 0xb5, + 0x30, 0x39, 0x63, 0x21, 0x0b, 0x10, 0xba, 0x69, 0xba, 0xd2, 0x70, 0xfe, 0xad, 0x3e, 0x84, 0x0c, + 0x97, 0x9e, 0x35, 0x37, 0x07, 0xe9, 0x06, 0xfb, 0x4a, 0xa0, 0x3c, 0x64, 0x70, 0xb3, 0xda, 0xf8, + 0x5c, 0x49, 0x22, 0x05, 0x8a, 0x8d, 0x56, 0xaf, 0xde, 0x69, 0xb7, 0x9b, 0xf5, 0x7e, 0xb3, 0xa1, + 0xa4, 0xd4, 0xdb, 0x90, 0x69, 0x0d, 0x99, 0xe6, 0x5b, 0x6c, 0xc9, 0xef, 0x11, 0x97, 0x38, 0x46, + 0xb0, 0x93, 0xa6, 0x04, 0xf5, 0x27, 0x79, 0xc8, 0x6c, 0xd3, 0xb1, 0xe3, 0xa3, 0xf5, 0x48, 0xd8, + 0x5a, 0x8c, 0x3f, 0xcb, 0x39, 0xb0, 0xd2, 0x9f, 0x8c, 0x88, 0x0c, 0x6b, 0x37, 0x20, 0x2b, 0x36, + 0x87, 0x1c, 0x8e, 0x6c, 0x31, 0xba, 0xaf, 0xbb, 0x03, 0xe2, 0xcb, 0xf1, 0xc8, 0x16, 0x7a, 0x8b, + 0x9d, 0x58, 0xba, 0x49, 0x1d, 0x7b, 0xc2, 0xf7, 0x50, 0x4e, 0x1c, 0x4b, 0x98, 0xe8, 0x66, 0xc7, + 0xb1, 0x27, 0x38, 0xe4, 0xa2, 0x4d, 0x28, 0xee, 0x5a, 0x8e, 0xa9, 0xd1, 0x91, 0x08, 0xf2, 0x99, + 0x8b, 0x77, 0x9c, 0xb0, 0xaa, 0x66, 0x39, 0x66, 0x47, 0x80, 0x71, 0x61, 0x77, 0xda, 0x40, 0x6d, + 0x58, 0x3c, 0xa4, 0xf6, 0x78, 0x48, 0x42, 0x5d, 0x59, 0xae, 0xeb, 0xcd, 0x8b, 0x75, 0x3d, 0xe1, + 0xf8, 0x40, 0xdb, 0xc2, 0x61, 0xb4, 0x89, 0x1e, 0xc3, 0x82, 0x3f, 0x1c, 0xed, 0x79, 0xa1, 0xba, + 0x79, 0xae, 0xee, 0x7b, 0x97, 0x38, 0x8c, 0xc1, 0x03, 0x6d, 0x45, 0x3f, 0xd2, 0x2a, 0xfd, 0x7a, + 0x0a, 0x0a, 0x11, 0xcb, 0x51, 0x0f, 0x0a, 0x23, 0x97, 0x8e, 0xf4, 0x01, 0x3f, 0xa8, 0xe4, 0x5c, + 0xdc, 0x7d, 0xa9, 0x51, 0x57, 0xba, 0x53, 0x41, 0x1c, 0xd5, 0xa2, 0x9e, 0x24, 0xa1, 0x10, 0x61, + 0xa2, 0x77, 0x20, 0x87, 0xbb, 0xb8, 0xf5, 0xa4, 0xda, 0x6f, 0x2a, 0x73, 0xa5, 0x5b, 0xc7, 0x27, + 0xe5, 0x15, 0xae, 0x2d, 0xaa, 0xa0, 0xeb, 0x5a, 0x87, 0x6c, 0xe9, 0xbd, 0x05, 0xf3, 0x01, 0x34, + 0x51, 0x7a, 0xe5, 0xf8, 0xa4, 0xfc, 0xdd, 0xf3, 0xd0, 0x08, 0x12, 0xf7, 0x36, 0xab, 0xb8, 0xd9, + 0x50, 0x92, 0xf1, 0x48, 0xdc, 0xdb, 0xd7, 0x5d, 0x62, 0xa2, 0xef, 0x41, 0x56, 0x02, 0x53, 0xa5, + 0xd2, 0xf1, 0x49, 0xf9, 0xc6, 0x79, 0xe0, 0x14, 0x87, 0x7b, 0x5b, 0xd5, 0x27, 0x4d, 0x25, 0x1d, + 0x8f, 0xc3, 0x3d, 0x5b, 0x3f, 0x24, 0xe8, 0x0d, 0xc8, 0x08, 0x58, 0xa6, 0x74, 0xf3, 0xf8, 0xa4, + 0xfc, 0x9d, 0x17, 0xd4, 0x31, 0x54, 0x69, 0xe5, 0xb7, 0xfe, 0x60, 0x75, 0xee, 0x2f, 0xff, 0x70, + 0x55, 0x39, 0xcf, 0x2e, 0xfd, 0x77, 0x02, 0x16, 0x66, 0xa6, 0x1c, 0xa9, 0x90, 0x75, 0xa8, 0x41, + 0x47, 0xe2, 0xfc, 0xca, 0xd5, 0xe0, 0xec, 0x74, 0x2d, 0xdb, 0xa6, 0x75, 0x3a, 0x9a, 0x60, 0xc9, + 0x41, 0x8f, 0xcf, 0x9d, 0xc0, 0xf7, 0x5e, 0x72, 0x3d, 0xc5, 0x9e, 0xc1, 0x9f, 0xc2, 0x82, 0xe9, + 0x5a, 0x87, 0xc4, 0xd5, 0x0c, 0xea, 0xec, 0x59, 0x03, 0x79, 0x36, 0x95, 0xe2, 0x74, 0x36, 0x38, + 0x10, 0x17, 0x85, 0x40, 0x9d, 0xe3, 0xbf, 0xc5, 0xe9, 0x5b, 0x7a, 0x02, 0xc5, 0xe8, 0x0a, 0x65, + 0xc7, 0x89, 0x67, 0xfd, 0x32, 0x91, 0xf9, 0x20, 0xcf, 0x1e, 0x71, 0x9e, 0x51, 0x44, 0x36, 0xf8, + 0x26, 0xa4, 0x87, 0xd4, 0x14, 0x7a, 0x16, 0x6a, 0xd7, 0x59, 0x12, 0xf0, 0x4f, 0xa7, 0x6b, 0x05, + 0xea, 0x55, 0x36, 0x2c, 0x9b, 0x6c, 0x53, 0x93, 0x60, 0x0e, 0x50, 0x0f, 0x21, 0xcd, 0x42, 0x05, + 0x7a, 0x05, 0xd2, 0xb5, 0x56, 0xbb, 0xa1, 0xcc, 0x95, 0xae, 0x1d, 0x9f, 0x94, 0x17, 0xb8, 0x4b, + 0x18, 0x83, 0xad, 0x5d, 0xb4, 0x06, 0xd9, 0x27, 0x9d, 0xad, 0x9d, 0x6d, 0xb6, 0xbc, 0xae, 0x1f, + 0x9f, 0x94, 0x97, 0x42, 0xb6, 0x70, 0x1a, 0x7a, 0x15, 0x32, 0xfd, 0xed, 0xee, 0x46, 0x4f, 0x49, + 0x96, 0xd0, 0xf1, 0x49, 0x79, 0x31, 0xe4, 0x73, 0x9b, 0x4b, 0xd7, 0xe4, 0xac, 0xe6, 0x43, 0xba, + 0xfa, 0xb3, 0x24, 0x2c, 0x60, 0x56, 0x9b, 0xb9, 0x7e, 0x97, 0xda, 0x96, 0x31, 0x41, 0x5d, 0xc8, + 0x1b, 0xd4, 0x31, 0xad, 0xc8, 0x9e, 0x5a, 0xbf, 0xe0, 0xd4, 0x9f, 0x4a, 0x05, 0xad, 0x7a, 0x20, + 0x89, 0xa7, 0x4a, 0xd0, 0x7b, 0x90, 0x31, 0x89, 0xad, 0x4f, 0x64, 0xfa, 0x71, 0xb3, 0x22, 0xaa, + 0xbf, 0x4a, 0x50, 0xfd, 0x55, 0x1a, 0xb2, 0xfa, 0xc3, 0x02, 0xc7, 0xd3, 0x6c, 0xfd, 0x99, 0xa6, + 0xfb, 0x3e, 0x19, 0x8e, 0x7c, 0x91, 0x7b, 0xa4, 0x71, 0x61, 0xa8, 0x3f, 0xab, 0x4a, 0x12, 0xba, + 0x0b, 0xd9, 0x23, 0xcb, 0x31, 0xe9, 0x91, 0x4c, 0x2f, 0x2e, 0x51, 0x2a, 0x81, 0xea, 0x31, 0x3b, + 0x75, 0xcf, 0x99, 0xc9, 0xfc, 0xdd, 0xee, 0xb4, 0x9b, 0x81, 0xbf, 0x25, 0xbf, 0xe3, 0xb4, 0xa9, + 0xc3, 0xf6, 0x0a, 0x74, 0xda, 0xda, 0x46, 0xb5, 0xb5, 0xb5, 0x83, 0x99, 0xcf, 0x97, 0x8f, 0x4f, + 0xca, 0x4a, 0x08, 0xd9, 0xd0, 0x2d, 0x9b, 0xe5, 0xbb, 0x37, 0x21, 0x55, 0x6d, 0x7f, 0xae, 0x24, + 0x4b, 0xca, 0xf1, 0x49, 0xb9, 0x18, 0xb2, 0xab, 0xce, 0x64, 0xba, 0x8d, 0xce, 0xf7, 0xab, 0xfe, + 0x6d, 0x0a, 0x8a, 0x3b, 0x23, 0x53, 0xf7, 0x89, 0x58, 0x93, 0xa8, 0x0c, 0x85, 0x91, 0xee, 0xea, + 0xb6, 0x4d, 0x6c, 0xcb, 0x1b, 0xca, 0xba, 0x36, 0x4a, 0x42, 0x0f, 0x5e, 0xd6, 0x8d, 0xb5, 0x1c, + 0x5b, 0x67, 0x3f, 0xfe, 0x97, 0xb5, 0x44, 0xe0, 0xd0, 0x1d, 0x58, 0xdc, 0x13, 0xd6, 0x6a, 0xba, + 0xc1, 0x27, 0x36, 0xc5, 0x27, 0xb6, 0x12, 0x37, 0xb1, 0x51, 0xb3, 0x2a, 0x72, 0x90, 0x55, 0x2e, + 0x85, 0x17, 0xf6, 0xa2, 0x4d, 0x74, 0x0f, 0xe6, 0x87, 0xd4, 0xb1, 0x7c, 0xea, 0x5e, 0x3d, 0x0b, + 0x01, 0x12, 0xbd, 0x03, 0xd7, 0xd8, 0xe4, 0x06, 0xf6, 0x70, 0x36, 0x3f, 0xb1, 0x92, 0x78, 0x69, + 0xa8, 0x3f, 0x93, 0x1d, 0x62, 0x46, 0x46, 0x35, 0xc8, 0x50, 0x97, 0xa5, 0x44, 0x59, 0x6e, 0xee, + 0xbb, 0x57, 0x9a, 0x2b, 0x1a, 0x1d, 0x26, 0x83, 0x85, 0xa8, 0xfa, 0x21, 0x2c, 0xcc, 0x0c, 0x82, + 0x65, 0x02, 0xdd, 0xea, 0x4e, 0xaf, 0xa9, 0xcc, 0xa1, 0x22, 0xe4, 0xea, 0x9d, 0x76, 0xbf, 0xd5, + 0xde, 0x61, 0xa9, 0x4c, 0x11, 0x72, 0xb8, 0xb3, 0xb5, 0x55, 0xab, 0xd6, 0x1f, 0x2b, 0x49, 0xb5, + 0x02, 0x85, 0x88, 0x36, 0xb4, 0x08, 0xd0, 0xeb, 0x77, 0xba, 0xda, 0x46, 0x0b, 0xf7, 0xfa, 0x22, + 0x11, 0xea, 0xf5, 0xab, 0xb8, 0x2f, 0x09, 0x09, 0xf5, 0x3f, 0x92, 0xc1, 0x8c, 0xca, 0xdc, 0xa7, + 0x36, 0x9b, 0xfb, 0x5c, 0x62, 0xbc, 0xcc, 0x7e, 0xa6, 0x8d, 0x30, 0x07, 0x7a, 0x00, 0xc0, 0x17, + 0x0e, 0x31, 0x35, 0xdd, 0x97, 0x13, 0x5f, 0x7a, 0xc1, 0xc9, 0xfd, 0xe0, 0x7a, 0x05, 0xe7, 0x25, + 0xba, 0xea, 0xa3, 0x8f, 0xa1, 0x68, 0xd0, 0xe1, 0xc8, 0x26, 0x52, 0x38, 0x75, 0xa5, 0x70, 0x21, + 0xc4, 0x57, 0xfd, 0x68, 0xf6, 0x95, 0x9e, 0xcd, 0x0f, 0x7f, 0x23, 0x11, 0x78, 0x26, 0x26, 0xe1, + 0x2a, 0x42, 0x6e, 0xa7, 0xdb, 0xa8, 0xf6, 0x5b, 0xed, 0x47, 0x4a, 0x02, 0x01, 0x64, 0xb9, 0xab, + 0x1b, 0x4a, 0x92, 0x25, 0x8a, 0xf5, 0xce, 0x76, 0x77, 0xab, 0xc9, 0x53, 0x2e, 0xb4, 0x0c, 0x4a, + 0xe0, 0x6c, 0x8d, 0x3b, 0xb2, 0xd9, 0x50, 0xd2, 0xe8, 0x3a, 0x2c, 0x85, 0x54, 0x29, 0x99, 0x41, + 0x37, 0x00, 0x85, 0xc4, 0xa9, 0x8a, 0xac, 0xfa, 0xab, 0xb0, 0x54, 0xa7, 0x8e, 0xaf, 0x5b, 0x4e, + 0x98, 0x44, 0xaf, 0xb3, 0x41, 0x4b, 0x92, 0x66, 0xc9, 0x5b, 0x8a, 0xda, 0xd2, 0xd9, 0xe9, 0x5a, + 0x21, 0x84, 0xb6, 0x1a, 0x6c, 0xa4, 0x41, 0xc3, 0x64, 0xfb, 0x77, 0x64, 0x99, 0xdc, 0xb9, 0x99, + 0xda, 0xfc, 0xd9, 0xe9, 0x5a, 0xaa, 0xdb, 0x6a, 0x60, 0x46, 0x43, 0xaf, 0x40, 0x9e, 0x3c, 0xb3, + 0x7c, 0xcd, 0x60, 0x31, 0x9c, 0x39, 0x30, 0x83, 0x73, 0x8c, 0x50, 0x67, 0x21, 0xbb, 0x06, 0xd0, + 0xa5, 0xae, 0x2f, 0x7b, 0x7e, 0x1f, 0x32, 0x23, 0xea, 0xf2, 0xf2, 0xfc, 0xc2, 0xeb, 0x1d, 0x06, + 0x17, 0x0b, 0x15, 0x0b, 0xb0, 0xfa, 0x57, 0x49, 0x80, 0xbe, 0xee, 0x1d, 0x48, 0x25, 0xf7, 0x21, + 0x1f, 0x5e, 0x95, 0xc9, 0x3a, 0xff, 0xd2, 0xd9, 0x0e, 0xc1, 0xe8, 0x5e, 0xb0, 0xd8, 0x44, 0x79, + 0x10, 0x5b, 0xa7, 0x05, 0x1d, 0xc5, 0x65, 0xd8, 0xb3, 0x35, 0x00, 0x3b, 0x12, 0x89, 0xeb, 0xca, + 0x99, 0x67, 0x9f, 0xa8, 0xce, 0x8f, 0x05, 0xe1, 0x34, 0x99, 0x60, 0xc6, 0xde, 0x6c, 0x9c, 0x9b, + 0x91, 0xcd, 0x39, 0x3c, 0x95, 0x43, 0x9f, 0x42, 0x81, 0x8d, 0x5b, 0xf3, 0x38, 0x4f, 0xe6, 0x96, + 0x17, 0xba, 0x4a, 0x68, 0xc0, 0x30, 0x0a, 0xbf, 0x6b, 0x0a, 0x2c, 0xba, 0x63, 0x87, 0x0d, 0x5b, + 0xea, 0x50, 0xff, 0x24, 0x09, 0xdf, 0x6d, 0x13, 0xff, 0x88, 0xba, 0x07, 0x55, 0xdf, 0xd7, 0x8d, + 0xfd, 0x21, 0x71, 0xa4, 0x93, 0x23, 0x99, 0x75, 0x62, 0x26, 0xb3, 0x5e, 0x81, 0x79, 0xdd, 0xb6, + 0x74, 0x8f, 0x88, 0x74, 0x24, 0x8f, 0x83, 0x26, 0xcb, 0xff, 0x59, 0x35, 0x41, 0x3c, 0x8f, 0x88, + 0x02, 0x3f, 0x8f, 0xa7, 0x04, 0xf4, 0x23, 0xb8, 0x21, 0x13, 0x0f, 0x3d, 0xec, 0x8a, 0x65, 0xb6, + 0xc1, 0x9d, 0x5e, 0x33, 0xb6, 0xbc, 0x89, 0x37, 0x4e, 0x66, 0x26, 0x53, 0x72, 0x67, 0xe4, 0xcb, + 0x3c, 0x67, 0xd9, 0x8c, 0x61, 0x95, 0x1e, 0xc1, 0xcd, 0x0b, 0x45, 0xbe, 0xd1, 0x05, 0xc2, 0x3f, + 0x24, 0x01, 0x5a, 0xdd, 0xea, 0xb6, 0x74, 0x52, 0x03, 0xb2, 0x7b, 0xfa, 0xd0, 0xb2, 0x27, 0x97, + 0xc5, 0xa9, 0x29, 0xbe, 0x52, 0x15, 0xee, 0xd8, 0xe0, 0x32, 0x58, 0xca, 0xf2, 0xe2, 0x66, 0xbc, + 0xeb, 0x10, 0x3f, 0x2c, 0x6e, 0x78, 0x8b, 0x99, 0xe1, 0xea, 0x4e, 0xb8, 0xc0, 0x44, 0x83, 0x4d, + 0xc0, 0x40, 0xf7, 0xc9, 0x91, 0x3e, 0x09, 0x82, 0x8b, 0x6c, 0xa2, 0x4d, 0x7e, 0x4d, 0x47, 0xdc, + 0x43, 0x62, 0xae, 0x64, 0xb8, 0x53, 0xaf, 0xb2, 0x07, 0x4b, 0xb8, 0xf0, 0x5d, 0x28, 0x5d, 0x7a, + 0xc8, 0x13, 0x9b, 0x29, 0xeb, 0x1b, 0xf9, 0xe8, 0x0e, 0x2c, 0xcc, 0x8c, 0xf3, 0x85, 0xaa, 0xb2, + 0xd5, 0x7d, 0xf2, 0xbe, 0x92, 0x96, 0x5f, 0x1f, 0x2a, 0x59, 0xf5, 0x8f, 0x52, 0x22, 0x1c, 0x48, + 0xaf, 0xc6, 0x5f, 0x24, 0xe7, 0xf8, 0x26, 0x36, 0xa8, 0x2d, 0xb7, 0xe9, 0x9b, 0x97, 0x47, 0x09, + 0x56, 0xa5, 0x70, 0x38, 0x0e, 0x05, 0xd1, 0x1a, 0x14, 0xc4, 0x2a, 0xd6, 0xd8, 0xb6, 0xe0, 0x6e, + 0x5d, 0xc0, 0x20, 0x48, 0x4c, 0x12, 0xdd, 0x86, 0x45, 0x7e, 0x0b, 0xe1, 0xed, 0x13, 0x53, 0x60, + 0xd2, 0x1c, 0xb3, 0x10, 0x52, 0x39, 0x6c, 0x1b, 0x8a, 0x92, 0xa0, 0xf1, 0x0c, 0x35, 0xc3, 0x0d, + 0x7a, 0xe7, 0x2a, 0x83, 0x84, 0x08, 0x4f, 0x5c, 0x0b, 0xa3, 0x69, 0x43, 0x6d, 0x40, 0x2e, 0x30, + 0x16, 0xad, 0x40, 0xaa, 0x5f, 0xef, 0x2a, 0x73, 0xa5, 0xa5, 0xe3, 0x93, 0x72, 0x21, 0x20, 0xf7, + 0xeb, 0x5d, 0xc6, 0xd9, 0x69, 0x74, 0x95, 0xc4, 0x2c, 0x67, 0xa7, 0xd1, 0x2d, 0xa5, 0x59, 0xa6, + 0xa4, 0xee, 0x41, 0x21, 0xd2, 0x03, 0x7a, 0x1d, 0xe6, 0x5b, 0xed, 0x47, 0xb8, 0xd9, 0xeb, 0x29, + 0x73, 0xa5, 0x1b, 0xc7, 0x27, 0x65, 0x14, 0xe1, 0xb6, 0x9c, 0x01, 0x9b, 0x1f, 0xf4, 0x2a, 0xa4, + 0x37, 0x3b, 0xec, 0x04, 0x16, 0x29, 0x71, 0x04, 0xb1, 0x49, 0x3d, 0xbf, 0x74, 0x5d, 0xa6, 0x60, + 0x51, 0xc5, 0xea, 0xef, 0x25, 0x20, 0x2b, 0x36, 0x53, 0xec, 0x44, 0x55, 0x61, 0x3e, 0xa8, 0x57, + 0x45, 0xb9, 0xf2, 0xe6, 0xc5, 0xa5, 0x45, 0x45, 0x56, 0x02, 0x62, 0xf9, 0x05, 0x72, 0xa5, 0x8f, + 0xa0, 0x18, 0x65, 0x7c, 0xa3, 0xc5, 0xf7, 0x23, 0x28, 0xb0, 0xf5, 0x1d, 0x94, 0x18, 0xeb, 0x90, + 0x15, 0x01, 0x21, 0x3c, 0x11, 0x2e, 0xae, 0x73, 0x24, 0x12, 0xdd, 0x87, 0x79, 0x51, 0x1b, 0x05, + 0xd7, 0x94, 0xab, 0x97, 0xef, 0x22, 0x1c, 0xc0, 0xd5, 0x4f, 0x21, 0xdd, 0x25, 0xc4, 0x65, 0xbe, + 0x77, 0xa8, 0x49, 0xa6, 0x87, 0xa8, 0x2c, 0xeb, 0x4c, 0xd2, 0x6a, 0xb0, 0xb2, 0xce, 0x24, 0x2d, + 0x33, 0xbc, 0x88, 0x49, 0x46, 0x2e, 0x62, 0xfa, 0x50, 0x7c, 0x4a, 0xac, 0xc1, 0xbe, 0x4f, 0x4c, + 0xae, 0xe8, 0x5d, 0x48, 0x8f, 0x48, 0x68, 0xfc, 0x4a, 0xec, 0x02, 0x23, 0xc4, 0xc5, 0x1c, 0xc5, + 0xe2, 0xc8, 0x11, 0x97, 0x96, 0x77, 0xeb, 0xb2, 0xa5, 0xfe, 0x7d, 0x12, 0x16, 0x5b, 0x9e, 0x37, + 0xd6, 0x1d, 0x23, 0xc8, 0xaf, 0x3e, 0x99, 0xcd, 0xaf, 0xde, 0x8a, 0x1d, 0xe1, 0x8c, 0xc8, 0xec, + 0xfd, 0x92, 0x3c, 0xe3, 0x92, 0xe1, 0x19, 0xa7, 0xfe, 0x7b, 0x22, 0xb8, 0x44, 0xba, 0x1d, 0xd9, + 0xee, 0xa5, 0x95, 0xe3, 0x93, 0xf2, 0x72, 0x54, 0x13, 0xd9, 0x71, 0x0e, 0x1c, 0x7a, 0xe4, 0xa0, + 0xd7, 0x20, 0x83, 0x9b, 0xed, 0xe6, 0x53, 0x25, 0x21, 0x96, 0xe7, 0x0c, 0x08, 0x13, 0x87, 0x1c, + 0x31, 0x4d, 0xdd, 0x66, 0xbb, 0xc1, 0xf2, 0xa1, 0x64, 0x8c, 0xa6, 0x2e, 0x71, 0x4c, 0xcb, 0x19, + 0xa0, 0xd7, 0x21, 0xdb, 0xea, 0xf5, 0x76, 0x78, 0x99, 0xff, 0xdd, 0xe3, 0x93, 0xf2, 0xf5, 0x19, + 0x14, 0xbf, 0x40, 0x34, 0x19, 0x88, 0x15, 0x23, 0x2c, 0x53, 0x8a, 0x01, 0xb1, 0x2c, 0x57, 0x80, + 0x70, 0xa7, 0x5f, 0xed, 0xb3, 0x0a, 0xff, 0x45, 0x10, 0xa6, 0xec, 0xaf, 0xdc, 0x6e, 0xff, 0x9c, + 0x04, 0xa5, 0x6a, 0x18, 0x64, 0xe4, 0x33, 0xbe, 0xac, 0xff, 0xfa, 0x90, 0x1b, 0xb1, 0x2f, 0x8b, + 0x04, 0xb9, 0xcc, 0xfd, 0xd8, 0x07, 0xaf, 0x73, 0x72, 0x15, 0x4c, 0x6d, 0x52, 0x35, 0x87, 0x96, + 0xe7, 0x59, 0xd4, 0x11, 0x34, 0x1c, 0x6a, 0x2a, 0xfd, 0x67, 0x02, 0xae, 0xc7, 0x20, 0xd0, 0x1d, + 0x48, 0xbb, 0xd4, 0x0e, 0xe6, 0xf0, 0xd6, 0x45, 0xf7, 0x83, 0x4c, 0x14, 0x73, 0x24, 0x5a, 0x05, + 0xd0, 0xc7, 0x3e, 0xd5, 0x79, 0xff, 0x7c, 0xf6, 0x72, 0x38, 0x42, 0x41, 0x4f, 0x21, 0xeb, 0x11, + 0xc3, 0x25, 0x41, 0xc6, 0xfb, 0xe9, 0xff, 0xd5, 0xfa, 0x4a, 0x8f, 0xab, 0xc1, 0x52, 0x5d, 0xa9, + 0x02, 0x59, 0x41, 0x61, 0xcb, 0xde, 0xd4, 0x7d, 0x5d, 0xde, 0x1e, 0xf3, 0x6f, 0xb6, 0x9a, 0x74, + 0x7b, 0x10, 0xac, 0x26, 0xdd, 0x1e, 0xa8, 0x7f, 0x93, 0x04, 0x68, 0x3e, 0xf3, 0x89, 0xeb, 0xe8, + 0x76, 0xbd, 0x8a, 0x9a, 0x91, 0xe8, 0x2f, 0x46, 0xfb, 0x76, 0xec, 0x95, 0x78, 0x28, 0x51, 0xa9, + 0x57, 0x63, 0xe2, 0xff, 0x4d, 0x48, 0x8d, 0x5d, 0xf9, 0x86, 0x29, 0xb2, 0xd5, 0x1d, 0xbc, 0x85, + 0x19, 0x0d, 0x35, 0xa7, 0x61, 0x2b, 0x75, 0xf1, 0x4b, 0x65, 0xa4, 0x83, 0xd8, 0xd0, 0xc5, 0x76, + 0xbe, 0xa1, 0x6b, 0x06, 0x91, 0x27, 0x47, 0x51, 0xec, 0xfc, 0x7a, 0xb5, 0x4e, 0x5c, 0x1f, 0x67, + 0x0d, 0x9d, 0xfd, 0xff, 0x56, 0xf1, 0xed, 0x5d, 0x80, 0xe9, 0xd0, 0xd0, 0x2a, 0x64, 0xea, 0x1b, + 0xbd, 0xde, 0x96, 0x32, 0x27, 0x02, 0xf8, 0x94, 0xc5, 0xc9, 0xea, 0x5f, 0x24, 0x21, 0x57, 0xaf, + 0xca, 0x63, 0xb5, 0x0e, 0x0a, 0x8f, 0x4a, 0xfc, 0xce, 0x9d, 0x3c, 0x1b, 0x59, 0xee, 0x44, 0x06, + 0x96, 0x4b, 0x4a, 0xcf, 0x45, 0x26, 0xc2, 0xac, 0x6e, 0x72, 0x01, 0x84, 0xa1, 0x48, 0xa4, 0x13, + 0x34, 0x43, 0x0f, 0x62, 0xfc, 0xea, 0xe5, 0xce, 0x12, 0x45, 0xc4, 0xb4, 0xed, 0xe1, 0x42, 0xa0, + 0xa4, 0xae, 0x7b, 0xe8, 0x01, 0x2c, 0x79, 0xd6, 0xc0, 0xb1, 0x9c, 0x81, 0x16, 0x38, 0x8f, 0x3f, + 0x00, 0xd4, 0xae, 0x9d, 0x9d, 0xae, 0x2d, 0xf4, 0x04, 0x4b, 0xfa, 0x70, 0x41, 0x22, 0xeb, 0xdc, + 0x95, 0xe8, 0x43, 0x58, 0x8c, 0x88, 0x32, 0x2f, 0x0a, 0xb7, 0x2b, 0x67, 0xa7, 0x6b, 0xc5, 0x50, + 0xf2, 0x31, 0x99, 0xe0, 0x62, 0x28, 0xf8, 0x98, 0xf0, 0x5b, 0x92, 0x3d, 0xea, 0x1a, 0x44, 0x73, + 0xf9, 0x9e, 0xe6, 0x27, 0x78, 0x1a, 0x17, 0x38, 0x4d, 0x6c, 0x73, 0xf5, 0x09, 0x5c, 0xef, 0xb8, + 0xc6, 0x3e, 0xf1, 0x7c, 0xe1, 0x0a, 0xe9, 0xc5, 0x4f, 0xe1, 0x96, 0xaf, 0x7b, 0x07, 0xda, 0xbe, + 0xe5, 0xf9, 0xd4, 0x9d, 0x68, 0x2e, 0xf1, 0x89, 0xc3, 0xf8, 0x1a, 0x7f, 0x35, 0x94, 0xd7, 0x58, + 0x37, 0x19, 0x66, 0x53, 0x40, 0x70, 0x80, 0xd8, 0x62, 0x00, 0xb5, 0x05, 0x45, 0x56, 0x4c, 0x34, + 0xc8, 0x9e, 0x3e, 0xb6, 0x7d, 0x36, 0x7a, 0xb0, 0xe9, 0x40, 0x7b, 0xe9, 0x63, 0x2a, 0x6f, 0xd3, + 0x81, 0xf8, 0x54, 0x7f, 0x08, 0x4a, 0xc3, 0xf2, 0x46, 0xba, 0x6f, 0xec, 0x07, 0xf7, 0x73, 0xa8, + 0x01, 0xca, 0x3e, 0xd1, 0x5d, 0x7f, 0x97, 0xe8, 0xbe, 0x36, 0x22, 0xae, 0x45, 0xcd, 0xab, 0x67, + 0x79, 0x29, 0x14, 0xe9, 0x72, 0x09, 0xf5, 0xbf, 0x12, 0x00, 0x58, 0xdf, 0x0b, 0x32, 0xb2, 0xef, + 0xc3, 0x35, 0xcf, 0xd1, 0x47, 0xde, 0x3e, 0xf5, 0x35, 0xcb, 0xf1, 0x89, 0x7b, 0xa8, 0xdb, 0xf2, + 0x9a, 0x45, 0x09, 0x18, 0x2d, 0x49, 0x47, 0xef, 0x02, 0x3a, 0x20, 0x64, 0xa4, 0x51, 0xdb, 0xd4, + 0x02, 0xa6, 0x78, 0xd3, 0x4c, 0x63, 0x85, 0x71, 0x3a, 0xb6, 0xd9, 0x0b, 0xe8, 0xa8, 0x06, 0xab, + 0x6c, 0xf8, 0xc4, 0xf1, 0x5d, 0x8b, 0x78, 0xda, 0x1e, 0x75, 0x35, 0xcf, 0xa6, 0x47, 0xda, 0x1e, + 0xb5, 0x6d, 0x7a, 0x44, 0xdc, 0xe0, 0x06, 0xab, 0x64, 0xd3, 0x41, 0x53, 0x80, 0x36, 0xa8, 0xdb, + 0xb3, 0xe9, 0xd1, 0x46, 0x80, 0x60, 0x69, 0xdb, 0x74, 0xcc, 0xbe, 0x65, 0x1c, 0x04, 0x69, 0x5b, + 0x48, 0xed, 0x5b, 0xc6, 0x01, 0x7a, 0x1d, 0x16, 0x88, 0x4d, 0xf8, 0x45, 0x86, 0x40, 0x65, 0x38, + 0xaa, 0x18, 0x10, 0x19, 0x48, 0xfd, 0x0c, 0x94, 0xa6, 0x63, 0xb8, 0x93, 0x51, 0x64, 0xce, 0xdf, + 0x05, 0xc4, 0x82, 0xa4, 0x66, 0x53, 0xe3, 0x40, 0x1b, 0xea, 0x8e, 0x3e, 0x60, 0x76, 0x89, 0xa7, + 0x26, 0x85, 0x71, 0xb6, 0xa8, 0x71, 0xb0, 0x2d, 0xe9, 0xea, 0x03, 0x80, 0xde, 0xc8, 0x25, 0xba, + 0xd9, 0x61, 0xd9, 0x04, 0x73, 0x1d, 0x6f, 0x69, 0xa6, 0x7c, 0xaa, 0xa3, 0xae, 0xdc, 0xea, 0x8a, + 0x60, 0x34, 0x42, 0xba, 0xfa, 0x0b, 0x70, 0xbd, 0x6b, 0xeb, 0x06, 0x7f, 0xb6, 0xee, 0x86, 0x6f, + 0x27, 0xe8, 0x3e, 0x64, 0x05, 0x54, 0xce, 0x64, 0xec, 0x76, 0x9b, 0xf6, 0xb9, 0x39, 0x87, 0x25, + 0xbe, 0x56, 0x04, 0x98, 0xea, 0x51, 0xff, 0x2c, 0x01, 0xf9, 0x50, 0x3f, 0x2a, 0x03, 0x2b, 0xe5, + 0xd9, 0xf2, 0xb6, 0x1c, 0x59, 0x7b, 0xe7, 0x71, 0x94, 0x84, 0x5a, 0x50, 0x18, 0x85, 0xd2, 0x97, + 0xe6, 0x73, 0x31, 0x56, 0xe3, 0xa8, 0x2c, 0xfa, 0x08, 0xf2, 0xc1, 0xdb, 0x68, 0x10, 0x61, 0x2f, + 0x7f, 0x4a, 0x9d, 0xc2, 0xd5, 0x4f, 0x00, 0x7e, 0x40, 0x2d, 0xa7, 0x4f, 0x0f, 0x88, 0xc3, 0xdf, + 0xfa, 0x58, 0x4d, 0x48, 0x02, 0x2f, 0xca, 0x16, 0x2f, 0xc8, 0xc5, 0x14, 0x84, 0x4f, 0x5e, 0xa2, + 0xa9, 0xfe, 0x75, 0x12, 0xb2, 0x98, 0x52, 0xbf, 0x5e, 0x45, 0x65, 0xc8, 0xca, 0x38, 0xc1, 0xcf, + 0x9f, 0x5a, 0xfe, 0xec, 0x74, 0x2d, 0x23, 0x02, 0x44, 0xc6, 0xe0, 0x91, 0x21, 0x12, 0xc1, 0x93, + 0x17, 0x45, 0x70, 0x74, 0x07, 0x8a, 0x12, 0xa4, 0xed, 0xeb, 0xde, 0xbe, 0x28, 0xd0, 0x6a, 0x8b, + 0x67, 0xa7, 0x6b, 0x20, 0x90, 0x9b, 0xba, 0xb7, 0x8f, 0x41, 0xa0, 0xd9, 0x37, 0x6a, 0x42, 0xe1, + 0x0b, 0x6a, 0x39, 0x9a, 0xcf, 0x07, 0x21, 0xaf, 0xfc, 0x62, 0xe7, 0x71, 0x3a, 0x54, 0xf9, 0xf0, + 0x0d, 0x5f, 0x4c, 0x07, 0xdf, 0x84, 0x05, 0x97, 0x52, 0x5f, 0x84, 0x2d, 0x8b, 0x3a, 0xf2, 0x36, + 0xa1, 0x1c, 0x7b, 0xc9, 0x4c, 0xa9, 0x8f, 0x25, 0x0e, 0x17, 0xdd, 0x48, 0x0b, 0xdd, 0x81, 0x65, + 0x5b, 0xf7, 0x7c, 0x8d, 0xc7, 0x3b, 0x73, 0xaa, 0x2d, 0xcb, 0xb7, 0x1a, 0x62, 0xbc, 0x0d, 0xce, + 0x0a, 0x24, 0xd4, 0x7f, 0x4c, 0x40, 0x81, 0x0d, 0xc6, 0xda, 0xb3, 0x0c, 0x96, 0xe4, 0x7d, 0xf3, + 0xdc, 0xe3, 0x26, 0xa4, 0x0c, 0xcf, 0x95, 0x4e, 0xe5, 0x87, 0x6f, 0xbd, 0x87, 0x31, 0xa3, 0xa1, + 0xcf, 0x20, 0x2b, 0x6f, 0x35, 0x44, 0xda, 0xa1, 0x5e, 0x9d, 0x8e, 0x4a, 0xdf, 0x48, 0x39, 0xbe, + 0x96, 0xa7, 0xd6, 0x89, 0x43, 0x00, 0x47, 0x49, 0xe8, 0x06, 0x24, 0x0d, 0xe1, 0x2e, 0xf9, 0xcb, + 0x8a, 0x7a, 0x1b, 0x27, 0x0d, 0x47, 0xfd, 0xbb, 0x04, 0x2c, 0x4c, 0x37, 0x3c, 0x5b, 0x01, 0xb7, + 0x20, 0xef, 0x8d, 0x77, 0xbd, 0x89, 0xe7, 0x93, 0x61, 0xf0, 0x8e, 0x19, 0x12, 0x50, 0x0b, 0xf2, + 0xba, 0x3d, 0xa0, 0xae, 0xe5, 0xef, 0x0f, 0x65, 0x25, 0x1a, 0x9f, 0x2a, 0x44, 0x75, 0x56, 0xaa, + 0x81, 0x08, 0x9e, 0x4a, 0x07, 0xe7, 0xbe, 0x78, 0xec, 0xe6, 0xe7, 0xfe, 0x6b, 0x50, 0xb4, 0xf5, + 0x21, 0xbf, 0xe6, 0xf1, 0xad, 0xa1, 0x18, 0x47, 0x1a, 0x17, 0x24, 0xad, 0x6f, 0x0d, 0x89, 0xaa, + 0x42, 0x3e, 0x54, 0x86, 0x96, 0xa0, 0x50, 0x6d, 0xf6, 0xb4, 0xbb, 0xeb, 0xf7, 0xb5, 0x47, 0xf5, + 0x6d, 0x65, 0x4e, 0xe6, 0xa6, 0x7f, 0x9e, 0x80, 0x05, 0x19, 0x8e, 0x64, 0xbe, 0xff, 0x3a, 0xcc, + 0xbb, 0xfa, 0x9e, 0x1f, 0x54, 0x24, 0x69, 0xb1, 0xaa, 0x59, 0x84, 0x67, 0x15, 0x09, 0x63, 0xc5, + 0x57, 0x24, 0x91, 0x97, 0xf5, 0xd4, 0xa5, 0x2f, 0xeb, 0xe9, 0x9f, 0xcb, 0xcb, 0xba, 0xfa, 0x6b, + 0x00, 0x1b, 0x96, 0x4d, 0xfa, 0xe2, 0xae, 0x29, 0xae, 0xbe, 0x64, 0x39, 0x9c, 0xbc, 0x71, 0x0c, + 0x72, 0xb8, 0x56, 0x03, 0x33, 0x1a, 0x63, 0x0d, 0x2c, 0x53, 0x6e, 0x46, 0xce, 0x7a, 0xc4, 0x58, + 0x03, 0xcb, 0x0c, 0xdf, 0x92, 0xd2, 0x57, 0xbd, 0x25, 0x9d, 0x24, 0x60, 0x49, 0xe6, 0xae, 0x61, + 0xf8, 0x7d, 0x1b, 0xf2, 0x22, 0x8d, 0x9d, 0x16, 0x74, 0xfc, 0x35, 0x59, 0xe0, 0x5a, 0x0d, 0x9c, + 0x13, 0xec, 0x96, 0x89, 0xd6, 0xa0, 0x20, 0xa1, 0x91, 0x5f, 0xe1, 0x80, 0x20, 0xb5, 0x99, 0xf9, + 0xef, 0x43, 0x7a, 0xcf, 0xb2, 0x89, 0x5c, 0xe8, 0xb1, 0x01, 0x60, 0xea, 0x80, 0xcd, 0x39, 0xcc, + 0xd1, 0xb5, 0x5c, 0x70, 0x19, 0xc7, 0xed, 0x93, 0x65, 0x67, 0xd4, 0x3e, 0x51, 0x81, 0x9e, 0xb3, + 0x4f, 0xe0, 0x98, 0x7d, 0x82, 0x2d, 0xec, 0x93, 0xd0, 0xa8, 0x7d, 0x82, 0xf4, 0x73, 0xb1, 0x6f, + 0x0b, 0x6e, 0xd4, 0x6c, 0xdd, 0x38, 0xb0, 0x2d, 0xcf, 0x27, 0x66, 0x34, 0x62, 0xac, 0x43, 0x76, + 0x26, 0xe9, 0xbc, 0xec, 0x72, 0x56, 0x22, 0xd5, 0x7f, 0x4b, 0x40, 0x71, 0x93, 0xe8, 0xb6, 0xbf, + 0x3f, 0xbd, 0x1a, 0xf2, 0x89, 0xe7, 0xcb, 0xc3, 0x8a, 0x7f, 0xa3, 0x0f, 0x20, 0x17, 0xe6, 0x24, + 0x57, 0xbe, 0x92, 0x85, 0x50, 0x74, 0x0f, 0xe6, 0xd9, 0x1e, 0xa3, 0xe3, 0xa0, 0xd8, 0xb9, 0xec, + 0x01, 0x46, 0x22, 0xd9, 0x21, 0xe3, 0x12, 0x9e, 0x84, 0xf0, 0xa5, 0x94, 0xc1, 0x41, 0x13, 0xfd, + 0x7f, 0x28, 0xf2, 0xf7, 0x83, 0x20, 0xe7, 0xca, 0x5c, 0xa5, 0xb3, 0x20, 0x9e, 0x00, 0x45, 0xbe, + 0xf5, 0x3f, 0x09, 0x58, 0xde, 0xd6, 0x27, 0xbb, 0x44, 0x86, 0x0d, 0x62, 0x62, 0x62, 0x50, 0xd7, + 0x44, 0xdd, 0x68, 0xb8, 0xb9, 0xe4, 0x45, 0x31, 0x4e, 0x38, 0x3e, 0xea, 0x04, 0x05, 0x58, 0x32, + 0x52, 0x80, 0x2d, 0x43, 0xc6, 0xa1, 0x8e, 0x41, 0x64, 0x2c, 0x12, 0x0d, 0xd5, 0x8a, 0x86, 0x9a, + 0x52, 0xf8, 0xd8, 0xc7, 0x9f, 0xea, 0xda, 0xd4, 0x0f, 0x7b, 0x43, 0x9f, 0x41, 0xa9, 0xd7, 0xac, + 0xe3, 0x66, 0xbf, 0xd6, 0xf9, 0xa1, 0xd6, 0xab, 0x6e, 0xf5, 0xaa, 0xeb, 0x77, 0xb4, 0x6e, 0x67, + 0xeb, 0xf3, 0xbb, 0xf7, 0xee, 0x7c, 0xa0, 0x24, 0x4a, 0xe5, 0xe3, 0x93, 0xf2, 0xad, 0x76, 0xb5, + 0xbe, 0x25, 0x76, 0xcc, 0x2e, 0x7d, 0xd6, 0xd3, 0x6d, 0x4f, 0x5f, 0xbf, 0xd3, 0xa5, 0xf6, 0x84, + 0x61, 0xd8, 0xb2, 0x2e, 0x46, 0xcf, 0xab, 0xe8, 0x31, 0x9c, 0xb8, 0xf0, 0x18, 0x9e, 0x9e, 0xe6, + 0xc9, 0x0b, 0x4e, 0xf3, 0x0d, 0x58, 0x36, 0x5c, 0xea, 0x79, 0x1a, 0xcb, 0xfe, 0x89, 0x79, 0xae, + 0xbe, 0xf8, 0xce, 0xd9, 0xe9, 0xda, 0xb5, 0x3a, 0xe3, 0xf7, 0x38, 0x5b, 0xaa, 0xbf, 0x66, 0x44, + 0x48, 0xbc, 0x27, 0xf5, 0xf7, 0x53, 0x2c, 0x91, 0xb2, 0x0e, 0x2d, 0x9b, 0x0c, 0x88, 0x87, 0x9e, + 0xc0, 0x92, 0xe1, 0x12, 0x93, 0xa5, 0xf5, 0xba, 0xad, 0x79, 0x23, 0x62, 0xc8, 0x45, 0xfd, 0xff, + 0x62, 0x73, 0x9a, 0x50, 0xb0, 0x52, 0x0f, 0xa5, 0x7a, 0x23, 0x62, 0xe0, 0x45, 0x63, 0xa6, 0x8d, + 0xbe, 0x80, 0x25, 0x8f, 0xd8, 0x96, 0x33, 0x7e, 0xa6, 0x19, 0xd4, 0xf1, 0xc9, 0xb3, 0xe0, 0xdd, + 0xea, 0x2a, 0xbd, 0xbd, 0xe6, 0x16, 0x93, 0xaa, 0x0b, 0xa1, 0x1a, 0x3a, 0x3b, 0x5d, 0x5b, 0x9c, + 0xa5, 0xe1, 0x45, 0xa9, 0x59, 0xb6, 0x4b, 0x6d, 0x58, 0x9c, 0xb5, 0x06, 0x2d, 0xcb, 0xbd, 0xcf, + 0x43, 0x48, 0xb0, 0xb7, 0xd1, 0x2d, 0xc8, 0xb9, 0x64, 0x60, 0x79, 0xbe, 0x2b, 0xdc, 0xcc, 0x38, + 0x21, 0x85, 0xed, 0x7c, 0xf1, 0x53, 0x9c, 0xd2, 0xaf, 0xc0, 0xb9, 0x1e, 0xd9, 0x66, 0x31, 0x2d, + 0x4f, 0xdf, 0x95, 0x2a, 0x73, 0x38, 0x68, 0xb2, 0x35, 0x38, 0xf6, 0xc2, 0x44, 0x8d, 0x7f, 0x33, + 0x1a, 0xcf, 0x28, 0xe4, 0x0f, 0x93, 0x78, 0xce, 0x10, 0xfc, 0xc2, 0x31, 0x1d, 0xf9, 0x85, 0xe3, + 0x32, 0x64, 0x6c, 0x72, 0x48, 0x6c, 0x71, 0x96, 0x63, 0xd1, 0x78, 0xe7, 0x67, 0x29, 0xc8, 0x87, + 0x6f, 0x34, 0xec, 0x24, 0x68, 0x37, 0x9f, 0x06, 0x6b, 0x35, 0xa4, 0xb7, 0xc9, 0x11, 0x7a, 0x6d, + 0x7a, 0xa7, 0xf4, 0x99, 0x78, 0x94, 0x0e, 0xd9, 0xc1, 0x7d, 0xd2, 0x1b, 0x90, 0xab, 0xf6, 0x7a, + 0xad, 0x47, 0xed, 0x66, 0x43, 0xf9, 0x32, 0x51, 0xfa, 0xce, 0xf1, 0x49, 0xf9, 0x5a, 0x08, 0xaa, + 0x7a, 0x62, 0x29, 0x71, 0x54, 0xbd, 0xde, 0xec, 0xf6, 0x9b, 0x0d, 0xe5, 0x79, 0xf2, 0x3c, 0x8a, + 0xdf, 0x91, 0xf0, 0x9f, 0x96, 0xe4, 0xbb, 0xb8, 0xd9, 0xad, 0x62, 0xd6, 0xe1, 0x97, 0x49, 0x71, + 0xd5, 0x35, 0xed, 0xd1, 0x25, 0x23, 0x9d, 0xff, 0xae, 0x78, 0x35, 0xf8, 0x89, 0xd5, 0xf3, 0x94, + 0xf8, 0xf9, 0xc1, 0xf4, 0xc1, 0x89, 0xe8, 0xe6, 0x84, 0xf5, 0xc6, 0x5f, 0xfa, 0xb8, 0x9a, 0xd4, + 0xb9, 0xde, 0x7a, 0x2c, 0x92, 0x30, 0x2d, 0x2a, 0xcc, 0xe3, 0x9d, 0x76, 0x9b, 0x81, 0x9e, 0xa7, + 0xcf, 0x8d, 0x0e, 0x8f, 0x1d, 0x56, 0xff, 0xa2, 0xdb, 0x90, 0x0b, 0x1e, 0x02, 0x95, 0x2f, 0xd3, + 0xe7, 0x0c, 0xaa, 0x07, 0xaf, 0x98, 0xbc, 0xc3, 0xcd, 0x9d, 0x3e, 0xff, 0x05, 0xd8, 0xf3, 0xcc, + 0xf9, 0x0e, 0xf7, 0xc7, 0xbe, 0x49, 0x8f, 0x1c, 0xb6, 0x03, 0xe5, 0xad, 0xda, 0x97, 0x19, 0x71, + 0x05, 0x11, 0x62, 0xe4, 0x95, 0xda, 0x1b, 0x90, 0xc3, 0xcd, 0x1f, 0x88, 0x1f, 0x8b, 0x3d, 0xcf, + 0x9e, 0xd3, 0x83, 0xc9, 0x17, 0xc4, 0x90, 0xbd, 0x75, 0x70, 0x77, 0xb3, 0xca, 0x5d, 0x7e, 0x1e, + 0xd5, 0x71, 0x47, 0xfb, 0xba, 0x43, 0xcc, 0xe9, 0x6f, 0x30, 0x42, 0xd6, 0x3b, 0xbf, 0x08, 0xb9, + 0x20, 0xcf, 0x44, 0xab, 0x90, 0x7d, 0xda, 0xc1, 0x8f, 0x9b, 0x58, 0x99, 0x13, 0x3e, 0x0c, 0x38, + 0x4f, 0x45, 0x85, 0x50, 0x86, 0xf9, 0xed, 0x6a, 0xbb, 0xfa, 0xa8, 0x89, 0x83, 0x0b, 0xef, 0x00, + 0x20, 0x93, 0xa5, 0x92, 0x22, 0x3b, 0x08, 0x75, 0xd6, 0x56, 0xbe, 0xfa, 0x7a, 0x75, 0xee, 0xa7, + 0x5f, 0xaf, 0xce, 0x3d, 0x3f, 0x5b, 0x4d, 0x7c, 0x75, 0xb6, 0x9a, 0xf8, 0xc9, 0xd9, 0x6a, 0xe2, + 0x5f, 0xcf, 0x56, 0x13, 0xbb, 0x59, 0x1e, 0xd2, 0xef, 0xfd, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xdb, 0x9d, 0xe2, 0x3d, 0xd2, 0x2f, 0x00, 0x00, } diff --git a/components/cli/vendor/github.com/docker/swarmkit/api/types.proto b/components/cli/vendor/github.com/docker/swarmkit/api/types.proto index 719b88a9c6..201bc3587f 100644 --- a/components/cli/vendor/github.com/docker/swarmkit/api/types.proto +++ b/components/cli/vendor/github.com/docker/swarmkit/api/types.proto @@ -30,12 +30,32 @@ message Annotations { repeated IndexEntry indices = 4 [(gogoproto.nullable) = false]; } +message GenericString { + string kind = 1; + string value = 2; +} + +message GenericDiscrete { + string kind = 1; + int64 value = 2; +} + +message GenericResource { + oneof resource { + GenericString str = 1; + GenericDiscrete discrete = 2; + } +} + message Resources { // Amount of CPUs (e.g. 2000000000 = 2 CPU cores) int64 nano_cpus = 1 [(gogoproto.customname) = "NanoCPUs"]; // Amount of memory in bytes. int64 memory_bytes = 2; + + // User specified resource (e.g: bananas=2;apple={red,yellow,green}) + repeated GenericResource generic = 3; } message ResourceRequirements { diff --git a/components/cli/vendor/github.com/docker/swarmkit/vendor.conf b/components/cli/vendor/github.com/docker/swarmkit/vendor.conf index 52fa7aafe5..4f5d293b8b 100644 --- a/components/cli/vendor/github.com/docker/swarmkit/vendor.conf +++ b/components/cli/vendor/github.com/docker/swarmkit/vendor.conf @@ -1,8 +1,9 @@ # grpc and protobuf -google.golang.org/grpc v1.0.4 +google.golang.org/grpc v1.3.0 github.com/gogo/protobuf v0.4 -github.com/golang/protobuf 8ee79997227bf9b34611aee7946ae64735e6fd93 +github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4 github.com/matttproud/golang_protobuf_extensions v1.0.0 +google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 # metrics github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 @@ -18,15 +19,24 @@ github.com/prometheus/common ebdfc6da46522d58825777cf1f90490a5b1ef1d8 github.com/prometheus/procfs abf152e5f3e97f2fafac028d2cc06c1feb87ffa5 github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621 -github.com/docker/docker 9585d0ea19859c5f145bc763d474190447b91c7b +github.com/docker/docker 77c9728847358a3ed3581d828fb0753017e1afd3 github.com/docker/go-connections 34b5052da6b11e27f5f2e357b38b571ddddd3928 github.com/docker/go-events 37d35add5005832485c0225ec870121b78fcff1c github.com/docker/go-units 954fed01cc617c55d838fa2230073f2cb17386c8 github.com/docker/libkv 9fd56606e928ff1f309808f5d5a0b7a2ef73f9a8 github.com/docker/libnetwork 37e20af882e13dd01ade3658b7aabdae3412118b github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a -github.com/opencontainers/runc 8e8d01d38d7b4fb0a35bf89b72bc3e18c98882d7 +github.com/opencontainers/runc b6b70e53451794e8333e9b602cc096b47a20bd0f github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb +github.com/opencontainers/image-spec f03dbe35d449c54915d235f1a3cf8f585a24babe + +# containerd executor +github.com/containerd/containerd 7fc91b05917e93d474fab9465547d44eacd10ce3 +github.com/containerd/continuity f4ad4294c92f596c9241947c416d1297f9faf3ea +github.com/containerd/fifo 69b99525e472735860a5269b75af1970142b3062 +github.com/opencontainers/runtime-spec v1.0.0-rc5 +github.com/nightlyone/lockfile 1d49c987357a327b5b03aa84cbddd582c328615d +golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d github.com/Microsoft/go-winio f778f05015353be65d242f3fedc18695756153bb @@ -49,7 +59,7 @@ github.com/spf13/cobra 8e91712f174ced10270cf66615e0a9127e7c4de5 github.com/spf13/pflag 7f60f83a2c81bc3c3c0d5297f61ddfa68da9d3b7 github.com/stretchr/testify v1.1.4 golang.org/x/crypto 3fbbcd23f1cb824e69491a5930cfeff09b12f4d2 -golang.org/x/net c427ad74c6d7a814201695e9ffde0c5d400a7674 +golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 golang.org/x/sys 5eaf0df67e70d6997a9fe0ed24383fa1b01638d3 golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756 golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb From d48d41f4e2221ffb9739716dfd1ed4fc6d0f1805 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sun, 2 Jul 2017 00:02:24 -0700 Subject: [PATCH 07/62] bump gRPC to v1.3.0, add genproto, update protobuf Signed-off-by: Sebastiaan van Stijn Upstream-commit: 74ec7a5b2cddfb055030984194e34334dbc5f991 Component: cli --- components/cli/vendor.conf | 5 +- .../github.com/golang/protobuf/README.md | 2 +- .../golang/protobuf/ptypes/any/any.pb.go | 168 ++++ .../golang/protobuf/ptypes/any/any.proto | 139 ++++ .../vendor/google.golang.org/genproto/LICENSE | 202 +++++ .../google.golang.org/genproto/README.md | 28 + .../googleapis/rpc/status/status.pb.go | 144 ++++ .../vendor/google.golang.org/grpc/README.md | 13 +- .../cli/vendor/google.golang.org/grpc/call.go | 144 +++- .../google.golang.org/grpc/clientconn.go | 260 ++++-- .../vendor/google.golang.org/grpc/codec.go | 118 +++ .../grpc/credentials/credentials.go | 8 +- .../grpc/credentials/credentials_util_go17.go | 3 +- .../grpc/credentials/credentials_util_go18.go | 53 ++ .../credentials/credentials_util_pre_go17.go | 2 - .../cli/vendor/google.golang.org/grpc/go16.go | 56 ++ .../grpc/{transport/pre_go16.go => go17.go} | 18 +- .../vendor/google.golang.org/grpc/grpclb.go | 749 ++++++++++++++++++ .../grpc/grpclb/grpc_lb_v1/grpclb.pb.go | 629 +++++++++++++++ .../grpc/grpclb/grpc_lb_v1/grpclb.proto | 179 +++++ .../google.golang.org/grpc/interceptor.go | 2 +- .../grpc/keepalive/keepalive.go | 80 ++ .../grpc/metadata/metadata.go | 85 +- .../vendor/google.golang.org/grpc/proxy.go | 145 ++++ .../vendor/google.golang.org/grpc/rpc_util.go | 206 +++-- .../vendor/google.golang.org/grpc/server.go | 346 +++++--- .../google.golang.org/grpc/stats/handlers.go | 76 ++ .../google.golang.org/grpc/stats/stats.go | 223 ++++++ .../google.golang.org/grpc/status/status.go | 145 ++++ .../vendor/google.golang.org/grpc/stream.go | 207 +++-- .../vendor/google.golang.org/grpc/tap/tap.go | 54 ++ .../grpc/transport/control.go | 52 +- .../grpc/transport/handler_server.go | 29 +- .../grpc/transport/http2_client.go | 382 ++++++--- .../grpc/transport/http2_server.go | 371 ++++++++- .../grpc/transport/http_util.go | 112 ++- .../grpc/transport/transport.go | 121 ++- 37 files changed, 4932 insertions(+), 624 deletions(-) create mode 100644 components/cli/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go create mode 100644 components/cli/vendor/github.com/golang/protobuf/ptypes/any/any.proto create mode 100644 components/cli/vendor/google.golang.org/genproto/LICENSE create mode 100644 components/cli/vendor/google.golang.org/genproto/README.md create mode 100644 components/cli/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go create mode 100644 components/cli/vendor/google.golang.org/grpc/codec.go create mode 100644 components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go create mode 100644 components/cli/vendor/google.golang.org/grpc/go16.go rename components/cli/vendor/google.golang.org/grpc/{transport/pre_go16.go => go17.go} (86%) create mode 100644 components/cli/vendor/google.golang.org/grpc/grpclb.go create mode 100644 components/cli/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.pb.go create mode 100644 components/cli/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto create mode 100644 components/cli/vendor/google.golang.org/grpc/keepalive/keepalive.go create mode 100644 components/cli/vendor/google.golang.org/grpc/proxy.go create mode 100644 components/cli/vendor/google.golang.org/grpc/stats/handlers.go create mode 100644 components/cli/vendor/google.golang.org/grpc/stats/stats.go create mode 100644 components/cli/vendor/google.golang.org/grpc/status/status.go create mode 100644 components/cli/vendor/google.golang.org/grpc/tap/tap.go diff --git a/components/cli/vendor.conf b/components/cli/vendor.conf index a9a8f3ddb6..f6def192a1 100755 --- a/components/cli/vendor.conf +++ b/components/cli/vendor.conf @@ -18,7 +18,7 @@ github.com/docker/notary v0.4.2 github.com/docker/swarmkit 79381d0840be27f8b3f5c667b348a4467d866eeb github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff github.com/gogo/protobuf 7efa791bd276fd4db00867cbd982b552627c24cb -github.com/golang/protobuf 8ee79997227bf9b34611aee7946ae64735e6fd93 +github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4 github.com/gorilla/context v1.1 github.com/gorilla/mux v1.1 github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 @@ -44,7 +44,8 @@ golang.org/x/net c427ad74c6d7a814201695e9ffde0c5d400a7674 golang.org/x/sys 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9 golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756 golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb -google.golang.org/grpc v1.0.4 +google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 +google.golang.org/grpc v1.3.0 gopkg.in/yaml.v2 4c78c975fe7c825c6d1466c42be594d1d6f3aba6 github.com/tonistiigi/fsutil 0ac4c11b053b9c5c7c47558f81f96c7100ce50fb github.com/stevvooe/continuity cd7a8e21e2b6f84799f5dd4b65faf49c8d3ee02d diff --git a/components/cli/vendor/github.com/golang/protobuf/README.md b/components/cli/vendor/github.com/golang/protobuf/README.md index 037fc7c8e2..aa933d7884 100644 --- a/components/cli/vendor/github.com/golang/protobuf/README.md +++ b/components/cli/vendor/github.com/golang/protobuf/README.md @@ -22,7 +22,7 @@ To use this software, you must: for details or, if you are using gccgo, follow the instructions at https://golang.org/doc/install/gccgo - Grab the code from the repository and install the proto package. - The simplest way is to run `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`. + The simplest way is to run `go get -u github.com/golang/protobuf/protoc-gen-go`. The compiler plugin, protoc-gen-go, will be installed in $GOBIN, defaulting to $GOPATH/bin. It must be in your $PATH for the protocol compiler, protoc, to find it. diff --git a/components/cli/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/components/cli/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go new file mode 100644 index 0000000000..1fbaa44caa --- /dev/null +++ b/components/cli/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go @@ -0,0 +1,168 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/ptypes/any/any.proto + +/* +Package any is a generated protocol buffer package. + +It is generated from these files: + github.com/golang/protobuf/ptypes/any/any.proto + +It has these top-level messages: + Any +*/ +package any + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +type Any struct { + // A URL/resource name whose content describes the type of the + // serialized protocol buffer message. + // + // For URLs which use the scheme `http`, `https`, or no scheme, the + // following restrictions and interpretations apply: + // + // * If no scheme is provided, `https` is assumed. + // * The last segment of the URL's path must represent the fully + // qualified name of the type (as in `path/google.protobuf.Duration`). + // The name should be in a canonical form (e.g., leading "." is + // not accepted). + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"` + // Must be a valid serialized protocol buffer of the above specified type. + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *Any) Reset() { *m = Any{} } +func (m *Any) String() string { return proto.CompactTextString(m) } +func (*Any) ProtoMessage() {} +func (*Any) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (*Any) XXX_WellKnownType() string { return "Any" } + +func (m *Any) GetTypeUrl() string { + if m != nil { + return m.TypeUrl + } + return "" +} + +func (m *Any) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func init() { + proto.RegisterType((*Any)(nil), "google.protobuf.Any") +} + +func init() { proto.RegisterFile("github.com/golang/protobuf/ptypes/any/any.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 184 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4f, 0xcf, 0x2c, 0xc9, + 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28, + 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0xcc, + 0xab, 0x04, 0x61, 0x3d, 0xb0, 0xb8, 0x10, 0x7f, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x1e, 0x4c, + 0x95, 0x92, 0x19, 0x17, 0xb3, 0x63, 0x5e, 0xa5, 0x90, 0x24, 0x17, 0x07, 0x48, 0x79, 0x7c, 0x69, + 0x51, 0x8e, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x3b, 0x88, 0x1f, 0x5a, 0x94, 0x23, 0x24, + 0xc2, 0xc5, 0x5a, 0x96, 0x98, 0x53, 0x9a, 0x2a, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x13, 0x04, 0xe1, + 0x38, 0xe5, 0x73, 0x09, 0x27, 0xe7, 0xe7, 0xea, 0xa1, 0x19, 0xe7, 0xc4, 0xe1, 0x98, 0x57, 0x19, + 0x00, 0xe2, 0x04, 0x30, 0x46, 0xa9, 0x12, 0xe5, 0xb8, 0x45, 0x4c, 0xcc, 0xee, 0x01, 0x4e, 0xab, + 0x98, 0xe4, 0xdc, 0x21, 0x46, 0x05, 0x40, 0x95, 0xe8, 0x85, 0xa7, 0xe6, 0xe4, 0x78, 0xe7, 0xe5, + 0x97, 0xe7, 0x85, 0x80, 0x94, 0x26, 0xb1, 0x81, 0xf5, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, + 0x45, 0x1f, 0x1a, 0xf2, 0xf3, 0x00, 0x00, 0x00, +} diff --git a/components/cli/vendor/github.com/golang/protobuf/ptypes/any/any.proto b/components/cli/vendor/github.com/golang/protobuf/ptypes/any/any.proto new file mode 100644 index 0000000000..9bd3f50a45 --- /dev/null +++ b/components/cli/vendor/github.com/golang/protobuf/ptypes/any/any.proto @@ -0,0 +1,139 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "github.com/golang/protobuf/ptypes/any"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name whose content describes the type of the + // serialized protocol buffer message. + // + // For URLs which use the scheme `http`, `https`, or no scheme, the + // following restrictions and interpretations apply: + // + // * If no scheme is provided, `https` is assumed. + // * The last segment of the URL's path must represent the fully + // qualified name of the type (as in `path/google.protobuf.Duration`). + // The name should be in a canonical form (e.g., leading "." is + // not accepted). + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/components/cli/vendor/google.golang.org/genproto/LICENSE b/components/cli/vendor/google.golang.org/genproto/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/components/cli/vendor/google.golang.org/genproto/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/components/cli/vendor/google.golang.org/genproto/README.md b/components/cli/vendor/google.golang.org/genproto/README.md new file mode 100644 index 0000000000..51d0bae5f7 --- /dev/null +++ b/components/cli/vendor/google.golang.org/genproto/README.md @@ -0,0 +1,28 @@ +Go generated proto packages +=========================== + +[![Build Status](https://travis-ci.org/google/go-genproto.svg?branch=master)](https://travis-ci.org/google/go-genproto) +[![GoDoc](https://godoc.org/google.golang.org/genproto?status.svg)](https://godoc.org/google.golang.org/genproto) + +> **IMPORTANT** This repository is currently experimental. The structure +> of the contained packages is subject to change. Please see the original +> source repositories (listed below) to find out the status of the each +> protocol buffer's associated service. + +This repository contains the generated Go packages for common protocol buffer +types, and the generated [gRPC][1] code necessary for interacting with Google's gRPC +APIs. + +There are two sources for the proto files used in this repository: + +1. [google/protobuf][2]: the code in the `protobuf` and `ptypes` subdirectories + is derived from this repo. The messages in `protobuf` are used to describe + protocol buffer messages themselves. The messages under `ptypes` define the + common well-known types. +2. [googleapis/googleapis][3]: the code in the `googleapis` is derived from this + repo. The packages here contain types specifically for interacting with Google + APIs. + +[1]: http://grpc.io +[2]: https://github.com/google/protobuf/ +[3]: https://github.com/googleapis/googleapis/ diff --git a/components/cli/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go b/components/cli/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go new file mode 100644 index 0000000000..ec26060bc9 --- /dev/null +++ b/components/cli/vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go @@ -0,0 +1,144 @@ +// Code generated by protoc-gen-go. +// source: google/rpc/status.proto +// DO NOT EDIT! + +/* +Package status is a generated protocol buffer package. + +It is generated from these files: + google/rpc/status.proto + +It has these top-level messages: + Status +*/ +package status + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/golang/protobuf/ptypes/any" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// The `Status` type defines a logical error model that is suitable for different +// programming environments, including REST APIs and RPC APIs. It is used by +// [gRPC](https://github.com/grpc). The error model is designed to be: +// +// - Simple to use and understand for most users +// - Flexible enough to meet unexpected needs +// +// # Overview +// +// The `Status` message contains three pieces of data: error code, error message, +// and error details. The error code should be an enum value of +// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The +// error message should be a developer-facing English message that helps +// developers *understand* and *resolve* the error. If a localized user-facing +// error message is needed, put the localized message in the error details or +// localize it in the client. The optional error details may contain arbitrary +// information about the error. There is a predefined set of error detail types +// in the package `google.rpc` which can be used for common error conditions. +// +// # Language mapping +// +// The `Status` message is the logical representation of the error model, but it +// is not necessarily the actual wire format. When the `Status` message is +// exposed in different client libraries and different wire protocols, it can be +// mapped differently. For example, it will likely be mapped to some exceptions +// in Java, but more likely mapped to some error codes in C. +// +// # Other uses +// +// The error model and the `Status` message can be used in a variety of +// environments, either with or without APIs, to provide a +// consistent developer experience across different environments. +// +// Example uses of this error model include: +// +// - Partial errors. If a service needs to return partial errors to the client, +// it may embed the `Status` in the normal response to indicate the partial +// errors. +// +// - Workflow errors. A typical workflow has multiple steps. Each step may +// have a `Status` message for error reporting purpose. +// +// - Batch operations. If a client uses batch request and batch response, the +// `Status` message should be used directly inside batch response, one for +// each error sub-response. +// +// - Asynchronous operations. If an API call embeds asynchronous operation +// results in its response, the status of those operations should be +// represented directly using the `Status` message. +// +// - Logging. If some API errors are stored in logs, the message `Status` could +// be used directly after any stripping needed for security/privacy reasons. +type Status struct { + // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. + Code int32 `protobuf:"varint,1,opt,name=code" json:"code,omitempty"` + // A developer-facing error message, which should be in English. Any + // user-facing error message should be localized and sent in the + // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + Message string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` + // A list of messages that carry the error details. There will be a + // common set of message types for APIs to use. + Details []*google_protobuf.Any `protobuf:"bytes,3,rep,name=details" json:"details,omitempty"` +} + +func (m *Status) Reset() { *m = Status{} } +func (m *Status) String() string { return proto.CompactTextString(m) } +func (*Status) ProtoMessage() {} +func (*Status) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *Status) GetCode() int32 { + if m != nil { + return m.Code + } + return 0 +} + +func (m *Status) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func (m *Status) GetDetails() []*google_protobuf.Any { + if m != nil { + return m.Details + } + return nil +} + +func init() { + proto.RegisterType((*Status)(nil), "google.rpc.Status") +} + +func init() { proto.RegisterFile("google/rpc/status.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 209 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4f, 0xcf, 0xcf, 0x4f, + 0xcf, 0x49, 0xd5, 0x2f, 0x2a, 0x48, 0xd6, 0x2f, 0x2e, 0x49, 0x2c, 0x29, 0x2d, 0xd6, 0x2b, 0x28, + 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x82, 0x48, 0xe8, 0x15, 0x15, 0x24, 0x4b, 0x49, 0x42, 0x15, 0x81, + 0x65, 0x92, 0x4a, 0xd3, 0xf4, 0x13, 0xf3, 0x2a, 0x21, 0xca, 0x94, 0xd2, 0xb8, 0xd8, 0x82, 0xc1, + 0xda, 0x84, 0x84, 0xb8, 0x58, 0x92, 0xf3, 0x53, 0x52, 0x25, 0x18, 0x15, 0x18, 0x35, 0x58, 0x83, + 0xc0, 0x6c, 0x21, 0x09, 0x2e, 0xf6, 0xdc, 0xd4, 0xe2, 0xe2, 0xc4, 0xf4, 0x54, 0x09, 0x26, 0x05, + 0x46, 0x0d, 0xce, 0x20, 0x18, 0x57, 0x48, 0x8f, 0x8b, 0x3d, 0x25, 0xb5, 0x24, 0x31, 0x33, 0xa7, + 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x44, 0x0f, 0x6a, 0x21, 0xcc, 0x12, 0x3d, 0xc7, + 0xbc, 0xca, 0x20, 0x98, 0x22, 0xa7, 0x38, 0x2e, 0xbe, 0xe4, 0xfc, 0x5c, 0x3d, 0x84, 0xa3, 0x9c, + 0xb8, 0x21, 0xf6, 0x06, 0x80, 0x94, 0x07, 0x30, 0x46, 0x99, 0x43, 0xa5, 0xd2, 0xf3, 0x73, 0x12, + 0xf3, 0xd2, 0xf5, 0xf2, 0x8b, 0xd2, 0xf5, 0xd3, 0x53, 0xf3, 0xc0, 0x86, 0xe9, 0x43, 0xa4, 0x12, + 0x0b, 0x32, 0x8b, 0x91, 0xfc, 0x69, 0x0d, 0xa1, 0x16, 0x31, 0x31, 0x07, 0x05, 0x38, 0x27, 0xb1, + 0x81, 0x55, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa4, 0x53, 0xf0, 0x7c, 0x10, 0x01, 0x00, + 0x00, +} diff --git a/components/cli/vendor/google.golang.org/grpc/README.md b/components/cli/vendor/google.golang.org/grpc/README.md index 110a8cf425..ae0236f92f 100644 --- a/components/cli/vendor/google.golang.org/grpc/README.md +++ b/components/cli/vendor/google.golang.org/grpc/README.md @@ -1,4 +1,4 @@ -#gRPC-Go +# gRPC-Go [![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go) [![GoDoc](https://godoc.org/google.golang.org/grpc?status.svg)](https://godoc.org/google.golang.org/grpc) @@ -16,7 +16,7 @@ $ go get google.golang.org/grpc Prerequisites ------------- -This requires Go 1.5 or later. +This requires Go 1.6 or later. Constraints ----------- @@ -30,3 +30,12 @@ Status ------ GA +FAQ +--- + +#### Compiling error, undefined: grpc.SupportPackageIsVersion + +Please update proto package, gRPC package and rebuild the proto files: + - `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}` + - `go get -u google.golang.org/grpc` + - `protoc --go_out=plugins=grpc:. *.proto` diff --git a/components/cli/vendor/google.golang.org/grpc/call.go b/components/cli/vendor/google.golang.org/grpc/call.go index 772c817edd..af34a71316 100644 --- a/components/cli/vendor/google.golang.org/grpc/call.go +++ b/components/cli/vendor/google.golang.org/grpc/call.go @@ -36,12 +36,14 @@ package grpc import ( "bytes" "io" - "math" "time" "golang.org/x/net/context" "golang.org/x/net/trace" "google.golang.org/grpc/codes" + "google.golang.org/grpc/peer" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/status" "google.golang.org/grpc/transport" ) @@ -49,7 +51,8 @@ import ( // On error, it returns the error and indicates whether the call should be retried. // // TODO(zhaoq): Check whether the received message sequence is valid. -func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) (err error) { +// TODO ctx is used for stats collection and processing. It is the context passed from the application. +func recvResponse(ctx context.Context, dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) (err error) { // Try to acquire header metadata from the server if there is any. defer func() { if err != nil { @@ -63,24 +66,34 @@ func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, s return } p := &parser{r: stream} + var inPayload *stats.InPayload + if dopts.copts.StatsHandler != nil { + inPayload = &stats.InPayload{ + Client: true, + } + } for { - if err = recv(p, dopts.codec, stream, dopts.dc, reply, math.MaxInt32); err != nil { + if err = recv(p, dopts.codec, stream, dopts.dc, reply, dopts.maxMsgSize, inPayload); err != nil { if err == io.EOF { break } return } } + if inPayload != nil && err == io.EOF && stream.Status().Code() == codes.OK { + // TODO in the current implementation, inTrailer may be handled before inPayload in some cases. + // Fix the order if necessary. + dopts.copts.StatsHandler.HandleRPC(ctx, inPayload) + } c.trailerMD = stream.Trailer() + if peer, ok := peer.FromContext(stream.Context()); ok { + c.peer = peer + } return nil } // sendRequest writes out various information of an RPC such as Context and Message. -func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHdr *transport.CallHdr, t transport.ClientTransport, args interface{}, opts *transport.Options) (_ *transport.Stream, err error) { - stream, err := t.NewStream(ctx, callHdr) - if err != nil { - return nil, err - } +func sendRequest(ctx context.Context, dopts dialOptions, compressor Compressor, callHdr *transport.CallHdr, stream *transport.Stream, t transport.ClientTransport, args interface{}, opts *transport.Options) (err error) { defer func() { if err != nil { // If err is connection error, t will be closed, no need to close stream here. @@ -89,23 +102,35 @@ func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHd } } }() - var cbuf *bytes.Buffer + var ( + cbuf *bytes.Buffer + outPayload *stats.OutPayload + ) if compressor != nil { cbuf = new(bytes.Buffer) } - outBuf, err := encode(codec, args, compressor, cbuf) + if dopts.copts.StatsHandler != nil { + outPayload = &stats.OutPayload{ + Client: true, + } + } + outBuf, err := encode(dopts.codec, args, compressor, cbuf, outPayload) if err != nil { - return nil, Errorf(codes.Internal, "grpc: %v", err) + return Errorf(codes.Internal, "grpc: %v", err) } err = t.Write(stream, outBuf, opts) + if err == nil && outPayload != nil { + outPayload.SentTime = time.Now() + dopts.copts.StatsHandler.HandleRPC(ctx, outPayload) + } // t.NewStream(...) could lead to an early rejection of the RPC (e.g., the service/method // does not exist.) so that t.Write could get io.EOF from wait(...). Leave the following // recvResponse to get the final status. if err != nil && err != io.EOF { - return nil, err + return err } // Sent successfully. - return stream, nil + return nil } // Invoke sends the RPC request on the wire and returns after response is received. @@ -118,8 +143,16 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli return invoke(ctx, method, args, reply, cc, opts...) } -func invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (err error) { +func invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (e error) { c := defaultCallInfo + if mc, ok := cc.getMethodConfig(method); ok { + c.failFast = !mc.WaitForReady + if mc.Timeout > 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, mc.Timeout) + defer cancel() + } + } for _, o := range opts { if err := o.before(&c); err != nil { return toRPCErr(err) @@ -140,12 +173,33 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli c.traceInfo.tr.LazyLog(&c.traceInfo.firstLine, false) // TODO(dsymonds): Arrange for c.traceInfo.firstLine.remoteAddr to be set. defer func() { - if err != nil { - c.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) + if e != nil { + c.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{e}}, true) c.traceInfo.tr.SetError() } }() } + ctx = newContextWithRPCInfo(ctx) + sh := cc.dopts.copts.StatsHandler + if sh != nil { + ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method}) + begin := &stats.Begin{ + Client: true, + BeginTime: time.Now(), + FailFast: c.failFast, + } + sh.HandleRPC(ctx, begin) + } + defer func() { + if sh != nil { + end := &stats.End{ + Client: true, + EndTime: time.Now(), + Error: e, + } + sh.HandleRPC(ctx, end) + } + }() topts := &transport.Options{ Last: true, Delay: false, @@ -167,13 +221,14 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli if cc.dopts.cp != nil { callHdr.SendCompress = cc.dopts.cp.Type() } + gopts := BalancerGetOptions{ BlockingWait: !c.failFast, } t, put, err = cc.getTransport(ctx, gopts) if err != nil { // TODO(zhaoq): Probably revisit the error handling. - if _, ok := err.(*rpcError); ok { + if _, ok := status.FromError(err); ok { return err } if err == errConnClosing || err == errConnUnavailable { @@ -188,33 +243,49 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli if c.traceInfo.tr != nil { c.traceInfo.tr.LazyLog(&payload{sent: true, msg: args}, true) } - stream, err = sendRequest(ctx, cc.dopts.codec, cc.dopts.cp, callHdr, t, args, topts) + stream, err = t.NewStream(ctx, callHdr) if err != nil { if put != nil { - put() - put = nil - } - // Retry a non-failfast RPC when - // i) there is a connection error; or - // ii) the server started to drain before this RPC was initiated. - if _, ok := err.(transport.ConnectionError); ok || err == transport.ErrStreamDrain { - if c.failFast { - return toRPCErr(err) + if _, ok := err.(transport.ConnectionError); ok { + // If error is connection error, transport was sending data on wire, + // and we are not sure if anything has been sent on wire. + // If error is not connection error, we are sure nothing has been sent. + updateRPCInfoInContext(ctx, rpcInfo{bytesSent: true, bytesReceived: false}) } + put() + } + if _, ok := err.(transport.ConnectionError); (ok || err == transport.ErrStreamDrain) && !c.failFast { continue } return toRPCErr(err) } - err = recvResponse(cc.dopts, t, &c, stream, reply) + err = sendRequest(ctx, cc.dopts, cc.dopts.cp, callHdr, stream, t, args, topts) if err != nil { if put != nil { + updateRPCInfoInContext(ctx, rpcInfo{ + bytesSent: stream.BytesSent(), + bytesReceived: stream.BytesReceived(), + }) put() - put = nil } - if _, ok := err.(transport.ConnectionError); ok || err == transport.ErrStreamDrain { - if c.failFast { - return toRPCErr(err) - } + // Retry a non-failfast RPC when + // i) there is a connection error; or + // ii) the server started to drain before this RPC was initiated. + if _, ok := err.(transport.ConnectionError); (ok || err == transport.ErrStreamDrain) && !c.failFast { + continue + } + return toRPCErr(err) + } + err = recvResponse(ctx, cc.dopts, t, &c, stream, reply) + if err != nil { + if put != nil { + updateRPCInfoInContext(ctx, rpcInfo{ + bytesSent: stream.BytesSent(), + bytesReceived: stream.BytesReceived(), + }) + put() + } + if _, ok := err.(transport.ConnectionError); (ok || err == transport.ErrStreamDrain) && !c.failFast { continue } return toRPCErr(err) @@ -224,9 +295,12 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli } t.CloseStream(stream, nil) if put != nil { + updateRPCInfoInContext(ctx, rpcInfo{ + bytesSent: stream.BytesSent(), + bytesReceived: stream.BytesReceived(), + }) put() - put = nil } - return Errorf(stream.StatusCode(), "%s", stream.StatusDesc()) + return stream.Status().Err() } } diff --git a/components/cli/vendor/google.golang.org/grpc/clientconn.go b/components/cli/vendor/google.golang.org/grpc/clientconn.go index 61674729a7..f542d8bd04 100644 --- a/components/cli/vendor/google.golang.org/grpc/clientconn.go +++ b/components/cli/vendor/google.golang.org/grpc/clientconn.go @@ -36,8 +36,8 @@ package grpc import ( "errors" "fmt" + "math" "net" - "strings" "sync" "time" @@ -45,6 +45,8 @@ import ( "golang.org/x/net/trace" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/keepalive" + "google.golang.org/grpc/stats" "google.golang.org/grpc/transport" ) @@ -54,6 +56,8 @@ var ( ErrClientConnClosing = errors.New("grpc: the client connection is closing") // ErrClientConnTimeout indicates that the ClientConn cannot establish the // underlying connections within the specified timeout. + // DEPRECATED: Please use context.DeadlineExceeded instead. This error will be + // removed in Q1 2017. ErrClientConnTimeout = errors.New("grpc: timed out when dialing") // errNoTransportSecurity indicates that there is no transport security @@ -75,7 +79,6 @@ var ( errConnClosing = errors.New("grpc: the connection is closing") // errConnUnavailable indicates that the connection is unavailable. errConnUnavailable = errors.New("grpc: the connection is unavailable") - errNoAddr = errors.New("grpc: there is no address available to dial") // minimum time to give a connection to complete minConnectTimeout = 20 * time.Second ) @@ -83,22 +86,33 @@ var ( // dialOptions configure a Dial call. dialOptions are set by the DialOption // values passed to Dial. type dialOptions struct { - unaryInt UnaryClientInterceptor - streamInt StreamClientInterceptor - codec Codec - cp Compressor - dc Decompressor - bs backoffStrategy - balancer Balancer - block bool - insecure bool - timeout time.Duration - copts transport.ConnectOptions + unaryInt UnaryClientInterceptor + streamInt StreamClientInterceptor + codec Codec + cp Compressor + dc Decompressor + bs backoffStrategy + balancer Balancer + block bool + insecure bool + timeout time.Duration + scChan <-chan ServiceConfig + copts transport.ConnectOptions + maxMsgSize int } +const defaultClientMaxMsgSize = math.MaxInt32 + // DialOption configures how we set up the connection. type DialOption func(*dialOptions) +// WithMaxMsgSize returns a DialOption which sets the maximum message size the client can receive. +func WithMaxMsgSize(s int) DialOption { + return func(o *dialOptions) { + o.maxMsgSize = s + } +} + // WithCodec returns a DialOption which sets a codec for message marshaling and unmarshaling. func WithCodec(c Codec) DialOption { return func(o *dialOptions) { @@ -129,6 +143,13 @@ func WithBalancer(b Balancer) DialOption { } } +// WithServiceConfig returns a DialOption which has a channel to read the service configuration. +func WithServiceConfig(c <-chan ServiceConfig) DialOption { + return func(o *dialOptions) { + o.scChan = c + } +} + // WithBackoffMaxDelay configures the dialer to use the provided maximum delay // when backing off after failed connection attempts. func WithBackoffMaxDelay(md time.Duration) DialOption { @@ -199,6 +220,8 @@ func WithTimeout(d time.Duration) DialOption { } // WithDialer returns a DialOption that specifies a function to use for dialing network addresses. +// If FailOnNonTempDialError() is set to true, and an error is returned by f, gRPC checks the error's +// Temporary() method to decide if it should try to reconnect to the network address. func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption { return func(o *dialOptions) { o.copts.Dialer = func(ctx context.Context, addr string) (net.Conn, error) { @@ -210,6 +233,25 @@ func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption { } } +// WithStatsHandler returns a DialOption that specifies the stats handler +// for all the RPCs and underlying network connections in this ClientConn. +func WithStatsHandler(h stats.Handler) DialOption { + return func(o *dialOptions) { + o.copts.StatsHandler = h + } +} + +// FailOnNonTempDialError returns a DialOption that specified if gRPC fails on non-temporary dial errors. +// If f is true, and dialer returns a non-temporary error, gRPC will fail the connection to the network +// address and won't try to reconnect. +// The default value of FailOnNonTempDialError is false. +// This is an EXPERIMENTAL API. +func FailOnNonTempDialError(f bool) DialOption { + return func(o *dialOptions) { + o.copts.FailOnNonTempDialError = f + } +} + // WithUserAgent returns a DialOption that specifies a user agent string for all the RPCs. func WithUserAgent(s string) DialOption { return func(o *dialOptions) { @@ -217,6 +259,13 @@ func WithUserAgent(s string) DialOption { } } +// WithKeepaliveParams returns a DialOption that specifies keepalive paramaters for the client transport. +func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption { + return func(o *dialOptions) { + o.copts.KeepaliveParams = kp + } +} + // WithUnaryInterceptor returns a DialOption that specifies the interceptor for unary RPCs. func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption { return func(o *dialOptions) { @@ -231,6 +280,15 @@ func WithStreamInterceptor(f StreamClientInterceptor) DialOption { } } +// WithAuthority returns a DialOption that specifies the value to be used as +// the :authority pseudo-header. This value only works with WithInsecure and +// has no effect if TransportCredentials are present. +func WithAuthority(a string) DialOption { + return func(o *dialOptions) { + o.copts.Authority = a + } +} + // Dial creates a client connection to the given target. func Dial(target string, opts ...DialOption) (*ClientConn, error) { return DialContext(context.Background(), target, opts...) @@ -247,6 +305,32 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * conns: make(map[Address]*addrConn), } cc.ctx, cc.cancel = context.WithCancel(context.Background()) + cc.dopts.maxMsgSize = defaultClientMaxMsgSize + for _, opt := range opts { + opt(&cc.dopts) + } + cc.mkp = cc.dopts.copts.KeepaliveParams + + if cc.dopts.copts.Dialer == nil { + cc.dopts.copts.Dialer = newProxyDialer( + func(ctx context.Context, addr string) (net.Conn, error) { + return dialContext(ctx, "tcp", addr) + }, + ) + } + + if cc.dopts.copts.UserAgent != "" { + cc.dopts.copts.UserAgent += " " + grpcUA + } else { + cc.dopts.copts.UserAgent = grpcUA + } + + if cc.dopts.timeout > 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, cc.dopts.timeout) + defer cancel() + } + defer func() { select { case <-ctx.Done(): @@ -259,10 +343,17 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } }() - for _, opt := range opts { - opt(&cc.dopts) + if cc.dopts.scChan != nil { + // Wait for the initial service config. + select { + case sc, ok := <-cc.dopts.scChan: + if ok { + cc.sc = sc + } + case <-ctx.Done(): + return nil, ctx.Err() + } } - // Set defaults. if cc.dopts.codec == nil { cc.dopts.codec = protoCodec{} @@ -273,21 +364,18 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * creds := cc.dopts.copts.TransportCredentials if creds != nil && creds.Info().ServerName != "" { cc.authority = creds.Info().ServerName + } else if cc.dopts.insecure && cc.dopts.copts.Authority != "" { + cc.authority = cc.dopts.copts.Authority } else { - colonPos := strings.LastIndex(target, ":") - if colonPos == -1 { - colonPos = len(target) - } - cc.authority = target[:colonPos] + cc.authority = target } - var ok bool waitC := make(chan error, 1) go func() { - var addrs []Address - if cc.dopts.balancer == nil { - // Connect to target directly if balancer is nil. - addrs = append(addrs, Address{Addr: target}) - } else { + defer close(waitC) + if cc.dopts.balancer == nil && cc.sc.LB != nil { + cc.dopts.balancer = cc.sc.LB + } + if cc.dopts.balancer != nil { var credsClone credentials.TransportCredentials if creds != nil { credsClone = creds.Clone() @@ -300,29 +388,23 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * return } ch := cc.dopts.balancer.Notify() - if ch == nil { - // There is no name resolver installed. - addrs = append(addrs, Address{Addr: target}) - } else { - addrs, ok = <-ch - if !ok || len(addrs) == 0 { - waitC <- errNoAddr - return + if ch != nil { + if cc.dopts.block { + doneChan := make(chan struct{}) + go cc.lbWatcher(doneChan) + <-doneChan + } else { + go cc.lbWatcher(nil) } - } - } - for _, a := range addrs { - if err := cc.resetAddrConn(a, false, nil); err != nil { - waitC <- err return } } - close(waitC) + // No balancer, or no resolver within the balancer. Connect directly. + if err := cc.resetAddrConn(Address{Addr: target}, cc.dopts.block, nil); err != nil { + waitC <- err + return + } }() - var timeoutCh <-chan time.Time - if cc.dopts.timeout > 0 { - timeoutCh = time.After(cc.dopts.timeout) - } select { case <-ctx.Done(): return nil, ctx.Err() @@ -330,14 +412,12 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * if err != nil { return nil, err } - case <-timeoutCh: - return nil, ErrClientConnTimeout } - // If balancer is nil or balancer.Notify() is nil, ok will be false here. - // The lbWatcher goroutine will not be created. - if ok { - go cc.lbWatcher() + + if cc.dopts.scChan != nil { + go cc.scWatcher() } + return cc, nil } @@ -384,10 +464,16 @@ type ClientConn struct { dopts dialOptions mu sync.RWMutex + sc ServiceConfig conns map[Address]*addrConn + // Keepalive parameter can be udated if a GoAway is received. + mkp keepalive.ClientParameters } -func (cc *ClientConn) lbWatcher() { +// lbWatcher watches the Notify channel of the balancer in cc and manages +// connections accordingly. If doneChan is not nil, it is closed after the +// first successfull connection is made. +func (cc *ClientConn) lbWatcher(doneChan chan struct{}) { for addrs := range cc.dopts.balancer.Notify() { var ( add []Address // Addresses need to setup connections. @@ -414,7 +500,15 @@ func (cc *ClientConn) lbWatcher() { } cc.mu.Unlock() for _, a := range add { - cc.resetAddrConn(a, true, nil) + if doneChan != nil { + err := cc.resetAddrConn(a, true, nil) + if err == nil { + close(doneChan) + doneChan = nil + } + } else { + cc.resetAddrConn(a, false, nil) + } } for _, c := range del { c.tearDown(errConnDrain) @@ -422,15 +516,36 @@ func (cc *ClientConn) lbWatcher() { } } +func (cc *ClientConn) scWatcher() { + for { + select { + case sc, ok := <-cc.dopts.scChan: + if !ok { + return + } + cc.mu.Lock() + // TODO: load balance policy runtime change is ignored. + // We may revist this decision in the future. + cc.sc = sc + cc.mu.Unlock() + case <-cc.ctx.Done(): + return + } + } +} + // resetAddrConn creates an addrConn for addr and adds it to cc.conns. // If there is an old addrConn for addr, it will be torn down, using tearDownErr as the reason. // If tearDownErr is nil, errConnDrain will be used instead. -func (cc *ClientConn) resetAddrConn(addr Address, skipWait bool, tearDownErr error) error { +func (cc *ClientConn) resetAddrConn(addr Address, block bool, tearDownErr error) error { ac := &addrConn{ cc: cc, addr: addr, dopts: cc.dopts, } + cc.mu.RLock() + ac.dopts.copts.KeepaliveParams = cc.mkp + cc.mu.RUnlock() ac.ctx, ac.cancel = context.WithCancel(cc.ctx) ac.stateCV = sync.NewCond(&ac.mu) if EnableTracing { @@ -475,8 +590,7 @@ func (cc *ClientConn) resetAddrConn(addr Address, skipWait bool, tearDownErr err stale.tearDown(tearDownErr) } } - // skipWait may overwrite the decision in ac.dopts.block. - if ac.dopts.block && !skipWait { + if block { if err := ac.resetTransport(false); err != nil { if err != errConnClosing { // Tear down ac and delete it from cc.conns. @@ -509,6 +623,14 @@ func (cc *ClientConn) resetAddrConn(addr Address, skipWait bool, tearDownErr err return nil } +// TODO: Avoid the locking here. +func (cc *ClientConn) getMethodConfig(method string) (m MethodConfig, ok bool) { + cc.mu.RLock() + defer cc.mu.RUnlock() + m, ok = cc.sc.Methods[method] + return +} + func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) (transport.ClientTransport, func(), error) { var ( ac *addrConn @@ -547,6 +669,7 @@ func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) } if !ok { if put != nil { + updateRPCInfoInContext(ctx, rpcInfo{bytesSent: false, bytesReceived: false}) put() } return nil, nil, errConnClosing @@ -554,6 +677,7 @@ func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) t, err := ac.wait(ctx, cc.dopts.balancer != nil, !opts.BlockingWait) if err != nil { if put != nil { + updateRPCInfoInContext(ctx, rpcInfo{bytesSent: false, bytesReceived: false}) put() } return nil, nil, err @@ -605,6 +729,20 @@ type addrConn struct { tearDownErr error } +// adjustParams updates parameters used to create transports upon +// receiving a GoAway. +func (ac *addrConn) adjustParams(r transport.GoAwayReason) { + switch r { + case transport.TooManyPings: + v := 2 * ac.dopts.copts.KeepaliveParams.Time + ac.cc.mu.Lock() + if v > ac.cc.mkp.Time { + ac.cc.mkp.Time = v + } + ac.cc.mu.Unlock() + } +} + // printf records an event in ac's event log, unless ac has been closed. // REQUIRES ac.mu is held. func (ac *addrConn) printf(format string, a ...interface{}) { @@ -689,6 +827,8 @@ func (ac *addrConn) resetTransport(closeTransport bool) error { Metadata: ac.addr.Metadata, } newTransport, err := transport.NewClientTransport(ctx, sinfo, ac.dopts.copts) + // Don't call cancel in success path due to a race in Go 1.6: + // https://github.com/golang/go/issues/15078. if err != nil { cancel() @@ -759,6 +899,7 @@ func (ac *addrConn) transportMonitor() { } return case <-t.GoAway(): + ac.adjustParams(t.GetGoAwayReason()) // If GoAway happens without any network I/O error, ac is closed without shutting down the // underlying transport (the transport will be closed when all the pending RPCs finished or // failed.). @@ -767,9 +908,9 @@ func (ac *addrConn) transportMonitor() { // In both cases, a new ac is created. select { case <-t.Error(): - ac.cc.resetAddrConn(ac.addr, true, errNetworkIO) + ac.cc.resetAddrConn(ac.addr, false, errNetworkIO) default: - ac.cc.resetAddrConn(ac.addr, true, errConnDrain) + ac.cc.resetAddrConn(ac.addr, false, errConnDrain) } return case <-t.Error(): @@ -778,7 +919,8 @@ func (ac *addrConn) transportMonitor() { t.Close() return case <-t.GoAway(): - ac.cc.resetAddrConn(ac.addr, true, errNetworkIO) + ac.adjustParams(t.GetGoAwayReason()) + ac.cc.resetAddrConn(ac.addr, false, errNetworkIO) return default: } diff --git a/components/cli/vendor/google.golang.org/grpc/codec.go b/components/cli/vendor/google.golang.org/grpc/codec.go new file mode 100644 index 0000000000..bd76ebb7f1 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/codec.go @@ -0,0 +1,118 @@ +/* +* + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +package grpc + +import ( + "math" + "sync" + + "github.com/golang/protobuf/proto" +) + +// Codec defines the interface gRPC uses to encode and decode messages. +// Note that implementations of this interface must be thread safe; +// a Codec's methods can be called from concurrent goroutines. +type Codec interface { + // Marshal returns the wire format of v. + Marshal(v interface{}) ([]byte, error) + // Unmarshal parses the wire format into v. + Unmarshal(data []byte, v interface{}) error + // String returns the name of the Codec implementation. The returned + // string will be used as part of content type in transmission. + String() string +} + +// protoCodec is a Codec implementation with protobuf. It is the default codec for gRPC. +type protoCodec struct { +} + +type cachedProtoBuffer struct { + lastMarshaledSize uint32 + proto.Buffer +} + +func capToMaxInt32(val int) uint32 { + if val > math.MaxInt32 { + return uint32(math.MaxInt32) + } + return uint32(val) +} + +func (p protoCodec) marshal(v interface{}, cb *cachedProtoBuffer) ([]byte, error) { + protoMsg := v.(proto.Message) + newSlice := make([]byte, 0, cb.lastMarshaledSize) + + cb.SetBuf(newSlice) + cb.Reset() + if err := cb.Marshal(protoMsg); err != nil { + return nil, err + } + out := cb.Bytes() + cb.lastMarshaledSize = capToMaxInt32(len(out)) + return out, nil +} + +func (p protoCodec) Marshal(v interface{}) ([]byte, error) { + cb := protoBufferPool.Get().(*cachedProtoBuffer) + out, err := p.marshal(v, cb) + + // put back buffer and lose the ref to the slice + cb.SetBuf(nil) + protoBufferPool.Put(cb) + return out, err +} + +func (p protoCodec) Unmarshal(data []byte, v interface{}) error { + cb := protoBufferPool.Get().(*cachedProtoBuffer) + cb.SetBuf(data) + err := cb.Unmarshal(v.(proto.Message)) + cb.SetBuf(nil) + protoBufferPool.Put(cb) + return err +} + +func (protoCodec) String() string { + return "proto" +} + +var ( + protoBufferPool = &sync.Pool{ + New: func() interface{} { + return &cachedProtoBuffer{ + Buffer: proto.Buffer{}, + lastMarshaledSize: 16, + } + }, + } +) diff --git a/components/cli/vendor/google.golang.org/grpc/credentials/credentials.go b/components/cli/vendor/google.golang.org/grpc/credentials/credentials.go index 5555ef024f..a8114d6713 100644 --- a/components/cli/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/components/cli/vendor/google.golang.org/grpc/credentials/credentials.go @@ -102,6 +102,10 @@ type TransportCredentials interface { // authentication protocol on rawConn for clients. It returns the authenticated // connection and the corresponding auth information about the connection. // Implementations must use the provided context to implement timely cancellation. + // gRPC will try to reconnect if the error returned is a temporary error + // (io.EOF, context.DeadlineExceeded or err.Temporary() == true). + // If the returned error is a wrapper error, implementations should make sure that + // the error implements Temporary() to have the correct retry behaviors. ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error) // ServerHandshake does the authentication handshake for servers. It returns // the authenticated connection and the corresponding auth information about @@ -165,9 +169,7 @@ func (c *tlsCreds) ClientHandshake(ctx context.Context, addr string, rawConn net case <-ctx.Done(): return nil, nil, ctx.Err() } - // TODO(zhaoq): Omit the auth info for client now. It is more for - // information than anything else. - return conn, nil, nil + return conn, TLSInfo{conn.ConnectionState()}, nil } func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) { diff --git a/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go b/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go index 9647b9ec83..7597b09e35 100644 --- a/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go +++ b/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go @@ -1,4 +1,5 @@ // +build go1.7 +// +build !go1.8 /* * @@ -44,8 +45,6 @@ import ( // contains a mutex and must not be copied. // // If cfg is nil, a new zero tls.Config is returned. -// -// TODO replace this function with official clone function. func cloneTLSConfig(cfg *tls.Config) *tls.Config { if cfg == nil { return &tls.Config{} diff --git a/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go b/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go new file mode 100644 index 0000000000..0ecf342da8 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go @@ -0,0 +1,53 @@ +// +build go1.8 + +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package credentials + +import ( + "crypto/tls" +) + +// cloneTLSConfig returns a shallow clone of the exported +// fields of cfg, ignoring the unexported sync.Once, which +// contains a mutex and must not be copied. +// +// If cfg is nil, a new zero tls.Config is returned. +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + + return cfg.Clone() +} diff --git a/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go b/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go index 09b8d12c79..cfd40dfa34 100644 --- a/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go +++ b/components/cli/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go @@ -44,8 +44,6 @@ import ( // contains a mutex and must not be copied. // // If cfg is nil, a new zero tls.Config is returned. -// -// TODO replace this function with official clone function. func cloneTLSConfig(cfg *tls.Config) *tls.Config { if cfg == nil { return &tls.Config{} diff --git a/components/cli/vendor/google.golang.org/grpc/go16.go b/components/cli/vendor/google.golang.org/grpc/go16.go new file mode 100644 index 0000000000..b61c57e88d --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/go16.go @@ -0,0 +1,56 @@ +// +build go1.6,!go1.7 + +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package grpc + +import ( + "fmt" + "net" + "net/http" + + "golang.org/x/net/context" +) + +// dialContext connects to the address on the named network. +func dialContext(ctx context.Context, network, address string) (net.Conn, error) { + return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address) +} + +func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error { + req.Cancel = ctx.Done() + if err := req.Write(conn); err != nil { + return fmt.Errorf("failed to write the HTTP request: %v", err) + } + return nil +} diff --git a/components/cli/vendor/google.golang.org/grpc/transport/pre_go16.go b/components/cli/vendor/google.golang.org/grpc/go17.go similarity index 86% rename from components/cli/vendor/google.golang.org/grpc/transport/pre_go16.go rename to components/cli/vendor/google.golang.org/grpc/go17.go index 33d91c17c4..844f0e1899 100644 --- a/components/cli/vendor/google.golang.org/grpc/transport/pre_go16.go +++ b/components/cli/vendor/google.golang.org/grpc/go17.go @@ -1,4 +1,4 @@ -// +build !go1.6 +// +build go1.7 /* * Copyright 2016, Google Inc. @@ -32,20 +32,24 @@ * */ -package transport +package grpc import ( "net" - "time" + "net/http" "golang.org/x/net/context" ) // dialContext connects to the address on the named network. func dialContext(ctx context.Context, network, address string) (net.Conn, error) { - var dialer net.Dialer - if deadline, ok := ctx.Deadline(); ok { - dialer.Timeout = deadline.Sub(time.Now()) + return (&net.Dialer{}).DialContext(ctx, network, address) +} + +func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error { + req = req.WithContext(ctx) + if err := req.Write(conn); err != nil { + return err } - return dialer.Dial(network, address) + return nil } diff --git a/components/cli/vendor/google.golang.org/grpc/grpclb.go b/components/cli/vendor/google.golang.org/grpc/grpclb.go new file mode 100644 index 0000000000..524e429df3 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/grpclb.go @@ -0,0 +1,749 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package grpc + +import ( + "errors" + "fmt" + "math/rand" + "net" + "sync" + "time" + + "golang.org/x/net/context" + "google.golang.org/grpc/codes" + lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/naming" +) + +// Client API for LoadBalancer service. +// Mostly copied from generated pb.go file. +// To avoid circular dependency. +type loadBalancerClient struct { + cc *ClientConn +} + +func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ...CallOption) (*balanceLoadClientStream, error) { + desc := &StreamDesc{ + StreamName: "BalanceLoad", + ServerStreams: true, + ClientStreams: true, + } + stream, err := NewClientStream(ctx, desc, c.cc, "/grpc.lb.v1.LoadBalancer/BalanceLoad", opts...) + if err != nil { + return nil, err + } + x := &balanceLoadClientStream{stream} + return x, nil +} + +type balanceLoadClientStream struct { + ClientStream +} + +func (x *balanceLoadClientStream) Send(m *lbpb.LoadBalanceRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *balanceLoadClientStream) Recv() (*lbpb.LoadBalanceResponse, error) { + m := new(lbpb.LoadBalanceResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// AddressType indicates the address type returned by name resolution. +type AddressType uint8 + +const ( + // Backend indicates the server is a backend server. + Backend AddressType = iota + // GRPCLB indicates the server is a grpclb load balancer. + GRPCLB +) + +// AddrMetadataGRPCLB contains the information the name resolution for grpclb should provide. The +// name resolver used by grpclb balancer is required to provide this type of metadata in +// its address updates. +type AddrMetadataGRPCLB struct { + // AddrType is the type of server (grpc load balancer or backend). + AddrType AddressType + // ServerName is the name of the grpc load balancer. Used for authentication. + ServerName string +} + +// NewGRPCLBBalancer creates a grpclb load balancer. +func NewGRPCLBBalancer(r naming.Resolver) Balancer { + return &balancer{ + r: r, + } +} + +type remoteBalancerInfo struct { + addr string + // the server name used for authentication with the remote LB server. + name string +} + +// grpclbAddrInfo consists of the information of a backend server. +type grpclbAddrInfo struct { + addr Address + connected bool + // dropForRateLimiting indicates whether this particular request should be + // dropped by the client for rate limiting. + dropForRateLimiting bool + // dropForLoadBalancing indicates whether this particular request should be + // dropped by the client for load balancing. + dropForLoadBalancing bool +} + +type balancer struct { + r naming.Resolver + target string + mu sync.Mutex + seq int // a sequence number to make sure addrCh does not get stale addresses. + w naming.Watcher + addrCh chan []Address + rbs []remoteBalancerInfo + addrs []*grpclbAddrInfo + next int + waitCh chan struct{} + done bool + expTimer *time.Timer + rand *rand.Rand + + clientStats lbpb.ClientStats +} + +func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan []remoteBalancerInfo) error { + updates, err := w.Next() + if err != nil { + return err + } + b.mu.Lock() + defer b.mu.Unlock() + if b.done { + return ErrClientConnClosing + } + for _, update := range updates { + switch update.Op { + case naming.Add: + var exist bool + for _, v := range b.rbs { + // TODO: Is the same addr with different server name a different balancer? + if update.Addr == v.addr { + exist = true + break + } + } + if exist { + continue + } + md, ok := update.Metadata.(*AddrMetadataGRPCLB) + if !ok { + // TODO: Revisit the handling here and may introduce some fallback mechanism. + grpclog.Printf("The name resolution contains unexpected metadata %v", update.Metadata) + continue + } + switch md.AddrType { + case Backend: + // TODO: Revisit the handling here and may introduce some fallback mechanism. + grpclog.Printf("The name resolution does not give grpclb addresses") + continue + case GRPCLB: + b.rbs = append(b.rbs, remoteBalancerInfo{ + addr: update.Addr, + name: md.ServerName, + }) + default: + grpclog.Printf("Received unknow address type %d", md.AddrType) + continue + } + case naming.Delete: + for i, v := range b.rbs { + if update.Addr == v.addr { + copy(b.rbs[i:], b.rbs[i+1:]) + b.rbs = b.rbs[:len(b.rbs)-1] + break + } + } + default: + grpclog.Println("Unknown update.Op ", update.Op) + } + } + // TODO: Fall back to the basic round-robin load balancing if the resulting address is + // not a load balancer. + select { + case <-ch: + default: + } + ch <- b.rbs + return nil +} + +func (b *balancer) serverListExpire(seq int) { + b.mu.Lock() + defer b.mu.Unlock() + // TODO: gRPC interanls do not clear the connections when the server list is stale. + // This means RPCs will keep using the existing server list until b receives new + // server list even though the list is expired. Revisit this behavior later. + if b.done || seq < b.seq { + return + } + b.next = 0 + b.addrs = nil + // Ask grpc internals to close all the corresponding connections. + b.addrCh <- nil +} + +func convertDuration(d *lbpb.Duration) time.Duration { + if d == nil { + return 0 + } + return time.Duration(d.Seconds)*time.Second + time.Duration(d.Nanos)*time.Nanosecond +} + +func (b *balancer) processServerList(l *lbpb.ServerList, seq int) { + if l == nil { + return + } + servers := l.GetServers() + expiration := convertDuration(l.GetExpirationInterval()) + var ( + sl []*grpclbAddrInfo + addrs []Address + ) + for _, s := range servers { + md := metadata.Pairs("lb-token", s.LoadBalanceToken) + addr := Address{ + Addr: fmt.Sprintf("%s:%d", net.IP(s.IpAddress), s.Port), + Metadata: &md, + } + sl = append(sl, &grpclbAddrInfo{ + addr: addr, + dropForRateLimiting: s.DropForRateLimiting, + dropForLoadBalancing: s.DropForLoadBalancing, + }) + addrs = append(addrs, addr) + } + b.mu.Lock() + defer b.mu.Unlock() + if b.done || seq < b.seq { + return + } + if len(sl) > 0 { + // reset b.next to 0 when replacing the server list. + b.next = 0 + b.addrs = sl + b.addrCh <- addrs + if b.expTimer != nil { + b.expTimer.Stop() + b.expTimer = nil + } + if expiration > 0 { + b.expTimer = time.AfterFunc(expiration, func() { + b.serverListExpire(seq) + }) + } + } + return +} + +func (b *balancer) sendLoadReport(s *balanceLoadClientStream, interval time.Duration, done <-chan struct{}) { + ticker := time.NewTicker(interval) + defer ticker.Stop() + for { + select { + case <-ticker.C: + case <-done: + return + } + b.mu.Lock() + stats := b.clientStats + b.clientStats = lbpb.ClientStats{} // Clear the stats. + b.mu.Unlock() + t := time.Now() + stats.Timestamp = &lbpb.Timestamp{ + Seconds: t.Unix(), + Nanos: int32(t.Nanosecond()), + } + if err := s.Send(&lbpb.LoadBalanceRequest{ + LoadBalanceRequestType: &lbpb.LoadBalanceRequest_ClientStats{ + ClientStats: &stats, + }, + }); err != nil { + return + } + } +} + +func (b *balancer) callRemoteBalancer(lbc *loadBalancerClient, seq int) (retry bool) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + stream, err := lbc.BalanceLoad(ctx) + if err != nil { + grpclog.Printf("Failed to perform RPC to the remote balancer %v", err) + return + } + b.mu.Lock() + if b.done { + b.mu.Unlock() + return + } + b.mu.Unlock() + initReq := &lbpb.LoadBalanceRequest{ + LoadBalanceRequestType: &lbpb.LoadBalanceRequest_InitialRequest{ + InitialRequest: &lbpb.InitialLoadBalanceRequest{ + Name: b.target, + }, + }, + } + if err := stream.Send(initReq); err != nil { + // TODO: backoff on retry? + return true + } + reply, err := stream.Recv() + if err != nil { + // TODO: backoff on retry? + return true + } + initResp := reply.GetInitialResponse() + if initResp == nil { + grpclog.Println("Failed to receive the initial response from the remote balancer.") + return + } + // TODO: Support delegation. + if initResp.LoadBalancerDelegate != "" { + // delegation + grpclog.Println("TODO: Delegation is not supported yet.") + return + } + streamDone := make(chan struct{}) + defer close(streamDone) + b.mu.Lock() + b.clientStats = lbpb.ClientStats{} // Clear client stats. + b.mu.Unlock() + if d := convertDuration(initResp.ClientStatsReportInterval); d > 0 { + go b.sendLoadReport(stream, d, streamDone) + } + // Retrieve the server list. + for { + reply, err := stream.Recv() + if err != nil { + break + } + b.mu.Lock() + if b.done || seq < b.seq { + b.mu.Unlock() + return + } + b.seq++ // tick when receiving a new list of servers. + seq = b.seq + b.mu.Unlock() + if serverList := reply.GetServerList(); serverList != nil { + b.processServerList(serverList, seq) + } + } + return true +} + +func (b *balancer) Start(target string, config BalancerConfig) error { + b.rand = rand.New(rand.NewSource(time.Now().Unix())) + // TODO: Fall back to the basic direct connection if there is no name resolver. + if b.r == nil { + return errors.New("there is no name resolver installed") + } + b.target = target + b.mu.Lock() + if b.done { + b.mu.Unlock() + return ErrClientConnClosing + } + b.addrCh = make(chan []Address) + w, err := b.r.Resolve(target) + if err != nil { + b.mu.Unlock() + return err + } + b.w = w + b.mu.Unlock() + balancerAddrsCh := make(chan []remoteBalancerInfo, 1) + // Spawn a goroutine to monitor the name resolution of remote load balancer. + go func() { + for { + if err := b.watchAddrUpdates(w, balancerAddrsCh); err != nil { + grpclog.Printf("grpc: the naming watcher stops working due to %v.\n", err) + close(balancerAddrsCh) + return + } + } + }() + // Spawn a goroutine to talk to the remote load balancer. + go func() { + var ( + cc *ClientConn + // ccError is closed when there is an error in the current cc. + // A new rb should be picked from rbs and connected. + ccError chan struct{} + rb *remoteBalancerInfo + rbs []remoteBalancerInfo + rbIdx int + ) + + defer func() { + if ccError != nil { + select { + case <-ccError: + default: + close(ccError) + } + } + if cc != nil { + cc.Close() + } + }() + + for { + var ok bool + select { + case rbs, ok = <-balancerAddrsCh: + if !ok { + return + } + foundIdx := -1 + if rb != nil { + for i, trb := range rbs { + if trb == *rb { + foundIdx = i + break + } + } + } + if foundIdx >= 0 { + if foundIdx >= 1 { + // Move the address in use to the beginning of the list. + b.rbs[0], b.rbs[foundIdx] = b.rbs[foundIdx], b.rbs[0] + rbIdx = 0 + } + continue // If found, don't dial new cc. + } else if len(rbs) > 0 { + // Pick a random one from the list, instead of always using the first one. + if l := len(rbs); l > 1 && rb != nil { + tmpIdx := b.rand.Intn(l - 1) + b.rbs[0], b.rbs[tmpIdx] = b.rbs[tmpIdx], b.rbs[0] + } + rbIdx = 0 + rb = &rbs[0] + } else { + // foundIdx < 0 && len(rbs) <= 0. + rb = nil + } + case <-ccError: + ccError = nil + if rbIdx < len(rbs)-1 { + rbIdx++ + rb = &rbs[rbIdx] + } else { + rb = nil + } + } + + if rb == nil { + continue + } + + if cc != nil { + cc.Close() + } + // Talk to the remote load balancer to get the server list. + var err error + creds := config.DialCreds + ccError = make(chan struct{}) + if creds == nil { + cc, err = Dial(rb.addr, WithInsecure()) + } else { + if rb.name != "" { + if err := creds.OverrideServerName(rb.name); err != nil { + grpclog.Printf("Failed to override the server name in the credentials: %v", err) + continue + } + } + cc, err = Dial(rb.addr, WithTransportCredentials(creds)) + } + if err != nil { + grpclog.Printf("Failed to setup a connection to the remote balancer %v: %v", rb.addr, err) + close(ccError) + continue + } + b.mu.Lock() + b.seq++ // tick when getting a new balancer address + seq := b.seq + b.next = 0 + b.mu.Unlock() + go func(cc *ClientConn, ccError chan struct{}) { + lbc := &loadBalancerClient{cc} + b.callRemoteBalancer(lbc, seq) + cc.Close() + select { + case <-ccError: + default: + close(ccError) + } + }(cc, ccError) + } + }() + return nil +} + +func (b *balancer) down(addr Address, err error) { + b.mu.Lock() + defer b.mu.Unlock() + for _, a := range b.addrs { + if addr == a.addr { + a.connected = false + break + } + } +} + +func (b *balancer) Up(addr Address) func(error) { + b.mu.Lock() + defer b.mu.Unlock() + if b.done { + return nil + } + var cnt int + for _, a := range b.addrs { + if a.addr == addr { + if a.connected { + return nil + } + a.connected = true + } + if a.connected && !a.dropForRateLimiting && !a.dropForLoadBalancing { + cnt++ + } + } + // addr is the only one which is connected. Notify the Get() callers who are blocking. + if cnt == 1 && b.waitCh != nil { + close(b.waitCh) + b.waitCh = nil + } + return func(err error) { + b.down(addr, err) + } +} + +func (b *balancer) Get(ctx context.Context, opts BalancerGetOptions) (addr Address, put func(), err error) { + var ch chan struct{} + b.mu.Lock() + if b.done { + b.mu.Unlock() + err = ErrClientConnClosing + return + } + seq := b.seq + + defer func() { + if err != nil { + return + } + put = func() { + s, ok := rpcInfoFromContext(ctx) + if !ok { + return + } + b.mu.Lock() + defer b.mu.Unlock() + if b.done || seq < b.seq { + return + } + b.clientStats.NumCallsFinished++ + if !s.bytesSent { + b.clientStats.NumCallsFinishedWithClientFailedToSend++ + } else if s.bytesReceived { + b.clientStats.NumCallsFinishedKnownReceived++ + } + } + }() + + b.clientStats.NumCallsStarted++ + if len(b.addrs) > 0 { + if b.next >= len(b.addrs) { + b.next = 0 + } + next := b.next + for { + a := b.addrs[next] + next = (next + 1) % len(b.addrs) + if a.connected { + if !a.dropForRateLimiting && !a.dropForLoadBalancing { + addr = a.addr + b.next = next + b.mu.Unlock() + return + } + if !opts.BlockingWait { + b.next = next + if a.dropForLoadBalancing { + b.clientStats.NumCallsFinished++ + b.clientStats.NumCallsFinishedWithDropForLoadBalancing++ + } else if a.dropForRateLimiting { + b.clientStats.NumCallsFinished++ + b.clientStats.NumCallsFinishedWithDropForRateLimiting++ + } + b.mu.Unlock() + err = Errorf(codes.Unavailable, "%s drops requests", a.addr.Addr) + return + } + } + if next == b.next { + // Has iterated all the possible address but none is connected. + break + } + } + } + if !opts.BlockingWait { + if len(b.addrs) == 0 { + b.clientStats.NumCallsFinished++ + b.clientStats.NumCallsFinishedWithClientFailedToSend++ + b.mu.Unlock() + err = Errorf(codes.Unavailable, "there is no address available") + return + } + // Returns the next addr on b.addrs for a failfast RPC. + addr = b.addrs[b.next].addr + b.next++ + b.mu.Unlock() + return + } + // Wait on b.waitCh for non-failfast RPCs. + if b.waitCh == nil { + ch = make(chan struct{}) + b.waitCh = ch + } else { + ch = b.waitCh + } + b.mu.Unlock() + for { + select { + case <-ctx.Done(): + b.mu.Lock() + b.clientStats.NumCallsFinished++ + b.clientStats.NumCallsFinishedWithClientFailedToSend++ + b.mu.Unlock() + err = ctx.Err() + return + case <-ch: + b.mu.Lock() + if b.done { + b.clientStats.NumCallsFinished++ + b.clientStats.NumCallsFinishedWithClientFailedToSend++ + b.mu.Unlock() + err = ErrClientConnClosing + return + } + + if len(b.addrs) > 0 { + if b.next >= len(b.addrs) { + b.next = 0 + } + next := b.next + for { + a := b.addrs[next] + next = (next + 1) % len(b.addrs) + if a.connected { + if !a.dropForRateLimiting && !a.dropForLoadBalancing { + addr = a.addr + b.next = next + b.mu.Unlock() + return + } + if !opts.BlockingWait { + b.next = next + if a.dropForLoadBalancing { + b.clientStats.NumCallsFinished++ + b.clientStats.NumCallsFinishedWithDropForLoadBalancing++ + } else if a.dropForRateLimiting { + b.clientStats.NumCallsFinished++ + b.clientStats.NumCallsFinishedWithDropForRateLimiting++ + } + b.mu.Unlock() + err = Errorf(codes.Unavailable, "drop requests for the addreess %s", a.addr.Addr) + return + } + } + if next == b.next { + // Has iterated all the possible address but none is connected. + break + } + } + } + // The newly added addr got removed by Down() again. + if b.waitCh == nil { + ch = make(chan struct{}) + b.waitCh = ch + } else { + ch = b.waitCh + } + b.mu.Unlock() + } + } +} + +func (b *balancer) Notify() <-chan []Address { + return b.addrCh +} + +func (b *balancer) Close() error { + b.mu.Lock() + defer b.mu.Unlock() + b.done = true + if b.expTimer != nil { + b.expTimer.Stop() + } + if b.waitCh != nil { + close(b.waitCh) + } + if b.addrCh != nil { + close(b.addrCh) + } + if b.w != nil { + b.w.Close() + } + return nil +} diff --git a/components/cli/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.pb.go b/components/cli/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.pb.go new file mode 100644 index 0000000000..f63941bd80 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.pb.go @@ -0,0 +1,629 @@ +// Code generated by protoc-gen-go. +// source: grpclb.proto +// DO NOT EDIT! + +/* +Package grpc_lb_v1 is a generated protocol buffer package. + +It is generated from these files: + grpclb.proto + +It has these top-level messages: + Duration + Timestamp + LoadBalanceRequest + InitialLoadBalanceRequest + ClientStats + LoadBalanceResponse + InitialLoadBalanceResponse + ServerList + Server +*/ +package grpc_lb_v1 + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Duration struct { + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. + Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` +} + +func (m *Duration) Reset() { *m = Duration{} } +func (m *Duration) String() string { return proto.CompactTextString(m) } +func (*Duration) ProtoMessage() {} +func (*Duration) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *Duration) GetSeconds() int64 { + if m != nil { + return m.Seconds + } + return 0 +} + +func (m *Duration) GetNanos() int32 { + if m != nil { + return m.Nanos + } + return 0 +} + +type Timestamp struct { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` +} + +func (m *Timestamp) Reset() { *m = Timestamp{} } +func (m *Timestamp) String() string { return proto.CompactTextString(m) } +func (*Timestamp) ProtoMessage() {} +func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *Timestamp) GetSeconds() int64 { + if m != nil { + return m.Seconds + } + return 0 +} + +func (m *Timestamp) GetNanos() int32 { + if m != nil { + return m.Nanos + } + return 0 +} + +type LoadBalanceRequest struct { + // Types that are valid to be assigned to LoadBalanceRequestType: + // *LoadBalanceRequest_InitialRequest + // *LoadBalanceRequest_ClientStats + LoadBalanceRequestType isLoadBalanceRequest_LoadBalanceRequestType `protobuf_oneof:"load_balance_request_type"` +} + +func (m *LoadBalanceRequest) Reset() { *m = LoadBalanceRequest{} } +func (m *LoadBalanceRequest) String() string { return proto.CompactTextString(m) } +func (*LoadBalanceRequest) ProtoMessage() {} +func (*LoadBalanceRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +type isLoadBalanceRequest_LoadBalanceRequestType interface { + isLoadBalanceRequest_LoadBalanceRequestType() +} + +type LoadBalanceRequest_InitialRequest struct { + InitialRequest *InitialLoadBalanceRequest `protobuf:"bytes,1,opt,name=initial_request,json=initialRequest,oneof"` +} +type LoadBalanceRequest_ClientStats struct { + ClientStats *ClientStats `protobuf:"bytes,2,opt,name=client_stats,json=clientStats,oneof"` +} + +func (*LoadBalanceRequest_InitialRequest) isLoadBalanceRequest_LoadBalanceRequestType() {} +func (*LoadBalanceRequest_ClientStats) isLoadBalanceRequest_LoadBalanceRequestType() {} + +func (m *LoadBalanceRequest) GetLoadBalanceRequestType() isLoadBalanceRequest_LoadBalanceRequestType { + if m != nil { + return m.LoadBalanceRequestType + } + return nil +} + +func (m *LoadBalanceRequest) GetInitialRequest() *InitialLoadBalanceRequest { + if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_InitialRequest); ok { + return x.InitialRequest + } + return nil +} + +func (m *LoadBalanceRequest) GetClientStats() *ClientStats { + if x, ok := m.GetLoadBalanceRequestType().(*LoadBalanceRequest_ClientStats); ok { + return x.ClientStats + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*LoadBalanceRequest) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _LoadBalanceRequest_OneofMarshaler, _LoadBalanceRequest_OneofUnmarshaler, _LoadBalanceRequest_OneofSizer, []interface{}{ + (*LoadBalanceRequest_InitialRequest)(nil), + (*LoadBalanceRequest_ClientStats)(nil), + } +} + +func _LoadBalanceRequest_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*LoadBalanceRequest) + // load_balance_request_type + switch x := m.LoadBalanceRequestType.(type) { + case *LoadBalanceRequest_InitialRequest: + b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.InitialRequest); err != nil { + return err + } + case *LoadBalanceRequest_ClientStats: + b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ClientStats); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("LoadBalanceRequest.LoadBalanceRequestType has unexpected type %T", x) + } + return nil +} + +func _LoadBalanceRequest_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*LoadBalanceRequest) + switch tag { + case 1: // load_balance_request_type.initial_request + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(InitialLoadBalanceRequest) + err := b.DecodeMessage(msg) + m.LoadBalanceRequestType = &LoadBalanceRequest_InitialRequest{msg} + return true, err + case 2: // load_balance_request_type.client_stats + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(ClientStats) + err := b.DecodeMessage(msg) + m.LoadBalanceRequestType = &LoadBalanceRequest_ClientStats{msg} + return true, err + default: + return false, nil + } +} + +func _LoadBalanceRequest_OneofSizer(msg proto.Message) (n int) { + m := msg.(*LoadBalanceRequest) + // load_balance_request_type + switch x := m.LoadBalanceRequestType.(type) { + case *LoadBalanceRequest_InitialRequest: + s := proto.Size(x.InitialRequest) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *LoadBalanceRequest_ClientStats: + s := proto.Size(x.ClientStats) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +type InitialLoadBalanceRequest struct { + // Name of load balanced service (IE, balancer.service.com) + // length should be less than 256 bytes. + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` +} + +func (m *InitialLoadBalanceRequest) Reset() { *m = InitialLoadBalanceRequest{} } +func (m *InitialLoadBalanceRequest) String() string { return proto.CompactTextString(m) } +func (*InitialLoadBalanceRequest) ProtoMessage() {} +func (*InitialLoadBalanceRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *InitialLoadBalanceRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// Contains client level statistics that are useful to load balancing. Each +// count except the timestamp should be reset to zero after reporting the stats. +type ClientStats struct { + // The timestamp of generating the report. + Timestamp *Timestamp `protobuf:"bytes,1,opt,name=timestamp" json:"timestamp,omitempty"` + // The total number of RPCs that started. + NumCallsStarted int64 `protobuf:"varint,2,opt,name=num_calls_started,json=numCallsStarted" json:"num_calls_started,omitempty"` + // The total number of RPCs that finished. + NumCallsFinished int64 `protobuf:"varint,3,opt,name=num_calls_finished,json=numCallsFinished" json:"num_calls_finished,omitempty"` + // The total number of RPCs that were dropped by the client because of rate + // limiting. + NumCallsFinishedWithDropForRateLimiting int64 `protobuf:"varint,4,opt,name=num_calls_finished_with_drop_for_rate_limiting,json=numCallsFinishedWithDropForRateLimiting" json:"num_calls_finished_with_drop_for_rate_limiting,omitempty"` + // The total number of RPCs that were dropped by the client because of load + // balancing. + NumCallsFinishedWithDropForLoadBalancing int64 `protobuf:"varint,5,opt,name=num_calls_finished_with_drop_for_load_balancing,json=numCallsFinishedWithDropForLoadBalancing" json:"num_calls_finished_with_drop_for_load_balancing,omitempty"` + // The total number of RPCs that failed to reach a server except dropped RPCs. + NumCallsFinishedWithClientFailedToSend int64 `protobuf:"varint,6,opt,name=num_calls_finished_with_client_failed_to_send,json=numCallsFinishedWithClientFailedToSend" json:"num_calls_finished_with_client_failed_to_send,omitempty"` + // The total number of RPCs that finished and are known to have been received + // by a server. + NumCallsFinishedKnownReceived int64 `protobuf:"varint,7,opt,name=num_calls_finished_known_received,json=numCallsFinishedKnownReceived" json:"num_calls_finished_known_received,omitempty"` +} + +func (m *ClientStats) Reset() { *m = ClientStats{} } +func (m *ClientStats) String() string { return proto.CompactTextString(m) } +func (*ClientStats) ProtoMessage() {} +func (*ClientStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *ClientStats) GetTimestamp() *Timestamp { + if m != nil { + return m.Timestamp + } + return nil +} + +func (m *ClientStats) GetNumCallsStarted() int64 { + if m != nil { + return m.NumCallsStarted + } + return 0 +} + +func (m *ClientStats) GetNumCallsFinished() int64 { + if m != nil { + return m.NumCallsFinished + } + return 0 +} + +func (m *ClientStats) GetNumCallsFinishedWithDropForRateLimiting() int64 { + if m != nil { + return m.NumCallsFinishedWithDropForRateLimiting + } + return 0 +} + +func (m *ClientStats) GetNumCallsFinishedWithDropForLoadBalancing() int64 { + if m != nil { + return m.NumCallsFinishedWithDropForLoadBalancing + } + return 0 +} + +func (m *ClientStats) GetNumCallsFinishedWithClientFailedToSend() int64 { + if m != nil { + return m.NumCallsFinishedWithClientFailedToSend + } + return 0 +} + +func (m *ClientStats) GetNumCallsFinishedKnownReceived() int64 { + if m != nil { + return m.NumCallsFinishedKnownReceived + } + return 0 +} + +type LoadBalanceResponse struct { + // Types that are valid to be assigned to LoadBalanceResponseType: + // *LoadBalanceResponse_InitialResponse + // *LoadBalanceResponse_ServerList + LoadBalanceResponseType isLoadBalanceResponse_LoadBalanceResponseType `protobuf_oneof:"load_balance_response_type"` +} + +func (m *LoadBalanceResponse) Reset() { *m = LoadBalanceResponse{} } +func (m *LoadBalanceResponse) String() string { return proto.CompactTextString(m) } +func (*LoadBalanceResponse) ProtoMessage() {} +func (*LoadBalanceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +type isLoadBalanceResponse_LoadBalanceResponseType interface { + isLoadBalanceResponse_LoadBalanceResponseType() +} + +type LoadBalanceResponse_InitialResponse struct { + InitialResponse *InitialLoadBalanceResponse `protobuf:"bytes,1,opt,name=initial_response,json=initialResponse,oneof"` +} +type LoadBalanceResponse_ServerList struct { + ServerList *ServerList `protobuf:"bytes,2,opt,name=server_list,json=serverList,oneof"` +} + +func (*LoadBalanceResponse_InitialResponse) isLoadBalanceResponse_LoadBalanceResponseType() {} +func (*LoadBalanceResponse_ServerList) isLoadBalanceResponse_LoadBalanceResponseType() {} + +func (m *LoadBalanceResponse) GetLoadBalanceResponseType() isLoadBalanceResponse_LoadBalanceResponseType { + if m != nil { + return m.LoadBalanceResponseType + } + return nil +} + +func (m *LoadBalanceResponse) GetInitialResponse() *InitialLoadBalanceResponse { + if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_InitialResponse); ok { + return x.InitialResponse + } + return nil +} + +func (m *LoadBalanceResponse) GetServerList() *ServerList { + if x, ok := m.GetLoadBalanceResponseType().(*LoadBalanceResponse_ServerList); ok { + return x.ServerList + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*LoadBalanceResponse) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _LoadBalanceResponse_OneofMarshaler, _LoadBalanceResponse_OneofUnmarshaler, _LoadBalanceResponse_OneofSizer, []interface{}{ + (*LoadBalanceResponse_InitialResponse)(nil), + (*LoadBalanceResponse_ServerList)(nil), + } +} + +func _LoadBalanceResponse_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*LoadBalanceResponse) + // load_balance_response_type + switch x := m.LoadBalanceResponseType.(type) { + case *LoadBalanceResponse_InitialResponse: + b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.InitialResponse); err != nil { + return err + } + case *LoadBalanceResponse_ServerList: + b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.ServerList); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("LoadBalanceResponse.LoadBalanceResponseType has unexpected type %T", x) + } + return nil +} + +func _LoadBalanceResponse_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*LoadBalanceResponse) + switch tag { + case 1: // load_balance_response_type.initial_response + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(InitialLoadBalanceResponse) + err := b.DecodeMessage(msg) + m.LoadBalanceResponseType = &LoadBalanceResponse_InitialResponse{msg} + return true, err + case 2: // load_balance_response_type.server_list + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(ServerList) + err := b.DecodeMessage(msg) + m.LoadBalanceResponseType = &LoadBalanceResponse_ServerList{msg} + return true, err + default: + return false, nil + } +} + +func _LoadBalanceResponse_OneofSizer(msg proto.Message) (n int) { + m := msg.(*LoadBalanceResponse) + // load_balance_response_type + switch x := m.LoadBalanceResponseType.(type) { + case *LoadBalanceResponse_InitialResponse: + s := proto.Size(x.InitialResponse) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *LoadBalanceResponse_ServerList: + s := proto.Size(x.ServerList) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +type InitialLoadBalanceResponse struct { + // This is an application layer redirect that indicates the client should use + // the specified server for load balancing. When this field is non-empty in + // the response, the client should open a separate connection to the + // load_balancer_delegate and call the BalanceLoad method. Its length should + // be less than 64 bytes. + LoadBalancerDelegate string `protobuf:"bytes,1,opt,name=load_balancer_delegate,json=loadBalancerDelegate" json:"load_balancer_delegate,omitempty"` + // This interval defines how often the client should send the client stats + // to the load balancer. Stats should only be reported when the duration is + // positive. + ClientStatsReportInterval *Duration `protobuf:"bytes,2,opt,name=client_stats_report_interval,json=clientStatsReportInterval" json:"client_stats_report_interval,omitempty"` +} + +func (m *InitialLoadBalanceResponse) Reset() { *m = InitialLoadBalanceResponse{} } +func (m *InitialLoadBalanceResponse) String() string { return proto.CompactTextString(m) } +func (*InitialLoadBalanceResponse) ProtoMessage() {} +func (*InitialLoadBalanceResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *InitialLoadBalanceResponse) GetLoadBalancerDelegate() string { + if m != nil { + return m.LoadBalancerDelegate + } + return "" +} + +func (m *InitialLoadBalanceResponse) GetClientStatsReportInterval() *Duration { + if m != nil { + return m.ClientStatsReportInterval + } + return nil +} + +type ServerList struct { + // Contains a list of servers selected by the load balancer. The list will + // be updated when server resolutions change or as needed to balance load + // across more servers. The client should consume the server list in order + // unless instructed otherwise via the client_config. + Servers []*Server `protobuf:"bytes,1,rep,name=servers" json:"servers,omitempty"` + // Indicates the amount of time that the client should consider this server + // list as valid. It may be considered stale after waiting this interval of + // time after receiving the list. If the interval is not positive, the + // client can assume the list is valid until the next list is received. + ExpirationInterval *Duration `protobuf:"bytes,3,opt,name=expiration_interval,json=expirationInterval" json:"expiration_interval,omitempty"` +} + +func (m *ServerList) Reset() { *m = ServerList{} } +func (m *ServerList) String() string { return proto.CompactTextString(m) } +func (*ServerList) ProtoMessage() {} +func (*ServerList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *ServerList) GetServers() []*Server { + if m != nil { + return m.Servers + } + return nil +} + +func (m *ServerList) GetExpirationInterval() *Duration { + if m != nil { + return m.ExpirationInterval + } + return nil +} + +// Contains server information. When none of the [drop_for_*] fields are true, +// use the other fields. When drop_for_rate_limiting is true, ignore all other +// fields. Use drop_for_load_balancing only when it is true and +// drop_for_rate_limiting is false. +type Server struct { + // A resolved address for the server, serialized in network-byte-order. It may + // either be an IPv4 or IPv6 address. + IpAddress []byte `protobuf:"bytes,1,opt,name=ip_address,json=ipAddress,proto3" json:"ip_address,omitempty"` + // A resolved port number for the server. + Port int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"` + // An opaque but printable token given to the frontend for each pick. All + // frontend requests for that pick must include the token in its initial + // metadata. The token is used by the backend to verify the request and to + // allow the backend to report load to the gRPC LB system. + // + // Its length is variable but less than 50 bytes. + LoadBalanceToken string `protobuf:"bytes,3,opt,name=load_balance_token,json=loadBalanceToken" json:"load_balance_token,omitempty"` + // Indicates whether this particular request should be dropped by the client + // for rate limiting. + DropForRateLimiting bool `protobuf:"varint,4,opt,name=drop_for_rate_limiting,json=dropForRateLimiting" json:"drop_for_rate_limiting,omitempty"` + // Indicates whether this particular request should be dropped by the client + // for load balancing. + DropForLoadBalancing bool `protobuf:"varint,5,opt,name=drop_for_load_balancing,json=dropForLoadBalancing" json:"drop_for_load_balancing,omitempty"` +} + +func (m *Server) Reset() { *m = Server{} } +func (m *Server) String() string { return proto.CompactTextString(m) } +func (*Server) ProtoMessage() {} +func (*Server) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +func (m *Server) GetIpAddress() []byte { + if m != nil { + return m.IpAddress + } + return nil +} + +func (m *Server) GetPort() int32 { + if m != nil { + return m.Port + } + return 0 +} + +func (m *Server) GetLoadBalanceToken() string { + if m != nil { + return m.LoadBalanceToken + } + return "" +} + +func (m *Server) GetDropForRateLimiting() bool { + if m != nil { + return m.DropForRateLimiting + } + return false +} + +func (m *Server) GetDropForLoadBalancing() bool { + if m != nil { + return m.DropForLoadBalancing + } + return false +} + +func init() { + proto.RegisterType((*Duration)(nil), "grpc.lb.v1.Duration") + proto.RegisterType((*Timestamp)(nil), "grpc.lb.v1.Timestamp") + proto.RegisterType((*LoadBalanceRequest)(nil), "grpc.lb.v1.LoadBalanceRequest") + proto.RegisterType((*InitialLoadBalanceRequest)(nil), "grpc.lb.v1.InitialLoadBalanceRequest") + proto.RegisterType((*ClientStats)(nil), "grpc.lb.v1.ClientStats") + proto.RegisterType((*LoadBalanceResponse)(nil), "grpc.lb.v1.LoadBalanceResponse") + proto.RegisterType((*InitialLoadBalanceResponse)(nil), "grpc.lb.v1.InitialLoadBalanceResponse") + proto.RegisterType((*ServerList)(nil), "grpc.lb.v1.ServerList") + proto.RegisterType((*Server)(nil), "grpc.lb.v1.Server") +} + +func init() { proto.RegisterFile("grpclb.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 733 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xdd, 0x4e, 0x1b, 0x39, + 0x14, 0x66, 0x36, 0xfc, 0xe5, 0x24, 0x5a, 0x58, 0x93, 0x85, 0xc0, 0xc2, 0x2e, 0x1b, 0xa9, 0x34, + 0xaa, 0x68, 0x68, 0x43, 0x7b, 0xd1, 0x9f, 0x9b, 0x02, 0x45, 0x41, 0xe5, 0xa2, 0x72, 0xa8, 0x7a, + 0x55, 0x59, 0x4e, 0xc6, 0x80, 0xc5, 0xc4, 0x9e, 0xda, 0x4e, 0x68, 0x2f, 0x7b, 0xd9, 0x47, 0xe9, + 0x63, 0x54, 0x7d, 0x86, 0xbe, 0x4f, 0x65, 0x7b, 0x26, 0x33, 0x90, 0x1f, 0xd4, 0xbb, 0xf1, 0xf1, + 0x77, 0xbe, 0xf3, 0xf9, 0xd8, 0xdf, 0x19, 0x28, 0x5f, 0xa8, 0xb8, 0x1b, 0x75, 0x1a, 0xb1, 0x92, + 0x46, 0x22, 0xb0, 0xab, 0x46, 0xd4, 0x69, 0x0c, 0x1e, 0xd7, 0x9e, 0xc3, 0xe2, 0x51, 0x5f, 0x51, + 0xc3, 0xa5, 0x40, 0x55, 0x58, 0xd0, 0xac, 0x2b, 0x45, 0xa8, 0xab, 0xc1, 0x76, 0x50, 0x2f, 0xe0, + 0x74, 0x89, 0x2a, 0x30, 0x27, 0xa8, 0x90, 0xba, 0xfa, 0xc7, 0x76, 0x50, 0x9f, 0xc3, 0x7e, 0x51, + 0x7b, 0x01, 0xc5, 0x33, 0xde, 0x63, 0xda, 0xd0, 0x5e, 0xfc, 0xdb, 0xc9, 0xdf, 0x03, 0x40, 0xa7, + 0x92, 0x86, 0x07, 0x34, 0xa2, 0xa2, 0xcb, 0x30, 0xfb, 0xd8, 0x67, 0xda, 0xa0, 0xb7, 0xb0, 0xc4, + 0x05, 0x37, 0x9c, 0x46, 0x44, 0xf9, 0x90, 0xa3, 0x2b, 0x35, 0xef, 0x35, 0x32, 0xd5, 0x8d, 0x13, + 0x0f, 0x19, 0xcd, 0x6f, 0xcd, 0xe0, 0x3f, 0x93, 0xfc, 0x94, 0xf1, 0x25, 0x94, 0xbb, 0x11, 0x67, + 0xc2, 0x10, 0x6d, 0xa8, 0xf1, 0x2a, 0x4a, 0xcd, 0xb5, 0x3c, 0xdd, 0xa1, 0xdb, 0x6f, 0xdb, 0xed, + 0xd6, 0x0c, 0x2e, 0x75, 0xb3, 0xe5, 0xc1, 0x3f, 0xb0, 0x1e, 0x49, 0x1a, 0x92, 0x8e, 0x2f, 0x93, + 0x8a, 0x22, 0xe6, 0x73, 0xcc, 0x6a, 0x7b, 0xb0, 0x3e, 0x51, 0x09, 0x42, 0x30, 0x2b, 0x68, 0x8f, + 0x39, 0xf9, 0x45, 0xec, 0xbe, 0x6b, 0x5f, 0x67, 0xa1, 0x94, 0x2b, 0x86, 0xf6, 0xa1, 0x68, 0xd2, + 0x0e, 0x26, 0xe7, 0xfc, 0x3b, 0x2f, 0x6c, 0xd8, 0x5e, 0x9c, 0xe1, 0xd0, 0x03, 0xf8, 0x4b, 0xf4, + 0x7b, 0xa4, 0x4b, 0xa3, 0x48, 0xdb, 0x33, 0x29, 0xc3, 0x42, 0x77, 0xaa, 0x02, 0x5e, 0x12, 0xfd, + 0xde, 0xa1, 0x8d, 0xb7, 0x7d, 0x18, 0xed, 0x02, 0xca, 0xb0, 0xe7, 0x5c, 0x70, 0x7d, 0xc9, 0xc2, + 0x6a, 0xc1, 0x81, 0x97, 0x53, 0xf0, 0x71, 0x12, 0x47, 0x04, 0x1a, 0xa3, 0x68, 0x72, 0xcd, 0xcd, + 0x25, 0x09, 0x95, 0x8c, 0xc9, 0xb9, 0x54, 0x44, 0x51, 0xc3, 0x48, 0xc4, 0x7b, 0xdc, 0x70, 0x71, + 0x51, 0x9d, 0x75, 0x4c, 0xf7, 0x6f, 0x33, 0xbd, 0xe7, 0xe6, 0xf2, 0x48, 0xc9, 0xf8, 0x58, 0x2a, + 0x4c, 0x0d, 0x3b, 0x4d, 0xe0, 0x88, 0xc2, 0xde, 0x9d, 0x05, 0x72, 0xed, 0xb6, 0x15, 0xe6, 0x5c, + 0x85, 0xfa, 0x94, 0x0a, 0x59, 0xef, 0x6d, 0x89, 0x0f, 0xf0, 0x70, 0x52, 0x89, 0xe4, 0x19, 0x9c, + 0x53, 0x1e, 0xb1, 0x90, 0x18, 0x49, 0x34, 0x13, 0x61, 0x75, 0xde, 0x15, 0xd8, 0x19, 0x57, 0xc0, + 0x5f, 0xd5, 0xb1, 0xc3, 0x9f, 0xc9, 0x36, 0x13, 0x21, 0x6a, 0xc1, 0xff, 0x63, 0xe8, 0xaf, 0x84, + 0xbc, 0x16, 0x44, 0xb1, 0x2e, 0xe3, 0x03, 0x16, 0x56, 0x17, 0x1c, 0xe5, 0xd6, 0x6d, 0xca, 0x37, + 0x16, 0x85, 0x13, 0x50, 0xed, 0x47, 0x00, 0x2b, 0x37, 0x9e, 0x8d, 0x8e, 0xa5, 0xd0, 0x0c, 0xb5, + 0x61, 0x39, 0x73, 0x80, 0x8f, 0x25, 0x4f, 0x63, 0xe7, 0x2e, 0x0b, 0x78, 0x74, 0x6b, 0x06, 0x2f, + 0x0d, 0x3d, 0x90, 0x90, 0x3e, 0x83, 0x92, 0x66, 0x6a, 0xc0, 0x14, 0x89, 0xb8, 0x36, 0x89, 0x07, + 0x56, 0xf3, 0x7c, 0x6d, 0xb7, 0x7d, 0xca, 0x9d, 0x87, 0x40, 0x0f, 0x57, 0x07, 0x9b, 0xb0, 0x71, + 0xcb, 0x01, 0x9e, 0xd3, 0x5b, 0xe0, 0x5b, 0x00, 0x1b, 0x93, 0xa5, 0xa0, 0x27, 0xb0, 0x9a, 0x4f, + 0x56, 0x24, 0x64, 0x11, 0xbb, 0xa0, 0x26, 0xb5, 0x45, 0x25, 0xca, 0x92, 0xd4, 0x51, 0xb2, 0x87, + 0xde, 0xc1, 0x66, 0xde, 0xb2, 0x44, 0xb1, 0x58, 0x2a, 0x43, 0xb8, 0x30, 0x4c, 0x0d, 0x68, 0x94, + 0xc8, 0xaf, 0xe4, 0xe5, 0xa7, 0x43, 0x0c, 0xaf, 0xe7, 0xdc, 0x8b, 0x5d, 0xde, 0x49, 0x92, 0x56, + 0xfb, 0x12, 0x00, 0x64, 0xc7, 0x44, 0xbb, 0x76, 0x62, 0xd9, 0x95, 0x9d, 0x58, 0x85, 0x7a, 0xa9, + 0x89, 0x46, 0xfb, 0x81, 0x53, 0x08, 0x7a, 0x0d, 0x2b, 0xec, 0x53, 0xcc, 0x7d, 0x95, 0x4c, 0x4a, + 0x61, 0x8a, 0x14, 0x94, 0x25, 0x0c, 0x35, 0xfc, 0x0c, 0x60, 0xde, 0x53, 0xa3, 0x2d, 0x00, 0x1e, + 0x13, 0x1a, 0x86, 0x8a, 0x69, 0x3f, 0x34, 0xcb, 0xb8, 0xc8, 0xe3, 0x57, 0x3e, 0x60, 0xe7, 0x87, + 0x55, 0x9f, 0x4c, 0x4d, 0xf7, 0x6d, 0xed, 0x7c, 0xe3, 0x2e, 0x8c, 0xbc, 0x62, 0xc2, 0x69, 0x28, + 0xe2, 0xe5, 0x5c, 0x2b, 0xcf, 0x6c, 0x1c, 0xed, 0xc3, 0xea, 0x14, 0xdb, 0x2e, 0xe2, 0x95, 0x70, + 0x8c, 0x45, 0x9f, 0xc2, 0xda, 0x34, 0x2b, 0x2e, 0xe2, 0x4a, 0x38, 0xc6, 0x76, 0xcd, 0x0e, 0x94, + 0x73, 0xf7, 0xaf, 0x10, 0x86, 0x52, 0xf2, 0x6d, 0xc3, 0xe8, 0xdf, 0x7c, 0x83, 0x46, 0x87, 0xe5, + 0xc6, 0x7f, 0x13, 0xf7, 0xfd, 0x43, 0xaa, 0x07, 0x8f, 0x82, 0xce, 0xbc, 0xfb, 0x7d, 0xed, 0xff, + 0x0a, 0x00, 0x00, 0xff, 0xff, 0x64, 0xbf, 0xda, 0x5e, 0xce, 0x06, 0x00, 0x00, +} diff --git a/components/cli/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto b/components/cli/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto new file mode 100644 index 0000000000..a2502fb284 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto @@ -0,0 +1,179 @@ +// Copyright 2016, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package grpc.lb.v1; + +message Duration { + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. + int64 seconds = 1; + + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + int32 nanos = 2; +} + +message Timestamp { + + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} + +service LoadBalancer { + // Bidirectional rpc to get a list of servers. + rpc BalanceLoad(stream LoadBalanceRequest) + returns (stream LoadBalanceResponse); +} + +message LoadBalanceRequest { + oneof load_balance_request_type { + // This message should be sent on the first request to the load balancer. + InitialLoadBalanceRequest initial_request = 1; + + // The client stats should be periodically reported to the load balancer + // based on the duration defined in the InitialLoadBalanceResponse. + ClientStats client_stats = 2; + } +} + +message InitialLoadBalanceRequest { + // Name of load balanced service (IE, balancer.service.com) + // length should be less than 256 bytes. + string name = 1; +} + +// Contains client level statistics that are useful to load balancing. Each +// count except the timestamp should be reset to zero after reporting the stats. +message ClientStats { + // The timestamp of generating the report. + Timestamp timestamp = 1; + + // The total number of RPCs that started. + int64 num_calls_started = 2; + + // The total number of RPCs that finished. + int64 num_calls_finished = 3; + + // The total number of RPCs that were dropped by the client because of rate + // limiting. + int64 num_calls_finished_with_drop_for_rate_limiting = 4; + + // The total number of RPCs that were dropped by the client because of load + // balancing. + int64 num_calls_finished_with_drop_for_load_balancing = 5; + + // The total number of RPCs that failed to reach a server except dropped RPCs. + int64 num_calls_finished_with_client_failed_to_send = 6; + + // The total number of RPCs that finished and are known to have been received + // by a server. + int64 num_calls_finished_known_received = 7; +} + +message LoadBalanceResponse { + oneof load_balance_response_type { + // This message should be sent on the first response to the client. + InitialLoadBalanceResponse initial_response = 1; + + // Contains the list of servers selected by the load balancer. The client + // should send requests to these servers in the specified order. + ServerList server_list = 2; + } +} + +message InitialLoadBalanceResponse { + // This is an application layer redirect that indicates the client should use + // the specified server for load balancing. When this field is non-empty in + // the response, the client should open a separate connection to the + // load_balancer_delegate and call the BalanceLoad method. Its length should + // be less than 64 bytes. + string load_balancer_delegate = 1; + + // This interval defines how often the client should send the client stats + // to the load balancer. Stats should only be reported when the duration is + // positive. + Duration client_stats_report_interval = 2; +} + +message ServerList { + // Contains a list of servers selected by the load balancer. The list will + // be updated when server resolutions change or as needed to balance load + // across more servers. The client should consume the server list in order + // unless instructed otherwise via the client_config. + repeated Server servers = 1; + + // Indicates the amount of time that the client should consider this server + // list as valid. It may be considered stale after waiting this interval of + // time after receiving the list. If the interval is not positive, the + // client can assume the list is valid until the next list is received. + Duration expiration_interval = 3; +} + +// Contains server information. When none of the [drop_for_*] fields are true, +// use the other fields. When drop_for_rate_limiting is true, ignore all other +// fields. Use drop_for_load_balancing only when it is true and +// drop_for_rate_limiting is false. +message Server { + // A resolved address for the server, serialized in network-byte-order. It may + // either be an IPv4 or IPv6 address. + bytes ip_address = 1; + + // A resolved port number for the server. + int32 port = 2; + + // An opaque but printable token given to the frontend for each pick. All + // frontend requests for that pick must include the token in its initial + // metadata. The token is used by the backend to verify the request and to + // allow the backend to report load to the gRPC LB system. + // + // Its length is variable but less than 50 bytes. + string load_balance_token = 3; + + // Indicates whether this particular request should be dropped by the client + // for rate limiting. + bool drop_for_rate_limiting = 4; + + // Indicates whether this particular request should be dropped by the client + // for load balancing. + bool drop_for_load_balancing = 5; +} diff --git a/components/cli/vendor/google.golang.org/grpc/interceptor.go b/components/cli/vendor/google.golang.org/grpc/interceptor.go index 8d932efed7..a692161457 100644 --- a/components/cli/vendor/google.golang.org/grpc/interceptor.go +++ b/components/cli/vendor/google.golang.org/grpc/interceptor.go @@ -40,7 +40,7 @@ import ( // UnaryInvoker is called by UnaryClientInterceptor to complete RPCs. type UnaryInvoker func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error -// UnaryClientInterceptor intercepts the execution of a unary RPC on the client. inovker is the handler to complete the RPC +// UnaryClientInterceptor intercepts the execution of a unary RPC on the client. invoker is the handler to complete the RPC // and it is the responsibility of the interceptor to call it. // This is the EXPERIMENTAL API. type UnaryClientInterceptor func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error diff --git a/components/cli/vendor/google.golang.org/grpc/keepalive/keepalive.go b/components/cli/vendor/google.golang.org/grpc/keepalive/keepalive.go new file mode 100644 index 0000000000..d492589c96 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/keepalive/keepalive.go @@ -0,0 +1,80 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// Package keepalive defines configurable parameters for point-to-point healthcheck. +package keepalive + +import ( + "time" +) + +// ClientParameters is used to set keepalive parameters on the client-side. +// These configure how the client will actively probe to notice when a connection broken +// and to cause activity so intermediaries are aware the connection is still in use. +// Make sure these parameters are set in coordination with the keepalive policy on the server, +// as incompatible settings can result in closing of connection. +type ClientParameters struct { + // After a duration of this time if the client doesn't see any activity it pings the server to see if the transport is still alive. + Time time.Duration // The current default value is infinity. + // After having pinged for keepalive check, the client waits for a duration of Timeout and if no activity is seen even after that + // the connection is closed. + Timeout time.Duration // The current default value is 20 seconds. + // If true, client runs keepalive checks even with no active RPCs. + PermitWithoutStream bool // false by default. +} + +// ServerParameters is used to set keepalive and max-age parameters on the server-side. +type ServerParameters struct { + // MaxConnectionIdle is a duration for the amount of time after which an idle connection would be closed by sending a GoAway. + // Idleness duration is defined since the most recent time the number of outstanding RPCs became zero or the connection establishment. + MaxConnectionIdle time.Duration // The current default value is infinity. + // MaxConnectionAge is a duration for the maximum amount of time a connection may exist before it will be closed by sending a GoAway. + // A random jitter of +/-10% will be added to MaxConnectionAge to spread out connection storms. + MaxConnectionAge time.Duration // The current default value is infinity. + // MaxConnectinoAgeGrace is an additive period after MaxConnectionAge after which the connection will be forcibly closed. + MaxConnectionAgeGrace time.Duration // The current default value is infinity. + // After a duration of this time if the server doesn't see any activity it pings the client to see if the transport is still alive. + Time time.Duration // The current default value is 2 hours. + // After having pinged for keepalive check, the server waits for a duration of Timeout and if no activity is seen even after that + // the connection is closed. + Timeout time.Duration // The current default value is 20 seconds. +} + +// EnforcementPolicy is used to set keepalive enforcement policy on the server-side. +// Server will close connection with a client that violates this policy. +type EnforcementPolicy struct { + // MinTime is the minimum amount of time a client should wait before sending a keepalive ping. + MinTime time.Duration // The current default value is 5 minutes. + // If true, server expects keepalive pings even when there are no active streams(RPCs). + PermitWithoutStream bool // false by default. +} diff --git a/components/cli/vendor/google.golang.org/grpc/metadata/metadata.go b/components/cli/vendor/google.golang.org/grpc/metadata/metadata.go index 3c0ca7a36c..5395ca8200 100644 --- a/components/cli/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/components/cli/vendor/google.golang.org/grpc/metadata/metadata.go @@ -32,49 +32,19 @@ */ // Package metadata define the structure of the metadata supported by gRPC library. +// Please refer to http://www.grpc.io/docs/guides/wire.html for more information about custom-metadata. package metadata // import "google.golang.org/grpc/metadata" import ( - "encoding/base64" "fmt" "strings" "golang.org/x/net/context" ) -const ( - binHdrSuffix = "-bin" -) - -// encodeKeyValue encodes key and value qualified for transmission via gRPC. -// Transmitting binary headers violates HTTP/2 spec. -// TODO(zhaoq): Maybe check if k is ASCII also. -func encodeKeyValue(k, v string) (string, string) { - k = strings.ToLower(k) - if strings.HasSuffix(k, binHdrSuffix) { - val := base64.StdEncoding.EncodeToString([]byte(v)) - v = string(val) - } - return k, v -} - -// DecodeKeyValue returns the original key and value corresponding to the -// encoded data in k, v. -// If k is a binary header and v contains comma, v is split on comma before decoded, -// and the decoded v will be joined with comma before returned. +// DecodeKeyValue returns k, v, nil. It is deprecated and should not be used. func DecodeKeyValue(k, v string) (string, string, error) { - if !strings.HasSuffix(k, binHdrSuffix) { - return k, v, nil - } - vvs := strings.Split(v, ",") - for i, vv := range vvs { - val, err := base64.StdEncoding.DecodeString(vv) - if err != nil { - return "", "", err - } - vvs[i] = string(val) - } - return k, strings.Join(vvs, ","), nil + return k, v, nil } // MD is a mapping from metadata keys to values. Users should use the following @@ -82,10 +52,11 @@ func DecodeKeyValue(k, v string) (string, string, error) { type MD map[string][]string // New creates a MD from given key-value map. +// Keys are automatically converted to lowercase. func New(m map[string]string) MD { md := MD{} - for k, v := range m { - key, val := encodeKeyValue(k, v) + for k, val := range m { + key := strings.ToLower(k) md[key] = append(md[key], val) } return md @@ -93,19 +64,19 @@ func New(m map[string]string) MD { // Pairs returns an MD formed by the mapping of key, value ... // Pairs panics if len(kv) is odd. +// Keys are automatically converted to lowercase. func Pairs(kv ...string) MD { if len(kv)%2 == 1 { panic(fmt.Sprintf("metadata: Pairs got the odd number of input pairs for metadata: %d", len(kv))) } md := MD{} - var k string + var key string for i, s := range kv { if i%2 == 0 { - k = s + key = strings.ToLower(s) continue } - key, val := encodeKeyValue(k, s) - md[key] = append(md[key], val) + md[key] = append(md[key], s) } return md } @@ -133,15 +104,41 @@ func Join(mds ...MD) MD { return out } -type mdKey struct{} +type mdIncomingKey struct{} +type mdOutgoingKey struct{} -// NewContext creates a new context with md attached. +// NewContext is a wrapper for NewOutgoingContext(ctx, md). Deprecated. func NewContext(ctx context.Context, md MD) context.Context { - return context.WithValue(ctx, mdKey{}, md) + return NewOutgoingContext(ctx, md) } -// FromContext returns the MD in ctx if it exists. +// NewIncomingContext creates a new context with incoming md attached. +func NewIncomingContext(ctx context.Context, md MD) context.Context { + return context.WithValue(ctx, mdIncomingKey{}, md) +} + +// NewOutgoingContext creates a new context with outgoing md attached. +func NewOutgoingContext(ctx context.Context, md MD) context.Context { + return context.WithValue(ctx, mdOutgoingKey{}, md) +} + +// FromContext is a wrapper for FromIncomingContext(ctx). Deprecated. func FromContext(ctx context.Context) (md MD, ok bool) { - md, ok = ctx.Value(mdKey{}).(MD) + return FromIncomingContext(ctx) +} + +// FromIncomingContext returns the incoming MD in ctx if it exists. The +// returned md should be immutable, writing to it may cause races. +// Modification should be made to the copies of the returned md. +func FromIncomingContext(ctx context.Context) (md MD, ok bool) { + md, ok = ctx.Value(mdIncomingKey{}).(MD) + return +} + +// FromOutgoingContext returns the outgoing MD in ctx if it exists. The +// returned md should be immutable, writing to it may cause races. +// Modification should be made to the copies of the returned md. +func FromOutgoingContext(ctx context.Context) (md MD, ok bool) { + md, ok = ctx.Value(mdOutgoingKey{}).(MD) return } diff --git a/components/cli/vendor/google.golang.org/grpc/proxy.go b/components/cli/vendor/google.golang.org/grpc/proxy.go new file mode 100644 index 0000000000..10188dc343 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/proxy.go @@ -0,0 +1,145 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package grpc + +import ( + "bufio" + "errors" + "fmt" + "io" + "net" + "net/http" + "net/http/httputil" + "net/url" + + "golang.org/x/net/context" +) + +var ( + // errDisabled indicates that proxy is disabled for the address. + errDisabled = errors.New("proxy is disabled for the address") + // The following variable will be overwritten in the tests. + httpProxyFromEnvironment = http.ProxyFromEnvironment +) + +func mapAddress(ctx context.Context, address string) (string, error) { + req := &http.Request{ + URL: &url.URL{ + Scheme: "https", + Host: address, + }, + } + url, err := httpProxyFromEnvironment(req) + if err != nil { + return "", err + } + if url == nil { + return "", errDisabled + } + return url.Host, nil +} + +// To read a response from a net.Conn, http.ReadResponse() takes a bufio.Reader. +// It's possible that this reader reads more than what's need for the response and stores +// those bytes in the buffer. +// bufConn wraps the original net.Conn and the bufio.Reader to make sure we don't lose the +// bytes in the buffer. +type bufConn struct { + net.Conn + r io.Reader +} + +func (c *bufConn) Read(b []byte) (int, error) { + return c.r.Read(b) +} + +func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, addr string) (_ net.Conn, err error) { + defer func() { + if err != nil { + conn.Close() + } + }() + + req := (&http.Request{ + Method: http.MethodConnect, + URL: &url.URL{Host: addr}, + Header: map[string][]string{"User-Agent": {grpcUA}}, + }) + + if err := sendHTTPRequest(ctx, req, conn); err != nil { + return nil, fmt.Errorf("failed to write the HTTP request: %v", err) + } + + r := bufio.NewReader(conn) + resp, err := http.ReadResponse(r, req) + if err != nil { + return nil, fmt.Errorf("reading server HTTP response: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + dump, err := httputil.DumpResponse(resp, true) + if err != nil { + return nil, fmt.Errorf("failed to do connect handshake, status code: %s", resp.Status) + } + return nil, fmt.Errorf("failed to do connect handshake, response: %q", dump) + } + + return &bufConn{Conn: conn, r: r}, nil +} + +// newProxyDialer returns a dialer that connects to proxy first if necessary. +// The returned dialer checks if a proxy is necessary, dial to the proxy with the +// provided dialer, does HTTP CONNECT handshake and returns the connection. +func newProxyDialer(dialer func(context.Context, string) (net.Conn, error)) func(context.Context, string) (net.Conn, error) { + return func(ctx context.Context, addr string) (conn net.Conn, err error) { + var skipHandshake bool + newAddr, err := mapAddress(ctx, addr) + if err != nil { + if err != errDisabled { + return nil, err + } + skipHandshake = true + newAddr = addr + } + + conn, err = dialer(ctx, newAddr) + if err != nil { + return + } + if !skipHandshake { + conn, err = doHTTPConnectHandshake(ctx, conn, addr) + } + return + } +} diff --git a/components/cli/vendor/google.golang.org/grpc/rpc_util.go b/components/cli/vendor/google.golang.org/grpc/rpc_util.go index a25eaa8a28..34e1ad03b9 100644 --- a/components/cli/vendor/google.golang.org/grpc/rpc_util.go +++ b/components/cli/vendor/google.golang.org/grpc/rpc_util.go @@ -37,45 +37,21 @@ import ( "bytes" "compress/gzip" "encoding/binary" - "fmt" "io" "io/ioutil" "math" "os" + "time" - "github.com/golang/protobuf/proto" "golang.org/x/net/context" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/status" "google.golang.org/grpc/transport" ) -// Codec defines the interface gRPC uses to encode and decode messages. -type Codec interface { - // Marshal returns the wire format of v. - Marshal(v interface{}) ([]byte, error) - // Unmarshal parses the wire format into v. - Unmarshal(data []byte, v interface{}) error - // String returns the name of the Codec implementation. The returned - // string will be used as part of content type in transmission. - String() string -} - -// protoCodec is a Codec implementation with protobuf. It is the default codec for gRPC. -type protoCodec struct{} - -func (protoCodec) Marshal(v interface{}) ([]byte, error) { - return proto.Marshal(v.(proto.Message)) -} - -func (protoCodec) Unmarshal(data []byte, v interface{}) error { - return proto.Unmarshal(data, v.(proto.Message)) -} - -func (protoCodec) String() string { - return "proto" -} - // Compressor defines the interface gRPC uses to compress a message. type Compressor interface { // Do compresses p into w. @@ -138,6 +114,7 @@ type callInfo struct { failFast bool headerMD metadata.MD trailerMD metadata.MD + peer *peer.Peer traceInfo traceInfo // in trace.go } @@ -181,12 +158,22 @@ func Trailer(md *metadata.MD) CallOption { }) } +// Peer returns a CallOption that retrieves peer information for a +// unary RPC. +func Peer(peer *peer.Peer) CallOption { + return afterCall(func(c *callInfo) { + if c.peer != nil { + *peer = *c.peer + } + }) +} + // FailFast configures the action to take when an RPC is attempted on broken // connections or unreachable servers. If failfast is true, the RPC will fail // immediately. Otherwise, the RPC client will block the call until a // connection is available (or the call is canceled or times out) and will retry // the call if it fails due to a transient error. Please refer to -// https://github.com/grpc/grpc/blob/master/doc/fail_fast.md +// https://github.com/grpc/grpc/blob/master/doc/fail_fast.md. Note: failFast is default to true. func FailFast(failFast bool) CallOption { return beforeCall(func(c *callInfo) error { c.failFast = failFast @@ -255,9 +242,11 @@ func (p *parser) recvMsg(maxMsgSize int) (pf payloadFormat, msg []byte, err erro // encode serializes msg and prepends the message header. If msg is nil, it // generates the message header of 0 message length. -func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer) ([]byte, error) { - var b []byte - var length uint +func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer, outPayload *stats.OutPayload) ([]byte, error) { + var ( + b []byte + length uint + ) if msg != nil { var err error // TODO(zhaoq): optimize to reduce memory alloc and copying. @@ -265,6 +254,12 @@ func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer) ([]byte if err != nil { return nil, err } + if outPayload != nil { + outPayload.Payload = msg + // TODO truncate large payload. + outPayload.Data = b + outPayload.Length = len(b) + } if cp != nil { if err := cp.Do(cbuf, b); err != nil { return nil, err @@ -295,6 +290,10 @@ func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer) ([]byte // Copy encoded msg to buf copy(buf[5:], b) + if outPayload != nil { + outPayload.WireLength = len(buf) + } + return buf, nil } @@ -311,11 +310,14 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) er return nil } -func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}, maxMsgSize int) error { +func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}, maxMsgSize int, inPayload *stats.InPayload) error { pf, d, err := p.recvMsg(maxMsgSize) if err != nil { return err } + if inPayload != nil { + inPayload.WireLength = len(d) + } if err := checkRecvPayload(pf, s.RecvCompress(), dc); err != nil { return err } @@ -333,91 +335,90 @@ func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{ if err := c.Unmarshal(d, m); err != nil { return Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err) } + if inPayload != nil { + inPayload.RecvTime = time.Now() + inPayload.Payload = m + // TODO truncate large payload. + inPayload.Data = d + inPayload.Length = len(d) + } return nil } -// rpcError defines the status from an RPC. -type rpcError struct { - code codes.Code - desc string +type rpcInfo struct { + bytesSent bool + bytesReceived bool } -func (e *rpcError) Error() string { - return fmt.Sprintf("rpc error: code = %d desc = %s", e.code, e.desc) +type rpcInfoContextKey struct{} + +func newContextWithRPCInfo(ctx context.Context) context.Context { + return context.WithValue(ctx, rpcInfoContextKey{}, &rpcInfo{}) +} + +func rpcInfoFromContext(ctx context.Context) (s *rpcInfo, ok bool) { + s, ok = ctx.Value(rpcInfoContextKey{}).(*rpcInfo) + return +} + +func updateRPCInfoInContext(ctx context.Context, s rpcInfo) { + if ss, ok := rpcInfoFromContext(ctx); ok { + *ss = s + } + return } // Code returns the error code for err if it was produced by the rpc system. // Otherwise, it returns codes.Unknown. +// +// Deprecated; use status.FromError and Code method instead. func Code(err error) codes.Code { - if err == nil { - return codes.OK - } - if e, ok := err.(*rpcError); ok { - return e.code + if s, ok := status.FromError(err); ok { + return s.Code() } return codes.Unknown } // ErrorDesc returns the error description of err if it was produced by the rpc system. // Otherwise, it returns err.Error() or empty string when err is nil. +// +// Deprecated; use status.FromError and Message method instead. func ErrorDesc(err error) string { - if err == nil { - return "" - } - if e, ok := err.(*rpcError); ok { - return e.desc + if s, ok := status.FromError(err); ok { + return s.Message() } return err.Error() } // Errorf returns an error containing an error code and a description; // Errorf returns nil if c is OK. +// +// Deprecated; use status.Errorf instead. func Errorf(c codes.Code, format string, a ...interface{}) error { - if c == codes.OK { - return nil - } - return &rpcError{ - code: c, - desc: fmt.Sprintf(format, a...), - } + return status.Errorf(c, format, a...) } -// toRPCErr converts an error into a rpcError. +// toRPCErr converts an error into an error from the status package. func toRPCErr(err error) error { - switch e := err.(type) { - case *rpcError: + if _, ok := status.FromError(err); ok { return err + } + switch e := err.(type) { case transport.StreamError: - return &rpcError{ - code: e.Code, - desc: e.Desc, - } + return status.Error(e.Code, e.Desc) case transport.ConnectionError: - return &rpcError{ - code: codes.Internal, - desc: e.Desc, - } + return status.Error(codes.Internal, e.Desc) default: switch err { case context.DeadlineExceeded: - return &rpcError{ - code: codes.DeadlineExceeded, - desc: err.Error(), - } + return status.Error(codes.DeadlineExceeded, err.Error()) case context.Canceled: - return &rpcError{ - code: codes.Canceled, - desc: err.Error(), - } + return status.Error(codes.Canceled, err.Error()) case ErrClientConnClosing: - return &rpcError{ - code: codes.FailedPrecondition, - desc: err.Error(), - } + return status.Error(codes.FailedPrecondition, err.Error()) } - } - return Errorf(codes.Unknown, "%v", err) + return status.Error(codes.Unknown, err.Error()) } // convertCode converts a standard Go error into its canonical code. Note that @@ -448,6 +449,44 @@ func convertCode(err error) codes.Code { return codes.Unknown } +// MethodConfig defines the configuration recommended by the service providers for a +// particular method. +// This is EXPERIMENTAL and subject to change. +type MethodConfig struct { + // WaitForReady indicates whether RPCs sent to this method should wait until + // the connection is ready by default (!failfast). The value specified via the + // gRPC client API will override the value set here. + WaitForReady bool + // Timeout is the default timeout for RPCs sent to this method. The actual + // deadline used will be the minimum of the value specified here and the value + // set by the application via the gRPC client API. If either one is not set, + // then the other will be used. If neither is set, then the RPC has no deadline. + Timeout time.Duration + // MaxReqSize is the maximum allowed payload size for an individual request in a + // stream (client->server) in bytes. The size which is measured is the serialized + // payload after per-message compression (but before stream compression) in bytes. + // The actual value used is the minumum of the value specified here and the value set + // by the application via the gRPC client API. If either one is not set, then the other + // will be used. If neither is set, then the built-in default is used. + // TODO: support this. + MaxReqSize uint32 + // MaxRespSize is the maximum allowed payload size for an individual response in a + // stream (server->client) in bytes. + // TODO: support this. + MaxRespSize uint32 +} + +// ServiceConfig is provided by the service provider and contains parameters for how +// clients that connect to the service should behave. +// This is EXPERIMENTAL and subject to change. +type ServiceConfig struct { + // LB is the load balancer the service providers recommends. The balancer specified + // via grpc.WithBalancer will override this. + LB Balancer + // Methods contains a map for the methods in this service. + Methods map[string]MethodConfig +} + // SupportPackageIsVersion4 is referenced from generated protocol buffer files // to assert that that code is compatible with this version of the grpc package. // @@ -455,3 +494,8 @@ func convertCode(err error) codes.Code { // requires a synchronised update of grpc-go and protoc-gen-go. This constant // should not be referenced from any other code. const SupportPackageIsVersion4 = true + +// Version is the current grpc version. +const Version = "1.3.0" + +const grpcUA = "grpc-go/" + Version diff --git a/components/cli/vendor/google.golang.org/grpc/server.go b/components/cli/vendor/google.golang.org/grpc/server.go index e0bb187ef9..b15f71c6c1 100644 --- a/components/cli/vendor/google.golang.org/grpc/server.go +++ b/components/cli/vendor/google.golang.org/grpc/server.go @@ -53,7 +53,11 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal" + "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/status" + "google.golang.org/grpc/tap" "google.golang.org/grpc/transport" ) @@ -110,8 +114,13 @@ type options struct { maxMsgSize int unaryInt UnaryServerInterceptor streamInt StreamServerInterceptor + inTapHandle tap.ServerInHandle + statsHandler stats.Handler maxConcurrentStreams uint32 useHandlerImpl bool // use http.Handler-based server + unknownStreamDesc *StreamDesc + keepaliveParams keepalive.ServerParameters + keepalivePolicy keepalive.EnforcementPolicy } var defaultMaxMsgSize = 1024 * 1024 * 4 // use 4MB as the default message size limit @@ -119,6 +128,20 @@ var defaultMaxMsgSize = 1024 * 1024 * 4 // use 4MB as the default message size l // A ServerOption sets options. type ServerOption func(*options) +// KeepaliveParams returns a ServerOption that sets keepalive and max-age parameters for the server. +func KeepaliveParams(kp keepalive.ServerParameters) ServerOption { + return func(o *options) { + o.keepaliveParams = kp + } +} + +// KeepaliveEnforcementPolicy returns a ServerOption that sets keepalive enforcement policy for the server. +func KeepaliveEnforcementPolicy(kep keepalive.EnforcementPolicy) ServerOption { + return func(o *options) { + o.keepalivePolicy = kep + } +} + // CustomCodec returns a ServerOption that sets a codec for message marshaling and unmarshaling. func CustomCodec(codec Codec) ServerOption { return func(o *options) { @@ -186,6 +209,42 @@ func StreamInterceptor(i StreamServerInterceptor) ServerOption { } } +// InTapHandle returns a ServerOption that sets the tap handle for all the server +// transport to be created. Only one can be installed. +func InTapHandle(h tap.ServerInHandle) ServerOption { + return func(o *options) { + if o.inTapHandle != nil { + panic("The tap handle has been set.") + } + o.inTapHandle = h + } +} + +// StatsHandler returns a ServerOption that sets the stats handler for the server. +func StatsHandler(h stats.Handler) ServerOption { + return func(o *options) { + o.statsHandler = h + } +} + +// UnknownServiceHandler returns a ServerOption that allows for adding a custom +// unknown service handler. The provided method is a bidi-streaming RPC service +// handler that will be invoked instead of returning the the "unimplemented" gRPC +// error whenever a request is received for an unregistered service or method. +// The handling function has full access to the Context of the request and the +// stream, and the invocation passes through interceptors. +func UnknownServiceHandler(streamHandler StreamHandler) ServerOption { + return func(o *options) { + o.unknownStreamDesc = &StreamDesc{ + StreamName: "unknown_service_handler", + Handler: streamHandler, + // We need to assume that the users of the streamHandler will want to use both. + ClientStreams: true, + ServerStreams: true, + } + } +} + // NewServer creates a gRPC server which has no service registered and has not // started to accept requests yet. func NewServer(opt ...ServerOption) *Server { @@ -329,6 +388,7 @@ func (s *Server) useTransportAuthenticator(rawConn net.Conn) (net.Conn, credenti // read gRPC requests and then call the registered handlers to reply to them. // Serve returns when lis.Accept fails with fatal errors. lis will be closed when // this method returns. +// Serve always returns non-nil error. func (s *Server) Serve(lis net.Listener) error { s.mu.Lock() s.printf("serving") @@ -412,17 +472,25 @@ func (s *Server) handleRawConn(rawConn net.Conn) { if s.opts.useHandlerImpl { s.serveUsingHandler(conn) } else { - s.serveNewHTTP2Transport(conn, authInfo) + s.serveHTTP2Transport(conn, authInfo) } } -// serveNewHTTP2Transport sets up a new http/2 transport (using the +// serveHTTP2Transport sets up a http/2 transport (using the // gRPC http2 server transport in transport/http2_server.go) and // serves streams on it. // This is run in its own goroutine (it does network I/O in // transport.NewServerTransport). -func (s *Server) serveNewHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) { - st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo) +func (s *Server) serveHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) { + config := &transport.ServerConfig{ + MaxStreams: s.opts.maxConcurrentStreams, + AuthInfo: authInfo, + InTapHandle: s.opts.inTapHandle, + StatsHandler: s.opts.statsHandler, + KeepaliveParams: s.opts.keepaliveParams, + KeepalivePolicy: s.opts.keepalivePolicy, + } + st, err := transport.NewServerTransport("http2", c, config) if err != nil { s.mu.Lock() s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err) @@ -448,6 +516,12 @@ func (s *Server) serveStreams(st transport.ServerTransport) { defer wg.Done() s.handleStream(st, stream, s.traceInfo(st, stream)) }() + }, func(ctx context.Context, method string) context.Context { + if !EnableTracing { + return ctx + } + tr := trace.New("grpc.Recv."+methodFamily(method), method) + return trace.NewContext(ctx, tr) }) wg.Wait() } @@ -497,15 +571,17 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // traceInfo returns a traceInfo and associates it with stream, if tracing is enabled. // If tracing is not enabled, it returns nil. func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Stream) (trInfo *traceInfo) { - if !EnableTracing { + tr, ok := trace.FromContext(stream.Context()) + if !ok { return nil } + trInfo = &traceInfo{ - tr: trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()), + tr: tr, } trInfo.firstLine.client = false trInfo.firstLine.remoteAddr = st.RemoteAddr() - stream.TraceContext(trInfo.tr) + if dl, ok := stream.Context().Deadline(); ok { trInfo.firstLine.deadline = dl.Sub(time.Now()) } @@ -532,11 +608,17 @@ func (s *Server) removeConn(c io.Closer) { } func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options) error { - var cbuf *bytes.Buffer + var ( + cbuf *bytes.Buffer + outPayload *stats.OutPayload + ) if cp != nil { cbuf = new(bytes.Buffer) } - p, err := encode(s.opts.codec, msg, cp, cbuf) + if s.opts.statsHandler != nil { + outPayload = &stats.OutPayload{} + } + p, err := encode(s.opts.codec, msg, cp, cbuf, outPayload) if err != nil { // This typically indicates a fatal issue (e.g., memory // corruption or hardware faults) the application program @@ -547,10 +629,33 @@ func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Str // the optimal option. grpclog.Fatalf("grpc: Server failed to encode response %v", err) } - return t.Write(stream, p, opts) + err = t.Write(stream, p, opts) + if err == nil && outPayload != nil { + outPayload.SentTime = time.Now() + s.opts.statsHandler.HandleRPC(stream.Context(), outPayload) + } + return err } func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, md *MethodDesc, trInfo *traceInfo) (err error) { + sh := s.opts.statsHandler + if sh != nil { + begin := &stats.Begin{ + BeginTime: time.Now(), + } + sh.HandleRPC(stream.Context(), begin) + } + defer func() { + if sh != nil { + end := &stats.End{ + EndTime: time.Now(), + } + if err != nil && err != io.EOF { + end.Error = toRPCErr(err) + } + sh.HandleRPC(stream.Context(), end) + } + }() if trInfo != nil { defer trInfo.tr.Finish() trInfo.firstLine.client = false @@ -567,7 +672,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. stream.SetSendCompress(s.opts.cp.Type()) } p := &parser{r: stream} - for { + for { // TODO: delete pf, req, err := p.recvMsg(s.opts.maxMsgSize) if err == io.EOF { // The entire stream is done (for unary RPC only). @@ -577,58 +682,68 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. err = Errorf(codes.Internal, io.ErrUnexpectedEOF.Error()) } if err != nil { - switch err := err.(type) { - case *rpcError: - if err := t.WriteStatus(stream, err.code, err.desc); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) + if st, ok := status.FromError(err); ok { + if e := t.WriteStatus(stream, st); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", e) } - case transport.ConnectionError: - // Nothing to do here. - case transport.StreamError: - if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) + } else { + switch st := err.(type) { + case transport.ConnectionError: + // Nothing to do here. + case transport.StreamError: + if e := t.WriteStatus(stream, status.New(st.Code, st.Desc)); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", e) + } + default: + panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", st, st)) } - default: - panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", err, err)) } return err } if err := checkRecvPayload(pf, stream.RecvCompress(), s.opts.dc); err != nil { - switch err := err.(type) { - case *rpcError: - if err := t.WriteStatus(stream, err.code, err.desc); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) + if st, ok := status.FromError(err); ok { + if e := t.WriteStatus(stream, st); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", e) } - default: - if err := t.WriteStatus(stream, codes.Internal, err.Error()); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) - } + return err + } + if e := t.WriteStatus(stream, status.New(codes.Internal, err.Error())); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", e) + } + // TODO checkRecvPayload always return RPC error. Add a return here if necessary. + } + var inPayload *stats.InPayload + if sh != nil { + inPayload = &stats.InPayload{ + RecvTime: time.Now(), } - return err } - statusCode := codes.OK - statusDesc := "" df := func(v interface{}) error { + if inPayload != nil { + inPayload.WireLength = len(req) + } if pf == compressionMade { var err error req, err = s.opts.dc.Do(bytes.NewReader(req)) if err != nil { - if err := t.WriteStatus(stream, codes.Internal, err.Error()); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", err) - } - return err + return Errorf(codes.Internal, err.Error()) } } if len(req) > s.opts.maxMsgSize { // TODO: Revisit the error code. Currently keep it consistent with // java implementation. - statusCode = codes.Internal - statusDesc = fmt.Sprintf("grpc: server received a message of %d bytes exceeding %d limit", len(req), s.opts.maxMsgSize) + return status.Errorf(codes.Internal, "grpc: server received a message of %d bytes exceeding %d limit", len(req), s.opts.maxMsgSize) } if err := s.opts.codec.Unmarshal(req, v); err != nil { - return err + return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err) + } + if inPayload != nil { + inPayload.Payload = v + inPayload.Data = req + inPayload.Length = len(req) + sh.HandleRPC(stream.Context(), inPayload) } if trInfo != nil { trInfo.tr.LazyLog(&payload{sent: false, msg: v}, true) @@ -637,22 +752,20 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. } reply, appErr := md.Handler(srv.server, stream.Context(), df, s.opts.unaryInt) if appErr != nil { - if err, ok := appErr.(*rpcError); ok { - statusCode = err.code - statusDesc = err.desc - } else { - statusCode = convertCode(appErr) - statusDesc = appErr.Error() + appStatus, ok := status.FromError(appErr) + if !ok { + // Convert appErr if it is not a grpc status error. + appErr = status.Error(convertCode(appErr), appErr.Error()) + appStatus, _ = status.FromError(appErr) } - if trInfo != nil && statusCode != codes.OK { - trInfo.tr.LazyLog(stringer(statusDesc), true) + if trInfo != nil { + trInfo.tr.LazyLog(stringer(appStatus.Message()), true) trInfo.tr.SetError() } - if err := t.WriteStatus(stream, statusCode, statusDesc); err != nil { - grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err) - return err + if e := t.WriteStatus(stream, appStatus); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", e) } - return nil + return appErr } if trInfo != nil { trInfo.tr.LazyLog(stringer("OK"), false) @@ -662,38 +775,70 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport. Delay: false, } if err := s.sendResponse(t, stream, reply, s.opts.cp, opts); err != nil { - switch err := err.(type) { - case transport.ConnectionError: - // Nothing to do here. - case transport.StreamError: - statusCode = err.Code - statusDesc = err.Desc - default: - statusCode = codes.Unknown - statusDesc = err.Error() + if err == io.EOF { + // The entire stream is done (for unary RPC only). + return err + } + if s, ok := status.FromError(err); ok { + if e := t.WriteStatus(stream, s); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", e) + } + } else { + switch st := err.(type) { + case transport.ConnectionError: + // Nothing to do here. + case transport.StreamError: + if e := t.WriteStatus(stream, status.New(st.Code, st.Desc)); e != nil { + grpclog.Printf("grpc: Server.processUnaryRPC failed to write status %v", e) + } + default: + panic(fmt.Sprintf("grpc: Unexpected error (%T) from sendResponse: %v", st, st)) + } } return err } if trInfo != nil { trInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true) } - return t.WriteStatus(stream, statusCode, statusDesc) + // TODO: Should we be logging if writing status failed here, like above? + // Should the logging be in WriteStatus? Should we ignore the WriteStatus + // error or allow the stats handler to see it? + return t.WriteStatus(stream, status.New(codes.OK, "")) } } func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc, trInfo *traceInfo) (err error) { + sh := s.opts.statsHandler + if sh != nil { + begin := &stats.Begin{ + BeginTime: time.Now(), + } + sh.HandleRPC(stream.Context(), begin) + } + defer func() { + if sh != nil { + end := &stats.End{ + EndTime: time.Now(), + } + if err != nil && err != io.EOF { + end.Error = toRPCErr(err) + } + sh.HandleRPC(stream.Context(), end) + } + }() if s.opts.cp != nil { stream.SetSendCompress(s.opts.cp.Type()) } ss := &serverStream{ - t: t, - s: stream, - p: &parser{r: stream}, - codec: s.opts.codec, - cp: s.opts.cp, - dc: s.opts.dc, - maxMsgSize: s.opts.maxMsgSize, - trInfo: trInfo, + t: t, + s: stream, + p: &parser{r: stream}, + codec: s.opts.codec, + cp: s.opts.cp, + dc: s.opts.dc, + maxMsgSize: s.opts.maxMsgSize, + trInfo: trInfo, + statsHandler: sh, } if ss.cp != nil { ss.cbuf = new(bytes.Buffer) @@ -712,39 +857,47 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp }() } var appErr error + var server interface{} + if srv != nil { + server = srv.server + } if s.opts.streamInt == nil { - appErr = sd.Handler(srv.server, ss) + appErr = sd.Handler(server, ss) } else { info := &StreamServerInfo{ FullMethod: stream.Method(), IsClientStream: sd.ClientStreams, IsServerStream: sd.ServerStreams, } - appErr = s.opts.streamInt(srv.server, ss, info, sd.Handler) + appErr = s.opts.streamInt(server, ss, info, sd.Handler) } if appErr != nil { - if err, ok := appErr.(*rpcError); ok { - ss.statusCode = err.code - ss.statusDesc = err.desc - } else if err, ok := appErr.(transport.StreamError); ok { - ss.statusCode = err.Code - ss.statusDesc = err.Desc - } else { - ss.statusCode = convertCode(appErr) - ss.statusDesc = appErr.Error() + appStatus, ok := status.FromError(appErr) + if !ok { + switch err := appErr.(type) { + case transport.StreamError: + appStatus = status.New(err.Code, err.Desc) + default: + appStatus = status.New(convertCode(appErr), appErr.Error()) + } + appErr = appStatus.Err() } + if trInfo != nil { + ss.mu.Lock() + ss.trInfo.tr.LazyLog(stringer(appStatus.Message()), true) + ss.trInfo.tr.SetError() + ss.mu.Unlock() + } + t.WriteStatus(ss.s, appStatus) + // TODO: Should we log an error from WriteStatus here and below? + return appErr } if trInfo != nil { ss.mu.Lock() - if ss.statusCode != codes.OK { - ss.trInfo.tr.LazyLog(stringer(ss.statusDesc), true) - ss.trInfo.tr.SetError() - } else { - ss.trInfo.tr.LazyLog(stringer("OK"), false) - } + ss.trInfo.tr.LazyLog(stringer("OK"), false) ss.mu.Unlock() } - return t.WriteStatus(ss.s, ss.statusCode, ss.statusDesc) + return t.WriteStatus(ss.s, status.New(codes.OK, "")) } @@ -759,7 +912,8 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []interface{}{sm}}, true) trInfo.tr.SetError() } - if err := t.WriteStatus(stream, codes.InvalidArgument, fmt.Sprintf("malformed method name: %q", stream.Method())); err != nil { + errDesc := fmt.Sprintf("malformed method name: %q", stream.Method()) + if err := t.WriteStatus(stream, status.New(codes.InvalidArgument, errDesc)); err != nil { if trInfo != nil { trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) trInfo.tr.SetError() @@ -775,11 +929,16 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str method := sm[pos+1:] srv, ok := s.m[service] if !ok { + if unknownDesc := s.opts.unknownStreamDesc; unknownDesc != nil { + s.processStreamingRPC(t, stream, nil, unknownDesc, trInfo) + return + } if trInfo != nil { trInfo.tr.LazyLog(&fmtStringer{"Unknown service %v", []interface{}{service}}, true) trInfo.tr.SetError() } - if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown service %v", service)); err != nil { + errDesc := fmt.Sprintf("unknown service %v", service) + if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil { if trInfo != nil { trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) trInfo.tr.SetError() @@ -804,7 +963,12 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str trInfo.tr.LazyLog(&fmtStringer{"Unknown method %v", []interface{}{method}}, true) trInfo.tr.SetError() } - if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown method %v", method)); err != nil { + if unknownDesc := s.opts.unknownStreamDesc; unknownDesc != nil { + s.processStreamingRPC(t, stream, nil, unknownDesc, trInfo) + return + } + errDesc := fmt.Sprintf("unknown method %v", method) + if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil { if trInfo != nil { trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) trInfo.tr.SetError() diff --git a/components/cli/vendor/google.golang.org/grpc/stats/handlers.go b/components/cli/vendor/google.golang.org/grpc/stats/handlers.go new file mode 100644 index 0000000000..26e1a8e2f0 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/stats/handlers.go @@ -0,0 +1,76 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package stats + +import ( + "net" + + "golang.org/x/net/context" +) + +// ConnTagInfo defines the relevant information needed by connection context tagger. +type ConnTagInfo struct { + // RemoteAddr is the remote address of the corresponding connection. + RemoteAddr net.Addr + // LocalAddr is the local address of the corresponding connection. + LocalAddr net.Addr + // TODO add QOS related fields. +} + +// RPCTagInfo defines the relevant information needed by RPC context tagger. +type RPCTagInfo struct { + // FullMethodName is the RPC method in the format of /package.service/method. + FullMethodName string +} + +// Handler defines the interface for the related stats handling (e.g., RPCs, connections). +type Handler interface { + // TagRPC can attach some information to the given context. + // The returned context is used in the rest lifetime of the RPC. + TagRPC(context.Context, *RPCTagInfo) context.Context + // HandleRPC processes the RPC stats. + HandleRPC(context.Context, RPCStats) + + // TagConn can attach some information to the given context. + // The returned context will be used for stats handling. + // For conn stats handling, the context used in HandleConn for this + // connection will be derived from the context returned. + // For RPC stats handling, + // - On server side, the context used in HandleRPC for all RPCs on this + // connection will be derived from the context returned. + // - On client side, the context is not derived from the context returned. + TagConn(context.Context, *ConnTagInfo) context.Context + // HandleConn processes the Conn stats. + HandleConn(context.Context, ConnStats) +} diff --git a/components/cli/vendor/google.golang.org/grpc/stats/stats.go b/components/cli/vendor/google.golang.org/grpc/stats/stats.go new file mode 100644 index 0000000000..43d6f0054d --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/stats/stats.go @@ -0,0 +1,223 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// Package stats is for collecting and reporting various network and RPC stats. +// This package is for monitoring purpose only. All fields are read-only. +// All APIs are experimental. +package stats // import "google.golang.org/grpc/stats" + +import ( + "net" + "time" +) + +// RPCStats contains stats information about RPCs. +type RPCStats interface { + isRPCStats() + // IsClient returns true if this RPCStats is from client side. + IsClient() bool +} + +// Begin contains stats when an RPC begins. +// FailFast are only valid if Client is true. +type Begin struct { + // Client is true if this Begin is from client side. + Client bool + // BeginTime is the time when the RPC begins. + BeginTime time.Time + // FailFast indicates if this RPC is failfast. + FailFast bool +} + +// IsClient indicates if this is from client side. +func (s *Begin) IsClient() bool { return s.Client } + +func (s *Begin) isRPCStats() {} + +// InPayload contains the information for an incoming payload. +type InPayload struct { + // Client is true if this InPayload is from client side. + Client bool + // Payload is the payload with original type. + Payload interface{} + // Data is the serialized message payload. + Data []byte + // Length is the length of uncompressed data. + Length int + // WireLength is the length of data on wire (compressed, signed, encrypted). + WireLength int + // RecvTime is the time when the payload is received. + RecvTime time.Time +} + +// IsClient indicates if this is from client side. +func (s *InPayload) IsClient() bool { return s.Client } + +func (s *InPayload) isRPCStats() {} + +// InHeader contains stats when a header is received. +// FullMethod, addresses and Compression are only valid if Client is false. +type InHeader struct { + // Client is true if this InHeader is from client side. + Client bool + // WireLength is the wire length of header. + WireLength int + + // FullMethod is the full RPC method string, i.e., /package.service/method. + FullMethod string + // RemoteAddr is the remote address of the corresponding connection. + RemoteAddr net.Addr + // LocalAddr is the local address of the corresponding connection. + LocalAddr net.Addr + // Compression is the compression algorithm used for the RPC. + Compression string +} + +// IsClient indicates if this is from client side. +func (s *InHeader) IsClient() bool { return s.Client } + +func (s *InHeader) isRPCStats() {} + +// InTrailer contains stats when a trailer is received. +type InTrailer struct { + // Client is true if this InTrailer is from client side. + Client bool + // WireLength is the wire length of trailer. + WireLength int +} + +// IsClient indicates if this is from client side. +func (s *InTrailer) IsClient() bool { return s.Client } + +func (s *InTrailer) isRPCStats() {} + +// OutPayload contains the information for an outgoing payload. +type OutPayload struct { + // Client is true if this OutPayload is from client side. + Client bool + // Payload is the payload with original type. + Payload interface{} + // Data is the serialized message payload. + Data []byte + // Length is the length of uncompressed data. + Length int + // WireLength is the length of data on wire (compressed, signed, encrypted). + WireLength int + // SentTime is the time when the payload is sent. + SentTime time.Time +} + +// IsClient indicates if this is from client side. +func (s *OutPayload) IsClient() bool { return s.Client } + +func (s *OutPayload) isRPCStats() {} + +// OutHeader contains stats when a header is sent. +// FullMethod, addresses and Compression are only valid if Client is true. +type OutHeader struct { + // Client is true if this OutHeader is from client side. + Client bool + // WireLength is the wire length of header. + WireLength int + + // FullMethod is the full RPC method string, i.e., /package.service/method. + FullMethod string + // RemoteAddr is the remote address of the corresponding connection. + RemoteAddr net.Addr + // LocalAddr is the local address of the corresponding connection. + LocalAddr net.Addr + // Compression is the compression algorithm used for the RPC. + Compression string +} + +// IsClient indicates if this is from client side. +func (s *OutHeader) IsClient() bool { return s.Client } + +func (s *OutHeader) isRPCStats() {} + +// OutTrailer contains stats when a trailer is sent. +type OutTrailer struct { + // Client is true if this OutTrailer is from client side. + Client bool + // WireLength is the wire length of trailer. + WireLength int +} + +// IsClient indicates if this is from client side. +func (s *OutTrailer) IsClient() bool { return s.Client } + +func (s *OutTrailer) isRPCStats() {} + +// End contains stats when an RPC ends. +type End struct { + // Client is true if this End is from client side. + Client bool + // EndTime is the time when the RPC ends. + EndTime time.Time + // Error is the error just happened. It implements status.Status if non-nil. + Error error +} + +// IsClient indicates if this is from client side. +func (s *End) IsClient() bool { return s.Client } + +func (s *End) isRPCStats() {} + +// ConnStats contains stats information about connections. +type ConnStats interface { + isConnStats() + // IsClient returns true if this ConnStats is from client side. + IsClient() bool +} + +// ConnBegin contains the stats of a connection when it is established. +type ConnBegin struct { + // Client is true if this ConnBegin is from client side. + Client bool +} + +// IsClient indicates if this is from client side. +func (s *ConnBegin) IsClient() bool { return s.Client } + +func (s *ConnBegin) isConnStats() {} + +// ConnEnd contains the stats of a connection when it ends. +type ConnEnd struct { + // Client is true if this ConnEnd is from client side. + Client bool +} + +// IsClient indicates if this is from client side. +func (s *ConnEnd) IsClient() bool { return s.Client } + +func (s *ConnEnd) isConnStats() {} diff --git a/components/cli/vendor/google.golang.org/grpc/status/status.go b/components/cli/vendor/google.golang.org/grpc/status/status.go new file mode 100644 index 0000000000..99a4cbe511 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/status/status.go @@ -0,0 +1,145 @@ +/* + * + * Copyright 2017, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// Package status implements errors returned by gRPC. These errors are +// serialized and transmitted on the wire between server and client, and allow +// for additional data to be transmitted via the Details field in the status +// proto. gRPC service handlers should return an error created by this +// package, and gRPC clients should expect a corresponding error to be +// returned from the RPC call. +// +// This package upholds the invariants that a non-nil error may not +// contain an OK code, and an OK code must result in a nil error. +package status + +import ( + "fmt" + + "github.com/golang/protobuf/proto" + spb "google.golang.org/genproto/googleapis/rpc/status" + "google.golang.org/grpc/codes" +) + +// statusError is an alias of a status proto. It implements error and Status, +// and a nil statusError should never be returned by this package. +type statusError spb.Status + +func (se *statusError) Error() string { + p := (*spb.Status)(se) + return fmt.Sprintf("rpc error: code = %s desc = %s", codes.Code(p.GetCode()), p.GetMessage()) +} + +func (se *statusError) status() *Status { + return &Status{s: (*spb.Status)(se)} +} + +// Status represents an RPC status code, message, and details. It is immutable +// and should be created with New, Newf, or FromProto. +type Status struct { + s *spb.Status +} + +// Code returns the status code contained in s. +func (s *Status) Code() codes.Code { + if s == nil || s.s == nil { + return codes.OK + } + return codes.Code(s.s.Code) +} + +// Message returns the message contained in s. +func (s *Status) Message() string { + if s == nil || s.s == nil { + return "" + } + return s.s.Message +} + +// Proto returns s's status as an spb.Status proto message. +func (s *Status) Proto() *spb.Status { + if s == nil { + return nil + } + return proto.Clone(s.s).(*spb.Status) +} + +// Err returns an immutable error representing s; returns nil if s.Code() is +// OK. +func (s *Status) Err() error { + if s.Code() == codes.OK { + return nil + } + return (*statusError)(s.s) +} + +// New returns a Status representing c and msg. +func New(c codes.Code, msg string) *Status { + return &Status{s: &spb.Status{Code: int32(c), Message: msg}} +} + +// Newf returns New(c, fmt.Sprintf(format, a...)). +func Newf(c codes.Code, format string, a ...interface{}) *Status { + return New(c, fmt.Sprintf(format, a...)) +} + +// Error returns an error representing c and msg. If c is OK, returns nil. +func Error(c codes.Code, msg string) error { + return New(c, msg).Err() +} + +// Errorf returns Error(c, fmt.Sprintf(format, a...)). +func Errorf(c codes.Code, format string, a ...interface{}) error { + return Error(c, fmt.Sprintf(format, a...)) +} + +// ErrorProto returns an error representing s. If s.Code is OK, returns nil. +func ErrorProto(s *spb.Status) error { + return FromProto(s).Err() +} + +// FromProto returns a Status representing s. +func FromProto(s *spb.Status) *Status { + return &Status{s: proto.Clone(s).(*spb.Status)} +} + +// FromError returns a Status representing err if it was produced from this +// package, otherwise it returns nil, false. +func FromError(err error) (s *Status, ok bool) { + if err == nil { + return &Status{s: &spb.Status{Code: int32(codes.OK)}}, true + } + if s, ok := err.(*statusError); ok { + return s.status(), true + } + return nil, false +} diff --git a/components/cli/vendor/google.golang.org/grpc/stream.go b/components/cli/vendor/google.golang.org/grpc/stream.go index 46810544f1..33f1c787b3 100644 --- a/components/cli/vendor/google.golang.org/grpc/stream.go +++ b/components/cli/vendor/google.golang.org/grpc/stream.go @@ -37,7 +37,6 @@ import ( "bytes" "errors" "io" - "math" "sync" "time" @@ -45,6 +44,8 @@ import ( "golang.org/x/net/trace" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/status" "google.golang.org/grpc/transport" ) @@ -97,7 +98,7 @@ type ClientStream interface { // NewClientStream creates a new Stream for the client side. This is called // by generated code. -func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) { +func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) { if cc.dopts.streamInt != nil { return cc.dopts.streamInt(ctx, desc, cc, method, newClientStream, opts...) } @@ -106,11 +107,18 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) { var ( - t transport.ClientTransport - s *transport.Stream - put func() + t transport.ClientTransport + s *transport.Stream + put func() + cancel context.CancelFunc ) c := defaultCallInfo + if mc, ok := cc.getMethodConfig(method); ok { + c.failFast = !mc.WaitForReady + if mc.Timeout > 0 { + ctx, cancel = context.WithTimeout(ctx, mc.Timeout) + } + } for _, o := range opts { if err := o.before(&c); err != nil { return nil, toRPCErr(err) @@ -143,6 +151,27 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth } }() } + ctx = newContextWithRPCInfo(ctx) + sh := cc.dopts.copts.StatsHandler + if sh != nil { + ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method}) + begin := &stats.Begin{ + Client: true, + BeginTime: time.Now(), + FailFast: c.failFast, + } + sh.HandleRPC(ctx, begin) + } + defer func() { + if err != nil && sh != nil { + // Only handle end stats if err != nil. + end := &stats.End{ + Client: true, + Error: err, + } + sh.HandleRPC(ctx, end) + } + }() gopts := BalancerGetOptions{ BlockingWait: !c.failFast, } @@ -150,7 +179,7 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth t, put, err = cc.getTransport(ctx, gopts) if err != nil { // TODO(zhaoq): Probably revisit the error handling. - if _, ok := err.(*rpcError); ok { + if _, ok := status.FromError(err); ok { return nil, err } if err == errConnClosing || err == errConnUnavailable { @@ -165,14 +194,17 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth s, err = t.NewStream(ctx, callHdr) if err != nil { + if _, ok := err.(transport.ConnectionError); ok && put != nil { + // If error is connection error, transport was sending data on wire, + // and we are not sure if anything has been sent on wire. + // If error is not connection error, we are sure nothing has been sent. + updateRPCInfoInContext(ctx, rpcInfo{bytesSent: true, bytesReceived: false}) + } if put != nil { put() put = nil } - if _, ok := err.(transport.ConnectionError); ok || err == transport.ErrStreamDrain { - if c.failFast { - return nil, toRPCErr(err) - } + if _, ok := err.(transport.ConnectionError); (ok || err == transport.ErrStreamDrain) && !c.failFast { continue } return nil, toRPCErr(err) @@ -180,12 +212,14 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth break } cs := &clientStream{ - opts: opts, - c: c, - desc: desc, - codec: cc.dopts.codec, - cp: cc.dopts.cp, - dc: cc.dopts.dc, + opts: opts, + c: c, + desc: desc, + codec: cc.dopts.codec, + cp: cc.dopts.cp, + dc: cc.dopts.dc, + maxMsgSize: cc.dopts.maxMsgSize, + cancel: cancel, put: put, t: t, @@ -194,6 +228,9 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth tracing: EnableTracing, trInfo: trInfo, + + statsCtx: ctx, + statsHandler: cc.dopts.copts.StatsHandler, } if cc.dopts.cp != nil { cs.cbuf = new(bytes.Buffer) @@ -204,14 +241,13 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth select { case <-t.Error(): // Incur transport error, simply exit. + case <-cc.ctx.Done(): + cs.finish(ErrClientConnClosing) + cs.closeTransportStream(ErrClientConnClosing) case <-s.Done(): // TODO: The trace of the RPC is terminated here when there is no pending // I/O, which is probably not the optimal solution. - if s.StatusCode() == codes.OK { - cs.finish(nil) - } else { - cs.finish(Errorf(s.StatusCode(), "%s", s.StatusDesc())) - } + cs.finish(s.Status().Err()) cs.closeTransportStream(nil) case <-s.GoAway(): cs.finish(errConnDrain) @@ -227,25 +263,34 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth // clientStream implements a client side Stream. type clientStream struct { - opts []CallOption - c callInfo - t transport.ClientTransport - s *transport.Stream - p *parser - desc *StreamDesc - codec Codec - cp Compressor - cbuf *bytes.Buffer - dc Decompressor + opts []CallOption + c callInfo + t transport.ClientTransport + s *transport.Stream + p *parser + desc *StreamDesc + codec Codec + cp Compressor + cbuf *bytes.Buffer + dc Decompressor + maxMsgSize int + cancel context.CancelFunc tracing bool // set to EnableTracing when the clientStream is created. - mu sync.Mutex - put func() - closed bool + mu sync.Mutex + put func() + closed bool + finished bool // trInfo.tr is set when the clientStream is created (if EnableTracing is true), // and is set to nil when the clientStream's finish method is called. trInfo traceInfo + + // statsCtx keeps the user context for stats handling. + // All stats collection should use the statsCtx (instead of the stream context) + // so that all the generated stats for a particular RPC can be associated in the processing phase. + statsCtx context.Context + statsHandler stats.Handler } func (cs *clientStream) Context() context.Context { @@ -274,6 +319,8 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { } cs.mu.Unlock() } + // TODO Investigate how to signal the stats handling party. + // generate error stats if err != nil && err != io.EOF? defer func() { if err != nil { cs.finish(err) @@ -296,7 +343,13 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { } err = toRPCErr(err) }() - out, err := encode(cs.codec, m, cs.cp, cs.cbuf) + var outPayload *stats.OutPayload + if cs.statsHandler != nil { + outPayload = &stats.OutPayload{ + Client: true, + } + } + out, err := encode(cs.codec, m, cs.cp, cs.cbuf, outPayload) defer func() { if cs.cbuf != nil { cs.cbuf.Reset() @@ -305,11 +358,22 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) { if err != nil { return Errorf(codes.Internal, "grpc: %v", err) } - return cs.t.Write(cs.s, out, &transport.Options{Last: false}) + err = cs.t.Write(cs.s, out, &transport.Options{Last: false}) + if err == nil && outPayload != nil { + outPayload.SentTime = time.Now() + cs.statsHandler.HandleRPC(cs.statsCtx, outPayload) + } + return err } func (cs *clientStream) RecvMsg(m interface{}) (err error) { - err = recv(cs.p, cs.codec, cs.s, cs.dc, m, math.MaxInt32) + var inPayload *stats.InPayload + if cs.statsHandler != nil { + inPayload = &stats.InPayload{ + Client: true, + } + } + err = recv(cs.p, cs.codec, cs.s, cs.dc, m, cs.maxMsgSize, inPayload) defer func() { // err != nil indicates the termination of the stream. if err != nil { @@ -324,21 +388,25 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) { } cs.mu.Unlock() } + if inPayload != nil { + cs.statsHandler.HandleRPC(cs.statsCtx, inPayload) + } if !cs.desc.ClientStreams || cs.desc.ServerStreams { return } // Special handling for client streaming rpc. - err = recv(cs.p, cs.codec, cs.s, cs.dc, m, math.MaxInt32) + // This recv expects EOF or errors, so we don't collect inPayload. + err = recv(cs.p, cs.codec, cs.s, cs.dc, m, cs.maxMsgSize, nil) cs.closeTransportStream(err) if err == nil { return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) } if err == io.EOF { - if cs.s.StatusCode() == codes.OK { - cs.finish(err) - return nil + if se := cs.s.Status().Err(); se != nil { + return se } - return Errorf(cs.s.StatusCode(), "%s", cs.s.StatusDesc()) + cs.finish(err) + return nil } return toRPCErr(err) } @@ -346,11 +414,11 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) { cs.closeTransportStream(err) } if err == io.EOF { - if cs.s.StatusCode() == codes.OK { - // Returns io.EOF to indicate the end of the stream. - return + if statusErr := cs.s.Status().Err(); statusErr != nil { + return statusErr } - return Errorf(cs.s.StatusCode(), "%s", cs.s.StatusDesc()) + // Returns io.EOF to indicate the end of the stream. + return } return toRPCErr(err) } @@ -386,13 +454,37 @@ func (cs *clientStream) closeTransportStream(err error) { func (cs *clientStream) finish(err error) { cs.mu.Lock() defer cs.mu.Unlock() + if cs.finished { + return + } + cs.finished = true + defer func() { + if cs.cancel != nil { + cs.cancel() + } + }() for _, o := range cs.opts { o.after(&cs.c) } if cs.put != nil { + updateRPCInfoInContext(cs.s.Context(), rpcInfo{ + bytesSent: cs.s.BytesSent(), + bytesReceived: cs.s.BytesReceived(), + }) cs.put() cs.put = nil } + if cs.statsHandler != nil { + end := &stats.End{ + Client: true, + EndTime: time.Now(), + } + if err != io.EOF { + // end.Error is nil if the RPC finished successfully. + end.Error = toRPCErr(err) + } + cs.statsHandler.HandleRPC(cs.statsCtx, end) + } if !cs.tracing { return } @@ -437,10 +529,10 @@ type serverStream struct { dc Decompressor cbuf *bytes.Buffer maxMsgSize int - statusCode codes.Code - statusDesc string trInfo *traceInfo + statsHandler stats.Handler + mu sync.Mutex // protects trInfo.tr after the service handler runs. } @@ -482,7 +574,11 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { ss.mu.Unlock() } }() - out, err := encode(ss.codec, m, ss.cp, ss.cbuf) + var outPayload *stats.OutPayload + if ss.statsHandler != nil { + outPayload = &stats.OutPayload{} + } + out, err := encode(ss.codec, m, ss.cp, ss.cbuf, outPayload) defer func() { if ss.cbuf != nil { ss.cbuf.Reset() @@ -495,6 +591,10 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) { if err := ss.t.Write(ss.s, out, &transport.Options{Last: false}); err != nil { return toRPCErr(err) } + if outPayload != nil { + outPayload.SentTime = time.Now() + ss.statsHandler.HandleRPC(ss.s.Context(), outPayload) + } return nil } @@ -513,7 +613,11 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { ss.mu.Unlock() } }() - if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxMsgSize); err != nil { + var inPayload *stats.InPayload + if ss.statsHandler != nil { + inPayload = &stats.InPayload{} + } + if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxMsgSize, inPayload); err != nil { if err == io.EOF { return err } @@ -522,5 +626,8 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) { } return toRPCErr(err) } + if inPayload != nil { + ss.statsHandler.HandleRPC(ss.s.Context(), inPayload) + } return nil } diff --git a/components/cli/vendor/google.golang.org/grpc/tap/tap.go b/components/cli/vendor/google.golang.org/grpc/tap/tap.go new file mode 100644 index 0000000000..0f36647674 --- /dev/null +++ b/components/cli/vendor/google.golang.org/grpc/tap/tap.go @@ -0,0 +1,54 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// Package tap defines the function handles which are executed on the transport +// layer of gRPC-Go and related information. Everything here is EXPERIMENTAL. +package tap + +import ( + "golang.org/x/net/context" +) + +// Info defines the relevant information needed by the handles. +type Info struct { + // FullMethodName is the string of grpc method (in the format of + // /package.service/method). + FullMethodName string + // TODO: More to be added. +} + +// ServerInHandle defines the function which runs when a new stream is created +// on the server side. Note that it is executed in the per-connection I/O goroutine(s) instead +// of per-RPC goroutine. Therefore, users should NOT have any blocking/time-consuming +// work in this handle. Otherwise all the RPCs would slow down. +type ServerInHandle func(ctx context.Context, info *Info) (context.Context, error) diff --git a/components/cli/vendor/google.golang.org/grpc/transport/control.go b/components/cli/vendor/google.golang.org/grpc/transport/control.go index 4ef0830b56..8d29aee53d 100644 --- a/components/cli/vendor/google.golang.org/grpc/transport/control.go +++ b/components/cli/vendor/google.golang.org/grpc/transport/control.go @@ -35,7 +35,9 @@ package transport import ( "fmt" + "math" "sync" + "time" "golang.org/x/net/http2" ) @@ -44,8 +46,18 @@ const ( // The default value of flow control window size in HTTP2 spec. defaultWindowSize = 65535 // The initial window size for flow control. - initialWindowSize = defaultWindowSize // for an RPC - initialConnWindowSize = defaultWindowSize * 16 // for a connection + initialWindowSize = defaultWindowSize // for an RPC + initialConnWindowSize = defaultWindowSize * 16 // for a connection + infinity = time.Duration(math.MaxInt64) + defaultClientKeepaliveTime = infinity + defaultClientKeepaliveTimeout = time.Duration(20 * time.Second) + defaultMaxStreamsClient = 100 + defaultMaxConnectionIdle = infinity + defaultMaxConnectionAge = infinity + defaultMaxConnectionAgeGrace = infinity + defaultServerKeepaliveTime = time.Duration(2 * time.Hour) + defaultServerKeepaliveTimeout = time.Duration(20 * time.Second) + defaultKeepalivePolicyMinTime = time.Duration(5 * time.Minute) ) // The following defines various control items which could flow through @@ -73,6 +85,8 @@ type resetStream struct { func (*resetStream) item() {} type goAway struct { + code http2.ErrCode + debugData []byte } func (*goAway) item() {} @@ -111,35 +125,9 @@ func newQuotaPool(q int) *quotaPool { return qb } -// add adds n to the available quota and tries to send it on acquire. -func (qb *quotaPool) add(n int) { - qb.mu.Lock() - defer qb.mu.Unlock() - qb.quota += n - if qb.quota <= 0 { - return - } - select { - case qb.c <- qb.quota: - qb.quota = 0 - default: - } -} - -// cancel cancels the pending quota sent on acquire, if any. -func (qb *quotaPool) cancel() { - qb.mu.Lock() - defer qb.mu.Unlock() - select { - case n := <-qb.c: - qb.quota += n - default: - } -} - -// reset cancels the pending quota sent on acquired, incremented by v and sends +// add cancels the pending quota sent on acquired, incremented by v and sends // it back on acquire. -func (qb *quotaPool) reset(v int) { +func (qb *quotaPool) add(v int) { qb.mu.Lock() defer qb.mu.Unlock() select { @@ -151,6 +139,10 @@ func (qb *quotaPool) reset(v int) { if qb.quota <= 0 { return } + // After the pool has been created, this is the only place that sends on + // the channel. Since mu is held at this point and any quota that was sent + // on the channel has been retrieved, we know that this code will always + // place any positive quota value on the channel. select { case qb.c <- qb.quota: qb.quota = 0 diff --git a/components/cli/vendor/google.golang.org/grpc/transport/handler_server.go b/components/cli/vendor/google.golang.org/grpc/transport/handler_server.go index 114e34906a..24f306babb 100644 --- a/components/cli/vendor/google.golang.org/grpc/transport/handler_server.go +++ b/components/cli/vendor/google.golang.org/grpc/transport/handler_server.go @@ -53,6 +53,7 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" + "google.golang.org/grpc/status" ) // NewServerHandlerTransport returns a ServerTransport handling gRPC @@ -110,6 +111,10 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request) (ServerTr v = v[:i] } } + v, err := decodeMetadataHeader(k, v) + if err != nil { + return nil, streamErrorf(codes.InvalidArgument, "malformed binary metadata: %v", err) + } metakv = append(metakv, k, v) } } @@ -182,7 +187,7 @@ func (ht *serverHandlerTransport) do(fn func()) error { } } -func (ht *serverHandlerTransport) WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error { +func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) error { err := ht.do(func() { ht.writeCommonHeaders(s) @@ -192,10 +197,13 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, statusCode codes.Code, ht.rw.(http.Flusher).Flush() h := ht.rw.Header() - h.Set("Grpc-Status", fmt.Sprintf("%d", statusCode)) - if statusDesc != "" { - h.Set("Grpc-Message", encodeGrpcMessage(statusDesc)) + h.Set("Grpc-Status", fmt.Sprintf("%d", st.Code())) + if m := st.Message(); m != "" { + h.Set("Grpc-Message", encodeGrpcMessage(m)) } + + // TODO: Support Grpc-Status-Details-Bin + if md := s.Trailer(); len(md) > 0 { for k, vv := range md { // Clients don't tolerate reading restricted headers after some non restricted ones were sent. @@ -203,10 +211,9 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, statusCode codes.Code, continue } for _, v := range vv { - // http2 ResponseWriter mechanism to - // send undeclared Trailers after the - // headers have possibly been written. - h.Add(http2.TrailerPrefix+k, v) + // http2 ResponseWriter mechanism to send undeclared Trailers after + // the headers have possibly been written. + h.Add(http2.TrailerPrefix+k, encodeMetadataHeader(k, v)) } } } @@ -234,6 +241,7 @@ func (ht *serverHandlerTransport) writeCommonHeaders(s *Stream) { // and https://golang.org/pkg/net/http/#example_ResponseWriter_trailers h.Add("Trailer", "Grpc-Status") h.Add("Trailer", "Grpc-Message") + // TODO: Support Grpc-Status-Details-Bin if s.sendCompress != "" { h.Set("Grpc-Encoding", s.sendCompress) @@ -260,6 +268,7 @@ func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error { continue } for _, v := range vv { + v = encodeMetadataHeader(k, v) h.Add(k, v) } } @@ -268,7 +277,7 @@ func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error { }) } -func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream)) { +func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), traceCtx func(context.Context, string) context.Context) { // With this transport type there will be exactly 1 stream: this HTTP request. var ctx context.Context @@ -314,7 +323,7 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream)) { if req.TLS != nil { pr.AuthInfo = credentials.TLSInfo{State: *req.TLS} } - ctx = metadata.NewContext(ctx, ht.headerMD) + ctx = metadata.NewIncomingContext(ctx, ht.headerMD) ctx = peer.NewContext(ctx, pr) s.ctx = newContextWithStream(ctx, s) s.dec = &recvBufferReader{ctx: s.ctx, recv: s.buf} diff --git a/components/cli/vendor/google.golang.org/grpc/transport/http2_client.go b/components/cli/vendor/google.golang.org/grpc/transport/http2_client.go index 2b0f68016a..380fff665f 100644 --- a/components/cli/vendor/google.golang.org/grpc/transport/http2_client.go +++ b/components/cli/vendor/google.golang.org/grpc/transport/http2_client.go @@ -35,12 +35,12 @@ package transport import ( "bytes" - "fmt" "io" "math" "net" "strings" "sync" + "sync/atomic" "time" "golang.org/x/net/context" @@ -49,18 +49,24 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/status" ) // http2Client implements the ClientTransport interface with HTTP2. type http2Client struct { - target string // server name/addr - userAgent string - md interface{} - conn net.Conn // underlying communication channel - authInfo credentials.AuthInfo // auth info about the connection - nextID uint32 // the next stream ID to be used + ctx context.Context + target string // server name/addr + userAgent string + md interface{} + conn net.Conn // underlying communication channel + remoteAddr net.Addr + localAddr net.Addr + authInfo credentials.AuthInfo // auth info about the connection + nextID uint32 // the next stream ID to be used // writableChan synchronizes write access to the transport. // A writer acquires the write lock by sending a value on writableChan @@ -76,6 +82,8 @@ type http2Client struct { // goAway is closed to notify the upper layer (i.e., addrConn.transportMonitor) // that the server sent GoAway on this transport. goAway chan struct{} + // awakenKeepalive is used to wake up keepalive when after it has gone dormant. + awakenKeepalive chan struct{} framer *framer hBuf *bytes.Buffer // the buffer for HPACK encoding @@ -95,6 +103,13 @@ type http2Client struct { creds []credentials.PerRPCCredentials + // Boolean to keep track of reading activity on transport. + // 1 is true and 0 is false. + activity uint32 // Accessed atomically. + kp keepalive.ClientParameters + + statsHandler stats.Handler + mu sync.Mutex // guard the following variables state transportState // the state of underlying connection activeStreams map[uint32]*Stream @@ -106,6 +121,9 @@ type http2Client struct { goAwayID uint32 // prevGoAway ID records the Last-Stream-ID in the previous GOAway frame. prevGoAwayID uint32 + // goAwayReason records the http2.ErrCode and debug data received with the + // GoAway frame. + goAwayReason GoAwayReason } func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr string) (net.Conn, error) { @@ -150,6 +168,9 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) ( scheme := "http" conn, err := dial(ctx, opts.Dialer, addr.Addr) if err != nil { + if opts.FailOnNonTempDialError { + return nil, connectionErrorf(isTemporary(err), err, "transport: %v", err) + } return nil, connectionErrorf(true, err, "transport: %v", err) } // Any further errors will close the underlying connection @@ -169,23 +190,31 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) ( return nil, connectionErrorf(temp, err, "transport: %v", err) } } - ua := primaryUA - if opts.UserAgent != "" { - ua = opts.UserAgent + " " + ua + kp := opts.KeepaliveParams + // Validate keepalive parameters. + if kp.Time == 0 { + kp.Time = defaultClientKeepaliveTime + } + if kp.Timeout == 0 { + kp.Timeout = defaultClientKeepaliveTimeout } var buf bytes.Buffer t := &http2Client{ - target: addr.Addr, - userAgent: ua, - md: addr.Metadata, - conn: conn, - authInfo: authInfo, + ctx: ctx, + target: addr.Addr, + userAgent: opts.UserAgent, + md: addr.Metadata, + conn: conn, + remoteAddr: conn.RemoteAddr(), + localAddr: conn.LocalAddr(), + authInfo: authInfo, // The client initiated stream id is odd starting from 1. nextID: 1, writableChan: make(chan int, 1), shutdownChan: make(chan struct{}), errorChan: make(chan struct{}), goAway: make(chan struct{}), + awakenKeepalive: make(chan struct{}, 1), framer: newFramer(conn), hBuf: &buf, hEnc: hpack.NewEncoder(&buf), @@ -196,8 +225,24 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) ( state: reachable, activeStreams: make(map[uint32]*Stream), creds: opts.PerRPCCredentials, - maxStreams: math.MaxInt32, + maxStreams: defaultMaxStreamsClient, + streamsQuota: newQuotaPool(defaultMaxStreamsClient), streamSendQuota: defaultWindowSize, + kp: kp, + statsHandler: opts.StatsHandler, + } + // Make sure awakenKeepalive can't be written upon. + // keepalive routine will make it writable, if need be. + t.awakenKeepalive <- struct{}{} + if t.statsHandler != nil { + t.ctx = t.statsHandler.TagConn(t.ctx, &stats.ConnTagInfo{ + RemoteAddr: t.remoteAddr, + LocalAddr: t.localAddr, + }) + connBegin := &stats.ConnBegin{ + Client: true, + } + t.statsHandler.HandleConn(t.ctx, connBegin) } // Start the reader goroutine for incoming message. Each transport has // a dedicated goroutine which reads HTTP2 frame from network. Then it @@ -233,6 +278,9 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) ( } } go t.controller() + if t.kp.Time != infinity { + go t.keepalive() + } t.writableChan <- 0 return t, nil } @@ -266,16 +314,17 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { return s } -// NewStream creates a stream and register it into the transport as "active" +// NewStream creates a stream and registers it into the transport as "active" // streams. func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) { pr := &peer.Peer{ - Addr: t.conn.RemoteAddr(), + Addr: t.remoteAddr, } // Attach Auth info if there is any. if t.authInfo != nil { pr.AuthInfo = t.authInfo } + userCtx := ctx ctx = peer.NewContext(ctx, pr) authData := make(map[string]string) for _, c := range t.creds { @@ -313,21 +362,18 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea t.mu.Unlock() return nil, ErrConnClosing } - checkStreamsQuota := t.streamsQuota != nil t.mu.Unlock() - if checkStreamsQuota { - sq, err := wait(ctx, nil, nil, t.shutdownChan, t.streamsQuota.acquire()) - if err != nil { - return nil, err - } - // Returns the quota balance back. - if sq > 1 { - t.streamsQuota.add(sq - 1) - } + sq, err := wait(ctx, nil, nil, t.shutdownChan, t.streamsQuota.acquire()) + if err != nil { + return nil, err + } + // Returns the quota balance back. + if sq > 1 { + t.streamsQuota.add(sq - 1) } if _, err := wait(ctx, nil, nil, t.shutdownChan, t.writableChan); err != nil { // Return the quota back now because there is no stream returned to the caller. - if _, ok := err.(StreamError); ok && checkStreamsQuota { + if _, ok := err.(StreamError); ok { t.streamsQuota.add(1) } return nil, err @@ -335,9 +381,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea t.mu.Lock() if t.state == draining { t.mu.Unlock() - if checkStreamsQuota { - t.streamsQuota.add(1) - } + t.streamsQuota.add(1) // Need to make t writable again so that the rpc in flight can still proceed. t.writableChan <- 0 return nil, ErrStreamDrain @@ -347,18 +391,19 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea return nil, ErrConnClosing } s := t.newStream(ctx, callHdr) + s.clientStatsCtx = userCtx t.activeStreams[s.id] = s + // If the number of active streams change from 0 to 1, then check if keepalive + // has gone dormant. If so, wake it up. + if len(t.activeStreams) == 1 { + select { + case t.awakenKeepalive <- struct{}{}: + t.framer.writePing(false, false, [8]byte{}) + default: + } + } - // This stream is not counted when applySetings(...) initialize t.streamsQuota. - // Reset t.streamsQuota to the right value. - var reset bool - if !checkStreamsQuota && t.streamsQuota != nil { - reset = true - } t.mu.Unlock() - if reset { - t.streamsQuota.reset(-1) - } // HPACK encodes various headers. Note that once WriteField(...) is // called, the corresponding headers/continuation frame has to be sent @@ -390,29 +435,30 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea hasMD bool endHeaders bool ) - if md, ok := metadata.FromContext(ctx); ok { + if md, ok := metadata.FromOutgoingContext(ctx); ok { hasMD = true - for k, v := range md { + for k, vv := range md { // HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set. if isReservedHeader(k) { continue } - for _, entry := range v { - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + for _, v := range vv { + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)}) } } } if md, ok := t.md.(*metadata.MD); ok { - for k, v := range *md { + for k, vv := range *md { if isReservedHeader(k) { continue } - for _, entry := range v { - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + for _, v := range vv { + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)}) } } } first := true + bufLen := t.hBuf.Len() // Sends the headers in a single batch even when they span multiple frames. for !endHeaders { size := t.hBuf.Len() @@ -447,6 +493,19 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea return nil, connectionErrorf(true, err, "transport: %v", err) } } + s.bytesSent = true + + if t.statsHandler != nil { + outHeader := &stats.OutHeader{ + Client: true, + WireLength: bufLen, + FullMethod: callHdr.Method, + RemoteAddr: t.remoteAddr, + LocalAddr: t.localAddr, + Compression: callHdr.SendCompress, + } + t.statsHandler.HandleRPC(s.clientStatsCtx, outHeader) + } t.writableChan <- 0 return s, nil } @@ -454,15 +513,11 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea // CloseStream clears the footprint of a stream when the stream is not needed any more. // This must not be executed in reader's goroutine. func (t *http2Client) CloseStream(s *Stream, err error) { - var updateStreams bool t.mu.Lock() if t.activeStreams == nil { t.mu.Unlock() return } - if t.streamsQuota != nil { - updateStreams = true - } delete(t.activeStreams, s.id) if t.state == draining && len(t.activeStreams) == 0 { // The transport is draining and s is the last live stream on t. @@ -471,10 +526,27 @@ func (t *http2Client) CloseStream(s *Stream, err error) { return } t.mu.Unlock() - if updateStreams { - t.streamsQuota.add(1) - } + // rstStream is true in case the stream is being closed at the client-side + // and the server needs to be intimated about it by sending a RST_STREAM + // frame. + // To make sure this frame is written to the wire before the headers of the + // next stream waiting for streamsQuota, we add to streamsQuota pool only + // after having acquired the writableChan to send RST_STREAM out (look at + // the controller() routine). + var rstStream bool + var rstError http2.ErrCode + defer func() { + // In case, the client doesn't have to send RST_STREAM to server + // we can safely add back to streamsQuota pool now. + if !rstStream { + t.streamsQuota.add(1) + return + } + t.controlBuf.put(&resetStream{s.id, rstError}) + }() s.mu.Lock() + rstStream = s.rstStream + rstError = s.rstError if q := s.fc.resetPendingData(); q > 0 { if n := t.fc.onRead(q); n > 0 { t.controlBuf.put(&windowUpdate{0, n}) @@ -490,8 +562,9 @@ func (t *http2Client) CloseStream(s *Stream, err error) { } s.state = streamDone s.mu.Unlock() - if se, ok := err.(StreamError); ok && se.Code != codes.DeadlineExceeded { - t.controlBuf.put(&resetStream{s.id, http2.ErrCodeCancel}) + if _, ok := err.(StreamError); ok { + rstStream = true + rstError = http2.ErrCodeCancel } } @@ -525,6 +598,12 @@ func (t *http2Client) Close() (err error) { s.mu.Unlock() s.write(recvMsg{err: ErrConnClosing}) } + if t.statsHandler != nil { + connEnd := &stats.ConnEnd{ + Client: true, + } + t.statsHandler.HandleConn(t.ctx, connEnd) + } return } @@ -582,19 +661,14 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error { var p []byte if r.Len() > 0 { size := http2MaxFrameLen - s.sendQuotaPool.add(0) // Wait until the stream has some quota to send the data. sq, err := wait(s.ctx, s.done, s.goAway, t.shutdownChan, s.sendQuotaPool.acquire()) if err != nil { return err } - t.sendQuotaPool.add(0) // Wait until the transport has some quota to send the data. tq, err := wait(s.ctx, s.done, s.goAway, t.shutdownChan, t.sendQuotaPool.acquire()) if err != nil { - if _, ok := err.(StreamError); ok || err == io.EOF { - t.sendQuotaPool.cancel() - } return err } if sq < size { @@ -704,7 +778,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) { } func (t *http2Client) handleData(f *http2.DataFrame) { - size := len(f.Data()) + size := f.Header().Length if err := t.fc.onData(uint32(size)); err != nil { t.notifyError(connectionErrorf(true, err, "%v", err)) return @@ -718,6 +792,11 @@ func (t *http2Client) handleData(f *http2.DataFrame) { return } if size > 0 { + if f.Header().Flags.Has(http2.FlagDataPadded) { + if w := t.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 { + t.controlBuf.put(&windowUpdate{0, w}) + } + } s.mu.Lock() if s.state == streamDone { s.mu.Unlock() @@ -728,22 +807,27 @@ func (t *http2Client) handleData(f *http2.DataFrame) { return } if err := s.fc.onData(uint32(size)); err != nil { - s.state = streamDone - s.statusCode = codes.Internal - s.statusDesc = err.Error() - close(s.done) + s.rstStream = true + s.rstError = http2.ErrCodeFlowControl + s.finish(status.New(codes.Internal, err.Error())) s.mu.Unlock() s.write(recvMsg{err: io.EOF}) - t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl}) return } + if f.Header().Flags.Has(http2.FlagDataPadded) { + if w := s.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 { + t.controlBuf.put(&windowUpdate{s.id, w}) + } + } s.mu.Unlock() // TODO(bradfitz, zhaoq): A copy is required here because there is no // guarantee f.Data() is consumed before the arrival of next frame. // Can this copy be eliminated? - data := make([]byte, size) - copy(data, f.Data()) - s.write(recvMsg{data: data}) + if len(f.Data()) > 0 { + data := make([]byte, len(f.Data())) + copy(data, f.Data()) + s.write(recvMsg{data: data}) + } } // The server has closed the stream without sending trailers. Record that // the read direction is closed, and set the status appropriately. @@ -753,10 +837,7 @@ func (t *http2Client) handleData(f *http2.DataFrame) { s.mu.Unlock() return } - s.state = streamDone - s.statusCode = codes.Internal - s.statusDesc = "server closed the stream without sending trailers" - close(s.done) + s.finish(status.New(codes.Internal, "server closed the stream without sending trailers")) s.mu.Unlock() s.write(recvMsg{err: io.EOF}) } @@ -772,18 +853,16 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) { s.mu.Unlock() return } - s.state = streamDone if !s.headerDone { close(s.headerChan) s.headerDone = true } - s.statusCode, ok = http2ErrConvTab[http2.ErrCode(f.ErrCode)] + statusCode, ok := http2ErrConvTab[http2.ErrCode(f.ErrCode)] if !ok { grpclog.Println("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error ", f.ErrCode) - s.statusCode = codes.Unknown + statusCode = codes.Unknown } - s.statusDesc = fmt.Sprintf("stream terminated by RST_STREAM with error code: %d", f.ErrCode) - close(s.done) + s.finish(status.Newf(statusCode, "stream terminated by RST_STREAM with error code: %d", f.ErrCode)) s.mu.Unlock() s.write(recvMsg{err: io.EOF}) } @@ -811,6 +890,9 @@ func (t *http2Client) handlePing(f *http2.PingFrame) { } func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { + if f.ErrCode == http2.ErrCodeEnhanceYourCalm { + grpclog.Printf("Client received GoAway with http2.ErrCodeEnhanceYourCalm.") + } t.mu.Lock() if t.state == reachable || t.state == draining { if f.LastStreamID > 0 && f.LastStreamID%2 != 1 { @@ -832,6 +914,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { t.mu.Unlock() return default: + t.setGoAwayReason(f) } t.goAwayID = f.LastStreamID close(t.goAway) @@ -839,6 +922,26 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { t.mu.Unlock() } +// setGoAwayReason sets the value of t.goAwayReason based +// on the GoAway frame received. +// It expects a lock on transport's mutext to be held by +// the caller. +func (t *http2Client) setGoAwayReason(f *http2.GoAwayFrame) { + t.goAwayReason = NoReason + switch f.ErrCode { + case http2.ErrCodeEnhanceYourCalm: + if string(f.DebugData()) == "too_many_pings" { + t.goAwayReason = TooManyPings + } + } +} + +func (t *http2Client) GetGoAwayReason() GoAwayReason { + t.mu.Lock() + defer t.mu.Unlock() + return t.goAwayReason +} + func (t *http2Client) handleWindowUpdate(f *http2.WindowUpdateFrame) { id := f.Header().StreamID incr := f.Increment @@ -857,23 +960,41 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { if !ok { return } + s.bytesReceived = true var state decodeState for _, hf := range frame.Fields { - state.processHeaderField(hf) - } - if state.err != nil { - s.mu.Lock() - if !s.headerDone { - close(s.headerChan) - s.headerDone = true + if err := state.processHeaderField(hf); err != nil { + s.mu.Lock() + if !s.headerDone { + close(s.headerChan) + s.headerDone = true + } + s.mu.Unlock() + s.write(recvMsg{err: err}) + // Something wrong. Stops reading even when there is remaining. + return } - s.mu.Unlock() - s.write(recvMsg{err: state.err}) - // Something wrong. Stops reading even when there is remaining. - return } endStream := frame.StreamEnded() + var isHeader bool + defer func() { + if t.statsHandler != nil { + if isHeader { + inHeader := &stats.InHeader{ + Client: true, + WireLength: int(frame.Header().Length), + } + t.statsHandler.HandleRPC(s.clientStatsCtx, inHeader) + } else { + inTrailer := &stats.InTrailer{ + Client: true, + WireLength: int(frame.Header().Length), + } + t.statsHandler.HandleRPC(s.clientStatsCtx, inTrailer) + } + } + }() s.mu.Lock() if !endStream { @@ -885,6 +1006,7 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { } close(s.headerChan) s.headerDone = true + isHeader = true } if !endStream || s.state == streamDone { s.mu.Unlock() @@ -894,10 +1016,7 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) { if len(state.mdata) > 0 { s.trailer = state.mdata } - s.statusCode = state.statusCode - s.statusDesc = state.statusDesc - close(s.done) - s.state = streamDone + s.finish(state.status()) s.mu.Unlock() s.write(recvMsg{err: io.EOF}) } @@ -925,6 +1044,7 @@ func (t *http2Client) reader() { t.notifyError(err) return } + atomic.CompareAndSwapUint32(&t.activity, 0, 1) sf, ok := frame.(*http2.SettingsFrame) if !ok { t.notifyError(err) @@ -935,6 +1055,7 @@ func (t *http2Client) reader() { // loop to keep reading incoming messages on this transport. for { frame, err := t.framer.readFrame() + atomic.CompareAndSwapUint32(&t.activity, 0, 1) if err != nil { // Abort an active stream if the http2.Framer returns a // http2.StreamError. This can happen only if the server's response @@ -986,21 +1107,15 @@ func (t *http2Client) applySettings(ss []http2.Setting) { s.Val = math.MaxInt32 } t.mu.Lock() - reset := t.streamsQuota != nil - if !reset { - t.streamsQuota = newQuotaPool(int(s.Val) - len(t.activeStreams)) - } ms := t.maxStreams t.maxStreams = int(s.Val) t.mu.Unlock() - if reset { - t.streamsQuota.reset(int(s.Val) - ms) - } + t.streamsQuota.add(int(s.Val) - ms) case http2.SettingInitialWindowSize: t.mu.Lock() for _, stream := range t.activeStreams { // Adjust the sending quota for each stream. - stream.sendQuotaPool.reset(int(s.Val - t.streamSendQuota)) + stream.sendQuotaPool.add(int(s.Val - t.streamSendQuota)) } t.streamSendQuota = s.Val t.mu.Unlock() @@ -1028,6 +1143,12 @@ func (t *http2Client) controller() { t.framer.writeSettings(true, i.ss...) } case *resetStream: + // If the server needs to be to intimated about stream closing, + // then we need to make sure the RST_STREAM frame is written to + // the wire before the headers of the next stream waiting on + // streamQuota. We ensure this by adding to the streamsQuota pool + // only after having acquired the writableChan to send RST_STREAM. + t.streamsQuota.add(1) t.framer.writeRSTStream(true, i.streamID, i.code) case *flushIO: t.framer.flushWrite() @@ -1047,6 +1168,61 @@ func (t *http2Client) controller() { } } +// keepalive running in a separate goroutune makes sure the connection is alive by sending pings. +func (t *http2Client) keepalive() { + p := &ping{data: [8]byte{}} + timer := time.NewTimer(t.kp.Time) + for { + select { + case <-timer.C: + if atomic.CompareAndSwapUint32(&t.activity, 1, 0) { + timer.Reset(t.kp.Time) + continue + } + // Check if keepalive should go dormant. + t.mu.Lock() + if len(t.activeStreams) < 1 && !t.kp.PermitWithoutStream { + // Make awakenKeepalive writable. + <-t.awakenKeepalive + t.mu.Unlock() + select { + case <-t.awakenKeepalive: + // If the control gets here a ping has been sent + // need to reset the timer with keepalive.Timeout. + case <-t.shutdownChan: + return + } + } else { + t.mu.Unlock() + // Send ping. + t.controlBuf.put(p) + } + + // By the time control gets here a ping has been sent one way or the other. + timer.Reset(t.kp.Timeout) + select { + case <-timer.C: + if atomic.CompareAndSwapUint32(&t.activity, 1, 0) { + timer.Reset(t.kp.Time) + continue + } + t.Close() + return + case <-t.shutdownChan: + if !timer.Stop() { + <-timer.C + } + return + } + case <-t.shutdownChan: + if !timer.Stop() { + <-timer.C + } + return + } + } +} + func (t *http2Client) Error() <-chan struct{} { return t.errorChan } diff --git a/components/cli/vendor/google.golang.org/grpc/transport/http2_server.go b/components/cli/vendor/google.golang.org/grpc/transport/http2_server.go index a62fb7c228..14cd19c64c 100644 --- a/components/cli/vendor/google.golang.org/grpc/transport/http2_server.go +++ b/components/cli/vendor/google.golang.org/grpc/transport/http2_server.go @@ -38,18 +38,26 @@ import ( "errors" "io" "math" + "math/rand" "net" "strconv" "sync" + "sync/atomic" + "time" + "github.com/golang/protobuf/proto" "golang.org/x/net/context" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/status" + "google.golang.org/grpc/tap" ) // ErrIllegalHeaderWrite indicates that setting header is illegal because of @@ -58,9 +66,13 @@ var ErrIllegalHeaderWrite = errors.New("transport: the stream is done or WriteHe // http2Server implements the ServerTransport interface with HTTP2. type http2Server struct { + ctx context.Context conn net.Conn + remoteAddr net.Addr + localAddr net.Addr maxStreamID uint32 // max stream ID ever seen authInfo credentials.AuthInfo // auth info about the connection + inTapHandle tap.ServerInHandle // writableChan synchronizes write access to the transport. // A writer acquires the write lock by receiving a value on writableChan // and releases it by sending on writableChan. @@ -82,21 +94,46 @@ type http2Server struct { // sendQuotaPool provides flow control to outbound message. sendQuotaPool *quotaPool + stats stats.Handler + + // Flag to keep track of reading activity on transport. + // 1 is true and 0 is false. + activity uint32 // Accessed atomically. + // Keepalive and max-age parameters for the server. + kp keepalive.ServerParameters + + // Keepalive enforcement policy. + kep keepalive.EnforcementPolicy + // The time instance last ping was received. + lastPingAt time.Time + // Number of times the client has violated keepalive ping policy so far. + pingStrikes uint8 + // Flag to signify that number of ping strikes should be reset to 0. + // This is set whenever data or header frames are sent. + // 1 means yes. + resetPingStrikes uint32 // Accessed atomically. + mu sync.Mutex // guard the following state transportState activeStreams map[uint32]*Stream // the per-stream outbound flow control window size set by the peer. streamSendQuota uint32 + // idle is the time instant when the connection went idle. + // This is either the begining of the connection or when the number of + // RPCs go down to 0. + // When the connection is busy, this value is set to 0. + idle time.Time } // newHTTP2Server constructs a ServerTransport based on HTTP2. ConnectionError is // returned if something goes wrong. -func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthInfo) (_ ServerTransport, err error) { +func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err error) { framer := newFramer(conn) // Send initial settings as connection preface to client. var settings []http2.Setting // TODO(zhaoq): Have a better way to signal "no limit" because 0 is // permitted in the HTTP2 spec. + maxStreams := config.MaxStreams if maxStreams == 0 { maxStreams = math.MaxUint32 } else { @@ -119,14 +156,40 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI return nil, connectionErrorf(true, err, "transport: %v", err) } } + kp := config.KeepaliveParams + if kp.MaxConnectionIdle == 0 { + kp.MaxConnectionIdle = defaultMaxConnectionIdle + } + if kp.MaxConnectionAge == 0 { + kp.MaxConnectionAge = defaultMaxConnectionAge + } + // Add a jitter to MaxConnectionAge. + kp.MaxConnectionAge += getJitter(kp.MaxConnectionAge) + if kp.MaxConnectionAgeGrace == 0 { + kp.MaxConnectionAgeGrace = defaultMaxConnectionAgeGrace + } + if kp.Time == 0 { + kp.Time = defaultServerKeepaliveTime + } + if kp.Timeout == 0 { + kp.Timeout = defaultServerKeepaliveTimeout + } + kep := config.KeepalivePolicy + if kep.MinTime == 0 { + kep.MinTime = defaultKeepalivePolicyMinTime + } var buf bytes.Buffer t := &http2Server{ + ctx: context.Background(), conn: conn, - authInfo: authInfo, + remoteAddr: conn.RemoteAddr(), + localAddr: conn.LocalAddr(), + authInfo: config.AuthInfo, framer: framer, hBuf: &buf, hEnc: hpack.NewEncoder(&buf), maxStreams: maxStreams, + inTapHandle: config.InTapHandle, controlBuf: newRecvBuffer(), fc: &inFlow{limit: initialConnWindowSize}, sendQuotaPool: newQuotaPool(defaultWindowSize), @@ -135,14 +198,27 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI shutdownChan: make(chan struct{}), activeStreams: make(map[uint32]*Stream), streamSendQuota: defaultWindowSize, + stats: config.StatsHandler, + kp: kp, + idle: time.Now(), + kep: kep, + } + if t.stats != nil { + t.ctx = t.stats.TagConn(t.ctx, &stats.ConnTagInfo{ + RemoteAddr: t.remoteAddr, + LocalAddr: t.localAddr, + }) + connBegin := &stats.ConnBegin{} + t.stats.HandleConn(t.ctx, connBegin) } go t.controller() + go t.keepalive() t.writableChan <- 0 return t, nil } // operateHeader takes action on the decoded headers. -func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream)) (close bool) { +func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (close bool) { buf := newRecvBuffer() s := &Stream{ id: frame.Header().StreamID, @@ -153,13 +229,12 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( var state decodeState for _, hf := range frame.Fields { - state.processHeaderField(hf) - } - if err := state.err; err != nil { - if se, ok := err.(StreamError); ok { - t.controlBuf.put(&resetStream{s.id, statusCodeConvTab[se.Code]}) + if err := state.processHeaderField(hf); err != nil { + if se, ok := err.(StreamError); ok { + t.controlBuf.put(&resetStream{s.id, statusCodeConvTab[se.Code]}) + } + return } - return } if frame.StreamEnded() { @@ -168,12 +243,12 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( } s.recvCompress = state.encoding if state.timeoutSet { - s.ctx, s.cancel = context.WithTimeout(context.TODO(), state.timeout) + s.ctx, s.cancel = context.WithTimeout(t.ctx, state.timeout) } else { - s.ctx, s.cancel = context.WithCancel(context.TODO()) + s.ctx, s.cancel = context.WithCancel(t.ctx) } pr := &peer.Peer{ - Addr: t.conn.RemoteAddr(), + Addr: t.remoteAddr, } // Attach Auth info if there is any. if t.authInfo != nil { @@ -186,7 +261,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( s.ctx = newContextWithStream(s.ctx, s) // Attach the received metadata to the context. if len(state.mdata) > 0 { - s.ctx = metadata.NewContext(s.ctx, state.mdata) + s.ctx = metadata.NewIncomingContext(s.ctx, state.mdata) } s.dec = &recvBufferReader{ @@ -195,6 +270,18 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( } s.recvCompress = state.encoding s.method = state.method + if t.inTapHandle != nil { + var err error + info := &tap.Info{ + FullMethodName: state.method, + } + s.ctx, err = t.inTapHandle(s.ctx, info) + if err != nil { + // TODO: Log the real error. + t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream}) + return + } + } t.mu.Lock() if t.state != reachable { t.mu.Unlock() @@ -214,17 +301,33 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func( t.maxStreamID = s.id s.sendQuotaPool = newQuotaPool(int(t.streamSendQuota)) t.activeStreams[s.id] = s + if len(t.activeStreams) == 1 { + t.idle = time.Time{} + } t.mu.Unlock() s.windowHandler = func(n int) { t.updateWindow(s, uint32(n)) } + s.ctx = traceCtx(s.ctx, s.method) + if t.stats != nil { + s.ctx = t.stats.TagRPC(s.ctx, &stats.RPCTagInfo{FullMethodName: s.method}) + inHeader := &stats.InHeader{ + FullMethod: s.method, + RemoteAddr: t.remoteAddr, + LocalAddr: t.localAddr, + Compression: s.recvCompress, + WireLength: int(frame.Header().Length), + } + t.stats.HandleRPC(s.ctx, inHeader) + } handle(s) return } // HandleStreams receives incoming streams using the given handler. This is // typically run in a separate goroutine. -func (t *http2Server) HandleStreams(handle func(*Stream)) { +// traceCtx attaches trace to ctx and returns the new context. +func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.Context, string) context.Context) { // Check the validity of client preface. preface := make([]byte, len(clientPreface)) if _, err := io.ReadFull(t.conn, preface); err != nil { @@ -248,6 +351,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) { t.Close() return } + atomic.StoreUint32(&t.activity, 1) sf, ok := frame.(*http2.SettingsFrame) if !ok { grpclog.Printf("transport: http2Server.HandleStreams saw invalid preface type %T from client", frame) @@ -258,6 +362,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) { for { frame, err := t.framer.readFrame() + atomic.StoreUint32(&t.activity, 1) if err != nil { if se, ok := err.(http2.StreamError); ok { t.mu.Lock() @@ -279,7 +384,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) { } switch frame := frame.(type) { case *http2.MetaHeadersFrame: - if t.operateHeaders(frame, handle) { + if t.operateHeaders(frame, handle, traceCtx) { t.Close() break } @@ -334,7 +439,7 @@ func (t *http2Server) updateWindow(s *Stream, n uint32) { } func (t *http2Server) handleData(f *http2.DataFrame) { - size := len(f.Data()) + size := f.Header().Length if err := t.fc.onData(uint32(size)); err != nil { grpclog.Printf("transport: http2Server %v", err) t.Close() @@ -349,6 +454,11 @@ func (t *http2Server) handleData(f *http2.DataFrame) { return } if size > 0 { + if f.Header().Flags.Has(http2.FlagDataPadded) { + if w := t.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 { + t.controlBuf.put(&windowUpdate{0, w}) + } + } s.mu.Lock() if s.state == streamDone { s.mu.Unlock() @@ -364,13 +474,20 @@ func (t *http2Server) handleData(f *http2.DataFrame) { t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl}) return } + if f.Header().Flags.Has(http2.FlagDataPadded) { + if w := s.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 { + t.controlBuf.put(&windowUpdate{s.id, w}) + } + } s.mu.Unlock() // TODO(bradfitz, zhaoq): A copy is required here because there is no // guarantee f.Data() is consumed before the arrival of next frame. // Can this copy be eliminated? - data := make([]byte, size) - copy(data, f.Data()) - s.write(recvMsg{data: data}) + if len(f.Data()) > 0 { + data := make([]byte, len(f.Data())) + copy(data, f.Data()) + s.write(recvMsg{data: data}) + } } if f.Header().Flags.Has(http2.FlagDataEndStream) { // Received the end of stream from the client. @@ -404,6 +521,11 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) { t.controlBuf.put(&settings{ack: true, ss: ss}) } +const ( + maxPingStrikes = 2 + defaultPingTimeout = 2 * time.Hour +) + func (t *http2Server) handlePing(f *http2.PingFrame) { if f.IsAck() { // Do nothing. return @@ -411,6 +533,38 @@ func (t *http2Server) handlePing(f *http2.PingFrame) { pingAck := &ping{ack: true} copy(pingAck.data[:], f.Data[:]) t.controlBuf.put(pingAck) + + now := time.Now() + defer func() { + t.lastPingAt = now + }() + // A reset ping strikes means that we don't need to check for policy + // violation for this ping and the pingStrikes counter should be set + // to 0. + if atomic.CompareAndSwapUint32(&t.resetPingStrikes, 1, 0) { + t.pingStrikes = 0 + return + } + t.mu.Lock() + ns := len(t.activeStreams) + t.mu.Unlock() + if ns < 1 && !t.kep.PermitWithoutStream { + // Keepalive shouldn't be active thus, this new ping should + // have come after atleast defaultPingTimeout. + if t.lastPingAt.Add(defaultPingTimeout).After(now) { + t.pingStrikes++ + } + } else { + // Check if keepalive policy is respected. + if t.lastPingAt.Add(t.kep.MinTime).After(now) { + t.pingStrikes++ + } + } + + if t.pingStrikes > maxPingStrikes { + // Send goaway and close the connection. + t.controlBuf.put(&goAway{code: http2.ErrCodeEnhanceYourCalm, debugData: []byte("too_many_pings")}) + } } func (t *http2Server) handleWindowUpdate(f *http2.WindowUpdateFrame) { @@ -429,6 +583,13 @@ func (t *http2Server) writeHeaders(s *Stream, b *bytes.Buffer, endStream bool) e first := true endHeaders := false var err error + defer func() { + if err == nil { + // Reset ping strikes when seding headers since that might cause the + // peer to send ping. + atomic.StoreUint32(&t.resetPingStrikes, 1) + } + }() // Sends the headers in a single batch. for !endHeaders { size := t.hBuf.Len() @@ -483,18 +644,25 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { if s.sendCompress != "" { t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) } - for k, v := range md { + for k, vv := range md { if isReservedHeader(k) { // Clients don't tolerate reading restricted headers after some non restricted ones were sent. continue } - for _, entry := range v { - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + for _, v := range vv { + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)}) } } + bufLen := t.hBuf.Len() if err := t.writeHeaders(s, t.hBuf, false); err != nil { return err } + if t.stats != nil { + outHeader := &stats.OutHeader{ + WireLength: bufLen, + } + t.stats.HandleRPC(s.Context(), outHeader) + } t.writableChan <- 0 return nil } @@ -503,7 +671,7 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error { // There is no further I/O operations being able to perform on this stream. // TODO(zhaoq): Now it indicates the end of entire stream. Revisit if early // OK is adopted. -func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error { +func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { var headersSent, hasHeader bool s.mu.Lock() if s.state == streamDone { @@ -534,23 +702,41 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s t.hEnc.WriteField( hpack.HeaderField{ Name: "grpc-status", - Value: strconv.Itoa(int(statusCode)), + Value: strconv.Itoa(int(st.Code())), }) - t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(statusDesc)}) + t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(st.Message())}) + + if p := st.Proto(); p != nil && len(p.Details) > 0 { + stBytes, err := proto.Marshal(p) + if err != nil { + // TODO: return error instead, when callers are able to handle it. + panic(err) + } + + t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)}) + } + // Attach the trailer metadata. - for k, v := range s.trailer { + for k, vv := range s.trailer { // Clients don't tolerate reading restricted headers after some non restricted ones were sent. if isReservedHeader(k) { continue } - for _, entry := range v { - t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: entry}) + for _, v := range vv { + t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)}) } } + bufLen := t.hBuf.Len() if err := t.writeHeaders(s, t.hBuf, true); err != nil { t.Close() return err } + if t.stats != nil { + outTrailer := &stats.OutTrailer{ + WireLength: bufLen, + } + t.stats.HandleRPC(s.Context(), outTrailer) + } t.closeStream(s) t.writableChan <- 0 return nil @@ -558,7 +744,7 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s // Write converts the data into HTTP2 data frame and sends it out. Non-nil error // is returns if it fails (e.g., framing error, transport error). -func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { +func (t *http2Server) Write(s *Stream, data []byte, opts *Options) (err error) { // TODO(zhaoq): Support multi-writers for a single stream. var writeHeaderFrame bool s.mu.Lock() @@ -573,25 +759,27 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error { if writeHeaderFrame { t.WriteHeader(s, nil) } + defer func() { + if err == nil { + // Reset ping strikes when sending data since this might cause + // the peer to send ping. + atomic.StoreUint32(&t.resetPingStrikes, 1) + } + }() r := bytes.NewBuffer(data) for { if r.Len() == 0 { return nil } size := http2MaxFrameLen - s.sendQuotaPool.add(0) // Wait until the stream has some quota to send the data. sq, err := wait(s.ctx, nil, nil, t.shutdownChan, s.sendQuotaPool.acquire()) if err != nil { return err } - t.sendQuotaPool.add(0) // Wait until the transport has some quota to send the data. tq, err := wait(s.ctx, nil, nil, t.shutdownChan, t.sendQuotaPool.acquire()) if err != nil { - if _, ok := err.(StreamError); ok { - t.sendQuotaPool.cancel() - } return err } if sq < size { @@ -659,7 +847,7 @@ func (t *http2Server) applySettings(ss []http2.Setting) { t.mu.Lock() defer t.mu.Unlock() for _, stream := range t.activeStreams { - stream.sendQuotaPool.reset(int(s.Val - t.streamSendQuota)) + stream.sendQuotaPool.add(int(s.Val - t.streamSendQuota)) } t.streamSendQuota = s.Val } @@ -667,6 +855,91 @@ func (t *http2Server) applySettings(ss []http2.Setting) { } } +// keepalive running in a separate goroutine does the following: +// 1. Gracefully closes an idle connection after a duration of keepalive.MaxConnectionIdle. +// 2. Gracefully closes any connection after a duration of keepalive.MaxConnectionAge. +// 3. Forcibly closes a connection after an additive period of keepalive.MaxConnectionAgeGrace over keepalive.MaxConnectionAge. +// 4. Makes sure a connection is alive by sending pings with a frequency of keepalive.Time and closes a non-resposive connection +// after an additional duration of keepalive.Timeout. +func (t *http2Server) keepalive() { + p := &ping{} + var pingSent bool + maxIdle := time.NewTimer(t.kp.MaxConnectionIdle) + maxAge := time.NewTimer(t.kp.MaxConnectionAge) + keepalive := time.NewTimer(t.kp.Time) + // NOTE: All exit paths of this function should reset their + // respecitve timers. A failure to do so will cause the + // following clean-up to deadlock and eventually leak. + defer func() { + if !maxIdle.Stop() { + <-maxIdle.C + } + if !maxAge.Stop() { + <-maxAge.C + } + if !keepalive.Stop() { + <-keepalive.C + } + }() + for { + select { + case <-maxIdle.C: + t.mu.Lock() + idle := t.idle + if idle.IsZero() { // The connection is non-idle. + t.mu.Unlock() + maxIdle.Reset(t.kp.MaxConnectionIdle) + continue + } + val := t.kp.MaxConnectionIdle - time.Since(idle) + if val <= 0 { + // The connection has been idle for a duration of keepalive.MaxConnectionIdle or more. + // Gracefully close the connection. + t.state = draining + t.mu.Unlock() + t.Drain() + // Reseting the timer so that the clean-up doesn't deadlock. + maxIdle.Reset(infinity) + return + } + t.mu.Unlock() + maxIdle.Reset(val) + case <-maxAge.C: + t.mu.Lock() + t.state = draining + t.mu.Unlock() + t.Drain() + maxAge.Reset(t.kp.MaxConnectionAgeGrace) + select { + case <-maxAge.C: + // Close the connection after grace period. + t.Close() + // Reseting the timer so that the clean-up doesn't deadlock. + maxAge.Reset(infinity) + case <-t.shutdownChan: + } + return + case <-keepalive.C: + if atomic.CompareAndSwapUint32(&t.activity, 1, 0) { + pingSent = false + keepalive.Reset(t.kp.Time) + continue + } + if pingSent { + t.Close() + // Reseting the timer so that the clean-up doesn't deadlock. + keepalive.Reset(infinity) + return + } + pingSent = true + t.controlBuf.put(p) + keepalive.Reset(t.kp.Timeout) + case <-t.shutdownChan: + return + } + } +} + // controller running in a separate goroutine takes charge of sending control // frames (e.g., window update, reset stream, setting, etc.) to the server. func (t *http2Server) controller() { @@ -698,7 +971,10 @@ func (t *http2Server) controller() { sid := t.maxStreamID t.state = draining t.mu.Unlock() - t.framer.writeGoAway(true, sid, http2.ErrCodeNo, nil) + t.framer.writeGoAway(true, sid, i.code, i.debugData) + if i.code == http2.ErrCodeEnhanceYourCalm { + t.Close() + } case *flushIO: t.framer.flushWrite() case *ping: @@ -736,6 +1012,10 @@ func (t *http2Server) Close() (err error) { for _, s := range streams { s.cancel() } + if t.stats != nil { + connEnd := &stats.ConnEnd{} + t.stats.HandleConn(t.ctx, connEnd) + } return } @@ -744,6 +1024,9 @@ func (t *http2Server) Close() (err error) { func (t *http2Server) closeStream(s *Stream) { t.mu.Lock() delete(t.activeStreams, s.id) + if len(t.activeStreams) == 0 { + t.idle = time.Now() + } if t.state == draining && len(t.activeStreams) == 0 { defer t.Close() } @@ -767,9 +1050,21 @@ func (t *http2Server) closeStream(s *Stream) { } func (t *http2Server) RemoteAddr() net.Addr { - return t.conn.RemoteAddr() + return t.remoteAddr } func (t *http2Server) Drain() { - t.controlBuf.put(&goAway{}) + t.controlBuf.put(&goAway{code: http2.ErrCodeNo}) +} + +var rgen = rand.New(rand.NewSource(time.Now().UnixNano())) + +func getJitter(v time.Duration) time.Duration { + if v == infinity { + return 0 + } + // Generate a jitter between +/- 10% of the value. + r := int64(v / 10) + j := rgen.Int63n(2*r) - r + return time.Duration(j) } diff --git a/components/cli/vendor/google.golang.org/grpc/transport/http_util.go b/components/cli/vendor/google.golang.org/grpc/transport/http_util.go index a3c68d4cac..795d5d18a4 100644 --- a/components/cli/vendor/google.golang.org/grpc/transport/http_util.go +++ b/components/cli/vendor/google.golang.org/grpc/transport/http_util.go @@ -36,6 +36,7 @@ package transport import ( "bufio" "bytes" + "encoding/base64" "fmt" "io" "net" @@ -44,16 +45,16 @@ import ( "sync/atomic" "time" + "github.com/golang/protobuf/proto" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" + spb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" ) const ( - // The primary user agent - primaryUA = "grpc-go/1.0" // http2MaxFrameLen specifies the max length of a HTTP2 frame. http2MaxFrameLen = 16384 // 16KB frame // http://http2.github.io/http2-spec/#SettingValues @@ -92,13 +93,15 @@ var ( // Records the states during HPACK decoding. Must be reset once the // decoding of the entire headers are finished. type decodeState struct { - err error // first error encountered decoding - encoding string - // statusCode caches the stream status received from the trailer - // the server sent. Client side only. - statusCode codes.Code - statusDesc string + // statusGen caches the stream status received from the trailer the server + // sent. Client side only. Do not access directly. After all trailers are + // parsed, use the status method to retrieve the status. + statusGen *status.Status + // rawStatusCode and rawStatusMsg are set from the raw trailer fields and are not + // intended for direct access outside of parsing. + rawStatusCode int32 + rawStatusMsg string // Server side only fields. timeoutSet bool timeout time.Duration @@ -121,6 +124,7 @@ func isReservedHeader(hdr string) bool { "grpc-message", "grpc-status", "grpc-timeout", + "grpc-status-details-bin", "te": return true default: @@ -139,12 +143,6 @@ func isWhitelistedPseudoHeader(hdr string) bool { } } -func (d *decodeState) setErr(err error) { - if d.err == nil { - d.err = err - } -} - func validContentType(t string) bool { e := "application/grpc" if !strings.HasPrefix(t, e) { @@ -158,56 +156,91 @@ func validContentType(t string) bool { return true } -func (d *decodeState) processHeaderField(f hpack.HeaderField) { +func (d *decodeState) status() *status.Status { + if d.statusGen == nil { + // No status-details were provided; generate status using code/msg. + d.statusGen = status.New(codes.Code(d.rawStatusCode), d.rawStatusMsg) + } + return d.statusGen +} + +const binHdrSuffix = "-bin" + +func encodeBinHeader(v []byte) string { + return base64.RawStdEncoding.EncodeToString(v) +} + +func decodeBinHeader(v string) ([]byte, error) { + if len(v)%4 == 0 { + // Input was padded, or padding was not necessary. + return base64.StdEncoding.DecodeString(v) + } + return base64.RawStdEncoding.DecodeString(v) +} + +func encodeMetadataHeader(k, v string) string { + if strings.HasSuffix(k, binHdrSuffix) { + return encodeBinHeader(([]byte)(v)) + } + return v +} + +func decodeMetadataHeader(k, v string) (string, error) { + if strings.HasSuffix(k, binHdrSuffix) { + b, err := decodeBinHeader(v) + return string(b), err + } + return v, nil +} + +func (d *decodeState) processHeaderField(f hpack.HeaderField) error { switch f.Name { case "content-type": if !validContentType(f.Value) { - d.setErr(streamErrorf(codes.FailedPrecondition, "transport: received the unexpected content-type %q", f.Value)) - return + return streamErrorf(codes.FailedPrecondition, "transport: received the unexpected content-type %q", f.Value) } case "grpc-encoding": d.encoding = f.Value case "grpc-status": code, err := strconv.Atoi(f.Value) if err != nil { - d.setErr(streamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err)) - return + return streamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err) } - d.statusCode = codes.Code(code) + d.rawStatusCode = int32(code) case "grpc-message": - d.statusDesc = decodeGrpcMessage(f.Value) + d.rawStatusMsg = decodeGrpcMessage(f.Value) + case "grpc-status-details-bin": + v, err := decodeBinHeader(f.Value) + if err != nil { + return streamErrorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + } + s := &spb.Status{} + if err := proto.Unmarshal(v, s); err != nil { + return streamErrorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err) + } + d.statusGen = status.FromProto(s) case "grpc-timeout": d.timeoutSet = true var err error - d.timeout, err = decodeTimeout(f.Value) - if err != nil { - d.setErr(streamErrorf(codes.Internal, "transport: malformed time-out: %v", err)) - return + if d.timeout, err = decodeTimeout(f.Value); err != nil { + return streamErrorf(codes.Internal, "transport: malformed time-out: %v", err) } case ":path": d.method = f.Value default: if !isReservedHeader(f.Name) || isWhitelistedPseudoHeader(f.Name) { - if f.Name == "user-agent" { - i := strings.LastIndex(f.Value, " ") - if i == -1 { - // There is no application user agent string being set. - return - } - // Extract the application user agent string. - f.Value = f.Value[:i] - } if d.mdata == nil { d.mdata = make(map[string][]string) } - k, v, err := metadata.DecodeKeyValue(f.Name, f.Value) + v, err := decodeMetadataHeader(f.Name, f.Value) if err != nil { grpclog.Printf("Failed to decode (%q, %q): %v", f.Name, f.Value, err) - return + return nil } - d.mdata[k] = append(d.mdata[k], v) + d.mdata[f.Name] = append(d.mdata[f.Name], v) } } + return nil } type timeoutUnit uint8 @@ -379,6 +412,9 @@ func newFramer(conn net.Conn) *framer { writer: bufio.NewWriterSize(conn, http2IOBufSize), } f.fr = http2.NewFramer(f.writer, f.reader) + // Opt-in to Frame reuse API on framer to reduce garbage. + // Frames aren't safe to read from after a subsequent call to ReadFrame. + f.fr.SetReuseFrames() f.fr.ReadMetaHeaders = hpack.NewDecoder(http2InitHeaderTableSize, nil) return f } diff --git a/components/cli/vendor/google.golang.org/grpc/transport/transport.go b/components/cli/vendor/google.golang.org/grpc/transport/transport.go index 413f7493b4..88c2c98721 100644 --- a/components/cli/vendor/google.golang.org/grpc/transport/transport.go +++ b/components/cli/vendor/google.golang.org/grpc/transport/transport.go @@ -45,10 +45,14 @@ import ( "sync" "golang.org/x/net/context" - "golang.org/x/net/trace" + "golang.org/x/net/http2" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/stats" + "google.golang.org/grpc/status" + "google.golang.org/grpc/tap" ) // recvMsg represents the received msg from the transport. All transport @@ -167,6 +171,11 @@ type Stream struct { id uint32 // nil for client side Stream. st ServerTransport + // clientStatsCtx keeps the user context for stats handling. + // It's only valid on client side. Server side stats context is same as s.ctx. + // All client side stats collection should use the clientStatsCtx (instead of the stream context) + // so that all the generated stats for a particular RPC can be associated in the processing phase. + clientStatsCtx context.Context // ctx is the associated context of the stream. ctx context.Context // cancel is always nil for client side Stream. @@ -204,9 +213,17 @@ type Stream struct { // true iff headerChan is closed. Used to avoid closing headerChan // multiple times. headerDone bool - // the status received from the server. - statusCode codes.Code - statusDesc string + // the status error received from the server. + status *status.Status + // rstStream indicates whether a RST_STREAM frame needs to be sent + // to the server to signify that this stream is closing. + rstStream bool + // rstError is the error that needs to be sent along with the RST_STREAM frame. + rstError http2.ErrCode + // bytesSent and bytesReceived indicates whether any bytes have been sent or + // received on this stream. + bytesSent bool + bytesReceived bool } // RecvCompress returns the compression algorithm applied to the inbound @@ -266,24 +283,14 @@ func (s *Stream) Context() context.Context { return s.ctx } -// TraceContext recreates the context of s with a trace.Trace. -func (s *Stream) TraceContext(tr trace.Trace) { - s.ctx = trace.NewContext(s.ctx, tr) -} - // Method returns the method for the stream. func (s *Stream) Method() string { return s.method } -// StatusCode returns statusCode received from the server. -func (s *Stream) StatusCode() codes.Code { - return s.statusCode -} - -// StatusDesc returns statusDesc received from the server. -func (s *Stream) StatusDesc() string { - return s.statusDesc +// Status returns the status received from the server. +func (s *Stream) Status() *status.Status { + return s.status } // SetHeader sets the header metadata. This can be called multiple times. @@ -330,6 +337,34 @@ func (s *Stream) Read(p []byte) (n int, err error) { return } +// finish sets the stream's state and status, and closes the done channel. +// s.mu must be held by the caller. st must always be non-nil. +func (s *Stream) finish(st *status.Status) { + s.status = st + s.state = streamDone + close(s.done) +} + +// BytesSent indicates whether any bytes have been sent on this stream. +func (s *Stream) BytesSent() bool { + s.mu.Lock() + defer s.mu.Unlock() + return s.bytesSent +} + +// BytesReceived indicates whether any bytes have been received on this stream. +func (s *Stream) BytesReceived() bool { + s.mu.Lock() + defer s.mu.Unlock() + return s.bytesReceived +} + +// GoString is implemented by Stream so context.String() won't +// race when printing %#v. +func (s *Stream) GoString() string { + return fmt.Sprintf("", s, s.method) +} + // The key to save transport.Stream in the context. type streamKey struct{} @@ -355,22 +390,41 @@ const ( draining ) +// ServerConfig consists of all the configurations to establish a server transport. +type ServerConfig struct { + MaxStreams uint32 + AuthInfo credentials.AuthInfo + InTapHandle tap.ServerInHandle + StatsHandler stats.Handler + KeepaliveParams keepalive.ServerParameters + KeepalivePolicy keepalive.EnforcementPolicy +} + // NewServerTransport creates a ServerTransport with conn or non-nil error // if it fails. -func NewServerTransport(protocol string, conn net.Conn, maxStreams uint32, authInfo credentials.AuthInfo) (ServerTransport, error) { - return newHTTP2Server(conn, maxStreams, authInfo) +func NewServerTransport(protocol string, conn net.Conn, config *ServerConfig) (ServerTransport, error) { + return newHTTP2Server(conn, config) } // ConnectOptions covers all relevant options for communicating with the server. type ConnectOptions struct { // UserAgent is the application user agent. UserAgent string + // Authority is the :authority pseudo-header to use. This field has no effect if + // TransportCredentials is set. + Authority string // Dialer specifies how to dial a network address. Dialer func(context.Context, string) (net.Conn, error) + // FailOnNonTempDialError specifies if gRPC fails on non-temporary dial errors. + FailOnNonTempDialError bool // PerRPCCredentials stores the PerRPCCredentials required to issue RPCs. PerRPCCredentials []credentials.PerRPCCredentials // TransportCredentials stores the Authenticator required to setup a client connection. TransportCredentials credentials.TransportCredentials + // KeepaliveParams stores the keepalive parameters. + KeepaliveParams keepalive.ClientParameters + // StatsHandler stores the handler for stats. + StatsHandler stats.Handler } // TargetInfo contains the information of the target such as network address and metadata. @@ -457,6 +511,9 @@ type ClientTransport interface { // receives the draining signal from the server (e.g., GOAWAY frame in // HTTP/2). GoAway() <-chan struct{} + + // GetGoAwayReason returns the reason why GoAway frame was received. + GetGoAwayReason() GoAwayReason } // ServerTransport is the common interface for all gRPC server-side transport @@ -466,7 +523,7 @@ type ClientTransport interface { // Write methods for a given Stream will be called serially. type ServerTransport interface { // HandleStreams receives incoming streams using the given handler. - HandleStreams(func(*Stream)) + HandleStreams(func(*Stream), func(context.Context, string) context.Context) // WriteHeader sends the header metadata for the given stream. // WriteHeader may not be called on all streams. @@ -476,10 +533,9 @@ type ServerTransport interface { // Write may not be called on all streams. Write(s *Stream, data []byte, opts *Options) error - // WriteStatus sends the status of a stream to the client. - // WriteStatus is the final call made on a stream and always - // occurs. - WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error + // WriteStatus sends the status of a stream to the client. WriteStatus is + // the final call made on a stream and always occurs. + WriteStatus(s *Stream, st *status.Status) error // Close tears down the transport. Once it is called, the transport // should not be accessed any more. All the pending streams and their @@ -545,6 +601,8 @@ var ( ErrStreamDrain = streamErrorf(codes.Unavailable, "the server stops accepting new RPCs") ) +// TODO: See if we can replace StreamError with status package errors. + // StreamError is an error that only affects one stream within a connection. type StreamError struct { Code codes.Code @@ -552,7 +610,7 @@ type StreamError struct { } func (e StreamError) Error() string { - return fmt.Sprintf("stream error: code = %d desc = %q", e.Code, e.Desc) + return fmt.Sprintf("stream error: code = %s desc = %q", e.Code, e.Desc) } // ContextErr converts the error from context package into a StreamError. @@ -593,3 +651,16 @@ func wait(ctx context.Context, done, goAway, closing <-chan struct{}, proceed <- return i, nil } } + +// GoAwayReason contains the reason for the GoAway frame received. +type GoAwayReason uint8 + +const ( + // Invalid indicates that no GoAway frame is received. + Invalid GoAwayReason = 0 + // NoReason is the default value when GoAway frame is received. + NoReason GoAwayReason = 1 + // TooManyPings indicates that a GoAway frame with ErrCodeEnhanceYourCalm + // was recieved and that the debug data said "too_many_pings". + TooManyPings GoAwayReason = 2 +) From 66062dd9b788a5b820b8757ab8bfdf7f7832a8b9 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sun, 2 Jul 2017 21:09:13 -0700 Subject: [PATCH 08/62] bump golang.org/x/net to 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 Signed-off-by: Sebastiaan van Stijn Upstream-commit: 679ae70241a961d650a7def4515db41c03b7c3b8 Component: cli --- components/cli/vendor.conf | 2 +- .../golang.org/x/net/context/context.go | 30 +- .../vendor/golang.org/x/net/context/go17.go | 4 +- .../golang.org/x/net/context/pre_go17.go | 18 +- .../vendor/golang.org/x/net/http2/ciphers.go | 641 ++++++++++++++++++ .../x/net/http2/client_conn_pool.go | 2 +- .../golang.org/x/net/http2/databuffer.go | 146 ++++ .../golang.org/x/net/http2/fixed_buffer.go | 60 -- .../vendor/golang.org/x/net/http2/frame.go | 81 ++- .../cli/vendor/golang.org/x/net/http2/go16.go | 27 - .../cli/vendor/golang.org/x/net/http2/go18.go | 6 +- .../cli/vendor/golang.org/x/net/http2/go19.go | 16 + .../golang.org/x/net/http2/hpack/encode.go | 29 +- .../golang.org/x/net/http2/hpack/hpack.go | 104 +-- .../golang.org/x/net/http2/hpack/tables.go | 255 +++++-- .../vendor/golang.org/x/net/http2/not_go16.go | 25 - .../vendor/golang.org/x/net/http2/not_go19.go | 16 + .../cli/vendor/golang.org/x/net/http2/pipe.go | 16 +- .../vendor/golang.org/x/net/http2/server.go | 421 +++++++----- .../golang.org/x/net/http2/transport.go | 16 +- .../x/net/http2/writesched_priority.go | 2 +- .../cli/vendor/golang.org/x/net/idna/idna.go | 390 +++++++---- .../vendor/golang.org/x/net/idna/punycode.go | 2 +- .../vendor/golang.org/x/net/idna/tables.go | 4 +- .../cli/vendor/golang.org/x/net/idna/trie.go | 5 +- .../vendor/golang.org/x/net/idna/trieval.go | 4 +- .../x/net/internal/timeseries/timeseries.go | 2 +- .../vendor/golang.org/x/net/proxy/socks5.go | 59 +- .../vendor/golang.org/x/net/trace/trace.go | 13 - .../golang.org/x/net/trace/trace_go16.go | 21 + .../golang.org/x/net/trace/trace_go17.go | 21 + 31 files changed, 1765 insertions(+), 673 deletions(-) create mode 100644 components/cli/vendor/golang.org/x/net/http2/ciphers.go create mode 100644 components/cli/vendor/golang.org/x/net/http2/databuffer.go delete mode 100644 components/cli/vendor/golang.org/x/net/http2/fixed_buffer.go create mode 100644 components/cli/vendor/golang.org/x/net/http2/go19.go create mode 100644 components/cli/vendor/golang.org/x/net/http2/not_go19.go create mode 100644 components/cli/vendor/golang.org/x/net/trace/trace_go16.go create mode 100644 components/cli/vendor/golang.org/x/net/trace/trace_go17.go diff --git a/components/cli/vendor.conf b/components/cli/vendor.conf index f6def192a1..cdfa6ecafc 100755 --- a/components/cli/vendor.conf +++ b/components/cli/vendor.conf @@ -40,7 +40,7 @@ github.com/xeipuuv/gojsonpointer e0fe6f68307607d540ed8eac07a342c33fa1b54a github.com/xeipuuv/gojsonreference e02fc20de94c78484cd5ffb007f8af96be030a45 github.com/xeipuuv/gojsonschema 93e72a773fade158921402d6a24c819b48aba29d golang.org/x/crypto 3fbbcd23f1cb824e69491a5930cfeff09b12f4d2 -golang.org/x/net c427ad74c6d7a814201695e9ffde0c5d400a7674 +golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 golang.org/x/sys 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9 golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756 golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb diff --git a/components/cli/vendor/golang.org/x/net/context/context.go b/components/cli/vendor/golang.org/x/net/context/context.go index 134654cf7e..f143ed6a1e 100644 --- a/components/cli/vendor/golang.org/x/net/context/context.go +++ b/components/cli/vendor/golang.org/x/net/context/context.go @@ -7,7 +7,7 @@ // and between processes. // // Incoming requests to a server should create a Context, and outgoing calls to -// servers should accept a Context. The chain of function calls between must +// servers should accept a Context. The chain of function calls between must // propagate the Context, optionally replacing it with a modified copy created // using WithDeadline, WithTimeout, WithCancel, or WithValue. // @@ -16,14 +16,14 @@ // propagation: // // Do not store Contexts inside a struct type; instead, pass a Context -// explicitly to each function that needs it. The Context should be the first +// explicitly to each function that needs it. The Context should be the first // parameter, typically named ctx: // // func DoSomething(ctx context.Context, arg Arg) error { // // ... use ctx ... // } // -// Do not pass a nil Context, even if a function permits it. Pass context.TODO +// Do not pass a nil Context, even if a function permits it. Pass context.TODO // if you are unsure about which Context to use. // // Use context Values only for request-scoped data that transits processes and @@ -44,13 +44,13 @@ import "time" // Context's methods may be called by multiple goroutines simultaneously. type Context interface { // Deadline returns the time when work done on behalf of this context - // should be canceled. Deadline returns ok==false when no deadline is - // set. Successive calls to Deadline return the same results. + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. Deadline() (deadline time.Time, ok bool) // Done returns a channel that's closed when work done on behalf of this - // context should be canceled. Done may return nil if this context can - // never be canceled. Successive calls to Done return the same value. + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. // // WithCancel arranges for Done to be closed when cancel is called; // WithDeadline arranges for Done to be closed when the deadline @@ -79,24 +79,24 @@ type Context interface { // a Done channel for cancelation. Done() <-chan struct{} - // Err returns a non-nil error value after Done is closed. Err returns + // Err returns a non-nil error value after Done is closed. Err returns // Canceled if the context was canceled or DeadlineExceeded if the - // context's deadline passed. No other values for Err are defined. + // context's deadline passed. No other values for Err are defined. // After Done is closed, successive calls to Err return the same value. Err() error // Value returns the value associated with this context for key, or nil - // if no value is associated with key. Successive calls to Value with + // if no value is associated with key. Successive calls to Value with // the same key returns the same result. // // Use context values only for request-scoped data that transits // processes and API boundaries, not for passing optional parameters to // functions. // - // A key identifies a specific value in a Context. Functions that wish + // A key identifies a specific value in a Context. Functions that wish // to store values in Context typically allocate a key in a global // variable then use that key as the argument to context.WithValue and - // Context.Value. A key can be any type that supports equality; + // Context.Value. A key can be any type that supports equality; // packages should define keys as an unexported type to avoid // collisions. // @@ -115,7 +115,7 @@ type Context interface { // // This prevents collisions with keys defined in other packages. // type key int // - // // userKey is the key for user.User values in Contexts. It is + // // userKey is the key for user.User values in Contexts. It is // // unexported; clients use user.NewContext and user.FromContext // // instead of using this key directly. // var userKey key = 0 @@ -134,14 +134,14 @@ type Context interface { } // Background returns a non-nil, empty Context. It is never canceled, has no -// values, and has no deadline. It is typically used by the main function, +// values, and has no deadline. It is typically used by the main function, // initialization, and tests, and as the top-level Context for incoming // requests. func Background() Context { return background } -// TODO returns a non-nil, empty Context. Code should use context.TODO when +// TODO returns a non-nil, empty Context. Code should use context.TODO when // it's unclear which Context to use or it is not yet available (because the // surrounding function has not yet been extended to accept a Context // parameter). TODO is recognized by static analysis tools that determine diff --git a/components/cli/vendor/golang.org/x/net/context/go17.go b/components/cli/vendor/golang.org/x/net/context/go17.go index f8cda19ada..d20f52b7de 100644 --- a/components/cli/vendor/golang.org/x/net/context/go17.go +++ b/components/cli/vendor/golang.org/x/net/context/go17.go @@ -35,8 +35,8 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { } // WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned // context's Done channel is closed when the deadline expires, when the returned // cancel function is called, or when the parent context's Done channel is // closed, whichever happens first. diff --git a/components/cli/vendor/golang.org/x/net/context/pre_go17.go b/components/cli/vendor/golang.org/x/net/context/pre_go17.go index 5a30acabd0..0f35592df5 100644 --- a/components/cli/vendor/golang.org/x/net/context/pre_go17.go +++ b/components/cli/vendor/golang.org/x/net/context/pre_go17.go @@ -13,7 +13,7 @@ import ( "time" ) -// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// An emptyCtx is never canceled, has no values, and has no deadline. It is not // struct{}, since vars of this type must have distinct addresses. type emptyCtx int @@ -104,7 +104,7 @@ func propagateCancel(parent Context, child canceler) { } // parentCancelCtx follows a chain of parent references until it finds a -// *cancelCtx. This function understands how each of the concrete types in this +// *cancelCtx. This function understands how each of the concrete types in this // package represents its parent. func parentCancelCtx(parent Context) (*cancelCtx, bool) { for { @@ -134,14 +134,14 @@ func removeChild(parent Context, child canceler) { p.mu.Unlock() } -// A canceler is a context type that can be canceled directly. The +// A canceler is a context type that can be canceled directly. The // implementations are *cancelCtx and *timerCtx. type canceler interface { cancel(removeFromParent bool, err error) Done() <-chan struct{} } -// A cancelCtx can be canceled. When canceled, it also cancels any children +// A cancelCtx can be canceled. When canceled, it also cancels any children // that implement canceler. type cancelCtx struct { Context @@ -193,8 +193,8 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) { } // WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned // context's Done channel is closed when the deadline expires, when the returned // cancel function is called, or when the parent context's Done channel is // closed, whichever happens first. @@ -226,8 +226,8 @@ func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { return c, func() { c.cancel(true, Canceled) } } -// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to -// implement Done and Err. It implements cancel by stopping its timer then +// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to +// implement Done and Err. It implements cancel by stopping its timer then // delegating to cancelCtx.cancel. type timerCtx struct { *cancelCtx @@ -281,7 +281,7 @@ func WithValue(parent Context, key interface{}, val interface{}) Context { return &valueCtx{parent, key, val} } -// A valueCtx carries a key-value pair. It implements Value for that key and +// A valueCtx carries a key-value pair. It implements Value for that key and // delegates all other calls to the embedded Context. type valueCtx struct { Context diff --git a/components/cli/vendor/golang.org/x/net/http2/ciphers.go b/components/cli/vendor/golang.org/x/net/http2/ciphers.go new file mode 100644 index 0000000000..698860b777 --- /dev/null +++ b/components/cli/vendor/golang.org/x/net/http2/ciphers.go @@ -0,0 +1,641 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package http2 + +// A list of the possible cipher suite ids. Taken from +// http://www.iana.org/assignments/tls-parameters/tls-parameters.txt + +const ( + cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000 + cipher_TLS_RSA_WITH_NULL_MD5 uint16 = 0x0001 + cipher_TLS_RSA_WITH_NULL_SHA uint16 = 0x0002 + cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0003 + cipher_TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004 + cipher_TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 + cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x0006 + cipher_TLS_RSA_WITH_IDEA_CBC_SHA uint16 = 0x0007 + cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0008 + cipher_TLS_RSA_WITH_DES_CBC_SHA uint16 = 0x0009 + cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000A + cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000B + cipher_TLS_DH_DSS_WITH_DES_CBC_SHA uint16 = 0x000C + cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x000D + cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000E + cipher_TLS_DH_RSA_WITH_DES_CBC_SHA uint16 = 0x000F + cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0010 + cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0011 + cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA uint16 = 0x0012 + cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x0013 + cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0014 + cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA uint16 = 0x0015 + cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016 + cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0017 + cipher_TLS_DH_anon_WITH_RC4_128_MD5 uint16 = 0x0018 + cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0019 + cipher_TLS_DH_anon_WITH_DES_CBC_SHA uint16 = 0x001A + cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0x001B + // Reserved uint16 = 0x001C-1D + cipher_TLS_KRB5_WITH_DES_CBC_SHA uint16 = 0x001E + cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA uint16 = 0x001F + cipher_TLS_KRB5_WITH_RC4_128_SHA uint16 = 0x0020 + cipher_TLS_KRB5_WITH_IDEA_CBC_SHA uint16 = 0x0021 + cipher_TLS_KRB5_WITH_DES_CBC_MD5 uint16 = 0x0022 + cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5 uint16 = 0x0023 + cipher_TLS_KRB5_WITH_RC4_128_MD5 uint16 = 0x0024 + cipher_TLS_KRB5_WITH_IDEA_CBC_MD5 uint16 = 0x0025 + cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA uint16 = 0x0026 + cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA uint16 = 0x0027 + cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA uint16 = 0x0028 + cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 uint16 = 0x0029 + cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x002A + cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5 uint16 = 0x002B + cipher_TLS_PSK_WITH_NULL_SHA uint16 = 0x002C + cipher_TLS_DHE_PSK_WITH_NULL_SHA uint16 = 0x002D + cipher_TLS_RSA_PSK_WITH_NULL_SHA uint16 = 0x002E + cipher_TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002F + cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0030 + cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0031 + cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0032 + cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033 + cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA uint16 = 0x0034 + cipher_TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 + cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0036 + cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0037 + cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0038 + cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039 + cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA uint16 = 0x003A + cipher_TLS_RSA_WITH_NULL_SHA256 uint16 = 0x003B + cipher_TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003C + cipher_TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003D + cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x003E + cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003F + cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x0040 + cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0041 + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0042 + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0043 + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0044 + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0045 + cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0046 + // Reserved uint16 = 0x0047-4F + // Reserved uint16 = 0x0050-58 + // Reserved uint16 = 0x0059-5C + // Unassigned uint16 = 0x005D-5F + // Reserved uint16 = 0x0060-66 + cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067 + cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x0068 + cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x0069 + cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x006A + cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006B + cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 uint16 = 0x006C + cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 uint16 = 0x006D + // Unassigned uint16 = 0x006E-83 + cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0084 + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0085 + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0086 + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0087 + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0088 + cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0089 + cipher_TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008A + cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008B + cipher_TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008C + cipher_TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008D + cipher_TLS_DHE_PSK_WITH_RC4_128_SHA uint16 = 0x008E + cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008F + cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0090 + cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0091 + cipher_TLS_RSA_PSK_WITH_RC4_128_SHA uint16 = 0x0092 + cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x0093 + cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0094 + cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0095 + cipher_TLS_RSA_WITH_SEED_CBC_SHA uint16 = 0x0096 + cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA uint16 = 0x0097 + cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA uint16 = 0x0098 + cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA uint16 = 0x0099 + cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA uint16 = 0x009A + cipher_TLS_DH_anon_WITH_SEED_CBC_SHA uint16 = 0x009B + cipher_TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009C + cipher_TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009D + cipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009E + cipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009F + cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x00A0 + cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x00A1 + cipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A2 + cipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A3 + cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A4 + cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A5 + cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256 uint16 = 0x00A6 + cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384 uint16 = 0x00A7 + cipher_TLS_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00A8 + cipher_TLS_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00A9 + cipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AA + cipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AB + cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AC + cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AD + cipher_TLS_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00AE + cipher_TLS_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00AF + cipher_TLS_PSK_WITH_NULL_SHA256 uint16 = 0x00B0 + cipher_TLS_PSK_WITH_NULL_SHA384 uint16 = 0x00B1 + cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B2 + cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B3 + cipher_TLS_DHE_PSK_WITH_NULL_SHA256 uint16 = 0x00B4 + cipher_TLS_DHE_PSK_WITH_NULL_SHA384 uint16 = 0x00B5 + cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B6 + cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B7 + cipher_TLS_RSA_PSK_WITH_NULL_SHA256 uint16 = 0x00B8 + cipher_TLS_RSA_PSK_WITH_NULL_SHA384 uint16 = 0x00B9 + cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BA + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BB + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BC + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BD + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BE + cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BF + cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C0 + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C1 + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C2 + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C3 + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C4 + cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C5 + // Unassigned uint16 = 0x00C6-FE + cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF + // Unassigned uint16 = 0x01-55,* + cipher_TLS_FALLBACK_SCSV uint16 = 0x5600 + // Unassigned uint16 = 0x5601 - 0xC000 + cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA uint16 = 0xC001 + cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA uint16 = 0xC002 + cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC003 + cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC004 + cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC005 + cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA uint16 = 0xC006 + cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xC007 + cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC008 + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC009 + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC00A + cipher_TLS_ECDH_RSA_WITH_NULL_SHA uint16 = 0xC00B + cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA uint16 = 0xC00C + cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC00D + cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC00E + cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC00F + cipher_TLS_ECDHE_RSA_WITH_NULL_SHA uint16 = 0xC010 + cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xC011 + cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC012 + cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC013 + cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC014 + cipher_TLS_ECDH_anon_WITH_NULL_SHA uint16 = 0xC015 + cipher_TLS_ECDH_anon_WITH_RC4_128_SHA uint16 = 0xC016 + cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0xC017 + cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA uint16 = 0xC018 + cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA uint16 = 0xC019 + cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01A + cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01B + cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01C + cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA uint16 = 0xC01D + cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC01E + cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA uint16 = 0xC01F + cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA uint16 = 0xC020 + cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC021 + cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA uint16 = 0xC022 + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC023 + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC024 + cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC025 + cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC026 + cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC027 + cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC028 + cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC029 + cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC02A + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02B + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02C + cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02D + cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02E + cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02F + cipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC030 + cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC031 + cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC032 + cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA uint16 = 0xC033 + cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0xC034 + cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xC035 + cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xC036 + cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0xC037 + cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0xC038 + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA uint16 = 0xC039 + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256 uint16 = 0xC03A + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384 uint16 = 0xC03B + cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03C + cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03D + cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03E + cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03F + cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC040 + cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC041 + cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC042 + cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC043 + cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC044 + cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC045 + cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC046 + cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC047 + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC048 + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC049 + cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04A + cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04B + cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04C + cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04D + cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04E + cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04F + cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC050 + cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC051 + cipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC052 + cipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC053 + cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC054 + cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC055 + cipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC056 + cipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC057 + cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC058 + cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC059 + cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05A + cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05B + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05C + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05D + cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05E + cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05F + cipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC060 + cipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC061 + cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC062 + cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC063 + cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC064 + cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC065 + cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC066 + cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC067 + cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC068 + cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC069 + cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06A + cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06B + cipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06C + cipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06D + cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06E + cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06F + cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC070 + cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC071 + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC072 + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC073 + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC074 + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC075 + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC076 + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC077 + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC078 + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC079 + cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07A + cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07B + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07C + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07D + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07E + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07F + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC080 + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC081 + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC082 + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC083 + cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC084 + cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC085 + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC086 + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC087 + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC088 + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC089 + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08A + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08B + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08C + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08D + cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08E + cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08F + cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC090 + cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC091 + cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC092 + cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC093 + cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC094 + cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC095 + cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC096 + cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC097 + cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC098 + cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC099 + cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC09A + cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC09B + cipher_TLS_RSA_WITH_AES_128_CCM uint16 = 0xC09C + cipher_TLS_RSA_WITH_AES_256_CCM uint16 = 0xC09D + cipher_TLS_DHE_RSA_WITH_AES_128_CCM uint16 = 0xC09E + cipher_TLS_DHE_RSA_WITH_AES_256_CCM uint16 = 0xC09F + cipher_TLS_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A0 + cipher_TLS_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A1 + cipher_TLS_DHE_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A2 + cipher_TLS_DHE_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A3 + cipher_TLS_PSK_WITH_AES_128_CCM uint16 = 0xC0A4 + cipher_TLS_PSK_WITH_AES_256_CCM uint16 = 0xC0A5 + cipher_TLS_DHE_PSK_WITH_AES_128_CCM uint16 = 0xC0A6 + cipher_TLS_DHE_PSK_WITH_AES_256_CCM uint16 = 0xC0A7 + cipher_TLS_PSK_WITH_AES_128_CCM_8 uint16 = 0xC0A8 + cipher_TLS_PSK_WITH_AES_256_CCM_8 uint16 = 0xC0A9 + cipher_TLS_PSK_DHE_WITH_AES_128_CCM_8 uint16 = 0xC0AA + cipher_TLS_PSK_DHE_WITH_AES_256_CCM_8 uint16 = 0xC0AB + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM uint16 = 0xC0AC + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM uint16 = 0xC0AD + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 uint16 = 0xC0AE + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 uint16 = 0xC0AF + // Unassigned uint16 = 0xC0B0-FF + // Unassigned uint16 = 0xC1-CB,* + // Unassigned uint16 = 0xCC00-A7 + cipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA8 + cipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA9 + cipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAA + cipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAB + cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAC + cipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAD + cipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAE +) + +// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec. +// References: +// https://tools.ietf.org/html/rfc7540#appendix-A +// Reject cipher suites from Appendix A. +// "This list includes those cipher suites that do not +// offer an ephemeral key exchange and those that are +// based on the TLS null, stream or block cipher type" +func isBadCipher(cipher uint16) bool { + switch cipher { + case cipher_TLS_NULL_WITH_NULL_NULL, + cipher_TLS_RSA_WITH_NULL_MD5, + cipher_TLS_RSA_WITH_NULL_SHA, + cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5, + cipher_TLS_RSA_WITH_RC4_128_MD5, + cipher_TLS_RSA_WITH_RC4_128_SHA, + cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, + cipher_TLS_RSA_WITH_IDEA_CBC_SHA, + cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_RSA_WITH_DES_CBC_SHA, + cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DH_DSS_WITH_DES_CBC_SHA, + cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DH_RSA_WITH_DES_CBC_SHA, + cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5, + cipher_TLS_DH_anon_WITH_RC4_128_MD5, + cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DH_anon_WITH_DES_CBC_SHA, + cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_KRB5_WITH_DES_CBC_SHA, + cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_KRB5_WITH_RC4_128_SHA, + cipher_TLS_KRB5_WITH_IDEA_CBC_SHA, + cipher_TLS_KRB5_WITH_DES_CBC_MD5, + cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5, + cipher_TLS_KRB5_WITH_RC4_128_MD5, + cipher_TLS_KRB5_WITH_IDEA_CBC_MD5, + cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, + cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA, + cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA, + cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5, + cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5, + cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5, + cipher_TLS_PSK_WITH_NULL_SHA, + cipher_TLS_DHE_PSK_WITH_NULL_SHA, + cipher_TLS_RSA_PSK_WITH_NULL_SHA, + cipher_TLS_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA, + cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA, + cipher_TLS_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA, + cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA, + cipher_TLS_RSA_WITH_NULL_SHA256, + cipher_TLS_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_RSA_WITH_AES_256_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256, + cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256, + cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_PSK_WITH_RC4_128_SHA, + cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_PSK_WITH_AES_128_CBC_SHA, + cipher_TLS_PSK_WITH_AES_256_CBC_SHA, + cipher_TLS_DHE_PSK_WITH_RC4_128_SHA, + cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, + cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, + cipher_TLS_RSA_PSK_WITH_RC4_128_SHA, + cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, + cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, + cipher_TLS_RSA_WITH_SEED_CBC_SHA, + cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA, + cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA, + cipher_TLS_DH_anon_WITH_SEED_CBC_SHA, + cipher_TLS_RSA_WITH_AES_128_GCM_SHA256, + cipher_TLS_RSA_WITH_AES_256_GCM_SHA384, + cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256, + cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384, + cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256, + cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384, + cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256, + cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384, + cipher_TLS_PSK_WITH_AES_128_GCM_SHA256, + cipher_TLS_PSK_WITH_AES_256_GCM_SHA384, + cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, + cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, + cipher_TLS_PSK_WITH_AES_128_CBC_SHA256, + cipher_TLS_PSK_WITH_AES_256_CBC_SHA384, + cipher_TLS_PSK_WITH_NULL_SHA256, + cipher_TLS_PSK_WITH_NULL_SHA384, + cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, + cipher_TLS_DHE_PSK_WITH_NULL_SHA256, + cipher_TLS_DHE_PSK_WITH_NULL_SHA384, + cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, + cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, + cipher_TLS_RSA_PSK_WITH_NULL_SHA256, + cipher_TLS_RSA_PSK_WITH_NULL_SHA384, + cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV, + cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA, + cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDH_RSA_WITH_NULL_SHA, + cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA, + cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDHE_RSA_WITH_NULL_SHA, + cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA, + cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDH_anon_WITH_NULL_SHA, + cipher_TLS_ECDH_anon_WITH_RC4_128_SHA, + cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA, + cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA, + cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA, + cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA, + cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA, + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256, + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384, + cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_RSA_WITH_AES_128_CCM, + cipher_TLS_RSA_WITH_AES_256_CCM, + cipher_TLS_RSA_WITH_AES_128_CCM_8, + cipher_TLS_RSA_WITH_AES_256_CCM_8, + cipher_TLS_PSK_WITH_AES_128_CCM, + cipher_TLS_PSK_WITH_AES_256_CCM, + cipher_TLS_PSK_WITH_AES_128_CCM_8, + cipher_TLS_PSK_WITH_AES_256_CCM_8: + return true + default: + return false + } +} diff --git a/components/cli/vendor/golang.org/x/net/http2/client_conn_pool.go b/components/cli/vendor/golang.org/x/net/http2/client_conn_pool.go index b13941258a..bdf5652b01 100644 --- a/components/cli/vendor/golang.org/x/net/http2/client_conn_pool.go +++ b/components/cli/vendor/golang.org/x/net/http2/client_conn_pool.go @@ -247,7 +247,7 @@ func filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn { } // noDialClientConnPool is an implementation of http2.ClientConnPool -// which never dials. We let the HTTP/1.1 client dial and use its TLS +// which never dials. We let the HTTP/1.1 client dial and use its TLS // connection instead. type noDialClientConnPool struct{ *clientConnPool } diff --git a/components/cli/vendor/golang.org/x/net/http2/databuffer.go b/components/cli/vendor/golang.org/x/net/http2/databuffer.go new file mode 100644 index 0000000000..a3067f8de7 --- /dev/null +++ b/components/cli/vendor/golang.org/x/net/http2/databuffer.go @@ -0,0 +1,146 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package http2 + +import ( + "errors" + "fmt" + "sync" +) + +// Buffer chunks are allocated from a pool to reduce pressure on GC. +// The maximum wasted space per dataBuffer is 2x the largest size class, +// which happens when the dataBuffer has multiple chunks and there is +// one unread byte in both the first and last chunks. We use a few size +// classes to minimize overheads for servers that typically receive very +// small request bodies. +// +// TODO: Benchmark to determine if the pools are necessary. The GC may have +// improved enough that we can instead allocate chunks like this: +// make([]byte, max(16<<10, expectedBytesRemaining)) +var ( + dataChunkSizeClasses = []int{ + 1 << 10, + 2 << 10, + 4 << 10, + 8 << 10, + 16 << 10, + } + dataChunkPools = [...]sync.Pool{ + {New: func() interface{} { return make([]byte, 1<<10) }}, + {New: func() interface{} { return make([]byte, 2<<10) }}, + {New: func() interface{} { return make([]byte, 4<<10) }}, + {New: func() interface{} { return make([]byte, 8<<10) }}, + {New: func() interface{} { return make([]byte, 16<<10) }}, + } +) + +func getDataBufferChunk(size int64) []byte { + i := 0 + for ; i < len(dataChunkSizeClasses)-1; i++ { + if size <= int64(dataChunkSizeClasses[i]) { + break + } + } + return dataChunkPools[i].Get().([]byte) +} + +func putDataBufferChunk(p []byte) { + for i, n := range dataChunkSizeClasses { + if len(p) == n { + dataChunkPools[i].Put(p) + return + } + } + panic(fmt.Sprintf("unexpected buffer len=%v", len(p))) +} + +// dataBuffer is an io.ReadWriter backed by a list of data chunks. +// Each dataBuffer is used to read DATA frames on a single stream. +// The buffer is divided into chunks so the server can limit the +// total memory used by a single connection without limiting the +// request body size on any single stream. +type dataBuffer struct { + chunks [][]byte + r int // next byte to read is chunks[0][r] + w int // next byte to write is chunks[len(chunks)-1][w] + size int // total buffered bytes + expected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0) +} + +var errReadEmpty = errors.New("read from empty dataBuffer") + +// Read copies bytes from the buffer into p. +// It is an error to read when no data is available. +func (b *dataBuffer) Read(p []byte) (int, error) { + if b.size == 0 { + return 0, errReadEmpty + } + var ntotal int + for len(p) > 0 && b.size > 0 { + readFrom := b.bytesFromFirstChunk() + n := copy(p, readFrom) + p = p[n:] + ntotal += n + b.r += n + b.size -= n + // If the first chunk has been consumed, advance to the next chunk. + if b.r == len(b.chunks[0]) { + putDataBufferChunk(b.chunks[0]) + end := len(b.chunks) - 1 + copy(b.chunks[:end], b.chunks[1:]) + b.chunks[end] = nil + b.chunks = b.chunks[:end] + b.r = 0 + } + } + return ntotal, nil +} + +func (b *dataBuffer) bytesFromFirstChunk() []byte { + if len(b.chunks) == 1 { + return b.chunks[0][b.r:b.w] + } + return b.chunks[0][b.r:] +} + +// Len returns the number of bytes of the unread portion of the buffer. +func (b *dataBuffer) Len() int { + return b.size +} + +// Write appends p to the buffer. +func (b *dataBuffer) Write(p []byte) (int, error) { + ntotal := len(p) + for len(p) > 0 { + // If the last chunk is empty, allocate a new chunk. Try to allocate + // enough to fully copy p plus any additional bytes we expect to + // receive. However, this may allocate less than len(p). + want := int64(len(p)) + if b.expected > want { + want = b.expected + } + chunk := b.lastChunkOrAlloc(want) + n := copy(chunk[b.w:], p) + p = p[n:] + b.w += n + b.size += n + b.expected -= int64(n) + } + return ntotal, nil +} + +func (b *dataBuffer) lastChunkOrAlloc(want int64) []byte { + if len(b.chunks) != 0 { + last := b.chunks[len(b.chunks)-1] + if b.w < len(last) { + return last + } + } + chunk := getDataBufferChunk(want) + b.chunks = append(b.chunks, chunk) + b.w = 0 + return chunk +} diff --git a/components/cli/vendor/golang.org/x/net/http2/fixed_buffer.go b/components/cli/vendor/golang.org/x/net/http2/fixed_buffer.go deleted file mode 100644 index 47da0f0bf7..0000000000 --- a/components/cli/vendor/golang.org/x/net/http2/fixed_buffer.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http2 - -import ( - "errors" -) - -// fixedBuffer is an io.ReadWriter backed by a fixed size buffer. -// It never allocates, but moves old data as new data is written. -type fixedBuffer struct { - buf []byte - r, w int -} - -var ( - errReadEmpty = errors.New("read from empty fixedBuffer") - errWriteFull = errors.New("write on full fixedBuffer") -) - -// Read copies bytes from the buffer into p. -// It is an error to read when no data is available. -func (b *fixedBuffer) Read(p []byte) (n int, err error) { - if b.r == b.w { - return 0, errReadEmpty - } - n = copy(p, b.buf[b.r:b.w]) - b.r += n - if b.r == b.w { - b.r = 0 - b.w = 0 - } - return n, nil -} - -// Len returns the number of bytes of the unread portion of the buffer. -func (b *fixedBuffer) Len() int { - return b.w - b.r -} - -// Write copies bytes from p into the buffer. -// It is an error to write more data than the buffer can hold. -func (b *fixedBuffer) Write(p []byte) (n int, err error) { - // Slide existing data to beginning. - if b.r > 0 && len(p) > len(b.buf)-b.w { - copy(b.buf, b.buf[b.r:b.w]) - b.w -= b.r - b.r = 0 - } - - // Write new data. - n = copy(b.buf[b.w:], p) - b.w += n - if n < len(p) { - err = errWriteFull - } - return n, err -} diff --git a/components/cli/vendor/golang.org/x/net/http2/frame.go b/components/cli/vendor/golang.org/x/net/http2/frame.go index 358833fedf..3b14890728 100644 --- a/components/cli/vendor/golang.org/x/net/http2/frame.go +++ b/components/cli/vendor/golang.org/x/net/http2/frame.go @@ -122,7 +122,7 @@ var flagName = map[FrameType]map[Flags]string{ // a frameParser parses a frame given its FrameHeader and payload // bytes. The length of payload will always equal fh.Length (which // might be 0). -type frameParser func(fh FrameHeader, payload []byte) (Frame, error) +type frameParser func(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) var frameParsers = map[FrameType]frameParser{ FrameData: parseDataFrame, @@ -312,7 +312,7 @@ type Framer struct { MaxHeaderListSize uint32 // TODO: track which type of frame & with which flags was sent - // last. Then return an error (unless AllowIllegalWrites) if + // last. Then return an error (unless AllowIllegalWrites) if // we're in the middle of a header block and a // non-Continuation or Continuation on a different stream is // attempted to be written. @@ -323,6 +323,8 @@ type Framer struct { debugFramerBuf *bytes.Buffer debugReadLoggerf func(string, ...interface{}) debugWriteLoggerf func(string, ...interface{}) + + frameCache *frameCache // nil if frames aren't reused (default) } func (fr *Framer) maxHeaderListSize() uint32 { @@ -398,6 +400,27 @@ const ( maxFrameSize = 1<<24 - 1 ) +// SetReuseFrames allows the Framer to reuse Frames. +// If called on a Framer, Frames returned by calls to ReadFrame are only +// valid until the next call to ReadFrame. +func (fr *Framer) SetReuseFrames() { + if fr.frameCache != nil { + return + } + fr.frameCache = &frameCache{} +} + +type frameCache struct { + dataFrame DataFrame +} + +func (fc *frameCache) getDataFrame() *DataFrame { + if fc == nil { + return &DataFrame{} + } + return &fc.dataFrame +} + // NewFramer returns a Framer that writes frames to w and reads them from r. func NewFramer(w io.Writer, r io.Reader) *Framer { fr := &Framer{ @@ -477,7 +500,7 @@ func (fr *Framer) ReadFrame() (Frame, error) { if _, err := io.ReadFull(fr.r, payload); err != nil { return nil, err } - f, err := typeFrameParser(fh.Type)(fh, payload) + f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, payload) if err != nil { if ce, ok := err.(connError); ok { return nil, fr.connError(ce.Code, ce.Reason) @@ -565,7 +588,7 @@ func (f *DataFrame) Data() []byte { return f.data } -func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) { +func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) { if fh.StreamID == 0 { // DATA frames MUST be associated with a stream. If a // DATA frame is received whose stream identifier @@ -574,9 +597,9 @@ func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) { // PROTOCOL_ERROR. return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"} } - f := &DataFrame{ - FrameHeader: fh, - } + f := fc.getDataFrame() + f.FrameHeader = fh + var padSize byte if fh.Flags.Has(FlagDataPadded) { var err error @@ -600,6 +623,7 @@ var ( errStreamID = errors.New("invalid stream ID") errDepStreamID = errors.New("invalid dependent stream ID") errPadLength = errors.New("pad length too large") + errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled") ) func validStreamIDOrZero(streamID uint32) bool { @@ -623,6 +647,7 @@ func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { // // If pad is nil, the padding bit is not sent. // The length of pad must not exceed 255 bytes. +// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set. // // It will perform exactly one Write to the underlying Writer. // It is the caller's responsibility not to violate the maximum frame size @@ -631,8 +656,18 @@ func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []by if !validStreamID(streamID) && !f.AllowIllegalWrites { return errStreamID } - if len(pad) > 255 { - return errPadLength + if len(pad) > 0 { + if len(pad) > 255 { + return errPadLength + } + if !f.AllowIllegalWrites { + for _, b := range pad { + if b != 0 { + // "Padding octets MUST be set to zero when sending." + return errPadBytes + } + } + } } var flags Flags if endStream { @@ -660,10 +695,10 @@ type SettingsFrame struct { p []byte } -func parseSettingsFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 { // When this (ACK 0x1) bit is set, the payload of the - // SETTINGS frame MUST be empty. Receipt of a + // SETTINGS frame MUST be empty. Receipt of a // SETTINGS frame with the ACK flag set and a length // field value other than 0 MUST be treated as a // connection error (Section 5.4.1) of type @@ -672,7 +707,7 @@ func parseSettingsFrame(fh FrameHeader, p []byte) (Frame, error) { } if fh.StreamID != 0 { // SETTINGS frames always apply to a connection, - // never a single stream. The stream identifier for a + // never a single stream. The stream identifier for a // SETTINGS frame MUST be zero (0x0). If an endpoint // receives a SETTINGS frame whose stream identifier // field is anything other than 0x0, the endpoint MUST @@ -762,7 +797,7 @@ type PingFrame struct { func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) } -func parsePingFrame(fh FrameHeader, payload []byte) (Frame, error) { +func parsePingFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) { if len(payload) != 8 { return nil, ConnectionError(ErrCodeFrameSize) } @@ -802,7 +837,7 @@ func (f *GoAwayFrame) DebugData() []byte { return f.debugData } -func parseGoAwayFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseGoAwayFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if fh.StreamID != 0 { return nil, ConnectionError(ErrCodeProtocol) } @@ -842,7 +877,7 @@ func (f *UnknownFrame) Payload() []byte { return f.p } -func parseUnknownFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseUnknownFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { return &UnknownFrame{fh, p}, nil } @@ -853,7 +888,7 @@ type WindowUpdateFrame struct { Increment uint32 // never read with high bit set } -func parseWindowUpdateFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if len(p) != 4 { return nil, ConnectionError(ErrCodeFrameSize) } @@ -918,12 +953,12 @@ func (f *HeadersFrame) HasPriority() bool { return f.FrameHeader.Flags.Has(FlagHeadersPriority) } -func parseHeadersFrame(fh FrameHeader, p []byte) (_ Frame, err error) { +func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) { hf := &HeadersFrame{ FrameHeader: fh, } if fh.StreamID == 0 { - // HEADERS frames MUST be associated with a stream. If a HEADERS frame + // HEADERS frames MUST be associated with a stream. If a HEADERS frame // is received whose stream identifier field is 0x0, the recipient MUST // respond with a connection error (Section 5.4.1) of type // PROTOCOL_ERROR. @@ -1045,7 +1080,7 @@ type PriorityParam struct { Exclusive bool // Weight is the stream's zero-indexed weight. It should be - // set together with StreamDep, or neither should be set. Per + // set together with StreamDep, or neither should be set. Per // the spec, "Add one to the value to obtain a weight between // 1 and 256." Weight uint8 @@ -1055,7 +1090,7 @@ func (p PriorityParam) IsZero() bool { return p == PriorityParam{} } -func parsePriorityFrame(fh FrameHeader, payload []byte) (Frame, error) { +func parsePriorityFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) { if fh.StreamID == 0 { return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"} } @@ -1102,7 +1137,7 @@ type RSTStreamFrame struct { ErrCode ErrCode } -func parseRSTStreamFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if len(p) != 4 { return nil, ConnectionError(ErrCodeFrameSize) } @@ -1132,7 +1167,7 @@ type ContinuationFrame struct { headerFragBuf []byte } -func parseContinuationFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseContinuationFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if fh.StreamID == 0 { return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"} } @@ -1182,7 +1217,7 @@ func (f *PushPromiseFrame) HeadersEnded() bool { return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders) } -func parsePushPromise(fh FrameHeader, p []byte) (_ Frame, err error) { +func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) { pp := &PushPromiseFrame{ FrameHeader: fh, } diff --git a/components/cli/vendor/golang.org/x/net/http2/go16.go b/components/cli/vendor/golang.org/x/net/http2/go16.go index 2b72855f55..00b2e9e3cf 100644 --- a/components/cli/vendor/golang.org/x/net/http2/go16.go +++ b/components/cli/vendor/golang.org/x/net/http2/go16.go @@ -7,7 +7,6 @@ package http2 import ( - "crypto/tls" "net/http" "time" ) @@ -15,29 +14,3 @@ import ( func transportExpectContinueTimeout(t1 *http.Transport) time.Duration { return t1.ExpectContinueTimeout } - -// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec. -func isBadCipher(cipher uint16) bool { - switch cipher { - case tls.TLS_RSA_WITH_RC4_128_SHA, - tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, - tls.TLS_RSA_WITH_AES_128_CBC_SHA, - tls.TLS_RSA_WITH_AES_256_CBC_SHA, - tls.TLS_RSA_WITH_AES_128_GCM_SHA256, - tls.TLS_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, - tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - // Reject cipher suites from Appendix A. - // "This list includes those cipher suites that do not - // offer an ephemeral key exchange and those that are - // based on the TLS null, stream or block cipher type" - return true - default: - return false - } -} diff --git a/components/cli/vendor/golang.org/x/net/http2/go18.go b/components/cli/vendor/golang.org/x/net/http2/go18.go index 633202c39f..73cc2381f3 100644 --- a/components/cli/vendor/golang.org/x/net/http2/go18.go +++ b/components/cli/vendor/golang.org/x/net/http2/go18.go @@ -12,7 +12,11 @@ import ( "net/http" ) -func cloneTLSConfig(c *tls.Config) *tls.Config { return c.Clone() } +func cloneTLSConfig(c *tls.Config) *tls.Config { + c2 := c.Clone() + c2.GetClientCertificate = c.GetClientCertificate // golang.org/issue/19264 + return c2 +} var _ http.Pusher = (*responseWriter)(nil) diff --git a/components/cli/vendor/golang.org/x/net/http2/go19.go b/components/cli/vendor/golang.org/x/net/http2/go19.go new file mode 100644 index 0000000000..38124ba56e --- /dev/null +++ b/components/cli/vendor/golang.org/x/net/http2/go19.go @@ -0,0 +1,16 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.9 + +package http2 + +import ( + "net/http" +) + +func configureServer19(s *http.Server, conf *Server) error { + s.RegisterOnShutdown(conf.state.startGracefulShutdown) + return nil +} diff --git a/components/cli/vendor/golang.org/x/net/http2/hpack/encode.go b/components/cli/vendor/golang.org/x/net/http2/hpack/encode.go index f9bb033984..54726c2a3c 100644 --- a/components/cli/vendor/golang.org/x/net/http2/hpack/encode.go +++ b/components/cli/vendor/golang.org/x/net/http2/hpack/encode.go @@ -39,13 +39,14 @@ func NewEncoder(w io.Writer) *Encoder { tableSizeUpdate: false, w: w, } + e.dynTab.table.init() e.dynTab.setMaxSize(initialHeaderTableSize) return e } // WriteField encodes f into a single Write to e's underlying Writer. // This function may also produce bytes for "Header Table Size Update" -// if necessary. If produced, it is done before encoding f. +// if necessary. If produced, it is done before encoding f. func (e *Encoder) WriteField(f HeaderField) error { e.buf = e.buf[:0] @@ -88,29 +89,17 @@ func (e *Encoder) WriteField(f HeaderField) error { // only name matches, i points to that index and nameValueMatch // becomes false. func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) { - for idx, hf := range staticTable { - if !constantTimeStringCompare(hf.Name, f.Name) { - continue - } - if i == 0 { - i = uint64(idx + 1) - } - if f.Sensitive { - continue - } - if !constantTimeStringCompare(hf.Value, f.Value) { - continue - } - i = uint64(idx + 1) - nameValueMatch = true - return + i, nameValueMatch = staticTable.search(f) + if nameValueMatch { + return i, true } - j, nameValueMatch := e.dynTab.search(f) + j, nameValueMatch := e.dynTab.table.search(f) if nameValueMatch || (i == 0 && j != 0) { - i = j + uint64(len(staticTable)) + return j + uint64(staticTable.len()), nameValueMatch } - return + + return i, false } // SetMaxDynamicTableSize changes the dynamic header table size to v. diff --git a/components/cli/vendor/golang.org/x/net/http2/hpack/hpack.go b/components/cli/vendor/golang.org/x/net/http2/hpack/hpack.go index 135b9f62cd..176644acda 100644 --- a/components/cli/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/components/cli/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -61,7 +61,7 @@ func (hf HeaderField) String() string { func (hf HeaderField) Size() uint32 { // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1 // "The size of the dynamic table is the sum of the size of - // its entries. The size of an entry is the sum of its name's + // its entries. The size of an entry is the sum of its name's // length in octets (as defined in Section 5.2), its value's // length in octets (see Section 5.2), plus 32. The size of // an entry is calculated using the length of the name and @@ -102,6 +102,7 @@ func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decod emit: emitFunc, emitEnabled: true, } + d.dynTab.table.init() d.dynTab.allowedMaxSize = maxDynamicTableSize d.dynTab.setMaxSize(maxDynamicTableSize) return d @@ -154,12 +155,9 @@ func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) { } type dynamicTable struct { - // ents is the FIFO described at // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2 - // The newest (low index) is append at the end, and items are - // evicted from the front. - ents []HeaderField - size uint32 + table headerFieldTable + size uint32 // in bytes maxSize uint32 // current maxSize allowedMaxSize uint32 // maxSize may go up to this, inclusive } @@ -169,95 +167,45 @@ func (dt *dynamicTable) setMaxSize(v uint32) { dt.evict() } -// TODO: change dynamicTable to be a struct with a slice and a size int field, -// per http://http2.github.io/http2-spec/compression.html#rfc.section.4.1: -// -// -// Then make add increment the size. maybe the max size should move from Decoder to -// dynamicTable and add should return an ok bool if there was enough space. -// -// Later we'll need a remove operation on dynamicTable. - func (dt *dynamicTable) add(f HeaderField) { - dt.ents = append(dt.ents, f) + dt.table.addEntry(f) dt.size += f.Size() dt.evict() } -// If we're too big, evict old stuff (front of the slice) +// If we're too big, evict old stuff. func (dt *dynamicTable) evict() { - base := dt.ents // keep base pointer of slice - for dt.size > dt.maxSize { - dt.size -= dt.ents[0].Size() - dt.ents = dt.ents[1:] + var n int + for dt.size > dt.maxSize && n < dt.table.len() { + dt.size -= dt.table.ents[n].Size() + n++ } - - // Shift slice contents down if we evicted things. - if len(dt.ents) != len(base) { - copy(base, dt.ents) - dt.ents = base[:len(dt.ents)] - } -} - -// constantTimeStringCompare compares string a and b in a constant -// time manner. -func constantTimeStringCompare(a, b string) bool { - if len(a) != len(b) { - return false - } - - c := byte(0) - - for i := 0; i < len(a); i++ { - c |= a[i] ^ b[i] - } - - return c == 0 -} - -// Search searches f in the table. The return value i is 0 if there is -// no name match. If there is name match or name/value match, i is the -// index of that entry (1-based). If both name and value match, -// nameValueMatch becomes true. -func (dt *dynamicTable) search(f HeaderField) (i uint64, nameValueMatch bool) { - l := len(dt.ents) - for j := l - 1; j >= 0; j-- { - ent := dt.ents[j] - if !constantTimeStringCompare(ent.Name, f.Name) { - continue - } - if i == 0 { - i = uint64(l - j) - } - if f.Sensitive { - continue - } - if !constantTimeStringCompare(ent.Value, f.Value) { - continue - } - i = uint64(l - j) - nameValueMatch = true - return - } - return + dt.table.evictOldest(n) } func (d *Decoder) maxTableIndex() int { - return len(d.dynTab.ents) + len(staticTable) + // This should never overflow. RFC 7540 Section 6.5.2 limits the size of + // the dynamic table to 2^32 bytes, where each entry will occupy more than + // one byte. Further, the staticTable has a fixed, small length. + return d.dynTab.table.len() + staticTable.len() } func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) { - if i < 1 { + // See Section 2.3.3. + if i == 0 { return } + if i <= uint64(staticTable.len()) { + return staticTable.ents[i-1], true + } if i > uint64(d.maxTableIndex()) { return } - if i <= uint64(len(staticTable)) { - return staticTable[i-1], true - } - dents := d.dynTab.ents - return dents[len(dents)-(int(i)-len(staticTable))], true + // In the dynamic table, newer entries have lower indices. + // However, dt.ents[0] is the oldest entry. Hence, dt.ents is + // the reversed dynamic table. + dt := d.dynTab.table + return dt.ents[dt.len()-(int(i)-staticTable.len())], true } // Decode decodes an entire block. @@ -307,7 +255,7 @@ func (d *Decoder) Write(p []byte) (n int, err error) { err = d.parseHeaderFieldRepr() if err == errNeedMore { // Extra paranoia, making sure saveBuf won't - // get too large. All the varint and string + // get too large. All the varint and string // reading code earlier should already catch // overlong things and return ErrStringLength, // but keep this as a last resort. diff --git a/components/cli/vendor/golang.org/x/net/http2/hpack/tables.go b/components/cli/vendor/golang.org/x/net/http2/hpack/tables.go index b9283a0233..a66cfbea69 100644 --- a/components/cli/vendor/golang.org/x/net/http2/hpack/tables.go +++ b/components/cli/vendor/golang.org/x/net/http2/hpack/tables.go @@ -4,73 +4,200 @@ package hpack -func pair(name, value string) HeaderField { - return HeaderField{Name: name, Value: value} +import ( + "fmt" +) + +// headerFieldTable implements a list of HeaderFields. +// This is used to implement the static and dynamic tables. +type headerFieldTable struct { + // For static tables, entries are never evicted. + // + // For dynamic tables, entries are evicted from ents[0] and added to the end. + // Each entry has a unique id that starts at one and increments for each + // entry that is added. This unique id is stable across evictions, meaning + // it can be used as a pointer to a specific entry. As in hpack, unique ids + // are 1-based. The unique id for ents[k] is k + evictCount + 1. + // + // Zero is not a valid unique id. + // + // evictCount should not overflow in any remotely practical situation. In + // practice, we will have one dynamic table per HTTP/2 connection. If we + // assume a very powerful server that handles 1M QPS per connection and each + // request adds (then evicts) 100 entries from the table, it would still take + // 2M years for evictCount to overflow. + ents []HeaderField + evictCount uint64 + + // byName maps a HeaderField name to the unique id of the newest entry with + // the same name. See above for a definition of "unique id". + byName map[string]uint64 + + // byNameValue maps a HeaderField name/value pair to the unique id of the newest + // entry with the same name and value. See above for a definition of "unique id". + byNameValue map[pairNameValue]uint64 +} + +type pairNameValue struct { + name, value string +} + +func (t *headerFieldTable) init() { + t.byName = make(map[string]uint64) + t.byNameValue = make(map[pairNameValue]uint64) +} + +// len reports the number of entries in the table. +func (t *headerFieldTable) len() int { + return len(t.ents) +} + +// addEntry adds a new entry. +func (t *headerFieldTable) addEntry(f HeaderField) { + id := uint64(t.len()) + t.evictCount + 1 + t.byName[f.Name] = id + t.byNameValue[pairNameValue{f.Name, f.Value}] = id + t.ents = append(t.ents, f) +} + +// evictOldest evicts the n oldest entries in the table. +func (t *headerFieldTable) evictOldest(n int) { + if n > t.len() { + panic(fmt.Sprintf("evictOldest(%v) on table with %v entries", n, t.len())) + } + for k := 0; k < n; k++ { + f := t.ents[k] + id := t.evictCount + uint64(k) + 1 + if t.byName[f.Name] == id { + delete(t.byName, f.Name) + } + if p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id { + delete(t.byNameValue, p) + } + } + copy(t.ents, t.ents[n:]) + for k := t.len() - n; k < t.len(); k++ { + t.ents[k] = HeaderField{} // so strings can be garbage collected + } + t.ents = t.ents[:t.len()-n] + if t.evictCount+uint64(n) < t.evictCount { + panic("evictCount overflow") + } + t.evictCount += uint64(n) +} + +// search finds f in the table. If there is no match, i is 0. +// If both name and value match, i is the matched index and nameValueMatch +// becomes true. If only name matches, i points to that index and +// nameValueMatch becomes false. +// +// The returned index is a 1-based HPACK index. For dynamic tables, HPACK says +// that index 1 should be the newest entry, but t.ents[0] is the oldest entry, +// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic +// table, the return value i actually refers to the entry t.ents[t.len()-i]. +// +// All tables are assumed to be a dynamic tables except for the global +// staticTable pointer. +// +// See Section 2.3.3. +func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) { + if !f.Sensitive { + if id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 { + return t.idToIndex(id), true + } + } + if id := t.byName[f.Name]; id != 0 { + return t.idToIndex(id), false + } + return 0, false +} + +// idToIndex converts a unique id to an HPACK index. +// See Section 2.3.3. +func (t *headerFieldTable) idToIndex(id uint64) uint64 { + if id <= t.evictCount { + panic(fmt.Sprintf("id (%v) <= evictCount (%v)", id, t.evictCount)) + } + k := id - t.evictCount - 1 // convert id to an index t.ents[k] + if t != staticTable { + return uint64(t.len()) - k // dynamic table + } + return k + 1 } // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B -var staticTable = [...]HeaderField{ - pair(":authority", ""), // index 1 (1-based) - pair(":method", "GET"), - pair(":method", "POST"), - pair(":path", "/"), - pair(":path", "/index.html"), - pair(":scheme", "http"), - pair(":scheme", "https"), - pair(":status", "200"), - pair(":status", "204"), - pair(":status", "206"), - pair(":status", "304"), - pair(":status", "400"), - pair(":status", "404"), - pair(":status", "500"), - pair("accept-charset", ""), - pair("accept-encoding", "gzip, deflate"), - pair("accept-language", ""), - pair("accept-ranges", ""), - pair("accept", ""), - pair("access-control-allow-origin", ""), - pair("age", ""), - pair("allow", ""), - pair("authorization", ""), - pair("cache-control", ""), - pair("content-disposition", ""), - pair("content-encoding", ""), - pair("content-language", ""), - pair("content-length", ""), - pair("content-location", ""), - pair("content-range", ""), - pair("content-type", ""), - pair("cookie", ""), - pair("date", ""), - pair("etag", ""), - pair("expect", ""), - pair("expires", ""), - pair("from", ""), - pair("host", ""), - pair("if-match", ""), - pair("if-modified-since", ""), - pair("if-none-match", ""), - pair("if-range", ""), - pair("if-unmodified-since", ""), - pair("last-modified", ""), - pair("link", ""), - pair("location", ""), - pair("max-forwards", ""), - pair("proxy-authenticate", ""), - pair("proxy-authorization", ""), - pair("range", ""), - pair("referer", ""), - pair("refresh", ""), - pair("retry-after", ""), - pair("server", ""), - pair("set-cookie", ""), - pair("strict-transport-security", ""), - pair("transfer-encoding", ""), - pair("user-agent", ""), - pair("vary", ""), - pair("via", ""), - pair("www-authenticate", ""), +var staticTable = newStaticTable() +var staticTableEntries = [...]HeaderField{ + {Name: ":authority"}, + {Name: ":method", Value: "GET"}, + {Name: ":method", Value: "POST"}, + {Name: ":path", Value: "/"}, + {Name: ":path", Value: "/index.html"}, + {Name: ":scheme", Value: "http"}, + {Name: ":scheme", Value: "https"}, + {Name: ":status", Value: "200"}, + {Name: ":status", Value: "204"}, + {Name: ":status", Value: "206"}, + {Name: ":status", Value: "304"}, + {Name: ":status", Value: "400"}, + {Name: ":status", Value: "404"}, + {Name: ":status", Value: "500"}, + {Name: "accept-charset"}, + {Name: "accept-encoding", Value: "gzip, deflate"}, + {Name: "accept-language"}, + {Name: "accept-ranges"}, + {Name: "accept"}, + {Name: "access-control-allow-origin"}, + {Name: "age"}, + {Name: "allow"}, + {Name: "authorization"}, + {Name: "cache-control"}, + {Name: "content-disposition"}, + {Name: "content-encoding"}, + {Name: "content-language"}, + {Name: "content-length"}, + {Name: "content-location"}, + {Name: "content-range"}, + {Name: "content-type"}, + {Name: "cookie"}, + {Name: "date"}, + {Name: "etag"}, + {Name: "expect"}, + {Name: "expires"}, + {Name: "from"}, + {Name: "host"}, + {Name: "if-match"}, + {Name: "if-modified-since"}, + {Name: "if-none-match"}, + {Name: "if-range"}, + {Name: "if-unmodified-since"}, + {Name: "last-modified"}, + {Name: "link"}, + {Name: "location"}, + {Name: "max-forwards"}, + {Name: "proxy-authenticate"}, + {Name: "proxy-authorization"}, + {Name: "range"}, + {Name: "referer"}, + {Name: "refresh"}, + {Name: "retry-after"}, + {Name: "server"}, + {Name: "set-cookie"}, + {Name: "strict-transport-security"}, + {Name: "transfer-encoding"}, + {Name: "user-agent"}, + {Name: "vary"}, + {Name: "via"}, + {Name: "www-authenticate"}, +} + +func newStaticTable() *headerFieldTable { + t := &headerFieldTable{} + t.init() + for _, e := range staticTableEntries[:] { + t.addEntry(e) + } + return t } var huffmanCodes = [256]uint32{ diff --git a/components/cli/vendor/golang.org/x/net/http2/not_go16.go b/components/cli/vendor/golang.org/x/net/http2/not_go16.go index efd2e1282c..508cebcc4d 100644 --- a/components/cli/vendor/golang.org/x/net/http2/not_go16.go +++ b/components/cli/vendor/golang.org/x/net/http2/not_go16.go @@ -7,7 +7,6 @@ package http2 import ( - "crypto/tls" "net/http" "time" ) @@ -20,27 +19,3 @@ func transportExpectContinueTimeout(t1 *http.Transport) time.Duration { return 0 } - -// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec. -func isBadCipher(cipher uint16) bool { - switch cipher { - case tls.TLS_RSA_WITH_RC4_128_SHA, - tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, - tls.TLS_RSA_WITH_AES_128_CBC_SHA, - tls.TLS_RSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, - tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - // Reject cipher suites from Appendix A. - // "This list includes those cipher suites that do not - // offer an ephemeral key exchange and those that are - // based on the TLS null, stream or block cipher type" - return true - default: - return false - } -} diff --git a/components/cli/vendor/golang.org/x/net/http2/not_go19.go b/components/cli/vendor/golang.org/x/net/http2/not_go19.go new file mode 100644 index 0000000000..5ae07726b7 --- /dev/null +++ b/components/cli/vendor/golang.org/x/net/http2/not_go19.go @@ -0,0 +1,16 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.9 + +package http2 + +import ( + "net/http" +) + +func configureServer19(s *http.Server, conf *Server) error { + // not supported prior to go1.9 + return nil +} diff --git a/components/cli/vendor/golang.org/x/net/http2/pipe.go b/components/cli/vendor/golang.org/x/net/http2/pipe.go index 53b7a1daf6..0b9848be8c 100644 --- a/components/cli/vendor/golang.org/x/net/http2/pipe.go +++ b/components/cli/vendor/golang.org/x/net/http2/pipe.go @@ -10,13 +10,13 @@ import ( "sync" ) -// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like +// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like // io.Pipe except there are no PipeReader/PipeWriter halves, and the // underlying buffer is an interface. (io.Pipe is always unbuffered) type pipe struct { mu sync.Mutex - c sync.Cond // c.L lazily initialized to &p.mu - b pipeBuffer + c sync.Cond // c.L lazily initialized to &p.mu + b pipeBuffer // nil when done reading err error // read error once empty. non-nil means closed. breakErr error // immediate read error (caller doesn't see rest of b) donec chan struct{} // closed on error @@ -32,6 +32,9 @@ type pipeBuffer interface { func (p *pipe) Len() int { p.mu.Lock() defer p.mu.Unlock() + if p.b == nil { + return 0 + } return p.b.Len() } @@ -55,6 +58,7 @@ func (p *pipe) Read(d []byte) (n int, err error) { p.readFn() // e.g. copy trailers p.readFn = nil // not sticky like p.err } + p.b = nil return 0, p.err } p.c.Wait() @@ -75,6 +79,9 @@ func (p *pipe) Write(d []byte) (n int, err error) { if p.err != nil { return 0, errClosedPipeWrite } + if p.breakErr != nil { + return len(d), nil // discard when there is no reader + } return p.b.Write(d) } @@ -109,6 +116,9 @@ func (p *pipe) closeWithError(dst *error, err error, fn func()) { return } p.readFn = fn + if dst == &p.breakErr { + p.b = nil + } *dst = err p.closeDoneLocked() } diff --git a/components/cli/vendor/golang.org/x/net/http2/server.go b/components/cli/vendor/golang.org/x/net/http2/server.go index 3c6b90ccd5..7367b31c57 100644 --- a/components/cli/vendor/golang.org/x/net/http2/server.go +++ b/components/cli/vendor/golang.org/x/net/http2/server.go @@ -110,9 +110,41 @@ type Server struct { // activity for the purposes of IdleTimeout. IdleTimeout time.Duration + // MaxUploadBufferPerConnection is the size of the initial flow + // control window for each connections. The HTTP/2 spec does not + // allow this to be smaller than 65535 or larger than 2^32-1. + // If the value is outside this range, a default value will be + // used instead. + MaxUploadBufferPerConnection int32 + + // MaxUploadBufferPerStream is the size of the initial flow control + // window for each stream. The HTTP/2 spec does not allow this to + // be larger than 2^32-1. If the value is zero or larger than the + // maximum, a default value will be used instead. + MaxUploadBufferPerStream int32 + // NewWriteScheduler constructs a write scheduler for a connection. // If nil, a default scheduler is chosen. NewWriteScheduler func() WriteScheduler + + // Internal state. This is a pointer (rather than embedded directly) + // so that we don't embed a Mutex in this struct, which will make the + // struct non-copyable, which might break some callers. + state *serverInternalState +} + +func (s *Server) initialConnRecvWindowSize() int32 { + if s.MaxUploadBufferPerConnection > initialWindowSize { + return s.MaxUploadBufferPerConnection + } + return 1 << 20 +} + +func (s *Server) initialStreamRecvWindowSize() int32 { + if s.MaxUploadBufferPerStream > 0 { + return s.MaxUploadBufferPerStream + } + return 1 << 20 } func (s *Server) maxReadFrameSize() uint32 { @@ -129,6 +161,40 @@ func (s *Server) maxConcurrentStreams() uint32 { return defaultMaxStreams } +type serverInternalState struct { + mu sync.Mutex + activeConns map[*serverConn]struct{} +} + +func (s *serverInternalState) registerConn(sc *serverConn) { + if s == nil { + return // if the Server was used without calling ConfigureServer + } + s.mu.Lock() + s.activeConns[sc] = struct{}{} + s.mu.Unlock() +} + +func (s *serverInternalState) unregisterConn(sc *serverConn) { + if s == nil { + return // if the Server was used without calling ConfigureServer + } + s.mu.Lock() + delete(s.activeConns, sc) + s.mu.Unlock() +} + +func (s *serverInternalState) startGracefulShutdown() { + if s == nil { + return // if the Server was used without calling ConfigureServer + } + s.mu.Lock() + for sc := range s.activeConns { + sc.startGracefulShutdown() + } + s.mu.Unlock() +} + // ConfigureServer adds HTTP/2 support to a net/http Server. // // The configuration conf may be nil. @@ -141,9 +207,13 @@ func ConfigureServer(s *http.Server, conf *Server) error { if conf == nil { conf = new(Server) } + conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})} if err := configureServer18(s, conf); err != nil { return err } + if err := configureServer19(s, conf); err != nil { + return err + } if s.TLSConfig == nil { s.TLSConfig = new(tls.Config) @@ -255,35 +325,37 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { defer cancel() sc := &serverConn{ - srv: s, - hs: opts.baseConfig(), - conn: c, - baseCtx: baseCtx, - remoteAddrStr: c.RemoteAddr().String(), - bw: newBufferedWriter(c), - handler: opts.handler(), - streams: make(map[uint32]*stream), - readFrameCh: make(chan readFrameResult), - wantWriteFrameCh: make(chan FrameWriteRequest, 8), - wantStartPushCh: make(chan startPushRequest, 8), - wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync - bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way - doneServing: make(chan struct{}), - clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value" - advMaxStreams: s.maxConcurrentStreams(), - initialWindowSize: initialWindowSize, - maxFrameSize: initialMaxFrameSize, - headerTableSize: initialHeaderTableSize, - serveG: newGoroutineLock(), - pushEnabled: true, + srv: s, + hs: opts.baseConfig(), + conn: c, + baseCtx: baseCtx, + remoteAddrStr: c.RemoteAddr().String(), + bw: newBufferedWriter(c), + handler: opts.handler(), + streams: make(map[uint32]*stream), + readFrameCh: make(chan readFrameResult), + wantWriteFrameCh: make(chan FrameWriteRequest, 8), + serveMsgCh: make(chan interface{}, 8), + wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync + bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way + doneServing: make(chan struct{}), + clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value" + advMaxStreams: s.maxConcurrentStreams(), + initialStreamSendWindowSize: initialWindowSize, + maxFrameSize: initialMaxFrameSize, + headerTableSize: initialHeaderTableSize, + serveG: newGoroutineLock(), + pushEnabled: true, } + s.state.registerConn(sc) + defer s.state.unregisterConn(sc) + // The net/http package sets the write deadline from the // http.Server.WriteTimeout during the TLS handshake, but then - // passes the connection off to us with the deadline already - // set. Disarm it here so that it is not applied to additional - // streams opened on this connection. - // TODO: implement WriteTimeout fully. See Issue 18437. + // passes the connection off to us with the deadline already set. + // Write deadlines are set per stream in serverConn.newStream. + // Disarm the net.Conn write deadline here. if sc.hs.WriteTimeout != 0 { sc.conn.SetWriteDeadline(time.Time{}) } @@ -294,6 +366,9 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { sc.writeSched = NewRandomWriteScheduler() } + // These start at the RFC-specified defaults. If there is a higher + // configured value for inflow, that will be updated when we send a + // WINDOW_UPDATE shortly after sending SETTINGS. sc.flow.add(initialWindowSize) sc.inflow.add(initialWindowSize) sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) @@ -376,10 +451,9 @@ type serverConn struct { doneServing chan struct{} // closed when serverConn.serve ends readFrameCh chan readFrameResult // written by serverConn.readFrames wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve - wantStartPushCh chan startPushRequest // from handlers -> serve wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes bodyReadCh chan bodyReadMsg // from handlers -> serve - testHookCh chan func(int) // code to run on the serve loop + serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop flow flow // conn-wide (not stream-specific) outbound flow control inflow flow // conn-wide inbound flow control tlsState *tls.ConnectionState // shared by all handlers, like net/http @@ -387,38 +461,39 @@ type serverConn struct { writeSched WriteScheduler // Everything following is owned by the serve loop; use serveG.check(): - serveG goroutineLock // used to verify funcs are on serve() - pushEnabled bool - sawFirstSettings bool // got the initial SETTINGS frame after the preface - needToSendSettingsAck bool - unackedSettings int // how many SETTINGS have we sent without ACKs? - clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit) - advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client - curClientStreams uint32 // number of open streams initiated by the client - curPushedStreams uint32 // number of open streams initiated by server push - maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests - maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes - streams map[uint32]*stream - initialWindowSize int32 - maxFrameSize int32 - headerTableSize uint32 - peerMaxHeaderListSize uint32 // zero means unknown (default) - canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case - writingFrame bool // started writing a frame (on serve goroutine or separate) - writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh - needsFrameFlush bool // last frame write wasn't a flush - inGoAway bool // we've started to or sent GOAWAY - inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop - needToSendGoAway bool // we need to schedule a GOAWAY frame write - goAwayCode ErrCode - shutdownTimerCh <-chan time.Time // nil until used - shutdownTimer *time.Timer // nil until used - idleTimer *time.Timer // nil if unused - idleTimerCh <-chan time.Time // nil if unused + serveG goroutineLock // used to verify funcs are on serve() + pushEnabled bool + sawFirstSettings bool // got the initial SETTINGS frame after the preface + needToSendSettingsAck bool + unackedSettings int // how many SETTINGS have we sent without ACKs? + clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit) + advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client + curClientStreams uint32 // number of open streams initiated by the client + curPushedStreams uint32 // number of open streams initiated by server push + maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests + maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes + streams map[uint32]*stream + initialStreamSendWindowSize int32 + maxFrameSize int32 + headerTableSize uint32 + peerMaxHeaderListSize uint32 // zero means unknown (default) + canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case + writingFrame bool // started writing a frame (on serve goroutine or separate) + writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh + needsFrameFlush bool // last frame write wasn't a flush + inGoAway bool // we've started to or sent GOAWAY + inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop + needToSendGoAway bool // we need to schedule a GOAWAY frame write + goAwayCode ErrCode + shutdownTimer *time.Timer // nil until used + idleTimer *time.Timer // nil if unused // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer hpackEncoder *hpack.Encoder + + // Used by startGracefulShutdown. + shutdownOnce sync.Once } func (sc *serverConn) maxHeaderListSize() uint32 { @@ -463,10 +538,10 @@ type stream struct { numTrailerValues int64 weight uint8 state streamState - resetQueued bool // RST_STREAM queued for write; set by sc.resetStream - gotTrailerHeader bool // HEADER frame for trailers was seen - wroteHeaders bool // whether we wrote headers (not status 100) - reqBuf []byte // if non-nil, body pipe buffer to return later at EOF + resetQueued bool // RST_STREAM queued for write; set by sc.resetStream + gotTrailerHeader bool // HEADER frame for trailers was seen + wroteHeaders bool // whether we wrote headers (not status 100) + writeDeadline *time.Timer // nil if unused trailer http.Header // accumulated trailers reqTrailer http.Header // handler's Request.Trailer @@ -696,48 +771,48 @@ func (sc *serverConn) serve() { {SettingMaxFrameSize, sc.srv.maxReadFrameSize()}, {SettingMaxConcurrentStreams, sc.advMaxStreams}, {SettingMaxHeaderListSize, sc.maxHeaderListSize()}, - - // TODO: more actual settings, notably - // SettingInitialWindowSize, but then we also - // want to bump up the conn window size the - // same amount here right after the settings + {SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())}, }, }) sc.unackedSettings++ + // Each connection starts with intialWindowSize inflow tokens. + // If a higher value is configured, we add more tokens. + if diff := sc.srv.initialConnRecvWindowSize() - initialWindowSize; diff > 0 { + sc.sendWindowUpdate(nil, int(diff)) + } + if err := sc.readPreface(); err != nil { sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err) return } // Now that we've got the preface, get us out of the - // "StateNew" state. We can't go directly to idle, though. + // "StateNew" state. We can't go directly to idle, though. // Active means we read some data and anticipate a request. We'll // do another Active when we get a HEADERS frame. sc.setConnState(http.StateActive) sc.setConnState(http.StateIdle) if sc.srv.IdleTimeout != 0 { - sc.idleTimer = time.NewTimer(sc.srv.IdleTimeout) + sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() - sc.idleTimerCh = sc.idleTimer.C - } - - var gracefulShutdownCh <-chan struct{} - if sc.hs != nil { - gracefulShutdownCh = h1ServerShutdownChan(sc.hs) } go sc.readFrames() // closed by defer sc.conn.Close above - settingsTimer := time.NewTimer(firstSettingsTimeout) + settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer) + defer settingsTimer.Stop() + loopNum := 0 for { loopNum++ select { case wr := <-sc.wantWriteFrameCh: + if se, ok := wr.write.(StreamError); ok { + sc.resetStream(se) + break + } sc.writeFrame(wr) - case spr := <-sc.wantStartPushCh: - sc.startPush(spr) case res := <-sc.wroteFrameCh: sc.wroteFrame(res) case res := <-sc.readFrameCh: @@ -745,26 +820,37 @@ func (sc *serverConn) serve() { return } res.readMore() - if settingsTimer.C != nil { + if settingsTimer != nil { settingsTimer.Stop() - settingsTimer.C = nil + settingsTimer = nil } case m := <-sc.bodyReadCh: sc.noteBodyRead(m.st, m.n) - case <-settingsTimer.C: - sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr()) - return - case <-gracefulShutdownCh: - gracefulShutdownCh = nil - sc.startGracefulShutdown() - case <-sc.shutdownTimerCh: - sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) - return - case <-sc.idleTimerCh: - sc.vlogf("connection is idle") - sc.goAway(ErrCodeNo) - case fn := <-sc.testHookCh: - fn(loopNum) + case msg := <-sc.serveMsgCh: + switch v := msg.(type) { + case func(int): + v(loopNum) // for testing + case *serverMessage: + switch v { + case settingsTimerMsg: + sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr()) + return + case idleTimerMsg: + sc.vlogf("connection is idle") + sc.goAway(ErrCodeNo) + case shutdownTimerMsg: + sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) + return + case gracefulShutdownMsg: + sc.startGracefulShutdownInternal() + default: + panic("unknown timer") + } + case *startPushRequest: + sc.startPush(v) + default: + panic(fmt.Sprintf("unexpected type %T", v)) + } } if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame { @@ -773,6 +859,36 @@ func (sc *serverConn) serve() { } } +func (sc *serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) { + select { + case <-sc.doneServing: + case <-sharedCh: + close(privateCh) + } +} + +type serverMessage int + +// Message values sent to serveMsgCh. +var ( + settingsTimerMsg = new(serverMessage) + idleTimerMsg = new(serverMessage) + shutdownTimerMsg = new(serverMessage) + gracefulShutdownMsg = new(serverMessage) +) + +func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) } +func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) } +func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) } + +func (sc *serverConn) sendServeMsg(msg interface{}) { + sc.serveG.checkNotOn() // NOT + select { + case sc.serveMsgCh <- msg: + case <-sc.doneServing: + } +} + // readPreface reads the ClientPreface greeting from the peer // or returns an error on timeout or an invalid greeting. func (sc *serverConn) readPreface() error { @@ -1014,7 +1130,11 @@ func (sc *serverConn) wroteFrame(res frameWriteResult) { // stateClosed after the RST_STREAM frame is // written. st.state = stateHalfClosedLocal - sc.resetStream(streamError(st.id, ErrCodeCancel)) + // Section 8.1: a server MAY request that the client abort + // transmission of a request without error by sending a + // RST_STREAM with an error code of NO_ERROR after sending + // a complete response. + sc.resetStream(streamError(st.id, ErrCodeNo)) case stateHalfClosedRemote: sc.closeStream(st, errHandlerComplete) } @@ -1086,10 +1206,19 @@ func (sc *serverConn) scheduleFrameWrite() { sc.inFrameScheduleLoop = false } -// startGracefulShutdown sends a GOAWAY with ErrCodeNo to tell the -// client we're gracefully shutting down. The connection isn't closed -// until all current streams are done. +// startGracefulShutdown gracefully shuts down a connection. This +// sends GOAWAY with ErrCodeNo to tell the client we're gracefully +// shutting down. The connection isn't closed until all current +// streams are done. +// +// startGracefulShutdown returns immediately; it does not wait until +// the connection has shut down. func (sc *serverConn) startGracefulShutdown() { + sc.serveG.checkNotOn() // NOT + sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) }) +} + +func (sc *serverConn) startGracefulShutdownInternal() { sc.goAwayIn(ErrCodeNo, 0) } @@ -1121,8 +1250,7 @@ func (sc *serverConn) goAwayIn(code ErrCode, forceCloseIn time.Duration) { func (sc *serverConn) shutDownIn(d time.Duration) { sc.serveG.check() - sc.shutdownTimer = time.NewTimer(d) - sc.shutdownTimerCh = sc.shutdownTimer.C + sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer) } func (sc *serverConn) resetStream(se StreamError) { @@ -1305,6 +1433,9 @@ func (sc *serverConn) closeStream(st *stream, err error) { panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state)) } st.state = stateClosed + if st.writeDeadline != nil { + st.writeDeadline.Stop() + } if st.isPushed() { sc.curPushedStreams-- } else { @@ -1317,7 +1448,7 @@ func (sc *serverConn) closeStream(st *stream, err error) { sc.idleTimer.Reset(sc.srv.IdleTimeout) } if h1ServerKeepAlivesDisabled(sc.hs) { - sc.startGracefulShutdown() + sc.startGracefulShutdownInternal() } } if p := st.body; p != nil { @@ -1395,9 +1526,9 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error { // adjust the size of all stream flow control windows that it // maintains by the difference between the new value and the // old value." - old := sc.initialWindowSize - sc.initialWindowSize = int32(val) - growth := sc.initialWindowSize - old // may be negative + old := sc.initialStreamSendWindowSize + sc.initialStreamSendWindowSize = int32(val) + growth := int32(val) - old // may be negative for _, st := range sc.streams { if !st.flow.add(growth) { // 6.9.2 Initial Flow Control Window Size @@ -1504,7 +1635,7 @@ func (sc *serverConn) processGoAway(f *GoAwayFrame) error { } else { sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f) } - sc.startGracefulShutdown() + sc.startGracefulShutdownInternal() // http://tools.ietf.org/html/rfc7540#section-6.8 // We should not create any new streams, which means we should disable push. sc.pushEnabled = false @@ -1543,6 +1674,12 @@ func (st *stream) copyTrailersToHandlerRequest() { } } +// onWriteTimeout is run on its own goroutine (from time.AfterFunc) +// when the stream's WriteTimeout has fired. +func (st *stream) onWriteTimeout() { + st.sc.writeFrameFromHandler(FrameWriteRequest{write: streamError(st.id, ErrCodeInternal)}) +} + func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { sc.serveG.check() id := f.StreamID @@ -1719,9 +1856,12 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream } st.cw.Init() st.flow.conn = &sc.flow // link to conn-level counter - st.flow.add(sc.initialWindowSize) - st.inflow.conn = &sc.inflow // link to conn-level counter - st.inflow.add(initialWindowSize) // TODO: update this when we send a higher initial window size in the initial settings + st.flow.add(sc.initialStreamSendWindowSize) + st.inflow.conn = &sc.inflow // link to conn-level counter + st.inflow.add(sc.srv.initialStreamRecvWindowSize()) + if sc.hs.WriteTimeout != 0 { + st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) + } sc.streams[id] = st sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID}) @@ -1785,16 +1925,14 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res return nil, nil, err } if bodyOpen { - st.reqBuf = getRequestBodyBuf() - req.Body.(*requestBody).pipe = &pipe{ - b: &fixedBuffer{buf: st.reqBuf}, - } - if vv, ok := rp.header["Content-Length"]; ok { req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64) } else { req.ContentLength = -1 } + req.Body.(*requestBody).pipe = &pipe{ + b: &dataBuffer{expected: req.ContentLength}, + } } return rw, req, nil } @@ -1890,24 +2028,6 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r return rw, req, nil } -var reqBodyCache = make(chan []byte, 8) - -func getRequestBodyBuf() []byte { - select { - case b := <-reqBodyCache: - return b - default: - return make([]byte, initialWindowSize) - } -} - -func putRequestBodyBuf(b []byte) { - select { - case reqBodyCache <- b: - default: - } -} - // Run on its own goroutine. func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { didPanic := true @@ -2003,12 +2123,6 @@ func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) { case <-sc.doneServing: } } - if err == io.EOF { - if buf := st.reqBuf; buf != nil { - st.reqBuf = nil // shouldn't matter; field unused by other - putRequestBodyBuf(buf) - } - } } func (sc *serverConn) noteBodyRead(st *stream, n int) { @@ -2103,8 +2217,8 @@ func (b *requestBody) Read(p []byte) (n int, err error) { return } -// responseWriter is the http.ResponseWriter implementation. It's -// intentionally small (1 pointer wide) to minimize garbage. The +// responseWriter is the http.ResponseWriter implementation. It's +// intentionally small (1 pointer wide) to minimize garbage. The // responseWriterState pointer inside is zeroed at the end of a // request (in handlerDone) and calls on the responseWriter thereafter // simply crash (caller's mistake), but the much larger responseWriterState @@ -2278,7 +2392,7 @@ const TrailerPrefix = "Trailer:" // says you SHOULD (but not must) predeclare any trailers in the // header, the official ResponseWriter rules said trailers in Go must // be predeclared, and then we reuse the same ResponseWriter.Header() -// map to mean both Headers and Trailers. When it's time to write the +// map to mean both Headers and Trailers. When it's time to write the // Trailers, we pick out the fields of Headers that were declared as // trailers. That worked for a while, until we found the first major // user of Trailers in the wild: gRPC (using them only over http2), @@ -2514,7 +2628,7 @@ func (w *responseWriter) push(target string, opts pushOptions) error { return fmt.Errorf("method %q must be GET or HEAD", opts.Method) } - msg := startPushRequest{ + msg := &startPushRequest{ parent: st, method: opts.Method, url: u, @@ -2527,7 +2641,7 @@ func (w *responseWriter) push(target string, opts pushOptions) error { return errClientDisconnected case <-st.cw: return errStreamClosed - case sc.wantStartPushCh <- msg: + case sc.serveMsgCh <- msg: } select { @@ -2549,7 +2663,7 @@ type startPushRequest struct { done chan error } -func (sc *serverConn) startPush(msg startPushRequest) { +func (sc *serverConn) startPush(msg *startPushRequest) { sc.serveG.check() // http://tools.ietf.org/html/rfc7540#section-6.6. @@ -2588,7 +2702,7 @@ func (sc *serverConn) startPush(msg startPushRequest) { // A server that is unable to establish a new stream identifier can send a GOAWAY // frame so that the client is forced to open a new connection for new streams. if sc.maxPushPromiseID+2 >= 1<<31 { - sc.startGracefulShutdown() + sc.startGracefulShutdownInternal() return 0, ErrPushLimitReached } sc.maxPushPromiseID += 2 @@ -2713,31 +2827,6 @@ var badTrailer = map[string]bool{ "Www-Authenticate": true, } -// h1ServerShutdownChan returns a channel that will be closed when the -// provided *http.Server wants to shut down. -// -// This is a somewhat hacky way to get at http1 innards. It works -// when the http2 code is bundled into the net/http package in the -// standard library. The alternatives ended up making the cmd/go tool -// depend on http Servers. This is the lightest option for now. -// This is tested via the TestServeShutdown* tests in net/http. -func h1ServerShutdownChan(hs *http.Server) <-chan struct{} { - if fn := testh1ServerShutdownChan; fn != nil { - return fn(hs) - } - var x interface{} = hs - type I interface { - getDoneChan() <-chan struct{} - } - if hs, ok := x.(I); ok { - return hs.getDoneChan() - } - return nil -} - -// optional test hook for h1ServerShutdownChan. -var testh1ServerShutdownChan func(hs *http.Server) <-chan struct{} - // h1ServerKeepAlivesDisabled reports whether hs has its keep-alives // disabled. See comments on h1ServerShutdownChan above for why // the code is written this way. diff --git a/components/cli/vendor/golang.org/x/net/http2/transport.go b/components/cli/vendor/golang.org/x/net/http2/transport.go index 0c7e859db1..3a85f25a20 100644 --- a/components/cli/vendor/golang.org/x/net/http2/transport.go +++ b/components/cli/vendor/golang.org/x/net/http2/transport.go @@ -575,7 +575,7 @@ func (cc *ClientConn) canTakeNewRequestLocked() bool { cc.nextStreamID < math.MaxInt32 } -// onIdleTimeout is called from a time.AfterFunc goroutine. It will +// onIdleTimeout is called from a time.AfterFunc goroutine. It will // only be called when we're idle, but because we're coming from a new // goroutine, there could be a new request coming in at the same time, // so this simply calls the synchronized closeIfIdle to shut down this @@ -809,8 +809,8 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { // 2xx, however, then assume the server DOES potentially // want our body (e.g. full-duplex streaming: // golang.org/issue/13444). If it turns out the server - // doesn't, they'll RST_STREAM us soon enough. This is a - // heuristic to avoid adding knobs to Transport. Hopefully + // doesn't, they'll RST_STREAM us soon enough. This is a + // heuristic to avoid adding knobs to Transport. Hopefully // we can keep it. bodyWriter.cancel() cs.abortRequestBodyWrite(errStopReqBodyWrite) @@ -1528,8 +1528,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra return res, nil } - buf := new(bytes.Buffer) // TODO(bradfitz): recycle this garbage - cs.bufPipe = pipe{b: buf} + cs.bufPipe = pipe{b: &dataBuffer{expected: res.ContentLength}} cs.bytesRemain = res.ContentLength res.Body = transportResponseBody{cs} go cs.awaitRequestCancel(cs.req) @@ -1656,6 +1655,7 @@ func (b transportResponseBody) Close() error { cc.wmu.Lock() if !serverSentStreamEnd { cc.fr.WriteRSTStream(cs.ID, ErrCodeCancel) + cs.didReset = true } // Return connection-level flow control. if unread > 0 { @@ -1703,12 +1703,6 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { return nil } if f.Length > 0 { - if len(data) > 0 && cs.bufPipe.b == nil { - // Data frame after it's already closed? - cc.logf("http2: Transport received DATA frame for closed stream; closing connection") - return ConnectionError(ErrCodeProtocol) - } - // Check connection-level flow control. cc.mu.Lock() if cs.inflow.available() >= int32(f.Length) { diff --git a/components/cli/vendor/golang.org/x/net/http2/writesched_priority.go b/components/cli/vendor/golang.org/x/net/http2/writesched_priority.go index 01132721bd..848fed6ec7 100644 --- a/components/cli/vendor/golang.org/x/net/http2/writesched_priority.go +++ b/components/cli/vendor/golang.org/x/net/http2/writesched_priority.go @@ -53,7 +53,7 @@ type PriorityWriteSchedulerConfig struct { } // NewPriorityWriteScheduler constructs a WriteScheduler that schedules -// frames by following HTTP/2 priorities as described in RFC 7340 Section 5.3. +// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3. // If cfg is nil, default options are used. func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler { if cfg == nil { diff --git a/components/cli/vendor/golang.org/x/net/idna/idna.go b/components/cli/vendor/golang.org/x/net/idna/idna.go index 47466e947a..ee2dbda6d0 100644 --- a/components/cli/vendor/golang.org/x/net/idna/idna.go +++ b/components/cli/vendor/golang.org/x/net/idna/idna.go @@ -1,4 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. // Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style @@ -39,27 +39,24 @@ import ( // error in the future. // I think Option 1 is best, but it is quite opinionated. -// ToASCII converts a domain or domain label to its ASCII form. For example, -// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and -// ToASCII("golang") is "golang". If an error is encountered it will return -// an error and a (partially) processed result. +// ToASCII is a wrapper for Punycode.ToASCII. func ToASCII(s string) (string, error) { - return Resolve.process(s, true) + return Punycode.process(s, true) } -// ToUnicode converts a domain or domain label to its Unicode form. For example, -// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and -// ToUnicode("golang") is "golang". If an error is encountered it will return -// an error and a (partially) processed result. +// ToUnicode is a wrapper for Punycode.ToUnicode. func ToUnicode(s string) (string, error) { - return NonTransitional.process(s, false) + return Punycode.process(s, false) } // An Option configures a Profile at creation time. type Option func(*options) -// Transitional sets a Profile to use the Transitional mapping as defined -// in UTS #46. +// Transitional sets a Profile to use the Transitional mapping as defined in UTS +// #46. This will cause, for example, "ß" to be mapped to "ss". Using the +// transitional mapping provides a compromise between IDNA2003 and IDNA2008 +// compatibility. It is used by most browsers when resolving domain names. This +// option is only meaningful if combined with MapForLookup. func Transitional(transitional bool) Option { return func(o *options) { o.transitional = true } } @@ -70,19 +67,93 @@ func VerifyDNSLength(verify bool) Option { return func(o *options) { o.verifyDNSLength = verify } } -// IgnoreSTD3Rules sets whether ASCII characters outside the A-Z, a-z, 0-9 and -// the hyphen should be allowed. By default this is not allowed, but IDNA2003, -// and as a consequence UTS #46, allows this to be overridden to support -// browsers that allow characters outside this range, for example a '_' (U+005F -// LOW LINE). See http://www.rfc- editor.org/std/std3.txt for more details. -func IgnoreSTD3Rules(ignore bool) Option { - return func(o *options) { o.ignoreSTD3Rules = ignore } +// ValidateLabels sets whether to check the mandatory label validation criteria +// as defined in Section 5.4 of RFC 5891. This includes testing for correct use +// of hyphens ('-'), normalization, validity of runes, and the context rules. +func ValidateLabels(enable bool) Option { + return func(o *options) { + // Don't override existing mappings, but set one that at least checks + // normalization if it is not set. + if o.mapping == nil && enable { + o.mapping = normalize + } + o.trie = trie + o.validateLabels = enable + o.fromPuny = validateFromPunycode + } +} + +// StrictDomainName limits the set of permissable ASCII characters to those +// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the +// hyphen). This is set by default for MapForLookup and ValidateForRegistration. +// +// This option is useful, for instance, for browsers that allow characters +// outside this range, for example a '_' (U+005F LOW LINE). See +// http://www.rfc-editor.org/std/std3.txt for more details This option +// corresponds to the UseSTD3ASCIIRules option in UTS #46. +func StrictDomainName(use bool) Option { + return func(o *options) { + o.trie = trie + o.useSTD3Rules = use + o.fromPuny = validateFromPunycode + } +} + +// NOTE: the following options pull in tables. The tables should not be linked +// in as long as the options are not used. + +// BidiRule enables the Bidi rule as defined in RFC 5893. Any application +// that relies on proper validation of labels should include this rule. +func BidiRule() Option { + return func(o *options) { o.bidirule = bidirule.ValidString } +} + +// ValidateForRegistration sets validation options to verify that a given IDN is +// properly formatted for registration as defined by Section 4 of RFC 5891. +func ValidateForRegistration() Option { + return func(o *options) { + o.mapping = validateRegistration + StrictDomainName(true)(o) + ValidateLabels(true)(o) + VerifyDNSLength(true)(o) + BidiRule()(o) + } +} + +// MapForLookup sets validation and mapping options such that a given IDN is +// transformed for domain name lookup according to the requirements set out in +// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894, +// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option +// to add this check. +// +// The mappings include normalization and mapping case, width and other +// compatibility mappings. +func MapForLookup() Option { + return func(o *options) { + o.mapping = validateAndMap + StrictDomainName(true)(o) + ValidateLabels(true)(o) + } } type options struct { transitional bool - ignoreSTD3Rules bool + useSTD3Rules bool + validateLabels bool verifyDNSLength bool + + trie *idnaTrie + + // fromPuny calls validation rules when converting A-labels to U-labels. + fromPuny func(p *Profile, s string) error + + // mapping implements a validation and mapping step as defined in RFC 5895 + // or UTS 46, tailored to, for example, domain registration or lookup. + mapping func(p *Profile, s string) (string, error) + + // bidirule, if specified, checks whether s conforms to the Bidi Rule + // defined in RFC 5893. + bidirule func(s string) bool } // A Profile defines the configuration of a IDNA mapper. @@ -97,8 +168,13 @@ func apply(o *options, opts []Option) { } // New creates a new Profile. -// With no options, the returned profile is the non-transitional profile as -// defined in UTS #46. +// +// With no options, the returned Profile is the most permissive and equals the +// Punycode Profile. Options can be passed to further restrict the Profile. The +// MapForLookup and ValidateForRegistration options set a collection of options, +// for lookup and registration purposes respectively, which can be tailored by +// adding more fine-grained options, where later options override earlier +// options. func New(o ...Option) *Profile { p := &Profile{} apply(&p.options, o) @@ -132,33 +208,67 @@ func (p *Profile) String() string { } else { s = "NonTransitional" } - if p.ignoreSTD3Rules { - s += ":NoSTD3Rules" + if p.useSTD3Rules { + s += ":UseSTD3Rules" + } + if p.validateLabels { + s += ":ValidateLabels" + } + if p.verifyDNSLength { + s += ":VerifyDNSLength" } return s } var ( - // Resolve is the recommended profile for resolving domain names. - // The configuration of this profile may change over time. - Resolve = resolve + // Punycode is a Profile that does raw punycode processing with a minimum + // of validation. + Punycode *Profile = punycode + + // Lookup is the recommended profile for looking up domain names, according + // to Section 5 of RFC 5891. The exact configuration of this profile may + // change over time. + Lookup *Profile = lookup // Display is the recommended profile for displaying domain names. // The configuration of this profile may change over time. - Display = display + Display *Profile = display - // NonTransitional defines a profile that implements the Transitional - // mapping as defined in UTS #46 with no additional constraints. - NonTransitional = nonTransitional + // Registration is the recommended profile for checking whether a given + // IDN is valid for registration, according to Section 4 of RFC 5891. + Registration *Profile = registration - resolve = &Profile{options{transitional: true}} - display = &Profile{} - nonTransitional = &Profile{} + punycode = &Profile{} + lookup = &Profile{options{ + transitional: true, + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + display = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + registration = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + verifyDNSLength: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateRegistration, + bidirule: bidirule.ValidString, + }} // TODO: profiles - // V2008: strict IDNA2008 - // Register: recommended for approving domain names: nontransitional, but - // bundle or block deviation characters. + // Register: recommended for approving domain names: don't do any mappings + // but rather reject on invalid input. Bundle or block deviation characters. ) type labelError struct{ label, code_ string } @@ -178,12 +288,117 @@ func (e runeError) Error() string { // process implements the algorithm described in section 4 of UTS #46, // see http://www.unicode.org/reports/tr46. func (p *Profile) process(s string, toASCII bool) (string, error) { + var err error + if p.mapping != nil { + s, err = p.mapping(p, s) + } + // Remove leading empty labels. + for ; len(s) > 0 && s[0] == '.'; s = s[1:] { + } + // It seems like we should only create this error on ToASCII, but the + // UTS 46 conformance tests suggests we should always check this. + if err == nil && p.verifyDNSLength && s == "" { + err = &labelError{s, "A4"} + } + labels := labelIter{orig: s} + for ; !labels.done(); labels.next() { + label := labels.label() + if label == "" { + // Empty labels are not okay. The label iterator skips the last + // label if it is empty. + if err == nil && p.verifyDNSLength { + err = &labelError{s, "A4"} + } + continue + } + if strings.HasPrefix(label, acePrefix) { + u, err2 := decode(label[len(acePrefix):]) + if err2 != nil { + if err == nil { + err = err2 + } + // Spec says keep the old label. + continue + } + labels.set(u) + if err == nil && p.validateLabels { + err = p.fromPuny(p, u) + } + if err == nil { + // This should be called on NonTransitional, according to the + // spec, but that currently does not have any effect. Use the + // original profile to preserve options. + err = p.validateLabel(u) + } + } else if err == nil { + err = p.validateLabel(label) + } + } + if toASCII { + for labels.reset(); !labels.done(); labels.next() { + label := labels.label() + if !ascii(label) { + a, err2 := encode(acePrefix, label) + if err == nil { + err = err2 + } + label = a + labels.set(a) + } + n := len(label) + if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { + err = &labelError{label, "A4"} + } + } + } + s = labels.result() + if toASCII && p.verifyDNSLength && err == nil { + // Compute the length of the domain name minus the root label and its dot. + n := len(s) + if n > 0 && s[n-1] == '.' { + n-- + } + if len(s) < 1 || n > 253 { + err = &labelError{s, "A4"} + } + } + return s, err +} + +func normalize(p *Profile, s string) (string, error) { + return norm.NFC.String(s), nil +} + +func validateRegistration(p *Profile, s string) (string, error) { + if !norm.NFC.IsNormalString(s) { + return s, &labelError{s, "V1"} + } + var err error + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + i += sz + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + // TODO: handle the NV8 defined in the Unicode idna data set to allow + // for strict conformance to IDNA2008. + case valid, deviation: + case disallowed, mapped, unknown, ignored: + if err == nil { + r, _ := utf8.DecodeRuneInString(s[i:]) + err = runeError(r) + } + } + } + return s, err +} + +func validateAndMap(p *Profile, s string) (string, error) { var ( - b []byte - err error - k, i int + err error + b []byte + k int ) - for i < len(s) { + for i := 0; i < len(s); { v, sz := trie.lookupString(s[i:]) start := i i += sz @@ -220,71 +435,6 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { // TODO: the punycode converters require strings as input. s = string(b) } - // Remove leading empty labels - for ; len(s) > 0 && s[0] == '.'; s = s[1:] { - } - if s == "" { - return "", &labelError{s, "A4"} - } - labels := labelIter{orig: s} - for ; !labels.done(); labels.next() { - label := labels.label() - if label == "" { - // Empty labels are not okay. The label iterator skips the last - // label if it is empty. - if err == nil { - err = &labelError{s, "A4"} - } - continue - } - if strings.HasPrefix(label, acePrefix) { - u, err2 := decode(label[len(acePrefix):]) - if err2 != nil { - if err == nil { - err = err2 - } - // Spec says keep the old label. - continue - } - labels.set(u) - if err == nil { - err = p.validateFromPunycode(u) - } - if err == nil { - err = NonTransitional.validate(u) - } - } else if err == nil { - err = p.validate(label) - } - } - if toASCII { - for labels.reset(); !labels.done(); labels.next() { - label := labels.label() - if !ascii(label) { - a, err2 := encode(acePrefix, label) - if err == nil { - err = err2 - } - label = a - labels.set(a) - } - n := len(label) - if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { - err = &labelError{label, "A4"} - } - } - } - s = labels.result() - if toASCII && p.verifyDNSLength && err == nil { - // Compute the length of the domain name minus the root label and its dot. - n := len(s) - if n > 0 && s[n-1] == '.' { - n-- - } - if len(s) < 1 || n > 253 { - err = &labelError{s, "A4"} - } - } return s, err } @@ -354,13 +504,13 @@ const acePrefix = "xn--" func (p *Profile) simplify(cat category) category { switch cat { case disallowedSTD3Mapped: - if !p.ignoreSTD3Rules { + if p.useSTD3Rules { cat = disallowed } else { cat = mapped } case disallowedSTD3Valid: - if !p.ignoreSTD3Rules { + if p.useSTD3Rules { cat = disallowed } else { cat = valid @@ -376,7 +526,7 @@ func (p *Profile) simplify(cat category) category { return cat } -func (p *Profile) validateFromPunycode(s string) error { +func validateFromPunycode(p *Profile, s string) error { if !norm.NFC.IsNormalString(s) { return &labelError{s, "V1"} } @@ -452,9 +602,22 @@ var joinStates = [][numJoinTypes]joinState{ }, } -// validate validates the criteria from Section 4.1. Item 1, 4, and 6 are +// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are // already implicitly satisfied by the overall implementation. -func (p *Profile) validate(s string) error { +func (p *Profile) validateLabel(s string) error { + if s == "" { + if p.verifyDNSLength { + return &labelError{s, "A4"} + } + return nil + } + if p.bidirule != nil && !p.bidirule(s) { + return &labelError{s, "B"} + } + if !p.validateLabels { + return nil + } + trie := p.trie // p.validateLabels is only set if trie is set. if len(s) > 4 && s[2] == '-' && s[3] == '-' { return &labelError{s, "V2"} } @@ -467,9 +630,6 @@ func (p *Profile) validate(s string) error { if x.isModifier() { return &labelError{s, "V5"} } - if !bidirule.ValidString(s) { - return &labelError{s, "B"} - } // Quickly return in the absence of zero-width (non) joiners. if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { return nil diff --git a/components/cli/vendor/golang.org/x/net/idna/punycode.go b/components/cli/vendor/golang.org/x/net/idna/punycode.go index df3411a5bc..02c7d59af3 100644 --- a/components/cli/vendor/golang.org/x/net/idna/punycode.go +++ b/components/cli/vendor/golang.org/x/net/idna/punycode.go @@ -1,4 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. // Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/components/cli/vendor/golang.org/x/net/idna/tables.go b/components/cli/vendor/golang.org/x/net/idna/tables.go index 663d73c531..d2819345fc 100644 --- a/components/cli/vendor/golang.org/x/net/idna/tables.go +++ b/components/cli/vendor/golang.org/x/net/idna/tables.go @@ -1,6 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT - -// This file was generated by go generate; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. package idna diff --git a/components/cli/vendor/golang.org/x/net/idna/trie.go b/components/cli/vendor/golang.org/x/net/idna/trie.go index 6d37998f5d..c4ef847e7a 100644 --- a/components/cli/vendor/golang.org/x/net/idna/trie.go +++ b/components/cli/vendor/golang.org/x/net/idna/trie.go @@ -1,4 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. // Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style @@ -44,7 +44,8 @@ var idnaSparse = sparseBlocks{ offset: idnaSparseOffset[:], } -var trie = newIdnaTrie(0) +// Don't use newIdnaTrie to avoid unconditional linking in of the table. +var trie = &idnaTrie{} // lookup determines the type of block n and looks up the value for b. // For n < t.cutoff, the block is a simple lookup table. Otherwise, the block diff --git a/components/cli/vendor/golang.org/x/net/idna/trieval.go b/components/cli/vendor/golang.org/x/net/idna/trieval.go index d1b3256c8b..63cb03b59b 100644 --- a/components/cli/vendor/golang.org/x/net/idna/trieval.go +++ b/components/cli/vendor/golang.org/x/net/idna/trieval.go @@ -1,6 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT - -// This file was generated by go generate; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. package idna diff --git a/components/cli/vendor/golang.org/x/net/internal/timeseries/timeseries.go b/components/cli/vendor/golang.org/x/net/internal/timeseries/timeseries.go index 1119f34482..685f0e7ea2 100644 --- a/components/cli/vendor/golang.org/x/net/internal/timeseries/timeseries.go +++ b/components/cli/vendor/golang.org/x/net/internal/timeseries/timeseries.go @@ -371,7 +371,7 @@ func (ts *timeSeries) ComputeRange(start, finish time.Time, num int) []Observabl } } - // Failed to find a level that covers the desired range. So just + // Failed to find a level that covers the desired range. So just // extract from the last level, even if it doesn't cover the entire // desired range. ts.extract(ts.levels[len(ts.levels)-1], start, finish, num, results) diff --git a/components/cli/vendor/golang.org/x/net/proxy/socks5.go b/components/cli/vendor/golang.org/x/net/proxy/socks5.go index 9b9628239a..973f57f197 100644 --- a/components/cli/vendor/golang.org/x/net/proxy/socks5.go +++ b/components/cli/vendor/golang.org/x/net/proxy/socks5.go @@ -72,24 +72,28 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { if err != nil { return nil, err } - closeConn := &conn - defer func() { - if closeConn != nil { - (*closeConn).Close() - } - }() - - host, portStr, err := net.SplitHostPort(addr) - if err != nil { + if err := s.connect(conn, addr); err != nil { + conn.Close() return nil, err } + return conn, nil +} + +// connect takes an existing connection to a socks5 proxy server, +// and commands the server to extend that connection to target, +// which must be a canonical address with a host and port. +func (s *socks5) connect(conn net.Conn, target string) error { + host, portStr, err := net.SplitHostPort(target) + if err != nil { + return err + } port, err := strconv.Atoi(portStr) if err != nil { - return nil, errors.New("proxy: failed to parse port number: " + portStr) + return errors.New("proxy: failed to parse port number: " + portStr) } if port < 1 || port > 0xffff { - return nil, errors.New("proxy: port number out of range: " + portStr) + return errors.New("proxy: port number out of range: " + portStr) } // the size here is just an estimate @@ -103,17 +107,17 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { } if _, err := conn.Write(buf); err != nil { - return nil, errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return nil, errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if buf[0] != 5 { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) } if buf[1] == 0xff { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") } if buf[1] == socks5AuthPassword { @@ -125,15 +129,15 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { buf = append(buf, s.password...) if _, err := conn.Write(buf); err != nil { - return nil, errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return nil, errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if buf[1] != 0 { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") } } @@ -150,7 +154,7 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { buf = append(buf, ip...) } else { if len(host) > 255 { - return nil, errors.New("proxy: destination hostname too long: " + host) + return errors.New("proxy: destination hostname too long: " + host) } buf = append(buf, socks5Domain) buf = append(buf, byte(len(host))) @@ -159,11 +163,11 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { buf = append(buf, byte(port>>8), byte(port)) if _, err := conn.Write(buf); err != nil { - return nil, errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if _, err := io.ReadFull(conn, buf[:4]); err != nil { - return nil, errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } failure := "unknown error" @@ -172,7 +176,7 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { } if len(failure) > 0 { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) } bytesToDiscard := 0 @@ -184,11 +188,11 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { case socks5Domain: _, err := io.ReadFull(conn, buf[:1]) if err != nil { - return nil, errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } bytesToDiscard = int(buf[0]) default: - return nil, errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) + return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) } if cap(buf) < bytesToDiscard { @@ -197,14 +201,13 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { buf = buf[:bytesToDiscard] } if _, err := io.ReadFull(conn, buf); err != nil { - return nil, errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } // Also need to discard the port number if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return nil, errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } - closeConn = nil - return conn, nil + return nil } diff --git a/components/cli/vendor/golang.org/x/net/trace/trace.go b/components/cli/vendor/golang.org/x/net/trace/trace.go index 64f56a3736..3d9b646111 100644 --- a/components/cli/vendor/golang.org/x/net/trace/trace.go +++ b/components/cli/vendor/golang.org/x/net/trace/trace.go @@ -77,7 +77,6 @@ import ( "sync/atomic" "time" - "golang.org/x/net/context" "golang.org/x/net/internal/timeseries" ) @@ -271,18 +270,6 @@ type contextKeyT string var contextKey = contextKeyT("golang.org/x/net/trace.Trace") -// NewContext returns a copy of the parent context -// and associates it with a Trace. -func NewContext(ctx context.Context, tr Trace) context.Context { - return context.WithValue(ctx, contextKey, tr) -} - -// FromContext returns the Trace bound to the context, if any. -func FromContext(ctx context.Context) (tr Trace, ok bool) { - tr, ok = ctx.Value(contextKey).(Trace) - return -} - // Trace represents an active request. type Trace interface { // LazyLog adds x to the event log. It will be evaluated each time the diff --git a/components/cli/vendor/golang.org/x/net/trace/trace_go16.go b/components/cli/vendor/golang.org/x/net/trace/trace_go16.go new file mode 100644 index 0000000000..d608191185 --- /dev/null +++ b/components/cli/vendor/golang.org/x/net/trace/trace_go16.go @@ -0,0 +1,21 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.7 + +package trace + +import "golang.org/x/net/context" + +// NewContext returns a copy of the parent context +// and associates it with a Trace. +func NewContext(ctx context.Context, tr Trace) context.Context { + return context.WithValue(ctx, contextKey, tr) +} + +// FromContext returns the Trace bound to the context, if any. +func FromContext(ctx context.Context) (tr Trace, ok bool) { + tr, ok = ctx.Value(contextKey).(Trace) + return +} diff --git a/components/cli/vendor/golang.org/x/net/trace/trace_go17.go b/components/cli/vendor/golang.org/x/net/trace/trace_go17.go new file mode 100644 index 0000000000..df6e1fba7c --- /dev/null +++ b/components/cli/vendor/golang.org/x/net/trace/trace_go17.go @@ -0,0 +1,21 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7 + +package trace + +import "context" + +// NewContext returns a copy of the parent context +// and associates it with a Trace. +func NewContext(ctx context.Context, tr Trace) context.Context { + return context.WithValue(ctx, contextKey, tr) +} + +// FromContext returns the Trace bound to the context, if any. +func FromContext(ctx context.Context) (tr Trace, ok bool) { + tr, ok = ctx.Value(contextKey).(Trace) + return +} From 41ac0e363c29211fac8ab5384c37fababc0baf24 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Mon, 3 Jul 2017 16:49:25 +0200 Subject: [PATCH 09/62] Add bash completion for `docker config` command family This adds bash completion for - https://github.com/docker/cli/pull/45 - https://github.com/moby/moby/pull/32336 Signed-off-by: Harald Albers Upstream-commit: c40952b3058db3c6e44bca8c518d888b83878ce5 Component: cli --- components/cli/contrib/completion/bash/docker | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 03e0bc625a..ebfbd30bee 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -20,6 +20,7 @@ # For several commands, the amount of completions can be configured by # setting environment variables. # +# DOCKER_COMPLETION_SHOW_CONFIG_IDS # DOCKER_COMPLETION_SHOW_CONTAINER_IDS # DOCKER_COMPLETION_SHOW_NETWORK_IDS # DOCKER_COMPLETION_SHOW_NODE_IDS @@ -61,6 +62,42 @@ __docker_q() { docker ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@" } +# __docker_configs returns a list of configs. Additional options to +# `docker config ls` may be specified in order to filter the list, e.g. +# `__docker_configs --filter label=stage=production`. +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_CONFIG_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_configs() { + local format + if [ "$1" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "$1" = "--name" ] ; then + format='{{.Name}}' + shift + elif [ "$DOCKER_COMPLETION_SHOW_CONFIG_IDS" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' + fi + + __docker_q config ls --format "$format" "$@" +} + +# __docker_complete_configs applies completion of configs based on the current value +# of `$cur` or the value of the optional first option `--cur`, if given. +__docker_complete_configs() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_configs "$@")" -- "$current") ) +} + # __docker_containers returns a list of containers. Additional options to # `docker ps` may be specified in order to filter the list, e.g. # `__docker_containers --filter status=running` @@ -1096,6 +1133,117 @@ _docker_checkpoint_rm() { } +_docker_config() { + local subcommands=" + create + inspect + ls + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_config_create() { + case "$prev" in + --label|-l) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --label -l" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--label|-l') + if [ $cword -eq $((counter + 1)) ]; then + _filedir + fi + ;; + esac +} + +_docker_config_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) + ;; + *) + __docker_complete_configs + ;; + esac +} + +_docker_config_list() { + _docker_config_ls +} + +_docker_config_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_configs --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_configs --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_config_remove() { + _docker_config_rm +} + +_docker_config_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_configs + ;; + esac +} + + _docker_container() { local subcommands=" attach @@ -3146,6 +3294,7 @@ _docker_service_update_and_create() { if [ "$subcommand" = "create" ] ; then options_with_args="$options_with_args + --config --constraint --container-label --dns @@ -3162,6 +3311,10 @@ _docker_service_update_and_create() { " case "$prev" in + --config) + __docker_complete_configs + return + ;; --env-file) _filedir return @@ -3196,6 +3349,8 @@ _docker_service_update_and_create() { if [ "$subcommand" = "update" ] ; then options_with_args="$options_with_args --args + --config-add + --config-rm --constraint-add --constraint-rm --container-label-add @@ -3223,6 +3378,10 @@ _docker_service_update_and_create() { " case "$prev" in + --config-add|--config-rm) + __docker_complete_configs + return + ;; --group-add|--group-rm) COMPREPLY=( $(compgen -g -- "$cur") ) return @@ -4594,6 +4753,7 @@ _docker() { shopt -s extglob local management_commands=( + config container image network From 9bf76d9f743b1682b7e99efe5c2892f7c0680a12 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Mon, 3 Jul 2017 16:55:16 +0200 Subject: [PATCH 10/62] Add bash completion for `secret inspect --pretty` Signed-off-by: Harald Albers Upstream-commit: 211bd55ae736705a48908833a5e10491f613e255 Component: cli --- components/cli/contrib/completion/bash/docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index ebfbd30bee..e6f3063a29 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -4151,7 +4151,7 @@ _docker_secret_inspect() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) ;; *) __docker_complete_secrets From 9806677f30721674b78d774062f761efba3ef90e Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Mon, 3 Jul 2017 16:55:40 +0200 Subject: [PATCH 11/62] Refactor alias delegation in bash completion for `secret rm|remove` The completion logic should be implemented in the documented subcommands (ls, rm) and delegated to from the aliases (list, remove). For the rm|remove pair, this was implemented vice versa. Signed-off-by: Harald Albers Upstream-commit: d585e554d5e3a16f424cb3d92d0f7be342b8c7ca Component: cli --- components/cli/contrib/completion/bash/docker | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index e6f3063a29..15fdec5ac0 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -4195,6 +4195,10 @@ _docker_secret_ls() { } _docker_secret_remove() { + _docker_secret_rm +} + +_docker_secret_rm() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -4205,10 +4209,6 @@ _docker_secret_remove() { esac } -_docker_secret_rm() { - _docker_secret_remove -} - _docker_search() { From 9cc50cd1cbc3d77a9ba2a2dedaf699b57edf1f72 Mon Sep 17 00:00:00 2001 From: Shukui Yang Date: Tue, 11 Jul 2017 03:02:35 +0000 Subject: [PATCH 12/62] Vendor, update moby to d58ffa0364c04d03a8f25704d7f0489ee6cd9634 Fix docker cp dir with hard link, refer to https://github.com/moby/moby/pull/3. Signed-off-by: Shukui Yang Upstream-commit: a996206cedb04d3fa62723ae96905d83984aa9d0 Component: cli --- components/cli/vendor.conf | 2 +- .../docker/docker/api/types/swarm/swarm.go | 2 +- .../github.com/docker/docker/client/client.go | 11 +++++++--- .../docker/docker/client/container_attach.go | 20 +++++++++++++++++++ .../docker/docker/client/container_logs.go | 20 +++++++++++++++++++ .../docker/docker/client/container_wait.go | 4 ++-- .../github.com/docker/docker/opts/ip.go | 2 +- .../docker/docker/pkg/archive/archive.go | 2 +- .../docker/docker/pkg/archive/copy.go | 3 +++ .../docker/docker/pkg/symlink/fs.go | 2 +- .../docker/docker/pkg/system/path_windows.go | 2 +- .../github.com/docker/docker/pkg/system/rm.go | 2 +- .../docker/docker/pkg/templates/templates.go | 2 +- .../docker/docker/registry/config.go | 2 +- .../docker/docker/registry/endpoint_v1.go | 2 +- .../github.com/docker/docker/vendor.conf | 1 - .../github.com/docker/docker/volume/volume.go | 2 +- .../docker/docker/volume/volume_linux.go | 2 +- 18 files changed, 65 insertions(+), 18 deletions(-) diff --git a/components/cli/vendor.conf b/components/cli/vendor.conf index a212dd0a3a..7808518fd3 100755 --- a/components/cli/vendor.conf +++ b/components/cli/vendor.conf @@ -7,7 +7,7 @@ github.com/coreos/etcd 824277cb3a577a0e8c829ca9ec557b973fe06d20 github.com/cpuguy83/go-md2man a65d4d2de4d5f7c74868dfa9b202a3c8be315aaa github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621 -github.com/docker/docker 87df0e533b619c088091fd1e2310e92bb9a24822 +github.com/docker/docker d58ffa0364c04d03a8f25704d7f0489ee6cd9634 github.com/docker/docker-credential-helpers v0.5.1 # the docker/go package contains a customized version of canonical/json diff --git a/components/cli/vendor/github.com/docker/docker/api/types/swarm/swarm.go b/components/cli/vendor/github.com/docker/docker/api/types/swarm/swarm.go index 5b74f14b11..b65fa86dac 100644 --- a/components/cli/vendor/github.com/docker/docker/api/types/swarm/swarm.go +++ b/components/cli/vendor/github.com/docker/docker/api/types/swarm/swarm.go @@ -2,7 +2,7 @@ package swarm import "time" -// ClusterInfo represents info about the cluster for outputing in "info" +// ClusterInfo represents info about the cluster for outputting in "info" // it contains the same information as "Swarm", but without the JoinTokens type ClusterInfo struct { ID string diff --git a/components/cli/vendor/github.com/docker/docker/client/client.go b/components/cli/vendor/github.com/docker/docker/client/client.go index 222aa50f11..7e14531723 100644 --- a/components/cli/vendor/github.com/docker/docker/client/client.go +++ b/components/cli/vendor/github.com/docker/docker/client/client.go @@ -91,7 +91,7 @@ type Client struct { // CheckRedirect specifies the policy for dealing with redirect responses: // If the request is non-GET return `ErrRedirect`. Otherwise use the last response. // -// Go 1.8 changes behavior for HTTP redirects (specificlaly 301, 307, and 308) in the client . +// Go 1.8 changes behavior for HTTP redirects (specifically 301, 307, and 308) in the client . // The Docker client (and by extension docker API client) can be made to to send a request // like POST /containers//start where what would normally be in the name section of the URL is empty. // This triggers an HTTP 301 from the daemon. @@ -260,8 +260,13 @@ func (cli *Client) NegotiateAPIVersionPing(p types.Ping) { p.APIVersion = "1.24" } - // if server version is lower than the current cli, downgrade - if versions.LessThan(p.APIVersion, cli.ClientVersion()) { + // if the client is not initialized with a version, start with the latest supported version + if cli.version == "" { + cli.version = api.DefaultVersion + } + + // if server version is lower than the maximum version supported by the Client, downgrade + if versions.LessThan(p.APIVersion, api.DefaultVersion) { cli.version = p.APIVersion } } diff --git a/components/cli/vendor/github.com/docker/docker/client/container_attach.go b/components/cli/vendor/github.com/docker/docker/client/container_attach.go index eea4682158..0fdf3ed0ce 100644 --- a/components/cli/vendor/github.com/docker/docker/client/container_attach.go +++ b/components/cli/vendor/github.com/docker/docker/client/container_attach.go @@ -11,6 +11,26 @@ import ( // It returns a types.HijackedConnection with the hijacked connection // and the a reader to get output. It's up to the called to close // the hijacked connection by calling types.HijackedResponse.Close. +// +// The stream format on the response will be in one of two formats: +// +// If the container is using a TTY, there is only a single stream (stdout), and +// data is copied directly from the container output stream, no extra +// multiplexing or headers. +// +// If the container is *not* using a TTY, streams for stdout and stderr are +// multiplexed. +// The format of the multiplexed stream is as follows: +// +// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT} +// +// STREAM_TYPE can be 1 for stdout and 2 for stderr +// +// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian. +// This is the size of OUTPUT. +// +// You can use github.com/docker/docker/pkg/stdcopy.StdCopy to demultiplex this +// stream. func (cli *Client) ContainerAttach(ctx context.Context, container string, options types.ContainerAttachOptions) (types.HijackedResponse, error) { query := url.Values{} if options.Stream { diff --git a/components/cli/vendor/github.com/docker/docker/client/container_logs.go b/components/cli/vendor/github.com/docker/docker/client/container_logs.go index 69056b6321..0f32e9f12b 100644 --- a/components/cli/vendor/github.com/docker/docker/client/container_logs.go +++ b/components/cli/vendor/github.com/docker/docker/client/container_logs.go @@ -13,6 +13,26 @@ import ( // ContainerLogs returns the logs generated by a container in an io.ReadCloser. // It's up to the caller to close the stream. +// +// The stream format on the response will be in one of two formats: +// +// If the container is using a TTY, there is only a single stream (stdout), and +// data is copied directly from the container output stream, no extra +// multiplexing or headers. +// +// If the container is *not* using a TTY, streams for stdout and stderr are +// multiplexed. +// The format of the multiplexed stream is as follows: +// +// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT} +// +// STREAM_TYPE can be 1 for stdout and 2 for stderr +// +// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian. +// This is the size of OUTPUT. +// +// You can use github.com/docker/docker/pkg/stdcopy.StdCopy to demultiplex this +// stream. func (cli *Client) ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) { query := url.Values{} if options.ShowStdout { diff --git a/components/cli/vendor/github.com/docker/docker/client/container_wait.go b/components/cli/vendor/github.com/docker/docker/client/container_wait.go index 13b5eea6a9..854c6c053b 100644 --- a/components/cli/vendor/github.com/docker/docker/client/container_wait.go +++ b/components/cli/vendor/github.com/docker/docker/client/container_wait.go @@ -14,7 +14,7 @@ import ( // indicated by the given condition, either "not-running" (default), // "next-exit", or "removed". // -// If this client's API version is beforer 1.30, condition is ignored and +// If this client's API version is before 1.30, condition is ignored and // ContainerWait will return immediately with the two channels, as the server // will wait as if the condition were "not-running". // @@ -23,7 +23,7 @@ import ( // then returns two channels on which the caller can wait for the exit status // of the container or an error if there was a problem either beginning the // wait request or in getting the response. This allows the caller to -// sychronize ContainerWait with other calls, such as specifying a +// synchronize ContainerWait with other calls, such as specifying a // "next-exit" condition before issuing a ContainerStart request. func (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) { if versions.LessThan(cli.ClientVersion(), "1.30") { diff --git a/components/cli/vendor/github.com/docker/docker/opts/ip.go b/components/cli/vendor/github.com/docker/docker/opts/ip.go index fb03b50111..1095063977 100644 --- a/components/cli/vendor/github.com/docker/docker/opts/ip.go +++ b/components/cli/vendor/github.com/docker/docker/opts/ip.go @@ -22,7 +22,7 @@ func NewIPOpt(ref *net.IP, defaultVal string) *IPOpt { } // Set sets an IPv4 or IPv6 address from a given string. If the given -// string is not parseable as an IP address it returns an error. +// string is not parsable as an IP address it returns an error. func (o *IPOpt) Set(val string) error { ip := net.ParseIP(val) if ip == nil { diff --git a/components/cli/vendor/github.com/docker/docker/pkg/archive/archive.go b/components/cli/vendor/github.com/docker/docker/pkg/archive/archive.go index c6ad7c58a8..79d871e20e 100644 --- a/components/cli/vendor/github.com/docker/docker/pkg/archive/archive.go +++ b/components/cli/vendor/github.com/docker/docker/pkg/archive/archive.go @@ -180,7 +180,7 @@ func DecompressStream(archive io.Reader) (io.ReadCloser, error) { } } -// CompressStream compresseses the dest with specified compression algorithm. +// CompressStream compresses the dest with specified compression algorithm. func CompressStream(dest io.Writer, compression Compression) (io.WriteCloser, error) { p := pools.BufioWriter32KPool buf := p.Get(dest) diff --git a/components/cli/vendor/github.com/docker/docker/pkg/archive/copy.go b/components/cli/vendor/github.com/docker/docker/pkg/archive/copy.go index 0614c67cec..5281e29d18 100644 --- a/components/cli/vendor/github.com/docker/docker/pkg/archive/copy.go +++ b/components/cli/vendor/github.com/docker/docker/pkg/archive/copy.go @@ -332,6 +332,9 @@ func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.Read } hdr.Name = strings.Replace(hdr.Name, oldBase, newBase, 1) + if hdr.Typeflag == tar.TypeLink { + hdr.Linkname = strings.Replace(hdr.Linkname, oldBase, newBase, 1) + } if err = rebasedTar.WriteHeader(hdr); err != nil { w.CloseWithError(err) diff --git a/components/cli/vendor/github.com/docker/docker/pkg/symlink/fs.go b/components/cli/vendor/github.com/docker/docker/pkg/symlink/fs.go index f6bc2231f6..52fb9a691b 100644 --- a/components/cli/vendor/github.com/docker/docker/pkg/symlink/fs.go +++ b/components/cli/vendor/github.com/docker/docker/pkg/symlink/fs.go @@ -40,7 +40,7 @@ func FollowSymlinkInScope(path, root string) (string, error) { // // Example: // If /foo/bar -> /outside, -// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide" +// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/outside" // // IMPORTANT: it is the caller's responsibility to call evalSymlinksInScope *after* relevant symlinks // are created and not to create subsequently, additional symlinks that could potentially make a diff --git a/components/cli/vendor/github.com/docker/docker/pkg/system/path_windows.go b/components/cli/vendor/github.com/docker/docker/pkg/system/path_windows.go index 3fc4744948..aab891522d 100644 --- a/components/cli/vendor/github.com/docker/docker/pkg/system/path_windows.go +++ b/components/cli/vendor/github.com/docker/docker/pkg/system/path_windows.go @@ -12,7 +12,7 @@ import ( // This is used, for example, when validating a user provided path in docker cp. // If a drive letter is supplied, it must be the system drive. The drive letter // is always removed. Also, it translates it to OS semantics (IOW / to \). We -// need the path in this syntax so that it can ultimately be contatenated with +// need the path in this syntax so that it can ultimately be concatenated with // a Windows long-path which doesn't support drive-letters. Examples: // C: --> Fail // C:\ --> \ diff --git a/components/cli/vendor/github.com/docker/docker/pkg/system/rm.go b/components/cli/vendor/github.com/docker/docker/pkg/system/rm.go index ca0621f04f..101b569a56 100644 --- a/components/cli/vendor/github.com/docker/docker/pkg/system/rm.go +++ b/components/cli/vendor/github.com/docker/docker/pkg/system/rm.go @@ -20,7 +20,7 @@ import ( // These types of errors do not need to be returned since it's ok for the dir to // be gone we can just retry the remove operation. // -// This should not return a `os.ErrNotExist` kind of error under any cirucmstances +// This should not return a `os.ErrNotExist` kind of error under any circumstances func EnsureRemoveAll(dir string) error { notExistErr := make(map[string]bool) diff --git a/components/cli/vendor/github.com/docker/docker/pkg/templates/templates.go b/components/cli/vendor/github.com/docker/docker/pkg/templates/templates.go index 75a3dd974e..d2d7e0c3d7 100644 --- a/components/cli/vendor/github.com/docker/docker/pkg/templates/templates.go +++ b/components/cli/vendor/github.com/docker/docker/pkg/templates/templates.go @@ -30,7 +30,7 @@ var basicFunctions = template.FuncMap{ // HeaderFunctions are used to created headers of a table. // This is a replacement of basicFunctions for header generation // because we want the header to remain intact. -// Some functions like `split` are irrevelant so not added. +// Some functions like `split` are irrelevant so not added. var HeaderFunctions = template.FuncMap{ "json": func(v string) string { return v diff --git a/components/cli/vendor/github.com/docker/docker/registry/config.go b/components/cli/vendor/github.com/docker/docker/registry/config.go index 651bd73097..182599e38d 100644 --- a/components/cli/vendor/github.com/docker/docker/registry/config.go +++ b/components/cli/vendor/github.com/docker/docker/registry/config.go @@ -252,7 +252,7 @@ skip: return nil } -// allowNondistributableArtifacts returns true if the provided hostname is part of the list of regsitries +// allowNondistributableArtifacts returns true if the provided hostname is part of the list of registries // that allow push of nondistributable artifacts. // // The list can contain elements with CIDR notation to specify a whole subnet. If the subnet contains an IP diff --git a/components/cli/vendor/github.com/docker/docker/registry/endpoint_v1.go b/components/cli/vendor/github.com/docker/docker/registry/endpoint_v1.go index 6bcf8c935d..c5ca961dd4 100644 --- a/components/cli/vendor/github.com/docker/docker/registry/endpoint_v1.go +++ b/components/cli/vendor/github.com/docker/docker/registry/endpoint_v1.go @@ -175,7 +175,7 @@ func (e *V1Endpoint) Ping() (PingResult, error) { Standalone: true, } if err := json.Unmarshal(jsonString, &info); err != nil { - logrus.Debugf("Error unmarshalling the _ping PingResult: %s", err) + logrus.Debugf("Error unmarshaling the _ping PingResult: %s", err) // don't stop here. Just assume sane defaults } if hdr := resp.Header.Get("X-Docker-Registry-Version"); hdr != "" { diff --git a/components/cli/vendor/github.com/docker/docker/vendor.conf b/components/cli/vendor/github.com/docker/docker/vendor.conf index bad511c4d4..20460d5cc9 100644 --- a/components/cli/vendor/github.com/docker/docker/vendor.conf +++ b/components/cli/vendor/github.com/docker/docker/vendor.conf @@ -13,7 +13,6 @@ github.com/kr/pty 5cf931ef8f github.com/mattn/go-shellwords v1.0.3 github.com/tchap/go-patricia v2.2.6 github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 -# forked golang.org/x/net package includes a patch for lazy loading trace templates golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 golang.org/x/sys 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9 github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1 diff --git a/components/cli/vendor/github.com/docker/docker/volume/volume.go b/components/cli/vendor/github.com/docker/docker/volume/volume.go index 2de248aa5f..8598d4cb8f 100644 --- a/components/cli/vendor/github.com/docker/docker/volume/volume.go +++ b/components/cli/vendor/github.com/docker/docker/volume/volume.go @@ -125,7 +125,7 @@ type MountPoint struct { Spec mounttypes.Mount // Track usage of this mountpoint - // Specicially needed for containers which are running and calls to `docker cp` + // Specifically needed for containers which are running and calls to `docker cp` // because both these actions require mounting the volumes. active int } diff --git a/components/cli/vendor/github.com/docker/docker/volume/volume_linux.go b/components/cli/vendor/github.com/docker/docker/volume/volume_linux.go index d4b4d800b2..fdf7b63e4b 100644 --- a/components/cli/vendor/github.com/docker/docker/volume/volume_linux.go +++ b/components/cli/vendor/github.com/docker/docker/volume/volume_linux.go @@ -26,7 +26,7 @@ func ConvertTmpfsOptions(opt *mounttypes.TmpfsOptions, readOnly bool) (string, e // okay, since API is that way anyways. // we do this by finding the suffix that divides evenly into the - // value, returing the value itself, with no suffix, if it fails. + // value, returning the value itself, with no suffix, if it fails. // // For the most part, we don't enforce any semantic to this values. // The operating system will usually align this and enforce minimum From b1d7c8f0146021ccd337380baea602df2547bd83 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Fri, 14 Jul 2017 10:22:55 +0200 Subject: [PATCH 13/62] Add bash completion for `--storage-opt dm.libdm_log_level` This adds bash completion for https://github.com/moby/moby/pull/33845. Signed-off-by: Harald Albers Upstream-commit: b8710ccef398bdfcd5ba323a39b16c5ab15e530a Component: cli --- components/cli/contrib/completion/bash/docker | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 95cc588ca0..66f629a0de 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -2068,6 +2068,10 @@ _docker_daemon() { COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur##*=}" ) ) return ;; + dm.libdm_log_level) + COMPREPLY=( $( compgen -W "2 3 4 5 6 7" -- "${cur##*=}" ) ) + return + ;; esac case "$prev" in @@ -2109,6 +2113,7 @@ _docker_daemon() { dm.blocksize dm.directlvm_device dm.fs + dm.libdm_log_level dm.loopdatasize dm.loopmetadatasize dm.min_free_space From 9fab9786f4a432ddec6b4eba295e9a830e255d9e Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Thu, 13 Jul 2017 09:03:52 -0600 Subject: [PATCH 14/62] docs: add --password-stdin also add an example of usage Signed-off-by: Tycho Andersen Upstream-commit: 3e392505a860eb6f99b303932038ccdcdd8951c1 Component: cli --- .../cli/docs/reference/commandline/login.md | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/components/cli/docs/reference/commandline/login.md b/components/cli/docs/reference/commandline/login.md index 0b8e697281..df3c5e8ea9 100644 --- a/components/cli/docs/reference/commandline/login.md +++ b/components/cli/docs/reference/commandline/login.md @@ -22,9 +22,10 @@ Log in to a Docker registry. If no server is specified, the default is defined by the daemon. Options: - --help Print usage - -p, --password string Password - -u, --username string Username + --help Print usage + -p, --password string Password + --password-stdin Read password from stdin + -u, --username string Username ``` ## Description @@ -40,6 +41,20 @@ adding the server name. $ docker login localhost:8080 ``` +### Provide a password using STDIN + +To run the `docker login` command non-interactively, you can set the +`--password-stdin` flag to provide a password through `STDIN`. Using +`STDIN` prevents the password from ending up in the shell's history, +or log-files. + +The following example reads a password from a file, and passes it to the +`docker login` command using `STDIN`: + +```bash +$ cat ~/my_password.txt | docker login --username foo --password-stdin +``` + ### Privileged user requirement `docker login` requires user to use `sudo` or be `root`, except when: From 3ddb21c1b115600ac2f6a25624152d7c707263e3 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Thu, 13 Jul 2017 09:05:04 -0600 Subject: [PATCH 15/62] bash completion: add --password-stdin Signed-off-by: Tycho Andersen Upstream-commit: bbfe23f9e6175e08c7a42b42919611cb038fcc72 Component: cli --- components/cli/contrib/completion/bash/docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 95cc588ca0..e9d8b6f2b6 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -2684,7 +2684,7 @@ _docker_login() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help --password -p --username -u" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help --password --password-stdin -p --username -u" -- "$cur" ) ) ;; esac } From 231e3a605bf2f82fbd1ea17b8ba2dfbfc04adfb1 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Thu, 13 Jul 2017 09:05:18 -0600 Subject: [PATCH 16/62] zsh completion: add --password-stdin Signed-off-by: Tycho Andersen Upstream-commit: 90619e5054d3e82a75b1c3768d5de556289c39d9 Component: cli --- components/cli/contrib/completion/zsh/_docker | 1 + 1 file changed, 1 insertion(+) diff --git a/components/cli/contrib/completion/zsh/_docker b/components/cli/contrib/completion/zsh/_docker index 4b0c1e25c7..075e87aa93 100644 --- a/components/cli/contrib/completion/zsh/_docker +++ b/components/cli/contrib/completion/zsh/_docker @@ -2761,6 +2761,7 @@ __docker_subcommand() { _arguments $(__docker_arguments) -A '-*' \ $opts_help \ "($help -p --password)"{-p=,--password=}"[Password]:password: " \ + "($help)--password-stdin[Read password from stdin]" \ "($help -u --user)"{-u=,--user=}"[Username]:username: " \ "($help -)1:server: " && ret=0 ;; From 70f1e387d982cd55a77ac44ef9c7c45f1c83fb34 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Thu, 13 Jul 2017 09:07:38 -0600 Subject: [PATCH 17/62] fish completion: add --password-stdin Signed-off-by: Tycho Andersen Upstream-commit: 3b7b6b5f7f46d582f929d3198eefebbe0c36d2eb Component: cli --- components/cli/contrib/completion/fish/docker.fish | 1 + 1 file changed, 1 insertion(+) diff --git a/components/cli/contrib/completion/fish/docker.fish b/components/cli/contrib/completion/fish/docker.fish index 38957b8b77..d825922776 100644 --- a/components/cli/contrib/completion/fish/docker.fish +++ b/components/cli/contrib/completion/fish/docker.fish @@ -229,6 +229,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from load' -s i -l input -d complete -c docker -f -n '__fish_docker_no_subcommand' -a login -d 'Log in to a Docker registry server' complete -c docker -A -f -n '__fish_seen_subcommand_from login' -l help -d 'Print usage' complete -c docker -A -f -n '__fish_seen_subcommand_from login' -s p -l password -d 'Password' +complete -c docker -A -f -n '__fish_seen_subcommand_from login' -l password-stdin -d 'Read password from stdin' complete -c docker -A -f -n '__fish_seen_subcommand_from login' -s u -l username -d 'Username' # logout From c04822c682ffc36e3702194edaf87867affaeeb5 Mon Sep 17 00:00:00 2001 From: Boaz Shuster Date: Wed, 19 Jul 2017 10:34:03 +0300 Subject: [PATCH 18/62] Sort services names in a natural order Signed-off-by: Boaz Shuster Upstream-commit: 7478e47b2db4f3eb257e88f229567f32324ba9ee Component: cli --- .../cli/cli/command/service/client_test.go | 35 +++++++++++++++++++ components/cli/cli/command/service/list.go | 14 ++++++-- .../cli/cli/command/service/list_test.go | 32 +++++++++++++++++ components/cli/cli/command/service/ps_test.go | 24 ------------- .../service/testdata/service-list-sort.golden | 3 ++ 5 files changed, 82 insertions(+), 26 deletions(-) create mode 100644 components/cli/cli/command/service/client_test.go create mode 100644 components/cli/cli/command/service/list_test.go create mode 100644 components/cli/cli/command/service/testdata/service-list-sort.golden diff --git a/components/cli/cli/command/service/client_test.go b/components/cli/cli/command/service/client_test.go new file mode 100644 index 0000000000..b4f8905159 --- /dev/null +++ b/components/cli/cli/command/service/client_test.go @@ -0,0 +1,35 @@ +package service + +import ( + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/client" + "golang.org/x/net/context" +) + +type fakeClient struct { + client.Client + serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error) +} + +func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { + if f.serviceListFunc != nil { + return f.serviceListFunc(ctx, options) + } + return nil, nil +} + +func (f *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) { + return nil, nil +} + +func (f *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) { + return nil, nil +} + +func newService(id string, name string) swarm.Service { + return swarm.Service{ + ID: id, + Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: name}}, + } +} diff --git a/components/cli/cli/command/service/list.go b/components/cli/cli/command/service/list.go index 5b359d307a..63adce1ec1 100644 --- a/components/cli/cli/command/service/list.go +++ b/components/cli/cli/command/service/list.go @@ -2,6 +2,9 @@ package service import ( "fmt" + "sort" + + "vbom.ml/util/sortorder" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -20,7 +23,7 @@ type listOptions struct { filter opts.FilterOpt } -func newListCommand(dockerCli *command.DockerCli) *cobra.Command { +func newListCommand(dockerCli command.Cli) *cobra.Command { options := listOptions{filter: opts.NewFilterOpt()} cmd := &cobra.Command{ @@ -41,7 +44,13 @@ func newListCommand(dockerCli *command.DockerCli) *cobra.Command { return cmd } -func runList(dockerCli *command.DockerCli, options listOptions) error { +type byName []swarm.Service + +func (n byName) Len() int { return len(n) } +func (n byName) Swap(i, j int) { n[i], n[j] = n[j], n[i] } +func (n byName) Less(i, j int) bool { return sortorder.NaturalLess(n[i].Spec.Name, n[j].Spec.Name) } + +func runList(dockerCli command.Cli, options listOptions) error { ctx := context.Background() client := dockerCli.Client() @@ -51,6 +60,7 @@ func runList(dockerCli *command.DockerCli, options listOptions) error { return err } + sort.Sort(byName(services)) info := map[string]formatter.ServiceListInfo{} if len(services) > 0 && !options.quiet { // only non-empty services and not quiet, should we call TaskList and NodeList api diff --git a/components/cli/cli/command/service/list_test.go b/components/cli/cli/command/service/list_test.go new file mode 100644 index 0000000000..85ccd1fb79 --- /dev/null +++ b/components/cli/cli/command/service/list_test.go @@ -0,0 +1,32 @@ +package service + +import ( + "testing" + + "golang.org/x/net/context" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/pkg/testutil" + "github.com/docker/docker/pkg/testutil/golden" + "github.com/stretchr/testify/assert" +) + +func TestServiceListOrder(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { + return []swarm.Service{ + newService("a57dbe8", "service-1-foo"), + newService("a57dbdd", "service-10-foo"), + newService("aaaaaaa", "service-2-foo"), + }, nil + }, + }) + cmd := newListCommand(cli) + cmd.Flags().Set("format", "{{.Name}}") + assert.NoError(t, cmd.Execute()) + actual := cli.OutBuffer().String() + expected := golden.Get(t, []byte(actual), "service-list-sort.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} diff --git a/components/cli/cli/command/service/ps_test.go b/components/cli/cli/command/service/ps_test.go index 0e1bcb438b..dac79ab50a 100644 --- a/components/cli/cli/command/service/ps_test.go +++ b/components/cli/cli/command/service/ps_test.go @@ -10,35 +10,11 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" - "github.com/docker/docker/client" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/net/context" ) -type fakeClient struct { - client.Client - serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error) -} - -func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { - if f.serviceListFunc != nil { - return f.serviceListFunc(ctx, options) - } - return nil, nil -} - -func (f *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) { - return nil, nil -} - -func newService(id string, name string) swarm.Service { - return swarm.Service{ - ID: id, - Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: name}}, - } -} - func TestCreateFilter(t *testing.T) { client := &fakeClient{ serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { diff --git a/components/cli/cli/command/service/testdata/service-list-sort.golden b/components/cli/cli/command/service/testdata/service-list-sort.golden new file mode 100644 index 0000000000..3b0cb2144d --- /dev/null +++ b/components/cli/cli/command/service/testdata/service-list-sort.golden @@ -0,0 +1,3 @@ +service-1-foo +service-2-foo +service-10-foo From c20d148cd49d04c3db8e3f93b442d85732592d3b Mon Sep 17 00:00:00 2001 From: Jean-Pierre Huynh Date: Tue, 18 Jul 2017 13:17:17 +0100 Subject: [PATCH 19/62] Add scripts folder to shellcheck Signed-off-by: Jean-Pierre Huynh Upstream-commit: 24c06c17237b622b427c7dd52cf299f15c33e5d0 Component: cli --- components/cli/scripts/build/binary | 2 +- components/cli/scripts/build/cross | 4 ++-- components/cli/scripts/build/dynbinary | 2 +- components/cli/scripts/docs/generate-man.sh | 2 +- components/cli/scripts/docs/generate-yaml.sh | 2 +- components/cli/scripts/gen/windows-resources | 23 +++++++++---------- components/cli/scripts/test/unit | 2 +- .../cli/scripts/test/unit-with-coverage | 6 ++--- components/cli/scripts/test/watch | 1 + .../cli/scripts/validate/check-git-diff | 4 ++-- components/cli/scripts/validate/shellcheck | 12 +++------- 11 files changed, 27 insertions(+), 33 deletions(-) diff --git a/components/cli/scripts/build/binary b/components/cli/scripts/build/binary index b40f9d5f9d..41c4196cc8 100755 --- a/components/cli/scripts/build/binary +++ b/components/cli/scripts/build/binary @@ -11,4 +11,4 @@ echo "Building statically linked $TARGET" export CGO_ENABLED=0 go build -o "${TARGET}" --ldflags "${LDFLAGS}" "${SOURCE}" -ln -sf "$(basename ${TARGET})" build/docker +ln -sf "$(basename "${TARGET}")" build/docker diff --git a/components/cli/scripts/build/cross b/components/cli/scripts/build/cross index 39dcee4162..919390dff3 100755 --- a/components/cli/scripts/build/cross +++ b/components/cli/scripts/build/cross @@ -18,7 +18,7 @@ jobs=( ) # Outside of circleCI run all at once. On circleCI run two at a time because -# each continer has access to two cores. +# each container has access to two cores. group=${CROSS_GROUP-"all"} if [ "$group" == "all" ]; then @@ -29,5 +29,5 @@ if [ "$group" == "all" ]; then fi -declare -i start=$group*2 +declare -i start="$group*2" parallel ::: "${jobs[@]:$start:2}" diff --git a/components/cli/scripts/build/dynbinary b/components/cli/scripts/build/dynbinary index d1107338ab..3c32ed342e 100755 --- a/components/cli/scripts/build/dynbinary +++ b/components/cli/scripts/build/dynbinary @@ -11,4 +11,4 @@ echo "Building dynamically linked $TARGET" export CGO_ENABLED=1 go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" "${SOURCE}" -ln -sf "$(basename ${TARGET})" build/docker +ln -sf "$(basename "${TARGET}")" build/docker diff --git a/components/cli/scripts/docs/generate-man.sh b/components/cli/scripts/docs/generate-man.sh index eb0a68da51..7412e5baa5 100755 --- a/components/cli/scripts/docs/generate-man.sh +++ b/components/cli/scripts/docs/generate-man.sh @@ -8,7 +8,7 @@ go install ./vendor/github.com/cpuguy83/go-md2man # Generate man pages from cobra commands go build -o /tmp/gen-manpages github.com/docker/cli/man -/tmp/gen-manpages --root $(pwd) --target $(pwd)/man/man1 +/tmp/gen-manpages --root "$(pwd)" --target "$(pwd)/man/man1" # Generate legacy pages from markdown ./man/md2man-all.sh -q diff --git a/components/cli/scripts/docs/generate-yaml.sh b/components/cli/scripts/docs/generate-yaml.sh index a8afed1796..2a7b0a8980 100755 --- a/components/cli/scripts/docs/generate-yaml.sh +++ b/components/cli/scripts/docs/generate-yaml.sh @@ -5,4 +5,4 @@ set -eu -o pipefail mkdir -p docs/yaml/gen go build -o build/yaml-docs-generator github.com/docker/cli/docs/yaml -build/yaml-docs-generator --root $(pwd) --target $(pwd)/docs/yaml/gen +build/yaml-docs-generator --root "$(pwd)" --target "$(pwd)/docs/yaml/gen" diff --git a/components/cli/scripts/gen/windows-resources b/components/cli/scripts/gen/windows-resources index bf9aface0a..14b45e08e0 100755 --- a/components/cli/scripts/gen/windows-resources +++ b/components/cli/scripts/gen/windows-resources @@ -6,6 +6,7 @@ set -eu -o pipefail SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +# shellcheck source=/go/src/github.com/docker/cli/scripts/build/.variables source $SCRIPTDIR/../build/.variables RESOURCES=$SCRIPTDIR/../winresources @@ -15,30 +16,28 @@ trap 'rm -rf $TEMPDIR' EXIT if [ "$(go env GOHOSTOS)" == "windows" ]; then WINDRES=windres - WINDMC=windmc else # Cross compiling WINDRES=x86_64-w64-mingw32-windres - WINDMC=x86_64-w64-mingw32-windmc fi # Generate a Windows file version of the form major,minor,patch,build (with any part optional) -VERSION_QUAD=$(echo -n $VERSION | sed -re 's/^([0-9.]*).*$/\1/' | tr . ,) +VERSION_QUAD=$(echo -n "$VERSION" | sed -re 's/^([0-9.]*).*$/\1/' | tr . ,) # Pass version and commit information into the resource compiler defs= -[ ! -z $VERSION ] && defs="$defs -D DOCKER_VERSION=\"$VERSION\"" -[ ! -z $VERSION_QUAD ] && defs="$defs -D DOCKER_VERSION_QUAD=$VERSION_QUAD" -[ ! -z $GITCOMMIT ] && defs="$defs -D DOCKER_COMMIT=\"$GITCOMMIT\"" +[ ! -z "$VERSION" ] && defs+=( "-D DOCKER_VERSION=\"$VERSION\"") +[ ! -z "$VERSION_QUAD" ] && defs+=( "-D DOCKER_VERSION_QUAD=$VERSION_QUAD") +[ ! -z "$GITCOMMIT" ] && defs+=( "-D DOCKER_COMMIT=\"$GITCOMMIT\"") function makeres { - $WINDRES \ - -i $RESOURCES/$1 \ - -o $3 \ - -F $2 \ + "$WINDRES" \ + -i "$RESOURCES/$1" \ + -o "$3" \ + -F "$2" \ --use-temp-file \ - -I $TEMPDIR \ - $defs + -I "$TEMPDIR" \ + ${defs[*]} } makeres docker.rc pe-x86-64 rsrc_amd64.syso diff --git a/components/cli/scripts/test/unit b/components/cli/scripts/test/unit index 8c2f9c75df..2a0f02af51 100755 --- a/components/cli/scripts/test/unit +++ b/components/cli/scripts/test/unit @@ -1,4 +1,4 @@ #!/usr/bin/env bash set -eu -o pipefail -go test -tags daemon -v $@ +go test -tags daemon -v "$@" diff --git a/components/cli/scripts/test/unit-with-coverage b/components/cli/scripts/test/unit-with-coverage index cd1ead8477..0b7a3586a2 100755 --- a/components/cli/scripts/test/unit-with-coverage +++ b/components/cli/scripts/test/unit-with-coverage @@ -3,14 +3,14 @@ set -eu -o pipefail # install test dependencies once before running tests for each package. This # reduces the runtime from 200s down to 23s -go test -i $@ +go test -i "$@" -for pkg in $@; do +for pkg in "$@"; do ./scripts/test/unit \ -cover \ -coverprofile=profile.out \ -covermode=atomic \ - ${pkg} + "${pkg}" if test -f profile.out; then cat profile.out >> coverage.txt diff --git a/components/cli/scripts/test/watch b/components/cli/scripts/test/watch index a63b94d32a..6c9745aead 100755 --- a/components/cli/scripts/test/watch +++ b/components/cli/scripts/test/watch @@ -1,2 +1,3 @@ #!/bin/sh +# shellcheck disable=SC2016 exec filewatcher -L 6 -x build -x script go test -timeout 10s -v './${dir}' diff --git a/components/cli/scripts/validate/check-git-diff b/components/cli/scripts/validate/check-git-diff index 4cdc0d2db6..333fc62f08 100755 --- a/components/cli/scripts/validate/check-git-diff +++ b/components/cli/scripts/validate/check-git-diff @@ -3,13 +3,13 @@ set -eu DIFF_PATH=$1 -DIFF=$(git status --porcelain -- $DIFF_PATH) +DIFF=$(git status --porcelain -- "$DIFF_PATH") if [ "$DIFF" ]; then echo echo "These files were changed:" echo - echo $DIFF + echo "$DIFF" echo exit 1 else diff --git a/components/cli/scripts/validate/shellcheck b/components/cli/scripts/validate/shellcheck index f14d1ab04d..f7ce7024d3 100755 --- a/components/cli/scripts/validate/shellcheck +++ b/components/cli/scripts/validate/shellcheck @@ -1,11 +1,5 @@ #!/usr/bin/env bash -set -e +set -eo pipefail -# Maintain an array of files to shellcheck not the best solution but will do for the time being -FILES=() -FILES+=("contrib/completion/bash/docker") -FILES+=("scripts/validate/shellcheck") - -for f in "${FILES[@]}"; do - shellcheck "$f" -done +shellcheck contrib/completion/bash/docker +find scripts/ -type f | grep -v scripts/winresources | xargs shellcheck From 0de63ac93fa804224ed64eb170b182fd45d15ae4 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 14 Jul 2017 17:05:31 -0400 Subject: [PATCH 20/62] Add Compose format 3.4 Signed-off-by: Daniel Nephin Upstream-commit: 0adccacb38f5862a94fedc811aa7f3b1e8009263 Component: cli --- components/cli/cli/compose/schema/bindata.go | 23 + .../schema/data/config_schema_v3.4.json | 534 ++++++++++++++++++ 2 files changed, 557 insertions(+) create mode 100644 components/cli/cli/compose/schema/data/config_schema_v3.4.json diff --git a/components/cli/cli/compose/schema/bindata.go b/components/cli/cli/compose/schema/bindata.go index 06fcae3591..cba2c1e17c 100644 --- a/components/cli/cli/compose/schema/bindata.go +++ b/components/cli/cli/compose/schema/bindata.go @@ -4,6 +4,7 @@ // data/config_schema_v3.1.json // data/config_schema_v3.2.json // data/config_schema_v3.3.json +// data/config_schema_v3.4.json // DO NOT EDIT! package schema @@ -151,6 +152,26 @@ func dataConfig_schema_v33Json() (*asset, error) { return a, nil } +var _dataConfig_schema_v34Json = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\xcd\x93\xdb\xa0\x15\xbf\xfb\xaf\xd0\x28\xb9\x65\x3f\x32\xd3\x4c\x67\x9a\x5b\x8f\x3d\xb5\xe7\xee\x38\x1a\x8c\x9e\x6d\xb2\x08\x08\x20\xef\x3a\x99\xfd\xdf\x3b\xfa\x34\x20\x10\xd8\xd6\x66\xb7\x6d\x4e\xbb\x96\x7e\x0f\x78\xdf\xef\x01\xfa\xb5\xca\xb2\xfc\xa3\xc2\x7b\xa8\x50\xfe\x35\xcb\xf7\x5a\x8b\xaf\xf7\xf7\xdf\x15\x67\xb7\xdd\xd3\x3b\x2e\x77\xf7\xa5\x44\x5b\x7d\xfb\xf9\xcb\x7d\xf7\xec\x43\x7e\xd3\xd0\x91\xb2\x21\xc1\x9c\x6d\xc9\xae\xe8\xde\x14\x87\xbf\xdc\x7d\xb9\x6b\xc8\x3b\x88\x3e\x0a\x68\x40\x7c\xf3\x1d\xb0\xee\x9e\x49\xf8\x51\x13\x09\x0d\xf1\x43\x7e\x00\xa9\x08\x67\xf9\xfa\x66\xd5\xbc\x13\x92\x0b\x90\x9a\x80\xca\xbf\x66\xcd\xe2\xb2\x6c\x84\x0c\x0f\x8c\x61\x95\x96\x84\xed\xf2\xf6\xf1\x4b\x3b\x42\x96\xe5\x0a\xe4\x81\x60\x63\x84\x71\xa9\x1f\xee\x4f\xe3\xdf\x8f\xb0\x1b\x77\x54\x63\xb1\xed\x73\x81\xb4\x06\xc9\xfe\x35\x5d\x5b\xfb\xfa\xdb\x03\xba\xfd\xf9\xf7\xdb\x7f\x7f\xbe\xfd\xdb\x5d\x71\xbb\xfe\xf4\xd1\x7a\xdd\xc8\x57\xc2\xb6\x9b\xbe\x84\x2d\x61\x44\x13\xce\xc6\xf9\xf3\x11\xf9\xd2\xff\xf7\x32\x4e\x8c\xca\xb2\x05\x23\x6a\xcd\xbd\x45\x54\x81\xcd\x33\x03\xfd\xc4\xe5\x63\x8c\xe7\x11\xf6\x46\x3c\xf7\xf3\x7b\x78\xb6\xd9\x39\x70\x5a\x57\x51\x0d\x0e\xa8\x37\x62\xa6\x9b\x7e\x19\xfd\x29\xc0\x12\x74\xdc\x64\x3b\xd4\x9b\x59\x6c\x33\xfd\x32\x0c\x77\x51\x23\xc6\xf0\x80\x7a\x23\x86\xbb\xe9\xaf\x63\x78\x35\x30\x3d\x8b\xed\x10\xc6\xdc\xed\x02\xad\x78\xe6\x13\x95\x2f\x9e\x84\x65\x35\x0a\x2b\x20\xa5\x12\x04\xe5\xc7\xe6\x59\x40\x1e\x1d\xa0\x02\xa6\xf3\x51\x04\x59\x96\x6f\x6a\x42\x4b\x57\xa2\x9c\xc1\x3f\x9b\x21\x1e\x8c\x87\x59\xf6\xcb\x0d\xdd\xc6\x38\xed\x7b\xeb\x57\x58\xe1\xe3\xfb\x00\x2f\xe3\x7b\xcc\x99\x86\x67\xdd\x32\x35\x3f\x75\x27\x02\x8e\x1f\x41\x6e\x09\x85\x54\x0a\x24\x3b\x2b\x0e\x88\x8c\x12\xa5\x0b\x2e\x8b\x92\x60\xed\xa5\xa7\x68\x03\xf4\xaa\x11\x30\xc2\x7b\x28\xb6\x92\x57\xd1\x51\xb6\x45\xc7\x89\xca\x5f\x9c\x71\x26\x03\xc7\x4d\x7b\x24\x35\x7e\xad\x57\x9e\x01\x73\x8c\x44\x81\xca\xd2\x12\x29\x92\x12\x1d\xf3\x9b\x2c\x27\x1a\x2a\xe5\x97\x76\x96\xd7\x8c\xfc\xa8\xe1\x1f\x3d\x44\xcb\x1a\xdc\x71\x4b\xc9\xc5\xf2\x03\xef\x24\xaf\x45\x21\x90\x6c\x6c\x7d\xde\x12\x72\xcc\xab\x0a\xb1\xa5\x1c\xe0\x1c\x3e\x12\x24\x3f\x09\xb3\x99\xe9\x55\xfd\x1c\xe6\xab\x71\x36\x6b\x59\x01\x6e\xe2\xfc\x4c\x5d\x3a\xee\xd4\x71\xb7\x6e\xa2\x22\xaf\x25\x4e\xf5\xd2\x66\x4e\x24\x77\x90\x1a\x07\xb2\x2c\xaf\x49\x99\x0e\xde\x9d\x03\xae\x78\x69\xaf\x9b\xd5\xd5\x06\xe4\xc4\x25\x6d\xcf\x9a\xfe\x5e\xaf\x7c\x6f\x1c\xed\x6b\x44\x18\xc8\x82\xa1\x2a\x26\xab\x1c\x4b\x28\x81\x69\x82\x68\xa1\x04\x60\x0b\x3e\x68\x6a\x46\x33\x79\x52\xd4\xcc\x25\xec\x88\xd2\xf2\xe8\x45\x9e\xb8\x30\x17\x56\x82\x00\x56\xaa\xa2\xeb\x01\x52\x03\x9c\x35\xc0\xd8\x10\x2c\x1a\x26\x4a\x36\x17\xb8\xbb\x61\x9a\xd0\xdd\xac\x2d\x77\x08\x0b\x05\x48\xe2\xfd\x85\xf4\xbc\x42\x84\xa5\x28\x15\x98\x96\x47\xc1\x49\x17\xc6\xde\x5d\x7c\x02\x76\x28\x46\xbb\x39\x5b\x0c\xc0\x0e\x44\x72\x56\x0d\x41\x3a\x2d\x81\x1a\xf4\xcf\x82\x2b\xb8\x3e\x38\xf6\x14\x0f\x03\xe3\x37\xa3\x4f\xaf\x6d\xe9\xe5\x5b\x2e\x2b\xd4\x2c\x76\x98\xdb\xf4\x61\x6b\xaa\xa9\xe5\x99\x02\x34\x79\x68\x0a\x5f\x44\x0b\x4a\xd8\xe3\xf2\x26\x0e\xcf\x5a\xa2\x62\xcf\x95\xbe\xa4\x46\xc9\xf7\x80\xa8\xde\xe3\x3d\xe0\xc7\x19\x72\x13\x65\x51\x73\xa5\x53\x8c\x9c\x54\x68\x17\x07\x09\x1c\x83\x5c\x5c\x8b\xe5\x8b\x0a\xdf\x18\x96\xef\x76\x0d\x34\x64\x71\x93\xda\xbe\x7f\x1d\xab\x8a\x4b\x49\x0e\x20\x53\x4b\x5c\x2e\x4e\x2d\x89\xfb\x32\x25\x9b\x47\xfb\x33\x0b\xfa\xed\xae\x6b\xcf\x66\xbc\xaa\xfd\x8f\xd2\x7c\x3d\x4d\x99\xd3\xa4\xe9\x3e\x71\x38\x4c\xab\x73\x2d\xad\x54\x08\x37\xe5\xac\x04\x15\xd0\xeb\x09\xda\x6f\x78\x14\x93\x9c\x7f\xc2\x4e\xc0\x93\xc4\x1a\x8a\xd4\x67\x27\xc2\xec\xa2\x0e\x2b\x49\x75\xd1\x16\x3b\xc2\x4d\x68\x79\xa9\xcb\x3c\x2d\x37\x6e\x62\x2d\x0e\x51\x82\x14\xc4\x9d\x3d\x28\x48\x6b\x34\x22\x0e\x5f\x12\x6d\xc2\x47\xfb\xd7\x59\xda\x00\x69\x70\xcc\xf4\xd6\x2d\x32\x94\x59\xa2\x52\xea\x5d\xc8\x3a\x5e\xb4\xbe\x66\x67\x29\xec\xc2\xdb\x8e\x15\x6d\x84\x30\x1d\x4c\x70\xa9\x7f\x4b\x2f\x74\x8a\x53\xa7\x84\xdf\x4d\x3e\x6d\x8f\x5c\x75\x27\x11\xbd\x4e\x4f\x35\x13\xa5\x3c\x68\x4f\x47\x45\x98\x86\x5d\xd3\xca\xf8\x93\x40\xbd\xa1\x44\xed\xa1\x3c\x87\x46\x72\xcd\x31\xa7\x69\x8e\xe1\xdd\xa0\x49\x77\x86\x99\xfe\xea\xa2\xda\x4c\x48\x72\x20\x14\x76\x0e\xc7\x1b\xce\x29\x20\x66\x25\x0a\x09\xa8\x2c\x38\xa3\xc7\x04\xa4\xd2\x48\x46\x77\x25\x14\xe0\x5a\x12\x7d\x2c\xb8\xd0\x8b\x57\x85\x6a\x5f\x15\x8a\xfc\x04\xdb\xf7\x4e\x56\xdf\x0f\xb4\x76\x16\xe4\x6c\x71\x67\x7f\xb6\x22\xfe\x6f\xb6\x22\xd4\x51\x61\x7d\x59\x6d\xad\x74\x49\x58\xc1\x05\xb0\xa8\x6f\x28\xcd\x45\xb1\x93\x08\x43\x21\x40\x12\xee\x15\x85\x15\x60\xcb\x5a\xa2\x66\xfe\xe9\x30\x8a\xec\x18\xf2\xc7\x1d\x03\xaa\x2b\xb1\xbd\x70\x13\x40\xeb\xb8\xb3\xd7\x94\x54\x24\xec\x34\x1e\xab\x4d\xa8\xd7\xba\x5a\xcd\x5f\xa2\xcd\x94\x67\x49\x21\x7b\xa6\x43\x98\x6f\x10\x12\x3a\x83\x3d\x92\x67\xa4\x8e\xd6\x31\xb7\x81\xfc\xe4\xeb\x1b\xbc\xeb\xb2\x0e\xab\xdb\xf1\x6e\xfa\x85\xac\xbd\xf8\xb3\x4a\x2f\x77\x19\xeb\x60\xf5\xe3\x77\xaa\x5a\x45\x9b\xb8\x16\xc3\xd4\x5c\x03\x32\x42\xa7\xa7\xae\xd9\x7f\x45\x84\xb6\x74\xd4\xc2\x3d\xba\x49\x88\xe3\xfd\x4c\x89\xb1\xf3\xb5\xa3\x7e\x72\x45\x60\xd0\x60\xce\x14\x51\x1a\x18\xf6\xef\xaf\x7a\x89\x36\x64\x72\x78\x31\x15\xca\x7c\xdf\x95\xd6\x75\xb5\x28\xb4\xeb\xe2\x6d\x72\xa3\x93\xee\xab\xfd\x81\xfc\x6f\x61\x85\x71\xcc\x45\x40\x35\xe9\x6c\x9c\x9b\x66\x9d\xad\x8b\x99\x3a\x34\x14\x32\x9e\xb8\x7c\x6c\x12\x52\x49\xfc\x91\x63\xe5\x90\x9c\x71\xa4\xef\xec\xf5\x0d\x03\xf8\xce\xaa\x4d\x68\xf4\x6c\x7f\xfe\xdc\xbc\x07\x05\xcf\xb4\x89\x42\x1b\xe7\x5c\xc2\x97\x68\x9b\xcc\x20\x0f\xf1\x7c\x2f\x41\x4b\xe2\x1c\x25\x0c\x45\x93\x99\xdb\x41\xbd\xcf\x0d\x77\x4d\x2a\xe0\xb5\x3f\x0c\xad\x4c\xc3\xe9\x89\x72\xe3\xcc\x3f\xa2\x54\x03\xe9\xea\xf4\xc1\x38\x40\xea\xfa\xf2\xa8\xe2\x52\x12\x16\xb0\xb2\x3d\xda\x48\xca\x6e\x12\x04\x25\x18\xa9\x58\x05\x71\xc5\x2e\x70\x2d\x4a\xa4\xa1\xe8\xaf\x8d\x9c\x53\xb3\xcd\x14\x6b\x02\x49\x44\x29\x50\xa2\xaa\x94\xe2\x27\x2f\x81\x22\x6f\xf4\x8f\xd6\xbd\x2d\xf9\x16\x11\x5a\x4b\x28\x10\x0e\x86\x69\x87\xa2\xe2\x8c\x68\xee\x0d\x27\x69\x53\x56\xe8\xb9\x18\xa6\x6d\x21\xb1\x96\xc4\xee\xc6\x53\x37\x70\x0d\x4b\xe8\x72\xf7\x79\x65\xf5\x8c\x8a\x4e\x45\x7a\xc0\x62\x86\x19\x27\xac\x4b\x50\x4d\xd8\x19\xf7\xd7\xa3\xf4\xd1\x00\xdf\x6f\x0f\x14\x82\x53\xd2\x55\x01\x4b\x70\x88\x39\xeb\x84\x9c\x62\x10\x57\x5a\x60\x63\x0e\x4d\x0f\x53\x09\x1d\x75\xd6\x96\xe0\x89\xb0\x92\x3f\x9d\x31\xe1\x72\xa6\x24\x28\xc2\xe0\x04\xc7\x6b\x05\xad\xb4\x44\x84\xe9\xb3\x8f\x93\x5c\xb1\x08\x09\x5b\x90\xc0\xa6\x86\x9e\xcd\x97\xf5\x59\xb8\xb4\x8f\xf1\x16\xe7\xb0\x47\x28\xd1\xd4\xb7\x6f\xb0\xab\x77\xad\xf2\xaf\x28\x90\x46\x2f\x8e\x24\xd2\x11\x17\x2d\x8d\x42\xc9\x13\x8b\x3a\x7a\x34\x55\x41\xc5\xe7\xaf\x61\x5c\x71\x11\x39\xc6\xe2\x00\x5b\xa0\x50\x48\x3a\xcb\xec\x51\x05\x17\xcb\x6f\xa6\xc4\xcf\x2b\xd7\xf1\xb0\x4d\x04\xaa\x96\x8a\x21\xc9\xa7\xbb\xb9\xb7\x52\xc9\xde\x41\x74\xa8\x37\x2c\xd0\x2b\xbf\xef\xe8\x60\xdf\x9c\x68\x2f\x66\x04\xb4\xfa\x30\xb6\x21\x37\xa3\xac\xd6\xc9\x2a\x0e\xde\x8a\x58\x6e\xfd\x6d\x47\xe4\xee\x80\xfa\x5a\x27\xa4\x35\xc2\xfb\xa4\x2e\xeb\xcc\xd2\xfa\x8a\x38\x34\xd9\x0b\xf0\x86\xa1\x1e\xf5\x27\x0a\xfd\x8f\xd8\xec\xef\xb3\xaf\xfe\x5b\x88\xe8\x9d\xfc\x16\x75\x71\x1e\x4f\xb8\x52\xf9\x0e\x74\xf6\xc6\xaa\x98\x24\x31\xaf\x2a\x7a\xd4\x1f\x55\xbc\xaa\x57\xd8\xa7\x5d\x86\x4a\xa6\x9b\x5f\x73\x92\x3c\xf7\x2b\x86\xb5\xbd\x0c\x17\xe6\xf9\x72\xd0\xae\x6b\xe6\xce\xc2\x07\x48\x60\xb3\xd5\x99\xb4\x17\xe2\x3c\xe7\x0b\xc6\xfd\xbb\x4f\x33\xd5\xdb\xdc\xd5\xb9\x57\x2a\x7b\x16\xb8\x67\xe0\xd7\xa9\xd3\x18\x0f\xd2\x9d\x7e\x1c\x15\xf6\xff\x81\x7e\xf2\xa9\x54\xc3\x27\x3b\x4e\x36\x67\x7f\xd9\x27\x4b\xdd\x67\x4e\x6b\x4b\x3e\x0e\xa4\xbb\x88\x6a\x24\xda\xb5\xb9\x57\x10\xbc\x39\xef\xfb\x80\xca\x3d\xd7\x1a\x3e\x64\x0a\x1c\xb5\xaf\xcc\xbf\xed\x47\x67\xab\x97\xd5\x7f\x02\x00\x00\xff\xff\x8b\xd2\x8d\x87\xde\x3b\x00\x00") + +func dataConfig_schema_v34JsonBytes() ([]byte, error) { + return bindataRead( + _dataConfig_schema_v34Json, + "data/config_schema_v3.4.json", + ) +} + +func dataConfig_schema_v34Json() (*asset, error) { + bytes, err := dataConfig_schema_v34JsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "data/config_schema_v3.4.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + // Asset loads and returns the asset for the given name. // It returns an error if the asset could not be found or // could not be loaded. @@ -207,6 +228,7 @@ var _bindata = map[string]func() (*asset, error){ "data/config_schema_v3.1.json": dataConfig_schema_v31Json, "data/config_schema_v3.2.json": dataConfig_schema_v32Json, "data/config_schema_v3.3.json": dataConfig_schema_v33Json, + "data/config_schema_v3.4.json": dataConfig_schema_v34Json, } // AssetDir returns the file names below a certain @@ -254,6 +276,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "config_schema_v3.1.json": &bintree{dataConfig_schema_v31Json, map[string]*bintree{}}, "config_schema_v3.2.json": &bintree{dataConfig_schema_v32Json, map[string]*bintree{}}, "config_schema_v3.3.json": &bintree{dataConfig_schema_v33Json, map[string]*bintree{}}, + "config_schema_v3.4.json": &bintree{dataConfig_schema_v34Json, map[string]*bintree{}}, }}, }} diff --git a/components/cli/cli/compose/schema/data/config_schema_v3.4.json b/components/cli/cli/compose/schema/data/config_schema_v3.4.json new file mode 100644 index 0000000000..2457a2de81 --- /dev/null +++ b/components/cli/cli/compose/schema/data/config_schema_v3.4.json @@ -0,0 +1,534 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "config_schema_v3.4.json", + "type": "object", + "required": ["version"], + + "properties": { + "version": { + "type": "string" + }, + + "services": { + "id": "#/properties/services", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/service" + } + }, + "additionalProperties": false + }, + + "networks": { + "id": "#/properties/networks", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/network" + } + } + }, + + "volumes": { + "id": "#/properties/volumes", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/volume" + } + }, + "additionalProperties": false + }, + + "secrets": { + "id": "#/properties/secrets", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/secret" + } + }, + "additionalProperties": false + }, + + "configs": { + "id": "#/properties/configs", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/config" + } + }, + "additionalProperties": false + } + }, + + "additionalProperties": false, + + "definitions": { + + "service": { + "id": "#/definitions/service", + "type": "object", + + "properties": { + "deploy": {"$ref": "#/definitions/deployment"}, + "build": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "properties": { + "context": {"type": "string"}, + "dockerfile": {"type": "string"}, + "args": {"$ref": "#/definitions/list_or_dict"}, + "labels": {"$ref": "#/definitions/list_or_dict"}, + "cache_from": {"$ref": "#/definitions/list_of_strings"} + }, + "additionalProperties": false + } + ] + }, + "cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "cgroup_parent": {"type": "string"}, + "command": { + "oneOf": [ + {"type": "string"}, + {"type": "array", "items": {"type": "string"}} + ] + }, + "configs": { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "properties": { + "source": {"type": "string"}, + "target": {"type": "string"}, + "uid": {"type": "string"}, + "gid": {"type": "string"}, + "mode": {"type": "number"} + } + } + ] + } + }, + "container_name": {"type": "string"}, + "credential_spec": {"type": "object", "properties": { + "file": {"type": "string"}, + "registry": {"type": "string"} + }}, + "depends_on": {"$ref": "#/definitions/list_of_strings"}, + "devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "dns": {"$ref": "#/definitions/string_or_list"}, + "dns_search": {"$ref": "#/definitions/string_or_list"}, + "domainname": {"type": "string"}, + "entrypoint": { + "oneOf": [ + {"type": "string"}, + {"type": "array", "items": {"type": "string"}} + ] + }, + "env_file": {"$ref": "#/definitions/string_or_list"}, + "environment": {"$ref": "#/definitions/list_or_dict"}, + + "expose": { + "type": "array", + "items": { + "type": ["string", "number"], + "format": "expose" + }, + "uniqueItems": true + }, + + "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "extra_hosts": {"$ref": "#/definitions/list_or_dict"}, + "healthcheck": {"$ref": "#/definitions/healthcheck"}, + "hostname": {"type": "string"}, + "image": {"type": "string"}, + "ipc": {"type": "string"}, + "labels": {"$ref": "#/definitions/list_or_dict"}, + "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + + "logging": { + "type": "object", + + "properties": { + "driver": {"type": "string"}, + "options": { + "type": "object", + "patternProperties": { + "^.+$": {"type": ["string", "number", "null"]} + } + } + }, + "additionalProperties": false + }, + + "mac_address": {"type": "string"}, + "network_mode": {"type": "string"}, + + "networks": { + "oneOf": [ + {"$ref": "#/definitions/list_of_strings"}, + { + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "oneOf": [ + { + "type": "object", + "properties": { + "aliases": {"$ref": "#/definitions/list_of_strings"}, + "ipv4_address": {"type": "string"}, + "ipv6_address": {"type": "string"} + }, + "additionalProperties": false + }, + {"type": "null"} + ] + } + }, + "additionalProperties": false + } + ] + }, + "pid": {"type": ["string", "null"]}, + + "ports": { + "type": "array", + "items": { + "oneOf": [ + {"type": "number", "format": "ports"}, + {"type": "string", "format": "ports"}, + { + "type": "object", + "properties": { + "mode": {"type": "string"}, + "target": {"type": "integer"}, + "published": {"type": "integer"}, + "protocol": {"type": "string"} + }, + "additionalProperties": false + } + ] + }, + "uniqueItems": true + }, + + "privileged": {"type": "boolean"}, + "read_only": {"type": "boolean"}, + "restart": {"type": "string"}, + "security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "shm_size": {"type": ["number", "string"]}, + "secrets": { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "properties": { + "source": {"type": "string"}, + "target": {"type": "string"}, + "uid": {"type": "string"}, + "gid": {"type": "string"}, + "mode": {"type": "number"} + } + } + ] + } + }, + "sysctls": {"$ref": "#/definitions/list_or_dict"}, + "stdin_open": {"type": "boolean"}, + "stop_grace_period": {"type": "string", "format": "duration"}, + "stop_signal": {"type": "string"}, + "tmpfs": {"$ref": "#/definitions/string_or_list"}, + "tty": {"type": "boolean"}, + "ulimits": { + "type": "object", + "patternProperties": { + "^[a-z]+$": { + "oneOf": [ + {"type": "integer"}, + { + "type":"object", + "properties": { + "hard": {"type": "integer"}, + "soft": {"type": "integer"} + }, + "required": ["soft", "hard"], + "additionalProperties": false + } + ] + } + } + }, + "user": {"type": "string"}, + "userns_mode": {"type": "string"}, + "volumes": { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "required": ["type"], + "properties": { + "type": {"type": "string"}, + "source": {"type": "string"}, + "target": {"type": "string"}, + "read_only": {"type": "boolean"}, + "consistency": {"type": "string"}, + "bind": { + "type": "object", + "properties": { + "propagation": {"type": "string"} + } + }, + "volume": { + "type": "object", + "properties": { + "nocopy": {"type": "boolean"} + } + } + } + } + ], + "uniqueItems": true + } + }, + "working_dir": {"type": "string"} + }, + "additionalProperties": false + }, + + "healthcheck": { + "id": "#/definitions/healthcheck", + "type": "object", + "additionalProperties": false, + "properties": { + "disable": {"type": "boolean"}, + "interval": {"type": "string"}, + "retries": {"type": "number"}, + "test": { + "oneOf": [ + {"type": "string"}, + {"type": "array", "items": {"type": "string"}} + ] + }, + "timeout": {"type": "string"} + } + }, + "deployment": { + "id": "#/definitions/deployment", + "type": ["object", "null"], + "properties": { + "mode": {"type": "string"}, + "endpoint_mode": {"type": "string"}, + "replicas": {"type": "integer"}, + "labels": {"$ref": "#/definitions/list_or_dict"}, + "update_config": { + "type": "object", + "properties": { + "parallelism": {"type": "integer"}, + "delay": {"type": "string", "format": "duration"}, + "failure_action": {"type": "string"}, + "monitor": {"type": "string", "format": "duration"}, + "max_failure_ratio": {"type": "number"} + }, + "additionalProperties": false + }, + "resources": { + "type": "object", + "properties": { + "limits": {"$ref": "#/definitions/resource"}, + "reservations": {"$ref": "#/definitions/resource"} + } + }, + "restart_policy": { + "type": "object", + "properties": { + "condition": {"type": "string"}, + "delay": {"type": "string", "format": "duration"}, + "max_attempts": {"type": "integer"}, + "window": {"type": "string", "format": "duration"} + }, + "additionalProperties": false + }, + "placement": { + "type": "object", + "properties": { + "constraints": {"type": "array", "items": {"type": "string"}}, + "preferences": { + "type": "array", + "items": { + "type": "object", + "properties": { + "spread": {"type": "string"} + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + + "resource": { + "id": "#/definitions/resource", + "type": "object", + "properties": { + "cpus": {"type": "string"}, + "memory": {"type": "string"} + }, + "additionalProperties": false + }, + + "network": { + "id": "#/definitions/network", + "type": ["object", "null"], + "properties": { + "driver": {"type": "string"}, + "driver_opts": { + "type": "object", + "patternProperties": { + "^.+$": {"type": ["string", "number"]} + } + }, + "ipam": { + "type": "object", + "properties": { + "driver": {"type": "string"}, + "config": { + "type": "array", + "items": { + "type": "object", + "properties": { + "subnet": {"type": "string"} + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + }, + "external": { + "type": ["boolean", "object"], + "properties": { + "name": {"type": "string"} + }, + "additionalProperties": false + }, + "internal": {"type": "boolean"}, + "attachable": {"type": "boolean"}, + "labels": {"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false + }, + + "volume": { + "id": "#/definitions/volume", + "type": ["object", "null"], + "properties": { + "driver": {"type": "string"}, + "driver_opts": { + "type": "object", + "patternProperties": { + "^.+$": {"type": ["string", "number"]} + } + }, + "external": { + "type": ["boolean", "object"], + "properties": { + "name": {"type": "string"} + }, + "additionalProperties": false + }, + "labels": {"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false + }, + + "secret": { + "id": "#/definitions/secret", + "type": "object", + "properties": { + "file": {"type": "string"}, + "external": { + "type": ["boolean", "object"], + "properties": { + "name": {"type": "string"} + } + }, + "labels": {"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false + }, + + "config": { + "id": "#/definitions/config", + "type": "object", + "properties": { + "file": {"type": "string"}, + "external": { + "type": ["boolean", "object"], + "properties": { + "name": {"type": "string"} + } + }, + "labels": {"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false + }, + + "string_or_list": { + "oneOf": [ + {"type": "string"}, + {"$ref": "#/definitions/list_of_strings"} + ] + }, + + "list_of_strings": { + "type": "array", + "items": {"type": "string"}, + "uniqueItems": true + }, + + "list_or_dict": { + "oneOf": [ + { + "type": "object", + "patternProperties": { + ".+": { + "type": ["string", "number", "null"] + } + }, + "additionalProperties": false + }, + {"type": "array", "items": {"type": "string"}, "uniqueItems": true} + ] + }, + + "constraints": { + "service": { + "id": "#/definitions/constraints/service", + "anyOf": [ + {"required": ["build"]}, + {"required": ["image"]} + ], + "properties": { + "build": { + "required": ["context"] + } + } + } + } + } +} From 82bb6886dfb3169c704790e42d605974ab2760fa Mon Sep 17 00:00:00 2001 From: Alex Mavrogiannis Date: Wed, 19 Jul 2017 16:01:13 -0700 Subject: [PATCH 21/62] Skip inspects of built-in networks on stack deploy Signed-off-by: Alex Mavrogiannis Upstream-commit: 7f53c99dfe5241a985dd5ce4bed6c116a2908b41 Component: cli --- components/cli/cli/command/stack/deploy_composefile.go | 7 ++++++- .../cli/cli/command/stack/deploy_composefile_test.go | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/components/cli/cli/command/stack/deploy_composefile.go b/components/cli/cli/command/stack/deploy_composefile.go index 8e5dfed4d5..1f50ae1a1d 100644 --- a/components/cli/cli/command/stack/deploy_composefile.go +++ b/components/cli/cli/command/stack/deploy_composefile.go @@ -171,13 +171,18 @@ func validateExternalNetworks( externalNetworks []string, ) error { for _, networkName := range externalNetworks { + if !container.NetworkMode(networkName).IsUserDefined() { + // Networks that are not user defined always exist on all nodes as + // local-scoped networks, so there's no need to inspect them. + continue + } network, err := client.NetworkInspect(ctx, networkName, types.NetworkInspectOptions{}) switch { case dockerclient.IsErrNotFound(err): return errors.Errorf("network %q is declared as external, but could not be found. You need to create a swarm-scoped network before the stack is deployed", networkName) case err != nil: return err - case container.NetworkMode(networkName).IsUserDefined() && network.Scope != "swarm": + case network.Scope != "swarm": return errors.Errorf("network %q is declared as external, but it is not in the right scope: %q instead of \"swarm\"", networkName, network.Scope) } } diff --git a/components/cli/cli/command/stack/deploy_composefile_test.go b/components/cli/cli/command/stack/deploy_composefile_test.go index 5d4813bc05..f303fc8865 100644 --- a/components/cli/cli/command/stack/deploy_composefile_test.go +++ b/components/cli/cli/command/stack/deploy_composefile_test.go @@ -42,6 +42,8 @@ func (n notFound) NotFound() bool { func TestValidateExternalNetworks(t *testing.T) { var testcases = []struct { + inspected bool + noInspect bool inspectResponse types.NetworkResource inspectError error expectedMsg string @@ -56,7 +58,8 @@ func TestValidateExternalNetworks(t *testing.T) { expectedMsg: "Unexpected", }, { - network: "host", + noInspect: true, + network: "host", }, { network: "user", @@ -71,11 +74,15 @@ func TestValidateExternalNetworks(t *testing.T) { for _, testcase := range testcases { fakeClient := &network.FakeClient{ NetworkInspectFunc: func(_ context.Context, _ string, _ types.NetworkInspectOptions) (types.NetworkResource, error) { + testcase.inspected = true return testcase.inspectResponse, testcase.inspectError }, } networks := []string{testcase.network} err := validateExternalNetworks(context.Background(), fakeClient, networks) + if testcase.noInspect && testcase.inspected { + assert.Fail(t, "expected no network inspect operation but one occurent") + } if testcase.expectedMsg == "" { assert.NoError(t, err) } else { From 0d6798190793dae721d72abc2cb5910aba3d940d Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 20 Jul 2017 12:05:20 -0400 Subject: [PATCH 22/62] Add myself to command/stack codeowners Cleanup a test Signed-off-by: Daniel Nephin Upstream-commit: 60991e943ba749ace778abac4188ad3f29b10e87 Component: cli --- components/cli/.github/CODEOWNERS | 1 + .../cli/cli/command/stack/deploy_composefile_test.go | 10 ++-------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/components/cli/.github/CODEOWNERS b/components/cli/.github/CODEOWNERS index f3164a64b5..a14fab44c3 100644 --- a/components/cli/.github/CODEOWNERS +++ b/components/cli/.github/CODEOWNERS @@ -1,6 +1,7 @@ # Github code owners # See https://github.com/blog/2392-introducing-code-owners +cli/command/stack/** @dnephin @vdemeester cli/compose/** @dnephin @vdemeester contrib/completion/bash/** @albers contrib/completion/zsh/** @sdurrheimer diff --git a/components/cli/cli/command/stack/deploy_composefile_test.go b/components/cli/cli/command/stack/deploy_composefile_test.go index f303fc8865..5d59ff7028 100644 --- a/components/cli/cli/command/stack/deploy_composefile_test.go +++ b/components/cli/cli/command/stack/deploy_composefile_test.go @@ -42,8 +42,6 @@ func (n notFound) NotFound() bool { func TestValidateExternalNetworks(t *testing.T) { var testcases = []struct { - inspected bool - noInspect bool inspectResponse types.NetworkResource inspectError error expectedMsg string @@ -58,8 +56,8 @@ func TestValidateExternalNetworks(t *testing.T) { expectedMsg: "Unexpected", }, { - noInspect: true, - network: "host", + inspectError: errors.New("host net does not exist on swarm classic"), + network: "host", }, { network: "user", @@ -74,15 +72,11 @@ func TestValidateExternalNetworks(t *testing.T) { for _, testcase := range testcases { fakeClient := &network.FakeClient{ NetworkInspectFunc: func(_ context.Context, _ string, _ types.NetworkInspectOptions) (types.NetworkResource, error) { - testcase.inspected = true return testcase.inspectResponse, testcase.inspectError }, } networks := []string{testcase.network} err := validateExternalNetworks(context.Background(), fakeClient, networks) - if testcase.noInspect && testcase.inspected { - assert.Fail(t, "expected no network inspect operation but one occurent") - } if testcase.expectedMsg == "" { assert.NoError(t, err) } else { From 384f10f42ee17d82a8a345f972b634cdaa007796 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 20 Jul 2017 12:11:27 -0400 Subject: [PATCH 23/62] Fix shellcheck on master Signed-off-by: Daniel Nephin Upstream-commit: 14d2c95d4a10503e39770da10128b6190d610437 Component: cli --- components/cli/contrib/completion/bash/docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 9539d50878..66174729d0 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -1184,7 +1184,7 @@ _docker_config_create() { ;; *) local counter=$(__docker_pos_first_nonflag '--label|-l') - if [ $cword -eq $((counter + 1)) ]; then + if [ "$cword" -eq $((counter + 1)) ]; then _filedir fi ;; From 69533b66d73dc8ddae79e716d86aa5655c93aadd Mon Sep 17 00:00:00 2001 From: khaled souf Date: Thu, 20 Jul 2017 13:59:00 +0200 Subject: [PATCH 24/62] adding connect disconnect network tests Signed-off-by: khaled souf Upstream-commit: 7296abf39f84d731843b35a1be793e7295accc05 Component: cli --- .../cli/cli/command/network/client_test.go | 19 ++++- .../cli/cli/command/network/connect_test.go | 70 +++++++++++++++++++ .../cli/command/network/disconnect_test.go | 41 +++++++++++ 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 components/cli/cli/command/network/connect_test.go create mode 100644 components/cli/cli/command/network/disconnect_test.go diff --git a/components/cli/cli/command/network/client_test.go b/components/cli/cli/command/network/client_test.go index 1a5ee4ed81..722c72bd18 100644 --- a/components/cli/cli/command/network/client_test.go +++ b/components/cli/cli/command/network/client_test.go @@ -2,13 +2,16 @@ package network import ( "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" "golang.org/x/net/context" ) type fakeClient struct { client.Client - networkCreateFunc func(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) + networkCreateFunc func(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) + networkConnectFunc func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error + networkDisconnectFunc func(ctx context.Context, networkID, container string, force bool) error } func (c *fakeClient) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) { @@ -17,3 +20,17 @@ func (c *fakeClient) NetworkCreate(ctx context.Context, name string, options typ } return types.NetworkCreateResponse{}, nil } + +func (c *fakeClient) NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error { + if c.networkConnectFunc != nil { + return c.networkConnectFunc(ctx, networkID, container, config) + } + return nil +} + +func (c *fakeClient) NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error { + if c.networkDisconnectFunc != nil { + return c.networkDisconnectFunc(ctx, networkID, container, force) + } + return nil +} diff --git a/components/cli/cli/command/network/connect_test.go b/components/cli/cli/command/network/connect_test.go new file mode 100644 index 0000000000..790ec25c21 --- /dev/null +++ b/components/cli/cli/command/network/connect_test.go @@ -0,0 +1,70 @@ +package network + +import ( + "io/ioutil" + "testing" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/api/types/network" + "github.com/docker/docker/pkg/testutil" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "golang.org/x/net/context" +) + +func TestNetworkConnectErrors(t *testing.T) { + testCases := []struct { + args []string + networkConnectFunc func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error + expectedError string + }{ + { + expectedError: "requires exactly 2 argument(s)", + }, + { + args: []string{"toto", "titi"}, + networkConnectFunc: func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error { + return errors.Errorf("error connecting network") + }, + expectedError: "error connecting network", + }, + } + + for _, tc := range testCases { + cmd := newConnectCommand( + test.NewFakeCli(&fakeClient{ + networkConnectFunc: tc.networkConnectFunc, + }), + ) + cmd.SetArgs(tc.args) + cmd.SetOutput(ioutil.Discard) + testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) + + } +} + +func TestNetworkConnectWithFlags(t *testing.T) { + expectedOpts := []network.IPAMConfig{ + { + "192.168.4.0/24", + "192.168.4.0/24", + "192.168.4.1/24", + map[string]string{}, + }, + } + cli := test.NewFakeCli(&fakeClient{ + networkConnectFunc: func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error { + assert.Equal(t, expectedOpts, config.IPAMConfig, "not expected driver error") + return nil + }, + }) + args := []string{"banana"} + cmd := newCreateCommand(cli) + + cmd.SetArgs(args) + cmd.Flags().Set("driver", "foo") + cmd.Flags().Set("ip-range", "192.168.4.0/24") + cmd.Flags().Set("gateway", "192.168.4.1/24") + cmd.Flags().Set("subnet", "192.168.4.0/24") + assert.NoError(t, cmd.Execute()) +} diff --git a/components/cli/cli/command/network/disconnect_test.go b/components/cli/cli/command/network/disconnect_test.go new file mode 100644 index 0000000000..01cba2ff36 --- /dev/null +++ b/components/cli/cli/command/network/disconnect_test.go @@ -0,0 +1,41 @@ +package network + +import ( + "io/ioutil" + "testing" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/pkg/testutil" + "github.com/pkg/errors" + "golang.org/x/net/context" +) + +func TestNetworkDisconnectErrors(t *testing.T) { + testCases := []struct { + args []string + networkDisconnectFunc func(ctx context.Context, networkID, container string, force bool) error + expectedError string + }{ + { + expectedError: "requires exactly 2 argument(s)", + }, + { + args: []string{"toto", "titi"}, + networkDisconnectFunc: func(ctx context.Context, networkID, container string, force bool) error { + return errors.Errorf("error disconnecting network") + }, + expectedError: "error disconnecting network", + }, + } + + for _, tc := range testCases { + cmd := newDisconnectCommand( + test.NewFakeCli(&fakeClient{ + networkDisconnectFunc: tc.networkDisconnectFunc, + }), + ) + cmd.SetArgs(tc.args) + cmd.SetOutput(ioutil.Discard) + testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) + } +} From a3b41349c580ceb26092878cf004b7ff10686fc2 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Huynh Date: Thu, 20 Jul 2017 23:13:04 +0100 Subject: [PATCH 25/62] Add zsh completion for `system prune --volumes` Signed-off-by: Jean-Pierre Huynh Upstream-commit: 6b256484ae3cb4da78e6ddad75b8aaf552b9ae60 Component: cli --- components/cli/contrib/completion/zsh/_docker | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/zsh/_docker b/components/cli/contrib/completion/zsh/_docker index 075e87aa93..d5eeca2413 100644 --- a/components/cli/contrib/completion/zsh/_docker +++ b/components/cli/contrib/completion/zsh/_docker @@ -2376,7 +2376,8 @@ __docker_system_subcommand() { $opts_help \ "($help -a --all)"{-a,--all}"[Remove all unused data, not just dangling ones]" \ "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \ - "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0 + "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" \ + "($help)--volumes=[Remove all unused volumes]" && ret=0 ;; (help) _arguments $(__docker_arguments) ":subcommand:__docker_volume_commands" && ret=0 From 6adc7715ee348498e97d059c3e4484f95d2e4e61 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Huynh Date: Thu, 20 Jul 2017 23:41:47 +0100 Subject: [PATCH 26/62] Update __docker_get_log_options completion Signed-off-by: Jean-Pierre Huynh Upstream-commit: d7ade64d29965a686ce7933865d273e84f1ccce1 Component: cli --- components/cli/contrib/completion/zsh/_docker | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/components/cli/contrib/completion/zsh/_docker b/components/cli/contrib/completion/zsh/_docker index 075e87aa93..bdb58fe22c 100644 --- a/components/cli/contrib/completion/zsh/_docker +++ b/components/cli/contrib/completion/zsh/_docker @@ -221,18 +221,19 @@ __docker_get_log_options() { integer ret=1 local log_driver=${opt_args[--log-driver]:-"all"} - local -a common_options awslogs_options fluentd_options gelf_options journald_options json_file_options logentries_options syslog_options splunk_options + local -a common_options common_options2 awslogs_options fluentd_options gelf_options journald_options json_file_options logentries_options syslog_options splunk_options common_options=("max-buffer-size" "mode") - awslogs_options=($common_options "awslogs-region" "awslogs-group" "awslogs-stream" "awslogs-create-group") - fluentd_options=($common_options "env" "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "labels" "tag") - gcplogs_options=($common_options "env" "gcp-log-cmd" "gcp-project" "labels") - gelf_options=($common_options "env" "gelf-address" "gelf-compression-level" "gelf-compression-type" "labels" "tag") - journald_options=($common_options "env" "labels" "tag") - json_file_options=($common_options "env" "labels" "max-file" "max-size") - logentries_options=($common_options "logentries-token") - syslog_options=($common_options "env" "labels" "syslog-address" "syslog-facility" "syslog-format" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "tag") - splunk_options=($common_options "env" "labels" "splunk-caname" "splunk-capath" "splunk-format" "splunk-gzip" "splunk-gzip-level" "splunk-index" "splunk-insecureskipverify" "splunk-source" "splunk-sourcetype" "splunk-token" "splunk-url" "splunk-verify-connection" "tag") + common_options2=("env" "env-regex" "labels") + awslogs_options=($common_options "awslogs-create-group" "awslogs-datetime-format" "awslogs-group" "awslogs-multiline-pattern" "awslogs-region" "awslogs-stream" "tag") + fluentd_options=($common_options $common_options2 "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "tag") + gcplogs_options=($common_options $common_options2 "gcp-log-cmd" "gcp-meta-id" "gcp-meta-name" "gcp-meta-zone" "gcp-project") + gelf_options=($common_options $common_options2 "gelf-address" "gelf-compression-level" "gelf-compression-type" "tag") + journald_options=($common_options $common_options2 "tag") + json_file_options=($common_options $common_options2 "max-file" "max-size") + logentries_options=($common_options $common_options2 "logentries-token" "tag") + syslog_options=($common_options $common_options2 "syslog-address" "syslog-facility" "syslog-format" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "tag") + splunk_options=($common_options $common_options2 "splunk-caname" "splunk-capath" "splunk-format" "splunk-gzip" "splunk-gzip-level" "splunk-index" "splunk-insecureskipverify" "splunk-source" "splunk-sourcetype" "splunk-token" "splunk-url" "splunk-verify-connection" "tag") [[ $log_driver = (awslogs|all) ]] && _describe -t awslogs-options "awslogs options" awslogs_options "$@" && ret=0 [[ $log_driver = (fluentd|all) ]] && _describe -t fluentd-options "fluentd options" fluentd_options "$@" && ret=0 From 49215da962d3430dc31b1ea726c50e19d61203fb Mon Sep 17 00:00:00 2001 From: Jean-Pierre Huynh Date: Fri, 21 Jul 2017 09:53:43 +0100 Subject: [PATCH 27/62] Remove duplicate publish option in docker service create/update completion Signed-off-by: Jean-Pierre Huynh Upstream-commit: 6c65ba6c0836ed14501cb40ad2d82cdde6fd168d Component: cli --- components/cli/contrib/completion/zsh/_docker | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/cli/contrib/completion/zsh/_docker b/components/cli/contrib/completion/zsh/_docker index 075e87aa93..47a49add56 100644 --- a/components/cli/contrib/completion/zsh/_docker +++ b/components/cli/contrib/completion/zsh/_docker @@ -1960,7 +1960,6 @@ __docker_service_subcommand() { "($help)*--mount=[Attach a filesystem mount to the service]:mount: " "($help)*--network=[Network attachments]:network: " "($help)--no-healthcheck[Disable any container-specified HEALTHCHECK]" - "($help)*"{-p=,--publish=}"[Publish a port as a node port]:port: " "($help)--read-only[Mount the container's root filesystem as read only]" "($help)--replicas=[Number of tasks]:replicas: " "($help)--reserve-cpu=[Reserve CPUs]:value: " @@ -2001,7 +2000,7 @@ __docker_service_subcommand() { "($help)--mode=[Service Mode]:mode:(global replicated)" \ "($help)--name=[Service name]:name: " \ "($help)*--placement-pref=[Add a placement preference]:pref:__docker_service_complete_placement_pref" \ - "($help)*--publish=[Publish a port]:port: " \ + "($help)*"{-p=,--publish=}"[Publish a port as a node port]:port: " \ "($help -): :__docker_complete_images" \ "($help -):command: _command_names -e" \ "($help -)*::arguments: _normal" && ret=0 From 53b038fa762b6a67defaf6950aa655e09aee4c2b Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 8 Jul 2017 16:11:57 -0700 Subject: [PATCH 28/62] Error if "until" filter is combined with "--volumes" on system prune The "until" filter is supported by all object types, except for volumes. Before this patch, the "until" filter would attempted to be used for the volume prune endpoint, resulting in an error being returned by the daemon, and further prune endpoints (networks, images) to be skipped. $ docker system prune --filter until=24h --filter label=label.foo=bar WARNING! This will remove: - all stopped containers - all volumes not used by at least one container - all networks not used by at least one container - all dangling images Are you sure you want to continue? [y/N] y Error response from daemon: Invalid filter 'until' Calling POST /v1.30/containers/prune?filters=%7B%22label%22%3A%7B%22label.foo%3D%3Dbar%22%3Atrue%7D%2C%22until%22%3A%7B%2224h%22%3Atrue%7D%7D Calling POST /v1.30/volumes/prune?filters=%7B%22label%22%3A%7B%22label.foo%3D%3Dbar%22%3Atrue%7D%2C%22until%22%3A%7B%2224h%22%3Atrue%7D%7D Handler for POST /v1.30/volumes/prune returned error: Invalid filter 'until' Error response from daemon: Invalid filter 'until' With this patch, an error is produced instead, preventing "partial" prune. $ docker system prune --filter until=24h --filter label=foo==bar --volumes ERROR: The "until" filter is not supported with "--volumes" Note that `docker volume prune` does not have this problem, and produces an error if the `until` filter is used; $ docker volume prune --filter until=24h WARNING! This will remove all volumes not used by at least one container. Are you sure you want to continue? [y/N] y Error response from daemon: Invalid filter 'until' Signed-off-by: Sebastiaan van Stijn Upstream-commit: 3c095dc546e9c90afcfb1ca1695b408d813b4306 Component: cli --- components/cli/cli/command/system/prune.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/cli/cli/command/system/prune.go b/components/cli/cli/command/system/prune.go index c0bc434fb0..d76d995e37 100644 --- a/components/cli/cli/command/system/prune.go +++ b/components/cli/cli/command/system/prune.go @@ -67,6 +67,10 @@ func runBuildCachePrune(dockerCli command.Cli, _ opts.FilterOpt) (uint64, string } func runPrune(dockerCli command.Cli, options pruneOptions) error { + // TODO version this once "until" filter is supported for volumes + if options.pruneVolumes && options.filter.Value().Include("until") { + return fmt.Errorf(`ERROR: The "until" filter is not supported with "--volumes"`) + } if versions.LessThan(dockerCli.Client().ClientVersion(), "1.31") { options.pruneBuildCache = false } From c6ce3f33024f04fd8b3cc64606651b2731f48f4f Mon Sep 17 00:00:00 2001 From: Jean-Pierre Huynh Date: Wed, 19 Jul 2017 16:44:39 +0100 Subject: [PATCH 29/62] Update README and add help target to make Signed-off-by: Jean-Pierre Huynh Upstream-commit: 649a5864f302d9ddc95b9adc5c77059d00fe1648 Component: cli --- components/cli/Makefile | 37 ++++++++++++++++++------------------- components/cli/README.md | 6 ++++++ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/components/cli/Makefile b/components/cli/Makefile index 926b39b25b..771f496abe 100644 --- a/components/cli/Makefile +++ b/components/cli/Makefile @@ -3,62 +3,61 @@ # all: binary -# remove build artifacts + .PHONY: clean -clean: +clean: ## remove build artifacts rm -rf ./build/* cli/winresources/rsrc_* ./man/man[1-9] docs/yaml/gen -# run go test -# the "-tags daemon" part is temporary .PHONY: test -test: +test: ## run go test ./scripts/test/unit $(shell go list ./... | grep -v '/vendor/') .PHONY: test-coverage -test-coverage: +test-coverage: ## run test coverage ./scripts/test/unit-with-coverage $(shell go list ./... | grep -v '/vendor/') .PHONY: lint -lint: +lint: ## run all the lint tools gometalinter --config gometalinter.json ./... .PHONY: binary -binary: +binary: ## build executable for Linux @echo "WARNING: binary creates a Linux executable. Use cross for macOS or Windows." ./scripts/build/binary .PHONY: cross -cross: +cross: ## build executable for macOS and Windows ./scripts/build/cross .PHONY: dynbinary -dynbinary: +dynbinary: ## build dynamically linked binary ./scripts/build/dynbinary .PHONY: watch -watch: +watch: ## monitor file changes and run go test ./scripts/test/watch -# Check vendor matches vendor.conf -vendor: vendor.conf +vendor: vendor.conf ## check that vendor matches vendor.conf vndr 2> /dev/null scripts/validate/check-git-diff vendor -## generate man pages from go source and markdown .PHONY: manpages -manpages: +manpages: ## generate man pages from go source and markdown scripts/docs/generate-man.sh -## generate documentation YAML files consumed by docs repo .PHONY: yamldocs -yamldocs: +yamldocs: ## generate documentation YAML files consumed by docs repo scripts/docs/generate-yaml.sh -## Shellcheck validation .PHONY: shellcheck -shellcheck: +shellcheck: ## run shellcheck validation scripts/validate/shellcheck +.PHONY: help +help: ## print this help + @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) + + cli/compose/schema/bindata.go: cli/compose/schema/data/*.json go generate github.com/docker/cli/cli/compose/schema diff --git a/components/cli/README.md b/components/cli/README.md index 340556d8c7..496d13f23c 100644 --- a/components/cli/README.md +++ b/components/cli/README.md @@ -29,6 +29,12 @@ Run all linting: $ make -f docker.Makefile lint ``` +List all the available targets: + +``` +$ make help +``` + ### In-container development environment Start an interactive development environment: From 04720d7b97dbeb3781a99ab90cc2d9ccc90117fc Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 22 Jul 2017 03:13:52 +0200 Subject: [PATCH 30/62] Bump version to 17.08.0-dev Signed-off-by: Sebastiaan van Stijn Upstream-commit: a8bcbfd9e009300812da97c690b73351222c26ee Component: cli --- components/cli/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/VERSION b/components/cli/VERSION index 3e9257aa26..fd2cab4039 100644 --- a/components/cli/VERSION +++ b/components/cli/VERSION @@ -1 +1 @@ -17.07.0-dev +17.08.0-dev From c394e66cf8299cea94a18c27a450a7a13ffa1ef5 Mon Sep 17 00:00:00 2001 From: Hernan Garcia Date: Mon, 24 Jul 2017 05:14:39 -0500 Subject: [PATCH 31/62] fixed word network on volume_ls.md Signed-off-by: Hernan Garcia Upstream-commit: f5bca7af10b378453376ebf7428de1c3c064547b Component: cli --- components/cli/docs/reference/commandline/volume_ls.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/cli/docs/reference/commandline/volume_ls.md b/components/cli/docs/reference/commandline/volume_ls.md index 713922d60f..6a6e85225c 100644 --- a/components/cli/docs/reference/commandline/volume_ls.md +++ b/components/cli/docs/reference/commandline/volume_ls.md @@ -168,11 +168,11 @@ Valid placeholders for the Go template are listed below: Placeholder | Description --------------|------------------------------------------------------------------------------------------ -`.Name` | Network name -`.Driver` | Network driver -`.Scope` | Network scope (local, global) -`.Mountpoint` | Whether the network is internal or not. -`.Labels` | All labels assigned to the volume. +`.Name` | Volume name +`.Driver` | Volume driver +`.Scope` | Volume scope (local, global) +`.Mountpoint` | The mount point of the volume on the host +`.Labels` | All labels assigned to the volume `.Label` | Value of a specific label for this volume. For example `{{.Label "project.version"}}` When using the `--format` option, the `volume ls` command will either From 77f384f48bb193e50824fb46412f29cdd1f07f7d Mon Sep 17 00:00:00 2001 From: Jean-Pierre Huynh Date: Tue, 25 Jul 2017 09:24:35 +0100 Subject: [PATCH 32/62] Add metric plugins to zsh completion for `plugin ls --filter capability` Signed-off-by: Jean-Pierre Huynh Upstream-commit: ff614383285c77d629fad4987eb64e5dd8f05b65 Component: cli --- components/cli/contrib/completion/zsh/_docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/zsh/_docker b/components/cli/contrib/completion/zsh/_docker index 6cc1da7948..cf6cc795a6 100644 --- a/components/cli/contrib/completion/zsh/_docker +++ b/components/cli/contrib/completion/zsh/_docker @@ -1521,7 +1521,7 @@ __docker_plugin_complete_ls_filters() { if compset -P '*='; then case "${${words[-1]%=*}#*=}" in (capability) - opts=('authz' 'ipamdriver' 'networkdriver' 'volumedriver') + opts=('authz' 'ipamdriver' 'logdriver' 'metricscollector' 'networkdriver' 'volumedriver') _describe -t capability-opts "capability options" opts && ret=0 ;; (enabled) From 5e49f90082819029a5f238e52c32e1cbd6117acc Mon Sep 17 00:00:00 2001 From: Christophe Robin Date: Wed, 26 Jul 2017 10:59:25 +0900 Subject: [PATCH 33/62] Add support for stop-signal in stack command Signed-off-by: Christophe Robin Upstream-commit: b129a70b5c6275e12d66cc1b5a729b4460577e35 Component: cli --- components/cli/cli/compose/convert/service.go | 1 + components/cli/cli/compose/types/types.go | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/cli/compose/convert/service.go b/components/cli/cli/compose/convert/service.go index 730f5e1ee5..165995d95c 100644 --- a/components/cli/cli/compose/convert/service.go +++ b/components/cli/cli/compose/convert/service.go @@ -142,6 +142,7 @@ func Service( User: service.User, Mounts: mounts, StopGracePeriod: service.StopGracePeriod, + StopSignal: service.StopSignal, TTY: service.Tty, OpenStdin: service.StdinOpen, Secrets: secrets, diff --git a/components/cli/cli/compose/types/types.go b/components/cli/cli/compose/types/types.go index 1eecc124f6..3f4b72f208 100644 --- a/components/cli/cli/compose/types/types.go +++ b/components/cli/cli/compose/types/types.go @@ -21,7 +21,6 @@ var UnsupportedProperties = []string{ "restart", "security_opt", "shm_size", - "stop_signal", "sysctls", "tmpfs", "userns_mode", From 36e04981d5576680824e74199ad6e1a7f29c7d31 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Huynh Date: Thu, 27 Jul 2017 07:48:39 +0100 Subject: [PATCH 34/62] Add zsh completion for `docker service scale --detach=false` Signed-off-by: Jean-Pierre Huynh Upstream-commit: 04d905f6fa851fe035e803e44571fe78788d87b7 Component: cli --- components/cli/contrib/completion/zsh/_docker | 1 + 1 file changed, 1 insertion(+) diff --git a/components/cli/contrib/completion/zsh/_docker b/components/cli/contrib/completion/zsh/_docker index cf6cc795a6..6e0c55b4dd 100644 --- a/components/cli/contrib/completion/zsh/_docker +++ b/components/cli/contrib/completion/zsh/_docker @@ -2040,6 +2040,7 @@ __docker_service_subcommand() { (scale) _arguments $(__docker_arguments) \ $opts_help \ + "($help -d --detach)"{-d=false,--detach=false}"[Disable detached mode]" \ "($help -)*:service:->values" && ret=0 case $state in (values) From 4fc5710ae55b7391217fa8ef4b6f9494de290fa1 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Wed, 26 Jul 2017 11:31:30 +0200 Subject: [PATCH 35/62] Fix sort order of options in bash completion See guidelines at the top of the script: # Note for developers: # Please arrange options sorted alphabetically by long name with the # short options immediately following their corresponding long form. # This order should be applied to lists, alternatives and code blocks. Signed-off-by: Harald Albers Upstream-commit: 393dc4a8c4026e0811fce1035f998965e4f409bf Component: cli --- components/cli/contrib/completion/bash/docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 66174729d0..42df4a9fa9 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -2851,7 +2851,7 @@ _docker_login() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help --password --password-stdin -p --username -u" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help --password -p --password-stdin --username -u" -- "$cur" ) ) ;; esac } From eb0bdbb81b186a697f4339123d64a75e4c06a3fa Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Wed, 26 Jul 2017 11:42:49 +0200 Subject: [PATCH 36/62] Add bash completion for `service scale --detach` Signed-off-by: Harald Albers Upstream-commit: 29d0f868e8db53842f54a1ef35478dad391d8b07 Component: cli --- components/cli/contrib/completion/bash/docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 66174729d0..8b92d632aa 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -3199,7 +3199,7 @@ _docker_service_rm() { _docker_service_scale() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--detach=false -d=false --help" -- "$cur" ) ) ;; *) __docker_complete_services From bb26636fb01048ad6241b931d0b31842d2b7f69f Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Wed, 26 Jul 2017 13:06:22 +0200 Subject: [PATCH 37/62] Add file completion to bash completion for `secret create` Signed-off-by: Harald Albers Upstream-commit: abc793e3331336183fe9ea8e3c462ec11a9f4ca7 Component: cli --- components/cli/contrib/completion/bash/docker | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 66174729d0..e8939e0967 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -1184,7 +1184,7 @@ _docker_config_create() { ;; *) local counter=$(__docker_pos_first_nonflag '--label|-l') - if [ "$cword" -eq $((counter + 1)) ]; then + if [ "$cword" -eq "$((counter + 1))" ]; then _filedir fi ;; @@ -4159,6 +4159,12 @@ _docker_secret_create() { -*) COMPREPLY=( $( compgen -W "--help --label -l" -- "$cur" ) ) ;; + *) + local counter=$(__docker_pos_first_nonflag '--label|-l') + if [ "$cword" -eq "$((counter + 1))" ]; then + _filedir + fi + ;; esac } From 05b4b48f443761d9a047c89d68d60116acd18acf Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Wed, 26 Jul 2017 13:52:52 +0200 Subject: [PATCH 38/62] Add support for redirections in bash completion for `docker save|load` Signed-off-by: Harald Albers Upstream-commit: 1862ac1e633f497c88dcf3f9bafc2a43f1394889 Component: cli --- components/cli/contrib/completion/bash/docker | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 66174729d0..06412ad1ed 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -2579,7 +2579,7 @@ _docker_image_inspect() { _docker_image_load() { case "$prev" in - --input|-i) + --input|-i|"<") _filedir return ;; @@ -2710,7 +2710,7 @@ _docker_image_rmi() { _docker_image_save() { case "$prev" in - --output|-o) + --output|-o|">") _filedir return ;; From ba32b46d687392f67be93fe2551cd2db773f0fb9 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 27 Jul 2017 22:05:31 +0200 Subject: [PATCH 39/62] Docs: update filter options for docker container ps The `is-task` filter was only documented in the usage section, but this section is not used in the documentation. This patch adds the missing filter, synchronises the man page source, and does some slight rephrasing and reformatting of the filters. Signed-off-by: Sebastiaan van Stijn Upstream-commit: 46064f33f4755ee4550ae1b940c5611666dd83e8 Component: cli --- .../cli/docs/reference/commandline/ps.md | 25 ++++---- components/cli/man/src/container/ls.md | 59 +++++++++++-------- 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/components/cli/docs/reference/commandline/ps.md b/components/cli/docs/reference/commandline/ps.md index 167e5d73be..596cf75a57 100644 --- a/components/cli/docs/reference/commandline/ps.md +++ b/components/cli/docs/reference/commandline/ps.md @@ -84,18 +84,19 @@ The currently supported filters are: | Filter | Description | |:----------------------|:-------------------------------------------------------------------------------------------------------------------------------------| -| `id` | container's ID | -| `name` | container's name | -| `label` | An arbitrary string representing either a key or a key-value pair | +| `id` | Container's ID | +| `name` | Container's name | +| `label` | An arbitrary string representing either a key or a key-value pair. Expressed as `` or `=` | | `exited` | An integer representing the container's exit code. Only useful with `--all`. | -| `status` | One of `created|restarting|running|removing|paused|exited|dead` | +| `status` | One of `created`, `restarting`, `running`, `removing`, `paused`, `exited`, or `dead` | | `ancestor` | Filters containers which share a given image as an ancestor. Expressed as `[:]`, ``, or `` | | `before` or `since` | Filters containers created before or after a given container ID or name | | `volume` | Filters running containers which have mounted a given volume or bind mount. | | `network` | Filters running containers connected to a given network. | -| `publish` or `expose` | Filters containers which publish or expose a given port. | -| `health` | One of `starting|healthy|unhealthy|none`. Filters containers based on their healthcheck status. | -| `isolation` | Windows daemon only. One of `default|process|hyperv`. | +| `publish` or `expose` | Filters containers which publish or expose a given port. Expressed as `[/]` or `/[]` | +| `health` | Filters containers based on their healthcheck status. One of `starting`, `healthy`, `unhealthy` or `none`. | +| `isolation` | Windows daemon only. One of `default`, `process`, or `hyperv`. | +| `is-task` | Filters containers that are a "task" for a service. Boolean option (`true` or `false`) | #### label @@ -208,11 +209,11 @@ CONTAINER ID IMAGE COMMAND CREATED The `ancestor` filter matches containers based on its image or a descendant of it. The filter supports the following image representation: -- image -- image:tag -- image:tag@digest -- short-id -- full-id +- `image` +- `image:tag` +- `image:tag@digest` +- `short-id` +- `full-id` If you don't specify a `tag`, the `latest` tag is used. For example, to filter for containers that use the latest `ubuntu` image: diff --git a/components/cli/man/src/container/ls.md b/components/cli/man/src/container/ls.md index 5cb63079ec..93a87efcab 100644 --- a/components/cli/man/src/container/ls.md +++ b/components/cli/man/src/container/ls.md @@ -4,39 +4,46 @@ the running containers. ## Filters Filter output based on these conditions: - - exited= an exit code of - - label= or label== - - status=(created|restarting|running|paused|exited|dead) - - name= a container's name - - id= a container's ID - - is-task=(true|false) - containers that are a task (part of a service managed by swarm) + - ancestor=([:tag]||) + containers created from an image or a descendant. - before=(|) + - expose=([/]|/[]) + - exited= an exit code of + - health=(starting|healthy|unhealthy|none) + - id= a container's ID + - isolation=(`default`|`process`|`hyperv`) (Windows daemon only) + - is-task=(true|false) + - label= or label== + - name= a container's name + - network=(|) + - publish=([/]|/[]) - since=(|) - - ancestor=([:tag]||) - containers created from an image or a descendant. - - volume=(|) - - network=(|) - containers connected to the provided network - - health=(starting|healthy|unhealthy|none) - filters containers based on healthcheck status - - publish=([/]|/[]) - filters containers based on published ports - - expose=([/]|/[]) - filters containers based on exposed ports + - status=(created|restarting|removing|running|paused|exited) + - volume=(|) ## Format - Pretty-print containers using a Go template. - Valid placeholders: - .ID - Container ID - .Image - Image ID - .Command - Quoted command - .CreatedAt - Time when the container was created. - .RunningFor - Elapsed time since the container was started. - .Ports - Exposed ports. - .Status - Container status. - .Size - Container disk size. - .Names - Container names. - .Labels - All labels assigned to the container. - .Label - Value of a specific label for this container. For example `{{.Label "com.docker.swarm.cpu"}}` - .Mounts - Names of the volumes mounted in this container. +The formatting option (**--format**) pretty-prints container output +using a Go template. + +Valid placeholders for the Go template are listed below: + - .ID - Container ID. + - .Image - Image ID. + - .Command - Quoted command. + - .CreatedAt - Time when the container was created. + - .RunningFor - Elapsed time since the container was started. + - .Ports - Exposed ports. + - .Status - Container status. + - .Size - Container disk size. + - .Names - Container names. + - .Labels - All labels assigned to the container. + - .Label - Value of a specific label for this container. + For example **'{{.Label "com.docker.swarm.cpu"}}'**. + - .Mounts - Names of the volumes mounted in this container. + - .Networks - Names of the networks attached to this container. # EXAMPLES + ## Display all containers, including non-running $ docker container ls -a From 3c0b1df0ba47dfa4867912955efa981448b1ecc9 Mon Sep 17 00:00:00 2001 From: Darren Stahl Date: Wed, 26 Jul 2017 12:11:02 -0700 Subject: [PATCH 40/62] Fast fail when save directory does not exist Signed-off-by: Darren Stahl Upstream-commit: 18c877d35cd1b70a796184211aa8ae030259bf19 Component: cli --- components/cli/cli/command/image/save.go | 16 ++++++++++++++++ components/cli/cli/command/image/save_test.go | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/components/cli/cli/command/image/save.go b/components/cli/cli/command/image/save.go index ba666d2740..9cae97b370 100644 --- a/components/cli/cli/command/image/save.go +++ b/components/cli/cli/command/image/save.go @@ -2,6 +2,8 @@ package image import ( "io" + "os" + "path/filepath" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -41,6 +43,10 @@ func runSave(dockerCli command.Cli, opts saveOptions) error { return errors.New("cowardly refusing to save to a terminal. Use the -o flag or redirect") } + if err := validateOutputPath(opts.output); err != nil { + return errors.Wrap(err, "failed to save image") + } + responseBody, err := dockerCli.Client().ImageSave(context.Background(), opts.images) if err != nil { return err @@ -54,3 +60,13 @@ func runSave(dockerCli command.Cli, opts saveOptions) error { return command.CopyToFile(opts.output, responseBody) } + +func validateOutputPath(path string) error { + dir := filepath.Dir(path) + if dir != "" && dir != "." { + if _, err := os.Stat(dir); os.IsNotExist(err) { + return errors.Errorf("unable to validate output path: directory %q does not exist", dir) + } + } + return nil +} diff --git a/components/cli/cli/command/image/save_test.go b/components/cli/cli/command/image/save_test.go index c63eeef41c..1cac4c5749 100644 --- a/components/cli/cli/command/image/save_test.go +++ b/components/cli/cli/command/image/save_test.go @@ -43,6 +43,11 @@ func TestNewSaveCommandErrors(t *testing.T) { return ioutil.NopCloser(strings.NewReader("")), errors.Errorf("error saving image") }, }, + { + name: "output directory does not exist", + args: []string{"-o", "fakedir/out.tar", "arg1"}, + expectedError: "failed to save image: unable to validate output path: directory \"fakedir\" does not exist", + }, } for _, tc := range testCases { cli := test.NewFakeCli(&fakeClient{imageSaveFunc: tc.imageSaveFunc}) From 337a036e64395b57a863fd8a4ab9d9336260f552 Mon Sep 17 00:00:00 2001 From: Liping Xue Date: Thu, 29 Jun 2017 16:25:50 -0700 Subject: [PATCH 41/62] Change to enable volume name can be customized. Signed-off-by: Liping Xue Change to enable volume name can be customized. Signed-off-by: Liping Xue Change to enable volume name can be customized. Remove unused debug info. Address comments from Daniel and solve the lint error. Signed-off-by: Liping Xue Address Daniel's comments to print warning message when name of external volume is set in loader code. Signed-off-by: Liping Xue Address Daniel's comments to return error when external volume is set in loader code. Signed-off-by: Liping Xue Address Daniel's comments to return error when external volume is set in loader code. Signed-off-by: Liping Xue Remove the case that specifying external volume name in full-example.yml. More fix. Add unit test. Signed-off-by: Liping Xue Address comments from Daniel, move the schema change to v3.4. Signed-off-by: Liping Xue Address comments from Sebastiaan. Signed-off-by: Liping Xue Address comments from Misty. Signed-off-by: Liping Xue Upstream-commit: 27a30808252d713e2691c492915984396a501a92 Component: cli --- components/cli/cli/compose/convert/volume.go | 4 ++ .../cli/cli/compose/convert/volume_test.go | 47 +++++++++++++++++++ .../cli/cli/compose/loader/full-example.yml | 18 ++++++- components/cli/cli/compose/loader/loader.go | 6 +++ .../cli/cli/compose/loader/loader_test.go | 31 ++++++++++++ components/cli/cli/compose/schema/bindata.go | 2 +- .../schema/data/config_schema_v3.4.json | 1 + components/cli/cli/compose/types/types.go | 2 + 8 files changed, 109 insertions(+), 2 deletions(-) diff --git a/components/cli/cli/compose/convert/volume.go b/components/cli/cli/compose/convert/volume.go index e767b07ee9..8400f8d523 100644 --- a/components/cli/cli/compose/convert/volume.go +++ b/components/cli/cli/compose/convert/volume.go @@ -74,6 +74,10 @@ func convertVolumeToMount( return result, nil } + if stackVolume.Name != "" { + result.Source = stackVolume.Name + } + result.VolumeOptions.Labels = AddStackLabel(namespace, stackVolume.Labels) if stackVolume.Driver != "" || stackVolume.DriverOpts != nil { result.VolumeOptions.DriverConfig = &mount.Driver{ diff --git a/components/cli/cli/compose/convert/volume_test.go b/components/cli/cli/compose/convert/volume_test.go index c3d3c1d54e..9e921701a0 100644 --- a/components/cli/cli/compose/convert/volume_test.go +++ b/components/cli/cli/compose/convert/volume_test.go @@ -98,6 +98,53 @@ func TestConvertVolumeToMountNamedVolume(t *testing.T) { assert.Equal(t, expected, mount) } +func TestConvertVolumeToMountNamedVolumeWithNameCustomizd(t *testing.T) { + stackVolumes := volumes{ + "normal": composetypes.VolumeConfig{ + Name: "user_specified_name", + Driver: "vsphere", + DriverOpts: map[string]string{ + "opt": "value", + }, + Labels: map[string]string{ + "something": "labeled", + }, + }, + } + namespace := NewNamespace("foo") + expected := mount.Mount{ + Type: mount.TypeVolume, + Source: "user_specified_name", + Target: "/foo", + ReadOnly: true, + VolumeOptions: &mount.VolumeOptions{ + Labels: map[string]string{ + LabelNamespace: "foo", + "something": "labeled", + }, + DriverConfig: &mount.Driver{ + Name: "vsphere", + Options: map[string]string{ + "opt": "value", + }, + }, + NoCopy: true, + }, + } + config := composetypes.ServiceVolumeConfig{ + Type: "volume", + Source: "normal", + Target: "/foo", + ReadOnly: true, + Volume: &composetypes.ServiceVolumeVolume{ + NoCopy: true, + }, + } + mount, err := convertVolumeToMount(config, stackVolumes, namespace) + assert.NoError(t, err) + assert.Equal(t, expected, mount) +} + func TestConvertVolumeToMountNamedVolumeExternal(t *testing.T) { stackVolumes := volumes{ "outside": composetypes.VolumeConfig{ diff --git a/components/cli/cli/compose/loader/full-example.yml b/components/cli/cli/compose/loader/full-example.yml index 76087c57ba..347dbf5136 100644 --- a/components/cli/cli/compose/loader/full-example.yml +++ b/components/cli/cli/compose/loader/full-example.yml @@ -1,4 +1,4 @@ -version: "3.3" +version: "3.4" services: foo: @@ -280,6 +280,15 @@ volumes: foo: "bar" baz: 1 + another-volume: + name: "user_specified_name" + driver: vsphere + + driver_opts: + # Values can be strings or numbers + foo: "bar" + baz: 1 + external-volume: # Specifies that a pre-existing volume called "external-volume" # can be referred to within this file as "external-volume" @@ -288,5 +297,12 @@ volumes: other-external-volume: # Specifies that a pre-existing volume called "my-cool-volume" # can be referred to within this file as "other-external-volume" + # This example uses the deprecated "volume.external.name" (replaced by "volume.name") external: name: my-cool-volume + + external-volume3: + # Specifies that a pre-existing volume called "this-is-volume3" + # can be referred to within this file as "external-volume3" + name: this-is-volume3 + external: true diff --git a/components/cli/cli/compose/loader/loader.go b/components/cli/cli/compose/loader/loader.go index b456e1824d..2fb2630087 100644 --- a/components/cli/cli/compose/loader/loader.go +++ b/components/cli/cli/compose/loader/loader.go @@ -444,6 +444,12 @@ func LoadVolumes(source map[string]interface{}) (map[string]types.VolumeConfig, if volume.External.Name == "" { volume.External.Name = name volumes[name] = volume + } else { + logrus.Warnf("volume %s: volume.external.name is deprecated in favor of volume.name", name) + + if volume.Name != "" { + return nil, errors.Errorf("volume %s: volume.external.name and volume.name conflict; only use volume.name", name) + } } } } diff --git a/components/cli/cli/compose/loader/loader_test.go b/components/cli/cli/compose/loader/loader_test.go index 6a43e52121..231109a1e8 100644 --- a/components/cli/cli/compose/loader/loader_test.go +++ b/components/cli/cli/compose/loader/loader_test.go @@ -628,6 +628,22 @@ volumes: assert.Contains(t, err.Error(), "external_volume") } +func TestInvalidExternalNameAndNameCombination(t *testing.T) { + _, err := loadYAML(` +version: "3.4" +volumes: + external_volume: + name: user_specified_name + external: + name: external_name +`) + + assert.Error(t, err) + fmt.Println(err) + assert.Contains(t, err.Error(), "volume.external.name and volume.name conflict; only use volume.name") + assert.Contains(t, err.Error(), "external_volume") +} + func durationPtr(value time.Duration) *time.Duration { return &value } @@ -983,6 +999,14 @@ func TestFullExample(t *testing.T) { "baz": "1", }, }, + "another-volume": { + Name: "user_specified_name", + Driver: "vsphere", + DriverOpts: map[string]string{ + "foo": "bar", + "baz": "1", + }, + }, "external-volume": { External: types.External{ Name: "external-volume", @@ -995,6 +1019,13 @@ func TestFullExample(t *testing.T) { External: true, }, }, + "external-volume3": { + Name: "this-is-volume3", + External: types.External{ + Name: "external-volume3", + External: true, + }, + }, } assert.Equal(t, expectedVolumeConfig, config.Volumes) diff --git a/components/cli/cli/compose/schema/bindata.go b/components/cli/cli/compose/schema/bindata.go index cba2c1e17c..f5301bc5c9 100644 --- a/components/cli/cli/compose/schema/bindata.go +++ b/components/cli/cli/compose/schema/bindata.go @@ -152,7 +152,7 @@ func dataConfig_schema_v33Json() (*asset, error) { return a, nil } -var _dataConfig_schema_v34Json = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\xcd\x93\xdb\xa0\x15\xbf\xfb\xaf\xd0\x28\xb9\x65\x3f\x32\xd3\x4c\x67\x9a\x5b\x8f\x3d\xb5\xe7\xee\x38\x1a\x8c\x9e\x6d\xb2\x08\x08\x20\xef\x3a\x99\xfd\xdf\x3b\xfa\x34\x20\x10\xd8\xd6\x66\xb7\x6d\x4e\xbb\x96\x7e\x0f\x78\xdf\xef\x01\xfa\xb5\xca\xb2\xfc\xa3\xc2\x7b\xa8\x50\xfe\x35\xcb\xf7\x5a\x8b\xaf\xf7\xf7\xdf\x15\x67\xb7\xdd\xd3\x3b\x2e\x77\xf7\xa5\x44\x5b\x7d\xfb\xf9\xcb\x7d\xf7\xec\x43\x7e\xd3\xd0\x91\xb2\x21\xc1\x9c\x6d\xc9\xae\xe8\xde\x14\x87\xbf\xdc\x7d\xb9\x6b\xc8\x3b\x88\x3e\x0a\x68\x40\x7c\xf3\x1d\xb0\xee\x9e\x49\xf8\x51\x13\x09\x0d\xf1\x43\x7e\x00\xa9\x08\x67\xf9\xfa\x66\xd5\xbc\x13\x92\x0b\x90\x9a\x80\xca\xbf\x66\xcd\xe2\xb2\x6c\x84\x0c\x0f\x8c\x61\x95\x96\x84\xed\xf2\xf6\xf1\x4b\x3b\x42\x96\xe5\x0a\xe4\x81\x60\x63\x84\x71\xa9\x1f\xee\x4f\xe3\xdf\x8f\xb0\x1b\x77\x54\x63\xb1\xed\x73\x81\xb4\x06\xc9\xfe\x35\x5d\x5b\xfb\xfa\xdb\x03\xba\xfd\xf9\xf7\xdb\x7f\x7f\xbe\xfd\xdb\x5d\x71\xbb\xfe\xf4\xd1\x7a\xdd\xc8\x57\xc2\xb6\x9b\xbe\x84\x2d\x61\x44\x13\xce\xc6\xf9\xf3\x11\xf9\xd2\xff\xf7\x32\x4e\x8c\xca\xb2\x05\x23\x6a\xcd\xbd\x45\x54\x81\xcd\x33\x03\xfd\xc4\xe5\x63\x8c\xe7\x11\xf6\x46\x3c\xf7\xf3\x7b\x78\xb6\xd9\x39\x70\x5a\x57\x51\x0d\x0e\xa8\x37\x62\xa6\x9b\x7e\x19\xfd\x29\xc0\x12\x74\xdc\x64\x3b\xd4\x9b\x59\x6c\x33\xfd\x32\x0c\x77\x51\x23\xc6\xf0\x80\x7a\x23\x86\xbb\xe9\xaf\x63\x78\x35\x30\x3d\x8b\xed\x10\xc6\xdc\xed\x02\xad\x78\xe6\x13\x95\x2f\x9e\x84\x65\x35\x0a\x2b\x20\xa5\x12\x04\xe5\xc7\xe6\x59\x40\x1e\x1d\xa0\x02\xa6\xf3\x51\x04\x59\x96\x6f\x6a\x42\x4b\x57\xa2\x9c\xc1\x3f\x9b\x21\x1e\x8c\x87\x59\xf6\xcb\x0d\xdd\xc6\x38\xed\x7b\xeb\x57\x58\xe1\xe3\xfb\x00\x2f\xe3\x7b\xcc\x99\x86\x67\xdd\x32\x35\x3f\x75\x27\x02\x8e\x1f\x41\x6e\x09\x85\x54\x0a\x24\x3b\x2b\x0e\x88\x8c\x12\xa5\x0b\x2e\x8b\x92\x60\xed\xa5\xa7\x68\x03\xf4\xaa\x11\x30\xc2\x7b\x28\xb6\x92\x57\xd1\x51\xb6\x45\xc7\x89\xca\x5f\x9c\x71\x26\x03\xc7\x4d\x7b\x24\x35\x7e\xad\x57\x9e\x01\x73\x8c\x44\x81\xca\xd2\x12\x29\x92\x12\x1d\xf3\x9b\x2c\x27\x1a\x2a\xe5\x97\x76\x96\xd7\x8c\xfc\xa8\xe1\x1f\x3d\x44\xcb\x1a\xdc\x71\x4b\xc9\xc5\xf2\x03\xef\x24\xaf\x45\x21\x90\x6c\x6c\x7d\xde\x12\x72\xcc\xab\x0a\xb1\xa5\x1c\xe0\x1c\x3e\x12\x24\x3f\x09\xb3\x99\xe9\x55\xfd\x1c\xe6\xab\x71\x36\x6b\x59\x01\x6e\xe2\xfc\x4c\x5d\x3a\xee\xd4\x71\xb7\x6e\xa2\x22\xaf\x25\x4e\xf5\xd2\x66\x4e\x24\x77\x90\x1a\x07\xb2\x2c\xaf\x49\x99\x0e\xde\x9d\x03\xae\x78\x69\xaf\x9b\xd5\xd5\x06\xe4\xc4\x25\x6d\xcf\x9a\xfe\x5e\xaf\x7c\x6f\x1c\xed\x6b\x44\x18\xc8\x82\xa1\x2a\x26\xab\x1c\x4b\x28\x81\x69\x82\x68\xa1\x04\x60\x0b\x3e\x68\x6a\x46\x33\x79\x52\xd4\xcc\x25\xec\x88\xd2\xf2\xe8\x45\x9e\xb8\x30\x17\x56\x82\x00\x56\xaa\xa2\xeb\x01\x52\x03\x9c\x35\xc0\xd8\x10\x2c\x1a\x26\x4a\x36\x17\xb8\xbb\x61\x9a\xd0\xdd\xac\x2d\x77\x08\x0b\x05\x48\xe2\xfd\x85\xf4\xbc\x42\x84\xa5\x28\x15\x98\x96\x47\xc1\x49\x17\xc6\xde\x5d\x7c\x02\x76\x28\x46\xbb\x39\x5b\x0c\xc0\x0e\x44\x72\x56\x0d\x41\x3a\x2d\x81\x1a\xf4\xcf\x82\x2b\xb8\x3e\x38\xf6\x14\x0f\x03\xe3\x37\xa3\x4f\xaf\x6d\xe9\xe5\x5b\x2e\x2b\xd4\x2c\x76\x98\xdb\xf4\x61\x6b\xaa\xa9\xe5\x99\x02\x34\x79\x68\x0a\x5f\x44\x0b\x4a\xd8\xe3\xf2\x26\x0e\xcf\x5a\xa2\x62\xcf\x95\xbe\xa4\x46\xc9\xf7\x80\xa8\xde\xe3\x3d\xe0\xc7\x19\x72\x13\x65\x51\x73\xa5\x53\x8c\x9c\x54\x68\x17\x07\x09\x1c\x83\x5c\x5c\x8b\xe5\x8b\x0a\xdf\x18\x96\xef\x76\x0d\x34\x64\x71\x93\xda\xbe\x7f\x1d\xab\x8a\x4b\x49\x0e\x20\x53\x4b\x5c\x2e\x4e\x2d\x89\xfb\x32\x25\x9b\x47\xfb\x33\x0b\xfa\xed\xae\x6b\xcf\x66\xbc\xaa\xfd\x8f\xd2\x7c\x3d\x4d\x99\xd3\xa4\xe9\x3e\x71\x38\x4c\xab\x73\x2d\xad\x54\x08\x37\xe5\xac\x04\x15\xd0\xeb\x09\xda\x6f\x78\x14\x93\x9c\x7f\xc2\x4e\xc0\x93\xc4\x1a\x8a\xd4\x67\x27\xc2\xec\xa2\x0e\x2b\x49\x75\xd1\x16\x3b\xc2\x4d\x68\x79\xa9\xcb\x3c\x2d\x37\x6e\x62\x2d\x0e\x51\x82\x14\xc4\x9d\x3d\x28\x48\x6b\x34\x22\x0e\x5f\x12\x6d\xc2\x47\xfb\xd7\x59\xda\x00\x69\x70\xcc\xf4\xd6\x2d\x32\x94\x59\xa2\x52\xea\x5d\xc8\x3a\x5e\xb4\xbe\x66\x67\x29\xec\xc2\xdb\x8e\x15\x6d\x84\x30\x1d\x4c\x70\xa9\x7f\x4b\x2f\x74\x8a\x53\xa7\x84\xdf\x4d\x3e\x6d\x8f\x5c\x75\x27\x11\xbd\x4e\x4f\x35\x13\xa5\x3c\x68\x4f\x47\x45\x98\x86\x5d\xd3\xca\xf8\x93\x40\xbd\xa1\x44\xed\xa1\x3c\x87\x46\x72\xcd\x31\xa7\x69\x8e\xe1\xdd\xa0\x49\x77\x86\x99\xfe\xea\xa2\xda\x4c\x48\x72\x20\x14\x76\x0e\xc7\x1b\xce\x29\x20\x66\x25\x0a\x09\xa8\x2c\x38\xa3\xc7\x04\xa4\xd2\x48\x46\x77\x25\x14\xe0\x5a\x12\x7d\x2c\xb8\xd0\x8b\x57\x85\x6a\x5f\x15\x8a\xfc\x04\xdb\xf7\x4e\x56\xdf\x0f\xb4\x76\x16\xe4\x6c\x71\x67\x7f\xb6\x22\xfe\x6f\xb6\x22\xd4\x51\x61\x7d\x59\x6d\xad\x74\x49\x58\xc1\x05\xb0\xa8\x6f\x28\xcd\x45\xb1\x93\x08\x43\x21\x40\x12\xee\x15\x85\x15\x60\xcb\x5a\xa2\x66\xfe\xe9\x30\x8a\xec\x18\xf2\xc7\x1d\x03\xaa\x2b\xb1\xbd\x70\x13\x40\xeb\xb8\xb3\xd7\x94\x54\x24\xec\x34\x1e\xab\x4d\xa8\xd7\xba\x5a\xcd\x5f\xa2\xcd\x94\x67\x49\x21\x7b\xa6\x43\x98\x6f\x10\x12\x3a\x83\x3d\x92\x67\xa4\x8e\xd6\x31\xb7\x81\xfc\xe4\xeb\x1b\xbc\xeb\xb2\x0e\xab\xdb\xf1\x6e\xfa\x85\xac\xbd\xf8\xb3\x4a\x2f\x77\x19\xeb\x60\xf5\xe3\x77\xaa\x5a\x45\x9b\xb8\x16\xc3\xd4\x5c\x03\x32\x42\xa7\xa7\xae\xd9\x7f\x45\x84\xb6\x74\xd4\xc2\x3d\xba\x49\x88\xe3\xfd\x4c\x89\xb1\xf3\xb5\xa3\x7e\x72\x45\x60\xd0\x60\xce\x14\x51\x1a\x18\xf6\xef\xaf\x7a\x89\x36\x64\x72\x78\x31\x15\xca\x7c\xdf\x95\xd6\x75\xb5\x28\xb4\xeb\xe2\x6d\x72\xa3\x93\xee\xab\xfd\x81\xfc\x6f\x61\x85\x71\xcc\x45\x40\x35\xe9\x6c\x9c\x9b\x66\x9d\xad\x8b\x99\x3a\x34\x14\x32\x9e\xb8\x7c\x6c\x12\x52\x49\xfc\x91\x63\xe5\x90\x9c\x71\xa4\xef\xec\xf5\x0d\x03\xf8\xce\xaa\x4d\x68\xf4\x6c\x7f\xfe\xdc\xbc\x07\x05\xcf\xb4\x89\x42\x1b\xe7\x5c\xc2\x97\x68\x9b\xcc\x20\x0f\xf1\x7c\x2f\x41\x4b\xe2\x1c\x25\x0c\x45\x93\x99\xdb\x41\xbd\xcf\x0d\x77\x4d\x2a\xe0\xb5\x3f\x0c\xad\x4c\xc3\xe9\x89\x72\xe3\xcc\x3f\xa2\x54\x03\xe9\xea\xf4\xc1\x38\x40\xea\xfa\xf2\xa8\xe2\x52\x12\x16\xb0\xb2\x3d\xda\x48\xca\x6e\x12\x04\x25\x18\xa9\x58\x05\x71\xc5\x2e\x70\x2d\x4a\xa4\xa1\xe8\xaf\x8d\x9c\x53\xb3\xcd\x14\x6b\x02\x49\x44\x29\x50\xa2\xaa\x94\xe2\x27\x2f\x81\x22\x6f\xf4\x8f\xd6\xbd\x2d\xf9\x16\x11\x5a\x4b\x28\x10\x0e\x86\x69\x87\xa2\xe2\x8c\x68\xee\x0d\x27\x69\x53\x56\xe8\xb9\x18\xa6\x6d\x21\xb1\x96\xc4\xee\xc6\x53\x37\x70\x0d\x4b\xe8\x72\xf7\x79\x65\xf5\x8c\x8a\x4e\x45\x7a\xc0\x62\x86\x19\x27\xac\x4b\x50\x4d\xd8\x19\xf7\xd7\xa3\xf4\xd1\x00\xdf\x6f\x0f\x14\x82\x53\xd2\x55\x01\x4b\x70\x88\x39\xeb\x84\x9c\x62\x10\x57\x5a\x60\x63\x0e\x4d\x0f\x53\x09\x1d\x75\xd6\x96\xe0\x89\xb0\x92\x3f\x9d\x31\xe1\x72\xa6\x24\x28\xc2\xe0\x04\xc7\x6b\x05\xad\xb4\x44\x84\xe9\xb3\x8f\x93\x5c\xb1\x08\x09\x5b\x90\xc0\xa6\x86\x9e\xcd\x97\xf5\x59\xb8\xb4\x8f\xf1\x16\xe7\xb0\x47\x28\xd1\xd4\xb7\x6f\xb0\xab\x77\xad\xf2\xaf\x28\x90\x46\x2f\x8e\x24\xd2\x11\x17\x2d\x8d\x42\xc9\x13\x8b\x3a\x7a\x34\x55\x41\xc5\xe7\xaf\x61\x5c\x71\x11\x39\xc6\xe2\x00\x5b\xa0\x50\x48\x3a\xcb\xec\x51\x05\x17\xcb\x6f\xa6\xc4\xcf\x2b\xd7\xf1\xb0\x4d\x04\xaa\x96\x8a\x21\xc9\xa7\xbb\xb9\xb7\x52\xc9\xde\x41\x74\xa8\x37\x2c\xd0\x2b\xbf\xef\xe8\x60\xdf\x9c\x68\x2f\x66\x04\xb4\xfa\x30\xb6\x21\x37\xa3\xac\xd6\xc9\x2a\x0e\xde\x8a\x58\x6e\xfd\x6d\x47\xe4\xee\x80\xfa\x5a\x27\xa4\x35\xc2\xfb\xa4\x2e\xeb\xcc\xd2\xfa\x8a\x38\x34\xd9\x0b\xf0\x86\xa1\x1e\xf5\x27\x0a\xfd\x8f\xd8\xec\xef\xb3\xaf\xfe\x5b\x88\xe8\x9d\xfc\x16\x75\x71\x1e\x4f\xb8\x52\xf9\x0e\x74\xf6\xc6\xaa\x98\x24\x31\xaf\x2a\x7a\xd4\x1f\x55\xbc\xaa\x57\xd8\xa7\x5d\x86\x4a\xa6\x9b\x5f\x73\x92\x3c\xf7\x2b\x86\xb5\xbd\x0c\x17\xe6\xf9\x72\xd0\xae\x6b\xe6\xce\xc2\x07\x48\x60\xb3\xd5\x99\xb4\x17\xe2\x3c\xe7\x0b\xc6\xfd\xbb\x4f\x33\xd5\xdb\xdc\xd5\xb9\x57\x2a\x7b\x16\xb8\x67\xe0\xd7\xa9\xd3\x18\x0f\xd2\x9d\x7e\x1c\x15\xf6\xff\x81\x7e\xf2\xa9\x54\xc3\x27\x3b\x4e\x36\x67\x7f\xd9\x27\x4b\xdd\x67\x4e\x6b\x4b\x3e\x0e\xa4\xbb\x88\x6a\x24\xda\xb5\xb9\x57\x10\xbc\x39\xef\xfb\x80\xca\x3d\xd7\x1a\x3e\x64\x0a\x1c\xb5\xaf\xcc\xbf\xed\x47\x67\xab\x97\xd5\x7f\x02\x00\x00\xff\xff\x8b\xd2\x8d\x87\xde\x3b\x00\x00") +var _dataConfig_schema_v34Json = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x4b\x93\xdb\x2a\x16\xde\xfb\x57\xa8\x74\xef\x2e\xfd\x48\xd5\xa4\xa6\x6a\xb2\x9b\xe5\xac\x66\xd6\xd3\xe5\xa8\x30\x3a\xb6\x49\x23\x20\x80\xdc\xed\xa4\xfa\xbf\x4f\xe9\x69\x40\x20\xb0\xad\x4e\x77\xe6\x66\xd5\x6d\xe9\x3b\xc0\x79\x9f\x03\xe8\xc7\x2a\xcb\xf2\x3f\x15\xde\x43\x85\xf2\xcf\x59\xbe\xd7\x5a\x7c\xbe\xbf\xff\xaa\x38\xbb\xed\x9e\xde\x71\xb9\xbb\x2f\x25\xda\xea\xdb\x8f\x9f\xee\xbb\x67\x7f\xe4\x37\x0d\x1d\x29\x1b\x12\xcc\xd9\x96\xec\x8a\xee\x4d\x71\xf8\xdb\xdd\xa7\xbb\x86\xbc\x83\xe8\xa3\x80\x06\xc4\x37\x5f\x01\xeb\xee\x99\x84\x6f\x35\x91\xd0\x10\x3f\xe4\x07\x90\x8a\x70\x96\xaf\x6f\x56\xcd\x3b\x21\xb9\x00\xa9\x09\xa8\xfc\x73\xd6\x2c\x2e\xcb\x46\xc8\xf0\xc0\x18\x56\x69\x49\xd8\x2e\x6f\x1f\xbf\xb4\x23\x64\x59\xae\x40\x1e\x08\x36\x46\x18\x97\xfa\xc7\xfd\x69\xfc\xfb\x11\x76\xe3\x8e\x6a\x2c\xb6\x7d\x2e\x90\xd6\x20\xd9\x7f\xa6\x6b\x6b\x5f\x7f\x79\x40\xb7\xdf\xff\x79\xfb\xdf\x8f\xb7\xff\xb8\x2b\x6e\xd7\x1f\xfe\xb4\x5e\x37\xf2\x95\xb0\xed\xa6\x2f\x61\x4b\x18\xd1\x84\xb3\x71\xfe\x7c\x44\xbe\xf4\xff\xbd\x8c\x13\xa3\xb2\x6c\xc1\x88\x5a\x73\x6f\x11\x55\x60\xf3\xcc\x40\x3f\x71\xf9\x18\xe3\x79\x84\xbd\x11\xcf\xfd\xfc\x1e\x9e\x6d\x76\x0e\x9c\xd6\x55\x54\x83\x03\xea\x8d\x98\xe9\xa6\x5f\x46\x7f\x0a\xb0\x04\x1d\x37\xd9\x0e\xf5\x66\x16\xdb\x4c\xbf\x0c\xc3\x5d\xd4\x88\x31\x3c\xa0\xde\x88\xe1\x6e\xfa\xeb\x18\x5e\x0d\x4c\xcf\x62\x3b\x84\x31\x77\xbb\x40\x2b\x9e\xf9\x44\xe5\x8b\x27\x61\x59\x8d\xc2\x0a\x48\xa9\x04\x41\xf9\xb1\x79\x16\x90\x47\x07\xa8\x80\xe9\x7c\x14\x41\x96\xe5\x9b\x9a\xd0\xd2\x95\x28\x67\xf0\xef\x66\x88\x07\xe3\x61\x96\xfd\x70\x43\xb7\x31\x4e\xfb\xde\xfa\x15\x56\xf8\xf8\x3e\xc0\xcb\xf8\x1e\x73\xa6\xe1\x59\xb7\x4c\xcd\x4f\xdd\x89\x80\xe3\x47\x90\x5b\x42\x21\x95\x02\xc9\xce\x8a\x03\x22\xa3\x44\xe9\x82\xcb\xa2\x24\x58\x7b\xe9\x29\xda\x00\xbd\x6a\x04\x8c\xf0\x1e\x8a\xad\xe4\x55\x74\x94\x6d\xd1\x71\xa2\xf2\x17\x67\x9c\xc9\xc0\x71\xd3\x1e\x49\x8d\x5f\xeb\x95\x67\xc0\x1c\x23\x51\xa0\xb2\xb4\x44\x8a\xa4\x44\xc7\xfc\x26\xcb\x89\x86\x4a\xf9\xa5\x9d\xe5\x35\x23\xdf\x6a\xf8\x57\x0f\xd1\xb2\x06\x77\xdc\x52\x72\xb1\xfc\xc0\x3b\xc9\x6b\x51\x08\x24\x1b\x5b\x9f\xb7\x84\x1c\xf3\xaa\x42\x6c\x29\x07\x38\x87\x8f\x04\xc9\x4f\xc2\x6c\x66\x7a\x55\x3f\x87\xf9\x6a\x9c\xcd\x5a\x56\x80\x9b\x38\x3f\x53\x97\x8e\x3b\x75\xdc\xad\x9b\xa8\xc8\x6b\x89\x53\xbd\xb4\x99\x13\xc9\x1d\xa4\xc6\x81\x2c\xcb\x6b\x52\xa6\x83\x77\xe7\x80\x2b\x5e\xda\xeb\x66\x75\xb5\x01\x39\x71\x49\xdb\xb3\xa6\xbf\xd7\x2b\xdf\x1b\x47\xfb\x1a\x11\x06\xb2\x60\xa8\x8a\xc9\x2a\xc7\x12\x4a\x60\x9a\x20\x5a\x28\x01\xd8\x82\x0f\x9a\x9a\xd1\x4c\x9e\x14\x35\x73\x09\x3b\xa2\xb4\x3c\x7a\x91\x27\x2e\xcc\x85\x95\x20\x80\x95\xaa\xe8\x7a\x80\xd4\x00\x67\x0d\x30\x36\x04\x8b\x86\x89\x92\xcd\x05\xee\x6e\x98\x26\x74\x37\x6b\xcb\x1d\xc2\x42\x01\x92\x78\x7f\x21\x3d\xaf\x10\x61\x29\x4a\x05\xa6\xe5\x51\x70\xd2\x85\xb1\x77\x17\x9f\x80\x1d\x8a\xd1\x6e\xce\x16\x03\xb0\x03\x91\x9c\x55\x43\x90\x4e\x4b\xa0\x06\xfd\xb3\xe0\x0a\xae\x0f\x8e\x3d\xc5\xc3\xc0\xf8\xcd\xe8\xd3\x6b\x5b\x7a\xf9\x96\xcb\x0a\x35\x8b\x1d\xe6\x36\x7d\xd8\x9a\x6a\x6a\x79\xa6\x00\x4d\x1e\x9a\xc2\x17\xd1\x82\x12\xf6\xb8\xbc\x89\xc3\xb3\x96\xa8\xd8\x73\xa5\x2f\xa9\x51\xf2\x3d\x20\xaa\xf7\x78\x0f\xf8\x71\x86\xdc\x44\x59\xd4\x5c\xe9\x14\x23\x27\x15\xda\xc5\x41\x02\xc7\x20\x17\xd7\x62\xf9\xa2\xc2\x37\x86\xe5\xbb\x5d\x03\x0d\x59\xdc\xa4\xb6\xef\x5f\xc7\xaa\xe2\x52\x92\x03\xc8\xd4\x12\x97\x8b\x53\x4b\xe2\xbe\x4c\xc9\xe6\xd1\xfe\xcc\x82\x7e\xb9\xeb\xda\xb3\x19\xaf\x6a\xff\xa3\x34\x5f\x4f\x53\xe6\x34\x69\xba\x4f\x1c\x0e\xd3\xea\x5c\x4b\x2b\x15\xc2\x4d\x39\x2b\x41\x05\xf4\x7a\x82\xf6\x1b\x1e\xc5\x24\xe7\x9f\xb0\x13\xf0\x24\xb1\x86\x22\xf5\xd9\x89\x30\xbb\xa8\xc3\x4a\x52\x5d\xb4\xc5\x8e\x70\x13\x5a\x5e\xea\x32\x4f\xcb\x8d\x9b\x58\x8b\x43\x94\x20\x05\x71\x67\x0f\x0a\xd2\x1a\x8d\x88\xc3\xa7\x44\x9b\xf0\xd1\xfe\x7d\x96\x36\x40\x1a\x1c\x33\xbd\x75\x8b\x0c\x65\x96\xa8\x94\x7a\x17\xb2\x8e\x17\xad\xaf\xd9\x59\x0a\xbb\xf0\xb6\x63\x45\x1b\x21\x4c\x07\x13\x5c\xea\x9f\xd2\x0b\x9d\xe2\xd4\x29\xe1\x77\x93\x4f\xdb\x23\x57\xdd\x49\x44\xaf\xd3\x53\xcd\x44\x29\x0f\xda\xd3\x51\x11\xa6\x61\xd7\xb4\x32\xfe\x24\x50\x6f\x28\x51\x7b\x28\xcf\xa1\x91\x5c\x73\xcc\x69\x9a\x63\x78\x37\x68\xd2\x9d\x61\xa6\xbf\xba\xa8\x36\x13\x92\x1c\x08\x85\x9d\xc3\xf1\x86\x73\x0a\x88\x59\x89\x42\x02\x2a\x0b\xce\xe8\x31\x01\xa9\x34\x92\xd1\x5d\x09\x05\xb8\x96\x44\x1f\x0b\x2e\xf4\xe2\x55\xa1\xda\x57\x85\x22\xdf\xc1\xf6\xbd\x93\xd5\xf7\x03\xad\x9d\x05\x39\x5b\xdc\xd9\xef\xad\x88\xbf\xcc\x56\x84\x3a\x2a\xac\x2f\xab\xad\x95\x2e\x09\x2b\xb8\x00\x16\xf5\x0d\xa5\xb9\x28\x76\x12\x61\x28\x04\x48\xc2\xbd\xa2\xb0\x02\x6c\x59\x4b\xd4\xcc\x3f\x1d\x46\x91\x1d\x43\xfe\xb8\x63\x40\x75\x25\xb6\x17\x6e\x02\x68\x1d\x77\xf6\x9a\x92\x8a\x84\x9d\xc6\x63\xb5\x09\xf5\x5a\x57\xab\xf9\x4b\xb4\x99\xf2\x2c\x29\x64\xcf\x74\x08\xf3\x0d\x42\x42\x67\xb0\x47\xf2\x8c\xd4\xd1\x3a\xe6\x36\x90\x9f\x7c\x7d\x83\x77\x5d\xd6\x61\x75\x3b\xde\x4d\xbf\x90\xb5\x17\x7f\x56\xe9\xe5\x2e\x63\x1d\xac\x7e\xfc\x4e\x55\xab\x68\x13\xd7\x62\x98\x9a\x6b\x40\x46\xe8\xf4\xd4\x35\xfb\x25\x22\xb4\xa5\xa3\x16\xee\xd1\x4d\x42\x1c\xef\x67\x4a\x8c\x9d\xaf\x1d\xf5\x93\x2b\x02\x83\x06\x73\xa6\x88\xd2\xc0\xb0\x7f\x7f\xd5\x4b\xb4\x21\x93\xc3\x8b\xa9\x50\xe6\xfb\xae\xb4\xae\xab\x45\xa1\x5d\x17\x6f\x93\x1b\x9d\x74\x5f\xed\x0f\xe4\x7f\x0a\x2b\x8c\x63\x2e\x02\xaa\x49\x67\xe3\xdc\x34\xeb\x6c\x5d\xcc\xd4\xa1\xa1\x90\xf1\xc4\xe5\x63\x93\x90\x4a\xe2\x8f\x1c\x2b\x87\xe4\x8c\x23\x7d\x67\xaf\x6f\x18\xc0\x77\x56\x6d\x42\xa3\x67\xfb\xf3\xe7\xe6\x3d\x28\x78\xa6\x4d\x14\xda\x38\xe7\x12\xbe\x44\xdb\x64\x06\x79\x88\xe7\x7b\x09\x5a\x12\xe7\x28\x61\x28\x9a\xcc\xdc\x0e\xea\x7d\x6e\xb8\x6b\x52\x01\xaf\xfd\x61\x68\x65\x1a\x4e\x4f\x94\x1b\x67\xfe\x11\xa5\x1a\x48\x57\xa7\x0f\xc6\x01\x52\xd7\x97\x47\x15\x97\x92\xb0\x80\x95\xed\xd1\x46\x52\x76\x93\x20\x28\xc1\x48\xc5\x2a\x88\x2b\x76\x81\x6b\x51\x22\x0d\x45\x7f\x6d\xe4\x9c\x9a\x6d\xa6\x58\x13\x48\x22\x4a\x81\x12\x55\xa5\x14\x3f\x79\x09\x14\x79\xa3\x7f\xb4\xee\x6d\xc9\xb7\x88\xd0\x5a\x42\x81\x70\x30\x4c\x3b\x14\x15\x67\x44\x73\x6f\x38\x49\x9b\xb2\x42\xcf\xc5\x30\x6d\x0b\x89\xb5\x24\x76\x37\x9e\xba\x81\x6b\x58\x42\x97\xbb\xcf\x2b\xab\x67\x54\x74\x2a\xd2\x03\x16\x33\xcc\x38\x61\x5d\x82\x6a\xc2\xce\xb8\xbf\x1e\xa5\x8f\x06\xf8\x7e\x7b\xa0\x10\x9c\x92\xae\x0a\x58\x82\x43\xcc\x59\x27\xe4\x14\x83\xb8\xd2\x02\x1b\x73\x68\x7a\x98\x4a\xe8\xa8\xb3\xb6\x04\x4f\x84\x95\xfc\xe9\x8c\x09\x97\x33\x25\x41\x11\x06\x27\x38\x5e\x2b\x68\xa5\x25\x22\x4c\x9f\x7d\x9c\xe4\x8a\x45\x48\xd8\x82\x04\x36\x35\xf4\x6c\xbe\xac\xcf\xc2\xa5\x7d\x8c\xb7\x38\x87\x3d\x42\x89\xa6\xbe\x7d\x83\x5d\xbd\x6b\x95\x7f\x45\x81\x34\x7a\x71\x24\x91\x8e\xb8\x68\x69\x14\x4a\x9e\x58\xd4\xd1\xa3\xa9\x0a\x2a\x3e\x7f\x0d\xe3\x8a\x8b\xc8\x31\x16\x07\xd8\x02\x85\x42\xd2\x59\x66\x8f\x2a\xb8\x58\x7e\x33\x25\x7e\x5e\xb9\x8e\x87\x6d\x22\x50\xb5\x54\x0c\x49\x3e\xdd\xcd\xbd\x95\x4a\xf6\x0e\xa2\x43\xbd\x61\x81\x5e\xf9\x7d\x47\x07\xfb\xe6\x44\x7b\x31\x23\xa0\xd5\x87\xb1\x0d\xb9\x19\x65\xb5\x4e\x56\x71\xf0\x56\xc4\x72\xeb\x6f\x3b\x22\x77\x07\xd4\xd7\x3a\x21\xad\x11\xde\x27\x75\x59\x67\x96\xd6\x57\xc4\xa1\xc9\x5e\x80\x37\x0c\xf5\xa8\x05\xa2\x50\xca\x35\x95\xff\x8f\x48\xf5\xab\xdb\xf5\xcf\xb3\xc1\xfe\x7b\x89\xe8\xbd\xfd\x16\x75\x71\xae\x4f\xb8\x76\xf9\x0e\x74\xf6\xc6\xaa\x98\x24\x3a\xaf\x2a\x7a\xd4\x6f\x55\xbc\xaa\x57\xd8\x27\x62\x86\x4a\xa6\x1b\x64\x73\x92\x3c\xf7\x4b\x87\xb5\xbd\x0c\x17\xe6\xf9\xba\xd0\xae\x7d\xe6\xce\xcb\x07\x48\x60\x43\xd6\x99\xb4\x17\xe2\x3c\xe7\x0b\xc6\xfd\xbb\x0f\x33\x15\xde\xdc\xf5\xba\x57\x2a\x8d\x16\xb8\x8b\xe0\xd7\xa9\xd3\x3c\x0f\xd2\x9d\x7e\x40\x15\xf6\xff\x81\x7e\xf2\x39\x55\xc3\x27\x3b\x4e\x36\x70\x7f\xd8\xa7\x4f\xdd\xa7\x50\x6b\x4b\x3e\x0e\xa4\xbb\xac\x6a\x24\xda\xb5\xb9\x9f\x10\xbc\x5d\xef\xfb\xc8\xca\x3d\xfb\x1a\x3e\x76\x0a\x1c\xc7\xaf\xcc\xbf\xed\x87\x69\xab\x97\xd5\xff\x02\x00\x00\xff\xff\xa6\x9f\xe0\x94\x02\x3c\x00\x00") func dataConfig_schema_v34JsonBytes() ([]byte, error) { return bindataRead( diff --git a/components/cli/cli/compose/schema/data/config_schema_v3.4.json b/components/cli/cli/compose/schema/data/config_schema_v3.4.json index 2457a2de81..4cfbd060a2 100644 --- a/components/cli/cli/compose/schema/data/config_schema_v3.4.json +++ b/components/cli/cli/compose/schema/data/config_schema_v3.4.json @@ -437,6 +437,7 @@ "id": "#/definitions/volume", "type": ["object", "null"], "properties": { + "name": {"type": "string"}, "driver": {"type": "string"}, "driver_opts": { "type": "object", diff --git a/components/cli/cli/compose/types/types.go b/components/cli/cli/compose/types/types.go index 1eecc124f6..918c9bef0c 100644 --- a/components/cli/cli/compose/types/types.go +++ b/components/cli/cli/compose/types/types.go @@ -305,6 +305,7 @@ type IPAMPool struct { // VolumeConfig for a volume type VolumeConfig struct { + Name string Driver string DriverOpts map[string]string `mapstructure:"driver_opts"` External External @@ -313,6 +314,7 @@ type VolumeConfig struct { // External identifies a Volume or Network as a reference to a resource that is // not managed, and should already exist. +// External.name is deprecated and replaced by Volume.name type External struct { Name string External bool From 2a260817293d1f633c5b523e4c1d13d48e566666 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Fri, 28 Jul 2017 15:43:34 +0200 Subject: [PATCH 42/62] bash completion for `service ps` supports multiple services Signed-off-by: Harald Albers Upstream-commit: 548758fe31508e7cc65a3e647965a19e5f795085 Component: cli --- components/cli/contrib/completion/bash/docker | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 66174729d0..53ac4e8dfd 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -3242,10 +3242,7 @@ _docker_service_ps() { COMPREPLY=( $( compgen -W "--filter -f --format --help --no-resolve --no-trunc --quiet -q" -- "$cur" ) ) ;; *) - local counter=$(__docker_pos_first_nonflag '--filter|-f') - if [ "$cword" -eq "$counter" ]; then - __docker_complete_services - fi + __docker_complete_services ;; esac } From c16c5f3db88b40c9f424d2b189f012ed11d1cf07 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Fri, 28 Jul 2017 10:28:23 -0700 Subject: [PATCH 43/62] Fix repo references in docs Since CLI was moved to a separate repo, these references are incorrect. Fixed with the help of sed script, verified manually. Signed-off-by: Kir Kolyshkin Upstream-commit: 6d85a4f5f800e79e6d6c00024313de04223c624d Component: cli --- components/cli/docs/README.md | 4 ++-- components/cli/docs/deprecated.md | 4 ++-- components/cli/docs/extend/EBS_volume.md | 4 ++-- components/cli/docs/extend/config.md | 4 ++-- components/cli/docs/extend/index.md | 4 ++-- components/cli/docs/extend/legacy_plugins.md | 4 ++-- components/cli/docs/extend/plugin_api.md | 4 ++-- components/cli/docs/extend/plugins_authorization.md | 4 ++-- components/cli/docs/extend/plugins_graphdriver.md | 4 ++-- components/cli/docs/extend/plugins_logging.md | 4 ++-- components/cli/docs/extend/plugins_metrics.md | 4 ++-- components/cli/docs/extend/plugins_network.md | 4 ++-- components/cli/docs/extend/plugins_services.md | 4 ++-- components/cli/docs/extend/plugins_volume.md | 4 ++-- components/cli/docs/reference/builder.md | 4 ++-- components/cli/docs/reference/commandline/attach.md | 4 ++-- components/cli/docs/reference/commandline/build.md | 4 ++-- components/cli/docs/reference/commandline/cli.md | 4 ++-- components/cli/docs/reference/commandline/commit.md | 4 ++-- components/cli/docs/reference/commandline/container.md | 4 ++-- components/cli/docs/reference/commandline/container_prune.md | 4 ++-- components/cli/docs/reference/commandline/cp.md | 4 ++-- components/cli/docs/reference/commandline/create.md | 4 ++-- components/cli/docs/reference/commandline/deploy.md | 4 ++-- components/cli/docs/reference/commandline/diff.md | 4 ++-- components/cli/docs/reference/commandline/dockerd.md | 4 ++-- components/cli/docs/reference/commandline/events.md | 2 +- components/cli/docs/reference/commandline/exec.md | 4 ++-- components/cli/docs/reference/commandline/export.md | 4 ++-- components/cli/docs/reference/commandline/history.md | 4 ++-- components/cli/docs/reference/commandline/image.md | 4 ++-- components/cli/docs/reference/commandline/image_prune.md | 4 ++-- components/cli/docs/reference/commandline/images.md | 4 ++-- components/cli/docs/reference/commandline/import.md | 4 ++-- components/cli/docs/reference/commandline/index.md | 4 ++-- components/cli/docs/reference/commandline/info.md | 4 ++-- components/cli/docs/reference/commandline/inspect.md | 4 ++-- components/cli/docs/reference/commandline/kill.md | 4 ++-- components/cli/docs/reference/commandline/load.md | 4 ++-- components/cli/docs/reference/commandline/login.md | 4 ++-- components/cli/docs/reference/commandline/logout.md | 4 ++-- components/cli/docs/reference/commandline/logs.md | 4 ++-- components/cli/docs/reference/commandline/network.md | 4 ++-- components/cli/docs/reference/commandline/network_connect.md | 4 ++-- components/cli/docs/reference/commandline/network_create.md | 4 ++-- .../cli/docs/reference/commandline/network_disconnect.md | 4 ++-- components/cli/docs/reference/commandline/network_inspect.md | 4 ++-- components/cli/docs/reference/commandline/network_ls.md | 4 ++-- components/cli/docs/reference/commandline/network_rm.md | 4 ++-- components/cli/docs/reference/commandline/node.md | 4 ++-- components/cli/docs/reference/commandline/node_demote.md | 4 ++-- components/cli/docs/reference/commandline/node_inspect.md | 4 ++-- components/cli/docs/reference/commandline/node_ls.md | 4 ++-- components/cli/docs/reference/commandline/node_promote.md | 4 ++-- components/cli/docs/reference/commandline/node_ps.md | 4 ++-- components/cli/docs/reference/commandline/node_rm.md | 4 ++-- components/cli/docs/reference/commandline/node_update.md | 4 ++-- components/cli/docs/reference/commandline/pause.md | 4 ++-- components/cli/docs/reference/commandline/plugin.md | 4 ++-- components/cli/docs/reference/commandline/plugin_create.md | 4 ++-- components/cli/docs/reference/commandline/plugin_disable.md | 4 ++-- components/cli/docs/reference/commandline/plugin_enable.md | 4 ++-- components/cli/docs/reference/commandline/plugin_inspect.md | 4 ++-- components/cli/docs/reference/commandline/plugin_install.md | 4 ++-- components/cli/docs/reference/commandline/plugin_ls.md | 4 ++-- components/cli/docs/reference/commandline/plugin_push.md | 4 ++-- components/cli/docs/reference/commandline/plugin_rm.md | 4 ++-- components/cli/docs/reference/commandline/plugin_set.md | 4 ++-- components/cli/docs/reference/commandline/plugin_upgrade.md | 4 ++-- components/cli/docs/reference/commandline/port.md | 4 ++-- components/cli/docs/reference/commandline/ps.md | 4 ++-- components/cli/docs/reference/commandline/pull.md | 4 ++-- components/cli/docs/reference/commandline/push.md | 4 ++-- components/cli/docs/reference/commandline/rename.md | 4 ++-- components/cli/docs/reference/commandline/restart.md | 4 ++-- components/cli/docs/reference/commandline/rm.md | 4 ++-- components/cli/docs/reference/commandline/rmi.md | 4 ++-- components/cli/docs/reference/commandline/run.md | 4 ++-- components/cli/docs/reference/commandline/save.md | 4 ++-- components/cli/docs/reference/commandline/search.md | 4 ++-- components/cli/docs/reference/commandline/secret.md | 4 ++-- components/cli/docs/reference/commandline/secret_create.md | 4 ++-- components/cli/docs/reference/commandline/secret_inspect.md | 4 ++-- components/cli/docs/reference/commandline/secret_ls.md | 4 ++-- components/cli/docs/reference/commandline/secret_rm.md | 4 ++-- components/cli/docs/reference/commandline/service.md | 4 ++-- components/cli/docs/reference/commandline/service_create.md | 4 ++-- components/cli/docs/reference/commandline/service_inspect.md | 4 ++-- components/cli/docs/reference/commandline/service_logs.md | 4 ++-- components/cli/docs/reference/commandline/service_ls.md | 4 ++-- components/cli/docs/reference/commandline/service_ps.md | 4 ++-- components/cli/docs/reference/commandline/service_rm.md | 4 ++-- components/cli/docs/reference/commandline/service_scale.md | 4 ++-- components/cli/docs/reference/commandline/service_update.md | 4 ++-- components/cli/docs/reference/commandline/stack.md | 4 ++-- components/cli/docs/reference/commandline/stack_deploy.md | 4 ++-- components/cli/docs/reference/commandline/stack_ls.md | 4 ++-- components/cli/docs/reference/commandline/stack_ps.md | 4 ++-- components/cli/docs/reference/commandline/stack_rm.md | 4 ++-- components/cli/docs/reference/commandline/stack_services.md | 4 ++-- components/cli/docs/reference/commandline/start.md | 4 ++-- components/cli/docs/reference/commandline/stats.md | 4 ++-- components/cli/docs/reference/commandline/stop.md | 4 ++-- components/cli/docs/reference/commandline/swarm.md | 4 ++-- components/cli/docs/reference/commandline/swarm_ca.md | 4 ++-- components/cli/docs/reference/commandline/swarm_init.md | 4 ++-- components/cli/docs/reference/commandline/swarm_join.md | 4 ++-- components/cli/docs/reference/commandline/swarm_join_token.md | 4 ++-- components/cli/docs/reference/commandline/swarm_leave.md | 4 ++-- components/cli/docs/reference/commandline/swarm_unlock.md | 4 ++-- components/cli/docs/reference/commandline/swarm_unlock_key.md | 4 ++-- components/cli/docs/reference/commandline/swarm_update.md | 4 ++-- components/cli/docs/reference/commandline/system.md | 4 ++-- components/cli/docs/reference/commandline/system_df.md | 4 ++-- components/cli/docs/reference/commandline/system_prune.md | 4 ++-- components/cli/docs/reference/commandline/tag.md | 4 ++-- components/cli/docs/reference/commandline/top.md | 4 ++-- components/cli/docs/reference/commandline/unpause.md | 4 ++-- components/cli/docs/reference/commandline/update.md | 4 ++-- components/cli/docs/reference/commandline/version.md | 4 ++-- components/cli/docs/reference/commandline/volume.md | 4 ++-- components/cli/docs/reference/commandline/volume_create.md | 4 ++-- components/cli/docs/reference/commandline/volume_inspect.md | 4 ++-- components/cli/docs/reference/commandline/volume_ls.md | 4 ++-- components/cli/docs/reference/commandline/volume_prune.md | 4 ++-- components/cli/docs/reference/commandline/volume_rm.md | 4 ++-- components/cli/docs/reference/commandline/wait.md | 4 ++-- components/cli/docs/reference/glossary.md | 4 ++-- components/cli/docs/reference/index.md | 4 ++-- components/cli/docs/reference/run.md | 4 ++-- 130 files changed, 259 insertions(+), 259 deletions(-) diff --git a/components/cli/docs/README.md b/components/cli/docs/README.md index da93093075..28d1f0e9a0 100644 --- a/components/cli/docs/README.md +++ b/components/cli/docs/README.md @@ -1,7 +1,7 @@ # The non-reference docs have been moved! -