diff --git a/CHANGELOG-1.7.md b/CHANGELOG-1.7.md
index 478466ed65b..bc54f09b32d 100644
--- a/CHANGELOG-1.7.md
+++ b/CHANGELOG-1.7.md
@@ -1,65 +1,72 @@
-- [v1.7.8](#v178)
- - [Downloads for v1.7.8](#downloads-for-v178)
+- [v1.7.9](#v179)
+ - [Downloads for v1.7.9](#downloads-for-v179)
- [Client Binaries](#client-binaries)
- [Server Binaries](#server-binaries)
- [Node Binaries](#node-binaries)
- - [Changelog since v1.7.7](#changelog-since-v177)
+ - [Changelog since v1.7.8](#changelog-since-v178)
- [Other notable changes](#other-notable-changes)
-- [v1.7.7](#v177)
- - [Downloads for v1.7.7](#downloads-for-v177)
+- [v1.7.8](#v178)
+ - [Downloads for v1.7.8](#downloads-for-v178)
- [Client Binaries](#client-binaries-1)
- [Server Binaries](#server-binaries-1)
- [Node Binaries](#node-binaries-1)
- - [Changelog since v1.7.6](#changelog-since-v176)
+ - [Changelog since v1.7.7](#changelog-since-v177)
- [Other notable changes](#other-notable-changes-1)
-- [v1.7.6](#v176)
- - [Downloads for v1.7.6](#downloads-for-v176)
+- [v1.7.7](#v177)
+ - [Downloads for v1.7.7](#downloads-for-v177)
- [Client Binaries](#client-binaries-2)
- [Server Binaries](#server-binaries-2)
- [Node Binaries](#node-binaries-2)
- - [Changelog since v1.7.5](#changelog-since-v175)
+ - [Changelog since v1.7.6](#changelog-since-v176)
- [Other notable changes](#other-notable-changes-2)
-- [v1.7.5](#v175)
- - [Downloads for v1.7.5](#downloads-for-v175)
+- [v1.7.6](#v176)
+ - [Downloads for v1.7.6](#downloads-for-v176)
- [Client Binaries](#client-binaries-3)
- [Server Binaries](#server-binaries-3)
- [Node Binaries](#node-binaries-3)
- - [Changelog since v1.7.4](#changelog-since-v174)
+ - [Changelog since v1.7.5](#changelog-since-v175)
- [Other notable changes](#other-notable-changes-3)
-- [v1.7.4](#v174)
- - [Downloads for v1.7.4](#downloads-for-v174)
+- [v1.7.5](#v175)
+ - [Downloads for v1.7.5](#downloads-for-v175)
- [Client Binaries](#client-binaries-4)
- [Server Binaries](#server-binaries-4)
- [Node Binaries](#node-binaries-4)
- - [Changelog since v1.7.3](#changelog-since-v173)
+ - [Changelog since v1.7.4](#changelog-since-v174)
- [Other notable changes](#other-notable-changes-4)
-- [v1.7.3](#v173)
- - [Downloads for v1.7.3](#downloads-for-v173)
+- [v1.7.4](#v174)
+ - [Downloads for v1.7.4](#downloads-for-v174)
- [Client Binaries](#client-binaries-5)
- [Server Binaries](#server-binaries-5)
- [Node Binaries](#node-binaries-5)
- - [Changelog since v1.7.2](#changelog-since-v172)
+ - [Changelog since v1.7.3](#changelog-since-v173)
- [Other notable changes](#other-notable-changes-5)
-- [v1.7.2](#v172)
- - [Downloads for v1.7.2](#downloads-for-v172)
+- [v1.7.3](#v173)
+ - [Downloads for v1.7.3](#downloads-for-v173)
- [Client Binaries](#client-binaries-6)
- [Server Binaries](#server-binaries-6)
- [Node Binaries](#node-binaries-6)
- - [Changelog since v1.7.1](#changelog-since-v171)
+ - [Changelog since v1.7.2](#changelog-since-v172)
- [Other notable changes](#other-notable-changes-6)
-- [v1.7.1](#v171)
- - [Downloads for v1.7.1](#downloads-for-v171)
+- [v1.7.2](#v172)
+ - [Downloads for v1.7.2](#downloads-for-v172)
- [Client Binaries](#client-binaries-7)
- [Server Binaries](#server-binaries-7)
- [Node Binaries](#node-binaries-7)
- - [Changelog since v1.7.0](#changelog-since-v170)
+ - [Changelog since v1.7.1](#changelog-since-v171)
- [Other notable changes](#other-notable-changes-7)
-- [v1.7.0](#v170)
- - [Downloads for v1.7.0](#downloads-for-v170)
+- [v1.7.1](#v171)
+ - [Downloads for v1.7.1](#downloads-for-v171)
- [Client Binaries](#client-binaries-8)
- [Server Binaries](#server-binaries-8)
- [Node Binaries](#node-binaries-8)
+ - [Changelog since v1.7.0](#changelog-since-v170)
+ - [Other notable changes](#other-notable-changes-8)
+- [v1.7.0](#v170)
+ - [Downloads for v1.7.0](#downloads-for-v170)
+ - [Client Binaries](#client-binaries-9)
+ - [Server Binaries](#server-binaries-9)
+ - [Node Binaries](#node-binaries-9)
- [**Major Themes**](#major-themes)
- [**Action Required Before Upgrading**](#action-required-before-upgrading)
- [Network](#network)
@@ -115,7 +122,7 @@
- [Local Storage](#local-storage)
- [Volume Plugins](#volume-plugins)
- [Metrics](#metrics)
- - [**Other notable changes**](#other-notable-changes-8)
+ - [**Other notable changes**](#other-notable-changes-9)
- [Admission plugin](#admission-plugin)
- [API Machinery](#api-machinery-1)
- [Application autoscaling](#application-autoscaling-1)
@@ -143,62 +150,123 @@
- [Previous Releases Included in v1.7.0](#previous-releases-included-in-v170)
- [v1.7.0-rc.1](#v170-rc1)
- [Downloads for v1.7.0-rc.1](#downloads-for-v170-rc1)
- - [Client Binaries](#client-binaries-9)
- - [Server Binaries](#server-binaries-9)
- - [Node Binaries](#node-binaries-9)
- - [Changelog since v1.7.0-beta.2](#changelog-since-v170-beta2)
- - [Action Required](#action-required)
- - [Other notable changes](#other-notable-changes-9)
-- [v1.7.0-beta.2](#v170-beta2)
- - [Downloads for v1.7.0-beta.2](#downloads-for-v170-beta2)
- [Client Binaries](#client-binaries-10)
- [Server Binaries](#server-binaries-10)
- [Node Binaries](#node-binaries-10)
- - [Changelog since v1.7.0-beta.1](#changelog-since-v170-beta1)
- - [Action Required](#action-required-1)
+ - [Changelog since v1.7.0-beta.2](#changelog-since-v170-beta2)
+ - [Action Required](#action-required)
- [Other notable changes](#other-notable-changes-10)
-- [v1.7.0-beta.1](#v170-beta1)
- - [Downloads for v1.7.0-beta.1](#downloads-for-v170-beta1)
+- [v1.7.0-beta.2](#v170-beta2)
+ - [Downloads for v1.7.0-beta.2](#downloads-for-v170-beta2)
- [Client Binaries](#client-binaries-11)
- [Server Binaries](#server-binaries-11)
- [Node Binaries](#node-binaries-11)
- - [Changelog since v1.7.0-alpha.4](#changelog-since-v170-alpha4)
- - [Action Required](#action-required-2)
+ - [Changelog since v1.7.0-beta.1](#changelog-since-v170-beta1)
+ - [Action Required](#action-required-1)
- [Other notable changes](#other-notable-changes-11)
-- [v1.7.0-alpha.4](#v170-alpha4)
- - [Downloads for v1.7.0-alpha.4](#downloads-for-v170-alpha4)
+- [v1.7.0-beta.1](#v170-beta1)
+ - [Downloads for v1.7.0-beta.1](#downloads-for-v170-beta1)
- [Client Binaries](#client-binaries-12)
- [Server Binaries](#server-binaries-12)
- [Node Binaries](#node-binaries-12)
- - [Changelog since v1.7.0-alpha.3](#changelog-since-v170-alpha3)
- - [Action Required](#action-required-3)
+ - [Changelog since v1.7.0-alpha.4](#changelog-since-v170-alpha4)
+ - [Action Required](#action-required-2)
- [Other notable changes](#other-notable-changes-12)
-- [v1.7.0-alpha.3](#v170-alpha3)
- - [Downloads for v1.7.0-alpha.3](#downloads-for-v170-alpha3)
+- [v1.7.0-alpha.4](#v170-alpha4)
+ - [Downloads for v1.7.0-alpha.4](#downloads-for-v170-alpha4)
- [Client Binaries](#client-binaries-13)
- [Server Binaries](#server-binaries-13)
- [Node Binaries](#node-binaries-13)
- - [Changelog since v1.7.0-alpha.2](#changelog-since-v170-alpha2)
- - [Action Required](#action-required-4)
+ - [Changelog since v1.7.0-alpha.3](#changelog-since-v170-alpha3)
+ - [Action Required](#action-required-3)
- [Other notable changes](#other-notable-changes-13)
-- [v1.7.0-alpha.2](#v170-alpha2)
- - [Downloads for v1.7.0-alpha.2](#downloads-for-v170-alpha2)
+- [v1.7.0-alpha.3](#v170-alpha3)
+ - [Downloads for v1.7.0-alpha.3](#downloads-for-v170-alpha3)
- [Client Binaries](#client-binaries-14)
- [Server Binaries](#server-binaries-14)
- - [Changelog since v1.7.0-alpha.1](#changelog-since-v170-alpha1)
- - [Action Required](#action-required-5)
+ - [Node Binaries](#node-binaries-14)
+ - [Changelog since v1.7.0-alpha.2](#changelog-since-v170-alpha2)
+ - [Action Required](#action-required-4)
- [Other notable changes](#other-notable-changes-14)
-- [v1.7.0-alpha.1](#v170-alpha1)
- - [Downloads for v1.7.0-alpha.1](#downloads-for-v170-alpha1)
+- [v1.7.0-alpha.2](#v170-alpha2)
+ - [Downloads for v1.7.0-alpha.2](#downloads-for-v170-alpha2)
- [Client Binaries](#client-binaries-15)
- [Server Binaries](#server-binaries-15)
- - [Changelog since v1.6.0](#changelog-since-v160)
+ - [Changelog since v1.7.0-alpha.1](#changelog-since-v170-alpha1)
+ - [Action Required](#action-required-5)
- [Other notable changes](#other-notable-changes-15)
+- [v1.7.0-alpha.1](#v170-alpha1)
+ - [Downloads for v1.7.0-alpha.1](#downloads-for-v170-alpha1)
+ - [Client Binaries](#client-binaries-16)
+ - [Server Binaries](#server-binaries-16)
+ - [Changelog since v1.6.0](#changelog-since-v160)
+ - [Other notable changes](#other-notable-changes-16)
+# v1.7.9
+
+[Documentation](https://docs.k8s.io) & [Examples](https://releases.k8s.io/release-1.7/examples)
+
+## Downloads for v1.7.9
+
+
+filename | sha256 hash
+-------- | -----------
+[kubernetes.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes.tar.gz) | `8c7c16c137c421cfe27311aba0fea49411ed725d3d41938706474c328647afcc`
+[kubernetes-src.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-src.tar.gz) | `eb2d967731d20b2f42787400fd9114ebd40c2722f3afd7ebb232324d2e66815e`
+
+### Client Binaries
+
+filename | sha256 hash
+-------- | -----------
+[kubernetes-client-darwin-386.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-darwin-386.tar.gz) | `930e24595a8cf87f65d0cbee6f033f8c441a64da86cdc22ad9d31cd5e0496928`
+[kubernetes-client-darwin-amd64.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-darwin-amd64.tar.gz) | `59c10f48351347821216d1cb9726db0b31868cd5e059814a5154dfdeb36548e1`
+[kubernetes-client-linux-386.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-linux-386.tar.gz) | `3a7e20a3d45eab69bd8a6c9572ecd98f50499b1880882c0e78c8cdd726046802`
+[kubernetes-client-linux-amd64.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-linux-amd64.tar.gz) | `ac530a89b701669df889c7d5e34c7c5ba0b1c231e45fd9a1ff441d807d0fba8f`
+[kubernetes-client-linux-arm64.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-linux-arm64.tar.gz) | `cdad0b14762b01aac8820e41cb89b850b1dc8d539ac892ca9f718d9e00e8505e`
+[kubernetes-client-linux-arm.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-linux-arm.tar.gz) | `11c1bb76f2fc7fa9038d1d8687df857a231bd8a44b00d3f3bfef277b44e1c604`
+[kubernetes-client-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-linux-ppc64le.tar.gz) | `e7ed462fb6d86b1205ca9c4701b521d80b9c614fb98ca3a75579d18835303f7f`
+[kubernetes-client-linux-s390x.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-linux-s390x.tar.gz) | `7aff3b2d0540c3efd53d383dc87d95b62b4203933bd154f66e167fffa5dd0d72`
+[kubernetes-client-windows-386.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-windows-386.tar.gz) | `45f64fae0368f80bff7f11fafcce4ccc5c79876cb496481fbcdb35fd5aa85a49`
+[kubernetes-client-windows-amd64.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-client-windows-amd64.tar.gz) | `f7c34d11b35424fe96e1477a9347618169b911d4ecc57f00945f63d5cef53968`
+
+### Server Binaries
+
+filename | sha256 hash
+-------- | -----------
+[kubernetes-server-linux-amd64.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-server-linux-amd64.tar.gz) | `9b94e2b1c13dd3304aa36d0800f88a86d1c335a2b56de8a69d67f50c6f08d0ad`
+[kubernetes-server-linux-arm64.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-server-linux-arm64.tar.gz) | `2c5cb85515137f58ddc475963cd42cd69a881b2269724e0c5237b365644974db`
+[kubernetes-server-linux-arm.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-server-linux-arm.tar.gz) | `e62d8e234bc31d8dd4c88b28261445f4bc00e9e19795c57f7e72da91c037b6cd`
+[kubernetes-server-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-server-linux-ppc64le.tar.gz) | `b59c47ff865c4f21da816500d1013e5bab71bcb2ed214ceb022395eb6d729634`
+[kubernetes-server-linux-s390x.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-server-linux-s390x.tar.gz) | `2c057b4dcfd40457fb5ee7d692239b702b61c17a9cc095ecd2a65ac553e4d2d7`
+
+### Node Binaries
+
+filename | sha256 hash
+-------- | -----------
+[kubernetes-node-linux-amd64.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-node-linux-amd64.tar.gz) | `e92e3deb34ce06b11b667027ddd9753f8c3149996320bb9dd3555d758775e60d`
+[kubernetes-node-linux-arm64.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-node-linux-arm64.tar.gz) | `96bf63c7ba4a322ec21b22c3fa3f37c713aa846bdde311bc7a52df8abc7ef291`
+[kubernetes-node-linux-arm.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-node-linux-arm.tar.gz) | `4274d183d002c57cf6fff21ba71cdb69121f520ae77c913013adb92f7efee2a6`
+[kubernetes-node-linux-ppc64le.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-node-linux-ppc64le.tar.gz) | `8c9a7ef4141dc59be1b613b461ca8e16612c5d36ca9cd1b9fbb92f35f02e63f1`
+[kubernetes-node-linux-s390x.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-node-linux-s390x.tar.gz) | `14314c3c958bf4b966bc6960495271412019973834e9ca427bcedb1bd51c787f`
+[kubernetes-node-windows-amd64.tar.gz](https://dl.k8s.io/v1.7.9/kubernetes-node-windows-amd64.tar.gz) | `a20e882b046f95ebb6c94f87aee99b27d43422ea5e09b48fa67aa4926b2edbfe`
+
+## Changelog since v1.7.8
+
+### Other notable changes
+
+* Support German cloud for azure disk mount feature ([#50673](https://github.com/kubernetes/kubernetes/pull/50673), [@clement-buchart](https://github.com/clement-buchart))
+* BugFix: Exited containers are not Garbage Collected by the kubelet while the pod is running ([#53167](https://github.com/kubernetes/kubernetes/pull/53167), [@dashpole](https://github.com/dashpole))
+* Address a bug which allowed the horizontal pod autoscaler to allocate `desiredReplicas` > `maxReplicas` in certain instances. ([#53690](https://github.com/kubernetes/kubernetes/pull/53690), [@mattjmcnaughton](https://github.com/mattjmcnaughton))
+* Use separate client for leader election in scheduler to avoid starving leader election by regular scheduler operations. ([#53793](https://github.com/kubernetes/kubernetes/pull/53793), [@wojtek-t](https://github.com/wojtek-t))
+* fix azure disk mounter issue ([#52260](https://github.com/kubernetes/kubernetes/pull/52260), [@andyzhangx](https://github.com/andyzhangx))
+* GCE: Fix issue deleting internal load balancers when the firewall resource may not exist. ([#53450](https://github.com/kubernetes/kubernetes/pull/53450), [@nicksardo](https://github.com/nicksardo))
+* Fix compilation of k8s.io/apiextensions-apiserver ([#48036](https://github.com/kubernetes/kubernetes/pull/48036), [@hongchaodeng](https://github.com/hongchaodeng))
+
+
# v1.7.8
[Documentation](https://docs.k8s.io) & [Examples](https://releases.k8s.io/release-1.7/examples)
diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index 9522823b0b9..d7ebc4a4234 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -2932,73 +2932,78 @@
},
{
"ImportPath": "google.golang.org/grpc",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/codes",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
+ },
+ {
+ "ImportPath": "google.golang.org/grpc/connectivity",
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/credentials",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclog",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/internal",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/keepalive",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/metadata",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/naming",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/peer",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/stats",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/status",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/tap",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/transport",
- "Comment": "v1.3.0",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "gopkg.in/gcfg.v1",
diff --git a/Godeps/LICENSES b/Godeps/LICENSES
index 505e9b9aa67..ad6fd773eaf 100644
--- a/Godeps/LICENSES
+++ b/Godeps/LICENSES
@@ -86882,504 +86882,3150 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
= vendor/google.golang.org/grpc licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/codes licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
+================================================================================
+
+
+================================================================================
+= vendor/google.golang.org/grpc/connectivity licensed under: =
+
+
+ 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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/credentials licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/grpclb/grpc_lb_v1 licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/grpclog licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/internal licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/keepalive licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/metadata licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/naming licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/peer licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/stats licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/status licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/tap licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
================================================================================
= vendor/google.golang.org/grpc/transport licensed under: =
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 1. Definitions.
-= vendor/google.golang.org/grpc/LICENSE a4bad33881612090c6035d8393175996
+ "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.
+
+= vendor/google.golang.org/grpc/LICENSE 3b83ef96387f14655fc854ddc3c6bd57
================================================================================
diff --git a/api/openapi-spec/README.md b/api/openapi-spec/README.md
index 31e0ed85140..59fbd90100d 100644
--- a/api/openapi-spec/README.md
+++ b/api/openapi-spec/README.md
@@ -4,7 +4,7 @@ This folder contains an [OpenAPI specification][openapi] for Kubernetes API.
## Vendor Extensions
-Kuberntes extends OpenAPI using these extensions. Note the version that
+Kuberntes extends OpenAPI using these extensions. Note the version that
extensions has been added.
### `x-kubernetes-group-version-kind`
@@ -56,5 +56,5 @@ For example:
### `x-kubernetes-patch-strategy` and `x-kubernetes-patch-merge-key`
-Some of the definitions may have these extensions. For more information about PatchStrategy and PatchMergeKey see
-[strategic-merge-patch] (https://github.com/kubernetes/community/blob/3a1e6d22f812751ee88eccf7c59101852de63d5b/contributors/devel/strategic-merge-patch.md).
+Some of the definitions may have these extensions. For more information about PatchStrategy and PatchMergeKey see
+[strategic-merge-patch] (https://github.com/kubernetes/community/blob/master/contributors/devel/strategic-merge-patch.md).
diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json
index 38bed12b0b4..ba098aeab49 100644
--- a/api/openapi-spec/swagger.json
+++ b/api/openapi-spec/swagger.json
@@ -62262,6 +62262,7 @@
"description": "AdmissionHookClientConfig contains the information to make a TLS connection with the webhook",
"required": [
"service",
+ "urlPath",
"caBundle"
],
"properties": {
@@ -62273,6 +62274,10 @@
"service": {
"description": "Service is a reference to the service for this webhook. If there is only one port open for the service, that port will be used. If there are multiple ports open, port 443 will be used if it is open, otherwise it is an error. Required",
"$ref": "#/definitions/io.k8s.api.admissionregistration.v1alpha1.ServiceReference"
+ },
+ "urlPath": {
+ "description": "URLPath is an optional field that specifies the URL path to use when posting the AdmissionReview object.",
+ "type": "string"
}
}
},
diff --git a/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json b/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json
index c3218e0ffcf..447807031ce 100644
--- a/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json
+++ b/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json
@@ -1764,6 +1764,7 @@
"description": "AdmissionHookClientConfig contains the information to make a TLS connection with the webhook",
"required": [
"service",
+ "urlPath",
"caBundle"
],
"properties": {
@@ -1771,6 +1772,10 @@
"$ref": "v1alpha1.ServiceReference",
"description": "Service is a reference to the service for this webhook. If there is only one port open for the service, that port will be used. If there are multiple ports open, port 443 will be used if it is open, otherwise it is an error. Required"
},
+ "urlPath": {
+ "type": "string",
+ "description": "URLPath is an optional field that specifies the URL path to use when posting the AdmissionReview object."
+ },
"caBundle": {
"type": "string",
"description": "CABundle is a PEM encoded CA bundle which will be used to validate webhook's server certificate. Required"
diff --git a/cluster/centos/config-build.sh b/cluster/centos/config-build.sh
index 4887bc13b93..4854f7e1062 100755
--- a/cluster/centos/config-build.sh
+++ b/cluster/centos/config-build.sh
@@ -40,8 +40,7 @@ FLANNEL_DOWNLOAD_URL=\
ETCD_DOWNLOAD_URL=\
"https://github.com/coreos/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz"
-# TODO(#33726): switch to dl.k8s.io
K8S_CLIENT_DOWNLOAD_URL=\
-"https://storage.googleapis.com/kubernetes-release/release/v${K8S_VERSION}/kubernetes-client-linux-amd64.tar.gz"
+"https://dl.k8s.io/v${K8S_VERSION}/kubernetes-client-linux-amd64.tar.gz"
K8S_SERVER_DOWNLOAD_URL=\
-"https://storage.googleapis.com/kubernetes-release/release/v${K8S_VERSION}/kubernetes-server-linux-amd64.tar.gz"
+"https://dl.k8s.io/v${K8S_VERSION}/kubernetes-server-linux-amd64.tar.gz"
diff --git a/cluster/gce/config-default.sh b/cluster/gce/config-default.sh
index 370939b7c98..91e79d7fe9e 100755
--- a/cluster/gce/config-default.sh
+++ b/cluster/gce/config-default.sh
@@ -250,6 +250,11 @@ if [[ -n "${GCE_ALPHA_FEATURES:-}" ]]; then
PROVIDER_VARS="${PROVIDER_VARS:-} GCE_ALPHA_FEATURES"
fi
+# Override default GLBC image
+if [[ -n "${GCE_GLBC_IMAGE:-}" ]]; then
+ PROVIDER_VARS="${PROVIDER_VARS:-} GCE_GLBC_IMAGE"
+fi
+
# Admission Controllers to invoke prior to persisting objects in cluster
# If we included ResourceQuota, we should keep it at the end of the list to prevent incrementing quota usage prematurely.
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,Priority,ResourceQuota
diff --git a/cluster/gce/config-test.sh b/cluster/gce/config-test.sh
index f736b7147ed..32be4e9d289 100755
--- a/cluster/gce/config-test.sh
+++ b/cluster/gce/config-test.sh
@@ -287,6 +287,11 @@ if [[ -n "${GCE_ALPHA_FEATURES:-}" ]]; then
PROVIDER_VARS="${PROVIDER_VARS:-} GCE_ALPHA_FEATURES"
fi
+# Override default GLBC image
+if [[ -n "${GCE_GLBC_IMAGE:-}" ]]; then
+ PROVIDER_VARS="${PROVIDER_VARS:-} GCE_GLBC_IMAGE"
+fi
+
# If we included ResourceQuota, we should keep it at the end of the list to prevent incrementing quota usage prematurely.
ADMISSION_CONTROL="${KUBE_ADMISSION_CONTROL:-Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,PodPreset,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,Priority,ResourceQuota}"
diff --git a/cluster/gce/container-linux/configure-helper.sh b/cluster/gce/container-linux/configure-helper.sh
index 30aeb9cd9a2..948c20baf4d 100755
--- a/cluster/gce/container-linux/configure-helper.sh
+++ b/cluster/gce/container-linux/configure-helper.sh
@@ -1358,8 +1358,12 @@ function start-lb-controller {
echo "Start GCE L7 pod"
prepare-log-file /var/log/glbc.log
setup-addon-manifests "addons" "cluster-loadbalancing/glbc"
- cp "${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/glbc.manifest" \
- /etc/kubernetes/manifests/
+
+ local -r glbc_manifest="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/glbc.manifest"
+ if [[ ! -z "${GCE_GLBC_IMAGE:-}" ]]; then
+ sed -i "s@image:.*@image: ${GCE_GLBC_IMAGE}@" "${glbc_manifest}"
+ fi
+ cp "${glbc_manifest}" /etc/kubernetes/manifests/
fi
}
diff --git a/cluster/gce/gci/configure-helper.sh b/cluster/gce/gci/configure-helper.sh
index 7749e097b15..defad8ddd9e 100644
--- a/cluster/gce/gci/configure-helper.sh
+++ b/cluster/gce/gci/configure-helper.sh
@@ -1878,8 +1878,12 @@ function start-lb-controller {
echo "Start GCE L7 pod"
prepare-log-file /var/log/glbc.log
setup-addon-manifests "addons" "cluster-loadbalancing/glbc"
- cp "${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/glbc.manifest" \
- /etc/kubernetes/manifests/
+
+ local -r glbc_manifest="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty/glbc.manifest"
+ if [[ ! -z "${GCE_GLBC_IMAGE:-}" ]]; then
+ sed -i "s@image:.*@image: ${GCE_GLBC_IMAGE}@" "${glbc_manifest}"
+ fi
+ cp "${glbc_manifest}" /etc/kubernetes/manifests/
fi
}
diff --git a/cluster/juju/layers/kubernetes-master/config.yaml b/cluster/juju/layers/kubernetes-master/config.yaml
index c328a43751c..73857e05958 100644
--- a/cluster/juju/layers/kubernetes-master/config.yaml
+++ b/cluster/juju/layers/kubernetes-master/config.yaml
@@ -7,6 +7,12 @@ options:
type: string
default: cluster.local
description: The local domain for cluster dns
+ extra_sans:
+ type: string
+ default: ""
+ description: |
+ Space-separated list of extra SAN entries to add to the x509 certificate
+ created for the master nodes.
service-cidr:
type: string
default: 10.152.183.0/24
diff --git a/cluster/juju/layers/kubernetes-master/reactive/kubernetes_master.py b/cluster/juju/layers/kubernetes-master/reactive/kubernetes_master.py
index b6430637d47..223d32b8a0b 100644
--- a/cluster/juju/layers/kubernetes-master/reactive/kubernetes_master.py
+++ b/cluster/juju/layers/kubernetes-master/reactive/kubernetes_master.py
@@ -356,7 +356,7 @@ def start_master(etcd):
'Configuring the Kubernetes master services.')
freeze_service_cidr()
if not etcd.get_connection_string():
- # etcd is not returning a connection string. This hapens when
+ # etcd is not returning a connection string. This happens when
# the master unit disconnects from etcd and is ready to terminate.
# No point in trying to start master services and fail. Just return.
return
@@ -457,12 +457,38 @@ def send_data(tls):
'kubernetes.default.svc',
'kubernetes.default.svc.{0}'.format(domain)
]
+
+ # maybe they have extra names they want as SANs
+ extra_sans = hookenv.config('extra_sans')
+ if extra_sans and not extra_sans == "":
+ sans.extend(extra_sans.split())
+
# Create a path safe name by removing path characters from the unit name.
certificate_name = hookenv.local_unit().replace('/', '_')
# Request a server cert with this information.
tls.request_server_cert(common_name, sans, certificate_name)
+@when('config.changed.extra_sans', 'certificates.available')
+def update_certificate(tls):
+ # I using the config.changed flag instead of something more
+ # specific to try and catch ip changes. Being a little
+ # spammy here is ok because the cert layer checks for
+ # changes to the cert before issuing a new one
+ send_data(tls)
+
+
+@when('certificates.server.cert.available',
+ 'kubernetes-master.components.started')
+def kick_api_server(tls):
+ # need to be idempotent and don't want to kick the api server
+ # without need
+ if data_changed('cert', tls.get_server_cert()):
+ # certificate changed, so restart the api server
+ hookenv.log("Certificate information changed, restarting api server")
+ set_state('kube-apiserver.do-restart')
+
+
@when('kubernetes-master.components.started')
def configure_cdk_addons():
''' Configure CDK addons '''
diff --git a/cluster/juju/layers/kubernetes-master/templates/rbd-persistent-volume.yaml b/cluster/juju/layers/kubernetes-master/templates/rbd-persistent-volume.yaml
index f82a7543b45..84248e54326 100644
--- a/cluster/juju/layers/kubernetes-master/templates/rbd-persistent-volume.yaml
+++ b/cluster/juju/layers/kubernetes-master/templates/rbd-persistent-volume.yaml
@@ -4,13 +4,12 @@ apiVersion: v1
kind: PersistentVolume
metadata:
name: {{ RBD_NAME }}
- annotations:
- volume.beta.kubernetes.io/storage-class: "rbd"
spec:
capacity:
storage: {{ RBD_SIZE }}M
accessModes:
- {{ PV_MODE }}
+ storageClassName: "rbd"
rbd:
monitors:
{% for host in monitors %}
diff --git a/cluster/saltbase/salt/cluster-autoscaler/cluster-autoscaler.manifest b/cluster/saltbase/salt/cluster-autoscaler/cluster-autoscaler.manifest
index c8635de966c..22471e9e909 100644
--- a/cluster/saltbase/salt/cluster-autoscaler/cluster-autoscaler.manifest
+++ b/cluster/saltbase/salt/cluster-autoscaler/cluster-autoscaler.manifest
@@ -25,7 +25,7 @@
"containers": [
{
"name": "cluster-autoscaler",
- "image": "gcr.io/google_containers/cluster-autoscaler:v1.0.1-beta1",
+ "image": "gcr.io/google_containers/cluster-autoscaler:v1.0.1",
"livenessProbe": {
"httpGet": {
"path": "/health-check",
diff --git a/cmd/kube-apiserver/app/BUILD b/cmd/kube-apiserver/app/BUILD
index 497e3bae6e5..494a9b6dab7 100644
--- a/cmd/kube-apiserver/app/BUILD
+++ b/cmd/kube-apiserver/app/BUILD
@@ -70,6 +70,7 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/storage/etcd3/preflight:go_default_library",
"//vendor/k8s.io/client-go/informers:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
+ "//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration:go_default_library",
"//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1:go_default_library",
diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go
index 9c14fa45829..16329486b1e 100644
--- a/cmd/kube-apiserver/app/server.go
+++ b/cmd/kube-apiserver/app/server.go
@@ -84,6 +84,7 @@ import (
"k8s.io/kubernetes/pkg/version"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap"
+ "k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/api"
_ "k8s.io/kubernetes/pkg/util/reflector/prometheus" // for reflector metric registration
_ "k8s.io/kubernetes/pkg/util/workqueue/prometheus" // for workqueue metric registration
@@ -456,12 +457,15 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp
client,
sharedInformers,
serviceResolver,
- proxyTransport,
)
if err != nil {
return nil, nil, nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %v", err)
}
+ webhookClientConfig := rest.AnonymousClientConfig(genericConfig.LoopbackClientConfig)
+ if proxyTransport != nil && proxyTransport.Dial != nil {
+ webhookClientConfig.Dial = proxyTransport.Dial
+ }
// TODO: this is the wrong cert/key pair.
// Given the generic case of webhook admission from a generic apiserver,
// this key pair should be signed by the the API server's client CA.
@@ -477,14 +481,17 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp
if err != nil {
return nil, nil, nil, nil, nil, fmt.Errorf("failed to read proxy client key file from: %s, err: %v", s.ProxyClientKeyFile, err)
}
+ webhookClientConfig.TLSClientConfig.CertData = certBytes
+ webhookClientConfig.TLSClientConfig.KeyData = keyBytes
}
+ webhookClientConfig.UserAgent = "kube-apiserver-admission"
+ webhookClientConfig.Timeout = 30 * time.Second
err = s.Admission.ApplyTo(
genericConfig,
versionedInformers,
- certBytes,
- keyBytes,
kubeClientConfig,
+ webhookClientConfig,
legacyscheme.Scheme,
pluginInitializer)
if err != nil {
@@ -494,7 +501,7 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp
}
// BuildAdmissionPluginInitializer constructs the admission plugin initializer
-func BuildAdmissionPluginInitializer(s *options.ServerRunOptions, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, serviceResolver aggregatorapiserver.ServiceResolver, proxyTransport *http.Transport) (admission.PluginInitializer, error) {
+func BuildAdmissionPluginInitializer(s *options.ServerRunOptions, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, serviceResolver aggregatorapiserver.ServiceResolver) (admission.PluginInitializer, error) {
var cloudConfig []byte
if s.CloudProvider.CloudConfigFile != "" {
@@ -515,7 +522,6 @@ func BuildAdmissionPluginInitializer(s *options.ServerRunOptions, client interna
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, cloudConfig, restMapper, quotaRegistry)
pluginInitializer = pluginInitializer.SetServiceResolver(serviceResolver)
- pluginInitializer = pluginInitializer.SetProxyTransport(proxyTransport)
return pluginInitializer, nil
}
diff --git a/cmd/kube-proxy/app/validation.go b/cmd/kube-proxy/app/validation.go
index f899bd35c71..89c8cea03c0 100644
--- a/cmd/kube-proxy/app/validation.go
+++ b/cmd/kube-proxy/app/validation.go
@@ -120,9 +120,10 @@ func validateProxyMode(mode componentconfig.ProxyMode, fldPath *field.Path) fiel
switch mode {
case componentconfig.ProxyModeUserspace:
case componentconfig.ProxyModeIPTables:
+ case componentconfig.ProxyModeIPVS:
case "":
default:
- modes := []string{string(componentconfig.ProxyModeUserspace), string(componentconfig.ProxyModeIPTables)}
+ modes := []string{string(componentconfig.ProxyModeUserspace), string(componentconfig.ProxyModeIPTables), string(componentconfig.ProxyModeIPVS)}
errMsg := fmt.Sprintf("must be %s or blank (blank means the best-available proxy (currently iptables)", strings.Join(modes, ","))
allErrs = append(allErrs, field.Invalid(fldPath.Child("ProxyMode"), string(mode), errMsg))
}
diff --git a/cmd/kube-proxy/app/validation_test.go b/cmd/kube-proxy/app/validation_test.go
index cd30adcdfa8..c860d1f5409 100644
--- a/cmd/kube-proxy/app/validation_test.go
+++ b/cmd/kube-proxy/app/validation_test.go
@@ -374,6 +374,7 @@ func TestValidateProxyMode(t *testing.T) {
successCases := []componentconfig.ProxyMode{
componentconfig.ProxyModeUserspace,
componentconfig.ProxyModeIPTables,
+ componentconfig.ProxyModeIPVS,
componentconfig.ProxyMode(""),
}
diff --git a/cmd/kubeadm/app/cmd/reset.go b/cmd/kubeadm/app/cmd/reset.go
index 97213254feb..44edae99a56 100644
--- a/cmd/kubeadm/app/cmd/reset.go
+++ b/cmd/kubeadm/app/cmd/reset.go
@@ -133,6 +133,9 @@ func (r *Reset) Run(out io.Writer) error {
}
// Remove contents from the config and pki directories
+ if r.certsDir != kubeadmapiext.DefaultCertificatesDir {
+ fmt.Printf("[reset] WARNING: Cleaning a non-default certificates directory: %q\n", r.certsDir)
+ }
resetConfigDir(kubeadmconstants.KubernetesDir, r.certsDir)
return nil
diff --git a/cmd/kubeadm/app/cmd/util/cmdutil.go b/cmd/kubeadm/app/cmd/util/cmdutil.go
index 3c0e7d65b10..21386775103 100644
--- a/cmd/kubeadm/app/cmd/util/cmdutil.go
+++ b/cmd/kubeadm/app/cmd/util/cmdutil.go
@@ -39,19 +39,21 @@ func SubCmdRunE(name string) func(*cobra.Command, []string) error {
// ValidateExactArgNumber validates that the required top-level arguments are specified
func ValidateExactArgNumber(args []string, supportedArgs []string) error {
+ lenSupported := len(supportedArgs)
validArgs := 0
// Disregard possible "" arguments; they are invalid
for _, arg := range args {
if len(arg) > 0 {
validArgs++
}
+ // break early for too many arguments
+ if validArgs > lenSupported {
+ return fmt.Errorf("too many arguments. Required arguments: %v", supportedArgs)
+ }
}
- if validArgs < len(supportedArgs) {
+ if validArgs < lenSupported {
return fmt.Errorf("missing one or more required arguments. Required arguments: %v", supportedArgs)
}
- if validArgs > len(supportedArgs) {
- return fmt.Errorf("too many arguments, only %d argument(s) supported: %v", validArgs, supportedArgs)
- }
return nil
}
diff --git a/cmd/kubeadm/app/preflight/checks.go b/cmd/kubeadm/app/preflight/checks.go
index 0925e11328f..85b1ee81da8 100644
--- a/cmd/kubeadm/app/preflight/checks.go
+++ b/cmd/kubeadm/app/preflight/checks.go
@@ -55,6 +55,7 @@ import (
const (
bridgenf = "/proc/sys/net/bridge/bridge-nf-call-iptables"
+ bridgenf6 = "/proc/sys/net/bridge/bridge-nf-call-ip6tables"
externalEtcdRequestTimeout = time.Duration(10 * time.Second)
externalEtcdRequestRetries = 3
externalEtcdRequestInterval = time.Duration(5 * time.Second)
@@ -700,6 +701,13 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
}
}
+ if ip := net.ParseIP(cfg.API.AdvertiseAddress); ip != nil {
+ if ip.To4() == nil && ip.To16() != nil {
+ checks = append(checks,
+ FileContentCheck{Path: bridgenf6, Content: []byte{'1'}},
+ )
+ }
+ }
return RunChecks(checks, os.Stderr)
}
@@ -734,6 +742,15 @@ func RunJoinNodeChecks(cfg *kubeadmapi.NodeConfiguration) error {
InPathCheck{executable: "touch", mandatory: false},
}
+ if len(cfg.DiscoveryTokenAPIServers) > 0 {
+ if ip := net.ParseIP(cfg.DiscoveryTokenAPIServers[0]); ip != nil {
+ if ip.To4() == nil && ip.To16() != nil {
+ checks = append(checks,
+ FileContentCheck{Path: bridgenf6, Content: []byte{'1'}},
+ )
+ }
+ }
+ }
return RunChecks(checks, os.Stderr)
}
diff --git a/cmd/kubeadm/app/preflight/checks_test.go b/cmd/kubeadm/app/preflight/checks_test.go
index 18efdfd1a60..150bc71eea1 100644
--- a/cmd/kubeadm/app/preflight/checks_test.go
+++ b/cmd/kubeadm/app/preflight/checks_test.go
@@ -205,6 +205,12 @@ func TestRunInitMasterChecks(t *testing.T) {
},
expected: false,
},
+ {
+ cfg: &kubeadmapi.MasterConfiguration{
+ API: kubeadmapi.API{AdvertiseAddress: "2001:1234::1:15"},
+ },
+ expected: false,
+ },
}
for _, rt := range tests {
@@ -229,6 +235,18 @@ func TestRunJoinNodeChecks(t *testing.T) {
cfg: &kubeadmapi.NodeConfiguration{},
expected: false,
},
+ {
+ cfg: &kubeadmapi.NodeConfiguration{
+ DiscoveryTokenAPIServers: []string{"192.168.1.15"},
+ },
+ expected: false,
+ },
+ {
+ cfg: &kubeadmapi.NodeConfiguration{
+ DiscoveryTokenAPIServers: []string{"2001:1234::1:15"},
+ },
+ expected: false,
+ },
}
for _, rt := range tests {
diff --git a/cmd/kubelet/app/options/options.go b/cmd/kubelet/app/options/options.go
index 539e3785b16..08e09e80aa5 100644
--- a/cmd/kubelet/app/options/options.go
+++ b/cmd/kubelet/app/options/options.go
@@ -156,6 +156,8 @@ type KubeletFlags struct {
// This flag, if set, instructs the kubelet to keep volumes from terminated pods mounted to the node.
// This can be useful for debugging volume related issues.
KeepTerminatedPodVolumes bool
+ // enable gathering custom metrics.
+ EnableCustomMetrics bool
}
// NewKubeletFlags will create a new KubeletFlags with default values
@@ -184,6 +186,8 @@ func NewKubeletFlags() *KubeletFlags {
ExperimentalQOSReserved: make(map[string]string),
RemoteRuntimeEndpoint: remoteRuntimeEndpoint,
RotateCertificates: false,
+ // TODO(#54161:v1.11.0): Remove --enable-custom-metrics flag, it is deprecated.
+ EnableCustomMetrics: false,
}
}
@@ -316,6 +320,9 @@ func (f *KubeletFlags) AddFlags(fs *pflag.FlagSet) {
fs.MarkDeprecated("non-masquerade-cidr", "will be removed in a future version")
fs.BoolVar(&f.KeepTerminatedPodVolumes, "keep-terminated-pod-volumes", f.KeepTerminatedPodVolumes, "Keep terminated pod volumes mounted to the node after the pod terminates. Can be useful for debugging volume related issues.")
fs.MarkDeprecated("keep-terminated-pod-volumes", "will be removed in a future version")
+ // TODO(#54161:v1.11.0): Remove --enable-custom-metrics flag, it is deprecated.
+ fs.BoolVar(&f.EnableCustomMetrics, "enable-custom-metrics", f.EnableCustomMetrics, "Support for gathering custom metrics.")
+ fs.MarkDeprecated("enable-custom-metrics", "will be removed in a future version")
}
@@ -428,7 +435,6 @@ func AddKubeletConfigFlags(fs *pflag.FlagSet, c *kubeletconfig.KubeletConfigurat
fs.Int32Var(&c.KubeAPIBurst, "kube-api-burst", c.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver")
fs.BoolVar(&c.SerializeImagePulls, "serialize-image-pulls", c.SerializeImagePulls, "Pull images one at a time. We recommend *not* changing the default value on nodes that run docker daemon with version < 1.9 or an Aufs storage backend. Issue #10959 has more details.")
- fs.BoolVar(&c.EnableCustomMetrics, "enable-custom-metrics", c.EnableCustomMetrics, "Support for gathering custom metrics.")
fs.StringVar(&c.RuntimeCgroups, "runtime-cgroups", c.RuntimeCgroups, "Optional absolute name of cgroups to create and run the runtime in.")
fs.StringVar(&c.EvictionHard, "eviction-hard", c.EvictionHard, "A set of eviction thresholds (e.g. memory.available<1Gi) that if met would trigger a pod eviction.")
fs.StringVar(&c.EvictionSoft, "eviction-soft", c.EvictionSoft, "A set of eviction thresholds (e.g. memory.available<1.5Gi) that if met over a corresponding grace period would trigger a pod eviction.")
diff --git a/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html b/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html
index ffd1dc03756..85c94a8e5bc 100755
--- a/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html
+++ b/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html
@@ -720,6 +720,13 @@ Depending on the enclosing object, subresources might not be allowed. Required.<
|
+urlPath |
+URLPath is an optional field that specifies the URL path to use when posting the AdmissionReview object. |
+true |
+string |
+ |
+
+
caBundle |
CABundle is a PEM encoded CA bundle which will be used to validate webhook’s server certificate. Required |
true |
diff --git a/examples/cockroachdb/cockroachdb-statefulset.yaml b/examples/cockroachdb/cockroachdb-statefulset.yaml
index a3eab10393d..0afdef391e1 100644
--- a/examples/cockroachdb/cockroachdb-statefulset.yaml
+++ b/examples/cockroachdb/cockroachdb-statefulset.yaml
@@ -163,8 +163,6 @@ spec:
volumeClaimTemplates:
- metadata:
name: datadir
- annotations:
- volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes:
- "ReadWriteOnce"
diff --git a/examples/storage/cassandra/cassandra-statefulset.yaml b/examples/storage/cassandra/cassandra-statefulset.yaml
index 62d7d2a7131..bade7674b3a 100644
--- a/examples/storage/cassandra/cassandra-statefulset.yaml
+++ b/examples/storage/cassandra/cassandra-statefulset.yaml
@@ -82,13 +82,12 @@ spec:
volumeClaimTemplates:
- metadata:
name: cassandra-data
- annotations:
- volume.beta.kubernetes.io/storage-class: fast
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
+ storageClassName: fast
---
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
diff --git a/examples/storage/minio/minio-distributed-statefulset.yaml b/examples/storage/minio/minio-distributed-statefulset.yaml
index 5457df249cf..9727f0e1808 100644
--- a/examples/storage/minio/minio-distributed-statefulset.yaml
+++ b/examples/storage/minio/minio-distributed-statefulset.yaml
@@ -39,8 +39,6 @@ spec:
volumeClaimTemplates:
- metadata:
name: data
- annotations:
- volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes:
- ReadWriteOnce
diff --git a/examples/storage/minio/minio-standalone-pvc.yaml b/examples/storage/minio/minio-standalone-pvc.yaml
index edd05215a9e..66b1c9800f2 100644
--- a/examples/storage/minio/minio-standalone-pvc.yaml
+++ b/examples/storage/minio/minio-standalone-pvc.yaml
@@ -3,8 +3,6 @@ kind: PersistentVolumeClaim
metadata:
# This name uniquely identifies the PVC. Will be used in deployment below.
name: minio-pv-claim
- annotations:
- volume.alpha.kubernetes.io/storage-class: anything
labels:
app: minio-storage-claim
spec:
diff --git a/examples/volumes/nfs/provisioner/nfs-server-gce-pv.yaml b/examples/volumes/nfs/provisioner/nfs-server-gce-pv.yaml
index 92f9f573584..cccb9a42a4a 100644
--- a/examples/volumes/nfs/provisioner/nfs-server-gce-pv.yaml
+++ b/examples/volumes/nfs/provisioner/nfs-server-gce-pv.yaml
@@ -4,8 +4,6 @@ metadata:
name: nfs-pv-provisioning-demo
labels:
demo: nfs-pv-provisioning
- annotations:
- volume.alpha.kubernetes.io/storage-class: any
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
diff --git a/examples/volumes/portworx/portworx-volume-pvcsc.yaml b/examples/volumes/portworx/portworx-volume-pvcsc.yaml
index b07ddb3029e..736e67feeaf 100644
--- a/examples/volumes/portworx/portworx-volume-pvcsc.yaml
+++ b/examples/volumes/portworx/portworx-volume-pvcsc.yaml
@@ -2,11 +2,10 @@ kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvcsc001
- annotations:
- volume.beta.kubernetes.io/storage-class: portworx-io-priority-high
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
+ storageClassName: portworx-io-priority-high
diff --git a/examples/volumes/scaleio/sc-pvc.yaml b/examples/volumes/scaleio/sc-pvc.yaml
index 3937a1e8254..078fb63548f 100644
--- a/examples/volumes/scaleio/sc-pvc.yaml
+++ b/examples/volumes/scaleio/sc-pvc.yaml
@@ -2,11 +2,10 @@ kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-sio-small
- annotations:
- volume.beta.kubernetes.io/storage-class: sio-small
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
+ storageClassName: sio-small
diff --git a/examples/volumes/vsphere/simple-statefulset.yaml b/examples/volumes/vsphere/simple-statefulset.yaml
index 465c7c5eddf..3684a3b64e1 100644
--- a/examples/volumes/vsphere/simple-statefulset.yaml
+++ b/examples/volumes/vsphere/simple-statefulset.yaml
@@ -37,10 +37,9 @@ spec:
volumeClaimTemplates:
- metadata:
name: www
- annotations:
- volume.beta.kubernetes.io/storage-class: thin-disk
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
+ storageClassName: thin-disk
diff --git a/examples/volumes/vsphere/vsphere-volume-pvcsc.yaml b/examples/volumes/vsphere/vsphere-volume-pvcsc.yaml
index f73ed91b5bd..03f3f8f8fe2 100644
--- a/examples/volumes/vsphere/vsphere-volume-pvcsc.yaml
+++ b/examples/volumes/vsphere/vsphere-volume-pvcsc.yaml
@@ -2,11 +2,10 @@ kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvcsc001
- annotations:
- volume.beta.kubernetes.io/storage-class: fast
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
+ storageClassName: fast
diff --git a/federation/cmd/federation-apiserver/app/BUILD b/federation/cmd/federation-apiserver/app/BUILD
index 17b50f446c1..94dca3aff96 100644
--- a/federation/cmd/federation-apiserver/app/BUILD
+++ b/federation/cmd/federation-apiserver/app/BUILD
@@ -84,6 +84,7 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
"//vendor/k8s.io/client-go/informers:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
+ "//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/common:go_default_library",
],
)
diff --git a/federation/cmd/federation-apiserver/app/server.go b/federation/cmd/federation-apiserver/app/server.go
index 7e1504533bc..e8f7a092b80 100644
--- a/federation/cmd/federation-apiserver/app/server.go
+++ b/federation/cmd/federation-apiserver/app/server.go
@@ -42,6 +42,7 @@ import (
serverstorage "k8s.io/apiserver/pkg/server/storage"
clientgoinformers "k8s.io/client-go/informers"
clientgoclientset "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/rest"
openapicommon "k8s.io/kube-openapi/pkg/common"
federationv1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1"
"k8s.io/kubernetes/federation/cmd/federation-apiserver/app/options"
@@ -215,9 +216,8 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
err = s.Admission.ApplyTo(
genericConfig,
versionedInformers,
- nil,
- nil,
kubeClientConfig,
+ rest.AnonymousClientConfig(kubeClientConfig),
legacyscheme.Scheme,
pluginInitializer,
)
diff --git a/federation/pkg/kubefed/init/init.go b/federation/pkg/kubefed/init/init.go
index 60803e75ec2..4193c598b45 100644
--- a/federation/pkg/kubefed/init/init.go
+++ b/federation/pkg/kubefed/init/init.go
@@ -136,6 +136,8 @@ type initFederation struct {
type initFederationOptions struct {
dnsZoneName string
serverImage string
+ imagePullPolicy string
+ imagePullSecrets string
dnsProvider string
dnsProviderConfig string
etcdImage string
@@ -161,6 +163,8 @@ type initFederationOptions struct {
func (o *initFederationOptions) Bind(flags *pflag.FlagSet, defaultServerImage, defaultEtcdImage string) {
flags.StringVar(&o.dnsZoneName, "dns-zone-name", "", "DNS suffix for this federation. Federated Service DNS names are published with this suffix.")
flags.StringVar(&o.serverImage, "image", defaultServerImage, "Image to use for federation API server and controller manager binaries.")
+ flags.StringVar(&o.imagePullPolicy, "image-pull-policy", string(api.PullIfNotPresent), "PullPolicy describes a policy for if/when to pull a container image. The default pull policy is IfNotPresent which will not pull an image if it already exists.")
+ flags.StringVar(&o.imagePullSecrets, "image-pull-secrets", "", "Provide secrets that can access the private registry.")
flags.StringVar(&o.dnsProvider, "dns-provider", "", "Dns provider to be used for this deployment.")
flags.StringVar(&o.dnsProviderConfig, "dns-provider-config", "", "Config file path on local file system for configuring DNS provider.")
flags.StringVar(&o.etcdImage, "etcd-image", defaultEtcdImage, "Image to use for etcd server.")
@@ -368,7 +372,7 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
fmt.Fprint(cmdOut, "Creating federation component deployments...")
glog.V(4).Info("Creating federation control plane components")
- _, err = createAPIServer(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.serverImage, i.options.etcdImage, advertiseAddress, serverCredName, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.apiServerOverrides, pvc, i.options.dryRun, i.options.nodeSelector)
+ _, err = createAPIServer(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.serverImage, i.options.etcdImage, advertiseAddress, serverCredName, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.apiServerOverrides, pvc, i.options.dryRun, i.options.nodeSelector, i.options.imagePullPolicy, i.options.imagePullSecrets)
if err != nil {
return err
}
@@ -403,7 +407,7 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error {
glog.V(4).Info("Creating federation controller manager deployment")
- _, err = createControllerManager(hostClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, cmName, i.options.serverImage, cmKubeconfigName, i.options.dnsZoneName, i.options.dnsProvider, i.options.dnsProviderConfig, sa.Name, dnsProviderSecret, i.options.controllerManagerOverrides, i.options.dryRun, i.options.nodeSelector)
+ _, err = createControllerManager(hostClientset, i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, cmName, i.options.serverImage, cmKubeconfigName, i.options.dnsZoneName, i.options.dnsProvider, i.options.dnsProviderConfig, sa.Name, dnsProviderSecret, i.options.controllerManagerOverrides, i.options.dryRun, i.options.nodeSelector, i.options.imagePullPolicy, i.options.imagePullSecrets)
if err != nil {
return err
}
@@ -709,7 +713,7 @@ func createPVC(clientset client.Interface, namespace, svcName, federationName, e
return clientset.Core().PersistentVolumeClaims(namespace).Create(pvc)
}
-func createAPIServer(clientset client.Interface, namespace, name, federationName, serverImage, etcdImage, advertiseAddress, credentialsName string, hasHTTPBasicAuthFile, hasTokenAuthFile bool, argOverrides map[string]string, pvc *api.PersistentVolumeClaim, dryRun bool, nodeSelector map[string]string) (*extensions.Deployment, error) {
+func createAPIServer(clientset client.Interface, namespace, name, federationName, serverImage, etcdImage, advertiseAddress, credentialsName string, hasHTTPBasicAuthFile, hasTokenAuthFile bool, argOverrides map[string]string, pvc *api.PersistentVolumeClaim, dryRun bool, nodeSelector map[string]string, imagePullPolicy, imagePullSecrets string) (*extensions.Deployment, error) {
command := []string{
"/hyperkube",
"federation-apiserver",
@@ -755,9 +759,10 @@ func createAPIServer(clientset client.Interface, namespace, name, federationName
Spec: api.PodSpec{
Containers: []api.Container{
{
- Name: "apiserver",
- Image: serverImage,
- Command: command,
+ Name: "apiserver",
+ Image: serverImage,
+ ImagePullPolicy: api.PullPolicy(imagePullPolicy),
+ Command: command,
Ports: []api.ContainerPort{
{
Name: apiServerSecurePortName,
@@ -787,6 +792,11 @@ func createAPIServer(clientset client.Interface, namespace, name, federationName
},
},
NodeSelector: nodeSelector,
+ ImagePullSecrets: []api.LocalObjectReference{
+ {
+ Name: imagePullSecrets,
+ },
+ },
Volumes: []api.Volume{
{
Name: credentialsName,
@@ -884,7 +894,7 @@ func createRoleBindings(clientset client.Interface, namespace, saName, federatio
return newRole, newRolebinding, err
}
-func createControllerManager(clientset client.Interface, namespace, name, svcName, cmName, image, kubeconfigName, dnsZoneName, dnsProvider, dnsProviderConfig, saName string, dnsProviderSecret *api.Secret, argOverrides map[string]string, dryRun bool, nodeSelector map[string]string) (*extensions.Deployment, error) {
+func createControllerManager(clientset client.Interface, namespace, name, svcName, cmName, image, kubeconfigName, dnsZoneName, dnsProvider, dnsProviderConfig, saName string, dnsProviderSecret *api.Secret, argOverrides map[string]string, dryRun bool, nodeSelector map[string]string, imagePullPolicy, imagePullSecrets string) (*extensions.Deployment, error) {
command := []string{
"/hyperkube",
"federation-controller-manager",
@@ -931,9 +941,10 @@ func createControllerManager(clientset client.Interface, namespace, name, svcNam
Spec: api.PodSpec{
Containers: []api.Container{
{
- Name: "controller-manager",
- Image: image,
- Command: command,
+ Name: "controller-manager",
+ Image: image,
+ ImagePullPolicy: api.PullPolicy(imagePullPolicy),
+ Command: command,
VolumeMounts: []api.VolumeMount{
{
Name: kubeconfigName,
@@ -954,6 +965,11 @@ func createControllerManager(clientset client.Interface, namespace, name, svcNam
},
},
NodeSelector: nodeSelector,
+ ImagePullSecrets: []api.LocalObjectReference{
+ {
+ Name: imagePullSecrets,
+ },
+ },
Volumes: []api.Volume{
{
Name: kubeconfigName,
diff --git a/federation/pkg/kubefed/init/init_test.go b/federation/pkg/kubefed/init/init_test.go
index 73e9e5d81c0..6db8e70110a 100644
--- a/federation/pkg/kubefed/init/init_test.go
+++ b/federation/pkg/kubefed/init/init_test.go
@@ -97,6 +97,8 @@ func TestInitFederation(t *testing.T) {
apiserverServiceType v1.ServiceType
advertiseAddress string
serverImage string
+ imagePullPolicy string
+ imagePullSecrets string
etcdImage string
etcdPVCapacity string
etcdPVStorageClass string
@@ -120,6 +122,7 @@ func TestInitFederation(t *testing.T) {
lbIP: lbIP,
apiserverServiceType: v1.ServiceTypeLoadBalancer,
serverImage: "example.test/foo:bar",
+ imagePullPolicy: "IfNotPresent",
etcdPVCapacity: "5Gi",
etcdPersistence: "true",
expectedErr: "",
@@ -138,6 +141,7 @@ func TestInitFederation(t *testing.T) {
lbIP: lbIP,
apiserverServiceType: v1.ServiceTypeLoadBalancer,
serverImage: "example.test/foo:bar",
+ imagePullPolicy: "IfNotPresent",
etcdPVCapacity: "", //test for default value of pvc-size
etcdPersistence: "true",
expectedErr: "",
@@ -151,6 +155,7 @@ func TestInitFederation(t *testing.T) {
lbIP: lbIP,
apiserverServiceType: v1.ServiceTypeLoadBalancer,
serverImage: "example.test/foo:bar",
+ imagePullPolicy: "IfNotPresent",
etcdPVCapacity: "",
etcdPersistence: "true",
expectedErr: "",
@@ -164,6 +169,7 @@ func TestInitFederation(t *testing.T) {
lbIP: lbIP,
apiserverServiceType: v1.ServiceTypeLoadBalancer,
serverImage: "example.test/foo:bar",
+ imagePullPolicy: "IfNotPresent",
etcdPVCapacity: "5Gi",
etcdPersistence: "false",
expectedErr: "",
@@ -176,6 +182,7 @@ func TestInitFederation(t *testing.T) {
dnsZoneName: "example.test.",
apiserverServiceType: v1.ServiceTypeNodePort,
serverImage: "example.test/foo:bar",
+ imagePullPolicy: "IfNotPresent",
etcdPVCapacity: "5Gi",
etcdPersistence: "true",
expectedErr: "",
@@ -189,6 +196,7 @@ func TestInitFederation(t *testing.T) {
apiserverServiceType: v1.ServiceTypeNodePort,
advertiseAddress: nodeIP,
serverImage: "example.test/foo:bar",
+ imagePullPolicy: "IfNotPresent",
etcdPVCapacity: "5Gi",
etcdPersistence: "true",
expectedErr: "",
@@ -202,6 +210,7 @@ func TestInitFederation(t *testing.T) {
apiserverServiceType: v1.ServiceTypeNodePort,
advertiseAddress: nodeIP,
serverImage: "example.test/foo:bar",
+ imagePullPolicy: "IfNotPresent",
etcdImage: "gcr.io/google_containers/etcd:latest",
etcdPVCapacity: "5Gi",
etcdPVStorageClass: "fast",
@@ -248,8 +257,11 @@ func TestInitFederation(t *testing.T) {
if tc.etcdImage == "" {
tc.etcdImage = defaultEtcdImage
}
+ if tc.imagePullPolicy == "" {
+ tc.imagePullPolicy = "IfNotPresent"
+ }
- hostFactory, err := fakeInitHostFactory(tc.apiserverServiceType, tc.federation, util.DefaultFederationSystemNamespace, tc.advertiseAddress, tc.lbIP, tc.dnsZoneName, tc.serverImage, tc.etcdImage, tc.dnsProvider, tc.dnsProviderConfig, tc.etcdPersistence, tc.etcdPVCapacity, tc.etcdPVStorageClass, tc.apiserverArgOverrides, tc.cmArgOverrides, tmpDirPath, tc.apiserverEnableHTTPBasicAuth, tc.apiserverEnableTokenAuth, tc.isRBACAPIAvailable, tc.nodeSelector)
+ hostFactory, err := fakeInitHostFactory(tc.apiserverServiceType, tc.federation, util.DefaultFederationSystemNamespace, tc.advertiseAddress, tc.lbIP, tc.dnsZoneName, tc.serverImage, tc.etcdImage, tc.dnsProvider, tc.dnsProviderConfig, tc.etcdPersistence, tc.etcdPVCapacity, tc.etcdPVStorageClass, tc.apiserverArgOverrides, tc.cmArgOverrides, tmpDirPath, tc.apiserverEnableHTTPBasicAuth, tc.apiserverEnableTokenAuth, tc.isRBACAPIAvailable, tc.nodeSelector, tc.imagePullPolicy, tc.imagePullSecrets)
if err != nil {
t.Fatalf("[%d] unexpected error: %v", i, err)
}
@@ -266,6 +278,7 @@ func TestInitFederation(t *testing.T) {
cmd.Flags().Set("dns-zone-name", tc.dnsZoneName)
cmd.Flags().Set("image", tc.serverImage)
cmd.Flags().Set("etcd-image", tc.etcdImage)
+ cmd.Flags().Set("image-pull-policy", tc.imagePullPolicy)
cmd.Flags().Set("dns-provider", tc.dnsProvider)
cmd.Flags().Set("apiserver-arg-overrides", tc.apiserverArgOverrides)
cmd.Flags().Set("controllermanager-arg-overrides", tc.cmArgOverrides)
@@ -282,6 +295,9 @@ func TestInitFederation(t *testing.T) {
if tc.etcdPersistence != "true" {
cmd.Flags().Set("etcd-persistent-storage", tc.etcdPersistence)
}
+ if tc.imagePullSecrets != "" {
+ cmd.Flags().Set("image-pull-secrets", tc.imagePullSecrets)
+ }
if tc.apiserverServiceType != v1.ServiceTypeLoadBalancer {
cmd.Flags().Set(apiserverServiceTypeFlag, string(tc.apiserverServiceType))
cmd.Flags().Set(apiserverAdvertiseAddressFlag, tc.advertiseAddress)
@@ -627,7 +643,7 @@ func TestCertsHTTPS(t *testing.T) {
}
}
-func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, namespaceName, advertiseAddress, lbIp, dnsZoneName, serverImage, etcdImage, dnsProvider, dnsProviderConfig, etcdPersistence, etcdPVCapacity, etcdPVStorageClass, apiserverOverrideArg, cmOverrideArg, tmpDirPath string, apiserverEnableHTTPBasicAuth, apiserverEnableTokenAuth, isRBACAPIAvailable bool, nodeSelectorString string) (cmdutil.Factory, error) {
+func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, namespaceName, advertiseAddress, lbIp, dnsZoneName, serverImage, etcdImage, dnsProvider, dnsProviderConfig, etcdPersistence, etcdPVCapacity, etcdPVStorageClass, apiserverOverrideArg, cmOverrideArg, tmpDirPath string, apiserverEnableHTTPBasicAuth, apiserverEnableTokenAuth, isRBACAPIAvailable bool, nodeSelectorString string, imagePullPolicy, imagePullSecrets string) (cmdutil.Factory, error) {
svcName := federationName + "-apiserver"
svcUrlPrefix := "/api/v1/namespaces/federation-system/services"
credSecretName := svcName + "-credentials"
@@ -923,9 +939,10 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
Spec: v1.PodSpec{
Containers: []v1.Container{
{
- Name: "apiserver",
- Image: serverImage,
- Command: apiserverCommand,
+ Name: "apiserver",
+ Image: serverImage,
+ ImagePullPolicy: v1.PullPolicy(imagePullPolicy),
+ Command: apiserverCommand,
Ports: []v1.ContainerPort{
{
Name: apiServerSecurePortName,
@@ -955,6 +972,11 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
},
},
NodeSelector: nodeSelector,
+ ImagePullSecrets: []v1.LocalObjectReference{
+ {
+ Name: imagePullSecrets,
+ },
+ },
Volumes: []v1.Volume{
{
Name: credSecretName,
@@ -1041,9 +1063,10 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
Spec: v1.PodSpec{
Containers: []v1.Container{
{
- Name: "controller-manager",
- Image: serverImage,
- Command: cmCommand,
+ Name: "controller-manager",
+ Image: serverImage,
+ ImagePullPolicy: v1.PullPolicy(imagePullPolicy),
+ Command: cmCommand,
VolumeMounts: []v1.VolumeMount{
{
Name: cmKubeconfigSecretName,
@@ -1064,6 +1087,11 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
},
},
NodeSelector: nodeSelector,
+ ImagePullSecrets: []v1.LocalObjectReference{
+ {
+ Name: imagePullSecrets,
+ },
+ },
Volumes: []v1.Volume{
{
Name: cmKubeconfigSecretName,
diff --git a/federation/test/e2e/BUILD b/federation/test/e2e/BUILD
index be0be028596..fc2ea68a058 100644
--- a/federation/test/e2e/BUILD
+++ b/federation/test/e2e/BUILD
@@ -34,7 +34,6 @@ go_library(
"//test/e2e/chaosmonkey:go_default_library",
"//test/e2e/common:go_default_library",
"//test/e2e/framework:go_default_library",
- "//test/utils/image:go_default_library",
"//vendor/github.com/onsi/ginkgo:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/api/batch/v1:go_default_library",
diff --git a/federation/test/e2e/job.go b/federation/test/e2e/job.go
index 5e1e3a67927..5c2214dd385 100644
--- a/federation/test/e2e/job.go
+++ b/federation/test/e2e/job.go
@@ -29,7 +29,6 @@ import (
fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
fedframework "k8s.io/kubernetes/federation/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/framework"
- imageutils "k8s.io/kubernetes/test/utils/image"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -279,7 +278,7 @@ func newJobForFed(namespace string, name string, completions int32, parallelism
Containers: []v1.Container{
{
Name: "sleep",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"sleep", "1"},
},
},
diff --git a/federation/test/e2e/util.go b/federation/test/e2e/util.go
index f30d039455a..972227d2613 100644
--- a/federation/test/e2e/util.go
+++ b/federation/test/e2e/util.go
@@ -36,7 +36,6 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
var (
@@ -403,7 +402,7 @@ func discoverService(f *fedframework.Framework, name string, exists bool, podNam
Containers: []v1.Container{
{
Name: "federated-service-discovery-container",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: command,
},
},
diff --git a/hack/.golint_failures b/hack/.golint_failures
index 2bc450c9b66..0b681ce5bbd 100644
--- a/hack/.golint_failures
+++ b/hack/.golint_failures
@@ -209,7 +209,7 @@ pkg/kubelet
pkg/kubelet/apis
pkg/kubelet/apis/cri/testing
pkg/kubelet/apis/cri/v1alpha1/runtime
-pkg/kubelet/apis/deviceplugin/v1alpha1
+pkg/kubelet/apis/deviceplugin/v1alpha
pkg/kubelet/apis/kubeletconfig
pkg/kubelet/apis/kubeletconfig/v1alpha1
pkg/kubelet/cadvisor
@@ -778,6 +778,14 @@ staging/src/k8s.io/sample-apiserver/pkg/client/informers/internalversion/interna
staging/src/k8s.io/sample-apiserver/pkg/cmd/server
staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/fischer
staging/src/k8s.io/sample-apiserver/pkg/registry/wardle/flunder
+staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller
+staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1
+staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned
+staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake
+staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme
+staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1
+staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake
+staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces
test/e2e
test/e2e/apimachinery
test/e2e/apps
diff --git a/hack/make-rules/helpers/cache_go_dirs.sh b/hack/make-rules/helpers/cache_go_dirs.sh
index a16f78b8c02..82402c66767 100755
--- a/hack/make-rules/helpers/cache_go_dirs.sh
+++ b/hack/make-rules/helpers/cache_go_dirs.sh
@@ -39,7 +39,7 @@ function kfind() {
# include the "special" vendor directories which are actually part
# of the Kubernetes source tree - generators will use these for
# including certain core API concepts.
- find -H . ./vendor/k8s.io/apimachinery ./vendor/k8s.io/apiserver ./vendor/k8s.io/kube-aggregator ./vendor/k8s.io/apiextensions-apiserver ./vendor/k8s.io/metrics ./vendor/k8s.io/sample-apiserver ./vendor/k8s.io/api ./vendor/k8s.io/client-go ./vendor/k8s.io/code-generator \
+ find -H . ./vendor/k8s.io/apimachinery ./vendor/k8s.io/apiserver ./vendor/k8s.io/kube-aggregator ./vendor/k8s.io/apiextensions-apiserver ./vendor/k8s.io/metrics ./vendor/k8s.io/sample-apiserver ./vendor/k8s.io/api ./vendor/k8s.io/client-go ./vendor/k8s.io/code-generator ./vendor/k8s.io/sample-controller \
\( \
-not \( \
\( \
diff --git a/hack/make-rules/test-cmd-util.sh b/hack/make-rules/test-cmd-util.sh
index e5c2b71edd5..685cffa0907 100755
--- a/hack/make-rules/test-cmd-util.sh
+++ b/hack/make-rules/test-cmd-util.sh
@@ -915,6 +915,32 @@ __EOF__
set +o errexit
}
+# runs specific kubectl create tests
+run_create_tests() {
+ set -o nounset
+ set -o errexit
+
+ ### Create generic secret with explicit namespace
+ # Pre-condition: secret 'mysecret' does not exist
+ output_message=$(! kubectl get secrets mysecret 2>&1 "${kube_flags[@]}")
+ kube::test::if_has_string "${output_message}" 'secrets "mysecret" not found'
+ # Command
+ output_message=$(kubectl create "${kube_flags[@]}" secret generic mysecret --dry-run --from-literal=foo=bar -o jsonpath='{.metadata.namespace}' --namespace=user-specified)
+ # Post-condition: mysecret still not created since --dry-run was used
+ # Output from 'create' command should contain the specified --namespace value
+ failure_message=$(! kubectl get secrets mysecret 2>&1 "${kube_flags[@]}")
+ kube::test::if_has_string "${failure_message}" 'secrets "mysecret" not found'
+ kube::test::if_has_string "${output_message}" 'user-specified'
+ # Command
+ output_message=$(kubectl create "${kube_flags[@]}" secret generic mysecret --dry-run --from-literal=foo=bar -o jsonpath='{.metadata.namespace}')
+ # Post-condition: jsonpath for .metadata.namespace should be empty for object since --namespace was not explicitly specified
+ kube::test::if_empty_string "${output_message}"
+
+ set +o nounset
+ set +o errexit
+}
+
+
# Runs tests related to kubectl apply.
run_kubectl_apply_tests() {
set -o nounset
@@ -4568,6 +4594,14 @@ runTests() {
record_command run_kubectl_get_tests
fi
+
+ ######################
+ # Create #
+ ######################
+ if kube::test::if_supports_resource "${secrets}" ; then
+ record_command run_create_tests
+ fi
+
##################
# Global timeout #
##################
diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh
index 8fae4073c72..e13f11d1b1e 100755
--- a/hack/update-codegen.sh
+++ b/hack/update-codegen.sh
@@ -125,5 +125,6 @@ ${informergen} \
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/code-generator/hack/update-codegen.sh
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/kube-aggregator/hack/update-codegen.sh
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/sample-apiserver/hack/update-codegen.sh
+CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/sample-controller/hack/update-codegen.sh
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/apiextensions-apiserver/hack/update-codegen.sh
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/metrics/hack/update-codegen.sh
diff --git a/hack/update-generated-device-plugin-dockerized.sh b/hack/update-generated-device-plugin-dockerized.sh
index 15003fd0ce0..0398058b03f 100755
--- a/hack/update-generated-device-plugin-dockerized.sh
+++ b/hack/update-generated-device-plugin-dockerized.sh
@@ -19,8 +19,7 @@ set -o nounset
set -o pipefail
KUBE_ROOT="$(cd "$(dirname "${BASH_SOURCE}")/../" && pwd -P)"
-DEVICE_PLUGIN_ROOT="${KUBE_ROOT}/pkg/kubelet/apis/deviceplugin/v1alpha1/"
+DEVICE_PLUGIN_ROOT="${KUBE_ROOT}/pkg/kubelet/apis/deviceplugin/v1alpha/"
source "${KUBE_ROOT}/hack/lib/protoc.sh"
-
kube::protoc::generate_proto ${DEVICE_PLUGIN_ROOT}
diff --git a/hack/verify-codegen.sh b/hack/verify-codegen.sh
index af94a334ae0..02b979c2f9a 100755
--- a/hack/verify-codegen.sh
+++ b/hack/verify-codegen.sh
@@ -30,6 +30,7 @@ kube::golang::setup_env
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/code-generator/hack/verify-codegen.sh
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/kube-aggregator/hack/verify-codegen.sh
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/sample-apiserver/hack/verify-codegen.sh
+CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/sample-controller/hack/verify-codegen.sh
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/apiextensions-apiserver/hack/verify-codegen.sh
CODEGEN_PKG=./vendor/k8s.io/code-generator vendor/k8s.io/metrics/hack/verify-codegen.sh
diff --git a/hack/verify-generated-device-plugin.sh b/hack/verify-generated-device-plugin.sh
index 10797f3a5ca..c98cebae968 100755
--- a/hack/verify-generated-device-plugin.sh
+++ b/hack/verify-generated-device-plugin.sh
@@ -19,8 +19,8 @@ set -o nounset
set -o pipefail
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
-DEVICE_PLUGIN_ROOT="${KUBE_ROOT}/pkg/kubelet/apis/deviceplugin/v1alpha1/"
ERROR="Device plugin api is out of date. Please run hack/update-generated-device-plugin.sh"
+DEVICE_PLUGIN_ROOT="${KUBE_ROOT}/pkg/kubelet/apis/deviceplugin/v1alpha/"
source "${KUBE_ROOT}/hack/lib/protoc.sh"
kube::golang::setup_env
diff --git a/pkg/apis/admissionregistration/types.go b/pkg/apis/admissionregistration/types.go
index b4676560037..092f790c491 100644
--- a/pkg/apis/admissionregistration/types.go
+++ b/pkg/apis/admissionregistration/types.go
@@ -199,6 +199,10 @@ type AdmissionHookClientConfig struct {
// ports open, port 443 will be used if it is open, otherwise it is an error.
// Required
Service ServiceReference
+
+ // URLPath is an optional field that specifies the URL path to use when posting the AdmissionReview object.
+ URLPath string
+
// CABundle is a PEM encoded CA bundle which will be used to validate webhook's server certificate.
// Required
CABundle []byte
diff --git a/pkg/apis/admissionregistration/v1alpha1/zz_generated.conversion.go b/pkg/apis/admissionregistration/v1alpha1/zz_generated.conversion.go
index 86ef143f0ae..792254ba656 100644
--- a/pkg/apis/admissionregistration/v1alpha1/zz_generated.conversion.go
+++ b/pkg/apis/admissionregistration/v1alpha1/zz_generated.conversion.go
@@ -63,6 +63,7 @@ func autoConvert_v1alpha1_AdmissionHookClientConfig_To_admissionregistration_Adm
if err := Convert_v1alpha1_ServiceReference_To_admissionregistration_ServiceReference(&in.Service, &out.Service, s); err != nil {
return err
}
+ out.URLPath = in.URLPath
out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle))
return nil
}
@@ -76,6 +77,7 @@ func autoConvert_admissionregistration_AdmissionHookClientConfig_To_v1alpha1_Adm
if err := Convert_admissionregistration_ServiceReference_To_v1alpha1_ServiceReference(&in.Service, &out.Service, s); err != nil {
return err
}
+ out.URLPath = in.URLPath
out.CABundle = *(*[]byte)(unsafe.Pointer(&in.CABundle))
return nil
}
diff --git a/pkg/apis/admissionregistration/validation/validation.go b/pkg/apis/admissionregistration/validation/validation.go
index 3c4068f24c7..d7e7ac04352 100644
--- a/pkg/apis/admissionregistration/validation/validation.go
+++ b/pkg/apis/admissionregistration/validation/validation.go
@@ -182,6 +182,44 @@ func validateExternalAdmissionHook(hook *admissionregistration.ExternalAdmission
if hook.FailurePolicy != nil && !supportedFailurePolicies.Has(string(*hook.FailurePolicy)) {
allErrors = append(allErrors, field.NotSupported(fldPath.Child("failurePolicy"), *hook.FailurePolicy, supportedFailurePolicies.List()))
}
+
+ if len(hook.ClientConfig.URLPath) != 0 {
+ allErrors = append(allErrors, validateURLPath(fldPath.Child("clientConfig", "urlPath"), hook.ClientConfig.URLPath)...)
+ }
+
+ return allErrors
+}
+
+func validateURLPath(fldPath *field.Path, urlPath string) field.ErrorList {
+ var allErrors field.ErrorList
+ if urlPath == "/" || len(urlPath) == 0 {
+ return allErrors
+ }
+ if urlPath == "//" {
+ allErrors = append(allErrors, field.Invalid(fldPath, urlPath, "segment[0] may not be empty"))
+ return allErrors
+ }
+
+ if !strings.HasPrefix(urlPath, "/") {
+ allErrors = append(allErrors, field.Invalid(fldPath, urlPath, "must start with a '/'"))
+ }
+
+ urlPathToCheck := urlPath[1:]
+ if strings.HasSuffix(urlPathToCheck, "/") {
+ urlPathToCheck = urlPathToCheck[:len(urlPathToCheck)-1]
+ }
+ steps := strings.Split(urlPathToCheck, "/")
+ for i, step := range steps {
+ if len(step) == 0 {
+ allErrors = append(allErrors, field.Invalid(fldPath, urlPath, fmt.Sprintf("segment[%d] may not be empty", i)))
+ continue
+ }
+ failures := validation.IsDNS1123Subdomain(step)
+ for _, failure := range failures {
+ allErrors = append(allErrors, field.Invalid(fldPath, urlPath, fmt.Sprintf("segment[%d]: %v", i, failure)))
+ }
+ }
+
return allErrors
}
diff --git a/pkg/apis/admissionregistration/validation/validation_test.go b/pkg/apis/admissionregistration/validation/validation_test.go
index a842c472818..cd8f85edeb1 100644
--- a/pkg/apis/admissionregistration/validation/validation_test.go
+++ b/pkg/apis/admissionregistration/validation/validation_test.go
@@ -482,18 +482,111 @@ func TestValidateExternalAdmissionHookConfiguration(t *testing.T) {
}),
expectedError: `externalAdmissionHooks[0].failurePolicy: Unsupported value: "other": supported values: "Fail", "Ignore"`,
},
+ {
+ name: "URLPath must start with slash",
+ config: getExternalAdmissionHookConfiguration(
+ []admissionregistration.ExternalAdmissionHook{
+ {
+ Name: "webhook.k8s.io",
+ ClientConfig: admissionregistration.AdmissionHookClientConfig{
+ URLPath: "foo/",
+ },
+ },
+ }),
+ expectedError: `clientConfig.urlPath: Invalid value: "foo/": must start with a '/'`,
+ },
+ {
+ name: "URLPath accepts slash",
+ config: getExternalAdmissionHookConfiguration(
+ []admissionregistration.ExternalAdmissionHook{
+ {
+ Name: "webhook.k8s.io",
+ ClientConfig: admissionregistration.AdmissionHookClientConfig{
+ URLPath: "/",
+ },
+ },
+ }),
+ expectedError: ``,
+ },
+ {
+ name: "URLPath accepts no trailing slash",
+ config: getExternalAdmissionHookConfiguration(
+ []admissionregistration.ExternalAdmissionHook{
+ {
+ Name: "webhook.k8s.io",
+ ClientConfig: admissionregistration.AdmissionHookClientConfig{
+ URLPath: "/foo",
+ },
+ },
+ }),
+ expectedError: ``,
+ },
+ {
+ name: "URLPath fails //",
+ config: getExternalAdmissionHookConfiguration(
+ []admissionregistration.ExternalAdmissionHook{
+ {
+ Name: "webhook.k8s.io",
+ ClientConfig: admissionregistration.AdmissionHookClientConfig{
+ URLPath: "//",
+ },
+ },
+ }),
+ expectedError: `clientConfig.urlPath: Invalid value: "//": segment[0] may not be empty`,
+ },
+ {
+ name: "URLPath no empty step",
+ config: getExternalAdmissionHookConfiguration(
+ []admissionregistration.ExternalAdmissionHook{
+ {
+ Name: "webhook.k8s.io",
+ ClientConfig: admissionregistration.AdmissionHookClientConfig{
+ URLPath: "/foo//bar/",
+ },
+ },
+ }),
+ expectedError: `clientConfig.urlPath: Invalid value: "/foo//bar/": segment[1] may not be empty`,
+ }, {
+ name: "URLPath no empty step 2",
+ config: getExternalAdmissionHookConfiguration(
+ []admissionregistration.ExternalAdmissionHook{
+ {
+ Name: "webhook.k8s.io",
+ ClientConfig: admissionregistration.AdmissionHookClientConfig{
+ URLPath: "/foo/bar//",
+ },
+ },
+ }),
+ expectedError: `clientConfig.urlPath: Invalid value: "/foo/bar//": segment[2] may not be empty`,
+ },
+ {
+ name: "URLPath no non-subdomain",
+ config: getExternalAdmissionHookConfiguration(
+ []admissionregistration.ExternalAdmissionHook{
+ {
+ Name: "webhook.k8s.io",
+ ClientConfig: admissionregistration.AdmissionHookClientConfig{
+ URLPath: "/apis/foo.bar/v1alpha1/--bad",
+ },
+ },
+ }),
+ expectedError: `clientConfig.urlPath: Invalid value: "/apis/foo.bar/v1alpha1/--bad": segment[3]: a DNS-1123 subdomain`,
+ },
}
for _, test := range tests {
- errs := ValidateExternalAdmissionHookConfiguration(test.config)
- err := errs.ToAggregate()
- if err != nil {
- if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" {
- t.Errorf("test case %s, expected to contain %s, got %s", test.name, e, a)
+ t.Run(test.name, func(t *testing.T) {
+ errs := ValidateExternalAdmissionHookConfiguration(test.config)
+ err := errs.ToAggregate()
+ if err != nil {
+ if e, a := test.expectedError, err.Error(); !strings.Contains(a, e) || e == "" {
+ t.Errorf("expected to contain %s, got %s", e, a)
+ }
+ } else {
+ if test.expectedError != "" {
+ t.Errorf("unexpected no error, expected to contain %s", test.expectedError)
+ }
}
- } else {
- if test.expectedError != "" {
- t.Errorf("test case %s, unexpected no error, expected to contain %s", test.name, test.expectedError)
- }
- }
+ })
+
}
}
diff --git a/pkg/apis/componentconfig/types.go b/pkg/apis/componentconfig/types.go
index 6aa64e436dc..00d6cb02317 100644
--- a/pkg/apis/componentconfig/types.go
+++ b/pkg/apis/componentconfig/types.go
@@ -158,6 +158,7 @@ type ProxyMode string
const (
ProxyModeUserspace ProxyMode = "userspace"
ProxyModeIPTables ProxyMode = "iptables"
+ ProxyModeIPVS ProxyMode = "ipvs"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/pkg/client/listers/admissionregistration/internalversion/BUILD b/pkg/client/listers/admissionregistration/internalversion/BUILD
index 16b67f74c03..455a1cff695 100644
--- a/pkg/client/listers/admissionregistration/internalversion/BUILD
+++ b/pkg/client/listers/admissionregistration/internalversion/BUILD
@@ -16,7 +16,6 @@ go_library(
deps = [
"//pkg/apis/admissionregistration:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/pkg/client/listers/admissionregistration/internalversion/externaladmissionhookconfiguration.go b/pkg/client/listers/admissionregistration/internalversion/externaladmissionhookconfiguration.go
index ac200d55291..b9145988d95 100644
--- a/pkg/client/listers/admissionregistration/internalversion/externaladmissionhookconfiguration.go
+++ b/pkg/client/listers/admissionregistration/internalversion/externaladmissionhookconfiguration.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
admissionregistration "k8s.io/kubernetes/pkg/apis/admissionregistration"
@@ -55,8 +54,7 @@ func (s *externalAdmissionHookConfigurationLister) List(selector labels.Selector
// Get retrieves the ExternalAdmissionHookConfiguration from the index for a given name.
func (s *externalAdmissionHookConfigurationLister) Get(name string) (*admissionregistration.ExternalAdmissionHookConfiguration, error) {
- key := &admissionregistration.ExternalAdmissionHookConfiguration{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/admissionregistration/internalversion/initializerconfiguration.go b/pkg/client/listers/admissionregistration/internalversion/initializerconfiguration.go
index 8fe394f0eaa..0a67f7d8e8b 100644
--- a/pkg/client/listers/admissionregistration/internalversion/initializerconfiguration.go
+++ b/pkg/client/listers/admissionregistration/internalversion/initializerconfiguration.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
admissionregistration "k8s.io/kubernetes/pkg/apis/admissionregistration"
@@ -55,8 +54,7 @@ func (s *initializerConfigurationLister) List(selector labels.Selector) (ret []*
// Get retrieves the InitializerConfiguration from the index for a given name.
func (s *initializerConfigurationLister) Get(name string) (*admissionregistration.InitializerConfiguration, error) {
- key := &admissionregistration.InitializerConfiguration{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/authentication/internalversion/BUILD b/pkg/client/listers/authentication/internalversion/BUILD
index b5ea7c5e630..8a3d4bf56c5 100644
--- a/pkg/client/listers/authentication/internalversion/BUILD
+++ b/pkg/client/listers/authentication/internalversion/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//pkg/apis/authentication:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/pkg/client/listers/authentication/internalversion/tokenreview.go b/pkg/client/listers/authentication/internalversion/tokenreview.go
index df92d2fb20e..ca878ccd343 100644
--- a/pkg/client/listers/authentication/internalversion/tokenreview.go
+++ b/pkg/client/listers/authentication/internalversion/tokenreview.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
authentication "k8s.io/kubernetes/pkg/apis/authentication"
@@ -55,8 +54,7 @@ func (s *tokenReviewLister) List(selector labels.Selector) (ret []*authenticatio
// Get retrieves the TokenReview from the index for a given name.
func (s *tokenReviewLister) Get(name string) (*authentication.TokenReview, error) {
- key := &authentication.TokenReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/authorization/internalversion/BUILD b/pkg/client/listers/authorization/internalversion/BUILD
index 765f66ffb06..25fc1d63da7 100644
--- a/pkg/client/listers/authorization/internalversion/BUILD
+++ b/pkg/client/listers/authorization/internalversion/BUILD
@@ -18,7 +18,6 @@ go_library(
deps = [
"//pkg/apis/authorization:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/pkg/client/listers/authorization/internalversion/selfsubjectaccessreview.go b/pkg/client/listers/authorization/internalversion/selfsubjectaccessreview.go
index c968fa6d5c5..b883ef6035e 100644
--- a/pkg/client/listers/authorization/internalversion/selfsubjectaccessreview.go
+++ b/pkg/client/listers/authorization/internalversion/selfsubjectaccessreview.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
authorization "k8s.io/kubernetes/pkg/apis/authorization"
@@ -55,8 +54,7 @@ func (s *selfSubjectAccessReviewLister) List(selector labels.Selector) (ret []*a
// Get retrieves the SelfSubjectAccessReview from the index for a given name.
func (s *selfSubjectAccessReviewLister) Get(name string) (*authorization.SelfSubjectAccessReview, error) {
- key := &authorization.SelfSubjectAccessReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/authorization/internalversion/selfsubjectrulesreview.go b/pkg/client/listers/authorization/internalversion/selfsubjectrulesreview.go
index 999956a5a6c..9efca6cbf81 100644
--- a/pkg/client/listers/authorization/internalversion/selfsubjectrulesreview.go
+++ b/pkg/client/listers/authorization/internalversion/selfsubjectrulesreview.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
authorization "k8s.io/kubernetes/pkg/apis/authorization"
@@ -55,8 +54,7 @@ func (s *selfSubjectRulesReviewLister) List(selector labels.Selector) (ret []*au
// Get retrieves the SelfSubjectRulesReview from the index for a given name.
func (s *selfSubjectRulesReviewLister) Get(name string) (*authorization.SelfSubjectRulesReview, error) {
- key := &authorization.SelfSubjectRulesReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/authorization/internalversion/subjectaccessreview.go b/pkg/client/listers/authorization/internalversion/subjectaccessreview.go
index fbb6f404458..d6980c8d69d 100644
--- a/pkg/client/listers/authorization/internalversion/subjectaccessreview.go
+++ b/pkg/client/listers/authorization/internalversion/subjectaccessreview.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
authorization "k8s.io/kubernetes/pkg/apis/authorization"
@@ -55,8 +54,7 @@ func (s *subjectAccessReviewLister) List(selector labels.Selector) (ret []*autho
// Get retrieves the SubjectAccessReview from the index for a given name.
func (s *subjectAccessReviewLister) Get(name string) (*authorization.SubjectAccessReview, error) {
- key := &authorization.SubjectAccessReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/certificates/internalversion/BUILD b/pkg/client/listers/certificates/internalversion/BUILD
index f158bd430a3..afc655b9eee 100644
--- a/pkg/client/listers/certificates/internalversion/BUILD
+++ b/pkg/client/listers/certificates/internalversion/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//pkg/apis/certificates:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/pkg/client/listers/certificates/internalversion/certificatesigningrequest.go b/pkg/client/listers/certificates/internalversion/certificatesigningrequest.go
index 3ba28efa5d6..4ded13d7a60 100644
--- a/pkg/client/listers/certificates/internalversion/certificatesigningrequest.go
+++ b/pkg/client/listers/certificates/internalversion/certificatesigningrequest.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
certificates "k8s.io/kubernetes/pkg/apis/certificates"
@@ -55,8 +54,7 @@ func (s *certificateSigningRequestLister) List(selector labels.Selector) (ret []
// Get retrieves the CertificateSigningRequest from the index for a given name.
func (s *certificateSigningRequestLister) Get(name string) (*certificates.CertificateSigningRequest, error) {
- key := &certificates.CertificateSigningRequest{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/core/internalversion/BUILD b/pkg/client/listers/core/internalversion/BUILD
index 9f54d487886..4d3837bb180 100644
--- a/pkg/client/listers/core/internalversion/BUILD
+++ b/pkg/client/listers/core/internalversion/BUILD
@@ -33,7 +33,6 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/pkg/client/listers/core/internalversion/componentstatus.go b/pkg/client/listers/core/internalversion/componentstatus.go
index 8f0a0a71f09..7e560ba7091 100644
--- a/pkg/client/listers/core/internalversion/componentstatus.go
+++ b/pkg/client/listers/core/internalversion/componentstatus.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
api "k8s.io/kubernetes/pkg/api"
@@ -55,8 +54,7 @@ func (s *componentStatusLister) List(selector labels.Selector) (ret []*api.Compo
// Get retrieves the ComponentStatus from the index for a given name.
func (s *componentStatusLister) Get(name string) (*api.ComponentStatus, error) {
- key := &api.ComponentStatus{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/core/internalversion/namespace.go b/pkg/client/listers/core/internalversion/namespace.go
index c925f652373..2f5933a6f5d 100644
--- a/pkg/client/listers/core/internalversion/namespace.go
+++ b/pkg/client/listers/core/internalversion/namespace.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
api "k8s.io/kubernetes/pkg/api"
@@ -55,8 +54,7 @@ func (s *namespaceLister) List(selector labels.Selector) (ret []*api.Namespace,
// Get retrieves the Namespace from the index for a given name.
func (s *namespaceLister) Get(name string) (*api.Namespace, error) {
- key := &api.Namespace{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/core/internalversion/node.go b/pkg/client/listers/core/internalversion/node.go
index ba33d64896d..8625fbc5f2d 100644
--- a/pkg/client/listers/core/internalversion/node.go
+++ b/pkg/client/listers/core/internalversion/node.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
api "k8s.io/kubernetes/pkg/api"
@@ -55,8 +54,7 @@ func (s *nodeLister) List(selector labels.Selector) (ret []*api.Node, err error)
// Get retrieves the Node from the index for a given name.
func (s *nodeLister) Get(name string) (*api.Node, error) {
- key := &api.Node{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/core/internalversion/persistentvolume.go b/pkg/client/listers/core/internalversion/persistentvolume.go
index 040058df20f..808af1e9ef5 100644
--- a/pkg/client/listers/core/internalversion/persistentvolume.go
+++ b/pkg/client/listers/core/internalversion/persistentvolume.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
api "k8s.io/kubernetes/pkg/api"
@@ -55,8 +54,7 @@ func (s *persistentVolumeLister) List(selector labels.Selector) (ret []*api.Pers
// Get retrieves the PersistentVolume from the index for a given name.
func (s *persistentVolumeLister) Get(name string) (*api.PersistentVolume, error) {
- key := &api.PersistentVolume{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/extensions/internalversion/podsecuritypolicy.go b/pkg/client/listers/extensions/internalversion/podsecuritypolicy.go
index 03a976bad28..f57b903989e 100644
--- a/pkg/client/listers/extensions/internalversion/podsecuritypolicy.go
+++ b/pkg/client/listers/extensions/internalversion/podsecuritypolicy.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
extensions "k8s.io/kubernetes/pkg/apis/extensions"
@@ -55,8 +54,7 @@ func (s *podSecurityPolicyLister) List(selector labels.Selector) (ret []*extensi
// Get retrieves the PodSecurityPolicy from the index for a given name.
func (s *podSecurityPolicyLister) Get(name string) (*extensions.PodSecurityPolicy, error) {
- key := &extensions.PodSecurityPolicy{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/extensions/internalversion/thirdpartyresource.go b/pkg/client/listers/extensions/internalversion/thirdpartyresource.go
index 6177bf5f55a..5537b374cd5 100644
--- a/pkg/client/listers/extensions/internalversion/thirdpartyresource.go
+++ b/pkg/client/listers/extensions/internalversion/thirdpartyresource.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
extensions "k8s.io/kubernetes/pkg/apis/extensions"
@@ -55,8 +54,7 @@ func (s *thirdPartyResourceLister) List(selector labels.Selector) (ret []*extens
// Get retrieves the ThirdPartyResource from the index for a given name.
func (s *thirdPartyResourceLister) Get(name string) (*extensions.ThirdPartyResource, error) {
- key := &extensions.ThirdPartyResource{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/imagepolicy/internalversion/BUILD b/pkg/client/listers/imagepolicy/internalversion/BUILD
index af588cda286..22a9151e0cf 100644
--- a/pkg/client/listers/imagepolicy/internalversion/BUILD
+++ b/pkg/client/listers/imagepolicy/internalversion/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//pkg/apis/imagepolicy:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/pkg/client/listers/imagepolicy/internalversion/imagereview.go b/pkg/client/listers/imagepolicy/internalversion/imagereview.go
index 98cfe57b9fb..68b75375902 100644
--- a/pkg/client/listers/imagepolicy/internalversion/imagereview.go
+++ b/pkg/client/listers/imagepolicy/internalversion/imagereview.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
imagepolicy "k8s.io/kubernetes/pkg/apis/imagepolicy"
@@ -55,8 +54,7 @@ func (s *imageReviewLister) List(selector labels.Selector) (ret []*imagepolicy.I
// Get retrieves the ImageReview from the index for a given name.
func (s *imageReviewLister) Get(name string) (*imagepolicy.ImageReview, error) {
- key := &imagepolicy.ImageReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/rbac/internalversion/BUILD b/pkg/client/listers/rbac/internalversion/BUILD
index f0b816c06a3..1530995394e 100644
--- a/pkg/client/listers/rbac/internalversion/BUILD
+++ b/pkg/client/listers/rbac/internalversion/BUILD
@@ -18,7 +18,6 @@ go_library(
deps = [
"//pkg/apis/rbac:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/pkg/client/listers/rbac/internalversion/clusterrole.go b/pkg/client/listers/rbac/internalversion/clusterrole.go
index eda1cc3acfe..ae4089520d3 100644
--- a/pkg/client/listers/rbac/internalversion/clusterrole.go
+++ b/pkg/client/listers/rbac/internalversion/clusterrole.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
rbac "k8s.io/kubernetes/pkg/apis/rbac"
@@ -55,8 +54,7 @@ func (s *clusterRoleLister) List(selector labels.Selector) (ret []*rbac.ClusterR
// Get retrieves the ClusterRole from the index for a given name.
func (s *clusterRoleLister) Get(name string) (*rbac.ClusterRole, error) {
- key := &rbac.ClusterRole{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/rbac/internalversion/clusterrolebinding.go b/pkg/client/listers/rbac/internalversion/clusterrolebinding.go
index fed2b2e9f36..258c41768e1 100644
--- a/pkg/client/listers/rbac/internalversion/clusterrolebinding.go
+++ b/pkg/client/listers/rbac/internalversion/clusterrolebinding.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
rbac "k8s.io/kubernetes/pkg/apis/rbac"
@@ -55,8 +54,7 @@ func (s *clusterRoleBindingLister) List(selector labels.Selector) (ret []*rbac.C
// Get retrieves the ClusterRoleBinding from the index for a given name.
func (s *clusterRoleBindingLister) Get(name string) (*rbac.ClusterRoleBinding, error) {
- key := &rbac.ClusterRoleBinding{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/scheduling/internalversion/BUILD b/pkg/client/listers/scheduling/internalversion/BUILD
index 2dd68118549..5c2f02bafe7 100644
--- a/pkg/client/listers/scheduling/internalversion/BUILD
+++ b/pkg/client/listers/scheduling/internalversion/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//pkg/apis/scheduling:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/pkg/client/listers/scheduling/internalversion/priorityclass.go b/pkg/client/listers/scheduling/internalversion/priorityclass.go
index b219677dd2f..1692ba758dd 100644
--- a/pkg/client/listers/scheduling/internalversion/priorityclass.go
+++ b/pkg/client/listers/scheduling/internalversion/priorityclass.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
scheduling "k8s.io/kubernetes/pkg/apis/scheduling"
@@ -55,8 +54,7 @@ func (s *priorityClassLister) List(selector labels.Selector) (ret []*scheduling.
// Get retrieves the PriorityClass from the index for a given name.
func (s *priorityClassLister) Get(name string) (*scheduling.PriorityClass, error) {
- key := &scheduling.PriorityClass{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/client/listers/storage/internalversion/BUILD b/pkg/client/listers/storage/internalversion/BUILD
index 4733b25a4ac..b9e4434de74 100644
--- a/pkg/client/listers/storage/internalversion/BUILD
+++ b/pkg/client/listers/storage/internalversion/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//pkg/apis/storage:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/pkg/client/listers/storage/internalversion/storageclass.go b/pkg/client/listers/storage/internalversion/storageclass.go
index f1898a98f7f..b14973fe250 100644
--- a/pkg/client/listers/storage/internalversion/storageclass.go
+++ b/pkg/client/listers/storage/internalversion/storageclass.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
storage "k8s.io/kubernetes/pkg/apis/storage"
@@ -55,8 +54,7 @@ func (s *storageClassLister) List(selector labels.Selector) (ret []*storage.Stor
// Get retrieves the StorageClass from the index for a given name.
func (s *storageClassLister) Get(name string) (*storage.StorageClass, error) {
- key := &storage.StorageClass{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/pkg/controller/node/node_controller.go b/pkg/controller/node/node_controller.go
index a33e0b8b75a..3f44a3313ac 100644
--- a/pkg/controller/node/node_controller.go
+++ b/pkg/controller/node/node_controller.go
@@ -186,7 +186,6 @@ type Controller struct {
cidrAllocator ipam.CIDRAllocator
taintManager *scheduler.NoExecuteTaintManager
- forcefullyDeletePod func(*v1.Pod) error
nodeExistsInCloudProvider func(types.NodeName) (bool, error)
computeZoneStateFunc func(nodeConditions []*v1.NodeCondition) (int, ZoneState)
enterPartialDisruptionFunc func(nodeNum int) float32
@@ -285,9 +284,6 @@ func NewNodeController(
serviceCIDR: serviceCIDR,
allocateNodeCIDRs: allocateNodeCIDRs,
allocatorType: allocatorType,
- forcefullyDeletePod: func(p *v1.Pod) error {
- return util.ForcefullyDeletePod(kubeClient, p)
- },
nodeExistsInCloudProvider: func(nodeName types.NodeName) (bool, error) {
return util.NodeExistsInCloudProvider(cloud, nodeName)
},
diff --git a/pkg/controller/node/util/controller_utils.go b/pkg/controller/node/util/controller_utils.go
index 17258e774f4..9fedc3bbe8f 100644
--- a/pkg/controller/node/util/controller_utils.go
+++ b/pkg/controller/node/util/controller_utils.go
@@ -129,17 +129,6 @@ func SetPodTerminationReason(kubeClient clientset.Interface, pod *v1.Pod, nodeNa
return updatedPod, nil
}
-// ForcefullyDeletePod deletes the pod immediately.
-func ForcefullyDeletePod(c clientset.Interface, pod *v1.Pod) error {
- var zero int64
- glog.Infof("NodeController is force deleting Pod: %v:%v", pod.Namespace, pod.Name)
- err := c.Core().Pods(pod.Namespace).Delete(pod.Name, &metav1.DeleteOptions{GracePeriodSeconds: &zero})
- if err == nil {
- glog.V(4).Infof("forceful deletion of %s succeeded", pod.Name)
- }
- return err
-}
-
// ForcefullyDeleteNode deletes the node immediately. The pods on the
// node are cleaned up by the podGC.
func ForcefullyDeleteNode(kubeClient clientset.Interface, nodeName string) error {
diff --git a/pkg/controller/podautoscaler/horizontal.go b/pkg/controller/podautoscaler/horizontal.go
index a09d40e8fd3..24c596c585c 100644
--- a/pkg/controller/podautoscaler/horizontal.go
+++ b/pkg/controller/podautoscaler/horizontal.go
@@ -88,6 +88,7 @@ func NewHorizontalController(
) *HorizontalController {
broadcaster := record.NewBroadcaster()
+ broadcaster.StartLogging(glog.Infof)
// TODO: remove the wrapper when every clients have moved to use the clientset.
broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: evtNamespacer.Events("")})
recorder := broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "horizontal-pod-autoscaler"})
diff --git a/pkg/controller/route/route_controller.go b/pkg/controller/route/route_controller.go
index bb6995d775e..352527a3d97 100644
--- a/pkg/controller/route/route_controller.go
+++ b/pkg/controller/route/route_controller.go
@@ -66,8 +66,8 @@ type RouteController struct {
}
func New(routes cloudprovider.Routes, kubeClient clientset.Interface, nodeInformer coreinformers.NodeInformer, clusterName string, clusterCIDR *net.IPNet) *RouteController {
- if kubeClient != nil && kubeClient.Core().RESTClient().GetRateLimiter() != nil {
- metrics.RegisterMetricAndTrackRateLimiterUsage("route_controller", kubeClient.Core().RESTClient().GetRateLimiter())
+ if kubeClient != nil && kubeClient.CoreV1().RESTClient().GetRateLimiter() != nil {
+ metrics.RegisterMetricAndTrackRateLimiterUsage("route_controller", kubeClient.CoreV1().RESTClient().GetRateLimiter())
}
if clusterCIDR == nil {
@@ -75,7 +75,8 @@ func New(routes cloudprovider.Routes, kubeClient clientset.Interface, nodeInform
}
eventBroadcaster := record.NewBroadcaster()
- recorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "route-controller"})
+ eventBroadcaster.StartLogging(glog.Infof)
+ recorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "route_controller"})
rc := &RouteController{
routes: routes,
@@ -114,7 +115,7 @@ func (rc *RouteController) Run(stopCh <-chan struct{}, syncPeriod time.Duration)
if err := rc.reconcileNodeRoutes(); err != nil {
glog.Errorf("Couldn't reconcile node routes: %v", err)
}
- }, syncPeriod, wait.NeverStop)
+ }, syncPeriod, stopCh)
<-stopCh
}
@@ -254,7 +255,7 @@ func (rc *RouteController) updateNetworkingCondition(nodeName types.NodeName, ro
glog.Errorf("Error updating node %s: %v", nodeName, err)
return err
}
- glog.Errorf("Error updating node %s, retrying: %v", nodeName, err)
+ glog.V(4).Infof("Error updating node %s, retrying: %v", nodeName, err)
}
glog.Errorf("Error updating node %s: %v", nodeName, err)
return err
diff --git a/pkg/controller/service/service_controller.go b/pkg/controller/service/service_controller.go
index 0f7c1f686b8..253d1cd7a3b 100644
--- a/pkg/controller/service/service_controller.go
+++ b/pkg/controller/service/service_controller.go
@@ -112,6 +112,7 @@ func New(
clusterName string,
) (*ServiceController, error) {
broadcaster := record.NewBroadcaster()
+ broadcaster.StartLogging(glog.Infof)
broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.Core().RESTClient()).Events("")})
recorder := broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "service-controller"})
broadcaster.StartLogging(glog.Infof)
diff --git a/pkg/controller/volume/attachdetach/cache/actual_state_of_world.go b/pkg/controller/volume/attachdetach/cache/actual_state_of_world.go
index fbb529154be..9bb6320c662 100644
--- a/pkg/controller/volume/attachdetach/cache/actual_state_of_world.go
+++ b/pkg/controller/volume/attachdetach/cache/actual_state_of_world.go
@@ -475,7 +475,6 @@ func (asw *actualStateOfWorld) updateNodeStatusUpdateNeeded(nodeName types.NodeN
// should not happen
errMsg := fmt.Sprintf("Failed to set statusUpdateNeeded to needed %t because nodeName=%q does not exist",
needed, nodeName)
- glog.Errorf(errMsg)
return fmt.Errorf(errMsg)
}
diff --git a/pkg/controller/volume/persistentvolume/pv_controller_base.go b/pkg/controller/volume/persistentvolume/pv_controller_base.go
index 2fb5852f7f4..73af960ace3 100644
--- a/pkg/controller/volume/persistentvolume/pv_controller_base.go
+++ b/pkg/controller/volume/persistentvolume/pv_controller_base.go
@@ -70,6 +70,7 @@ func NewController(p ControllerParameters) (*PersistentVolumeController, error)
eventRecorder := p.EventRecorder
if eventRecorder == nil {
broadcaster := record.NewBroadcaster()
+ broadcaster.StartLogging(glog.Infof)
broadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(p.KubeClient.Core().RESTClient()).Events("")})
eventRecorder = broadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "persistentvolume-controller"})
}
diff --git a/pkg/kubeapiserver/admission/initializer.go b/pkg/kubeapiserver/admission/initializer.go
index d90e9bc63b3..27b10036fd6 100644
--- a/pkg/kubeapiserver/admission/initializer.go
+++ b/pkg/kubeapiserver/admission/initializer.go
@@ -17,7 +17,6 @@ limitations under the License.
package admission
import (
- "net/http"
"net/url"
"k8s.io/apimachinery/pkg/api/meta"
@@ -71,12 +70,6 @@ type ServiceResolver interface {
ResolveEndpoint(namespace, name string) (*url.URL, error)
}
-// WantsProxyTransport defines a fuction that accepts a proxy transport for admission
-// plugins that need to make calls to pods.
-type WantsProxyTransport interface {
- SetProxyTransport(proxyTransport *http.Transport)
-}
-
type PluginInitializer struct {
internalClient internalclientset.Interface
externalClient clientset.Interface
@@ -86,9 +79,6 @@ type PluginInitializer struct {
restMapper meta.RESTMapper
quotaRegistry quota.Registry
serviceResolver ServiceResolver
-
- // for proving we are apiserver in call-outs
- proxyTransport *http.Transport
}
var _ admission.PluginInitializer = &PluginInitializer{}
@@ -118,12 +108,6 @@ func (i *PluginInitializer) SetServiceResolver(s ServiceResolver) *PluginInitial
return i
}
-// SetProxyTransport sets the proxyTransport which is needed by some plugins.
-func (i *PluginInitializer) SetProxyTransport(proxyTransport *http.Transport) *PluginInitializer {
- i.proxyTransport = proxyTransport
- return i
-}
-
// Initialize checks the initialization interfaces implemented by each plugin
// and provide the appropriate initialization data
func (i *PluginInitializer) Initialize(plugin admission.Interface) {
@@ -150,8 +134,4 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) {
if wants, ok := plugin.(WantsServiceResolver); ok {
wants.SetServiceResolver(i.serviceResolver)
}
-
- if wants, ok := plugin.(WantsProxyTransport); ok {
- wants.SetProxyTransport(i.proxyTransport)
- }
}
diff --git a/pkg/kubectl/cmd/create.go b/pkg/kubectl/cmd/create.go
index 5ed32cb813f..61433deb608 100644
--- a/pkg/kubectl/cmd/create.go
+++ b/pkg/kubectl/cmd/create.go
@@ -23,7 +23,9 @@ import (
"github.com/spf13/cobra"
+ "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"
+
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
@@ -242,7 +244,7 @@ type CreateSubcommandOptions struct {
// RunCreateSubcommand executes a create subcommand using the specified options
func RunCreateSubcommand(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *CreateSubcommandOptions) error {
- namespace, _, err := f.DefaultNamespace()
+ namespace, nsOverriden, err := f.DefaultNamespace()
if err != nil {
return err
}
@@ -283,6 +285,10 @@ func RunCreateSubcommand(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, o
if err != nil {
return err
}
+ } else {
+ if meta, err := meta.Accessor(obj); err == nil && nsOverriden {
+ meta.SetNamespace(namespace)
+ }
}
if useShortOutput := options.OutputFormat == "name"; useShortOutput || len(options.OutputFormat) == 0 {
diff --git a/pkg/kubectl/cmd/create_secret.go b/pkg/kubectl/cmd/create_secret.go
index 85909ceb05b..f49048bf9a3 100644
--- a/pkg/kubectl/cmd/create_secret.go
+++ b/pkg/kubectl/cmd/create_secret.go
@@ -169,6 +169,7 @@ func NewCmdCreateSecretDockerRegistry(f cmdutil.Factory, cmdOut io.Writer) *cobr
cmd.Flags().String("docker-email", "", i18n.T("Email for Docker registry"))
cmd.Flags().String("docker-server", "https://index.docker.io/v1/", i18n.T("Server location for Docker registry"))
cmd.Flags().Bool("append-hash", false, "Append a hash of the secret to its name.")
+
cmdutil.AddInclude3rdPartyFlags(cmd)
return cmd
}
diff --git a/pkg/kubectl/cmd/create_service.go b/pkg/kubectl/cmd/create_service.go
index 54587422933..cdc28455775 100644
--- a/pkg/kubectl/cmd/create_service.go
+++ b/pkg/kubectl/cmd/create_service.go
@@ -47,13 +47,13 @@ func NewCmdCreateService(f cmdutil.Factory, cmdOut, errOut io.Writer) *cobra.Com
var (
serviceClusterIPLong = templates.LongDesc(i18n.T(`
- Create a clusterIP service with the specified name.`))
+ Create a ClusterIP service with the specified name.`))
serviceClusterIPExample = templates.Examples(i18n.T(`
- # Create a new clusterIP service named my-cs
+ # Create a new ClusterIP service named my-cs
kubectl create service clusterip my-cs --tcp=5678:8080
- # Create a new clusterIP service named my-cs (in headless mode)
+ # Create a new ClusterIP service named my-cs (in headless mode)
kubectl create service clusterip my-cs --clusterip="None"`))
)
@@ -61,11 +61,11 @@ func addPortFlags(cmd *cobra.Command) {
cmd.Flags().StringSlice("tcp", []string{}, "Port pairs can be specified as ':'.")
}
-// NewCmdCreateServiceClusterIP is a command to create a clusterIP service
+// NewCmdCreateServiceClusterIP is a command to create a ClusterIP service
func NewCmdCreateServiceClusterIP(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "clusterip NAME [--tcp=:] [--dry-run]",
- Short: i18n.T("Create a clusterIP service."),
+ Short: i18n.T("Create a ClusterIP service."),
Long: serviceClusterIPLong,
Example: serviceClusterIPExample,
Run: func(cmd *cobra.Command, args []string) {
@@ -86,7 +86,7 @@ func errUnsupportedGenerator(cmd *cobra.Command, generatorName string) error {
return cmdutil.UsageErrorf(cmd, "Generator %s not supported. ", generatorName)
}
-// CreateServiceClusterIP implements the behavior to run the create service clusterIP command
+// CreateServiceClusterIP is the implementation of the create service clusterip command
func CreateServiceClusterIP(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args)
if err != nil {
@@ -114,10 +114,10 @@ func CreateServiceClusterIP(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Comm
var (
serviceNodePortLong = templates.LongDesc(i18n.T(`
- Create a nodeport service with the specified name.`))
+ Create a NodePort service with the specified name.`))
serviceNodePortExample = templates.Examples(i18n.T(`
- # Create a new nodeport service named my-ns
+ # Create a new NodePort service named my-ns
kubectl create service nodeport my-ns --tcp=5678:8080`))
)
@@ -198,7 +198,7 @@ func NewCmdCreateServiceLoadBalancer(f cmdutil.Factory, cmdOut io.Writer) *cobra
return cmd
}
-// CreateServiceLoadBalancer is the implementation of the service loadbalancer command
+// CreateServiceLoadBalancer is the implementation of the create service loadbalancer command
func CreateServiceLoadBalancer(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args)
if err != nil {
@@ -237,7 +237,7 @@ var (
kubectl create service externalname my-ns --external-name bar.com`))
)
-// NewCmdCreateServiceExternalName is a macro command for creating a ExternalName service
+// NewCmdCreateServiceExternalName is a macro command for creating an ExternalName service
func NewCmdCreateServiceExternalName(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "externalname NAME --external-name external.name [--dry-run]",
@@ -259,7 +259,7 @@ func NewCmdCreateServiceExternalName(f cmdutil.Factory, cmdOut io.Writer) *cobra
return cmd
}
-// CreateExternalNameService is the implementation of the service externalname command
+// CreateExternalNameService is the implementation of the create service externalname command
func CreateExternalNameService(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args)
if err != nil {
diff --git a/pkg/kubectl/cmd/expose.go b/pkg/kubectl/cmd/expose.go
index 6ae43873763..7f0654c421c 100644
--- a/pkg/kubectl/cmd/expose.go
+++ b/pkg/kubectl/cmd/expose.go
@@ -98,7 +98,7 @@ func NewCmdExposeService(f cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().String("generator", "service/v2", i18n.T("The name of the API generator to use. There are 2 generators: 'service/v1' and 'service/v2'. The only difference between them is that service port in v1 is named 'default', while it is left unnamed in v2. Default is 'service/v2'."))
cmd.Flags().String("protocol", "", i18n.T("The network protocol for the service to be created. Default is 'TCP'."))
cmd.Flags().String("port", "", i18n.T("The port that the service should serve on. Copied from the resource being exposed, if unspecified"))
- cmd.Flags().String("type", "", i18n.T("Type for this service: ClusterIP, NodePort, or LoadBalancer. Default is 'ClusterIP'."))
+ cmd.Flags().String("type", "", i18n.T("Type for this service: ClusterIP, NodePort, LoadBalancer, or ExternalName. Default is 'ClusterIP'."))
cmd.Flags().String("load-balancer-ip", "", i18n.T("IP to assign to the Load Balancer. If empty, an ephemeral IP will be created and used (cloud-provider specific)."))
cmd.Flags().String("selector", "", i18n.T("A label selector to use for this service. Only equality-based selector requirements are supported. If empty (the default) infer the selector from the replication controller or replica set.)"))
cmd.Flags().StringP("labels", "l", "", "Labels to apply to the service created by this call.")
diff --git a/pkg/kubectl/cmd/util/openapi/validation/validation_test.go b/pkg/kubectl/cmd/util/openapi/validation/validation_test.go
index c1f86f256a3..bd70accb12a 100644
--- a/pkg/kubectl/cmd/util/openapi/validation/validation_test.go
+++ b/pkg/kubectl/cmd/util/openapi/validation/validation_test.go
@@ -335,4 +335,63 @@ items:
Expect(err).To(BeNil())
})
+
+ It("fails because apiVersion is not provided", func() {
+ err := validator.ValidateBytes([]byte(`
+kind: Pod
+metadata:
+ name: name
+spec:
+ containers:
+ - name: name
+ image: image
+`))
+ Expect(err.Error()).To(Equal("apiVersion not set"))
+ })
+
+ It("fails because apiVersion type is not string and kind is not provided", func() {
+ err := validator.ValidateBytes([]byte(`
+apiVersion: 1
+metadata:
+ name: name
+spec:
+ containers:
+ - name: name
+ image: image
+`))
+ Expect(err.Error()).To(Equal("[apiVersion isn't string type, kind not set]"))
+ })
+
+ It("fails because List first item is missing kind and second item is missing apiVersion", func() {
+ err := validator.ValidateBytes([]byte(`
+apiVersion: v1
+kind: List
+items:
+- apiVersion: v1
+ metadata:
+ name: name
+ spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ name: name
+ spec:
+ containers:
+ - name: name
+ image: image
+- kind: Service
+ metadata:
+ name: name
+ spec:
+ type: NodePort
+ ports:
+ - port: 123
+ targetPort: 1234
+ name: name
+ selector:
+ name: name
+`))
+ Expect(err.Error()).To(Equal("[kind not set, apiVersion not set]"))
+ })
})
diff --git a/pkg/kubectl/secret_for_docker_registry.go b/pkg/kubectl/secret_for_docker_registry.go
index d39ebb5b32b..d7a4154ed38 100644
--- a/pkg/kubectl/secret_for_docker_registry.go
+++ b/pkg/kubectl/secret_for_docker_registry.go
@@ -141,7 +141,9 @@ func handleDockercfgContent(username, password, email, server string) ([]byte, e
Email: email,
}
- dockerCfg := map[string]credentialprovider.DockerConfigEntry{server: dockercfgAuth}
+ dockerCfg := credentialprovider.DockerConfigJson{
+ Auths: map[string]credentialprovider.DockerConfigEntry{server: dockercfgAuth},
+ }
return json.Marshal(dockerCfg)
}
diff --git a/pkg/kubectl/secret_for_docker_registry_test.go b/pkg/kubectl/secret_for_docker_registry_test.go
index e1621cbefa5..e9cb0abf159 100644
--- a/pkg/kubectl/secret_for_docker_registry_test.go
+++ b/pkg/kubectl/secret_for_docker_registry_test.go
@@ -70,7 +70,7 @@ func TestSecretForDockerRegistryGenerate(t *testing.T) {
},
expected: &api.Secret{
ObjectMeta: metav1.ObjectMeta{
- Name: "foo-gb4kftc655",
+ Name: "foo-94759gc65b",
},
Data: map[string][]byte{
api.DockerConfigKey: secretData,
diff --git a/pkg/kubectl/service.go b/pkg/kubectl/service.go
index 072bddbeb03..578cfeaeb36 100644
--- a/pkg/kubectl/service.go
+++ b/pkg/kubectl/service.go
@@ -135,7 +135,7 @@ func generate(genericParams map[string]interface{}) (runtime.Object, error) {
if portString, found = params["ports"]; !found {
portString, found = params["port"]
if !found && !isHeadlessService {
- return nil, fmt.Errorf("'port' is a required parameter.")
+ return nil, fmt.Errorf("'ports' or 'port' is a required parameter.")
}
}
diff --git a/pkg/kubelet/apis/BUILD b/pkg/kubelet/apis/BUILD
index 00352f578d7..490bbd581f9 100644
--- a/pkg/kubelet/apis/BUILD
+++ b/pkg/kubelet/apis/BUILD
@@ -26,7 +26,7 @@ filegroup(
srcs = [
":package-srcs",
"//pkg/kubelet/apis/cri:all-srcs",
- "//pkg/kubelet/apis/deviceplugin/v1alpha1:all-srcs",
+ "//pkg/kubelet/apis/deviceplugin/v1alpha:all-srcs",
"//pkg/kubelet/apis/kubeletconfig:all-srcs",
"//pkg/kubelet/apis/stats/v1alpha1:all-srcs",
],
diff --git a/pkg/kubelet/apis/deviceplugin/v1alpha1/BUILD b/pkg/kubelet/apis/deviceplugin/v1alpha/BUILD
similarity index 98%
rename from pkg/kubelet/apis/deviceplugin/v1alpha1/BUILD
rename to pkg/kubelet/apis/deviceplugin/v1alpha/BUILD
index f9677feacf2..b60d55569c9 100644
--- a/pkg/kubelet/apis/deviceplugin/v1alpha1/BUILD
+++ b/pkg/kubelet/apis/deviceplugin/v1alpha/BUILD
@@ -11,7 +11,7 @@ go_library(
"api.pb.go",
"constants.go",
],
- importpath = "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1",
+ importpath = "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha",
deps = [
"//vendor/github.com/gogo/protobuf/gogoproto:go_default_library",
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
diff --git a/pkg/kubelet/apis/deviceplugin/v1alpha1/api.pb.go b/pkg/kubelet/apis/deviceplugin/v1alpha/api.pb.go
similarity index 85%
rename from pkg/kubelet/apis/deviceplugin/v1alpha1/api.pb.go
rename to pkg/kubelet/apis/deviceplugin/v1alpha/api.pb.go
index 2d73929bdf1..6a939acde52 100644
--- a/pkg/kubelet/apis/deviceplugin/v1alpha1/api.pb.go
+++ b/pkg/kubelet/apis/deviceplugin/v1alpha/api.pb.go
@@ -31,7 +31,6 @@ limitations under the License.
Device
AllocateRequest
AllocateResponse
- DeviceRuntimeSpec
Mount
DeviceSpec
*/
@@ -177,64 +176,42 @@ func (m *AllocateRequest) GetDevicesIDs() []string {
return nil
}
+// AllocateResponse includes the artifacts that needs to be injected into
+// a container for accessing 'deviceIDs' that were mentioned as part of
+// 'AllocateRequest'.
// Failure Handling:
// if Kubelet sends an allocation request for dev1 and dev2.
// Allocation on dev1 succeeds but allocation on dev2 fails.
// The Device plugin should send a ListAndWatch update and fail the
// Allocation request
type AllocateResponse struct {
- Spec []*DeviceRuntimeSpec `protobuf:"bytes,1,rep,name=spec" json:"spec,omitempty"`
+ // List of environment variable to be set in the container to access one of more devices.
+ Envs map[string]string `protobuf:"bytes,1,rep,name=envs" json:"envs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ // Mounts for the container.
+ Mounts []*Mount `protobuf:"bytes,2,rep,name=mounts" json:"mounts,omitempty"`
+ // Devices for the container.
+ Devices []*DeviceSpec `protobuf:"bytes,3,rep,name=devices" json:"devices,omitempty"`
}
func (m *AllocateResponse) Reset() { *m = AllocateResponse{} }
func (*AllocateResponse) ProtoMessage() {}
func (*AllocateResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{5} }
-func (m *AllocateResponse) GetSpec() []*DeviceRuntimeSpec {
- if m != nil {
- return m.Spec
- }
- return nil
-}
-
-// The list to be added to the CRI spec
-type DeviceRuntimeSpec struct {
- // ID of the Device
- ID string `protobuf:"bytes,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
- // List of environment variable to set in the container.
- Envs map[string]string `protobuf:"bytes,2,rep,name=envs" json:"envs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
- // Mounts for the container.
- Mounts []*Mount `protobuf:"bytes,3,rep,name=mounts" json:"mounts,omitempty"`
- // Devices for the container
- Devices []*DeviceSpec `protobuf:"bytes,4,rep,name=devices" json:"devices,omitempty"`
-}
-
-func (m *DeviceRuntimeSpec) Reset() { *m = DeviceRuntimeSpec{} }
-func (*DeviceRuntimeSpec) ProtoMessage() {}
-func (*DeviceRuntimeSpec) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{6} }
-
-func (m *DeviceRuntimeSpec) GetID() string {
- if m != nil {
- return m.ID
- }
- return ""
-}
-
-func (m *DeviceRuntimeSpec) GetEnvs() map[string]string {
+func (m *AllocateResponse) GetEnvs() map[string]string {
if m != nil {
return m.Envs
}
return nil
}
-func (m *DeviceRuntimeSpec) GetMounts() []*Mount {
+func (m *AllocateResponse) GetMounts() []*Mount {
if m != nil {
return m.Mounts
}
return nil
}
-func (m *DeviceRuntimeSpec) GetDevices() []*DeviceSpec {
+func (m *AllocateResponse) GetDevices() []*DeviceSpec {
if m != nil {
return m.Devices
}
@@ -254,7 +231,7 @@ type Mount struct {
func (m *Mount) Reset() { *m = Mount{} }
func (*Mount) ProtoMessage() {}
-func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{7} }
+func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{6} }
func (m *Mount) GetContainerPath() string {
if m != nil {
@@ -292,7 +269,7 @@ type DeviceSpec struct {
func (m *DeviceSpec) Reset() { *m = DeviceSpec{} }
func (*DeviceSpec) ProtoMessage() {}
-func (*DeviceSpec) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{8} }
+func (*DeviceSpec) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{7} }
func (m *DeviceSpec) GetContainerPath() string {
if m != nil {
@@ -322,7 +299,6 @@ func init() {
proto.RegisterType((*Device)(nil), "deviceplugin.Device")
proto.RegisterType((*AllocateRequest)(nil), "deviceplugin.AllocateRequest")
proto.RegisterType((*AllocateResponse)(nil), "deviceplugin.AllocateResponse")
- proto.RegisterType((*DeviceRuntimeSpec)(nil), "deviceplugin.DeviceRuntimeSpec")
proto.RegisterType((*Mount)(nil), "deviceplugin.Mount")
proto.RegisterType((*DeviceSpec)(nil), "deviceplugin.DeviceSpec")
}
@@ -698,45 +674,9 @@ func (m *AllocateResponse) MarshalTo(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
- if len(m.Spec) > 0 {
- for _, msg := range m.Spec {
- dAtA[i] = 0xa
- i++
- i = encodeVarintApi(dAtA, i, uint64(msg.Size()))
- n, err := msg.MarshalTo(dAtA[i:])
- if err != nil {
- return 0, err
- }
- i += n
- }
- }
- return i, nil
-}
-
-func (m *DeviceRuntimeSpec) 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 *DeviceRuntimeSpec) MarshalTo(dAtA []byte) (int, error) {
- var i int
- _ = i
- var l int
- _ = l
- if len(m.ID) > 0 {
- dAtA[i] = 0xa
- i++
- i = encodeVarintApi(dAtA, i, uint64(len(m.ID)))
- i += copy(dAtA[i:], m.ID)
- }
if len(m.Envs) > 0 {
for k := range m.Envs {
- dAtA[i] = 0x12
+ dAtA[i] = 0xa
i++
v := m.Envs[k]
mapSize := 1 + len(k) + sovApi(uint64(len(k))) + 1 + len(v) + sovApi(uint64(len(v)))
@@ -753,7 +693,7 @@ func (m *DeviceRuntimeSpec) MarshalTo(dAtA []byte) (int, error) {
}
if len(m.Mounts) > 0 {
for _, msg := range m.Mounts {
- dAtA[i] = 0x1a
+ dAtA[i] = 0x12
i++
i = encodeVarintApi(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
@@ -765,7 +705,7 @@ func (m *DeviceRuntimeSpec) MarshalTo(dAtA []byte) (int, error) {
}
if len(m.Devices) > 0 {
for _, msg := range m.Devices {
- dAtA[i] = 0x22
+ dAtA[i] = 0x1a
i++
i = encodeVarintApi(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
@@ -946,22 +886,6 @@ func (m *AllocateRequest) Size() (n int) {
func (m *AllocateResponse) Size() (n int) {
var l int
_ = l
- if len(m.Spec) > 0 {
- for _, e := range m.Spec {
- l = e.Size()
- n += 1 + l + sovApi(uint64(l))
- }
- }
- return n
-}
-
-func (m *DeviceRuntimeSpec) Size() (n int) {
- var l int
- _ = l
- l = len(m.ID)
- if l > 0 {
- n += 1 + l + sovApi(uint64(l))
- }
if len(m.Envs) > 0 {
for k, v := range m.Envs {
_ = k
@@ -1086,16 +1010,6 @@ func (this *AllocateRequest) String() string {
return s
}
func (this *AllocateResponse) String() string {
- if this == nil {
- return "nil"
- }
- s := strings.Join([]string{`&AllocateResponse{`,
- `Spec:` + strings.Replace(fmt.Sprintf("%v", this.Spec), "DeviceRuntimeSpec", "DeviceRuntimeSpec", 1) + `,`,
- `}`,
- }, "")
- return s
-}
-func (this *DeviceRuntimeSpec) String() string {
if this == nil {
return "nil"
}
@@ -1109,8 +1023,7 @@ func (this *DeviceRuntimeSpec) String() string {
mapStringForEnvs += fmt.Sprintf("%v: %v,", k, this.Envs[k])
}
mapStringForEnvs += "}"
- s := strings.Join([]string{`&DeviceRuntimeSpec{`,
- `ID:` + fmt.Sprintf("%v", this.ID) + `,`,
+ s := strings.Join([]string{`&AllocateResponse{`,
`Envs:` + mapStringForEnvs + `,`,
`Mounts:` + strings.Replace(fmt.Sprintf("%v", this.Mounts), "Mount", "Mount", 1) + `,`,
`Devices:` + strings.Replace(fmt.Sprintf("%v", this.Devices), "DeviceSpec", "DeviceSpec", 1) + `,`,
@@ -1635,116 +1548,6 @@ func (m *AllocateResponse) Unmarshal(dAtA []byte) error {
}
switch fieldNum {
case 1:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
- }
- var msglen int
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowApi
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- msglen |= (int(b) & 0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- if msglen < 0 {
- return ErrInvalidLengthApi
- }
- postIndex := iNdEx + msglen
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.Spec = append(m.Spec, &DeviceRuntimeSpec{})
- if err := m.Spec[len(m.Spec)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
- return err
- }
- iNdEx = postIndex
- default:
- iNdEx = preIndex
- skippy, err := skipApi(dAtA[iNdEx:])
- if err != nil {
- return err
- }
- if skippy < 0 {
- return ErrInvalidLengthApi
- }
- if (iNdEx + skippy) > l {
- return io.ErrUnexpectedEOF
- }
- iNdEx += skippy
- }
- }
-
- if iNdEx > l {
- return io.ErrUnexpectedEOF
- }
- return nil
-}
-func (m *DeviceRuntimeSpec) 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 ErrIntOverflowApi
- }
- 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: DeviceRuntimeSpec: wiretype end group for non-group")
- }
- if fieldNum <= 0 {
- return fmt.Errorf("proto: DeviceRuntimeSpec: illegal tag %d (wire type %d)", fieldNum, wire)
- }
- switch fieldNum {
- case 1:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
- }
- var stringLen uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowApi
- }
- 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 ErrInvalidLengthApi
- }
- postIndex := iNdEx + intStringLen
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.ID = string(dAtA[iNdEx:postIndex])
- iNdEx = postIndex
- case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Envs", wireType)
}
@@ -1860,7 +1663,7 @@ func (m *DeviceRuntimeSpec) Unmarshal(dAtA []byte) error {
m.Envs[mapkey] = mapvalue
}
iNdEx = postIndex
- case 3:
+ case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Mounts", wireType)
}
@@ -1891,7 +1694,7 @@ func (m *DeviceRuntimeSpec) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
- case 4:
+ case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Devices", wireType)
}
@@ -2316,42 +2119,41 @@ var (
func init() { proto.RegisterFile("api.proto", fileDescriptorApi) }
var fileDescriptorApi = []byte{
- // 590 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcd, 0x6e, 0xd3, 0x40,
- 0x10, 0xce, 0x26, 0x6d, 0x9a, 0x4c, 0xd3, 0x1f, 0x96, 0x0a, 0x59, 0x01, 0x4c, 0x65, 0x84, 0x54,
- 0x84, 0x70, 0x4b, 0x7a, 0x00, 0x21, 0x21, 0x51, 0x94, 0x82, 0xaa, 0xf2, 0x53, 0x99, 0x03, 0xc7,
- 0x6a, 0xeb, 0x0c, 0xf1, 0x0a, 0x7b, 0xd7, 0x78, 0xd7, 0x91, 0x72, 0xe3, 0x11, 0x78, 0x0c, 0x1e,
- 0xa5, 0x47, 0x8e, 0x1c, 0x69, 0x78, 0x0d, 0x0e, 0xc8, 0xeb, 0x75, 0x9b, 0xa6, 0x41, 0x5c, 0xb8,
- 0x79, 0xbe, 0xf9, 0x66, 0xe6, 0x9b, 0xcd, 0x7c, 0x81, 0x36, 0x4b, 0xb9, 0x9f, 0x66, 0x52, 0x4b,
- 0xda, 0x19, 0xe0, 0x88, 0x87, 0x98, 0xc6, 0xf9, 0x90, 0x8b, 0xee, 0xc3, 0x21, 0xd7, 0x51, 0x7e,
- 0xe2, 0x87, 0x32, 0xd9, 0x1e, 0xca, 0xa1, 0xdc, 0x36, 0xa4, 0x93, 0xfc, 0xa3, 0x89, 0x4c, 0x60,
- 0xbe, 0xca, 0x62, 0x2f, 0x86, 0xb5, 0x00, 0x87, 0x5c, 0x69, 0xcc, 0x02, 0xfc, 0x9c, 0xa3, 0xd2,
- 0xd4, 0x81, 0xa5, 0x11, 0x66, 0x8a, 0x4b, 0xe1, 0x90, 0x4d, 0xb2, 0xd5, 0x0e, 0xaa, 0x90, 0x76,
- 0xa1, 0x85, 0x62, 0x90, 0x4a, 0x2e, 0xb4, 0x53, 0x37, 0xa9, 0xf3, 0x98, 0xde, 0x85, 0x95, 0x0c,
- 0x95, 0xcc, 0xb3, 0x10, 0x8f, 0x05, 0x4b, 0xd0, 0x69, 0x18, 0x42, 0xa7, 0x02, 0xdf, 0xb2, 0x04,
- 0xbd, 0x25, 0x58, 0xdc, 0x4f, 0x52, 0x3d, 0xf6, 0x5e, 0xc2, 0xc6, 0x6b, 0xae, 0xf4, 0x9e, 0x18,
- 0x7c, 0x60, 0x3a, 0x8c, 0x02, 0x54, 0xa9, 0x14, 0x0a, 0xa9, 0x0f, 0x4b, 0xe5, 0x36, 0xca, 0x21,
- 0x9b, 0x8d, 0xad, 0xe5, 0xde, 0x86, 0x3f, 0xbd, 0x9d, 0xdf, 0x37, 0x41, 0x50, 0x91, 0xbc, 0x1d,
- 0x68, 0x96, 0x10, 0x5d, 0x85, 0xfa, 0x41, 0xdf, 0x0a, 0xae, 0xf3, 0x3e, 0xbd, 0x01, 0xcd, 0x08,
- 0x59, 0xac, 0x23, 0xab, 0xd4, 0x46, 0xde, 0x23, 0x58, 0xdb, 0x8b, 0x63, 0x19, 0x32, 0x8d, 0xd5,
- 0xc2, 0x2e, 0x80, 0xed, 0x77, 0xd0, 0x2f, 0xe7, 0xb6, 0x83, 0x29, 0xc4, 0x7b, 0x05, 0xeb, 0x17,
- 0x25, 0x56, 0xe8, 0x2e, 0x2c, 0xa8, 0x14, 0x43, 0xab, 0xf2, 0xce, 0x5c, 0x95, 0xb9, 0xd0, 0x3c,
- 0xc1, 0xf7, 0x29, 0x86, 0x81, 0x21, 0x7b, 0xbf, 0x09, 0x5c, 0xbb, 0x92, 0xbb, 0xa2, 0xfc, 0x19,
- 0x2c, 0xa0, 0x18, 0x29, 0xa7, 0x6e, 0x5a, 0xdf, 0xff, 0x47, 0x6b, 0x7f, 0x5f, 0x8c, 0xd4, 0xbe,
- 0xd0, 0xd9, 0x38, 0x30, 0x65, 0xf4, 0x01, 0x34, 0x13, 0x99, 0x0b, 0xad, 0x9c, 0x86, 0x69, 0x70,
- 0xfd, 0x72, 0x83, 0x37, 0x45, 0x2e, 0xb0, 0x14, 0xda, 0xbb, 0x78, 0xef, 0x05, 0xc3, 0x76, 0xe6,
- 0x8d, 0x33, 0x2b, 0x54, 0xc4, 0xee, 0x63, 0x68, 0x9f, 0xcf, 0xa4, 0xeb, 0xd0, 0xf8, 0x84, 0x63,
- 0xab, 0xbe, 0xf8, 0xa4, 0x1b, 0xb0, 0x38, 0x62, 0x71, 0x8e, 0xf6, 0xdd, 0xcb, 0xe0, 0x69, 0xfd,
- 0x09, 0xf1, 0x22, 0x58, 0x34, 0xd3, 0xe9, 0x3d, 0x58, 0x0d, 0xa5, 0xd0, 0x8c, 0x0b, 0xcc, 0x8e,
- 0x53, 0xa6, 0x23, 0x5b, 0xbf, 0x72, 0x8e, 0x1e, 0x31, 0x1d, 0xd1, 0x9b, 0xd0, 0x8e, 0xa4, 0xd2,
- 0x25, 0xc3, 0xde, 0x5b, 0x01, 0x54, 0xc9, 0x0c, 0xd9, 0xe0, 0x58, 0x8a, 0x78, 0x6c, 0x6e, 0xad,
- 0x15, 0xb4, 0x0a, 0xe0, 0x9d, 0x88, 0xc7, 0x5e, 0x06, 0x70, 0xa1, 0xfc, 0xbf, 0x8c, 0xdb, 0x84,
- 0xe5, 0x14, 0xb3, 0x84, 0xab, 0xc2, 0x08, 0xca, 0x1e, 0xf7, 0x34, 0xd4, 0x3b, 0x82, 0x4e, 0xe9,
- 0xa4, 0x8c, 0xe9, 0xc2, 0x2c, 0xcf, 0xa1, 0x55, 0x39, 0x8b, 0xde, 0xbe, 0xfc, 0xaa, 0x33, 0x8e,
- 0xeb, 0xce, 0xfc, 0x44, 0xa5, 0x45, 0x6a, 0xbd, 0x6f, 0x04, 0x3a, 0xe5, 0x1a, 0x47, 0x26, 0x41,
- 0x0f, 0xa1, 0x33, 0xed, 0x1a, 0x3a, 0xaf, 0xae, 0xeb, 0x5d, 0x06, 0xe7, 0xd9, 0xcc, 0xab, 0xed,
- 0x10, 0x7a, 0x08, 0xad, 0xea, 0xaa, 0x67, 0xf5, 0xcd, 0x18, 0xa4, 0xeb, 0xfe, 0x2d, 0x5d, 0xb5,
- 0x7b, 0x71, 0xeb, 0xf4, 0xcc, 0x25, 0x3f, 0xce, 0xdc, 0xda, 0x97, 0x89, 0x4b, 0x4e, 0x27, 0x2e,
- 0xf9, 0x3e, 0x71, 0xc9, 0xcf, 0x89, 0x4b, 0xbe, 0xfe, 0x72, 0x6b, 0x27, 0x4d, 0xf3, 0x5f, 0xb3,
- 0xfb, 0x27, 0x00, 0x00, 0xff, 0xff, 0x99, 0xda, 0x39, 0xd8, 0xb5, 0x04, 0x00, 0x00,
+ // 562 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcb, 0x8e, 0xd3, 0x4a,
+ 0x10, 0x4d, 0x27, 0x77, 0xf2, 0xa8, 0xc9, 0x3c, 0xd4, 0x37, 0x42, 0x96, 0x01, 0x2b, 0x32, 0x42,
+ 0x8a, 0x84, 0xf0, 0x0c, 0x61, 0x01, 0x42, 0x2c, 0x18, 0x94, 0x20, 0x8d, 0x86, 0x47, 0x64, 0x16,
+ 0x2c, 0xa3, 0x8e, 0x53, 0xc4, 0x16, 0x76, 0xb7, 0x71, 0xb7, 0x23, 0x65, 0xc7, 0x27, 0xf0, 0x19,
+ 0x7c, 0xca, 0x2c, 0x59, 0xb2, 0x64, 0xc2, 0x8e, 0xaf, 0x40, 0x6e, 0xdb, 0x79, 0x29, 0x62, 0xc5,
+ 0xce, 0x75, 0xea, 0x9c, 0xd4, 0xa9, 0xca, 0xb1, 0xa1, 0xc5, 0xe2, 0xc0, 0x89, 0x13, 0xa1, 0x04,
+ 0x6d, 0x4f, 0x71, 0x1e, 0x78, 0x18, 0x87, 0xe9, 0x2c, 0xe0, 0xe6, 0xc3, 0x59, 0xa0, 0xfc, 0x74,
+ 0xe2, 0x78, 0x22, 0x3a, 0x9b, 0x89, 0x99, 0x38, 0xd3, 0xa4, 0x49, 0xfa, 0x51, 0x57, 0xba, 0xd0,
+ 0x4f, 0xb9, 0xd8, 0x0e, 0xe1, 0xc4, 0xc5, 0x59, 0x20, 0x15, 0x26, 0x2e, 0x7e, 0x4e, 0x51, 0x2a,
+ 0x6a, 0x40, 0x63, 0x8e, 0x89, 0x0c, 0x04, 0x37, 0x48, 0x97, 0xf4, 0x5a, 0x6e, 0x59, 0x52, 0x13,
+ 0x9a, 0xc8, 0xa7, 0xb1, 0x08, 0xb8, 0x32, 0xaa, 0xba, 0xb5, 0xaa, 0xe9, 0x3d, 0x38, 0x4a, 0x50,
+ 0x8a, 0x34, 0xf1, 0x70, 0xcc, 0x59, 0x84, 0x46, 0x4d, 0x13, 0xda, 0x25, 0xf8, 0x96, 0x45, 0x68,
+ 0x37, 0xe0, 0x60, 0x18, 0xc5, 0x6a, 0x61, 0xbf, 0x82, 0xce, 0xeb, 0x40, 0xaa, 0x0b, 0x3e, 0xfd,
+ 0xc0, 0x94, 0xe7, 0xbb, 0x28, 0x63, 0xc1, 0x25, 0x52, 0x07, 0x1a, 0xf9, 0x36, 0xd2, 0x20, 0xdd,
+ 0x5a, 0xef, 0xb0, 0xdf, 0x71, 0x36, 0xb7, 0x73, 0x06, 0xba, 0x70, 0x4b, 0x92, 0x7d, 0x0e, 0xf5,
+ 0x1c, 0xa2, 0xc7, 0x50, 0xbd, 0x1c, 0x14, 0x86, 0xab, 0xc1, 0x80, 0xde, 0x82, 0xba, 0x8f, 0x2c,
+ 0x54, 0x7e, 0xe1, 0xb4, 0xa8, 0xec, 0x47, 0x70, 0x72, 0x11, 0x86, 0xc2, 0x63, 0x0a, 0xcb, 0x85,
+ 0x2d, 0x80, 0xe2, 0xf7, 0x2e, 0x07, 0xf9, 0xdc, 0x96, 0xbb, 0x81, 0xd8, 0xbf, 0x09, 0x9c, 0xae,
+ 0x35, 0x85, 0xd3, 0xe7, 0xf0, 0x1f, 0xf2, 0x79, 0x69, 0xb3, 0xb7, 0x6d, 0x73, 0x97, 0xed, 0x0c,
+ 0xf9, 0x5c, 0x0e, 0xb9, 0x4a, 0x16, 0xae, 0x56, 0xd1, 0x07, 0x50, 0x8f, 0x44, 0xca, 0x95, 0x34,
+ 0xaa, 0x5a, 0xff, 0xff, 0xb6, 0xfe, 0x4d, 0xd6, 0x73, 0x0b, 0x0a, 0xed, 0xaf, 0x8f, 0x52, 0xd3,
+ 0x6c, 0x63, 0xdf, 0x51, 0xde, 0xc7, 0xe8, 0xad, 0x0e, 0x63, 0x3e, 0x81, 0xd6, 0x6a, 0x26, 0x3d,
+ 0x85, 0xda, 0x27, 0x5c, 0x14, 0xc7, 0xc9, 0x1e, 0x69, 0x07, 0x0e, 0xe6, 0x2c, 0x4c, 0xb1, 0x38,
+ 0x4e, 0x5e, 0x3c, 0xab, 0x3e, 0x25, 0xb6, 0x0f, 0x07, 0x7a, 0x3a, 0xbd, 0x0f, 0xc7, 0x9e, 0xe0,
+ 0x8a, 0x05, 0x1c, 0x93, 0x71, 0xcc, 0x94, 0x5f, 0xe8, 0x8f, 0x56, 0xe8, 0x88, 0x29, 0x9f, 0xde,
+ 0x86, 0x96, 0x2f, 0xa4, 0xca, 0x19, 0x45, 0x28, 0x32, 0xa0, 0x6c, 0x26, 0xc8, 0xa6, 0x63, 0xc1,
+ 0xc3, 0x85, 0x0e, 0x44, 0xd3, 0x6d, 0x66, 0xc0, 0x3b, 0x1e, 0x2e, 0xec, 0x04, 0x60, 0xed, 0xfc,
+ 0x9f, 0x8c, 0xeb, 0xc2, 0x61, 0x8c, 0x49, 0x14, 0xc8, 0x2c, 0xad, 0xb2, 0x48, 0xe0, 0x26, 0xd4,
+ 0x1f, 0x41, 0x3b, 0x8f, 0x7b, 0xc2, 0x54, 0x96, 0xe8, 0x17, 0xd0, 0x2c, 0xe3, 0x4f, 0xef, 0x6e,
+ 0x5f, 0x75, 0xe7, 0xb5, 0x30, 0x77, 0xfe, 0xa2, 0x3c, 0xc7, 0x95, 0xfe, 0x37, 0x02, 0xed, 0x7c,
+ 0x8d, 0x91, 0x6e, 0xd0, 0x2b, 0x68, 0x6f, 0x46, 0x9b, 0xee, 0xd3, 0x99, 0xf6, 0x36, 0xb8, 0xef,
+ 0x5d, 0xb0, 0x2b, 0xe7, 0x84, 0x5e, 0x41, 0xb3, 0xcc, 0xd2, 0xae, 0xbf, 0x9d, 0x14, 0x9b, 0xd6,
+ 0xdf, 0x23, 0x68, 0x57, 0x5e, 0xde, 0xb9, 0xbe, 0xb1, 0xc8, 0x8f, 0x1b, 0xab, 0xf2, 0x65, 0x69,
+ 0x91, 0xeb, 0xa5, 0x45, 0xbe, 0x2f, 0x2d, 0xf2, 0x73, 0x69, 0x91, 0xaf, 0xbf, 0xac, 0xca, 0xa4,
+ 0xae, 0x3f, 0x08, 0x8f, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x17, 0x55, 0xaf, 0xe1, 0x5a, 0x04,
+ 0x00, 0x00,
}
diff --git a/pkg/kubelet/apis/deviceplugin/v1alpha1/api.proto b/pkg/kubelet/apis/deviceplugin/v1alpha/api.proto
similarity index 91%
rename from pkg/kubelet/apis/deviceplugin/v1alpha1/api.proto
rename to pkg/kubelet/apis/deviceplugin/v1alpha/api.proto
index e222d14a76f..05408cbb1fa 100644
--- a/pkg/kubelet/apis/deviceplugin/v1alpha1/api.proto
+++ b/pkg/kubelet/apis/deviceplugin/v1alpha/api.proto
@@ -81,25 +81,21 @@ message AllocateRequest {
repeated string devicesIDs = 1;
}
+// AllocateResponse includes the artifacts that needs to be injected into
+// a container for accessing 'deviceIDs' that were mentioned as part of
+// 'AllocateRequest'.
// Failure Handling:
// if Kubelet sends an allocation request for dev1 and dev2.
// Allocation on dev1 succeeds but allocation on dev2 fails.
// The Device plugin should send a ListAndWatch update and fail the
// Allocation request
message AllocateResponse {
- repeated DeviceRuntimeSpec spec = 1;
-}
-
-// The list to be added to the CRI spec
-message DeviceRuntimeSpec {
- // ID of the Device
- string ID = 1;
- // List of environment variable to set in the container.
- map envs = 2;
+ // List of environment variable to be set in the container to access one of more devices.
+ map envs = 1;
// Mounts for the container.
- repeated Mount mounts = 3;
- // Devices for the container
- repeated DeviceSpec devices = 4;
+ repeated Mount mounts = 2;
+ // Devices for the container.
+ repeated DeviceSpec devices = 3;
}
// Mount specifies a host volume to mount into a container.
diff --git a/pkg/kubelet/apis/deviceplugin/v1alpha1/constants.go b/pkg/kubelet/apis/deviceplugin/v1alpha/constants.go
similarity index 93%
rename from pkg/kubelet/apis/deviceplugin/v1alpha1/constants.go
rename to pkg/kubelet/apis/deviceplugin/v1alpha/constants.go
index fb0440cce59..896354ab901 100644
--- a/pkg/kubelet/apis/deviceplugin/v1alpha1/constants.go
+++ b/pkg/kubelet/apis/deviceplugin/v1alpha/constants.go
@@ -22,8 +22,8 @@ const (
// UnHealthy means that the device is unhealty
Unhealthy = "Unhealthy"
- // Version is the API version
- Version = "0.1"
+ // Current version of the API supported by kubelet
+ Version = "v1alpha2"
// DevicePluginPath is the folder the Device Plugin is expecting sockets to be on
// Only privileged pods have access to this path
// Note: Placeholder until we find a "standard path"
diff --git a/pkg/kubelet/apis/kubeletconfig/types.go b/pkg/kubelet/apis/kubeletconfig/types.go
index 73fb46334de..575a991cd97 100644
--- a/pkg/kubelet/apis/kubeletconfig/types.go
+++ b/pkg/kubelet/apis/kubeletconfig/types.go
@@ -252,8 +252,6 @@ type KubeletConfiguration struct {
SerializeImagePulls bool
// nodeLabels to add when registering the node in the cluster.
NodeLabels map[string]string
- // enable gathering custom metrics.
- EnableCustomMetrics bool
// Comma-delimited list of hard eviction expressions. For example, 'memory.available<300Mi'.
// +optional
EvictionHard string
diff --git a/pkg/kubelet/apis/kubeletconfig/v1alpha1/types.go b/pkg/kubelet/apis/kubeletconfig/v1alpha1/types.go
index c90fbff0427..8921b193637 100644
--- a/pkg/kubelet/apis/kubeletconfig/v1alpha1/types.go
+++ b/pkg/kubelet/apis/kubeletconfig/v1alpha1/types.go
@@ -244,8 +244,6 @@ type KubeletConfiguration struct {
SerializeImagePulls *bool `json:"serializeImagePulls"`
// nodeLabels to add when registering the node in the cluster.
NodeLabels map[string]string `json:"nodeLabels"`
- // enable gathering custom metrics.
- EnableCustomMetrics bool `json:"enableCustomMetrics"`
// Comma-delimited list of hard eviction expressions. For example, 'memory.available<300Mi'.
EvictionHard *string `json:"evictionHard"`
// Comma-delimited list of soft eviction expressions. For example, 'memory.available<300Mi'.
diff --git a/pkg/kubelet/apis/kubeletconfig/v1alpha1/zz_generated.conversion.go b/pkg/kubelet/apis/kubeletconfig/v1alpha1/zz_generated.conversion.go
index 5b4aeef5542..51c98995f52 100644
--- a/pkg/kubelet/apis/kubeletconfig/v1alpha1/zz_generated.conversion.go
+++ b/pkg/kubelet/apis/kubeletconfig/v1alpha1/zz_generated.conversion.go
@@ -244,7 +244,6 @@ func autoConvert_v1alpha1_KubeletConfiguration_To_kubeletconfig_KubeletConfigura
return err
}
out.NodeLabels = *(*map[string]string)(unsafe.Pointer(&in.NodeLabels))
- out.EnableCustomMetrics = in.EnableCustomMetrics
if err := v1.Convert_Pointer_string_To_string(&in.EvictionHard, &out.EvictionHard, s); err != nil {
return err
}
@@ -385,7 +384,6 @@ func autoConvert_kubeletconfig_KubeletConfiguration_To_v1alpha1_KubeletConfigura
return err
}
out.NodeLabels = *(*map[string]string)(unsafe.Pointer(&in.NodeLabels))
- out.EnableCustomMetrics = in.EnableCustomMetrics
if err := v1.Convert_string_To_Pointer_string(&in.EvictionHard, &out.EvictionHard, s); err != nil {
return err
}
diff --git a/pkg/kubelet/cm/BUILD b/pkg/kubelet/cm/BUILD
index d046325f2b9..b107c893320 100644
--- a/pkg/kubelet/cm/BUILD
+++ b/pkg/kubelet/cm/BUILD
@@ -34,7 +34,7 @@ go_library(
deps = [
"//pkg/features:go_default_library",
"//pkg/kubelet/apis/cri:go_default_library",
- "//pkg/kubelet/apis/deviceplugin/v1alpha1:go_default_library",
+ "//pkg/kubelet/apis/deviceplugin/v1alpha:go_default_library",
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
"//pkg/kubelet/cadvisor:go_default_library",
"//pkg/kubelet/cm/cpumanager:go_default_library",
@@ -94,7 +94,7 @@ go_test(
importpath = "k8s.io/kubernetes/pkg/kubelet/cm",
library = ":go_default_library",
deps = [
- "//pkg/kubelet/apis/deviceplugin/v1alpha1:go_default_library",
+ "//pkg/kubelet/apis/deviceplugin/v1alpha:go_default_library",
"//pkg/util/mount:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
diff --git a/pkg/kubelet/cm/container_manager_linux.go b/pkg/kubelet/cm/container_manager_linux.go
index 61a34fc079a..d320c90d2ec 100644
--- a/pkg/kubelet/cm/container_manager_linux.go
+++ b/pkg/kubelet/cm/container_manager_linux.go
@@ -628,56 +628,60 @@ func (cm *containerManagerImpl) GetResources(pod *v1.Pod, container *v1.Containe
}
// Loops through AllocationResponses of all required extended resources.
for _, resp := range allocResps {
- // Loops through runtime spec of all devices of the given resource.
- for _, devRuntime := range resp.Spec {
- // Updates RunContainerOptions.Devices.
- for _, dev := range devRuntime.Devices {
- if d, ok := devsMap[dev.ContainerPath]; ok {
- glog.V(3).Infof("skip existing device %s %s", dev.ContainerPath, dev.HostPath)
- if d != dev.HostPath {
- glog.Errorf("Container device %s has conflicting mapping host devices: %s and %s",
- dev.ContainerPath, d, dev.HostPath)
- }
- continue
+ // Each Allocate response has the following artifacts.
+ // Environment variables
+ // Mount points
+ // Device files
+ // These artifacts are per resource per container.
+ // Updates RunContainerOptions.Envs.
+ for k, v := range resp.Envs {
+ if e, ok := envsMap[k]; ok {
+ glog.V(3).Infof("skip existing envs %s %s", k, v)
+ if e != v {
+ glog.Errorf("Environment variable %s has conflicting setting: %s and %s", k, e, v)
}
- devsMap[dev.ContainerPath] = dev.HostPath
- opts.Devices = append(opts.Devices, kubecontainer.DeviceInfo{
- PathOnHost: dev.HostPath,
- PathInContainer: dev.ContainerPath,
- Permissions: dev.Permissions,
- })
+ continue
}
- // Updates RunContainerOptions.Mounts.
- for _, mount := range devRuntime.Mounts {
- if m, ok := mountsMap[mount.ContainerPath]; ok {
- glog.V(3).Infof("skip existing mount %s %s", mount.ContainerPath, mount.HostPath)
- if m != mount.HostPath {
- glog.Errorf("Container mount %s has conflicting mapping host mounts: %s and %s",
- mount.ContainerPath, m, mount.HostPath)
- }
- continue
+ envsMap[k] = v
+ opts.Envs = append(opts.Envs, kubecontainer.EnvVar{Name: k, Value: v})
+ }
+
+ // Updates RunContainerOptions.Devices.
+ for _, dev := range resp.Devices {
+ if d, ok := devsMap[dev.ContainerPath]; ok {
+ glog.V(3).Infof("skip existing device %s %s", dev.ContainerPath, dev.HostPath)
+ if d != dev.HostPath {
+ glog.Errorf("Container device %s has conflicting mapping host devices: %s and %s",
+ dev.ContainerPath, d, dev.HostPath)
}
- mountsMap[mount.ContainerPath] = mount.HostPath
- opts.Mounts = append(opts.Mounts, kubecontainer.Mount{
- Name: mount.ContainerPath,
- ContainerPath: mount.ContainerPath,
- HostPath: mount.HostPath,
- ReadOnly: mount.ReadOnly,
- SELinuxRelabel: false,
- })
+ continue
}
- // Updates RunContainerOptions.Envs.
- for k, v := range devRuntime.Envs {
- if e, ok := envsMap[k]; ok {
- glog.V(3).Infof("skip existing envs %s %s", k, v)
- if e != v {
- glog.Errorf("Environment variable %s has conflicting setting: %s and %s", k, e, v)
- }
- continue
+ devsMap[dev.ContainerPath] = dev.HostPath
+ opts.Devices = append(opts.Devices, kubecontainer.DeviceInfo{
+ PathOnHost: dev.HostPath,
+ PathInContainer: dev.ContainerPath,
+ Permissions: dev.Permissions,
+ })
+ }
+ // Updates RunContainerOptions.Mounts.
+ for _, mount := range resp.Mounts {
+ if m, ok := mountsMap[mount.ContainerPath]; ok {
+ glog.V(3).Infof("skip existing mount %s %s", mount.ContainerPath, mount.HostPath)
+ if m != mount.HostPath {
+ glog.Errorf("Container mount %s has conflicting mapping host mounts: %s and %s",
+ mount.ContainerPath, m, mount.HostPath)
}
- envsMap[k] = v
- opts.Envs = append(opts.Envs, kubecontainer.EnvVar{Name: k, Value: v})
+ continue
}
+ mountsMap[mount.ContainerPath] = mount.HostPath
+ opts.Mounts = append(opts.Mounts, kubecontainer.Mount{
+ Name: mount.ContainerPath,
+ ContainerPath: mount.ContainerPath,
+ HostPath: mount.HostPath,
+ ReadOnly: mount.ReadOnly,
+ // TODO: This may need to be part of Device plugin API.
+ SELinuxRelabel: false,
+ })
}
}
return opts, nil
diff --git a/pkg/kubelet/cm/device_plugin_handler.go b/pkg/kubelet/cm/device_plugin_handler.go
index 790f720eeca..8217e107d2a 100644
--- a/pkg/kubelet/cm/device_plugin_handler.go
+++ b/pkg/kubelet/cm/device_plugin_handler.go
@@ -28,7 +28,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/util/sets"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
"k8s.io/kubernetes/pkg/kubelet/deviceplugin"
)
diff --git a/pkg/kubelet/cm/device_plugin_handler_stub.go b/pkg/kubelet/cm/device_plugin_handler_stub.go
index a70c281086c..879997f5504 100644
--- a/pkg/kubelet/cm/device_plugin_handler_stub.go
+++ b/pkg/kubelet/cm/device_plugin_handler_stub.go
@@ -18,7 +18,7 @@ package cm
import (
"k8s.io/api/core/v1"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
// A simple stub implementation for DevicePluginHandler.
diff --git a/pkg/kubelet/cm/device_plugin_handler_test.go b/pkg/kubelet/cm/device_plugin_handler_test.go
index e9df09ef2cc..99d375f65dc 100644
--- a/pkg/kubelet/cm/device_plugin_handler_test.go
+++ b/pkg/kubelet/cm/device_plugin_handler_test.go
@@ -28,7 +28,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/uuid"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
func TestUpdateCapacity(t *testing.T) {
@@ -99,9 +99,8 @@ func (m *DevicePluginManagerTestStub) Allocate(resourceName string, devIds []str
for _, id := range devIds {
key := resourceName + id
fmt.Printf("Alloc device %q for resource %q\n", id, resourceName)
- devRuntime := new(pluginapi.DeviceRuntimeSpec)
for _, dev := range m.devRuntimeDevices[key] {
- devRuntime.Devices = append(devRuntime.Devices, &pluginapi.DeviceSpec{
+ resp.Devices = append(resp.Devices, &pluginapi.DeviceSpec{
ContainerPath: dev.value1,
HostPath: dev.value2,
Permissions: "mrw",
@@ -109,17 +108,16 @@ func (m *DevicePluginManagerTestStub) Allocate(resourceName string, devIds []str
}
for _, mount := range m.devRuntimeMounts[key] {
fmt.Printf("Add mount %q %q\n", mount.value1, mount.value2)
- devRuntime.Mounts = append(devRuntime.Mounts, &pluginapi.Mount{
+ resp.Mounts = append(resp.Mounts, &pluginapi.Mount{
ContainerPath: mount.value1,
HostPath: mount.value2,
ReadOnly: true,
})
}
- devRuntime.Envs = make(map[string]string)
+ resp.Envs = make(map[string]string)
for _, env := range m.devRuntimeEnvs[key] {
- devRuntime.Envs[env.value1] = env.value2
+ resp.Envs[env.value1] = env.value2
}
- resp.Spec = append(resp.Spec, devRuntime)
}
return resp, nil
}
@@ -164,6 +162,7 @@ func TestCheckpoint(t *testing.T) {
}
func TestPodContainerDeviceAllocation(t *testing.T) {
+ t.Skip("Skipping due to issue #54100")
flag.Set("alsologtostderr", fmt.Sprintf("%t", true))
var logLevel string
flag.StringVar(&logLevel, "logLevel", "4", "test")
diff --git a/pkg/kubelet/config/BUILD b/pkg/kubelet/config/BUILD
index 44b9f6be54c..854f5dab964 100644
--- a/pkg/kubelet/config/BUILD
+++ b/pkg/kubelet/config/BUILD
@@ -47,7 +47,6 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
diff --git a/pkg/kubelet/config/common.go b/pkg/kubelet/config/common.go
index c3fd9aa6728..345e50ff2e2 100644
--- a/pkg/kubelet/config/common.go
+++ b/pkg/kubelet/config/common.go
@@ -119,8 +119,7 @@ func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *v
newPod, ok := obj.(*api.Pod)
// Check whether the object could be converted to single pod.
if !ok {
- err = fmt.Errorf("invalid pod: %#v", obj)
- return false, pod, err
+ return false, pod, fmt.Errorf("invalid pod: %#v", obj)
}
// Apply default values and validate the pod.
@@ -128,11 +127,11 @@ func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *v
return true, pod, err
}
if errs := validation.ValidatePod(newPod); len(errs) > 0 {
- err = fmt.Errorf("invalid pod: %v", errs)
- return true, pod, err
+ return true, pod, fmt.Errorf("invalid pod: %v", errs)
}
v1Pod := &v1.Pod{}
if err := k8s_api_v1.Convert_api_Pod_To_v1_Pod(newPod, v1Pod, nil); err != nil {
+ glog.Errorf("Pod %q failed to convert to v1", newPod.Name)
return true, nil, err
}
return true, v1Pod, nil
diff --git a/pkg/kubelet/config/config.go b/pkg/kubelet/config/config.go
index ed7869dfb01..ca322d45f3c 100644
--- a/pkg/kubelet/config/config.go
+++ b/pkg/kubelet/config/config.go
@@ -25,11 +25,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
- "k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/client-go/tools/record"
- "k8s.io/kubernetes/pkg/api"
- k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
- "k8s.io/kubernetes/pkg/api/validation"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/events"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
@@ -323,34 +319,17 @@ func (s *podStorage) seenSources(sources ...string) bool {
func filterInvalidPods(pods []*v1.Pod, source string, recorder record.EventRecorder) (filtered []*v1.Pod) {
names := sets.String{}
for i, pod := range pods {
- var errlist field.ErrorList
- // TODO: remove the conversion when validation is performed on versioned objects.
- internalPod := &api.Pod{}
- if err := k8s_api_v1.Convert_v1_Pod_To_api_Pod(pod, internalPod, nil); err != nil {
- glog.Warningf("Pod[%d] (%s) from %s failed to convert to v1, ignoring: %v", i+1, format.Pod(pod), source, err)
- recorder.Eventf(pod, v1.EventTypeWarning, "FailedConversion", "Error converting pod %s from %s, ignoring: %v", format.Pod(pod), source, err)
+ // Pods from each source are assumed to have passed validation individually.
+ // This function only checks if there is any naming conflict.
+ name := kubecontainer.GetPodFullName(pod)
+ if names.Has(name) {
+ glog.Warningf("Pod[%d] (%s) from %s failed validation due to duplicate pod name %q, ignoring", i+1, format.Pod(pod), source, pod.Name)
+ recorder.Eventf(pod, v1.EventTypeWarning, events.FailedValidation, "Error validating pod %s from %s due to duplicate pod name %q, ignoring", format.Pod(pod), source, pod.Name)
continue
- }
- if errs := validation.ValidatePod(internalPod); len(errs) != 0 {
- errlist = append(errlist, errs...)
- // If validation fails, don't trust it any further -
- // even Name could be bad.
} else {
- name := kubecontainer.GetPodFullName(pod)
- if names.Has(name) {
- // TODO: when validation becomes versioned, this gets a bit
- // more complicated.
- errlist = append(errlist, field.Duplicate(field.NewPath("metadata", "name"), pod.Name))
- } else {
- names.Insert(name)
- }
- }
- if len(errlist) > 0 {
- err := errlist.ToAggregate()
- glog.Warningf("Pod[%d] (%s) from %s failed validation, ignoring: %v", i+1, format.Pod(pod), source, err)
- recorder.Eventf(pod, v1.EventTypeWarning, events.FailedValidation, "Error validating pod %s from %s, ignoring: %v", format.Pod(pod), source, err)
- continue
+ names.Insert(name)
}
+
filtered = append(filtered, pod)
}
return
diff --git a/pkg/kubelet/config/config_test.go b/pkg/kubelet/config/config_test.go
index 1e93e5f2ab0..deb1f4dcaf3 100644
--- a/pkg/kubelet/config/config_test.go
+++ b/pkg/kubelet/config/config_test.go
@@ -146,8 +146,10 @@ func TestNewPodAddedInvalidNamespace(t *testing.T) {
// see an update
podUpdate := CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", ""))
channel <- podUpdate
+ expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.ADD, TestSource, CreateValidPod("foo", "")))
+
config.Sync()
- expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, kubetypes.AllSource))
+ expectPodUpdate(t, ch, CreatePodUpdate(kubetypes.SET, kubetypes.AllSource, CreateValidPod("foo", "")))
}
func TestNewPodAddedDefaultNamespace(t *testing.T) {
diff --git a/pkg/kubelet/deviceplugin/BUILD b/pkg/kubelet/deviceplugin/BUILD
index beaaaaebd82..c6cb50c6258 100644
--- a/pkg/kubelet/deviceplugin/BUILD
+++ b/pkg/kubelet/deviceplugin/BUILD
@@ -18,7 +18,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/kubelet/deviceplugin",
deps = [
"//pkg/api/v1/helper:go_default_library",
- "//pkg/kubelet/apis/deviceplugin/v1alpha1:go_default_library",
+ "//pkg/kubelet/apis/deviceplugin/v1alpha:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/golang.org/x/net/context:go_default_library",
"//vendor/google.golang.org/grpc:go_default_library",
@@ -49,7 +49,7 @@ go_test(
importpath = "k8s.io/kubernetes/pkg/kubelet/deviceplugin",
library = ":go_default_library",
deps = [
- "//pkg/kubelet/apis/deviceplugin/v1alpha1:go_default_library",
+ "//pkg/kubelet/apis/deviceplugin/v1alpha:go_default_library",
"//vendor/github.com/stretchr/testify/require:go_default_library",
],
)
diff --git a/pkg/kubelet/deviceplugin/device_plugin_stub.go b/pkg/kubelet/deviceplugin/device_plugin_stub.go
index a0f103d03a9..01f08c15987 100644
--- a/pkg/kubelet/deviceplugin/device_plugin_stub.go
+++ b/pkg/kubelet/deviceplugin/device_plugin_stub.go
@@ -26,7 +26,7 @@ import (
"golang.org/x/net/context"
"google.golang.org/grpc"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
// Stub implementation for DevicePlugin.
diff --git a/pkg/kubelet/deviceplugin/endpoint.go b/pkg/kubelet/deviceplugin/endpoint.go
index f0523471a38..fc55006a60d 100644
--- a/pkg/kubelet/deviceplugin/endpoint.go
+++ b/pkg/kubelet/deviceplugin/endpoint.go
@@ -26,7 +26,7 @@ import (
"golang.org/x/net/context"
"google.golang.org/grpc"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
// endpoint maps to a single registered device plugin. It is responsible
diff --git a/pkg/kubelet/deviceplugin/endpoint_test.go b/pkg/kubelet/deviceplugin/endpoint_test.go
index a1786711de9..362856c69a5 100644
--- a/pkg/kubelet/deviceplugin/endpoint_test.go
+++ b/pkg/kubelet/deviceplugin/endpoint_test.go
@@ -23,7 +23,7 @@ import (
"github.com/stretchr/testify/require"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
var (
diff --git a/pkg/kubelet/deviceplugin/manager.go b/pkg/kubelet/deviceplugin/manager.go
index 5c05a972894..6701dc63228 100644
--- a/pkg/kubelet/deviceplugin/manager.go
+++ b/pkg/kubelet/deviceplugin/manager.go
@@ -27,7 +27,7 @@ import (
"golang.org/x/net/context"
"google.golang.org/grpc"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
// ManagerImpl is the structure in charge of managing Device Plugins.
diff --git a/pkg/kubelet/deviceplugin/manager_test.go b/pkg/kubelet/deviceplugin/manager_test.go
index cdc43a0b255..835ce09a949 100644
--- a/pkg/kubelet/deviceplugin/manager_test.go
+++ b/pkg/kubelet/deviceplugin/manager_test.go
@@ -23,7 +23,7 @@ import (
"github.com/stretchr/testify/require"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
const (
diff --git a/pkg/kubelet/deviceplugin/types.go b/pkg/kubelet/deviceplugin/types.go
index 3a2eae6fee1..6ef8046687f 100644
--- a/pkg/kubelet/deviceplugin/types.go
+++ b/pkg/kubelet/deviceplugin/types.go
@@ -17,7 +17,7 @@ limitations under the License.
package deviceplugin
import (
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
// MonitorCallback is the function called when a device's health state changes,
diff --git a/pkg/kubelet/deviceplugin/utils.go b/pkg/kubelet/deviceplugin/utils.go
index b30ac2f640e..ce7f19665cb 100644
--- a/pkg/kubelet/deviceplugin/utils.go
+++ b/pkg/kubelet/deviceplugin/utils.go
@@ -21,7 +21,7 @@ import (
"k8s.io/api/core/v1"
v1helper "k8s.io/kubernetes/pkg/api/v1/helper"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
func cloneDevice(d *pluginapi.Device) *pluginapi.Device {
diff --git a/pkg/kubelet/deviceplugin/utils_test.go b/pkg/kubelet/deviceplugin/utils_test.go
index 33924605c5c..99156d6475d 100644
--- a/pkg/kubelet/deviceplugin/utils_test.go
+++ b/pkg/kubelet/deviceplugin/utils_test.go
@@ -21,7 +21,7 @@ import (
"github.com/stretchr/testify/require"
- pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha1"
+ pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1alpha"
)
func TestCloneDevice(t *testing.T) {
diff --git a/pkg/kubelet/dockershim/docker_image.go b/pkg/kubelet/dockershim/docker_image.go
index b1171c6f054..1b39522f862 100644
--- a/pkg/kubelet/dockershim/docker_image.go
+++ b/pkg/kubelet/dockershim/docker_image.go
@@ -21,6 +21,7 @@ import (
"net/http"
dockertypes "github.com/docker/docker/api/types"
+ dockerfilters "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/pkg/jsonmessage"
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
@@ -33,8 +34,9 @@ import (
func (ds *dockerService) ListImages(filter *runtimeapi.ImageFilter) ([]*runtimeapi.Image, error) {
opts := dockertypes.ImageListOptions{}
if filter != nil {
- if imgSpec := filter.GetImage(); imgSpec != nil {
- opts.Filters.Add("reference", imgSpec.Image)
+ if filter.GetImage().GetImage() != "" {
+ opts.Filters = dockerfilters.NewArgs()
+ opts.Filters.Add("reference", filter.GetImage().GetImage())
}
}
diff --git a/pkg/kubemark/hollow_kubelet.go b/pkg/kubemark/hollow_kubelet.go
index 671d19912d8..aa50be6c443 100644
--- a/pkg/kubemark/hollow_kubelet.go
+++ b/pkg/kubemark/hollow_kubelet.go
@@ -144,7 +144,6 @@ func GetHollowKubeletConfig(
c.CPUCFSQuota = true
c.RuntimeCgroups = ""
c.EnableControllerAttachDetach = false
- c.EnableCustomMetrics = false
c.EnableDebuggingHandlers = true
c.EnableServer = true
c.CgroupsPerQOS = false
diff --git a/pkg/master/controller.go b/pkg/master/controller.go
index 158b5d1f6f0..c0bd6c02508 100644
--- a/pkg/master/controller.go
+++ b/pkg/master/controller.go
@@ -112,6 +112,11 @@ func (c *Controller) PostStartHook(hookContext genericapiserver.PostStartHookCon
return nil
}
+func (c *Controller) PreShutdownHook() error {
+ c.Stop()
+ return nil
+}
+
// Start begins the core controller loops that must exist for bootstrapping
// a cluster.
func (c *Controller) Start() {
@@ -140,6 +145,14 @@ func (c *Controller) Start() {
c.runner.Start()
}
+func (c *Controller) Stop() {
+ if c.runner != nil {
+ c.runner.Stop()
+ }
+ endpointPorts := createEndpointPortSpec(c.PublicServicePort, "https", c.ExtraEndpointPorts)
+ c.EndpointReconciler.StopReconciling("kubernetes", c.PublicIP, endpointPorts)
+}
+
// RunKubernetesNamespaces periodically makes sure that all internal namespaces exist
func (c *Controller) RunKubernetesNamespaces(ch chan struct{}) {
wait.Until(func() {
diff --git a/pkg/master/master.go b/pkg/master/master.go
index b5a559dfd05..84e734d6459 100644
--- a/pkg/master/master.go
+++ b/pkg/master/master.go
@@ -93,8 +93,6 @@ const (
DefaultEndpointReconcilerInterval = 10 * time.Second
// DefaultEndpointReconcilerTTL is the default TTL timeout for the storage layer
DefaultEndpointReconcilerTTL = 15 * time.Second
- // DefaultStorageEndpoint is the default storage endpoint for the lease controller
- DefaultStorageEndpoint = "kube-apiserver-endpoint"
)
type ExtraConfig struct {
@@ -206,7 +204,7 @@ func (c *Config) createLeaseReconciler() reconcilers.EndpointReconciler {
if err != nil {
glog.Fatalf("Error creating storage factory: %v", err)
}
- endpointConfig, err := c.ExtraConfig.StorageFactory.NewConfig(kapi.Resource(DefaultStorageEndpoint))
+ endpointConfig, err := c.ExtraConfig.StorageFactory.NewConfig(kapi.Resource("endpoints"))
if err != nil {
glog.Fatalf("Error getting storage config: %v", err)
}
@@ -214,7 +212,7 @@ func (c *Config) createLeaseReconciler() reconcilers.EndpointReconciler {
StorageConfig: endpointConfig,
Decorator: generic.UndecoratedStorage,
DeleteCollectionWorkers: 0,
- ResourcePrefix: c.ExtraConfig.StorageFactory.ResourcePrefix(kapi.Resource(DefaultStorageEndpoint)),
+ ResourcePrefix: c.ExtraConfig.StorageFactory.ResourcePrefix(kapi.Resource("endpoints")),
})
endpointRegistry := endpoint.NewRegistry(endpointsStorage)
masterLeases := reconcilers.NewLeases(leaseStorage, "/masterleases/", ttl)
@@ -372,9 +370,11 @@ func (m *Master) InstallLegacyAPI(c *completedConfig, restOptionsGetter generic.
}
if c.ExtraConfig.EnableCoreControllers {
+ controllerName := "bootstrap-controller"
coreClient := coreclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
bootstrapController := c.NewBootstrapController(legacyRESTStorage, coreClient, coreClient)
- m.GenericAPIServer.AddPostStartHookOrDie("bootstrap-controller", bootstrapController.PostStartHook)
+ m.GenericAPIServer.AddPostStartHookOrDie(controllerName, bootstrapController.PostStartHook)
+ m.GenericAPIServer.AddPreShutdownHookOrDie(controllerName, bootstrapController.PreShutdownHook)
}
if err := m.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.DefaultLegacyAPIPrefix, &apiGroupInfo); err != nil {
diff --git a/pkg/master/reconcilers/BUILD b/pkg/master/reconcilers/BUILD
index f24446b9798..ae48372d4f0 100644
--- a/pkg/master/reconcilers/BUILD
+++ b/pkg/master/reconcilers/BUILD
@@ -22,6 +22,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage:go_default_library",
+ "//vendor/k8s.io/client-go/util/retry:go_default_library",
],
)
diff --git a/pkg/master/reconcilers/lease.go b/pkg/master/reconcilers/lease.go
index 75e8d64c4a0..e3c3f46240b 100644
--- a/pkg/master/reconcilers/lease.go
+++ b/pkg/master/reconcilers/lease.go
@@ -24,6 +24,8 @@ https://github.com/openshift/origin/blob/bb340c5dd5ff72718be86fb194dedc0faed7f4c
import (
"fmt"
"net"
+ "path"
+ "sync"
"time"
"github.com/golang/glog"
@@ -44,6 +46,9 @@ type Leases interface {
// UpdateLease adds or refreshes a master's lease
UpdateLease(ip string) error
+
+ // RemoveLease removes a master's lease
+ RemoveLease(ip string) error
}
type storageLeases struct {
@@ -73,7 +78,8 @@ func (s *storageLeases) ListLeases() ([]string, error) {
// UpdateLease resets the TTL on a master IP in storage
func (s *storageLeases) UpdateLease(ip string) error {
- return s.storage.GuaranteedUpdate(apirequest.NewDefaultContext(), s.baseKey+"/"+ip, &api.Endpoints{}, true, nil, func(input kruntime.Object, respMeta storage.ResponseMeta) (kruntime.Object, *uint64, error) {
+ key := path.Join(s.baseKey, ip)
+ return s.storage.GuaranteedUpdate(apirequest.NewDefaultContext(), key, &api.Endpoints{}, true, nil, func(input kruntime.Object, respMeta storage.ResponseMeta) (kruntime.Object, *uint64, error) {
// just make sure we've got the right IP set, and then refresh the TTL
existing := input.(*api.Endpoints)
existing.Subsets = []api.EndpointSubset{
@@ -82,7 +88,8 @@ func (s *storageLeases) UpdateLease(ip string) error {
},
}
- leaseTime := uint64(s.leaseTime)
+ // leaseTime needs to be in seconds
+ leaseTime := uint64(s.leaseTime / time.Second)
// NB: GuaranteedUpdate does not perform the store operation unless
// something changed between load and store (not including resource
@@ -96,6 +103,11 @@ func (s *storageLeases) UpdateLease(ip string) error {
})
}
+// RemoveLease removes the lease on a master IP in storage
+func (s *storageLeases) RemoveLease(ip string) error {
+ return s.storage.Delete(apirequest.NewDefaultContext(), s.baseKey+"/"+ip, &api.Endpoints{}, nil)
+}
+
// NewLeases creates a new etcd-based Leases implementation.
func NewLeases(storage storage.Interface, baseKey string, leaseTime time.Duration) Leases {
return &storageLeases{
@@ -106,15 +118,18 @@ func NewLeases(storage storage.Interface, baseKey string, leaseTime time.Duratio
}
type leaseEndpointReconciler struct {
- endpointRegistry endpoint.Registry
- masterLeases Leases
+ endpointRegistry endpoint.Registry
+ masterLeases Leases
+ stopReconcilingCalled bool
+ reconcilingLock sync.Mutex
}
// NewLeaseEndpointReconciler creates a new LeaseEndpoint reconciler
func NewLeaseEndpointReconciler(endpointRegistry endpoint.Registry, masterLeases Leases) EndpointReconciler {
return &leaseEndpointReconciler{
- endpointRegistry: endpointRegistry,
- masterLeases: masterLeases,
+ endpointRegistry: endpointRegistry,
+ masterLeases: masterLeases,
+ stopReconcilingCalled: false,
}
}
@@ -126,7 +141,12 @@ func NewLeaseEndpointReconciler(endpointRegistry endpoint.Registry, masterLeases
// different from the directory listing, and update the endpoints object
// accordingly.
func (r *leaseEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []api.EndpointPort, reconcilePorts bool) error {
- ctx := apirequest.NewDefaultContext()
+ r.reconcilingLock.Lock()
+ defer r.reconcilingLock.Unlock()
+
+ if r.stopReconcilingCalled {
+ return nil
+ }
// Refresh the TTL on our key, independently of whether any error or
// update conflict happens below. This makes sure that at least some of
@@ -135,6 +155,12 @@ func (r *leaseEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.
return err
}
+ return r.doReconcile(serviceName, endpointPorts, reconcilePorts)
+}
+
+func (r *leaseEndpointReconciler) doReconcile(serviceName string, endpointPorts []api.EndpointPort, reconcilePorts bool) error {
+ ctx := apirequest.NewDefaultContext()
+
// Retrieve the current list of endpoints...
e, err := r.endpointRegistry.GetEndpoints(ctx, serviceName, &metav1.GetOptions{})
if err != nil {
@@ -249,3 +275,15 @@ func checkEndpointSubsetFormatWithLease(e *api.Endpoints, expectedIPs []string,
return true, ipsCorrect, portsCorrect
}
+
+func (r *leaseEndpointReconciler) StopReconciling(serviceName string, ip net.IP, endpointPorts []api.EndpointPort) error {
+ r.reconcilingLock.Lock()
+ defer r.reconcilingLock.Unlock()
+ r.stopReconcilingCalled = true
+
+ if err := r.masterLeases.RemoveLease(ip.String()); err != nil {
+ return err
+ }
+
+ return r.doReconcile(serviceName, endpointPorts, true)
+}
diff --git a/pkg/master/reconcilers/lease_test.go b/pkg/master/reconcilers/lease_test.go
index 5f2c66ee1e4..1cdab4e4b53 100644
--- a/pkg/master/reconcilers/lease_test.go
+++ b/pkg/master/reconcilers/lease_test.go
@@ -54,6 +54,11 @@ func (f *fakeLeases) UpdateLease(ip string) error {
return nil
}
+func (f *fakeLeases) RemoveLease(ip string) error {
+ delete(f.keys, ip)
+ return nil
+}
+
func (f *fakeLeases) SetKeys(keys []string) {
for _, ip := range keys {
f.keys[ip] = false
@@ -529,3 +534,100 @@ func TestLeaseEndpointReconciler(t *testing.T) {
}
}
}
+
+func TestLeaseStopReconciling(t *testing.T) {
+ ns := api.NamespaceDefault
+ om := func(name string) metav1.ObjectMeta {
+ return metav1.ObjectMeta{Namespace: ns, Name: name}
+ }
+ stopTests := []struct {
+ testName string
+ serviceName string
+ ip string
+ endpointPorts []api.EndpointPort
+ endpointKeys []string
+ endpoints *api.EndpointsList
+ expectUpdate *api.Endpoints // nil means none expected
+ }{
+ {
+ testName: "successful stop reconciling",
+ serviceName: "foo",
+ ip: "1.2.3.4",
+ endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
+ endpointKeys: []string{"1.2.3.4", "4.3.2.2", "4.3.2.3", "4.3.2.4"},
+ endpoints: &api.EndpointsList{
+ Items: []api.Endpoints{{
+ ObjectMeta: om("foo"),
+ Subsets: []api.EndpointSubset{{
+ Addresses: []api.EndpointAddress{
+ {IP: "1.2.3.4"},
+ {IP: "4.3.2.2"},
+ {IP: "4.3.2.3"},
+ {IP: "4.3.2.4"},
+ },
+ Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
+ }},
+ }},
+ },
+ expectUpdate: &api.Endpoints{
+ ObjectMeta: om("foo"),
+ Subsets: []api.EndpointSubset{{
+ Addresses: []api.EndpointAddress{
+ {IP: "4.3.2.2"},
+ {IP: "4.3.2.3"},
+ {IP: "4.3.2.4"},
+ },
+ Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
+ }},
+ },
+ },
+ {
+ testName: "stop reconciling with ip not in endpoint ip list",
+ serviceName: "foo",
+ ip: "5.6.7.8",
+ endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
+ endpointKeys: []string{"1.2.3.4", "4.3.2.2", "4.3.2.3", "4.3.2.4"},
+ endpoints: &api.EndpointsList{
+ Items: []api.Endpoints{{
+ ObjectMeta: om("foo"),
+ Subsets: []api.EndpointSubset{{
+ Addresses: []api.EndpointAddress{
+ {IP: "1.2.3.4"},
+ {IP: "4.3.2.2"},
+ {IP: "4.3.2.3"},
+ {IP: "4.3.2.4"},
+ },
+ Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
+ }},
+ }},
+ },
+ },
+ }
+ for _, test := range stopTests {
+ fakeLeases := newFakeLeases()
+ fakeLeases.SetKeys(test.endpointKeys)
+ registry := ®istrytest.EndpointRegistry{
+ Endpoints: test.endpoints,
+ }
+ r := NewLeaseEndpointReconciler(registry, fakeLeases)
+ err := r.StopReconciling(test.serviceName, net.ParseIP(test.ip), test.endpointPorts)
+ if err != nil {
+ t.Errorf("case %q: unexpected error: %v", test.testName, err)
+ }
+ if test.expectUpdate != nil {
+ if len(registry.Updates) != 1 {
+ t.Errorf("case %q: unexpected updates: %v", test.testName, registry.Updates)
+ } else if e, a := test.expectUpdate, ®istry.Updates[0]; !reflect.DeepEqual(e, a) {
+ t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a)
+ }
+ }
+ if test.expectUpdate == nil && len(registry.Updates) > 0 {
+ t.Errorf("case %q: no update expected, yet saw: %v", test.testName, registry.Updates)
+ }
+ for _, key := range fakeLeases.GetUpdatedKeys() {
+ if key == test.ip {
+ t.Errorf("case %q: Found ip %s in leases but shouldn't be there", test.testName, key)
+ }
+ }
+ }
+}
diff --git a/pkg/master/reconcilers/mastercount.go b/pkg/master/reconcilers/mastercount.go
index 5984fec2d60..8d5493e59dc 100644
--- a/pkg/master/reconcilers/mastercount.go
+++ b/pkg/master/reconcilers/mastercount.go
@@ -19,10 +19,12 @@ package reconcilers
import (
"net"
+ "sync"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/client-go/util/retry"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/endpoints"
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
@@ -31,8 +33,10 @@ import (
// masterCountEndpointReconciler reconciles endpoints based on a specified expected number of
// masters. masterCountEndpointReconciler implements EndpointReconciler.
type masterCountEndpointReconciler struct {
- masterCount int
- endpointClient coreclient.EndpointsGetter
+ masterCount int
+ endpointClient coreclient.EndpointsGetter
+ stopReconcilingCalled bool
+ reconcilingLock sync.Mutex
}
// NewMasterCountEndpointReconciler creates a new EndpointReconciler that reconciles based on a
@@ -57,6 +61,13 @@ func NewMasterCountEndpointReconciler(masterCount int, endpointClient coreclient
// to be running (c.masterCount).
// * ReconcileEndpoints is called periodically from all apiservers.
func (r *masterCountEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []api.EndpointPort, reconcilePorts bool) error {
+ r.reconcilingLock.Lock()
+ defer r.reconcilingLock.Unlock()
+
+ if r.stopReconcilingCalled {
+ return nil
+ }
+
e, err := r.endpointClient.Endpoints(metav1.NamespaceDefault).Get(serviceName, metav1.GetOptions{})
if err != nil {
e = &api.Endpoints{
@@ -126,6 +137,36 @@ func (r *masterCountEndpointReconciler) ReconcileEndpoints(serviceName string, i
return err
}
+func (r *masterCountEndpointReconciler) StopReconciling(serviceName string, ip net.IP, endpointPorts []api.EndpointPort) error {
+ r.reconcilingLock.Lock()
+ defer r.reconcilingLock.Unlock()
+ r.stopReconcilingCalled = true
+
+ e, err := r.endpointClient.Endpoints(metav1.NamespaceDefault).Get(serviceName, metav1.GetOptions{})
+ if err != nil {
+ if errors.IsNotFound(err) {
+ // Endpoint doesn't exist
+ return nil
+ }
+ return err
+ }
+
+ // Remove our IP from the list of addresses
+ new := []api.EndpointAddress{}
+ for _, addr := range e.Subsets[0].Addresses {
+ if addr.IP != ip.String() {
+ new = append(new, addr)
+ }
+ }
+ e.Subsets[0].Addresses = new
+ e.Subsets = endpoints.RepackSubsets(e.Subsets)
+ err = retry.RetryOnConflict(retry.DefaultBackoff, func() error {
+ _, err := r.endpointClient.Endpoints(metav1.NamespaceDefault).Update(e)
+ return err
+ })
+ return err
+}
+
// Determine if the endpoint is in the format ReconcileEndpoints expects.
//
// Return values:
diff --git a/pkg/master/reconcilers/none.go b/pkg/master/reconcilers/none.go
index 33e65ab7db0..ca73e1a5913 100644
--- a/pkg/master/reconcilers/none.go
+++ b/pkg/master/reconcilers/none.go
@@ -36,3 +36,8 @@ func NewNoneEndpointReconciler() EndpointReconciler {
func (r *noneEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []api.EndpointPort, reconcilePorts bool) error {
return nil
}
+
+// StopReconciling noop reconcile
+func (r *noneEndpointReconciler) StopReconciling(serviceName string, ip net.IP, endpointPorts []api.EndpointPort) error {
+ return nil
+}
diff --git a/pkg/master/reconcilers/reconcilers.go b/pkg/master/reconcilers/reconcilers.go
index 346fa8fb529..abaabaa03c0 100644
--- a/pkg/master/reconcilers/reconcilers.go
+++ b/pkg/master/reconcilers/reconcilers.go
@@ -36,6 +36,7 @@ type EndpointReconciler interface {
// endpoints for their {rw, ro} services.
// * ReconcileEndpoints is called periodically from all apiservers.
ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []api.EndpointPort, reconcilePorts bool) error
+ StopReconciling(serviceName string, ip net.IP, endpointPorts []api.EndpointPort) error
}
// Type the reconciler type
diff --git a/pkg/volume/aws_ebs/aws_ebs_test.go b/pkg/volume/aws_ebs/aws_ebs_test.go
index 7c149bf06d6..a09ad35a625 100644
--- a/pkg/volume/aws_ebs/aws_ebs_test.go
+++ b/pkg/volume/aws_ebs/aws_ebs_test.go
@@ -71,23 +71,14 @@ func TestGetAccessModes(t *testing.T) {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) {
t.Errorf("Expected to support AccessModeTypes: %s", v1.ReadWriteOnce)
}
- if contains(plug.GetAccessModes(), v1.ReadOnlyMany) {
+ if volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) {
t.Errorf("Expected not to support AccessModeTypes: %s", v1.ReadOnlyMany)
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
type fakePDManager struct {
}
diff --git a/pkg/volume/azure_file/azure_file_test.go b/pkg/volume/azure_file/azure_file_test.go
index d6fc125963e..f995b4eee32 100644
--- a/pkg/volume/azure_file/azure_file_test.go
+++ b/pkg/volume/azure_file/azure_file_test.go
@@ -71,20 +71,11 @@ func TestGetAccessModes(t *testing.T) {
if err != nil {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) || !contains(plug.GetAccessModes(), v1.ReadOnlyMany) || !contains(plug.GetAccessModes(), v1.ReadWriteMany) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteMany) {
t.Errorf("Expected three AccessModeTypes: %s, %s, and %s", v1.ReadWriteOnce, v1.ReadOnlyMany, v1.ReadWriteMany)
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
func getAzureTestCloud(t *testing.T) *azure.Cloud {
config := `{
"aadClientId": "--aad-client-id--",
diff --git a/pkg/volume/fc/fc_test.go b/pkg/volume/fc/fc_test.go
index b8006942817..e304263f945 100644
--- a/pkg/volume/fc/fc_test.go
+++ b/pkg/volume/fc/fc_test.go
@@ -67,20 +67,11 @@ func TestGetAccessModes(t *testing.T) {
if err != nil {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) || !contains(plug.GetAccessModes(), v1.ReadOnlyMany) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) {
t.Errorf("Expected two AccessModeTypes: %s and %s", v1.ReadWriteOnce, v1.ReadOnlyMany)
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
type fakeDiskManager struct {
tmpDir string
attachCalled bool
diff --git a/pkg/volume/flexvolume/flexvolume_test.go b/pkg/volume/flexvolume/flexvolume_test.go
index 292beb54506..4b0b8b95a10 100644
--- a/pkg/volume/flexvolume/flexvolume_test.go
+++ b/pkg/volume/flexvolume/flexvolume_test.go
@@ -208,16 +208,7 @@ func TestGetAccessModes(t *testing.T) {
if err != nil {
t.Fatalf("Can't find the plugin by name")
}
- if !contains(plugin.GetAccessModes(), v1.ReadWriteOnce) || !contains(plugin.GetAccessModes(), v1.ReadOnlyMany) {
+ if !volumetest.ContainsAccessMode(plugin.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plugin.GetAccessModes(), v1.ReadOnlyMany) {
t.Errorf("Expected two AccessModeTypes: %s and %s", v1.ReadWriteOnce, v1.ReadOnlyMany)
}
}
-
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
diff --git a/pkg/volume/gce_pd/gce_pd_test.go b/pkg/volume/gce_pd/gce_pd_test.go
index cb8397da2b8..325c98c608e 100644
--- a/pkg/volume/gce_pd/gce_pd_test.go
+++ b/pkg/volume/gce_pd/gce_pd_test.go
@@ -69,20 +69,11 @@ func TestGetAccessModes(t *testing.T) {
if err != nil {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) || !contains(plug.GetAccessModes(), v1.ReadOnlyMany) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) {
t.Errorf("Expected two AccessModeTypes: %s and %s", v1.ReadWriteOnce, v1.ReadOnlyMany)
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
type fakePDManager struct {
}
diff --git a/pkg/volume/glusterfs/glusterfs_test.go b/pkg/volume/glusterfs/glusterfs_test.go
index ba8a2fb3726..9057e0cb542 100644
--- a/pkg/volume/glusterfs/glusterfs_test.go
+++ b/pkg/volume/glusterfs/glusterfs_test.go
@@ -73,20 +73,11 @@ func TestGetAccessModes(t *testing.T) {
if err != nil {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) || !contains(plug.GetAccessModes(), v1.ReadOnlyMany) || !contains(plug.GetAccessModes(), v1.ReadWriteMany) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteMany) {
t.Errorf("Expected three AccessModeTypes: %s, %s, and %s", v1.ReadWriteOnce, v1.ReadOnlyMany, v1.ReadWriteMany)
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
func doTestPlugin(t *testing.T, spec *volume.Spec) {
tmpDir, err := utiltesting.MkTmpdir("glusterfs_test")
if err != nil {
diff --git a/pkg/volume/iscsi/iscsi_test.go b/pkg/volume/iscsi/iscsi_test.go
index dd034657939..7bbbd84a0d0 100644
--- a/pkg/volume/iscsi/iscsi_test.go
+++ b/pkg/volume/iscsi/iscsi_test.go
@@ -67,20 +67,11 @@ func TestGetAccessModes(t *testing.T) {
if err != nil {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) || !contains(plug.GetAccessModes(), v1.ReadOnlyMany) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) {
t.Errorf("Expected two AccessModeTypes: %s and %s", v1.ReadWriteOnce, v1.ReadOnlyMany)
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
type fakeDiskManager struct {
tmpDir string
attachCalled bool
diff --git a/pkg/volume/local/local_test.go b/pkg/volume/local/local_test.go
index 87fb829c493..d4ddd12020d 100644
--- a/pkg/volume/local/local_test.go
+++ b/pkg/volume/local/local_test.go
@@ -93,15 +93,6 @@ func getTestVolume(readOnly bool, path string) *volume.Spec {
return volume.NewSpecFromPersistentVolume(pv, readOnly)
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
func TestCanSupport(t *testing.T) {
tmpDir, plug := getPlugin(t)
defer os.RemoveAll(tmpDir)
@@ -116,14 +107,14 @@ func TestGetAccessModes(t *testing.T) {
defer os.RemoveAll(tmpDir)
modes := plug.GetAccessModes()
- if !contains(modes, v1.ReadWriteOnce) {
+ if !volumetest.ContainsAccessMode(modes, v1.ReadWriteOnce) {
t.Errorf("Expected AccessModeType %q", v1.ReadWriteOnce)
}
- if contains(modes, v1.ReadWriteMany) {
+ if volumetest.ContainsAccessMode(modes, v1.ReadWriteMany) {
t.Errorf("Found AccessModeType %q, expected not", v1.ReadWriteMany)
}
- if contains(modes, v1.ReadOnlyMany) {
+ if volumetest.ContainsAccessMode(modes, v1.ReadOnlyMany) {
t.Errorf("Found AccessModeType %q, expected not", v1.ReadOnlyMany)
}
}
diff --git a/pkg/volume/nfs/nfs_test.go b/pkg/volume/nfs/nfs_test.go
index 2cb83235b59..cfc6f36d181 100644
--- a/pkg/volume/nfs/nfs_test.go
+++ b/pkg/volume/nfs/nfs_test.go
@@ -73,7 +73,7 @@ func TestGetAccessModes(t *testing.T) {
if err != nil {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) || !contains(plug.GetAccessModes(), v1.ReadOnlyMany) || !contains(plug.GetAccessModes(), v1.ReadWriteMany) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteMany) {
t.Errorf("Expected three AccessModeTypes: %s, %s, and %s", v1.ReadWriteOnce, v1.ReadOnlyMany, v1.ReadWriteMany)
}
}
@@ -95,15 +95,6 @@ func TestRecycler(t *testing.T) {
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
func doTestPlugin(t *testing.T, spec *volume.Spec) {
tmpDir, err := utiltesting.MkTmpdir("nfs_test")
if err != nil {
@@ -120,17 +111,16 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
fake := &mount.FakeMounter{}
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
mounter, err := plug.(*nfsPlugin).newMounterInternal(spec, pod, fake)
- volumePath := mounter.GetPath()
if err != nil {
t.Errorf("Failed to make a new Mounter: %v", err)
}
if mounter == nil {
t.Errorf("Got a nil Mounter")
}
- path := mounter.GetPath()
+ volumePath := mounter.GetPath()
expectedPath := fmt.Sprintf("%s/pods/poduid/volumes/kubernetes.io~nfs/vol1", tmpDir)
- if path != expectedPath {
- t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, path)
+ if volumePath != expectedPath {
+ t.Errorf("Unexpected path, expected %q, got: %q", expectedPath, volumePath)
}
if err := mounter.SetUp(nil); err != nil {
t.Errorf("Expected success, got: %v", err)
diff --git a/pkg/volume/photon_pd/photon_pd_test.go b/pkg/volume/photon_pd/photon_pd_test.go
index 719727307e5..04dd2fee48f 100644
--- a/pkg/volume/photon_pd/photon_pd_test.go
+++ b/pkg/volume/photon_pd/photon_pd_test.go
@@ -68,23 +68,14 @@ func TestGetAccessModes(t *testing.T) {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) {
t.Errorf("Expected to support AccessModeTypes: %s", v1.ReadWriteOnce)
}
- if contains(plug.GetAccessModes(), v1.ReadOnlyMany) {
+ if volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) {
t.Errorf("Expected not to support AccessModeTypes: %s", v1.ReadOnlyMany)
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
type fakePDManager struct {
}
diff --git a/pkg/volume/plugins.go b/pkg/volume/plugins.go
index f439187bf2a..1ec55d2392b 100644
--- a/pkg/volume/plugins.go
+++ b/pkg/volume/plugins.go
@@ -711,7 +711,7 @@ func NewPersistentVolumeRecyclerPodTemplate() *v1.Pod {
Containers: []v1.Container{
{
Name: "pv-recycler",
- Image: "busybox:latest",
+ Image: "busybox:1.27",
Command: []string{"/bin/sh"},
Args: []string{"-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"},
VolumeMounts: []v1.VolumeMount{
diff --git a/pkg/volume/portworx/portworx_test.go b/pkg/volume/portworx/portworx_test.go
index 5401b6384dc..074f25c47da 100644
--- a/pkg/volume/portworx/portworx_test.go
+++ b/pkg/volume/portworx/portworx_test.go
@@ -72,26 +72,17 @@ func TestGetAccessModes(t *testing.T) {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) {
t.Errorf("Expected to support AccessModeTypes: %s", v1.ReadWriteOnce)
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteMany) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteMany) {
t.Errorf("Expected to support AccessModeTypes: %s", v1.ReadWriteMany)
}
- if contains(plug.GetAccessModes(), v1.ReadOnlyMany) {
+ if volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) {
t.Errorf("Expected not to support AccessModeTypes: %s", v1.ReadOnlyMany)
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
type fakePortworxManager struct {
attachCalled bool
mountCalled bool
diff --git a/pkg/volume/quobyte/quobyte_test.go b/pkg/volume/quobyte/quobyte_test.go
index 1ae60e4078b..61c061ad0f2 100644
--- a/pkg/volume/quobyte/quobyte_test.go
+++ b/pkg/volume/quobyte/quobyte_test.go
@@ -69,20 +69,11 @@ func TestGetAccessModes(t *testing.T) {
if err != nil {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) || !contains(plug.GetAccessModes(), v1.ReadOnlyMany) || !contains(plug.GetAccessModes(), v1.ReadWriteMany) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteMany) {
t.Errorf("Expected three AccessModeTypes: %s, %s, and %s", v1.ReadWriteOnce, v1.ReadOnlyMany, v1.ReadWriteMany)
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
func doTestPlugin(t *testing.T, spec *volume.Spec) {
tmpDir, err := utiltesting.MkTmpdir("quobyte_test")
if err != nil {
diff --git a/pkg/volume/storageos/storageos_test.go b/pkg/volume/storageos/storageos_test.go
index 645dd8c6cef..54ac430b551 100644
--- a/pkg/volume/storageos/storageos_test.go
+++ b/pkg/volume/storageos/storageos_test.go
@@ -69,7 +69,7 @@ func TestGetAccessModes(t *testing.T) {
if err != nil {
t.Errorf("Can't find the plugin by name")
}
- if !contains(plug.GetAccessModes(), v1.ReadWriteOnce) || !contains(plug.GetAccessModes(), v1.ReadOnlyMany) {
+ if !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadWriteOnce) || !volumetest.ContainsAccessMode(plug.GetAccessModes(), v1.ReadOnlyMany) {
t.Errorf("Expected two AccessModeTypes: %s and %s", v1.ReadWriteOnce, v1.ReadOnlyMany)
}
}
@@ -308,15 +308,6 @@ func TestPlugin(t *testing.T) {
}
}
-func contains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
- for _, m := range modes {
- if m == mode {
- return true
- }
- }
- return false
-}
-
func TestPersistentClaimReadOnlyFlag(t *testing.T) {
tmpDir, err := utiltesting.MkTmpdir("storageos_test")
if err != nil {
diff --git a/pkg/volume/testing/testing.go b/pkg/volume/testing/testing.go
index d2903f5f144..7c6f78481fc 100644
--- a/pkg/volume/testing/testing.go
+++ b/pkg/volume/testing/testing.go
@@ -803,3 +803,12 @@ func MetricsEqualIgnoreTimestamp(a *Metrics, b *Metrics) bool {
inodesUsed := a.InodesUsed == b.InodesUsed
return available && capacity && used && inodes && inodesFree && inodesUsed
}
+
+func ContainsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
+ for _, m := range modes {
+ if m == mode {
+ return true
+ }
+ }
+ return false
+}
diff --git a/pkg/volume/util.go b/pkg/volume/util.go
index b976ce947f5..afd28aa8f34 100644
--- a/pkg/volume/util.go
+++ b/pkg/volume/util.go
@@ -48,8 +48,8 @@ type RecycleEventRecorder func(eventtype, message string)
// attempted before returning.
//
// In case there is a pod with the same namespace+name already running, this
-// function assumes it's an older instance of the recycler pod and watches
-// this old pod instead of starting a new one.
+// function deletes it as it is not able to judge if it is an old recycler
+// or user has forged a fake recycler to block Kubernetes from recycling.//
//
// pod - the pod designed by a volume plugin to recycle the volume. pod.Name
// will be overwritten with unique name based on PV.Name.
@@ -81,20 +81,44 @@ func internalRecycleVolumeByWatchingPodUntilCompletion(pvName string, pod *v1.Po
_, err = recyclerClient.CreatePod(pod)
if err != nil {
if errors.IsAlreadyExists(err) {
- glog.V(5).Infof("old recycler pod %q found for volume", pod.Name)
+ deleteErr := recyclerClient.DeletePod(pod.Name, pod.Namespace)
+ if deleteErr != nil {
+ return fmt.Errorf("failed to delete old recycler pod %s/%s: %s", pod.Namespace, pod.Name, deleteErr)
+ }
+ // Recycler will try again and the old pod will be hopefuly deleted
+ // at that time.
+ return fmt.Errorf("old recycler pod found, will retry later")
} else {
return fmt.Errorf("unexpected error creating recycler pod: %+v\n", err)
}
}
- defer func(pod *v1.Pod) {
- glog.V(2).Infof("deleting recycler pod %s/%s", pod.Namespace, pod.Name)
- if err := recyclerClient.DeletePod(pod.Name, pod.Namespace); err != nil {
- glog.Errorf("failed to delete recycler pod %s/%s: %v", pod.Namespace, pod.Name, err)
- }
- }(pod)
+ err = waitForPod(pod, recyclerClient, podCh)
- // Now only the old pod or the new pod run. Watch it until it finishes
- // and send all events on the pod to the PV
+ // In all cases delete the recycler pod and log its result.
+ glog.V(2).Infof("deleting recycler pod %s/%s", pod.Namespace, pod.Name)
+ deleteErr := recyclerClient.DeletePod(pod.Name, pod.Namespace)
+ if deleteErr != nil {
+ glog.Errorf("failed to delete recycler pod %s/%s: %v", pod.Namespace, pod.Name, err)
+ }
+
+ // Returning recycler error is preferred, the pod will be deleted again on
+ // the next retry.
+ if err != nil {
+ return fmt.Errorf("failed to recycle volume: %s", err)
+ }
+
+ // Recycle succeeded but we failed to delete the recycler pod. Report it,
+ // the controller will re-try recycling the PV again shortly.
+ if deleteErr != nil {
+ return fmt.Errorf("failed to delete recycler pod: %s", deleteErr)
+ }
+
+ return nil
+}
+
+// waitForPod watches the pod it until it finishes and send all events on the
+// pod to the PV.
+func waitForPod(pod *v1.Pod, recyclerClient recyclerClient, podCh <-chan watch.Event) error {
for {
event, ok := <-podCh
if !ok {
diff --git a/pkg/volume/util_test.go b/pkg/volume/util_test.go
index 6eeb00a7543..8d3a0f12a70 100644
--- a/pkg/volume/util_test.go
+++ b/pkg/volume/util_test.go
@@ -128,7 +128,7 @@ func TestRecyclerPod(t *testing.T) {
{v1.EventTypeWarning, "Unable to mount volumes for pod \"recycler-for-podRecyclerFailure_default(3c9809e5-347c-11e6-a79b-3c970e965218)\": timeout expired waiting for volumes to attach/mount"},
{v1.EventTypeWarning, "Error syncing pod, skipping: timeout expired waiting for volumes to attach/mount for pod \"default\"/\"recycler-for-podRecyclerFailure\". list of unattached/unmounted"},
},
- expectedError: "Pod was active on the node longer than specified deadline",
+ expectedError: "failed to recycle volume: Pod was active on the node longer than specified deadline",
},
{
// Recycler pod gets deleted
@@ -143,32 +143,15 @@ func TestRecyclerPod(t *testing.T) {
expectedEvents: []mockEvent{
{v1.EventTypeNormal, "Successfully assigned recycler-for-podRecyclerDeleted to 127.0.0.1"},
},
- expectedError: "recycler pod was deleted",
+ expectedError: "failed to recycle volume: recycler pod was deleted",
},
{
// Another recycler pod is already running
- name: "RecyclerRunning",
- existingPod: newPod("podOldRecycler", v1.PodRunning, ""),
- createPod: newPod("podNewRecycler", v1.PodFailed, "mock message"),
- eventSequence: []watch.Event{
- // Old pod succeeds
- newPodEvent(watch.Modified, "podOldRecycler", v1.PodSucceeded, ""),
- },
- // No error = old pod succeeded. If the new pod was used, there
- // would be error with "mock message".
- expectedError: "",
- },
- {
- // Another recycler pod is already running and fails
- name: "FailedRecyclerRunning",
- existingPod: newPod("podOldRecycler", v1.PodRunning, ""),
- createPod: newPod("podNewRecycler", v1.PodFailed, "mock message"),
- eventSequence: []watch.Event{
- // Old pod failure
- newPodEvent(watch.Modified, "podOldRecycler", v1.PodFailed, "Pod was active on the node longer than specified deadline"),
- },
- // If the new pod was used, there would be error with "mock message".
- expectedError: "Pod was active on the node longer than specified deadline",
+ name: "RecyclerRunning",
+ existingPod: newPod("podOldRecycler", v1.PodRunning, ""),
+ createPod: newPod("podNewRecycler", v1.PodFailed, "mock message"),
+ eventSequence: []watch.Event{},
+ expectedError: "old recycler pod found, will retry later",
},
}
diff --git a/plugin/pkg/admission/gc/gc_admission_test.go b/plugin/pkg/admission/gc/gc_admission_test.go
index 99fdf606202..d5c31f64572 100644
--- a/plugin/pkg/admission/gc/gc_admission_test.go
+++ b/plugin/pkg/admission/gc/gc_admission_test.go
@@ -86,7 +86,7 @@ func newGCPermissionsEnforcement() (*gcPermissionsEnforcement, error) {
whiteList: whiteList,
}
- genericPluginInitializer, err := initializer.New(nil, nil, fakeAuthorizer{}, nil, nil, nil)
+ genericPluginInitializer, err := initializer.New(nil, nil, fakeAuthorizer{}, nil, nil)
if err != nil {
return nil, err
}
diff --git a/plugin/pkg/admission/imagepolicy/admission.go b/plugin/pkg/admission/imagepolicy/admission.go
index 2061561e8cc..97215ba02c4 100644
--- a/plugin/pkg/admission/imagepolicy/admission.go
+++ b/plugin/pkg/admission/imagepolicy/admission.go
@@ -31,7 +31,6 @@ import (
"k8s.io/api/imagepolicy/v1alpha1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
- kubeschema "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/cache"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/apiserver/pkg/admission"
@@ -110,11 +109,7 @@ func (a *imagePolicyWebhook) webhookError(pod *api.Pod, attributes admission.Att
func (a *imagePolicyWebhook) Admit(attributes admission.Attributes) (err error) {
// Ignore all calls to subresources or resources other than pods.
- allowedResources := map[kubeschema.GroupResource]bool{
- api.Resource("pods"): true,
- }
-
- if len(attributes.GetSubresource()) != 0 || !allowedResources[attributes.GetResource().GroupResource()] {
+ if attributes.GetSubresource() != "" || attributes.GetResource().GroupResource() != api.Resource("pods") {
return nil
}
diff --git a/plugin/pkg/admission/imagepolicy/admission_test.go b/plugin/pkg/admission/imagepolicy/admission_test.go
index 1ee2d76504c..e700cdaa616 100644
--- a/plugin/pkg/admission/imagepolicy/admission_test.go
+++ b/plugin/pkg/admission/imagepolicy/admission_test.go
@@ -404,6 +404,9 @@ func newImagePolicyWebhook(callbackURL string, clientCert, clientKey, ca []byte,
}
defer configFile.Close()
wh, err := NewImagePolicyWebhook(configFile)
+ if err != nil {
+ return nil, err
+ }
return wh.(*imagePolicyWebhook), err
}
diff --git a/plugin/pkg/admission/webhook/BUILD b/plugin/pkg/admission/webhook/BUILD
index 6495af040ce..ef77878e899 100644
--- a/plugin/pkg/admission/webhook/BUILD
+++ b/plugin/pkg/admission/webhook/BUILD
@@ -53,6 +53,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
+ "//vendor/k8s.io/client-go/rest:go_default_library",
],
)
diff --git a/plugin/pkg/admission/webhook/admission.go b/plugin/pkg/admission/webhook/admission.go
index f7155b5a658..3452cdb0d14 100644
--- a/plugin/pkg/admission/webhook/admission.go
+++ b/plugin/pkg/admission/webhook/admission.go
@@ -21,10 +21,7 @@ import (
"context"
"fmt"
"io"
- "net"
- "net/http"
"sync"
- "time"
"github.com/golang/glog"
@@ -45,6 +42,8 @@ import (
admissioninit "k8s.io/kubernetes/pkg/kubeapiserver/admission"
// install the clientgo admission API for use with api registry
+ "path"
+
_ "k8s.io/kubernetes/pkg/apis/admission/install"
)
@@ -103,19 +102,18 @@ type GenericAdmissionWebhook struct {
hookSource WebhookSource
serviceResolver admissioninit.ServiceResolver
negotiatedSerializer runtime.NegotiatedSerializer
- clientCert []byte
- clientKey []byte
- proxyTransport *http.Transport
+
+ restClientConfig *rest.Config
}
var (
_ = admissioninit.WantsServiceResolver(&GenericAdmissionWebhook{})
- _ = genericadmissioninit.WantsClientCert(&GenericAdmissionWebhook{})
+ _ = genericadmissioninit.WantsWebhookRESTClientConfig(&GenericAdmissionWebhook{})
_ = genericadmissioninit.WantsExternalKubeClientSet(&GenericAdmissionWebhook{})
)
-func (a *GenericAdmissionWebhook) SetProxyTransport(pt *http.Transport) {
- a.proxyTransport = pt
+func (a *GenericAdmissionWebhook) SetWebhookRESTClientConfig(in *rest.Config) {
+ a.restClientConfig = in
}
// SetServiceResolver sets a service resolver for the webhook admission plugin.
@@ -135,18 +133,13 @@ func (a *GenericAdmissionWebhook) SetScheme(scheme *runtime.Scheme) {
}
}
-func (a *GenericAdmissionWebhook) SetClientCert(cert, key []byte) {
- a.clientCert = cert
- a.clientKey = key
-}
-
func (a *GenericAdmissionWebhook) SetExternalKubeClientSet(client clientset.Interface) {
a.hookSource = configuration.NewExternalAdmissionHookConfigurationManager(client.Admissionregistration().ExternalAdmissionHookConfigurations())
}
func (a *GenericAdmissionWebhook) Validate() error {
- if a.clientCert == nil || a.clientKey == nil {
- return fmt.Errorf("the GenericAdmissionWebhook admission plugin requires a client certificate and the private key to be provided")
+ if a.restClientConfig == nil {
+ return fmt.Errorf("the GenericAdmissionWebhook admission plugin requires a restClientConfig to be provided")
}
if a.hookSource == nil {
return fmt.Errorf("the GenericAdmissionWebhook admission plugin requires a Kubernetes client to be provided")
@@ -198,7 +191,7 @@ func (a *GenericAdmissionWebhook) Admit(attr admission.Attributes) error {
return
}
- ignoreClientCallFailures := hook.FailurePolicy == nil || *hook.FailurePolicy == v1alpha1.Ignore
+ ignoreClientCallFailures := hook.FailurePolicy != nil && *hook.FailurePolicy == v1alpha1.Ignore
if callErr, ok := err.(*ErrCallingWebhook); ok {
if ignoreClientCallFailures {
glog.Warningf("Failed calling webhook, failing open %v: %v", hook.Name, callErr)
@@ -278,27 +271,12 @@ func (a *GenericAdmissionWebhook) hookClient(h *v1alpha1.ExternalAdmissionHook)
return nil, err
}
- var dial func(network, addr string) (net.Conn, error)
- if a.proxyTransport != nil && a.proxyTransport.Dial != nil {
- dial = a.proxyTransport.Dial
- }
-
// TODO: cache these instead of constructing one each time
- cfg := &rest.Config{
- Host: u.Host,
- APIPath: u.Path,
- TLSClientConfig: rest.TLSClientConfig{
- ServerName: h.ClientConfig.Service.Name + "." + h.ClientConfig.Service.Namespace + ".svc",
- CAData: h.ClientConfig.CABundle,
- CertData: a.clientCert,
- KeyData: a.clientKey,
- },
- UserAgent: "kube-apiserver-admission",
- Timeout: 30 * time.Second,
- ContentConfig: rest.ContentConfig{
- NegotiatedSerializer: a.negotiatedSerializer,
- },
- Dial: dial,
- }
+ cfg := rest.CopyConfig(a.restClientConfig)
+ cfg.Host = u.Host
+ cfg.APIPath = path.Join(u.Path, h.ClientConfig.URLPath)
+ cfg.TLSClientConfig.ServerName = h.ClientConfig.Service.Name + "." + h.ClientConfig.Service.Namespace + ".svc"
+ cfg.TLSClientConfig.CAData = h.ClientConfig.CABundle
+ cfg.ContentConfig.NegotiatedSerializer = a.negotiatedSerializer
return rest.UnversionedRESTClientFor(cfg)
}
diff --git a/plugin/pkg/admission/webhook/admission_test.go b/plugin/pkg/admission/webhook/admission_test.go
index 71076d0a813..82a1d28ff1e 100644
--- a/plugin/pkg/admission/webhook/admission_test.go
+++ b/plugin/pkg/admission/webhook/admission_test.go
@@ -32,6 +32,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authentication/user"
+ "k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/legacyscheme"
@@ -54,7 +55,6 @@ func (f *fakeHookSource) Run(stopCh <-chan struct{}) {}
type fakeServiceResolver struct {
base url.URL
- path string
}
func (f fakeServiceResolver) ResolveEndpoint(namespace, name string) (*url.URL, error) {
@@ -62,7 +62,6 @@ func (f fakeServiceResolver) ResolveEndpoint(namespace, name string) (*url.URL,
return nil, fmt.Errorf("couldn't resolve service location")
}
u := f.base
- u.Path = f.path
return &u, nil
}
@@ -91,8 +90,10 @@ func TestAdmit(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- wh.clientCert = clientCert
- wh.clientKey = clientKey
+ wh.restClientConfig = &rest.Config{}
+ wh.restClientConfig.TLSClientConfig.CAData = caCert
+ wh.restClientConfig.TLSClientConfig.CertData = clientCert
+ wh.restClientConfig.TLSClientConfig.KeyData = clientKey
// Set up a test object for the call
kind := api.Kind("Pod").WithVersion("v1")
@@ -128,13 +129,17 @@ func TestAdmit(t *testing.T) {
expectAllow bool
errorContains string
}
- ccfg := registrationv1alpha1.AdmissionHookClientConfig{
- Service: registrationv1alpha1.ServiceReference{
- Name: "webhook-test",
- Namespace: "default",
- },
- CABundle: caCert,
+ ccfg := func(urlPath string) registrationv1alpha1.AdmissionHookClientConfig {
+ return registrationv1alpha1.AdmissionHookClientConfig{
+ Service: registrationv1alpha1.ServiceReference{
+ Name: "webhook-test",
+ Namespace: "default",
+ },
+ URLPath: urlPath,
+ CABundle: caCert,
+ }
}
+
matchEverythingRules := []registrationv1alpha1.RuleWithOperations{{
Operations: []registrationv1alpha1.OperationType{registrationv1alpha1.OperationAll},
Rule: registrationv1alpha1.Rule{
@@ -152,109 +157,102 @@ func TestAdmit(t *testing.T) {
hookSource: fakeHookSource{
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
Name: "nomatch",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("disallow"),
Rules: []registrationv1alpha1.RuleWithOperations{{
Operations: []registrationv1alpha1.OperationType{registrationv1alpha1.Create},
}},
}},
},
- path: "disallow",
expectAllow: true,
},
"match & allow": {
hookSource: fakeHookSource{
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
Name: "allow",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("allow"),
Rules: matchEverythingRules,
}},
},
- path: "allow",
expectAllow: true,
},
"match & disallow": {
hookSource: fakeHookSource{
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
Name: "disallow",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("disallow"),
Rules: matchEverythingRules,
}},
},
- path: "disallow",
errorContains: "without explanation",
},
"match & disallow ii": {
hookSource: fakeHookSource{
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
Name: "disallowReason",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("disallowReason"),
Rules: matchEverythingRules,
}},
},
- path: "disallowReason",
errorContains: "you shall not pass",
},
"match & fail (but allow because fail open)": {
hookSource: fakeHookSource{
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
Name: "internalErr A",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("internalErr"),
Rules: matchEverythingRules,
FailurePolicy: &policyIgnore,
}, {
Name: "internalErr B",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("internalErr"),
Rules: matchEverythingRules,
FailurePolicy: &policyIgnore,
}, {
Name: "internalErr C",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("internalErr"),
Rules: matchEverythingRules,
FailurePolicy: &policyIgnore,
}},
},
- path: "internalErr",
expectAllow: true,
},
- "match & fail (but allow because fail open on nil)": {
+ "match & fail (but disallow because fail closed on nil)": {
hookSource: fakeHookSource{
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
Name: "internalErr A",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("internalErr"),
Rules: matchEverythingRules,
}, {
Name: "internalErr B",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("internalErr"),
Rules: matchEverythingRules,
}, {
Name: "internalErr C",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("internalErr"),
Rules: matchEverythingRules,
}},
},
- path: "internalErr",
- expectAllow: true,
+ expectAllow: false,
},
"match & fail (but fail because fail closed)": {
hookSource: fakeHookSource{
hooks: []registrationv1alpha1.ExternalAdmissionHook{{
Name: "internalErr A",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("internalErr"),
Rules: matchEverythingRules,
FailurePolicy: &policyFail,
}, {
Name: "internalErr B",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("internalErr"),
Rules: matchEverythingRules,
FailurePolicy: &policyFail,
}, {
Name: "internalErr C",
- ClientConfig: ccfg,
+ ClientConfig: ccfg("internalErr"),
Rules: matchEverythingRules,
FailurePolicy: &policyFail,
}},
},
- path: "internalErr",
expectAllow: false,
},
}
@@ -262,7 +260,7 @@ func TestAdmit(t *testing.T) {
for name, tt := range table {
t.Run(name, func(t *testing.T) {
wh.hookSource = &tt.hookSource
- wh.serviceResolver = fakeServiceResolver{base: *serverURL, path: tt.path}
+ wh.serviceResolver = fakeServiceResolver{base: *serverURL}
wh.SetScheme(legacyscheme.Scheme)
err = wh.Admit(admission.NewAttributesRecord(&object, &oldObject, kind, namespace, name, resource, subResource, operation, &userInfo))
diff --git a/plugin/pkg/scheduler/algorithm/predicates/predicates.go b/plugin/pkg/scheduler/algorithm/predicates/predicates.go
index 1463010633a..25f97f3353e 100644
--- a/plugin/pkg/scheduler/algorithm/predicates/predicates.go
+++ b/plugin/pkg/scheduler/algorithm/predicates/predicates.go
@@ -49,7 +49,7 @@ const (
// IMPORTANT NOTE for predicate developers:
// We are using cached predicate result for pods belonging to the same equivalence class.
-// So when updating a existing predicate, you should consider whether your change will introduce new
+// So when updating an existing predicate, you should consider whether your change will introduce new
// dependency to attributes of any API object like Pod, Node, Service etc.
// If yes, you are expected to invalidate the cached predicate result for related API object change.
// For example:
diff --git a/plugin/pkg/scheduler/algorithm/predicates/predicates_test.go b/plugin/pkg/scheduler/algorithm/predicates/predicates_test.go
index e19a4a23a38..be45e373609 100644
--- a/plugin/pkg/scheduler/algorithm/predicates/predicates_test.go
+++ b/plugin/pkg/scheduler/algorithm/predicates/predicates_test.go
@@ -663,7 +663,7 @@ func TestGetUsedPorts(t *testing.T) {
}
}
-func TestDiskConflicts(t *testing.T) {
+func TestGCEDiskConflicts(t *testing.T) {
volState := v1.PodSpec{
Volumes: []v1.Volume{
{
diff --git a/plugin/pkg/scheduler/api/validation/validation.go b/plugin/pkg/scheduler/api/validation/validation.go
index 620a0343ed7..cec33b1955b 100644
--- a/plugin/pkg/scheduler/api/validation/validation.go
+++ b/plugin/pkg/scheduler/api/validation/validation.go
@@ -36,7 +36,7 @@ func ValidatePolicy(policy schedulerapi.Policy) error {
binders := 0
for _, extender := range policy.ExtenderConfigs {
- if extender.Weight <= 0 {
+ if len(extender.PrioritizeVerb) > 0 && extender.Weight <= 0 {
validationErrors = append(validationErrors, fmt.Errorf("Priority for extender %s should have a positive weight applied to it", extender.URLPrefix))
}
if extender.BindVerb != "" {
diff --git a/plugin/pkg/scheduler/api/validation/validation_test.go b/plugin/pkg/scheduler/api/validation/validation_test.go
index b7a6cd2ca9a..b0b01a8573b 100644
--- a/plugin/pkg/scheduler/api/validation/validation_test.go
+++ b/plugin/pkg/scheduler/api/validation/validation_test.go
@@ -50,18 +50,22 @@ func TestValidatePolicy(t *testing.T) {
expected: errors.New("Priority WeightPriority should have a positive weight applied to it or it has overflown"),
},
{
- policy: api.Policy{ExtenderConfigs: []api.ExtenderConfig{{URLPrefix: "http://127.0.0.1:8081/extender", FilterVerb: "filter", Weight: 2}}},
+ policy: api.Policy{ExtenderConfigs: []api.ExtenderConfig{{URLPrefix: "http://127.0.0.1:8081/extender", PrioritizeVerb: "prioritize", Weight: 2}}},
expected: nil,
},
{
- policy: api.Policy{ExtenderConfigs: []api.ExtenderConfig{{URLPrefix: "http://127.0.0.1:8081/extender", FilterVerb: "filter", Weight: -2}}},
+ policy: api.Policy{ExtenderConfigs: []api.ExtenderConfig{{URLPrefix: "http://127.0.0.1:8081/extender", PrioritizeVerb: "prioritize", Weight: -2}}},
expected: errors.New("Priority for extender http://127.0.0.1:8081/extender should have a positive weight applied to it"),
},
+ {
+ policy: api.Policy{ExtenderConfigs: []api.ExtenderConfig{{URLPrefix: "http://127.0.0.1:8081/extender", FilterVerb: "filter"}}},
+ expected: nil,
+ },
{
policy: api.Policy{
ExtenderConfigs: []api.ExtenderConfig{
- {URLPrefix: "http://127.0.0.1:8081/extender", BindVerb: "bind", Weight: 2},
- {URLPrefix: "http://127.0.0.1:8082/extender", BindVerb: "bind", Weight: 2},
+ {URLPrefix: "http://127.0.0.1:8081/extender", BindVerb: "bind"},
+ {URLPrefix: "http://127.0.0.1:8082/extender", BindVerb: "bind"},
}},
expected: errors.New("Only one extender can implement bind, found 2"),
},
diff --git a/staging/BUILD b/staging/BUILD
index 7b541e908a5..d1f33145250 100644
--- a/staging/BUILD
+++ b/staging/BUILD
@@ -208,6 +208,7 @@ filegroup(
"//staging/src/k8s.io/metrics/pkg/client/clientset_generated/clientset:all-srcs",
"//staging/src/k8s.io/metrics/pkg/client/custom_metrics:all-srcs",
"//staging/src/k8s.io/sample-apiserver:all-srcs",
+ "//staging/src/k8s.io/sample-controller:all-srcs",
],
tags = ["automanaged"],
)
diff --git a/staging/README.md b/staging/README.md
index 177f37e23c3..98d47d18b57 100644
--- a/staging/README.md
+++ b/staging/README.md
@@ -15,6 +15,7 @@ Repositories currently staged here:
- [`k8s.io/code-generator`](https://github.com/kubernetes/code-generator)
- [`k8s.io/metrics`](https://github.com/kubernetes/metrics)
- [`k8s.io/sample-apiserver`](https://github.com/kubernetes/sample-apiserver)
+- [`k8s.io/sample-controller`](https://github.com/kubernetes/sample-controller)
The code in the staging/ directory is authoritative, i.e. the only copy of the
code. You can directly modify such code.
diff --git a/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go b/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go
index 6a1977f8331..4c66de146ca 100644
--- a/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go
+++ b/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.pb.go
@@ -151,6 +151,10 @@ func (m *AdmissionHookClientConfig) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintGenerated(dAtA, i, uint64(len(m.CABundle)))
i += copy(dAtA[i:], m.CABundle)
}
+ dAtA[i] = 0x1a
+ i++
+ i = encodeVarintGenerated(dAtA, i, uint64(len(m.URLPath)))
+ i += copy(dAtA[i:], m.URLPath)
return i, nil
}
@@ -554,6 +558,8 @@ func (m *AdmissionHookClientConfig) Size() (n int) {
l = len(m.CABundle)
n += 1 + l + sovGenerated(uint64(l))
}
+ l = len(m.URLPath)
+ n += 1 + l + sovGenerated(uint64(l))
return n
}
@@ -715,6 +721,7 @@ func (this *AdmissionHookClientConfig) String() string {
s := strings.Join([]string{`&AdmissionHookClientConfig{`,
`Service:` + strings.Replace(strings.Replace(this.Service.String(), "ServiceReference", "ServiceReference", 1), `&`, ``, 1) + `,`,
`CABundle:` + valueToStringGenerated(this.CABundle) + `,`,
+ `URLPath:` + fmt.Sprintf("%v", this.URLPath) + `,`,
`}`,
}, "")
return s
@@ -919,6 +926,35 @@ func (m *AdmissionHookClientConfig) Unmarshal(dAtA []byte) error {
m.CABundle = []byte{}
}
iNdEx = postIndex
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field URLPath", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ 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 ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.URLPath = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -2128,60 +2164,61 @@ func init() {
}
var fileDescriptorGenerated = []byte{
- // 871 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcd, 0x8b, 0x23, 0x45,
- 0x14, 0x4f, 0x65, 0x32, 0x6c, 0x52, 0x49, 0xd8, 0xdd, 0x42, 0x97, 0x38, 0x48, 0x77, 0xe8, 0xc3,
- 0x12, 0x11, 0xbb, 0x9d, 0x51, 0x16, 0x41, 0x44, 0xa7, 0xc7, 0xaf, 0x81, 0xfd, 0x18, 0xcb, 0x45,
- 0x41, 0x3c, 0x58, 0xe9, 0xbc, 0x24, 0x65, 0xfa, 0x8b, 0xaa, 0xea, 0xe0, 0x78, 0x10, 0x2f, 0xde,
- 0x05, 0x2f, 0x5e, 0xbd, 0x79, 0xf1, 0xff, 0x98, 0xe3, 0x1e, 0xf7, 0x14, 0x9c, 0x16, 0xbc, 0x08,
- 0xfe, 0x01, 0x73, 0x92, 0xfe, 0x4a, 0x3a, 0x9b, 0x84, 0x4d, 0x5c, 0x98, 0x5b, 0xea, 0xf7, 0xea,
- 0xf7, 0xde, 0xef, 0xfd, 0xf2, 0x5e, 0x35, 0xa6, 0x93, 0x77, 0xa4, 0xc9, 0x03, 0x6b, 0x12, 0xf5,
- 0x41, 0xf8, 0xa0, 0x40, 0x5a, 0x53, 0xf0, 0x07, 0x81, 0xb0, 0xf2, 0x00, 0x0b, 0xb9, 0xc5, 0x06,
- 0x1e, 0x97, 0x92, 0x07, 0xbe, 0x80, 0x11, 0x97, 0x4a, 0x30, 0xc5, 0x03, 0xdf, 0x9a, 0x1e, 0x32,
- 0x37, 0x1c, 0xb3, 0x43, 0x6b, 0x04, 0x3e, 0x08, 0xa6, 0x60, 0x60, 0x86, 0x22, 0x50, 0x01, 0x79,
- 0x2d, 0xa3, 0x9a, 0x2c, 0xe4, 0xe6, 0x5a, 0xaa, 0x59, 0x50, 0x0f, 0xde, 0x18, 0x71, 0x35, 0x8e,
- 0xfa, 0xa6, 0x13, 0x78, 0xd6, 0x28, 0x18, 0x05, 0x56, 0x9a, 0xa1, 0x1f, 0x0d, 0xd3, 0x53, 0x7a,
- 0x48, 0x7f, 0x65, 0x99, 0x0f, 0xde, 0x5e, 0x88, 0xf2, 0x98, 0x33, 0xe6, 0x3e, 0x88, 0x73, 0x2b,
- 0x9c, 0x8c, 0x12, 0x40, 0x5a, 0x1e, 0x28, 0x66, 0x4d, 0x57, 0xf4, 0x1c, 0x58, 0x9b, 0x58, 0x22,
- 0xf2, 0x15, 0xf7, 0x60, 0x85, 0x70, 0xef, 0x79, 0x04, 0xe9, 0x8c, 0xc1, 0x63, 0x2b, 0xbc, 0xb7,
- 0x36, 0xf1, 0x22, 0xc5, 0x5d, 0x8b, 0xfb, 0x4a, 0x2a, 0xf1, 0x2c, 0xc9, 0xf8, 0x03, 0xe1, 0x57,
- 0x8e, 0x0b, 0x97, 0x3e, 0x0d, 0x82, 0xc9, 0x89, 0xcb, 0xc1, 0x57, 0x27, 0x81, 0x3f, 0xe4, 0x23,
- 0x32, 0xc4, 0x37, 0x24, 0x88, 0x29, 0x77, 0xa0, 0x83, 0xba, 0xa8, 0xd7, 0x3c, 0x7a, 0xd7, 0xdc,
- 0xda, 0x5d, 0xf3, 0xf3, 0x8c, 0x49, 0x61, 0x08, 0x02, 0x7c, 0x07, 0xec, 0x9b, 0x17, 0x33, 0xbd,
- 0x12, 0xcf, 0xf4, 0x1b, 0x45, 0xa4, 0x48, 0x4e, 0x7a, 0xb8, 0xee, 0x30, 0x3b, 0xf2, 0x07, 0x2e,
- 0x74, 0xaa, 0x5d, 0xd4, 0x6b, 0xd9, 0xad, 0x78, 0xa6, 0xd7, 0x4f, 0x8e, 0x33, 0x8c, 0xce, 0xa3,
- 0xc6, 0x3f, 0x55, 0xfc, 0xf2, 0x47, 0xdf, 0x29, 0x10, 0x3e, 0x73, 0x97, 0x74, 0x93, 0x2e, 0xae,
- 0xf9, 0xcc, 0xcb, 0x84, 0x36, 0xec, 0x56, 0x5e, 0xab, 0xf6, 0x90, 0x79, 0x40, 0xd3, 0x08, 0xf9,
- 0x01, 0xb7, 0x9c, 0x52, 0x77, 0x69, 0xa5, 0xe6, 0xd1, 0x87, 0x3b, 0xb4, 0xb4, 0xd1, 0x29, 0xfb,
- 0xa5, 0xbc, 0x5e, 0xab, 0x8c, 0xd2, 0xa5, 0x7a, 0xa4, 0x8f, 0xf7, 0x45, 0xe4, 0x82, 0xec, 0xec,
- 0x75, 0xf7, 0x7a, 0xcd, 0xa3, 0xf7, 0x76, 0x28, 0x4c, 0x23, 0x17, 0xbe, 0xe4, 0x6a, 0xfc, 0x28,
- 0x84, 0x2c, 0x24, 0xed, 0x76, 0x5e, 0x71, 0x3f, 0x89, 0x49, 0x9a, 0xa5, 0x26, 0xf7, 0x71, 0x7b,
- 0xc8, 0xb8, 0x1b, 0x09, 0x38, 0x0b, 0x5c, 0xee, 0x9c, 0x77, 0x6a, 0xa9, 0x1d, 0x77, 0xe3, 0x99,
- 0xde, 0xfe, 0xb8, 0x1c, 0xb8, 0x9a, 0xe9, 0xb7, 0x97, 0x80, 0xc7, 0xe7, 0x21, 0xd0, 0x65, 0xb2,
- 0xf1, 0x5b, 0x15, 0x1b, 0x6b, 0xdd, 0xce, 0x3a, 0x8a, 0x32, 0x2d, 0xe4, 0x1b, 0x5c, 0x4f, 0xa6,
- 0x7f, 0xc0, 0x14, 0xcb, 0xe7, 0xe4, 0xcd, 0x52, 0x6f, 0xf3, 0x61, 0x34, 0xc3, 0xc9, 0x28, 0x01,
- 0xa4, 0x99, 0xdc, 0x36, 0xa7, 0x87, 0xe6, 0xa3, 0xfe, 0xb7, 0xe0, 0xa8, 0x07, 0xa0, 0x98, 0x4d,
- 0xf2, 0x76, 0xf0, 0x02, 0xa3, 0xf3, 0xac, 0xe4, 0x57, 0x84, 0xef, 0xc0, 0x3a, 0x21, 0xb2, 0x53,
- 0x4d, 0xcd, 0xfc, 0x60, 0x07, 0x33, 0xd7, 0x76, 0x64, 0x6b, 0xb9, 0x80, 0x3b, 0x6b, 0xc3, 0x92,
- 0x6e, 0xa8, 0x6f, 0x5c, 0x21, 0x7c, 0xf7, 0xf9, 0x1e, 0xdd, 0xe7, 0x52, 0x91, 0xaf, 0x57, 0x7c,
- 0x32, 0xb7, 0xf3, 0x29, 0x61, 0xa7, 0x2e, 0xdd, 0xca, 0x45, 0xd6, 0x0b, 0xa4, 0xe4, 0x91, 0xc0,
- 0xfb, 0x5c, 0x81, 0x57, 0x38, 0xf2, 0xe0, 0x45, 0x1d, 0x59, 0xd2, 0xbf, 0x18, 0xb7, 0xd3, 0xa4,
- 0x06, 0xcd, 0x4a, 0x19, 0x3f, 0x21, 0xdc, 0x3c, 0xf5, 0xb9, 0xe2, 0xcc, 0xe5, 0xdf, 0x83, 0xd8,
- 0x62, 0x09, 0x1f, 0x17, 0x4b, 0x90, 0xa9, 0xb4, 0x76, 0x5c, 0x82, 0xf5, 0x63, 0x6f, 0xfc, 0x8b,
- 0x70, 0xa7, 0xa4, 0xe3, 0xba, 0xc7, 0x33, 0xc4, 0x2d, 0xbe, 0xa8, 0x5e, 0xf4, 0x76, 0x6f, 0x87,
- 0xde, 0x4a, 0xe2, 0x17, 0x6f, 0x49, 0x09, 0x94, 0x74, 0xa9, 0x82, 0xf1, 0x37, 0xc2, 0xaf, 0x6e,
- 0x6a, 0xf8, 0x1a, 0x66, 0x6d, 0xbc, 0x3c, 0x6b, 0x27, 0xff, 0xaf, 0xd3, 0x6d, 0x26, 0xec, 0x17,
- 0x84, 0x6b, 0xc9, 0x5f, 0x4d, 0x5e, 0xc7, 0x0d, 0x16, 0xf2, 0x4f, 0x44, 0x10, 0x85, 0xb2, 0x83,
- 0xba, 0x7b, 0xbd, 0x86, 0xdd, 0x8e, 0x67, 0x7a, 0xe3, 0xf8, 0xec, 0x34, 0x03, 0xe9, 0x22, 0x4e,
- 0x0e, 0x71, 0x93, 0x85, 0xfc, 0x0b, 0x10, 0x89, 0x8e, 0x4c, 0x65, 0xc3, 0xbe, 0x19, 0xcf, 0xf4,
- 0xe6, 0xf1, 0xd9, 0x69, 0x01, 0xd3, 0xf2, 0x9d, 0x24, 0xbf, 0x00, 0x19, 0x44, 0xc2, 0xc9, 0x5f,
- 0xe8, 0x3c, 0x3f, 0x2d, 0x40, 0xba, 0x88, 0x1b, 0xbf, 0x23, 0x4c, 0x56, 0xdf, 0x64, 0xf2, 0x3e,
- 0xc6, 0xc1, 0xfc, 0x94, 0x8b, 0xd4, 0xd3, 0xa9, 0x99, 0xa3, 0x57, 0x33, 0xbd, 0x3d, 0x3f, 0xa5,
- 0x6f, 0x6e, 0x89, 0x42, 0x3e, 0xc3, 0xb5, 0x64, 0xa0, 0xf3, 0x4f, 0xd3, 0xce, 0xcb, 0x31, 0x5f,
- 0xb8, 0xe4, 0x44, 0xd3, 0x54, 0x06, 0xe0, 0x5b, 0xcf, 0x7e, 0x89, 0x89, 0x85, 0x1b, 0xc9, 0x32,
- 0xca, 0x90, 0x39, 0xc5, 0xae, 0xde, 0xce, 0xa9, 0x8d, 0x87, 0x45, 0x80, 0x2e, 0xee, 0xcc, 0xf7,
- 0xba, 0xba, 0x69, 0xaf, 0x6d, 0xf3, 0xe2, 0x52, 0xab, 0x3c, 0xb9, 0xd4, 0x2a, 0x4f, 0x2f, 0xb5,
- 0xca, 0x8f, 0xb1, 0x86, 0x2e, 0x62, 0x0d, 0x3d, 0x89, 0x35, 0xf4, 0x34, 0xd6, 0xd0, 0x9f, 0xb1,
- 0x86, 0x7e, 0xfe, 0x4b, 0xab, 0x7c, 0x55, 0x2f, 0xf4, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0xe7,
- 0xb5, 0x5f, 0xd5, 0xfb, 0x09, 0x00, 0x00,
+ // 893 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcf, 0x8b, 0x23, 0x45,
+ 0x14, 0x4e, 0x65, 0x32, 0x4c, 0x52, 0x49, 0xd8, 0xdd, 0x42, 0x97, 0x38, 0x48, 0x27, 0xf4, 0x61,
+ 0xc9, 0x22, 0x76, 0x3b, 0xa3, 0x2c, 0x82, 0x88, 0x4e, 0x8f, 0xbf, 0x06, 0x66, 0x77, 0xc7, 0x72,
+ 0x55, 0x10, 0x0f, 0x56, 0x3a, 0x2f, 0x49, 0x99, 0xfe, 0x45, 0x55, 0x75, 0x70, 0x3c, 0x88, 0x17,
+ 0xef, 0x82, 0x17, 0xaf, 0xde, 0xfc, 0x53, 0xe6, 0xb8, 0xc7, 0x39, 0x05, 0xa7, 0x05, 0x2f, 0x82,
+ 0x7f, 0xc0, 0x9c, 0xa4, 0x7f, 0xa5, 0x3b, 0x9b, 0x84, 0x9d, 0x28, 0xec, 0x2d, 0xf5, 0xbd, 0xfa,
+ 0xde, 0xfb, 0xde, 0x97, 0xf7, 0xaa, 0x31, 0x9d, 0xbe, 0x2d, 0x0d, 0xee, 0x9b, 0xd3, 0x70, 0x00,
+ 0xc2, 0x03, 0x05, 0xd2, 0x9c, 0x81, 0x37, 0xf4, 0x85, 0x99, 0x05, 0x58, 0xc0, 0x4d, 0x36, 0x74,
+ 0xb9, 0x94, 0xdc, 0xf7, 0x04, 0x8c, 0xb9, 0x54, 0x82, 0x29, 0xee, 0x7b, 0xe6, 0xec, 0x80, 0x39,
+ 0xc1, 0x84, 0x1d, 0x98, 0x63, 0xf0, 0x40, 0x30, 0x05, 0x43, 0x23, 0x10, 0xbe, 0xf2, 0xc9, 0xfd,
+ 0x94, 0x6a, 0xb0, 0x80, 0x1b, 0x6b, 0xa9, 0x46, 0x4e, 0xdd, 0x7f, 0x7d, 0xcc, 0xd5, 0x24, 0x1c,
+ 0x18, 0xb6, 0xef, 0x9a, 0x63, 0x7f, 0xec, 0x9b, 0x49, 0x86, 0x41, 0x38, 0x4a, 0x4e, 0xc9, 0x21,
+ 0xf9, 0x95, 0x66, 0xde, 0x7f, 0xab, 0x10, 0xe5, 0x32, 0x7b, 0xc2, 0x3d, 0x10, 0xe7, 0x66, 0x30,
+ 0x1d, 0xc7, 0x80, 0x34, 0x5d, 0x50, 0xcc, 0x9c, 0xad, 0xe8, 0xd9, 0x37, 0x37, 0xb1, 0x44, 0xe8,
+ 0x29, 0xee, 0xc2, 0x0a, 0xe1, 0xc1, 0xf3, 0x08, 0xd2, 0x9e, 0x80, 0xcb, 0x56, 0x78, 0x6f, 0x6e,
+ 0xe2, 0x85, 0x8a, 0x3b, 0x26, 0xf7, 0x94, 0x54, 0xe2, 0x59, 0x92, 0x7e, 0x89, 0xf0, 0x2b, 0x47,
+ 0xb9, 0x4b, 0x9f, 0xf8, 0xfe, 0xf4, 0xd8, 0xe1, 0xe0, 0xa9, 0x63, 0xdf, 0x1b, 0xf1, 0x31, 0x19,
+ 0xe1, 0x3d, 0x09, 0x62, 0xc6, 0x6d, 0xe8, 0xa0, 0x1e, 0xea, 0x37, 0x0f, 0xdf, 0x31, 0x6e, 0xec,
+ 0xae, 0xf1, 0x59, 0xca, 0xa4, 0x30, 0x02, 0x01, 0x9e, 0x0d, 0xd6, 0xad, 0x8b, 0x79, 0xb7, 0x12,
+ 0xcd, 0xbb, 0x7b, 0x79, 0x24, 0x4f, 0x4e, 0xfa, 0xb8, 0x6e, 0x33, 0x2b, 0xf4, 0x86, 0x0e, 0x74,
+ 0xaa, 0x3d, 0xd4, 0x6f, 0x59, 0xad, 0x68, 0xde, 0xad, 0x1f, 0x1f, 0xa5, 0x18, 0x5d, 0x44, 0xc9,
+ 0x7d, 0xbc, 0x17, 0x0a, 0xe7, 0x8c, 0xa9, 0x49, 0x67, 0xa7, 0x87, 0xfa, 0x8d, 0x22, 0xe9, 0xe7,
+ 0xf4, 0x34, 0x86, 0x69, 0x1e, 0xd7, 0xff, 0xae, 0xe2, 0x97, 0x3f, 0xfc, 0x4e, 0x81, 0xf0, 0x98,
+ 0xb3, 0xd4, 0x22, 0xe9, 0xe1, 0x9a, 0xc7, 0xdc, 0xb4, 0xa7, 0x86, 0xd5, 0xca, 0x32, 0xd4, 0x1e,
+ 0x31, 0x17, 0x68, 0x12, 0x21, 0x3f, 0xe0, 0x96, 0x5d, 0x32, 0x22, 0x11, 0xd5, 0x3c, 0xfc, 0x60,
+ 0x8b, 0xee, 0x37, 0x9a, 0x6a, 0xbd, 0x94, 0xd5, 0x6b, 0x95, 0x51, 0xba, 0x54, 0x8f, 0x0c, 0xf0,
+ 0xae, 0x08, 0x1d, 0x90, 0x9d, 0x9d, 0xde, 0x4e, 0xbf, 0x79, 0xf8, 0xee, 0x16, 0x85, 0x69, 0xe8,
+ 0xc0, 0x97, 0x5c, 0x4d, 0x1e, 0x07, 0x90, 0x86, 0xa4, 0xd5, 0xce, 0x2a, 0xee, 0xc6, 0x31, 0x49,
+ 0xd3, 0xd4, 0xe4, 0x14, 0xb7, 0x47, 0x8c, 0x3b, 0xa1, 0x80, 0x33, 0xdf, 0xe1, 0xf6, 0x79, 0xa7,
+ 0x96, 0xd8, 0x71, 0x2f, 0x9a, 0x77, 0xdb, 0x1f, 0x95, 0x03, 0xd7, 0xf3, 0xee, 0x9d, 0x25, 0xe0,
+ 0xc9, 0x79, 0x00, 0x74, 0x99, 0xac, 0xff, 0x56, 0xc5, 0xfa, 0x5a, 0xb7, 0xd3, 0x8e, 0xc2, 0x54,
+ 0x0b, 0xf9, 0x06, 0xd7, 0xe3, 0x45, 0x19, 0x32, 0xc5, 0xb2, 0x91, 0x7a, 0xa3, 0xd4, 0xdb, 0x62,
+ 0x6e, 0x8d, 0x60, 0x3a, 0x8e, 0x01, 0x69, 0xc4, 0xb7, 0x8d, 0xd9, 0x81, 0xf1, 0x78, 0xf0, 0x2d,
+ 0xd8, 0xea, 0x21, 0x28, 0x66, 0x91, 0xac, 0x1d, 0x5c, 0x60, 0x74, 0x91, 0x95, 0xfc, 0x8a, 0xf0,
+ 0x5d, 0x58, 0x27, 0x44, 0x76, 0xaa, 0x89, 0x99, 0xef, 0x6f, 0x61, 0xe6, 0xda, 0x8e, 0x2c, 0x2d,
+ 0x13, 0x70, 0x77, 0x6d, 0x58, 0xd2, 0x0d, 0xf5, 0xf5, 0x6b, 0x84, 0xef, 0x3d, 0xdf, 0xa3, 0x53,
+ 0x2e, 0x15, 0xf9, 0x7a, 0xc5, 0x27, 0xe3, 0x66, 0x3e, 0xc5, 0xec, 0xc4, 0xa5, 0xdb, 0x99, 0xc8,
+ 0x7a, 0x8e, 0x94, 0x3c, 0x12, 0x78, 0x97, 0x2b, 0x70, 0x73, 0x47, 0x1e, 0xfe, 0x5f, 0x47, 0x96,
+ 0xf4, 0x17, 0xe3, 0x76, 0x12, 0xd7, 0xa0, 0x69, 0x29, 0xfd, 0x27, 0x84, 0x9b, 0x27, 0x1e, 0x57,
+ 0x9c, 0x39, 0xfc, 0x7b, 0x10, 0x37, 0x58, 0xc2, 0x27, 0xf9, 0x12, 0xa4, 0x2a, 0xcd, 0x2d, 0x97,
+ 0x60, 0xfd, 0xd8, 0xeb, 0xff, 0x20, 0xdc, 0x29, 0xe9, 0x78, 0xd1, 0xe3, 0x19, 0xe0, 0x16, 0x2f,
+ 0xaa, 0xe7, 0xbd, 0x3d, 0xd8, 0xa2, 0xb7, 0x92, 0xf8, 0xe2, 0x2d, 0x29, 0x81, 0x92, 0x2e, 0x55,
+ 0xd0, 0xff, 0x42, 0xf8, 0xd5, 0x4d, 0x0d, 0xbf, 0x80, 0x59, 0x9b, 0x2c, 0xcf, 0xda, 0xf1, 0x7f,
+ 0xeb, 0xf4, 0x26, 0x13, 0xf6, 0x0b, 0xc2, 0xb5, 0xf8, 0xaf, 0x26, 0xaf, 0xe1, 0x06, 0x0b, 0xf8,
+ 0xc7, 0xc2, 0x0f, 0x03, 0xd9, 0x41, 0xbd, 0x9d, 0x7e, 0xc3, 0x6a, 0x47, 0xf3, 0x6e, 0xe3, 0xe8,
+ 0xec, 0x24, 0x05, 0x69, 0x11, 0x27, 0x07, 0xb8, 0xc9, 0x02, 0xfe, 0x05, 0x88, 0x58, 0x47, 0xaa,
+ 0xb2, 0x61, 0xdd, 0x8a, 0xe6, 0xdd, 0xe6, 0xd1, 0xd9, 0x49, 0x0e, 0xd3, 0xf2, 0x9d, 0x38, 0xbf,
+ 0x00, 0xe9, 0x87, 0xc2, 0xce, 0x5e, 0xe8, 0x2c, 0x3f, 0xcd, 0x41, 0x5a, 0xc4, 0xf5, 0xdf, 0x11,
+ 0x26, 0xab, 0x6f, 0x32, 0x79, 0x0f, 0x63, 0x7f, 0x71, 0xca, 0x44, 0x76, 0x93, 0xa9, 0x59, 0xa0,
+ 0xd7, 0xf3, 0x6e, 0x7b, 0x71, 0x4a, 0xde, 0xdc, 0x12, 0x85, 0x7c, 0x8a, 0x6b, 0xf1, 0x40, 0x67,
+ 0x9f, 0xa6, 0xad, 0x97, 0x63, 0xb1, 0x70, 0xf1, 0x89, 0x26, 0xa9, 0x74, 0xc0, 0xb7, 0x9f, 0xfd,
+ 0x68, 0x13, 0x13, 0x37, 0xe2, 0x65, 0x94, 0x01, 0xb3, 0xf3, 0x5d, 0xbd, 0x93, 0x51, 0x1b, 0x8f,
+ 0xf2, 0x00, 0x2d, 0xee, 0x2c, 0xf6, 0xba, 0xba, 0x69, 0xaf, 0x2d, 0xe3, 0xe2, 0x4a, 0xab, 0x3c,
+ 0xbd, 0xd2, 0x2a, 0x97, 0x57, 0x5a, 0xe5, 0xc7, 0x48, 0x43, 0x17, 0x91, 0x86, 0x9e, 0x46, 0x1a,
+ 0xba, 0x8c, 0x34, 0xf4, 0x47, 0xa4, 0xa1, 0x9f, 0xff, 0xd4, 0x2a, 0x5f, 0xd5, 0x73, 0xbd, 0xff,
+ 0x06, 0x00, 0x00, 0xff, 0xff, 0x01, 0xf7, 0xd5, 0xa0, 0x26, 0x0a, 0x00, 0x00,
}
diff --git a/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.proto b/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.proto
index 5b0d4f0065b..b5ad69cd789 100644
--- a/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.proto
+++ b/staging/src/k8s.io/api/admissionregistration/v1alpha1/generated.proto
@@ -38,6 +38,9 @@ message AdmissionHookClientConfig {
// Required
optional ServiceReference service = 1;
+ // URLPath is an optional field that specifies the URL path to use when posting the AdmissionReview object.
+ optional string urlPath = 3;
+
// CABundle is a PEM encoded CA bundle which will be used to validate webhook's server certificate.
// Required
optional bytes caBundle = 2;
diff --git a/staging/src/k8s.io/api/admissionregistration/v1alpha1/types.go b/staging/src/k8s.io/api/admissionregistration/v1alpha1/types.go
index d4827e59d33..5e8541f4fa5 100644
--- a/staging/src/k8s.io/api/admissionregistration/v1alpha1/types.go
+++ b/staging/src/k8s.io/api/admissionregistration/v1alpha1/types.go
@@ -203,6 +203,10 @@ type AdmissionHookClientConfig struct {
// ports open, port 443 will be used if it is open, otherwise it is an error.
// Required
Service ServiceReference `json:"service" protobuf:"bytes,1,opt,name=service"`
+
+ // URLPath is an optional field that specifies the URL path to use when posting the AdmissionReview object.
+ URLPath string `json:"urlPath" protobuf:"bytes,3,opt,name=urlPath"`
+
// CABundle is a PEM encoded CA bundle which will be used to validate webhook's server certificate.
// Required
CABundle []byte `json:"caBundle" protobuf:"bytes,2,opt,name=caBundle"`
diff --git a/staging/src/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go
index 0b30ecc802e..77a8a5197b7 100644
--- a/staging/src/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go
+++ b/staging/src/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go
@@ -30,6 +30,7 @@ package v1alpha1
var map_AdmissionHookClientConfig = map[string]string{
"": "AdmissionHookClientConfig contains the information to make a TLS connection with the webhook",
"service": "Service is a reference to the service for this webhook. If there is only one port open for the service, that port will be used. If there are multiple ports open, port 443 will be used if it is open, otherwise it is an error. Required",
+ "urlPath": "URLPath is an optional field that specifies the URL path to use when posting the AdmissionReview object.",
"caBundle": "CABundle is a PEM encoded CA bundle which will be used to validate webhook's server certificate. Required",
}
diff --git a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json
index c24c1f0d1af..6a050185b36 100644
--- a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json
+++ b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json
@@ -448,59 +448,63 @@
},
{
"ImportPath": "google.golang.org/grpc",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/codes",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
+ },
+ {
+ "ImportPath": "google.golang.org/grpc/connectivity",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/credentials",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclog",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/internal",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/keepalive",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/metadata",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/naming",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/peer",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/stats",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/status",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/tap",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/transport",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "gopkg.in/inf.v0",
diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/BUILD b/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/BUILD
index 023b4d89486..54732b7f9c8 100644
--- a/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/BUILD
+++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/customresourcedefinition.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/customresourcedefinition.go
index 27bb4cad884..1bd8480514e 100644
--- a/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/customresourcedefinition.go
+++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/customresourcedefinition.go
@@ -21,7 +21,6 @@ package internalversion
import (
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *customResourceDefinitionLister) List(selector labels.Selector) (ret []*
// Get retrieves the CustomResourceDefinition from the index for a given name.
func (s *customResourceDefinitionLister) Get(name string) (*apiextensions.CustomResourceDefinition, error) {
- key := &apiextensions.CustomResourceDefinition{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/BUILD b/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/BUILD
index 5970f58a12d..f57e6d77fcf 100644
--- a/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/BUILD
+++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/customresourcedefinition.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/customresourcedefinition.go
index f9b2a8f1e4b..316721bd68e 100644
--- a/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/customresourcedefinition.go
+++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/customresourcedefinition.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *customResourceDefinitionLister) List(selector labels.Selector) (ret []*
// Get retrieves the CustomResourceDefinition from the index for a given name.
func (s *customResourceDefinitionLister) Get(name string) (*v1beta1.CustomResourceDefinition, error) {
- key := &v1beta1.CustomResourceDefinition{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go
index 18c6c2b7454..f001dc57a0f 100644
--- a/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go
+++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go
@@ -135,7 +135,7 @@ func (a customResourceValidator) Validate(ctx genericapirequest.Context, obj run
return field.ErrorList{field.Invalid(field.NewPath("kind"), typeAccessor.GetKind(), fmt.Sprintf("must be %v", a.kind.Kind))}
}
if typeAccessor.GetAPIVersion() != a.kind.Group+"/"+a.kind.Version {
- return field.ErrorList{field.Invalid(field.NewPath("apiVersion"), typeAccessor.GetKind(), fmt.Sprintf("must be %v", a.kind.Group+"/"+a.kind.Version))}
+ return field.ErrorList{field.Invalid(field.NewPath("apiVersion"), typeAccessor.GetAPIVersion(), fmt.Sprintf("must be %v", a.kind.Group+"/"+a.kind.Version))}
}
customResourceObject, ok := obj.(*unstructured.Unstructured)
@@ -169,7 +169,7 @@ func (a customResourceValidator) ValidateUpdate(ctx genericapirequest.Context, o
return field.ErrorList{field.Invalid(field.NewPath("kind"), typeAccessor.GetKind(), fmt.Sprintf("must be %v", a.kind.Kind))}
}
if typeAccessor.GetAPIVersion() != a.kind.Group+"/"+a.kind.Version {
- return field.ErrorList{field.Invalid(field.NewPath("apiVersion"), typeAccessor.GetKind(), fmt.Sprintf("must be %v", a.kind.Group+"/"+a.kind.Version))}
+ return field.ErrorList{field.Invalid(field.NewPath("apiVersion"), typeAccessor.GetAPIVersion(), fmt.Sprintf("must be %v", a.kind.Group+"/"+a.kind.Version))}
}
customResourceObject, ok := obj.(*unstructured.Unstructured)
diff --git a/staging/src/k8s.io/apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiserver/Godeps/Godeps.json
index 77de2ce1ae3..ad053943994 100644
--- a/staging/src/k8s.io/apiserver/Godeps/Godeps.json
+++ b/staging/src/k8s.io/apiserver/Godeps/Godeps.json
@@ -696,59 +696,64 @@
},
{
"ImportPath": "google.golang.org/grpc",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/codes",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
+ },
+ {
+ "ImportPath": "google.golang.org/grpc/connectivity",
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/credentials",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclog",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/internal",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/keepalive",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/metadata",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/naming",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/peer",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/stats",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/status",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/tap",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/transport",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "gopkg.in/inf.v0",
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/initializer/BUILD b/staging/src/k8s.io/apiserver/pkg/admission/initializer/BUILD
index 6884d643a4e..98a3573b968 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/initializer/BUILD
+++ b/staging/src/k8s.io/apiserver/pkg/admission/initializer/BUILD
@@ -19,6 +19,7 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//vendor/k8s.io/client-go/informers:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
+ "//vendor/k8s.io/client-go/rest:go_default_library",
],
)
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer.go b/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer.go
index bce5433a34b..d41b305d964 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer.go
@@ -22,17 +22,16 @@ import (
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/rest"
)
type pluginInitializer struct {
externalClient kubernetes.Interface
externalInformers informers.SharedInformerFactory
authorizer authorizer.Authorizer
- // serverIdentifyingClientCert used to provide identity when calling out to admission plugins
- serverIdentifyingClientCert []byte
- // serverIdentifyingClientKey private key for the client certificate used when calling out to admission plugins
- serverIdentifyingClientKey []byte
- scheme *runtime.Scheme
+ // webhookRESTClientConfig provies a client used to contact webhooks
+ webhookRESTClientConfig *rest.Config
+ scheme *runtime.Scheme
}
// New creates an instance of admission plugins initializer.
@@ -41,17 +40,15 @@ func New(
extClientset kubernetes.Interface,
extInformers informers.SharedInformerFactory,
authz authorizer.Authorizer,
- serverIdentifyingClientCert,
- serverIdentifyingClientKey []byte,
+ webhookRESTClientConfig *rest.Config,
scheme *runtime.Scheme,
) (pluginInitializer, error) {
return pluginInitializer{
- externalClient: extClientset,
- externalInformers: extInformers,
- authorizer: authz,
- serverIdentifyingClientCert: serverIdentifyingClientCert,
- serverIdentifyingClientKey: serverIdentifyingClientKey,
- scheme: scheme,
+ externalClient: extClientset,
+ externalInformers: extInformers,
+ authorizer: authz,
+ webhookRESTClientConfig: webhookRESTClientConfig,
+ scheme: scheme,
}, nil
}
@@ -70,8 +67,8 @@ func (i pluginInitializer) Initialize(plugin admission.Interface) {
wants.SetAuthorizer(i.authorizer)
}
- if wants, ok := plugin.(WantsClientCert); ok {
- wants.SetClientCert(i.serverIdentifyingClientCert, i.serverIdentifyingClientKey)
+ if wants, ok := plugin.(WantsWebhookRESTClientConfig); ok {
+ wants.SetWebhookRESTClientConfig(i.webhookRESTClientConfig)
}
if wants, ok := plugin.(WantsScheme); ok {
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer_test.go b/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer_test.go
index 0550bd17cc8..9a5236316d3 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer_test.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer_test.go
@@ -33,7 +33,7 @@ import (
// the WantsScheme interface is implemented by a plugin.
func TestWantsScheme(t *testing.T) {
scheme := runtime.NewScheme()
- target, err := initializer.New(nil, nil, nil, nil, nil, scheme)
+ target, err := initializer.New(nil, nil, nil, nil, scheme)
if err != nil {
t.Fatal(err)
}
@@ -47,7 +47,7 @@ func TestWantsScheme(t *testing.T) {
// TestWantsAuthorizer ensures that the authorizer is injected
// when the WantsAuthorizer interface is implemented by a plugin.
func TestWantsAuthorizer(t *testing.T) {
- target, err := initializer.New(nil, nil, &TestAuthorizer{}, nil, nil, nil)
+ target, err := initializer.New(nil, nil, &TestAuthorizer{}, nil, nil)
if err != nil {
t.Fatal(err)
}
@@ -62,7 +62,7 @@ func TestWantsAuthorizer(t *testing.T) {
// when the WantsExternalKubeClientSet interface is implemented by a plugin.
func TestWantsExternalKubeClientSet(t *testing.T) {
cs := &fake.Clientset{}
- target, err := initializer.New(cs, nil, &TestAuthorizer{}, nil, nil, nil)
+ target, err := initializer.New(cs, nil, &TestAuthorizer{}, nil, nil)
if err != nil {
t.Fatal(err)
}
@@ -78,7 +78,7 @@ func TestWantsExternalKubeClientSet(t *testing.T) {
func TestWantsExternalKubeInformerFactory(t *testing.T) {
cs := &fake.Clientset{}
sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second)
- target, err := initializer.New(cs, sf, &TestAuthorizer{}, nil, nil, nil)
+ target, err := initializer.New(cs, sf, &TestAuthorizer{}, nil, nil)
if err != nil {
t.Fatal(err)
}
@@ -89,20 +89,6 @@ func TestWantsExternalKubeInformerFactory(t *testing.T) {
}
}
-// TestWantsClientCert ensures that the client certificate and key are injected
-// when the WantsClientCert interface is implemented by a plugin.
-func TestWantsClientCert(t *testing.T) {
- target, err := initializer.New(nil, nil, nil, []byte("cert"), []byte("key"), nil)
- if err != nil {
- t.Fatal(err)
- }
- wantClientCert := &clientCertWanter{}
- target.Initialize(wantClientCert)
- if string(wantClientCert.gotCert) != "cert" || string(wantClientCert.gotKey) != "key" {
- t.Errorf("expected client cert to be initialized, clientCert = %v, clientKey = %v", wantClientCert.gotCert, wantClientCert.gotKey)
- }
-}
-
// WantExternalKubeInformerFactory is a test stub that fulfills the WantsExternalKubeInformerFactory interface
type WantExternalKubeInformerFactory struct {
sf informers.SharedInformerFactory
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/initializer/interfaces.go b/staging/src/k8s.io/apiserver/pkg/admission/initializer/interfaces.go
index 067b4a1da23..7571252169f 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/initializer/interfaces.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/initializer/interfaces.go
@@ -22,6 +22,7 @@ import (
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/rest"
)
// WantsExternalKubeClientSet defines a function which sets external ClientSet for admission plugins that need it
@@ -42,10 +43,10 @@ type WantsAuthorizer interface {
admission.Validator
}
-// WantsClientCert defines a fuction that accepts a cert & key for admission
+// WantsWebhookRESTClientConfig defines a function that accepts client config for admission
// plugins that need to make calls and prove their identity.
-type WantsClientCert interface {
- SetClientCert(cert, key []byte)
+type WantsWebhookRESTClientConfig interface {
+ SetWebhookRESTClientConfig(*rest.Config)
admission.Validator
}
diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle/admission_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle/admission_test.go
index b0cad52f824..c3e8162e72c 100644
--- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle/admission_test.go
+++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle/admission_test.go
@@ -48,7 +48,7 @@ func newHandlerForTestWithClock(c clientset.Interface, cacheClock clock.Clock) (
if err != nil {
return nil, f, err
}
- pluginInitializer, err := kubeadmission.New(c, f, nil, nil, nil, nil)
+ pluginInitializer, err := kubeadmission.New(c, f, nil, nil, nil)
if err != nil {
return handler, f, err
}
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/BUILD b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/BUILD
index 3075c3bbec8..2640ff64b64 100644
--- a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/BUILD
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/BUILD
@@ -8,6 +8,7 @@ load(
go_library(
name = "go_default_library",
srcs = [
+ "conversion.go",
"doc.go",
"register.go",
"types.go",
diff --git a/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/conversion.go b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/conversion.go
new file mode 100644
index 00000000000..378cc080d3a
--- /dev/null
+++ b/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/conversion.go
@@ -0,0 +1,88 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+ runtime "k8s.io/apimachinery/pkg/runtime"
+)
+
+var _ runtime.NestedObjectDecoder = &AdmissionConfiguration{}
+
+// DecodeNestedObjects handles encoding RawExtensions on the AdmissionConfiguration, ensuring the
+// objects are decoded with the provided decoder.
+func (c *AdmissionConfiguration) DecodeNestedObjects(d runtime.Decoder) error {
+ // decoding failures result in a runtime.Unknown object being created in Object and passed
+ // to conversion
+ for k, v := range c.Plugins {
+ decodeNestedRawExtensionOrUnknown(d, &v.Configuration)
+ c.Plugins[k] = v
+ }
+ return nil
+}
+
+var _ runtime.NestedObjectEncoder = &AdmissionConfiguration{}
+
+// EncodeNestedObjects handles encoding RawExtensions on the AdmissionConfiguration, ensuring the
+// objects are encoded with the provided encoder.
+func (c *AdmissionConfiguration) EncodeNestedObjects(e runtime.Encoder) error {
+ for k, v := range c.Plugins {
+ if err := encodeNestedRawExtension(e, &v.Configuration); err != nil {
+ return err
+ }
+ c.Plugins[k] = v
+ }
+ return nil
+}
+
+// decodeNestedRawExtensionOrUnknown decodes the raw extension into an object once. If called
+// On a RawExtension that has already been decoded (has an object), it will not run again.
+func decodeNestedRawExtensionOrUnknown(d runtime.Decoder, ext *runtime.RawExtension) {
+ if ext.Raw == nil || ext.Object != nil {
+ return
+ }
+ obj, gvk, err := d.Decode(ext.Raw, nil, nil)
+ if err != nil {
+ unk := &runtime.Unknown{Raw: ext.Raw}
+ if runtime.IsNotRegisteredError(err) {
+ if _, gvk, err := d.Decode(ext.Raw, nil, unk); err == nil {
+ unk.APIVersion = gvk.GroupVersion().String()
+ unk.Kind = gvk.Kind
+ ext.Object = unk
+ return
+ }
+ }
+ // TODO: record mime-type with the object
+ if gvk != nil {
+ unk.APIVersion = gvk.GroupVersion().String()
+ unk.Kind = gvk.Kind
+ }
+ obj = unk
+ }
+ ext.Object = obj
+}
+
+func encodeNestedRawExtension(e runtime.Encoder, ext *runtime.RawExtension) error {
+ if ext.Raw != nil || ext.Object == nil {
+ return nil
+ }
+ data, err := runtime.Encode(e, ext.Object)
+ if err != nil {
+ return err
+ }
+ ext.Raw = data
+ return nil
+}
diff --git a/staging/src/k8s.io/apiserver/pkg/server/BUILD b/staging/src/k8s.io/apiserver/pkg/server/BUILD
index f0e3ac3d480..353862cfc41 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/BUILD
+++ b/staging/src/k8s.io/apiserver/pkg/server/BUILD
@@ -77,6 +77,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
diff --git a/staging/src/k8s.io/apiserver/pkg/server/config.go b/staging/src/k8s.io/apiserver/pkg/server/config.go
index ebf621636be..e1c81c7d4a3 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/config.go
+++ b/staging/src/k8s.io/apiserver/pkg/server/config.go
@@ -460,6 +460,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
openAPIConfig: c.OpenAPIConfig,
postStartHooks: map[string]postStartHookEntry{},
+ preShutdownHooks: map[string]preShutdownHookEntry{},
disabledPostStartHooks: c.DisabledPostStartHooks,
healthzChecks: c.HealthzChecks,
@@ -473,8 +474,12 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
s.postStartHooks[k] = v
}
+ for k, v := range delegationTarget.PreShutdownHooks() {
+ s.preShutdownHooks[k] = v
+ }
+
genericApiServerHookName := "generic-apiserver-start-informers"
- if c.SharedInformerFactory != nil && !s.isHookRegistered(genericApiServerHookName) {
+ if c.SharedInformerFactory != nil && !s.isPostStartHookRegistered(genericApiServerHookName) {
err := s.AddPostStartHook(genericApiServerHookName, func(context PostStartHookContext) error {
c.SharedInformerFactory.Start(context.StopCh)
return nil
diff --git a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go
index ad24415bc03..1927f7a8a0d 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go
+++ b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go
@@ -134,6 +134,10 @@ type GenericAPIServer struct {
postStartHooksCalled bool
disabledPostStartHooks sets.String
+ preShutdownHookLock sync.Mutex
+ preShutdownHooks map[string]preShutdownHookEntry
+ preShutdownHooksCalled bool
+
// healthz checks
healthzLock sync.Mutex
healthzChecks []healthz.HealthzChecker
@@ -163,6 +167,9 @@ type DelegationTarget interface {
// PostStartHooks returns the post-start hooks that need to be combined
PostStartHooks() map[string]postStartHookEntry
+ // PreShutdownHooks returns the pre-stop hooks that need to be combined
+ PreShutdownHooks() map[string]preShutdownHookEntry
+
// HealthzChecks returns the healthz checks that need to be combined
HealthzChecks() []healthz.HealthzChecker
@@ -180,6 +187,9 @@ func (s *GenericAPIServer) UnprotectedHandler() http.Handler {
func (s *GenericAPIServer) PostStartHooks() map[string]postStartHookEntry {
return s.postStartHooks
}
+func (s *GenericAPIServer) PreShutdownHooks() map[string]preShutdownHookEntry {
+ return s.preShutdownHooks
+}
func (s *GenericAPIServer) HealthzChecks() []healthz.HealthzChecker {
return s.healthzChecks
}
@@ -205,6 +215,9 @@ func (s emptyDelegate) UnprotectedHandler() http.Handler {
func (s emptyDelegate) PostStartHooks() map[string]postStartHookEntry {
return map[string]postStartHookEntry{}
}
+func (s emptyDelegate) PreShutdownHooks() map[string]preShutdownHookEntry {
+ return map[string]preShutdownHookEntry{}
+}
func (s emptyDelegate) HealthzChecks() []healthz.HealthzChecker {
return []healthz.HealthzChecker{}
}
@@ -264,7 +277,7 @@ func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error {
s.GenericAPIServer.AuditBackend.Shutdown()
}
- return nil
+ return s.RunPreShutdownHooks()
}
// NonBlockingRun spawns the secure http server. An error is
diff --git a/staging/src/k8s.io/apiserver/pkg/server/hooks.go b/staging/src/k8s.io/apiserver/pkg/server/hooks.go
index a190f562202..ccf8ee17ad0 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/hooks.go
+++ b/staging/src/k8s.io/apiserver/pkg/server/hooks.go
@@ -23,6 +23,7 @@ import (
"github.com/golang/glog"
+ utilerrors "k8s.io/apimachinery/pkg/util/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/server/healthz"
restclient "k8s.io/client-go/rest"
@@ -39,6 +40,9 @@ import (
// until it becomes easier to use.
type PostStartHookFunc func(context PostStartHookContext) error
+// PreShutdownHookFunc is a function that can be added to the shutdown logic.
+type PreShutdownHookFunc func() error
+
// PostStartHookContext provides information about this API server to a PostStartHookFunc
type PostStartHookContext struct {
// LoopbackClientConfig is a config for a privileged loopback connection to the API server
@@ -59,6 +63,10 @@ type postStartHookEntry struct {
done chan struct{}
}
+type preShutdownHookEntry struct {
+ hook PreShutdownHookFunc
+}
+
// AddPostStartHook allows you to add a PostStartHook.
func (s *GenericAPIServer) AddPostStartHook(name string, hook PostStartHookFunc) error {
if len(name) == 0 {
@@ -97,6 +105,37 @@ func (s *GenericAPIServer) AddPostStartHookOrDie(name string, hook PostStartHook
}
}
+// AddPreShutdownHook allows you to add a PreShutdownHook.
+func (s *GenericAPIServer) AddPreShutdownHook(name string, hook PreShutdownHookFunc) error {
+ if len(name) == 0 {
+ return fmt.Errorf("missing name")
+ }
+ if hook == nil {
+ return nil
+ }
+
+ s.preShutdownHookLock.Lock()
+ defer s.preShutdownHookLock.Unlock()
+
+ if s.preShutdownHooksCalled {
+ return fmt.Errorf("unable to add %q because PreShutdownHooks have already been called", name)
+ }
+ if _, exists := s.preShutdownHooks[name]; exists {
+ return fmt.Errorf("unable to add %q because it is already registered", name)
+ }
+
+ s.preShutdownHooks[name] = preShutdownHookEntry{hook: hook}
+
+ return nil
+}
+
+// AddPreShutdownHookOrDie allows you to add a PostStartHook, but dies on failure
+func (s *GenericAPIServer) AddPreShutdownHookOrDie(name string, hook PreShutdownHookFunc) {
+ if err := s.AddPreShutdownHook(name, hook); err != nil {
+ glog.Fatalf("Error registering PreShutdownHook %q: %v", name, err)
+ }
+}
+
// RunPostStartHooks runs the PostStartHooks for the server
func (s *GenericAPIServer) RunPostStartHooks(stopCh <-chan struct{}) {
s.postStartHookLock.Lock()
@@ -113,8 +152,24 @@ func (s *GenericAPIServer) RunPostStartHooks(stopCh <-chan struct{}) {
}
}
-// isHookRegistered checks whether a given hook is registered
-func (s *GenericAPIServer) isHookRegistered(name string) bool {
+// RunPreShutdownHooks runs the PreShutdownHooks for the server
+func (s *GenericAPIServer) RunPreShutdownHooks() error {
+ var errorList []error
+
+ s.preShutdownHookLock.Lock()
+ defer s.preShutdownHookLock.Unlock()
+ s.preShutdownHooksCalled = true
+
+ for hookName, hookEntry := range s.preShutdownHooks {
+ if err := runPreShutdownHook(hookName, hookEntry); err != nil {
+ errorList = append(errorList, err)
+ }
+ }
+ return utilerrors.NewAggregate(errorList)
+}
+
+// isPostStartHookRegistered checks whether a given PostStartHook is registered
+func (s *GenericAPIServer) isPostStartHookRegistered(name string) bool {
s.postStartHookLock.Lock()
defer s.postStartHookLock.Unlock()
_, exists := s.postStartHooks[name]
@@ -135,6 +190,19 @@ func runPostStartHook(name string, entry postStartHookEntry, context PostStartHo
close(entry.done)
}
+func runPreShutdownHook(name string, entry preShutdownHookEntry) error {
+ var err error
+ func() {
+ // don't let the hook *accidentally* panic and kill the server
+ defer utilruntime.HandleCrash()
+ err = entry.hook()
+ }()
+ if err != nil {
+ return fmt.Errorf("PreShutdownHook %q failed: %v", name, err)
+ }
+ return nil
+}
+
// postStartHookHealthz implements a healthz check for poststarthooks. It will return a "hookNotFinished"
// error until the poststarthook is finished.
type postStartHookHealthz struct {
diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/admission.go b/staging/src/k8s.io/apiserver/pkg/server/options/admission.go
index 1c23d3e2f96..d784b767246 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/options/admission.go
+++ b/staging/src/k8s.io/apiserver/pkg/server/options/admission.go
@@ -80,9 +80,8 @@ func (a *AdmissionOptions) AddFlags(fs *pflag.FlagSet) {
func (a *AdmissionOptions) ApplyTo(
c *server.Config,
informers informers.SharedInformerFactory,
- serverIdentifyingClientCert []byte,
- serverIdentifyingClientKey []byte,
- clientConfig *rest.Config,
+ kubeAPIServerClientConfig *rest.Config,
+ webhookClientConfig *rest.Config,
scheme *runtime.Scheme,
pluginInitializers ...admission.PluginInitializer,
) error {
@@ -96,11 +95,11 @@ func (a *AdmissionOptions) ApplyTo(
return fmt.Errorf("failed to read plugin config: %v", err)
}
- clientset, err := kubernetes.NewForConfig(clientConfig)
+ clientset, err := kubernetes.NewForConfig(kubeAPIServerClientConfig)
if err != nil {
return err
}
- genericInitializer, err := initializer.New(clientset, informers, c.Authorizer, serverIdentifyingClientCert, serverIdentifyingClientKey, scheme)
+ genericInitializer, err := initializer.New(clientset, informers, c.Authorizer, webhookClientConfig, scheme)
if err != nil {
return err
}
diff --git a/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/BUILD b/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/BUILD
index 64bbbe59bd1..1322950313f 100644
--- a/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/BUILD
@@ -16,7 +16,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/admissionregistration/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/externaladmissionhookconfiguration.go b/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/externaladmissionhookconfiguration.go
index 9a536c99ea6..490fc4155ee 100644
--- a/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/externaladmissionhookconfiguration.go
+++ b/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/externaladmissionhookconfiguration.go
@@ -21,7 +21,6 @@ package v1alpha1
import (
v1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *externalAdmissionHookConfigurationLister) List(selector labels.Selector
// Get retrieves the ExternalAdmissionHookConfiguration from the index for a given name.
func (s *externalAdmissionHookConfigurationLister) Get(name string) (*v1alpha1.ExternalAdmissionHookConfiguration, error) {
- key := &v1alpha1.ExternalAdmissionHookConfiguration{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/initializerconfiguration.go b/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/initializerconfiguration.go
index a19d2080750..60b004ef9f7 100644
--- a/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/initializerconfiguration.go
+++ b/staging/src/k8s.io/client-go/listers/admissionregistration/v1alpha1/initializerconfiguration.go
@@ -21,7 +21,6 @@ package v1alpha1
import (
v1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *initializerConfigurationLister) List(selector labels.Selector) (ret []*
// Get retrieves the InitializerConfiguration from the index for a given name.
func (s *initializerConfigurationLister) Get(name string) (*v1alpha1.InitializerConfiguration, error) {
- key := &v1alpha1.InitializerConfiguration{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/authentication/v1/BUILD b/staging/src/k8s.io/client-go/listers/authentication/v1/BUILD
index 09e46ffea6a..18c90f1d340 100644
--- a/staging/src/k8s.io/client-go/listers/authentication/v1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/authentication/v1/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/authentication/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/authentication/v1/tokenreview.go b/staging/src/k8s.io/client-go/listers/authentication/v1/tokenreview.go
index deea23293bb..cfae0476f37 100644
--- a/staging/src/k8s.io/client-go/listers/authentication/v1/tokenreview.go
+++ b/staging/src/k8s.io/client-go/listers/authentication/v1/tokenreview.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/authentication/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *tokenReviewLister) List(selector labels.Selector) (ret []*v1.TokenRevie
// Get retrieves the TokenReview from the index for a given name.
func (s *tokenReviewLister) Get(name string) (*v1.TokenReview, error) {
- key := &v1.TokenReview{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/authentication/v1beta1/BUILD b/staging/src/k8s.io/client-go/listers/authentication/v1beta1/BUILD
index 7838effea11..45a7b02ebd2 100644
--- a/staging/src/k8s.io/client-go/listers/authentication/v1beta1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/authentication/v1beta1/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/authentication/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/authentication/v1beta1/tokenreview.go b/staging/src/k8s.io/client-go/listers/authentication/v1beta1/tokenreview.go
index ec62c1f2e85..035ad62da3d 100644
--- a/staging/src/k8s.io/client-go/listers/authentication/v1beta1/tokenreview.go
+++ b/staging/src/k8s.io/client-go/listers/authentication/v1beta1/tokenreview.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/authentication/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *tokenReviewLister) List(selector labels.Selector) (ret []*v1beta1.Token
// Get retrieves the TokenReview from the index for a given name.
func (s *tokenReviewLister) Get(name string) (*v1beta1.TokenReview, error) {
- key := &v1beta1.TokenReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/authorization/v1/BUILD b/staging/src/k8s.io/client-go/listers/authorization/v1/BUILD
index e9f89280663..dbea6dcc2f6 100644
--- a/staging/src/k8s.io/client-go/listers/authorization/v1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/authorization/v1/BUILD
@@ -18,7 +18,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/authorization/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/authorization/v1/selfsubjectaccessreview.go b/staging/src/k8s.io/client-go/listers/authorization/v1/selfsubjectaccessreview.go
index 108a37b49ad..64ff1744be4 100644
--- a/staging/src/k8s.io/client-go/listers/authorization/v1/selfsubjectaccessreview.go
+++ b/staging/src/k8s.io/client-go/listers/authorization/v1/selfsubjectaccessreview.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/authorization/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *selfSubjectAccessReviewLister) List(selector labels.Selector) (ret []*v
// Get retrieves the SelfSubjectAccessReview from the index for a given name.
func (s *selfSubjectAccessReviewLister) Get(name string) (*v1.SelfSubjectAccessReview, error) {
- key := &v1.SelfSubjectAccessReview{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/authorization/v1/selfsubjectrulesreview.go b/staging/src/k8s.io/client-go/listers/authorization/v1/selfsubjectrulesreview.go
index b654974b488..63ad0f1ff74 100644
--- a/staging/src/k8s.io/client-go/listers/authorization/v1/selfsubjectrulesreview.go
+++ b/staging/src/k8s.io/client-go/listers/authorization/v1/selfsubjectrulesreview.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/authorization/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *selfSubjectRulesReviewLister) List(selector labels.Selector) (ret []*v1
// Get retrieves the SelfSubjectRulesReview from the index for a given name.
func (s *selfSubjectRulesReviewLister) Get(name string) (*v1.SelfSubjectRulesReview, error) {
- key := &v1.SelfSubjectRulesReview{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/authorization/v1/subjectaccessreview.go b/staging/src/k8s.io/client-go/listers/authorization/v1/subjectaccessreview.go
index 8a701e526d7..f389e07b1fb 100644
--- a/staging/src/k8s.io/client-go/listers/authorization/v1/subjectaccessreview.go
+++ b/staging/src/k8s.io/client-go/listers/authorization/v1/subjectaccessreview.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/authorization/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *subjectAccessReviewLister) List(selector labels.Selector) (ret []*v1.Su
// Get retrieves the SubjectAccessReview from the index for a given name.
func (s *subjectAccessReviewLister) Get(name string) (*v1.SubjectAccessReview, error) {
- key := &v1.SubjectAccessReview{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/authorization/v1beta1/BUILD b/staging/src/k8s.io/client-go/listers/authorization/v1beta1/BUILD
index 63d0b70b975..66564270665 100644
--- a/staging/src/k8s.io/client-go/listers/authorization/v1beta1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/authorization/v1beta1/BUILD
@@ -18,7 +18,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/authorization/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/authorization/v1beta1/selfsubjectaccessreview.go b/staging/src/k8s.io/client-go/listers/authorization/v1beta1/selfsubjectaccessreview.go
index 1f2a42113e4..4936b9b6c99 100644
--- a/staging/src/k8s.io/client-go/listers/authorization/v1beta1/selfsubjectaccessreview.go
+++ b/staging/src/k8s.io/client-go/listers/authorization/v1beta1/selfsubjectaccessreview.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/authorization/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *selfSubjectAccessReviewLister) List(selector labels.Selector) (ret []*v
// Get retrieves the SelfSubjectAccessReview from the index for a given name.
func (s *selfSubjectAccessReviewLister) Get(name string) (*v1beta1.SelfSubjectAccessReview, error) {
- key := &v1beta1.SelfSubjectAccessReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/authorization/v1beta1/selfsubjectrulesreview.go b/staging/src/k8s.io/client-go/listers/authorization/v1beta1/selfsubjectrulesreview.go
index 8c775961af1..8eb7a21b506 100644
--- a/staging/src/k8s.io/client-go/listers/authorization/v1beta1/selfsubjectrulesreview.go
+++ b/staging/src/k8s.io/client-go/listers/authorization/v1beta1/selfsubjectrulesreview.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/authorization/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *selfSubjectRulesReviewLister) List(selector labels.Selector) (ret []*v1
// Get retrieves the SelfSubjectRulesReview from the index for a given name.
func (s *selfSubjectRulesReviewLister) Get(name string) (*v1beta1.SelfSubjectRulesReview, error) {
- key := &v1beta1.SelfSubjectRulesReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/authorization/v1beta1/subjectaccessreview.go b/staging/src/k8s.io/client-go/listers/authorization/v1beta1/subjectaccessreview.go
index f994f3a1b74..4b155de1575 100644
--- a/staging/src/k8s.io/client-go/listers/authorization/v1beta1/subjectaccessreview.go
+++ b/staging/src/k8s.io/client-go/listers/authorization/v1beta1/subjectaccessreview.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/authorization/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *subjectAccessReviewLister) List(selector labels.Selector) (ret []*v1bet
// Get retrieves the SubjectAccessReview from the index for a given name.
func (s *subjectAccessReviewLister) Get(name string) (*v1beta1.SubjectAccessReview, error) {
- key := &v1beta1.SubjectAccessReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/certificates/v1beta1/BUILD b/staging/src/k8s.io/client-go/listers/certificates/v1beta1/BUILD
index 2e40008b668..b7ca4270c19 100644
--- a/staging/src/k8s.io/client-go/listers/certificates/v1beta1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/certificates/v1beta1/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/certificates/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/certificates/v1beta1/certificatesigningrequest.go b/staging/src/k8s.io/client-go/listers/certificates/v1beta1/certificatesigningrequest.go
index 62af289b240..425dc6b4d94 100644
--- a/staging/src/k8s.io/client-go/listers/certificates/v1beta1/certificatesigningrequest.go
+++ b/staging/src/k8s.io/client-go/listers/certificates/v1beta1/certificatesigningrequest.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/certificates/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *certificateSigningRequestLister) List(selector labels.Selector) (ret []
// Get retrieves the CertificateSigningRequest from the index for a given name.
func (s *certificateSigningRequestLister) Get(name string) (*v1beta1.CertificateSigningRequest, error) {
- key := &v1beta1.CertificateSigningRequest{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/core/v1/BUILD b/staging/src/k8s.io/client-go/listers/core/v1/BUILD
index adc5061988f..313cdc299c6 100644
--- a/staging/src/k8s.io/client-go/listers/core/v1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/core/v1/BUILD
@@ -33,7 +33,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/core/v1/componentstatus.go b/staging/src/k8s.io/client-go/listers/core/v1/componentstatus.go
index a612a544cc9..6ba67d0bd56 100644
--- a/staging/src/k8s.io/client-go/listers/core/v1/componentstatus.go
+++ b/staging/src/k8s.io/client-go/listers/core/v1/componentstatus.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *componentStatusLister) List(selector labels.Selector) (ret []*v1.Compon
// Get retrieves the ComponentStatus from the index for a given name.
func (s *componentStatusLister) Get(name string) (*v1.ComponentStatus, error) {
- key := &v1.ComponentStatus{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/core/v1/namespace.go b/staging/src/k8s.io/client-go/listers/core/v1/namespace.go
index 9b184f71c3b..21be6878a38 100644
--- a/staging/src/k8s.io/client-go/listers/core/v1/namespace.go
+++ b/staging/src/k8s.io/client-go/listers/core/v1/namespace.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *namespaceLister) List(selector labels.Selector) (ret []*v1.Namespace, e
// Get retrieves the Namespace from the index for a given name.
func (s *namespaceLister) Get(name string) (*v1.Namespace, error) {
- key := &v1.Namespace{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/core/v1/node.go b/staging/src/k8s.io/client-go/listers/core/v1/node.go
index 24a01fbdda8..d43a682c90b 100644
--- a/staging/src/k8s.io/client-go/listers/core/v1/node.go
+++ b/staging/src/k8s.io/client-go/listers/core/v1/node.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *nodeLister) List(selector labels.Selector) (ret []*v1.Node, err error)
// Get retrieves the Node from the index for a given name.
func (s *nodeLister) Get(name string) (*v1.Node, error) {
- key := &v1.Node{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/core/v1/persistentvolume.go b/staging/src/k8s.io/client-go/listers/core/v1/persistentvolume.go
index ea2f79dd775..593ba14ed18 100644
--- a/staging/src/k8s.io/client-go/listers/core/v1/persistentvolume.go
+++ b/staging/src/k8s.io/client-go/listers/core/v1/persistentvolume.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *persistentVolumeLister) List(selector labels.Selector) (ret []*v1.Persi
// Get retrieves the PersistentVolume from the index for a given name.
func (s *persistentVolumeLister) Get(name string) (*v1.PersistentVolume, error) {
- key := &v1.PersistentVolume{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go b/staging/src/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go
index da47dbb5263..3189ff7c9da 100644
--- a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go
+++ b/staging/src/k8s.io/client-go/listers/extensions/v1beta1/podsecuritypolicy.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *podSecurityPolicyLister) List(selector labels.Selector) (ret []*v1beta1
// Get retrieves the PodSecurityPolicy from the index for a given name.
func (s *podSecurityPolicyLister) Get(name string) (*v1beta1.PodSecurityPolicy, error) {
- key := &v1beta1.PodSecurityPolicy{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/thirdpartyresource.go b/staging/src/k8s.io/client-go/listers/extensions/v1beta1/thirdpartyresource.go
index 3cd699a8637..9cc5a6ea0d9 100644
--- a/staging/src/k8s.io/client-go/listers/extensions/v1beta1/thirdpartyresource.go
+++ b/staging/src/k8s.io/client-go/listers/extensions/v1beta1/thirdpartyresource.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *thirdPartyResourceLister) List(selector labels.Selector) (ret []*v1beta
// Get retrieves the ThirdPartyResource from the index for a given name.
func (s *thirdPartyResourceLister) Get(name string) (*v1beta1.ThirdPartyResource, error) {
- key := &v1beta1.ThirdPartyResource{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/imagepolicy/v1alpha1/BUILD b/staging/src/k8s.io/client-go/listers/imagepolicy/v1alpha1/BUILD
index bef22aaf1df..da825e6a55c 100644
--- a/staging/src/k8s.io/client-go/listers/imagepolicy/v1alpha1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/imagepolicy/v1alpha1/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/imagepolicy/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/imagepolicy/v1alpha1/imagereview.go b/staging/src/k8s.io/client-go/listers/imagepolicy/v1alpha1/imagereview.go
index ee8c19f1205..8ffd9d05f61 100644
--- a/staging/src/k8s.io/client-go/listers/imagepolicy/v1alpha1/imagereview.go
+++ b/staging/src/k8s.io/client-go/listers/imagepolicy/v1alpha1/imagereview.go
@@ -21,7 +21,6 @@ package v1alpha1
import (
v1alpha1 "k8s.io/api/imagepolicy/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *imageReviewLister) List(selector labels.Selector) (ret []*v1alpha1.Imag
// Get retrieves the ImageReview from the index for a given name.
func (s *imageReviewLister) Get(name string) (*v1alpha1.ImageReview, error) {
- key := &v1alpha1.ImageReview{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/rbac/v1/BUILD b/staging/src/k8s.io/client-go/listers/rbac/v1/BUILD
index a046b68ee9f..9facdc04dfd 100644
--- a/staging/src/k8s.io/client-go/listers/rbac/v1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/rbac/v1/BUILD
@@ -18,7 +18,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/rbac/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/rbac/v1/clusterrole.go b/staging/src/k8s.io/client-go/listers/rbac/v1/clusterrole.go
index f95d063bef3..5dc9a225e70 100644
--- a/staging/src/k8s.io/client-go/listers/rbac/v1/clusterrole.go
+++ b/staging/src/k8s.io/client-go/listers/rbac/v1/clusterrole.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *clusterRoleLister) List(selector labels.Selector) (ret []*v1.ClusterRol
// Get retrieves the ClusterRole from the index for a given name.
func (s *clusterRoleLister) Get(name string) (*v1.ClusterRole, error) {
- key := &v1.ClusterRole{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/rbac/v1/clusterrolebinding.go b/staging/src/k8s.io/client-go/listers/rbac/v1/clusterrolebinding.go
index cce8a0f4870..bb3186a067b 100644
--- a/staging/src/k8s.io/client-go/listers/rbac/v1/clusterrolebinding.go
+++ b/staging/src/k8s.io/client-go/listers/rbac/v1/clusterrolebinding.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *clusterRoleBindingLister) List(selector labels.Selector) (ret []*v1.Clu
// Get retrieves the ClusterRoleBinding from the index for a given name.
func (s *clusterRoleBindingLister) Get(name string) (*v1.ClusterRoleBinding, error) {
- key := &v1.ClusterRoleBinding{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/BUILD b/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/BUILD
index 3501bfbb484..917c535fc54 100644
--- a/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/BUILD
@@ -18,7 +18,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/rbac/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/clusterrole.go b/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/clusterrole.go
index 21adfb3512d..9e20a6d1629 100644
--- a/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/clusterrole.go
+++ b/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/clusterrole.go
@@ -21,7 +21,6 @@ package v1alpha1
import (
v1alpha1 "k8s.io/api/rbac/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *clusterRoleLister) List(selector labels.Selector) (ret []*v1alpha1.Clus
// Get retrieves the ClusterRole from the index for a given name.
func (s *clusterRoleLister) Get(name string) (*v1alpha1.ClusterRole, error) {
- key := &v1alpha1.ClusterRole{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/clusterrolebinding.go b/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/clusterrolebinding.go
index 5c1b93a77c3..155666aba02 100644
--- a/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/clusterrolebinding.go
+++ b/staging/src/k8s.io/client-go/listers/rbac/v1alpha1/clusterrolebinding.go
@@ -21,7 +21,6 @@ package v1alpha1
import (
v1alpha1 "k8s.io/api/rbac/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *clusterRoleBindingLister) List(selector labels.Selector) (ret []*v1alph
// Get retrieves the ClusterRoleBinding from the index for a given name.
func (s *clusterRoleBindingLister) Get(name string) (*v1alpha1.ClusterRoleBinding, error) {
- key := &v1alpha1.ClusterRoleBinding{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/rbac/v1beta1/BUILD b/staging/src/k8s.io/client-go/listers/rbac/v1beta1/BUILD
index babebd826e0..bde3d52e81b 100644
--- a/staging/src/k8s.io/client-go/listers/rbac/v1beta1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/rbac/v1beta1/BUILD
@@ -18,7 +18,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/rbac/v1beta1/clusterrole.go b/staging/src/k8s.io/client-go/listers/rbac/v1beta1/clusterrole.go
index 4e759c494c6..65ec3eb978f 100644
--- a/staging/src/k8s.io/client-go/listers/rbac/v1beta1/clusterrole.go
+++ b/staging/src/k8s.io/client-go/listers/rbac/v1beta1/clusterrole.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/rbac/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *clusterRoleLister) List(selector labels.Selector) (ret []*v1beta1.Clust
// Get retrieves the ClusterRole from the index for a given name.
func (s *clusterRoleLister) Get(name string) (*v1beta1.ClusterRole, error) {
- key := &v1beta1.ClusterRole{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/rbac/v1beta1/clusterrolebinding.go b/staging/src/k8s.io/client-go/listers/rbac/v1beta1/clusterrolebinding.go
index 6781ac60eef..146f2d7f294 100644
--- a/staging/src/k8s.io/client-go/listers/rbac/v1beta1/clusterrolebinding.go
+++ b/staging/src/k8s.io/client-go/listers/rbac/v1beta1/clusterrolebinding.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/rbac/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *clusterRoleBindingLister) List(selector labels.Selector) (ret []*v1beta
// Get retrieves the ClusterRoleBinding from the index for a given name.
func (s *clusterRoleBindingLister) Get(name string) (*v1beta1.ClusterRoleBinding, error) {
- key := &v1beta1.ClusterRoleBinding{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/scheduling/v1alpha1/BUILD b/staging/src/k8s.io/client-go/listers/scheduling/v1alpha1/BUILD
index c076382da48..cf60e81322d 100644
--- a/staging/src/k8s.io/client-go/listers/scheduling/v1alpha1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/scheduling/v1alpha1/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/scheduling/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go b/staging/src/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go
index 67b6864e7db..9ed04fd2ae1 100644
--- a/staging/src/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go
+++ b/staging/src/k8s.io/client-go/listers/scheduling/v1alpha1/priorityclass.go
@@ -21,7 +21,6 @@ package v1alpha1
import (
v1alpha1 "k8s.io/api/scheduling/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *priorityClassLister) List(selector labels.Selector) (ret []*v1alpha1.Pr
// Get retrieves the PriorityClass from the index for a given name.
func (s *priorityClassLister) Get(name string) (*v1alpha1.PriorityClass, error) {
- key := &v1alpha1.PriorityClass{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/storage/v1/BUILD b/staging/src/k8s.io/client-go/listers/storage/v1/BUILD
index ed6bb798182..b90f06bb7a6 100644
--- a/staging/src/k8s.io/client-go/listers/storage/v1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/storage/v1/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/storage/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/storage/v1/storageclass.go b/staging/src/k8s.io/client-go/listers/storage/v1/storageclass.go
index 09e65943808..7c37321fd9e 100644
--- a/staging/src/k8s.io/client-go/listers/storage/v1/storageclass.go
+++ b/staging/src/k8s.io/client-go/listers/storage/v1/storageclass.go
@@ -21,7 +21,6 @@ package v1
import (
v1 "k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/api/errors"
- meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *storageClassLister) List(selector labels.Selector) (ret []*v1.StorageCl
// Get retrieves the StorageClass from the index for a given name.
func (s *storageClassLister) Get(name string) (*v1.StorageClass, error) {
- key := &v1.StorageClass{ObjectMeta: meta_v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/listers/storage/v1beta1/BUILD b/staging/src/k8s.io/client-go/listers/storage/v1beta1/BUILD
index fbae43859fc..d4b82cbc808 100644
--- a/staging/src/k8s.io/client-go/listers/storage/v1beta1/BUILD
+++ b/staging/src/k8s.io/client-go/listers/storage/v1beta1/BUILD
@@ -15,7 +15,6 @@ go_library(
deps = [
"//vendor/k8s.io/api/storage/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
diff --git a/staging/src/k8s.io/client-go/listers/storage/v1beta1/storageclass.go b/staging/src/k8s.io/client-go/listers/storage/v1beta1/storageclass.go
index 04efe5f8dad..9253319bec6 100644
--- a/staging/src/k8s.io/client-go/listers/storage/v1beta1/storageclass.go
+++ b/staging/src/k8s.io/client-go/listers/storage/v1beta1/storageclass.go
@@ -21,7 +21,6 @@ package v1beta1
import (
v1beta1 "k8s.io/api/storage/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
@@ -55,8 +54,7 @@ func (s *storageClassLister) List(selector labels.Selector) (ret []*v1beta1.Stor
// Get retrieves the StorageClass from the index for a given name.
func (s *storageClassLister) Get(name string) (*v1beta1.StorageClass, error) {
- key := &v1beta1.StorageClass{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/client-go/rest/config.go b/staging/src/k8s.io/client-go/rest/config.go
index 57848c8a74f..038fee94537 100644
--- a/staging/src/k8s.io/client-go/rest/config.go
+++ b/staging/src/k8s.io/client-go/rest/config.go
@@ -420,5 +420,45 @@ func AnonymousClientConfig(config *Config) *Config {
QPS: config.QPS,
Burst: config.Burst,
Timeout: config.Timeout,
+ Dial: config.Dial,
+ }
+}
+
+// CopyConfig returns a copy of the given config
+func CopyConfig(config *Config) *Config {
+ return &Config{
+ Host: config.Host,
+ APIPath: config.APIPath,
+ Prefix: config.Prefix,
+ ContentConfig: config.ContentConfig,
+ Username: config.Username,
+ Password: config.Password,
+ BearerToken: config.BearerToken,
+ CacheDir: config.CacheDir,
+ Impersonate: ImpersonationConfig{
+ Groups: config.Impersonate.Groups,
+ Extra: config.Impersonate.Extra,
+ UserName: config.Impersonate.UserName,
+ },
+ AuthProvider: config.AuthProvider,
+ AuthConfigPersister: config.AuthConfigPersister,
+ TLSClientConfig: TLSClientConfig{
+ Insecure: config.TLSClientConfig.Insecure,
+ ServerName: config.TLSClientConfig.ServerName,
+ CertFile: config.TLSClientConfig.CertFile,
+ KeyFile: config.TLSClientConfig.KeyFile,
+ CAFile: config.TLSClientConfig.CAFile,
+ CertData: config.TLSClientConfig.CertData,
+ KeyData: config.TLSClientConfig.KeyData,
+ CAData: config.TLSClientConfig.CAData,
+ },
+ UserAgent: config.UserAgent,
+ Transport: config.Transport,
+ WrapTransport: config.WrapTransport,
+ QPS: config.QPS,
+ Burst: config.Burst,
+ RateLimiter: config.RateLimiter,
+ Timeout: config.Timeout,
+ Dial: config.Dial,
}
}
diff --git a/staging/src/k8s.io/client-go/rest/config_test.go b/staging/src/k8s.io/client-go/rest/config_test.go
index ff851e6ade4..0e86442dbd0 100644
--- a/staging/src/k8s.io/client-go/rest/config_test.go
+++ b/staging/src/k8s.io/client-go/rest/config_test.go
@@ -35,6 +35,8 @@ import (
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/client-go/util/flowcontrol"
+ "errors"
+
"github.com/stretchr/testify/assert"
)
@@ -206,6 +208,19 @@ func (n *fakeNegotiatedSerializer) DecoderToVersion(serializer runtime.Decoder,
return &fakeCodec{}
}
+var fakeDialFunc = func(network, addr string) (net.Conn, error) {
+ return nil, fakeDialerError
+}
+var fakeDialerError = errors.New("fakedialer")
+
+type fakeAuthProviderConfigPersister struct{}
+
+func (fakeAuthProviderConfigPersister) Persist(map[string]string) error {
+ return fakeAuthProviderConfigPersisterError
+}
+
+var fakeAuthProviderConfigPersisterError = errors.New("fakeAuthProviderConfigPersisterError")
+
func TestAnonymousConfig(t *testing.T) {
f := fuzz.New().NilChance(0.0).NumElements(1, 1)
f.Funcs(
@@ -268,9 +283,94 @@ func TestAnonymousConfig(t *testing.T) {
actual.WrapTransport = nil
expected.WrapTransport = nil
}
+ if actual.Dial != nil {
+ _, actualError := actual.Dial("", "")
+ _, expectedError := actual.Dial("", "")
+ if !reflect.DeepEqual(expectedError, actualError) {
+ t.Fatalf("CopyConfig dropped the Dial field")
+ }
+ } else {
+ actual.Dial = nil
+ expected.Dial = nil
+ }
if !reflect.DeepEqual(*actual, expected) {
t.Fatalf("AnonymousClientConfig dropped unexpected fields, identify whether they are security related or not: %s", diff.ObjectGoPrintDiff(expected, actual))
}
}
}
+
+func TestCopyConfig(t *testing.T) {
+ f := fuzz.New().NilChance(0.0).NumElements(1, 1)
+ f.Funcs(
+ func(r *runtime.Codec, f fuzz.Continue) {
+ codec := &fakeCodec{}
+ f.Fuzz(codec)
+ *r = codec
+ },
+ func(r *http.RoundTripper, f fuzz.Continue) {
+ roundTripper := &fakeRoundTripper{}
+ f.Fuzz(roundTripper)
+ *r = roundTripper
+ },
+ func(fn *func(http.RoundTripper) http.RoundTripper, f fuzz.Continue) {
+ *fn = fakeWrapperFunc
+ },
+ func(r *runtime.NegotiatedSerializer, f fuzz.Continue) {
+ serializer := &fakeNegotiatedSerializer{}
+ f.Fuzz(serializer)
+ *r = serializer
+ },
+ func(r *flowcontrol.RateLimiter, f fuzz.Continue) {
+ limiter := &fakeLimiter{}
+ f.Fuzz(limiter)
+ *r = limiter
+ },
+ func(r *AuthProviderConfigPersister, f fuzz.Continue) {
+ *r = fakeAuthProviderConfigPersister{}
+ },
+ func(r *func(network, addr string) (net.Conn, error), f fuzz.Continue) {
+ *r = fakeDialFunc
+ },
+ )
+ for i := 0; i < 20; i++ {
+ original := &Config{}
+ f.Fuzz(original)
+ actual := CopyConfig(original)
+ expected := *original
+
+ // this is the list of known risky fields, add to this list if a new field
+ // is added to Config, update CopyConfig to preserve the field otherwise.
+
+ // The DeepEqual cannot handle the func comparison, so we just verify if the
+ // function return the expected object.
+ if actual.WrapTransport == nil || !reflect.DeepEqual(expected.WrapTransport(nil), &fakeRoundTripper{}) {
+ t.Fatalf("CopyConfig dropped the WrapTransport field")
+ } else {
+ actual.WrapTransport = nil
+ expected.WrapTransport = nil
+ }
+ if actual.Dial != nil {
+ _, actualError := actual.Dial("", "")
+ _, expectedError := actual.Dial("", "")
+ if !reflect.DeepEqual(expectedError, actualError) {
+ t.Fatalf("CopyConfig dropped the Dial field")
+ }
+ }
+ actual.Dial = nil
+ expected.Dial = nil
+ if actual.AuthConfigPersister != nil {
+ actualError := actual.AuthConfigPersister.Persist(nil)
+ expectedError := actual.AuthConfigPersister.Persist(nil)
+ if !reflect.DeepEqual(expectedError, actualError) {
+ t.Fatalf("CopyConfig dropped the Dial field")
+ }
+ }
+ actual.AuthConfigPersister = nil
+ expected.AuthConfigPersister = nil
+
+ if !reflect.DeepEqual(*actual, expected) {
+ t.Fatalf("CopyConfig dropped unexpected fields, identify whether they are security related or not: %s", diff.ObjectReflectDiff(expected, *actual))
+ }
+ }
+}
diff --git a/staging/src/k8s.io/code-generator/cmd/lister-gen/generators/lister.go b/staging/src/k8s.io/code-generator/cmd/lister-gen/generators/lister.go
index 9466e3cb07d..e25a5a1a189 100644
--- a/staging/src/k8s.io/code-generator/cmd/lister-gen/generators/lister.go
+++ b/staging/src/k8s.io/code-generator/cmd/lister-gen/generators/lister.go
@@ -322,8 +322,7 @@ func (s *$.type|private$Lister) $.type|publicPlural$(namespace string) $.type|pu
var typeLister_NonNamespacedGet = `
// Get retrieves the $.type|public$ from the index for a given name.
func (s *$.type|private$Lister) Get(name string) (*$.type|raw$, error) {
- key := &$.type|raw${ObjectMeta: $.objectMeta|raw${Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json
index 65fb053ed83..b8062fb9a70 100644
--- a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json
+++ b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json
@@ -424,59 +424,64 @@
},
{
"ImportPath": "google.golang.org/grpc",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/codes",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
+ },
+ {
+ "ImportPath": "google.golang.org/grpc/connectivity",
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/credentials",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclog",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/internal",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/keepalive",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/metadata",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/naming",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/peer",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/stats",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/status",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/tap",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/transport",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "gopkg.in/inf.v0",
diff --git a/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/internalversion/BUILD b/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/internalversion/BUILD
index 67c54ae6da7..5e8cbddf431 100644
--- a/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/internalversion/BUILD
+++ b/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/internalversion/BUILD
@@ -14,7 +14,6 @@ go_library(
importpath = "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/internalversion",
deps = [
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration:go_default_library",
diff --git a/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/internalversion/apiservice.go b/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/internalversion/apiservice.go
index 24f2409d997..675d8228a96 100644
--- a/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/internalversion/apiservice.go
+++ b/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/internalversion/apiservice.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
apiregistration "k8s.io/kube-aggregator/pkg/apis/apiregistration"
@@ -55,8 +54,7 @@ func (s *aPIServiceLister) List(selector labels.Selector) (ret []*apiregistratio
// Get retrieves the APIService from the index for a given name.
func (s *aPIServiceLister) Get(name string) (*apiregistration.APIService, error) {
- key := &apiregistration.APIService{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1/BUILD b/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1/BUILD
index f21b7e594f2..eb3a9a8073e 100644
--- a/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1/BUILD
+++ b/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1/BUILD
@@ -14,7 +14,6 @@ go_library(
importpath = "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1",
deps = [
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1:go_default_library",
diff --git a/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1/apiservice.go b/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1/apiservice.go
index 145f318e63d..4ccaa66956d 100644
--- a/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1/apiservice.go
+++ b/staging/src/k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1/apiservice.go
@@ -20,7 +20,6 @@ package v1beta1
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
v1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1"
@@ -55,8 +54,7 @@ func (s *aPIServiceLister) List(selector labels.Selector) (ret []*v1beta1.APISer
// Get retrieves the APIService from the index for a given name.
func (s *aPIServiceLister) Get(name string) (*v1beta1.APIService, error) {
- key := &v1beta1.APIService{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json
index e56ed79b84b..04e0663349f 100644
--- a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json
+++ b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json
@@ -408,59 +408,64 @@
},
{
"ImportPath": "google.golang.org/grpc",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/codes",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
+ },
+ {
+ "ImportPath": "google.golang.org/grpc/connectivity",
+ "Comment": "v1.5.2",
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/credentials",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/grpclog",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/internal",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/keepalive",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/metadata",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/naming",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/peer",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/stats",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/status",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/tap",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "google.golang.org/grpc/transport",
- "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5"
+ "Rev": "b3ddf786825de56a4178401b7e174ee332173b66"
},
{
"ImportPath": "gopkg.in/inf.v0",
diff --git a/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/internalversion/BUILD b/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/internalversion/BUILD
index 41d04cefcfc..5e89485051d 100644
--- a/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/internalversion/BUILD
+++ b/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/internalversion/BUILD
@@ -11,7 +11,6 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/sample-apiserver/pkg/apis/wardle:go_default_library",
diff --git a/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/internalversion/fischer.go b/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/internalversion/fischer.go
index 43ac4bdd001..9968bade8ca 100644
--- a/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/internalversion/fischer.go
+++ b/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/internalversion/fischer.go
@@ -20,7 +20,6 @@ package internalversion
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
wardle "k8s.io/sample-apiserver/pkg/apis/wardle"
@@ -55,8 +54,7 @@ func (s *fischerLister) List(selector labels.Selector) (ret []*wardle.Fischer, e
// Get retrieves the Fischer from the index for a given name.
func (s *fischerLister) Get(name string) (*wardle.Fischer, error) {
- key := &wardle.Fischer{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/v1alpha1/BUILD b/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/v1alpha1/BUILD
index d6cd90cd80e..ecff53d5c29 100644
--- a/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/v1alpha1/BUILD
+++ b/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/v1alpha1/BUILD
@@ -11,7 +11,6 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1:go_default_library",
diff --git a/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/v1alpha1/fischer.go b/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/v1alpha1/fischer.go
index 1be3ffbed83..e5d452cf175 100644
--- a/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/v1alpha1/fischer.go
+++ b/staging/src/k8s.io/sample-apiserver/pkg/client/listers/wardle/v1alpha1/fischer.go
@@ -20,7 +20,6 @@ package v1alpha1
import (
"k8s.io/apimachinery/pkg/api/errors"
- v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
v1alpha1 "k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1"
@@ -55,8 +54,7 @@ func (s *fischerLister) List(selector labels.Selector) (ret []*v1alpha1.Fischer,
// Get retrieves the Fischer from the index for a given name.
func (s *fischerLister) Get(name string) (*v1alpha1.Fischer, error) {
- key := &v1alpha1.Fischer{ObjectMeta: v1.ObjectMeta{Name: name}}
- obj, exists, err := s.indexer.Get(key)
+ obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/sample-apiserver/pkg/cmd/server/start.go b/staging/src/k8s.io/sample-apiserver/pkg/cmd/server/start.go
index b45290be1a8..f46d0327347 100644
--- a/staging/src/k8s.io/sample-apiserver/pkg/cmd/server/start.go
+++ b/staging/src/k8s.io/sample-apiserver/pkg/cmd/server/start.go
@@ -119,7 +119,7 @@ func (o WardleServerOptions) Config() (*apiserver.Config, error) {
return nil, err
}
- if err := o.Admission.ApplyTo(&serverConfig.Config, serverConfig.SharedInformerFactory, nil, nil, serverConfig.ClientConfig, apiserver.Scheme, admissionInitializer); err != nil {
+ if err := o.Admission.ApplyTo(&serverConfig.Config, serverConfig.SharedInformerFactory, serverConfig.ClientConfig, serverConfig.ClientConfig, apiserver.Scheme, admissionInitializer); err != nil {
return nil, err
}
diff --git a/staging/src/k8s.io/sample-controller/BUILD b/staging/src/k8s.io/sample-controller/BUILD
new file mode 100644
index 00000000000..3bdd428f777
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/BUILD
@@ -0,0 +1,64 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "controller.go",
+ "main.go",
+ ],
+ importpath = "k8s.io/sample-controller",
+ visibility = ["//visibility:private"],
+ deps = [
+ "//vendor/github.com/golang/glog:go_default_library",
+ "//vendor/k8s.io/api/apps/v1beta2:go_default_library",
+ "//vendor/k8s.io/api/core/v1:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
+ "//vendor/k8s.io/client-go/informers:go_default_library",
+ "//vendor/k8s.io/client-go/kubernetes:go_default_library",
+ "//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library",
+ "//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
+ "//vendor/k8s.io/client-go/listers/apps/v1beta2:go_default_library",
+ "//vendor/k8s.io/client-go/tools/cache:go_default_library",
+ "//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
+ "//vendor/k8s.io/client-go/tools/record:go_default_library",
+ "//vendor/k8s.io/client-go/util/workqueue:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/signals:go_default_library",
+ ],
+)
+
+go_binary(
+ name = "sample-controller",
+ importpath = "k8s.io/sample-controller",
+ library = ":go_default_library",
+ visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [
+ ":package-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller:all-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned:all-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions:all-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1:all-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/signals:all-srcs",
+ ],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/Godeps/Godeps.json b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json
new file mode 100644
index 00000000000..4798b300ec6
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json
@@ -0,0 +1,946 @@
+{
+ "ImportPath": "k8s.io/sample-controller",
+ "GoVersion": "go1.8",
+ "GodepVersion": "v79",
+ "Packages": [
+ "./..."
+ ],
+ "Deps": [
+ {
+ "ImportPath": "github.com/PuerkitoBio/purell",
+ "Rev": "8a290539e2e8629dbc4e6bad948158f790ec31f4"
+ },
+ {
+ "ImportPath": "github.com/PuerkitoBio/urlesc",
+ "Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
+ },
+ {
+ "ImportPath": "github.com/davecgh/go-spew/spew",
+ "Rev": "782f4967f2dc4564575ca782fe2d04090b5faca8"
+ },
+ {
+ "ImportPath": "github.com/emicklei/go-restful",
+ "Rev": "ff4f55a206334ef123e4f79bbf348980da81ca46"
+ },
+ {
+ "ImportPath": "github.com/emicklei/go-restful/log",
+ "Rev": "ff4f55a206334ef123e4f79bbf348980da81ca46"
+ },
+ {
+ "ImportPath": "github.com/ghodss/yaml",
+ "Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee"
+ },
+ {
+ "ImportPath": "github.com/go-openapi/jsonpointer",
+ "Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98"
+ },
+ {
+ "ImportPath": "github.com/go-openapi/jsonreference",
+ "Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272"
+ },
+ {
+ "ImportPath": "github.com/go-openapi/spec",
+ "Rev": "7abd5745472fff5eb3685386d5fb8bf38683154d"
+ },
+ {
+ "ImportPath": "github.com/go-openapi/swag",
+ "Rev": "f3f9494671f93fcff853e3c6e9e948b3eb71e590"
+ },
+ {
+ "ImportPath": "github.com/gogo/protobuf/proto",
+ "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
+ },
+ {
+ "ImportPath": "github.com/gogo/protobuf/sortkeys",
+ "Rev": "c0656edd0d9eab7c66d1eb0c568f9039345796f7"
+ },
+ {
+ "ImportPath": "github.com/golang/glog",
+ "Rev": "44145f04b68cf362d9c4df2182967c2275eaefed"
+ },
+ {
+ "ImportPath": "github.com/golang/groupcache/lru",
+ "Rev": "02826c3e79038b59d737d3b1c0a1d937f71a4433"
+ },
+ {
+ "ImportPath": "github.com/golang/protobuf/proto",
+ "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7"
+ },
+ {
+ "ImportPath": "github.com/golang/protobuf/ptypes",
+ "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7"
+ },
+ {
+ "ImportPath": "github.com/golang/protobuf/ptypes/any",
+ "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7"
+ },
+ {
+ "ImportPath": "github.com/golang/protobuf/ptypes/duration",
+ "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7"
+ },
+ {
+ "ImportPath": "github.com/golang/protobuf/ptypes/timestamp",
+ "Rev": "4bd1920723d7b7c925de087aa32e2187708897f7"
+ },
+ {
+ "ImportPath": "github.com/google/btree",
+ "Rev": "7d79101e329e5a3adf994758c578dab82b90c017"
+ },
+ {
+ "ImportPath": "github.com/google/gofuzz",
+ "Rev": "44d81051d367757e1c7c6a5a86423ece9afcf63c"
+ },
+ {
+ "ImportPath": "github.com/googleapis/gnostic/OpenAPIv2",
+ "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
+ },
+ {
+ "ImportPath": "github.com/googleapis/gnostic/compiler",
+ "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
+ },
+ {
+ "ImportPath": "github.com/googleapis/gnostic/extensions",
+ "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
+ },
+ {
+ "ImportPath": "github.com/gregjones/httpcache",
+ "Rev": "787624de3eb7bd915c329cba748687a3b22666a6"
+ },
+ {
+ "ImportPath": "github.com/gregjones/httpcache/diskcache",
+ "Rev": "787624de3eb7bd915c329cba748687a3b22666a6"
+ },
+ {
+ "ImportPath": "github.com/hashicorp/golang-lru",
+ "Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
+ },
+ {
+ "ImportPath": "github.com/hashicorp/golang-lru/simplelru",
+ "Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
+ },
+ {
+ "ImportPath": "github.com/howeyc/gopass",
+ "Rev": "bf9dde6d0d2c004a008c27aaee91170c786f6db8"
+ },
+ {
+ "ImportPath": "github.com/imdario/mergo",
+ "Rev": "6633656539c1639d9d78127b7d47c622b5d7b6dc"
+ },
+ {
+ "ImportPath": "github.com/json-iterator/go",
+ "Rev": "36b14963da70d11297d313183d7e6388c8510e1e"
+ },
+ {
+ "ImportPath": "github.com/juju/ratelimit",
+ "Rev": "5b9ff866471762aa2ab2dced63c9fb6f53921342"
+ },
+ {
+ "ImportPath": "github.com/mailru/easyjson/buffer",
+ "Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
+ },
+ {
+ "ImportPath": "github.com/mailru/easyjson/jlexer",
+ "Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
+ },
+ {
+ "ImportPath": "github.com/mailru/easyjson/jwriter",
+ "Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
+ },
+ {
+ "ImportPath": "github.com/peterbourgon/diskv",
+ "Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
+ },
+ {
+ "ImportPath": "github.com/spf13/pflag",
+ "Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
+ },
+ {
+ "ImportPath": "golang.org/x/crypto/ssh/terminal",
+ "Rev": "81e90905daefcd6fd217b62423c0908922eadb30"
+ },
+ {
+ "ImportPath": "golang.org/x/net/context",
+ "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f"
+ },
+ {
+ "ImportPath": "golang.org/x/net/http2",
+ "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f"
+ },
+ {
+ "ImportPath": "golang.org/x/net/http2/hpack",
+ "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f"
+ },
+ {
+ "ImportPath": "golang.org/x/net/idna",
+ "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f"
+ },
+ {
+ "ImportPath": "golang.org/x/net/lex/httplex",
+ "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f"
+ },
+ {
+ "ImportPath": "golang.org/x/sys/unix",
+ "Rev": "7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce"
+ },
+ {
+ "ImportPath": "golang.org/x/sys/windows",
+ "Rev": "7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce"
+ },
+ {
+ "ImportPath": "golang.org/x/text/cases",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/internal",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/internal/tag",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/language",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/runes",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/secure/bidirule",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/secure/precis",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/transform",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/unicode/bidi",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/unicode/norm",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "golang.org/x/text/width",
+ "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01"
+ },
+ {
+ "ImportPath": "gopkg.in/inf.v0",
+ "Rev": "3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4"
+ },
+ {
+ "ImportPath": "gopkg.in/yaml.v2",
+ "Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77"
+ },
+ {
+ "ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/apps/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/apps/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/apps/v1beta2",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/authentication/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/authentication/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/authorization/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/authorization/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/autoscaling/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/autoscaling/v2beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/batch/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/batch/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/batch/v2alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/certificates/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/core/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/extensions/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/networking/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/policy/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/rbac/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/rbac/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/rbac/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/scheduling/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/settings/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/storage/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/api/storage/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/api/equality",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/api/errors",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/api/meta",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/api/resource",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/conversion",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/fields",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/labels",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/runtime",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/selection",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/types",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/cache",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/clock",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/diff",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/errors",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/framer",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/json",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/net",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/sets",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/validation",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/wait",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/version",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/pkg/watch",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/discovery",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/discovery/fake",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/admissionregistration",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/admissionregistration/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/apps",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/apps/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/apps/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/apps/v1beta2",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/autoscaling",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/autoscaling/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/autoscaling/v2beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/batch",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/batch/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/batch/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/batch/v2alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/certificates",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/certificates/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/core",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/core/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/extensions",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/extensions/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/internalinterfaces",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/networking",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/networking/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/policy",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/policy/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/rbac",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/rbac/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/rbac/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/rbac/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/scheduling",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/scheduling/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/settings",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/settings/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/storage",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/storage/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/informers/storage/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/scheme",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta2",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v2alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/certificates/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/core/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/extensions/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/networking/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/policy/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/settings/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/admissionregistration/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/apps/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/apps/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/apps/v1beta2",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/autoscaling/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/autoscaling/v2beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/batch/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/batch/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/batch/v2alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/certificates/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/core/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/extensions/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/networking/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/policy/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/rbac/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/rbac/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/rbac/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/scheduling/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/settings/v1alpha1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/storage/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/listers/storage/v1beta1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/pkg/version",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/rest",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/rest/watch",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/testing",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/auth",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/cache",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/clientcmd",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/clientcmd/api",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/clientcmd/api/latest",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/clientcmd/api/v1",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/metrics",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/pager",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/record",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/tools/reference",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/transport",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/util/buffer",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/util/cert",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/util/flowcontrol",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/util/homedir",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/util/integer",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/client-go/util/workqueue",
+ "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ },
+ {
+ "ImportPath": "k8s.io/kube-openapi/pkg/common",
+ "Rev": "868f2f29720b192240e18284659231b440f9cda5"
+ }
+ ]
+}
diff --git a/staging/src/k8s.io/sample-controller/Godeps/Readme b/staging/src/k8s.io/sample-controller/Godeps/Readme
new file mode 100644
index 00000000000..4cdaa53d56d
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/Godeps/Readme
@@ -0,0 +1,5 @@
+This directory tree is generated automatically by godep.
+
+Please do not edit.
+
+See https://github.com/tools/godep for more information.
diff --git a/staging/src/k8s.io/sample-controller/LICENSE b/staging/src/k8s.io/sample-controller/LICENSE
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/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/staging/src/k8s.io/sample-controller/OWNERS b/staging/src/k8s.io/sample-controller/OWNERS
new file mode 100644
index 00000000000..2a55092e9f3
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/OWNERS
@@ -0,0 +1,9 @@
+approvers:
+- sttts
+- munnerz
+reviewers:
+- gregory-m
+- kargakis
+- sttts
+- munnerz
+- nikhita
diff --git a/staging/src/k8s.io/sample-controller/README.md b/staging/src/k8s.io/sample-controller/README.md
new file mode 100644
index 00000000000..a3948929617
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/README.md
@@ -0,0 +1,34 @@
+# sample-controller
+
+This repository implements a simple controller for watching Foo resources as
+defined with a CustomResourceDefinition (CRD).
+
+It makes use of the generators in [k8s.io/code-generator](https://github.com/kubernetes/code-generator)
+to generate a typed client, informers, listers and deep-copy functions. You can
+do this yourself using the `./hack/update-codegen.sh` script.
+
+The `update-codegen` script will automatically generate the following files &
+directories:
+
+* `pkg/apis/samplecontroller/v1alpha1/zz_generated.deepcopy.go`
+* `pkg/client/`
+
+Changes should not be made to these files manually, and when creating your own
+controller based off of this implementation you should not copy these files and
+instead run the `update-codegen` script to generate your own.
+
+# Purpose
+
+This is an example of how to build a kube-like controller with a single type.
+
+# Compatibility
+
+HEAD of this repository will match HEAD of k8s.io/apimachinery and
+k8s.io/client-go.
+
+# Where does it come from?
+
+`sample-controller` is synced from
+https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/sample-controller.
+Code changes are made in that location, merged into k8s.io/kubernetes and
+later synced here.
diff --git a/staging/src/k8s.io/sample-controller/artifacts/examples/crd.yaml b/staging/src/k8s.io/sample-controller/artifacts/examples/crd.yaml
new file mode 100644
index 00000000000..4a457068dcd
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/artifacts/examples/crd.yaml
@@ -0,0 +1,11 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: foos.samplecontroller.k8s.io
+spec:
+ group: samplecontroller.k8s.io
+ version: v1alpha1
+ names:
+ kind: Foo
+ plural: foos
+ scope: Namespaced
diff --git a/staging/src/k8s.io/sample-controller/artifacts/examples/example-foo.yaml b/staging/src/k8s.io/sample-controller/artifacts/examples/example-foo.yaml
new file mode 100644
index 00000000000..897059c3d0c
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/artifacts/examples/example-foo.yaml
@@ -0,0 +1,7 @@
+apiVersion: samplecontroller.k8s.io/v1alpha1
+kind: Foo
+metadata:
+ name: example-foo
+spec:
+ deploymentName: example-foo
+ replicas: 1
diff --git a/staging/src/k8s.io/sample-controller/controller.go b/staging/src/k8s.io/sample-controller/controller.go
new file mode 100644
index 00000000000..9ca22f6f8a5
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/controller.go
@@ -0,0 +1,431 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/golang/glog"
+ appsv1beta2 "k8s.io/api/apps/v1beta2"
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/util/runtime"
+ "k8s.io/apimachinery/pkg/util/wait"
+ kubeinformers "k8s.io/client-go/informers"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/kubernetes/scheme"
+ typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
+ appslisters "k8s.io/client-go/listers/apps/v1beta2"
+ "k8s.io/client-go/tools/cache"
+ "k8s.io/client-go/tools/record"
+ "k8s.io/client-go/util/workqueue"
+
+ samplev1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
+ clientset "k8s.io/sample-controller/pkg/client/clientset/versioned"
+ samplescheme "k8s.io/sample-controller/pkg/client/clientset/versioned/scheme"
+ informers "k8s.io/sample-controller/pkg/client/informers/externalversions"
+ listers "k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1"
+)
+
+const controllerAgentName = "sample-controller"
+
+const (
+ // SuccessSynced is used as part of the Event 'reason' when a Foo is synced
+ SuccessSynced = "Synced"
+ // ErrResourceExists is used as part of the Event 'reason' when a Foo fails
+ // to sync due to a Deployment of the same name already existing.
+ ErrResourceExists = "ErrResourceExists"
+
+ // MessageResourceExists is the message used for Events when a resource
+ // fails to sync due to a Deployment already existing
+ MessageResourceExists = "Resource %q already exists and is not managed by Foo"
+ // MessageResourceSynced is the message used for an Event fired when a Foo
+ // is synced successfully
+ MessageResourceSynced = "Foo synced successfully"
+)
+
+// Controller is the controller implementation for Foo resources
+type Controller struct {
+ // kubeclientset is a standard kubernetes clientset
+ kubeclientset kubernetes.Interface
+ // sampleclientset is a clientset for our own API group
+ sampleclientset clientset.Interface
+
+ deploymentsLister appslisters.DeploymentLister
+ deploymentsSynced cache.InformerSynced
+ foosLister listers.FooLister
+ foosSynced cache.InformerSynced
+
+ // workqueue is a rate limited work queue. This is used to queue work to be
+ // processed instead of performing it as soon as a change happens. This
+ // means we can ensure we only process a fixed amount of resources at a
+ // time, and makes it easy to ensure we are never processing the same item
+ // simultaneously in two different workers.
+ workqueue workqueue.RateLimitingInterface
+ // recorder is an event recorder for recording Event resources to the
+ // Kubernetes API.
+ recorder record.EventRecorder
+}
+
+// NewController returns a new sample controller
+func NewController(
+ kubeclientset kubernetes.Interface,
+ sampleclientset clientset.Interface,
+ kubeInformerFactory kubeinformers.SharedInformerFactory,
+ sampleInformerFactory informers.SharedInformerFactory) *Controller {
+
+ // obtain references to shared index informers for the Deployment and Foo
+ // types.
+ deploymentInformer := kubeInformerFactory.Apps().V1beta2().Deployments()
+ fooInformer := sampleInformerFactory.Samplecontroller().V1alpha1().Foos()
+
+ // Create event broadcaster
+ // Add sample-controller types to the default Kubernetes Scheme so Events can be
+ // logged for sample-controller types.
+ samplescheme.AddToScheme(scheme.Scheme)
+ glog.V(4).Info("Creating event broadcaster")
+ eventBroadcaster := record.NewBroadcaster()
+ eventBroadcaster.StartLogging(glog.Infof)
+ eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeclientset.CoreV1().Events("")})
+ recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName})
+
+ controller := &Controller{
+ kubeclientset: kubeclientset,
+ sampleclientset: sampleclientset,
+ deploymentsLister: deploymentInformer.Lister(),
+ deploymentsSynced: deploymentInformer.Informer().HasSynced,
+ foosLister: fooInformer.Lister(),
+ foosSynced: fooInformer.Informer().HasSynced,
+ workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Foos"),
+ recorder: recorder,
+ }
+
+ glog.Info("Setting up event handlers")
+ // Set up an event handler for when Foo resources change
+ fooInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
+ AddFunc: controller.enqueueFoo,
+ UpdateFunc: func(old, new interface{}) {
+ controller.enqueueFoo(new)
+ },
+ })
+ // Set up an event handler for when Deployment resources change. This
+ // handler will lookup the owner of the given Deployment, and if it is
+ // owned by a Foo resource will enqueue that Foo resource for
+ // processing. This way, we don't need to implement custom logic for
+ // handling Deployment resources. More info on this pattern:
+ // https://github.com/kubernetes/community/blob/8cafef897a22026d42f5e5bb3f104febe7e29830/contributors/devel/controllers.md
+ deploymentInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
+ AddFunc: controller.handleObject,
+ UpdateFunc: func(old, new interface{}) {
+ newDepl := new.(*appsv1beta2.Deployment)
+ oldDepl := old.(*appsv1beta2.Deployment)
+ if newDepl.ResourceVersion == oldDepl.ResourceVersion {
+ // Periodic resync will send update events for all known Deployments.
+ // Two different versions of the same Deployment will always have different RVs.
+ return
+ }
+ controller.handleObject(new)
+ },
+ DeleteFunc: controller.handleObject,
+ })
+
+ return controller
+}
+
+// Run will set up the event handlers for types we are interested in, as well
+// as syncing informer caches and starting workers. It will block until stopCh
+// is closed, at which point it will shutdown the workqueue and wait for
+// workers to finish processing their current work items.
+func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error {
+ defer runtime.HandleCrash()
+ defer c.workqueue.ShutDown()
+
+ // Start the informer factories to begin populating the informer caches
+ glog.Info("Starting Foo controller")
+
+ // Wait for the caches to be synced before starting workers
+ glog.Info("Waiting for informer caches to sync")
+ if ok := cache.WaitForCacheSync(stopCh, c.deploymentsSynced, c.foosSynced); !ok {
+ return fmt.Errorf("failed to wait for caches to sync")
+ }
+
+ glog.Info("Starting workers")
+ // Launch two workers to process Foo resources
+ for i := 0; i < threadiness; i++ {
+ go wait.Until(c.runWorker, time.Second, stopCh)
+ }
+
+ glog.Info("Started workers")
+ <-stopCh
+ glog.Info("Shutting down workers")
+
+ return nil
+}
+
+// runWorker is a long-running function that will continually call the
+// processNextWorkItem function in order to read and process a message on the
+// workqueue.
+func (c *Controller) runWorker() {
+ for c.processNextWorkItem() {
+ }
+}
+
+// processNextWorkItem will read a single work item off the workqueue and
+// attempt to process it, by calling the syncHandler.
+func (c *Controller) processNextWorkItem() bool {
+ obj, shutdown := c.workqueue.Get()
+
+ if shutdown {
+ return false
+ }
+
+ // We wrap this block in a func so we can defer c.workqueue.Done.
+ err := func(obj interface{}) error {
+ // We call Done here so the workqueue knows we have finished
+ // processing this item. We also must remember to call Forget if we
+ // do not want this work item being re-queued. For example, we do
+ // not call Forget if a transient error occurs, instead the item is
+ // put back on the workqueue and attempted again after a back-off
+ // period.
+ defer c.workqueue.Done(obj)
+ var key string
+ var ok bool
+ // We expect strings to come off the workqueue. These are of the
+ // form namespace/name. We do this as the delayed nature of the
+ // workqueue means the items in the informer cache may actually be
+ // more up to date that when the item was initially put onto the
+ // workqueue.
+ if key, ok = obj.(string); !ok {
+ // As the item in the workqueue is actually invalid, we call
+ // Forget here else we'd go into a loop of attempting to
+ // process a work item that is invalid.
+ c.workqueue.Forget(obj)
+ runtime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj))
+ return nil
+ }
+ // Run the syncHandler, passing it the namespace/name string of the
+ // Foo resource to be synced.
+ if err := c.syncHandler(key); err != nil {
+ return fmt.Errorf("error syncing '%s': %s", key, err.Error())
+ }
+ // Finally, if no error occurs we Forget this item so it does not
+ // get queued again until another change happens.
+ c.workqueue.Forget(obj)
+ glog.Infof("Successfully synced '%s'", key)
+ return nil
+ }(obj)
+
+ if err != nil {
+ runtime.HandleError(err)
+ return true
+ }
+
+ return true
+}
+
+// syncHandler compares the actual state with the desired, and attempts to
+// converge the two. It then updates the Status block of the Foo resource
+// with the current status of the resource.
+func (c *Controller) syncHandler(key string) error {
+ // Convert the namespace/name string into a distinct namespace and name
+ namespace, name, err := cache.SplitMetaNamespaceKey(key)
+ if err != nil {
+ runtime.HandleError(fmt.Errorf("invalid resource key: %s", key))
+ return nil
+ }
+
+ // Get the Foo resource with this namespace/name
+ foo, err := c.foosLister.Foos(namespace).Get(name)
+ if err != nil {
+ // The Foo resource may no longer exist, in which case we stop
+ // processing.
+ if errors.IsNotFound(err) {
+ runtime.HandleError(fmt.Errorf("foo '%s' in work queue no longer exists", key))
+ return nil
+ }
+
+ return err
+ }
+
+ deploymentName := foo.Spec.DeploymentName
+ if deploymentName == "" {
+ // We choose to absorb the error here as the worker would requeue the
+ // resource otherwise. Instead, the next time the resource is updated
+ // the resource will be queued again.
+ runtime.HandleError(fmt.Errorf("%s: deployment name must be specified", key))
+ return nil
+ }
+
+ // Get the deployment with the name specified in Foo.spec
+ deployment, err := c.deploymentsLister.Deployments(foo.Namespace).Get(deploymentName)
+ // If the resource doesn't exist, we'll create it
+ if errors.IsNotFound(err) {
+ deployment, err = c.kubeclientset.AppsV1beta2().Deployments(foo.Namespace).Create(newDeployment(foo))
+ }
+
+ // If an error occurs during Get/Create, we'll requeue the item so we can
+ // attempt processing again later. This could have been caused by a
+ // temporary network failure, or any other transient reason.
+ if err != nil {
+ return err
+ }
+
+ // If the Deployment is not controlled by this Foo resource, we should log
+ // a warning to the event recorder and ret
+ if !metav1.IsControlledBy(deployment, foo) {
+ msg := fmt.Sprintf(MessageResourceExists, deployment.Name)
+ c.recorder.Event(foo, corev1.EventTypeWarning, ErrResourceExists, msg)
+ return fmt.Errorf(msg)
+ }
+
+ // If this number of the replicas on the Foo resource is specified, and the
+ // number does not equal the current desired replicas on the Deployment, we
+ // should update the Deployment resource.
+ if foo.Spec.Replicas != nil && *foo.Spec.Replicas != *deployment.Spec.Replicas {
+ glog.V(4).Infof("Foor: %d, deplR: %d", *foo.Spec.Replicas, *deployment.Spec.Replicas)
+ deployment, err = c.kubeclientset.AppsV1beta2().Deployments(foo.Namespace).Update(newDeployment(foo))
+ }
+
+ // If an error occurs during Update, we'll requeue the item so we can
+ // attempt processing again later. THis could have been caused by a
+ // temporary network failure, or any other transient reason.
+ if err != nil {
+ return err
+ }
+
+ // Finally, we update the status block of the Foo resource to reflect the
+ // current state of the world
+ err = c.updateFooStatus(foo, deployment)
+ if err != nil {
+ return err
+ }
+
+ c.recorder.Event(foo, corev1.EventTypeNormal, SuccessSynced, MessageResourceSynced)
+ return nil
+}
+
+func (c *Controller) updateFooStatus(foo *samplev1alpha1.Foo, deployment *appsv1beta2.Deployment) error {
+ // NEVER modify objects from the store. It's a read-only, local cache.
+ // You can use DeepCopy() to make a deep copy of original object and modify this copy
+ // Or create a copy manually for better performance
+ fooCopy := foo.DeepCopy()
+ fooCopy.Status.AvailableReplicas = deployment.Status.AvailableReplicas
+ // Until #38113 is merged, we must use Update instead of UpdateStatus to
+ // update the Status block of the Foo resource. UpdateStatus will not
+ // allow changes to the Spec of the resource, which is ideal for ensuring
+ // nothing other than resource status has been updated.
+ _, err := c.sampleclientset.SamplecontrollerV1alpha1().Foos(foo.Namespace).Update(fooCopy)
+ return err
+}
+
+// enqueueFoo takes a Foo resource and converts it into a namespace/name
+// string which is then put onto the work queue. This method should *not* be
+// passed resources of any type other than Foo.
+func (c *Controller) enqueueFoo(obj interface{}) {
+ var key string
+ var err error
+ if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil {
+ runtime.HandleError(err)
+ return
+ }
+ c.workqueue.AddRateLimited(key)
+}
+
+// handleObject will take any resource implementing metav1.Object and attempt
+// to find the Foo resource that 'owns' it. It does this by looking at the
+// objects metadata.ownerReferences field for an appropriate OwnerReference.
+// It then enqueues that Foo resource to be processed. If the object does not
+// have an appropriate OwnerReference, it will simply be skipped.
+func (c *Controller) handleObject(obj interface{}) {
+ var object metav1.Object
+ var ok bool
+ if object, ok = obj.(metav1.Object); !ok {
+ tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
+ if !ok {
+ runtime.HandleError(fmt.Errorf("error decoding object, invalid type"))
+ return
+ }
+ object, ok = tombstone.Obj.(metav1.Object)
+ if !ok {
+ runtime.HandleError(fmt.Errorf("error decoding object tombstone, invalid type"))
+ return
+ }
+ glog.V(4).Infof("Recovered deleted object '%s' from tombstone", object.GetName())
+ }
+ glog.V(4).Infof("Processing object: %s", object.GetName())
+ if ownerRef := metav1.GetControllerOf(object); ownerRef != nil {
+ // If this object is not owned by a Foo, we should not do anything more
+ // with it.
+ if ownerRef.Kind != "Foo" {
+ return
+ }
+
+ foo, err := c.foosLister.Foos(object.GetNamespace()).Get(ownerRef.Name)
+ if err != nil {
+ glog.V(4).Infof("ignoring orphaned object '%s' of foo '%s'", object.GetSelfLink(), ownerRef.Name)
+ return
+ }
+
+ c.enqueueFoo(foo)
+ return
+ }
+}
+
+// newDeployment creates a new Deployment for a Foo resource. It also sets
+// the appropriate OwnerReferences on the resource so handleObject can discover
+// the Foo resource that 'owns' it.
+func newDeployment(foo *samplev1alpha1.Foo) *appsv1beta2.Deployment {
+ labels := map[string]string{
+ "app": "nginx",
+ "controller": foo.Name,
+ }
+ return &appsv1beta2.Deployment{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: foo.Spec.DeploymentName,
+ Namespace: foo.Namespace,
+ OwnerReferences: []metav1.OwnerReference{
+ *metav1.NewControllerRef(foo, schema.GroupVersionKind{
+ Group: samplev1alpha1.SchemeGroupVersion.Group,
+ Version: samplev1alpha1.SchemeGroupVersion.Version,
+ Kind: "Foo",
+ }),
+ },
+ },
+ Spec: appsv1beta2.DeploymentSpec{
+ Replicas: foo.Spec.Replicas,
+ Selector: &metav1.LabelSelector{
+ MatchLabels: labels,
+ },
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: labels,
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "nginx",
+ Image: "nginx:latest",
+ },
+ },
+ },
+ },
+ },
+ }
+}
diff --git a/staging/src/k8s.io/sample-controller/hack/custom-boilerplate.go.txt b/staging/src/k8s.io/sample-controller/hack/custom-boilerplate.go.txt
new file mode 100644
index 00000000000..e4cd20e3808
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/hack/custom-boilerplate.go.txt
@@ -0,0 +1,16 @@
+/*
+Copyright YEAR The Kubernetes sample-controller Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
diff --git a/staging/src/k8s.io/sample-controller/hack/update-codegen.sh b/staging/src/k8s.io/sample-controller/hack/update-codegen.sh
new file mode 100755
index 00000000000..d0fd734f75a
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/hack/update-codegen.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+# Copyright 2017 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
+CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)}
+
+# generate the code with:
+# --output-base because this script should also be able to run inside the vendor dir of
+# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir
+# instead of the $GOPATH directly. For normal projects this can be dropped.
+${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \
+ k8s.io/sample-controller/pkg/client k8s.io/sample-controller/pkg/apis \
+ samplecontroller:v1alpha1 \
+ --output-base "$(dirname ${BASH_SOURCE})/../../.."
+
+# To use your own boilerplate text append:
+# --go-header-file ${SCRIPT_ROOT}/hack/custom-boilerplate.go.txt
diff --git a/staging/src/k8s.io/sample-controller/hack/verify-codegen.sh b/staging/src/k8s.io/sample-controller/hack/verify-codegen.sh
new file mode 100755
index 00000000000..9cc02a5a4a2
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/hack/verify-codegen.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# Copyright 2017 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/..
+
+DIFFROOT="${SCRIPT_ROOT}/pkg"
+TMP_DIFFROOT="${SCRIPT_ROOT}/_tmp/pkg"
+_tmp="${SCRIPT_ROOT}/_tmp"
+
+cleanup() {
+ rm -rf "${_tmp}"
+}
+trap "cleanup" EXIT SIGINT
+
+cleanup
+
+mkdir -p "${TMP_DIFFROOT}"
+cp -a "${DIFFROOT}"/* "${TMP_DIFFROOT}"
+
+"${SCRIPT_ROOT}/hack/update-codegen.sh"
+echo "diffing ${DIFFROOT} against freshly generated codegen"
+ret=0
+diff -Naupr "${DIFFROOT}" "${TMP_DIFFROOT}" || ret=$?
+cp -a "${TMP_DIFFROOT}"/* "${DIFFROOT}"
+if [[ $ret -eq 0 ]]
+then
+ echo "${DIFFROOT} up to date."
+else
+ echo "${DIFFROOT} is out of date. Please run hack/update-codegen.sh"
+ exit 1
+fi
diff --git a/staging/src/k8s.io/sample-controller/main.go b/staging/src/k8s.io/sample-controller/main.go
new file mode 100644
index 00000000000..d3514fc3a5d
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/main.go
@@ -0,0 +1,77 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+ "flag"
+ "time"
+
+ "github.com/golang/glog"
+ kubeinformers "k8s.io/client-go/informers"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/tools/clientcmd"
+ // Uncomment the following line to load the gcp plugin (only required to authenticate against GKE clusters).
+ // _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
+
+ clientset "k8s.io/sample-controller/pkg/client/clientset/versioned"
+ informers "k8s.io/sample-controller/pkg/client/informers/externalversions"
+ "k8s.io/sample-controller/pkg/signals"
+)
+
+var (
+ masterURL string
+ kubeconfig string
+)
+
+func main() {
+ flag.Parse()
+
+ // set up signals so we handle the first shutdown signal gracefully
+ stopCh := signals.SetupSignalHandler()
+
+ cfg, err := clientcmd.BuildConfigFromFlags(masterURL, kubeconfig)
+ if err != nil {
+ glog.Fatalf("Error building kubeconfig: %s", err.Error())
+ }
+
+ kubeClient, err := kubernetes.NewForConfig(cfg)
+ if err != nil {
+ glog.Fatalf("Error building kubernetes clientset: %s", err.Error())
+ }
+
+ exampleClient, err := clientset.NewForConfig(cfg)
+ if err != nil {
+ glog.Fatalf("Error building example clientset: %s", err.Error())
+ }
+
+ kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, time.Second*30)
+ exampleInformerFactory := informers.NewSharedInformerFactory(exampleClient, time.Second*30)
+
+ controller := NewController(kubeClient, exampleClient, kubeInformerFactory, exampleInformerFactory)
+
+ go kubeInformerFactory.Start(stopCh)
+ go exampleInformerFactory.Start(stopCh)
+
+ if err = controller.Run(2, stopCh); err != nil {
+ glog.Fatalf("Error running controller: %s", err.Error())
+ }
+}
+
+func init() {
+ flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
+ flag.StringVar(&masterURL, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/BUILD b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/BUILD
new file mode 100644
index 00000000000..8fc8dfc80ae
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/BUILD
@@ -0,0 +1,25 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = ["register.go"],
+ importpath = "k8s.io/sample-controller/pkg/apis/samplecontroller",
+ visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [
+ ":package-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:all-srcs",
+ ],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/register.go b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/register.go
new file mode 100644
index 00000000000..394f7967e2b
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/register.go
@@ -0,0 +1,21 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package samplecontroller
+
+const (
+ GroupName = "samplecontroller.k8s.io"
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/BUILD b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/BUILD
new file mode 100644
index 00000000000..adc455441af
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/BUILD
@@ -0,0 +1,34 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "doc.go",
+ "register.go",
+ "types.go",
+ "zz_generated.deepcopy.go",
+ ],
+ importpath = "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/doc.go b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/doc.go
new file mode 100644
index 00000000000..bf65b19df2f
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/doc.go
@@ -0,0 +1,21 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// +k8s:deepcopy-gen=package,register
+
+// Package v1alpha1 is the v1alpha1 version of the API.
+// +groupName=samplecontroller.k8s.io
+package v1alpha1
diff --git a/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/register.go b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/register.go
new file mode 100644
index 00000000000..e72b4034b93
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/register.go
@@ -0,0 +1,57 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+
+ samplecontroller "k8s.io/sample-controller/pkg/apis/samplecontroller"
+)
+
+// SchemeGroupVersion is group version used to register these objects
+var SchemeGroupVersion = schema.GroupVersion{Group: samplecontroller.GroupName, Version: "v1alpha1"}
+
+// Resource takes an unqualified resource and returns a Group qualified GroupResource
+func Resource(resource string) schema.GroupResource {
+ return SchemeGroupVersion.WithResource(resource).GroupResource()
+}
+
+var (
+ // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
+ SchemeBuilder runtime.SchemeBuilder
+ localSchemeBuilder = &SchemeBuilder
+ AddToScheme = localSchemeBuilder.AddToScheme
+)
+
+func init() {
+ // We only register manually written functions here. The registration of the
+ // generated functions takes place in the generated files. The separation
+ // makes the code compile even when the generated files are missing.
+ localSchemeBuilder.Register(addKnownTypes)
+}
+
+// Adds the list of known types to api.Scheme.
+func addKnownTypes(scheme *runtime.Scheme) error {
+ scheme.AddKnownTypes(SchemeGroupVersion,
+ &Foo{},
+ &FooList{},
+ )
+ metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
+ return nil
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/types.go b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/types.go
new file mode 100644
index 00000000000..8f071033f54
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/types.go
@@ -0,0 +1,57 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// +genclient
+// +genclient:noStatus
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// +resource:path=foo
+
+// Foo is a specification for a Foo resource
+type Foo struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec FooSpec `json:"spec"`
+ Status FooStatus `json:"status"`
+}
+
+// FooSpec is the spec for a Foo resource
+type FooSpec struct {
+ DeploymentName string `json:"deploymentName"`
+ Replicas *int32 `json:"replicas"`
+}
+
+// FooStatus is the status for a Foo resource
+type FooStatus struct {
+ AvailableReplicas int32 `json:"availableReplicas"`
+}
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+// +resource:path=foos
+
+// FooList is a list of Foo resources
+type FooList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata"`
+
+ Items []Foo `json:"items"`
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/zz_generated.deepcopy.go b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/zz_generated.deepcopy.go
new file mode 100644
index 00000000000..ca85b4011a8
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1/zz_generated.deepcopy.go
@@ -0,0 +1,160 @@
+// +build !ignore_autogenerated
+
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This file was autogenerated by deepcopy-gen. Do not edit it manually!
+
+package v1alpha1
+
+import (
+ conversion "k8s.io/apimachinery/pkg/conversion"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ reflect "reflect"
+)
+
+func init() {
+ SchemeBuilder.Register(RegisterDeepCopies)
+}
+
+// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
+// to allow building arbitrary schemes.
+//
+// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
+func RegisterDeepCopies(scheme *runtime.Scheme) error {
+ return scheme.AddGeneratedDeepCopyFuncs(
+ conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
+ in.(*Foo).DeepCopyInto(out.(*Foo))
+ return nil
+ }, InType: reflect.TypeOf(&Foo{})},
+ conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
+ in.(*FooList).DeepCopyInto(out.(*FooList))
+ return nil
+ }, InType: reflect.TypeOf(&FooList{})},
+ conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
+ in.(*FooSpec).DeepCopyInto(out.(*FooSpec))
+ return nil
+ }, InType: reflect.TypeOf(&FooSpec{})},
+ conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
+ in.(*FooStatus).DeepCopyInto(out.(*FooStatus))
+ return nil
+ }, InType: reflect.TypeOf(&FooStatus{})},
+ )
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Foo) DeepCopyInto(out *Foo) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ out.Status = in.Status
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Foo.
+func (in *Foo) DeepCopy() *Foo {
+ if in == nil {
+ return nil
+ }
+ out := new(Foo)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Foo) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ } else {
+ return nil
+ }
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FooList) DeepCopyInto(out *FooList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ out.ListMeta = in.ListMeta
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]Foo, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooList.
+func (in *FooList) DeepCopy() *FooList {
+ if in == nil {
+ return nil
+ }
+ out := new(FooList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *FooList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ } else {
+ return nil
+ }
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FooSpec) DeepCopyInto(out *FooSpec) {
+ *out = *in
+ if in.Replicas != nil {
+ in, out := &in.Replicas, &out.Replicas
+ if *in == nil {
+ *out = nil
+ } else {
+ *out = new(int32)
+ **out = **in
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooSpec.
+func (in *FooSpec) DeepCopy() *FooSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(FooSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FooStatus) DeepCopyInto(out *FooStatus) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooStatus.
+func (in *FooStatus) DeepCopy() *FooStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(FooStatus)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/BUILD
new file mode 100644
index 00000000000..d208e963c71
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/BUILD
@@ -0,0 +1,37 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "clientset.go",
+ "doc.go",
+ ],
+ importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/github.com/golang/glog:go_default_library",
+ "//vendor/k8s.io/client-go/discovery:go_default_library",
+ "//vendor/k8s.io/client-go/rest:go_default_library",
+ "//vendor/k8s.io/client-go/util/flowcontrol:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [
+ ":package-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake:all-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme:all-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1:all-srcs",
+ ],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/clientset.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/clientset.go
new file mode 100644
index 00000000000..ee1011cb303
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/clientset.go
@@ -0,0 +1,98 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package versioned
+
+import (
+ glog "github.com/golang/glog"
+ discovery "k8s.io/client-go/discovery"
+ rest "k8s.io/client-go/rest"
+ flowcontrol "k8s.io/client-go/util/flowcontrol"
+ samplecontrollerv1alpha1 "k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1"
+)
+
+type Interface interface {
+ Discovery() discovery.DiscoveryInterface
+ SamplecontrollerV1alpha1() samplecontrollerv1alpha1.SamplecontrollerV1alpha1Interface
+ // Deprecated: please explicitly pick a version if possible.
+ Samplecontroller() samplecontrollerv1alpha1.SamplecontrollerV1alpha1Interface
+}
+
+// Clientset contains the clients for groups. Each group has exactly one
+// version included in a Clientset.
+type Clientset struct {
+ *discovery.DiscoveryClient
+ samplecontrollerV1alpha1 *samplecontrollerv1alpha1.SamplecontrollerV1alpha1Client
+}
+
+// SamplecontrollerV1alpha1 retrieves the SamplecontrollerV1alpha1Client
+func (c *Clientset) SamplecontrollerV1alpha1() samplecontrollerv1alpha1.SamplecontrollerV1alpha1Interface {
+ return c.samplecontrollerV1alpha1
+}
+
+// Deprecated: Samplecontroller retrieves the default version of SamplecontrollerClient.
+// Please explicitly pick a version.
+func (c *Clientset) Samplecontroller() samplecontrollerv1alpha1.SamplecontrollerV1alpha1Interface {
+ return c.samplecontrollerV1alpha1
+}
+
+// Discovery retrieves the DiscoveryClient
+func (c *Clientset) Discovery() discovery.DiscoveryInterface {
+ if c == nil {
+ return nil
+ }
+ return c.DiscoveryClient
+}
+
+// NewForConfig creates a new Clientset for the given config.
+func NewForConfig(c *rest.Config) (*Clientset, error) {
+ configShallowCopy := *c
+ if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
+ configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
+ }
+ var cs Clientset
+ var err error
+ cs.samplecontrollerV1alpha1, err = samplecontrollerv1alpha1.NewForConfig(&configShallowCopy)
+ if err != nil {
+ return nil, err
+ }
+
+ cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
+ if err != nil {
+ glog.Errorf("failed to create the DiscoveryClient: %v", err)
+ return nil, err
+ }
+ return &cs, nil
+}
+
+// NewForConfigOrDie creates a new Clientset for the given config and
+// panics if there is an error in the config.
+func NewForConfigOrDie(c *rest.Config) *Clientset {
+ var cs Clientset
+ cs.samplecontrollerV1alpha1 = samplecontrollerv1alpha1.NewForConfigOrDie(c)
+
+ cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
+ return &cs
+}
+
+// New creates a new Clientset for the given RESTClient.
+func New(c rest.Interface) *Clientset {
+ var cs Clientset
+ cs.samplecontrollerV1alpha1 = samplecontrollerv1alpha1.New(c)
+
+ cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
+ return &cs
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/doc.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/doc.go
new file mode 100644
index 00000000000..7d2f4d80d3a
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/doc.go
@@ -0,0 +1,18 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This package has the automatically generated clientset.
+package versioned
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/BUILD
new file mode 100644
index 00000000000..55fb43e1d18
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/BUILD
@@ -0,0 +1,40 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "clientset_generated.go",
+ "doc.go",
+ "register.go",
+ ],
+ importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned/fake",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
+ "//vendor/k8s.io/client-go/discovery:go_default_library",
+ "//vendor/k8s.io/client-go/discovery/fake:go_default_library",
+ "//vendor/k8s.io/client-go/testing:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/clientset_generated.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/clientset_generated.go
new file mode 100644
index 00000000000..864cfe59b70
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/clientset_generated.go
@@ -0,0 +1,71 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package fake
+
+import (
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/watch"
+ "k8s.io/client-go/discovery"
+ fakediscovery "k8s.io/client-go/discovery/fake"
+ "k8s.io/client-go/testing"
+ clientset "k8s.io/sample-controller/pkg/client/clientset/versioned"
+ samplecontrollerv1alpha1 "k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1"
+ fakesamplecontrollerv1alpha1 "k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake"
+)
+
+// NewSimpleClientset returns a clientset that will respond with the provided objects.
+// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
+// without applying any validations and/or defaults. It shouldn't be considered a replacement
+// for a real clientset and is mostly useful in simple unit tests.
+func NewSimpleClientset(objects ...runtime.Object) *Clientset {
+ o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
+ for _, obj := range objects {
+ if err := o.Add(obj); err != nil {
+ panic(err)
+ }
+ }
+
+ fakePtr := testing.Fake{}
+ fakePtr.AddReactor("*", "*", testing.ObjectReaction(o))
+ fakePtr.AddWatchReactor("*", testing.DefaultWatchReactor(watch.NewFake(), nil))
+
+ return &Clientset{fakePtr, &fakediscovery.FakeDiscovery{Fake: &fakePtr}}
+}
+
+// Clientset implements clientset.Interface. Meant to be embedded into a
+// struct to get a default implementation. This makes faking out just the method
+// you want to test easier.
+type Clientset struct {
+ testing.Fake
+ discovery *fakediscovery.FakeDiscovery
+}
+
+func (c *Clientset) Discovery() discovery.DiscoveryInterface {
+ return c.discovery
+}
+
+var _ clientset.Interface = &Clientset{}
+
+// SamplecontrollerV1alpha1 retrieves the SamplecontrollerV1alpha1Client
+func (c *Clientset) SamplecontrollerV1alpha1() samplecontrollerv1alpha1.SamplecontrollerV1alpha1Interface {
+ return &fakesamplecontrollerv1alpha1.FakeSamplecontrollerV1alpha1{Fake: &c.Fake}
+}
+
+// Samplecontroller retrieves the SamplecontrollerV1alpha1Client
+func (c *Clientset) Samplecontroller() samplecontrollerv1alpha1.SamplecontrollerV1alpha1Interface {
+ return &fakesamplecontrollerv1alpha1.FakeSamplecontrollerV1alpha1{Fake: &c.Fake}
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/doc.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/doc.go
new file mode 100644
index 00000000000..3fd8e1e2cdc
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/doc.go
@@ -0,0 +1,18 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This package has the automatically generated fake clientset.
+package fake
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/register.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/register.go
new file mode 100644
index 00000000000..97db71e50e4
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake/register.go
@@ -0,0 +1,53 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package fake
+
+import (
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ serializer "k8s.io/apimachinery/pkg/runtime/serializer"
+ samplecontrollerv1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
+)
+
+var scheme = runtime.NewScheme()
+var codecs = serializer.NewCodecFactory(scheme)
+var parameterCodec = runtime.NewParameterCodec(scheme)
+
+func init() {
+ v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
+ AddToScheme(scheme)
+}
+
+// AddToScheme adds all types of this clientset into the given scheme. This allows composition
+// of clientsets, like in:
+//
+// import (
+// "k8s.io/client-go/kubernetes"
+// clientsetscheme "k8s.io/client-go/kuberentes/scheme"
+// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
+// )
+//
+// kclientset, _ := kubernetes.NewForConfig(c)
+// aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
+//
+// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
+// correctly.
+func AddToScheme(scheme *runtime.Scheme) {
+ samplecontrollerv1alpha1.AddToScheme(scheme)
+
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme/BUILD
new file mode 100644
index 00000000000..edf9cf501f8
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme/BUILD
@@ -0,0 +1,32 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "doc.go",
+ "register.go",
+ ],
+ importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned/scheme",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme/doc.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme/doc.go
new file mode 100644
index 00000000000..3ec2200d099
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme/doc.go
@@ -0,0 +1,18 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This package contains the scheme of the automatically generated clientset.
+package scheme
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme/register.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme/register.go
new file mode 100644
index 00000000000..6afb0553192
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme/register.go
@@ -0,0 +1,53 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package scheme
+
+import (
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ serializer "k8s.io/apimachinery/pkg/runtime/serializer"
+ samplecontrollerv1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
+)
+
+var Scheme = runtime.NewScheme()
+var Codecs = serializer.NewCodecFactory(Scheme)
+var ParameterCodec = runtime.NewParameterCodec(Scheme)
+
+func init() {
+ v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
+ AddToScheme(Scheme)
+}
+
+// AddToScheme adds all types of this clientset into the given scheme. This allows composition
+// of clientsets, like in:
+//
+// import (
+// "k8s.io/client-go/kubernetes"
+// clientsetscheme "k8s.io/client-go/kuberentes/scheme"
+// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
+// )
+//
+// kclientset, _ := kubernetes.NewForConfig(c)
+// aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
+//
+// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
+// correctly.
+func AddToScheme(scheme *runtime.Scheme) {
+ samplecontrollerv1alpha1.AddToScheme(scheme)
+
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/BUILD
new file mode 100644
index 00000000000..fc739e0527d
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/BUILD
@@ -0,0 +1,39 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "doc.go",
+ "foo.go",
+ "generated_expansion.go",
+ "samplecontroller_client.go",
+ ],
+ importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
+ "//vendor/k8s.io/client-go/rest:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [
+ ":package-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake:all-srcs",
+ ],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/doc.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/doc.go
new file mode 100644
index 00000000000..cdaaf620786
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/doc.go
@@ -0,0 +1,18 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This package has the automatically generated typed clients.
+package v1alpha1
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/BUILD
new file mode 100644
index 00000000000..b8b0305e27a
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/BUILD
@@ -0,0 +1,37 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "doc.go",
+ "fake_foo.go",
+ "fake_samplecontroller_client.go",
+ ],
+ importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
+ "//vendor/k8s.io/client-go/rest:go_default_library",
+ "//vendor/k8s.io/client-go/testing:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/doc.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/doc.go
new file mode 100644
index 00000000000..c58fac35e4b
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/doc.go
@@ -0,0 +1,18 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package fake has the automatically generated clients.
+package fake
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/fake_foo.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/fake_foo.go
new file mode 100644
index 00000000000..66a5dfbf735
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/fake_foo.go
@@ -0,0 +1,126 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package fake
+
+import (
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ labels "k8s.io/apimachinery/pkg/labels"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ testing "k8s.io/client-go/testing"
+ v1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
+)
+
+// FakeFoos implements FooInterface
+type FakeFoos struct {
+ Fake *FakeSamplecontrollerV1alpha1
+ ns string
+}
+
+var foosResource = schema.GroupVersionResource{Group: "samplecontroller.k8s.io", Version: "v1alpha1", Resource: "foos"}
+
+var foosKind = schema.GroupVersionKind{Group: "samplecontroller.k8s.io", Version: "v1alpha1", Kind: "Foo"}
+
+// Get takes name of the foo, and returns the corresponding foo object, and an error if there is any.
+func (c *FakeFoos) Get(name string, options v1.GetOptions) (result *v1alpha1.Foo, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewGetAction(foosResource, c.ns, name), &v1alpha1.Foo{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.Foo), err
+}
+
+// List takes label and field selectors, and returns the list of Foos that match those selectors.
+func (c *FakeFoos) List(opts v1.ListOptions) (result *v1alpha1.FooList, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewListAction(foosResource, foosKind, c.ns, opts), &v1alpha1.FooList{})
+
+ if obj == nil {
+ return nil, err
+ }
+
+ label, _, _ := testing.ExtractFromListOptions(opts)
+ if label == nil {
+ label = labels.Everything()
+ }
+ list := &v1alpha1.FooList{}
+ for _, item := range obj.(*v1alpha1.FooList).Items {
+ if label.Matches(labels.Set(item.Labels)) {
+ list.Items = append(list.Items, item)
+ }
+ }
+ return list, err
+}
+
+// Watch returns a watch.Interface that watches the requested foos.
+func (c *FakeFoos) Watch(opts v1.ListOptions) (watch.Interface, error) {
+ return c.Fake.
+ InvokesWatch(testing.NewWatchAction(foosResource, c.ns, opts))
+
+}
+
+// Create takes the representation of a foo and creates it. Returns the server's representation of the foo, and an error, if there is any.
+func (c *FakeFoos) Create(foo *v1alpha1.Foo) (result *v1alpha1.Foo, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewCreateAction(foosResource, c.ns, foo), &v1alpha1.Foo{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.Foo), err
+}
+
+// Update takes the representation of a foo and updates it. Returns the server's representation of the foo, and an error, if there is any.
+func (c *FakeFoos) Update(foo *v1alpha1.Foo) (result *v1alpha1.Foo, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateAction(foosResource, c.ns, foo), &v1alpha1.Foo{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.Foo), err
+}
+
+// Delete takes name of the foo and deletes it. Returns an error if one occurs.
+func (c *FakeFoos) Delete(name string, options *v1.DeleteOptions) error {
+ _, err := c.Fake.
+ Invokes(testing.NewDeleteAction(foosResource, c.ns, name), &v1alpha1.Foo{})
+
+ return err
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *FakeFoos) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
+ action := testing.NewDeleteCollectionAction(foosResource, c.ns, listOptions)
+
+ _, err := c.Fake.Invokes(action, &v1alpha1.FooList{})
+ return err
+}
+
+// Patch applies the patch and returns the patched foo.
+func (c *FakeFoos) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Foo, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewPatchSubresourceAction(foosResource, c.ns, name, data, subresources...), &v1alpha1.Foo{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.Foo), err
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/fake_samplecontroller_client.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/fake_samplecontroller_client.go
new file mode 100644
index 00000000000..3d04e5df30b
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake/fake_samplecontroller_client.go
@@ -0,0 +1,38 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package fake
+
+import (
+ rest "k8s.io/client-go/rest"
+ testing "k8s.io/client-go/testing"
+ v1alpha1 "k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1"
+)
+
+type FakeSamplecontrollerV1alpha1 struct {
+ *testing.Fake
+}
+
+func (c *FakeSamplecontrollerV1alpha1) Foos(namespace string) v1alpha1.FooInterface {
+ return &FakeFoos{c, namespace}
+}
+
+// RESTClient returns a RESTClient that is used to communicate
+// with API server by this client implementation.
+func (c *FakeSamplecontrollerV1alpha1) RESTClient() rest.Interface {
+ var ret *rest.RESTClient
+ return ret
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go
new file mode 100644
index 00000000000..1c631da7a59
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/foo.go
@@ -0,0 +1,155 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ rest "k8s.io/client-go/rest"
+ v1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
+ scheme "k8s.io/sample-controller/pkg/client/clientset/versioned/scheme"
+)
+
+// FoosGetter has a method to return a FooInterface.
+// A group's client should implement this interface.
+type FoosGetter interface {
+ Foos(namespace string) FooInterface
+}
+
+// FooInterface has methods to work with Foo resources.
+type FooInterface interface {
+ Create(*v1alpha1.Foo) (*v1alpha1.Foo, error)
+ Update(*v1alpha1.Foo) (*v1alpha1.Foo, error)
+ Delete(name string, options *v1.DeleteOptions) error
+ DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
+ Get(name string, options v1.GetOptions) (*v1alpha1.Foo, error)
+ List(opts v1.ListOptions) (*v1alpha1.FooList, error)
+ Watch(opts v1.ListOptions) (watch.Interface, error)
+ Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Foo, err error)
+ FooExpansion
+}
+
+// foos implements FooInterface
+type foos struct {
+ client rest.Interface
+ ns string
+}
+
+// newFoos returns a Foos
+func newFoos(c *SamplecontrollerV1alpha1Client, namespace string) *foos {
+ return &foos{
+ client: c.RESTClient(),
+ ns: namespace,
+ }
+}
+
+// Get takes name of the foo, and returns the corresponding foo object, and an error if there is any.
+func (c *foos) Get(name string, options v1.GetOptions) (result *v1alpha1.Foo, err error) {
+ result = &v1alpha1.Foo{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("foos").
+ Name(name).
+ VersionedParams(&options, scheme.ParameterCodec).
+ Do().
+ Into(result)
+ return
+}
+
+// List takes label and field selectors, and returns the list of Foos that match those selectors.
+func (c *foos) List(opts v1.ListOptions) (result *v1alpha1.FooList, err error) {
+ result = &v1alpha1.FooList{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("foos").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Do().
+ Into(result)
+ return
+}
+
+// Watch returns a watch.Interface that watches the requested foos.
+func (c *foos) Watch(opts v1.ListOptions) (watch.Interface, error) {
+ opts.Watch = true
+ return c.client.Get().
+ Namespace(c.ns).
+ Resource("foos").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Watch()
+}
+
+// Create takes the representation of a foo and creates it. Returns the server's representation of the foo, and an error, if there is any.
+func (c *foos) Create(foo *v1alpha1.Foo) (result *v1alpha1.Foo, err error) {
+ result = &v1alpha1.Foo{}
+ err = c.client.Post().
+ Namespace(c.ns).
+ Resource("foos").
+ Body(foo).
+ Do().
+ Into(result)
+ return
+}
+
+// Update takes the representation of a foo and updates it. Returns the server's representation of the foo, and an error, if there is any.
+func (c *foos) Update(foo *v1alpha1.Foo) (result *v1alpha1.Foo, err error) {
+ result = &v1alpha1.Foo{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("foos").
+ Name(foo.Name).
+ Body(foo).
+ Do().
+ Into(result)
+ return
+}
+
+// Delete takes name of the foo and deletes it. Returns an error if one occurs.
+func (c *foos) Delete(name string, options *v1.DeleteOptions) error {
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("foos").
+ Name(name).
+ Body(options).
+ Do().
+ Error()
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *foos) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("foos").
+ VersionedParams(&listOptions, scheme.ParameterCodec).
+ Body(options).
+ Do().
+ Error()
+}
+
+// Patch applies the patch and returns the patched foo.
+func (c *foos) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Foo, err error) {
+ result = &v1alpha1.Foo{}
+ err = c.client.Patch(pt).
+ Namespace(c.ns).
+ Resource("foos").
+ SubResource(subresources...).
+ Name(name).
+ Body(data).
+ Do().
+ Into(result)
+ return
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/generated_expansion.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/generated_expansion.go
new file mode 100644
index 00000000000..5bc2b313352
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/generated_expansion.go
@@ -0,0 +1,19 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+type FooExpansion interface{}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/samplecontroller_client.go b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/samplecontroller_client.go
new file mode 100644
index 00000000000..323b9ebcfd9
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/samplecontroller_client.go
@@ -0,0 +1,88 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+ serializer "k8s.io/apimachinery/pkg/runtime/serializer"
+ rest "k8s.io/client-go/rest"
+ v1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
+ "k8s.io/sample-controller/pkg/client/clientset/versioned/scheme"
+)
+
+type SamplecontrollerV1alpha1Interface interface {
+ RESTClient() rest.Interface
+ FoosGetter
+}
+
+// SamplecontrollerV1alpha1Client is used to interact with features provided by the samplecontroller.k8s.io group.
+type SamplecontrollerV1alpha1Client struct {
+ restClient rest.Interface
+}
+
+func (c *SamplecontrollerV1alpha1Client) Foos(namespace string) FooInterface {
+ return newFoos(c, namespace)
+}
+
+// NewForConfig creates a new SamplecontrollerV1alpha1Client for the given config.
+func NewForConfig(c *rest.Config) (*SamplecontrollerV1alpha1Client, error) {
+ config := *c
+ if err := setConfigDefaults(&config); err != nil {
+ return nil, err
+ }
+ client, err := rest.RESTClientFor(&config)
+ if err != nil {
+ return nil, err
+ }
+ return &SamplecontrollerV1alpha1Client{client}, nil
+}
+
+// NewForConfigOrDie creates a new SamplecontrollerV1alpha1Client for the given config and
+// panics if there is an error in the config.
+func NewForConfigOrDie(c *rest.Config) *SamplecontrollerV1alpha1Client {
+ client, err := NewForConfig(c)
+ if err != nil {
+ panic(err)
+ }
+ return client
+}
+
+// New creates a new SamplecontrollerV1alpha1Client for the given RESTClient.
+func New(c rest.Interface) *SamplecontrollerV1alpha1Client {
+ return &SamplecontrollerV1alpha1Client{c}
+}
+
+func setConfigDefaults(config *rest.Config) error {
+ gv := v1alpha1.SchemeGroupVersion
+ config.GroupVersion = &gv
+ config.APIPath = "/apis"
+ config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
+
+ if config.UserAgent == "" {
+ config.UserAgent = rest.DefaultKubernetesUserAgent()
+ }
+
+ return nil
+}
+
+// RESTClient returns a RESTClient that is used to communicate
+// with API server by this client implementation.
+func (c *SamplecontrollerV1alpha1Client) RESTClient() rest.Interface {
+ if c == nil {
+ return nil
+ }
+ return c.restClient
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/BUILD
new file mode 100644
index 00000000000..d87ae00e251
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/BUILD
@@ -0,0 +1,38 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "factory.go",
+ "generic.go",
+ ],
+ importpath = "k8s.io/sample-controller/pkg/client/informers/externalversions",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
+ "//vendor/k8s.io/client-go/tools/cache:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [
+ ":package-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces:all-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller:all-srcs",
+ ],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/factory.go b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/factory.go
new file mode 100644
index 00000000000..50f8326f57c
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/factory.go
@@ -0,0 +1,118 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This file was automatically generated by informer-gen
+
+package externalversions
+
+import (
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ cache "k8s.io/client-go/tools/cache"
+ versioned "k8s.io/sample-controller/pkg/client/clientset/versioned"
+ internalinterfaces "k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces"
+ samplecontroller "k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller"
+ reflect "reflect"
+ sync "sync"
+ time "time"
+)
+
+type sharedInformerFactory struct {
+ client versioned.Interface
+ lock sync.Mutex
+ defaultResync time.Duration
+
+ informers map[reflect.Type]cache.SharedIndexInformer
+ // startedInformers is used for tracking which informers have been started.
+ // This allows Start() to be called multiple times safely.
+ startedInformers map[reflect.Type]bool
+}
+
+// NewSharedInformerFactory constructs a new instance of sharedInformerFactory
+func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
+ return &sharedInformerFactory{
+ client: client,
+ defaultResync: defaultResync,
+ informers: make(map[reflect.Type]cache.SharedIndexInformer),
+ startedInformers: make(map[reflect.Type]bool),
+ }
+}
+
+// Start initializes all requested informers.
+func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ for informerType, informer := range f.informers {
+ if !f.startedInformers[informerType] {
+ go informer.Run(stopCh)
+ f.startedInformers[informerType] = true
+ }
+ }
+}
+
+// WaitForCacheSync waits for all started informers' cache were synced.
+func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool {
+ informers := func() map[reflect.Type]cache.SharedIndexInformer {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ informers := map[reflect.Type]cache.SharedIndexInformer{}
+ for informerType, informer := range f.informers {
+ if f.startedInformers[informerType] {
+ informers[informerType] = informer
+ }
+ }
+ return informers
+ }()
+
+ res := map[reflect.Type]bool{}
+ for informType, informer := range informers {
+ res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced)
+ }
+ return res
+}
+
+// InternalInformerFor returns the SharedIndexInformer for obj using an internal
+// client.
+func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
+ f.lock.Lock()
+ defer f.lock.Unlock()
+
+ informerType := reflect.TypeOf(obj)
+ informer, exists := f.informers[informerType]
+ if exists {
+ return informer
+ }
+ informer = newFunc(f.client, f.defaultResync)
+ f.informers[informerType] = informer
+
+ return informer
+}
+
+// SharedInformerFactory provides shared informers for resources in all known
+// API group versions.
+type SharedInformerFactory interface {
+ internalinterfaces.SharedInformerFactory
+ ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
+ WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool
+
+ Samplecontroller() samplecontroller.Interface
+}
+
+func (f *sharedInformerFactory) Samplecontroller() samplecontroller.Interface {
+ return samplecontroller.New(f)
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/generic.go b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/generic.go
new file mode 100644
index 00000000000..02867e96ae9
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/generic.go
@@ -0,0 +1,61 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This file was automatically generated by informer-gen
+
+package externalversions
+
+import (
+ "fmt"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ cache "k8s.io/client-go/tools/cache"
+ v1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
+)
+
+// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
+// sharedInformers based on type
+type GenericInformer interface {
+ Informer() cache.SharedIndexInformer
+ Lister() cache.GenericLister
+}
+
+type genericInformer struct {
+ informer cache.SharedIndexInformer
+ resource schema.GroupResource
+}
+
+// Informer returns the SharedIndexInformer.
+func (f *genericInformer) Informer() cache.SharedIndexInformer {
+ return f.informer
+}
+
+// Lister returns the GenericLister.
+func (f *genericInformer) Lister() cache.GenericLister {
+ return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
+}
+
+// ForResource gives generic access to a shared informer of the matching type
+// TODO extend this to unknown resources with a client pool
+func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
+ switch resource {
+ // Group=Samplecontroller, Version=V1alpha1
+ case v1alpha1.SchemeGroupVersion.WithResource("foos"):
+ return &genericInformer{resource: resource.GroupResource(), informer: f.Samplecontroller().V1alpha1().Foos().Informer()}, nil
+
+ }
+
+ return nil, fmt.Errorf("no informer found for %v", resource)
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces/BUILD
new file mode 100644
index 00000000000..41b1ecae7c2
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces/BUILD
@@ -0,0 +1,27 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = ["factory_interfaces.go"],
+ importpath = "k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
+ "//vendor/k8s.io/client-go/tools/cache:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go
new file mode 100644
index 00000000000..e246b3f5c47
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go
@@ -0,0 +1,34 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This file was automatically generated by informer-gen
+
+package internalinterfaces
+
+import (
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ cache "k8s.io/client-go/tools/cache"
+ versioned "k8s.io/sample-controller/pkg/client/clientset/versioned"
+ time "time"
+)
+
+type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer
+
+// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
+type SharedInformerFactory interface {
+ Start(stopCh <-chan struct{})
+ InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/BUILD
new file mode 100644
index 00000000000..960cb64ce21
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/BUILD
@@ -0,0 +1,29 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = ["interface.go"],
+ importpath = "k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [
+ ":package-srcs",
+ "//staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1:all-srcs",
+ ],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/interface.go b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/interface.go
new file mode 100644
index 00000000000..a9d41a3e7d0
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/interface.go
@@ -0,0 +1,44 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This file was automatically generated by informer-gen
+
+package samplecontroller
+
+import (
+ internalinterfaces "k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces"
+ v1alpha1 "k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1"
+)
+
+// Interface provides access to each of this group's versions.
+type Interface interface {
+ // V1alpha1 provides access to shared informers for resources in V1alpha1.
+ V1alpha1() v1alpha1.Interface
+}
+
+type group struct {
+ internalinterfaces.SharedInformerFactory
+}
+
+// New returns a new Interface.
+func New(f internalinterfaces.SharedInformerFactory) Interface {
+ return &group{f}
+}
+
+// V1alpha1 returns a new v1alpha1.Interface.
+func (g *group) V1alpha1() v1alpha1.Interface {
+ return v1alpha1.New(g.SharedInformerFactory)
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/BUILD
new file mode 100644
index 00000000000..056bdba953d
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/BUILD
@@ -0,0 +1,35 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "foo.go",
+ "interface.go",
+ ],
+ importpath = "k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
+ "//vendor/k8s.io/client-go/tools/cache:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/foo.go b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/foo.go
new file mode 100644
index 00000000000..97207c879c2
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/foo.go
@@ -0,0 +1,73 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This file was automatically generated by informer-gen
+
+package v1alpha1
+
+import (
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ watch "k8s.io/apimachinery/pkg/watch"
+ cache "k8s.io/client-go/tools/cache"
+ samplecontroller_v1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
+ versioned "k8s.io/sample-controller/pkg/client/clientset/versioned"
+ internalinterfaces "k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces"
+ v1alpha1 "k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1"
+ time "time"
+)
+
+// FooInformer provides access to a shared informer and lister for
+// Foos.
+type FooInformer interface {
+ Informer() cache.SharedIndexInformer
+ Lister() v1alpha1.FooLister
+}
+
+type fooInformer struct {
+ factory internalinterfaces.SharedInformerFactory
+}
+
+// NewFooInformer constructs a new informer for Foo type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewFooInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+ return cache.NewSharedIndexInformer(
+ &cache.ListWatch{
+ ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
+ return client.SamplecontrollerV1alpha1().Foos(namespace).List(options)
+ },
+ WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
+ return client.SamplecontrollerV1alpha1().Foos(namespace).Watch(options)
+ },
+ },
+ &samplecontroller_v1alpha1.Foo{},
+ resyncPeriod,
+ indexers,
+ )
+}
+
+func defaultFooInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+ return NewFooInformer(client, v1.NamespaceAll, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
+}
+
+func (f *fooInformer) Informer() cache.SharedIndexInformer {
+ return f.factory.InformerFor(&samplecontroller_v1alpha1.Foo{}, defaultFooInformer)
+}
+
+func (f *fooInformer) Lister() v1alpha1.FooLister {
+ return v1alpha1.NewFooLister(f.Informer().GetIndexer())
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/interface.go b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/interface.go
new file mode 100644
index 00000000000..1d159b5df5a
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1/interface.go
@@ -0,0 +1,43 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This file was automatically generated by informer-gen
+
+package v1alpha1
+
+import (
+ internalinterfaces "k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces"
+)
+
+// Interface provides access to all the informers in this group version.
+type Interface interface {
+ // Foos returns a FooInformer.
+ Foos() FooInformer
+}
+
+type version struct {
+ internalinterfaces.SharedInformerFactory
+}
+
+// New returns a new Interface.
+func New(f internalinterfaces.SharedInformerFactory) Interface {
+ return &version{f}
+}
+
+// Foos returns a FooInformer.
+func (v *version) Foos() FooInformer {
+ return &fooInformer{factory: v.SharedInformerFactory}
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1/BUILD b/staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1/BUILD
new file mode 100644
index 00000000000..80052e00b37
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1/BUILD
@@ -0,0 +1,31 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "expansion_generated.go",
+ "foo.go",
+ ],
+ importpath = "k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
+ "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
+ "//vendor/k8s.io/client-go/tools/cache:go_default_library",
+ "//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1/expansion_generated.go b/staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1/expansion_generated.go
new file mode 100644
index 00000000000..8829daba673
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1/expansion_generated.go
@@ -0,0 +1,27 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This file was automatically generated by lister-gen
+
+package v1alpha1
+
+// FooListerExpansion allows custom methods to be added to
+// FooLister.
+type FooListerExpansion interface{}
+
+// FooNamespaceListerExpansion allows custom methods to be added to
+// FooNamespaceLister.
+type FooNamespaceListerExpansion interface{}
diff --git a/staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1/foo.go b/staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1/foo.go
new file mode 100644
index 00000000000..646a7e38a5e
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1/foo.go
@@ -0,0 +1,94 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// This file was automatically generated by lister-gen
+
+package v1alpha1
+
+import (
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/client-go/tools/cache"
+ v1alpha1 "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1"
+)
+
+// FooLister helps list Foos.
+type FooLister interface {
+ // List lists all Foos in the indexer.
+ List(selector labels.Selector) (ret []*v1alpha1.Foo, err error)
+ // Foos returns an object that can list and get Foos.
+ Foos(namespace string) FooNamespaceLister
+ FooListerExpansion
+}
+
+// fooLister implements the FooLister interface.
+type fooLister struct {
+ indexer cache.Indexer
+}
+
+// NewFooLister returns a new FooLister.
+func NewFooLister(indexer cache.Indexer) FooLister {
+ return &fooLister{indexer: indexer}
+}
+
+// List lists all Foos in the indexer.
+func (s *fooLister) List(selector labels.Selector) (ret []*v1alpha1.Foo, err error) {
+ err = cache.ListAll(s.indexer, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1alpha1.Foo))
+ })
+ return ret, err
+}
+
+// Foos returns an object that can list and get Foos.
+func (s *fooLister) Foos(namespace string) FooNamespaceLister {
+ return fooNamespaceLister{indexer: s.indexer, namespace: namespace}
+}
+
+// FooNamespaceLister helps list and get Foos.
+type FooNamespaceLister interface {
+ // List lists all Foos in the indexer for a given namespace.
+ List(selector labels.Selector) (ret []*v1alpha1.Foo, err error)
+ // Get retrieves the Foo from the indexer for a given namespace and name.
+ Get(name string) (*v1alpha1.Foo, error)
+ FooNamespaceListerExpansion
+}
+
+// fooNamespaceLister implements the FooNamespaceLister
+// interface.
+type fooNamespaceLister struct {
+ indexer cache.Indexer
+ namespace string
+}
+
+// List lists all Foos in the indexer for a given namespace.
+func (s fooNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Foo, err error) {
+ err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1alpha1.Foo))
+ })
+ return ret, err
+}
+
+// Get retrieves the Foo from the indexer for a given namespace and name.
+func (s fooNamespaceLister) Get(name string) (*v1alpha1.Foo, error) {
+ obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
+ if err != nil {
+ return nil, err
+ }
+ if !exists {
+ return nil, errors.NewNotFound(v1alpha1.Resource("foo"), name)
+ }
+ return obj.(*v1alpha1.Foo), nil
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/signals/BUILD b/staging/src/k8s.io/sample-controller/pkg/signals/BUILD
new file mode 100644
index 00000000000..190d148992e
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/signals/BUILD
@@ -0,0 +1,30 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "signal.go",
+ "signal_posix.go",
+ ] + select({
+ "@io_bazel_rules_go//go/platform:windows_amd64": [
+ "signal_windows.go",
+ ],
+ "//conditions:default": [],
+ }),
+ importpath = "k8s.io/sample-controller/pkg/signals",
+ visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/staging/src/k8s.io/sample-controller/pkg/signals/signal.go b/staging/src/k8s.io/sample-controller/pkg/signals/signal.go
new file mode 100644
index 00000000000..6bddfddb4f9
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/signals/signal.go
@@ -0,0 +1,43 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package signals
+
+import (
+ "os"
+ "os/signal"
+)
+
+var onlyOneSignalHandler = make(chan struct{})
+
+// SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned
+// which is closed on one of these signals. If a second signal is caught, the program
+// is terminated with exit code 1.
+func SetupSignalHandler() (stopCh <-chan struct{}) {
+ close(onlyOneSignalHandler) // panics when called twice
+
+ stop := make(chan struct{})
+ c := make(chan os.Signal, 2)
+ signal.Notify(c, shutdownSignals...)
+ go func() {
+ <-c
+ close(stop)
+ <-c
+ os.Exit(1) // second signal. Exit directly.
+ }()
+
+ return stop
+}
diff --git a/staging/src/k8s.io/sample-controller/pkg/signals/signal_posix.go b/staging/src/k8s.io/sample-controller/pkg/signals/signal_posix.go
new file mode 100644
index 00000000000..9bdb4e7418b
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/signals/signal_posix.go
@@ -0,0 +1,26 @@
+// +build !windows
+
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package signals
+
+import (
+ "os"
+ "syscall"
+)
+
+var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM}
diff --git a/staging/src/k8s.io/sample-controller/pkg/signals/signal_windows.go b/staging/src/k8s.io/sample-controller/pkg/signals/signal_windows.go
new file mode 100644
index 00000000000..4907d573fe0
--- /dev/null
+++ b/staging/src/k8s.io/sample-controller/pkg/signals/signal_windows.go
@@ -0,0 +1,23 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package signals
+
+import (
+ "os"
+)
+
+var shutdownSignals = []os.Signal{os.Interrupt}
diff --git a/test/OWNERS b/test/OWNERS
index 7fc52ff2c7e..f051eeac370 100644
--- a/test/OWNERS
+++ b/test/OWNERS
@@ -21,6 +21,7 @@ reviewers:
- soltysh
- sig-testing-reviewers
- sttts
+ - timothysc
- zmerlynn
- vishh
approvers:
@@ -47,5 +48,6 @@ approvers:
- smarterclayton
- soltysh
- sttts
+ - timothysc
- zmerlynn
- vishh
diff --git a/test/e2e/apimachinery/garbage_collector.go b/test/e2e/apimachinery/garbage_collector.go
index c974167a923..3c250607724 100644
--- a/test/e2e/apimachinery/garbage_collector.go
+++ b/test/e2e/apimachinery/garbage_collector.go
@@ -288,7 +288,7 @@ func newCronJob(name, schedule string) *batchv1beta1.CronJob {
Containers: []v1.Container{
{
Name: "c",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"sleep", "300"},
},
},
diff --git a/test/e2e/apimachinery/generated_clientset.go b/test/e2e/apimachinery/generated_clientset.go
index 7e3a3d00648..6c1ae3972eb 100644
--- a/test/e2e/apimachinery/generated_clientset.go
+++ b/test/e2e/apimachinery/generated_clientset.go
@@ -243,7 +243,7 @@ func newTestingCronJob(name string, value string) *batchv1beta1.CronJob {
Containers: []v1.Container{
{
Name: "c",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
VolumeMounts: []v1.VolumeMount{
{
MountPath: "/data",
diff --git a/test/e2e/apps/cronjob.go b/test/e2e/apps/cronjob.go
index 39f5fcdaa1f..571b4ef8c82 100644
--- a/test/e2e/apps/cronjob.go
+++ b/test/e2e/apps/cronjob.go
@@ -35,7 +35,6 @@ import (
"k8s.io/kubernetes/pkg/controller/job"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/test/e2e/framework"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
const (
@@ -304,7 +303,7 @@ func newTestCronJob(name, schedule string, concurrencyPolicy batchv1beta1.Concur
Containers: []v1.Container{
{
Name: "c",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
VolumeMounts: []v1.VolumeMount{
{
MountPath: "/data",
diff --git a/test/e2e/common/util.go b/test/e2e/common/util.go
index aa6bfc1e98b..c65e9199bb9 100644
--- a/test/e2e/common/util.go
+++ b/test/e2e/common/util.go
@@ -42,7 +42,7 @@ const (
var (
mountImage = imageutils.GetE2EImage(imageutils.Mounttest)
- busyboxImage = imageutils.GetBusyBoxImage()
+ busyboxImage = "busybox"
)
var CurrentSuite Suite
@@ -52,7 +52,7 @@ var CurrentSuite Suite
// only used by node e2e test.
// TODO(random-liu): Change the image puller pod to use similar mechanism.
var CommonImageWhiteList = sets.NewString(
- imageutils.GetBusyBoxImage(),
+ "busybox",
imageutils.GetE2EImage(imageutils.EntrypointTester),
imageutils.GetE2EImage(imageutils.Liveness),
imageutils.GetE2EImage(imageutils.Mounttest),
diff --git a/test/e2e/framework/deployment_util.go b/test/e2e/framework/deployment_util.go
index 80c19dcbfd3..c0a251faae3 100644
--- a/test/e2e/framework/deployment_util.go
+++ b/test/e2e/framework/deployment_util.go
@@ -289,3 +289,22 @@ func RunDeployment(config testutils.DeploymentConfig) error {
func logPodsOfDeployment(c clientset.Interface, deployment *extensions.Deployment, rsList []*extensions.ReplicaSet) {
testutils.LogPodsOfDeployment(c, deployment, rsList, Logf)
}
+
+func WaitForDeploymentCompletes(c clientset.Interface, deployment *extensions.Deployment) error {
+ return testutils.WaitForDeploymentCompletes(c, deployment, Logf, Poll, pollLongTimeout)
+}
+
+func WaitForDeploymentRevision(c clientset.Interface, d *extensions.Deployment, targetRevision string) error {
+ err := wait.PollImmediate(Poll, pollLongTimeout, func() (bool, error) {
+ deployment, err := c.ExtensionsV1beta1().Deployments(d.Namespace).Get(d.Name, metav1.GetOptions{})
+ if err != nil {
+ return false, err
+ }
+ revision := deployment.Annotations[deploymentutil.RevisionAnnotation]
+ return revision == targetRevision, nil
+ })
+ if err != nil {
+ return fmt.Errorf("error waiting for revision to become %q for deployment %q: %v", targetRevision, d.Name, err)
+ }
+ return nil
+}
diff --git a/test/e2e/framework/nodes_util.go b/test/e2e/framework/nodes_util.go
index 5cfd4d95751..0926a8a7703 100644
--- a/test/e2e/framework/nodes_util.go
+++ b/test/e2e/framework/nodes_util.go
@@ -29,7 +29,6 @@ import (
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
func EtcdUpgrade(target_storage, target_version string) error {
@@ -327,7 +326,7 @@ func gceUpgradeScript() string {
func waitForSSHTunnels() {
Logf("Waiting for SSH tunnels to establish")
RunKubectl("run", "ssh-tunnel-test",
- "--image="+imageutils.GetBusyBoxImage(),
+ "--image=busybox",
"--restart=Never",
"--command", "--",
"echo", "Hello")
diff --git a/test/e2e/framework/service_util.go b/test/e2e/framework/service_util.go
index 84b687a829d..a9dab3a201f 100644
--- a/test/e2e/framework/service_util.go
+++ b/test/e2e/framework/service_util.go
@@ -89,6 +89,10 @@ const (
// ServiceTestTimeout is used for most polling/waiting activities
ServiceTestTimeout = 60 * time.Second
+
+ // GCPMaxInstancesInInstanceGroup is the maximum number of instances supported in
+ // one instance group on GCP.
+ GCPMaxInstancesInInstanceGroup = 2000
)
// This should match whatever the default/configured range is
diff --git a/test/e2e/framework/statefulset_utils.go b/test/e2e/framework/statefulset_utils.go
index 600161c0058..426553d99a1 100644
--- a/test/e2e/framework/statefulset_utils.go
+++ b/test/e2e/framework/statefulset_utils.go
@@ -751,9 +751,6 @@ func NewStatefulSetPVC(name string) v1.PersistentVolumeClaim {
return v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: name,
- Annotations: map[string]string{
- "volume.alpha.kubernetes.io/storage-class": "anything",
- },
},
Spec: v1.PersistentVolumeClaimSpec{
AccessModes: []v1.PersistentVolumeAccessMode{
diff --git a/test/e2e/framework/test_context.go b/test/e2e/framework/test_context.go
index c8462253225..cda164b1405 100644
--- a/test/e2e/framework/test_context.go
+++ b/test/e2e/framework/test_context.go
@@ -19,12 +19,16 @@ package framework
import (
"flag"
"fmt"
+ "io/ioutil"
"os"
"time"
+ "github.com/golang/glog"
"github.com/onsi/ginkgo/config"
"github.com/spf13/viper"
+ restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
+ clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
"k8s.io/kubernetes/pkg/kubemark"
@@ -296,12 +300,61 @@ func ViperizeFlags() {
AfterReadingAllFlags(&TestContext)
}
+func createKubeConfig(clientCfg *restclient.Config) *clientcmdapi.Config {
+ clusterNick := "cluster"
+ userNick := "user"
+ contextNick := "context"
+
+ config := clientcmdapi.NewConfig()
+
+ credentials := clientcmdapi.NewAuthInfo()
+ credentials.Token = clientCfg.BearerToken
+ credentials.ClientCertificate = clientCfg.TLSClientConfig.CertFile
+ if len(credentials.ClientCertificate) == 0 {
+ credentials.ClientCertificateData = clientCfg.TLSClientConfig.CertData
+ }
+ credentials.ClientKey = clientCfg.TLSClientConfig.KeyFile
+ if len(credentials.ClientKey) == 0 {
+ credentials.ClientKeyData = clientCfg.TLSClientConfig.KeyData
+ }
+ config.AuthInfos[userNick] = credentials
+
+ cluster := clientcmdapi.NewCluster()
+ cluster.Server = clientCfg.Host
+ cluster.CertificateAuthority = clientCfg.CAFile
+ if len(cluster.CertificateAuthority) == 0 {
+ cluster.CertificateAuthorityData = clientCfg.CAData
+ }
+ cluster.InsecureSkipTLSVerify = clientCfg.Insecure
+ config.Clusters[clusterNick] = cluster
+
+ context := clientcmdapi.NewContext()
+ context.Cluster = clusterNick
+ context.AuthInfo = userNick
+ config.Contexts[contextNick] = context
+ config.CurrentContext = contextNick
+
+ return config
+}
+
// AfterReadingAllFlags makes changes to the context after all flags
// have been read.
func AfterReadingAllFlags(t *TestContextType) {
// Only set a default host if one won't be supplied via kubeconfig
if len(t.Host) == 0 && len(t.KubeConfig) == 0 {
- t.Host = defaultHost
+ // Check if we can use the in-cluster config
+ if clusterConfig, err := restclient.InClusterConfig(); err == nil {
+ if tempFile, err := ioutil.TempFile(os.TempDir(), "kubeconfig-"); err == nil {
+ kubeConfig := createKubeConfig(clusterConfig)
+ clientcmd.WriteToFile(*kubeConfig, tempFile.Name())
+ t.KubeConfig = tempFile.Name()
+ glog.Infof("Using a temporary kubeconfig file from in-cluster config : %s", tempFile.Name())
+ }
+ }
+ if len(t.KubeConfig) == 0 {
+ glog.Warningf("Unable to find in-cluster config, using default host : %s", defaultHost)
+ t.Host = defaultHost
+ }
}
// Reset the cluster IP range flag to CLUSTER_IP_RANGE env var, if defined.
if clusterIPRange := os.Getenv("CLUSTER_IP_RANGE"); clusterIPRange != "" {
diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go
index 36d0830fb02..92ccc7f2892 100644
--- a/test/e2e/framework/util.go
+++ b/test/e2e/framework/util.go
@@ -192,7 +192,7 @@ const (
)
var (
- BusyBoxImage = imageutils.GetBusyBoxImage()
+ BusyBoxImage = "busybox"
// Label allocated to the image puller static pod that runs on each node
// before e2es.
ImagePullerLabels = map[string]string{"name": "e2e-image-puller"}
diff --git a/test/e2e/instrumentation/logging/BUILD b/test/e2e/instrumentation/logging/BUILD
index 43f301895c1..6d1698b4138 100644
--- a/test/e2e/instrumentation/logging/BUILD
+++ b/test/e2e/instrumentation/logging/BUILD
@@ -17,7 +17,6 @@ go_library(
"//test/e2e/instrumentation/common:go_default_library",
"//test/e2e/instrumentation/logging/elasticsearch:go_default_library",
"//test/e2e/instrumentation/logging/stackdrvier:go_default_library",
- "//test/utils/image:go_default_library",
"//vendor/github.com/onsi/ginkgo:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
diff --git a/test/e2e/instrumentation/logging/generic_soak.go b/test/e2e/instrumentation/logging/generic_soak.go
index d08e9ad22ed..3c94306f066 100644
--- a/test/e2e/instrumentation/logging/generic_soak.go
+++ b/test/e2e/instrumentation/logging/generic_soak.go
@@ -28,7 +28,6 @@ import (
"k8s.io/api/core/v1"
"k8s.io/kubernetes/test/e2e/framework"
instrumentation "k8s.io/kubernetes/test/e2e/instrumentation/common"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
var _ = instrumentation.SIGDescribe("Logging soak [Performance] [Slow] [Disruptive]", func() {
@@ -101,7 +100,7 @@ func RunLogPodsWithSleepOf(f *framework.Framework, sleep time.Duration, podname
return v1.PodSpec{
Containers: []v1.Container{{
Name: "logging-soak",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Args: []string{
"/bin/sh",
"-c",
diff --git a/test/e2e/kubectl/kubectl.go b/test/e2e/kubectl/kubectl.go
index 233707da358..205ddd3ae9a 100644
--- a/test/e2e/kubectl/kubectl.go
+++ b/test/e2e/kubectl/kubectl.go
@@ -95,7 +95,7 @@ var (
kittenImage = imageutils.GetE2EImage(imageutils.Kitten)
redisImage = imageutils.GetE2EImage(imageutils.Redis)
nginxImage = imageutils.GetE2EImage(imageutils.NginxSlim)
- busyboxImage = imageutils.GetBusyBoxImage()
+ busyboxImage = "busybox"
)
var testImages = struct {
diff --git a/test/e2e/network/network_policy.go b/test/e2e/network/network_policy.go
index 653187aeb1f..be870744a29 100644
--- a/test/e2e/network/network_policy.go
+++ b/test/e2e/network/network_policy.go
@@ -514,7 +514,7 @@ func createNetworkClientPod(f *framework.Framework, namespace *v1.Namespace, pod
Containers: []v1.Container{
{
Name: fmt.Sprintf("%s-container", podName),
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Args: []string{
"/bin/sh",
"-c",
diff --git a/test/e2e/network/service.go b/test/e2e/network/service.go
index 0d19372c431..0b0beee86cd 100644
--- a/test/e2e/network/service.go
+++ b/test/e2e/network/service.go
@@ -1339,8 +1339,15 @@ var _ = SIGDescribe("Services", func() {
It("should be able to create an internal type load balancer [Slow]", func() {
framework.SkipUnlessProviderIs("azure", "gke", "gce")
+ if framework.ProviderIs("gke", "gce") {
+ framework.SkipUnlessNodeCountIsAtMost(framework.GCPMaxInstancesInInstanceGroup)
+ }
createTimeout := framework.LoadBalancerCreateTimeoutDefault
+ if nodes := framework.GetReadySchedulableNodesOrDie(cs); len(nodes.Items) > framework.LargeClusterMinNodesNumber {
+ createTimeout = framework.LoadBalancerCreateTimeoutLarge
+ }
+
pollInterval := framework.Poll * 10
namespace := f.Namespace.Name
diff --git a/test/e2e/node/BUILD b/test/e2e/node/BUILD
index ad29d21ceb6..b1a2c719cf7 100644
--- a/test/e2e/node/BUILD
+++ b/test/e2e/node/BUILD
@@ -17,7 +17,6 @@ go_library(
"//test/e2e/common:go_default_library",
"//test/e2e/framework:go_default_library",
"//test/utils:go_default_library",
- "//test/utils/image:go_default_library",
"//vendor/github.com/onsi/ginkgo:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
diff --git a/test/e2e/node/kubelet.go b/test/e2e/node/kubelet.go
index c5e1c32ca2f..420a2f9f20f 100644
--- a/test/e2e/node/kubelet.go
+++ b/test/e2e/node/kubelet.go
@@ -34,7 +34,6 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
const (
@@ -170,7 +169,7 @@ func createPodUsingNfs(f *framework.Framework, c clientset.Interface, ns, nfsIP,
Containers: []v1.Container{
{
Name: "pod-nfs-vol",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"/bin/sh"},
Args: cmdLine,
VolumeMounts: []v1.VolumeMount{
diff --git a/test/e2e/node/security_context.go b/test/e2e/node/security_context.go
index 118bc650f47..22062836c28 100644
--- a/test/e2e/node/security_context.go
+++ b/test/e2e/node/security_context.go
@@ -32,7 +32,6 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
func scTestPod(hostIPC bool, hostPID bool) *v1.Pod {
@@ -50,7 +49,7 @@ func scTestPod(hostIPC bool, hostPID bool) *v1.Pod {
Containers: []v1.Container{
{
Name: "test-container",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
},
},
RestartPolicy: v1.RestartPolicyNever,
diff --git a/test/e2e/pod_gc.go b/test/e2e/pod_gc.go
index ebab2b2a49a..11e0f9acfe1 100644
--- a/test/e2e/pod_gc.go
+++ b/test/e2e/pod_gc.go
@@ -27,7 +27,6 @@ import (
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/test/e2e/framework"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
// This test requires that --terminated-pod-gc-threshold=100 be set on the controller manager
@@ -90,7 +89,7 @@ func createTerminatingPod(f *framework.Framework) (*v1.Pod, error) {
Containers: []v1.Container{
{
Name: string(uuid),
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
},
},
SchedulerName: "please don't schedule my pods",
diff --git a/test/e2e/pre_stop.go b/test/e2e/pre_stop.go
index 4e4204068c5..93c1f5d29a3 100644
--- a/test/e2e/pre_stop.go
+++ b/test/e2e/pre_stop.go
@@ -80,7 +80,7 @@ func testPreStop(c clientset.Interface, ns string) {
Containers: []v1.Container{
{
Name: "tester",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"sleep", "600"},
Lifecycle: &v1.Lifecycle{
PreStop: &v1.Handler{
diff --git a/test/e2e/storage/BUILD b/test/e2e/storage/BUILD
index 7f173a8dda3..cae7333ec47 100644
--- a/test/e2e/storage/BUILD
+++ b/test/e2e/storage/BUILD
@@ -23,6 +23,7 @@ go_library(
"volume_metrics.go",
"volume_provisioning.go",
"volumes.go",
+ "vsphere_statefulsets.go",
"vsphere_utils.go",
"vsphere_volume_cluster_ds.go",
"vsphere_volume_datastore.go",
diff --git a/test/e2e/storage/empty_dir_wrapper.go b/test/e2e/storage/empty_dir_wrapper.go
index 2a39611017f..15a205c0f5c 100644
--- a/test/e2e/storage/empty_dir_wrapper.go
+++ b/test/e2e/storage/empty_dir_wrapper.go
@@ -351,7 +351,7 @@ func testNoWrappedVolumeRace(f *framework.Framework, volumes []v1.Volume, volume
Containers: []v1.Container{
{
Name: "test-container",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"sleep", "10000"},
Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{
diff --git a/test/e2e/storage/pd.go b/test/e2e/storage/pd.go
index bc88a4a2c3b..0fdb21a839c 100644
--- a/test/e2e/storage/pd.go
+++ b/test/e2e/storage/pd.go
@@ -38,7 +38,6 @@ import (
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/test/e2e/framework"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
const (
@@ -486,7 +485,7 @@ func testPDPod(diskNames []string, targetNode types.NodeName, readOnly bool, num
if numContainers > 1 {
containers[i].Name = fmt.Sprintf("mycontainer%v", i+1)
}
- containers[i].Image = imageutils.GetBusyBoxImage()
+ containers[i].Image = "busybox"
containers[i].Command = []string{"sleep", "6000"}
containers[i].VolumeMounts = make([]v1.VolumeMount, len(diskNames))
for k := range diskNames {
diff --git a/test/e2e/storage/volume_provisioning.go b/test/e2e/storage/volume_provisioning.go
index 465c4fa4015..093b584efd2 100644
--- a/test/e2e/storage/volume_provisioning.go
+++ b/test/e2e/storage/volume_provisioning.go
@@ -45,7 +45,6 @@ import (
storageutil "k8s.io/kubernetes/pkg/apis/storage/v1/util"
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
"k8s.io/kubernetes/test/e2e/framework"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
type storageClassTest struct {
@@ -796,7 +795,7 @@ func runInPodWithVolume(c clientset.Interface, ns, claimName, command string) {
Containers: []v1.Container{
{
Name: "volume-tester",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"/bin/sh"},
Args: []string{"-c", command},
VolumeMounts: []v1.VolumeMount{
diff --git a/test/e2e/storage/vsphere_statefulsets.go b/test/e2e/storage/vsphere_statefulsets.go
new file mode 100644
index 00000000000..c2823c72d85
--- /dev/null
+++ b/test/e2e/storage/vsphere_statefulsets.go
@@ -0,0 +1,156 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package storage
+
+import (
+ "fmt"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ apierrs "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/types"
+ clientset "k8s.io/client-go/kubernetes"
+ "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere"
+ "k8s.io/kubernetes/test/e2e/framework"
+)
+
+/*
+ Test performs following operations
+
+ Steps
+ 1. Create a storage class with thin diskformat.
+ 2. Create nginx service.
+ 3. Create nginx statefulsets with 3 replicas.
+ 4. Wait until all Pods are ready and PVCs are bounded with PV.
+ 5. Verify volumes are accessible in all statefulsets pods with creating empty file.
+ 6. Scale down statefulsets to 2 replicas.
+ 7. Scale up statefulsets to 4 replicas.
+ 8. Scale down statefulsets to 0 replicas and delete all pods.
+ 9. Delete all PVCs from the test namespace.
+ 10. Delete the storage class.
+*/
+
+const (
+ manifestPath = "test/e2e/testing-manifests/statefulset/nginx"
+ mountPath = "/usr/share/nginx/html"
+ storageclassname = "nginx-sc"
+)
+
+var _ = SIGDescribe("vsphere statefulset", func() {
+ f := framework.NewDefaultFramework("vsphere-statefulset")
+ var (
+ namespace string
+ client clientset.Interface
+ )
+ BeforeEach(func() {
+ framework.SkipUnlessProviderIs("vsphere")
+ namespace = f.Namespace.Name
+ client = f.ClientSet
+ })
+ AfterEach(func() {
+ framework.Logf("Deleting all statefulset in namespace: %v", namespace)
+ framework.DeleteAllStatefulSets(client, namespace)
+ })
+
+ It("vsphere statefulset testing", func() {
+ By("Creating StorageClass for Statefulset")
+ scParameters := make(map[string]string)
+ scParameters["diskformat"] = "thin"
+ scSpec := getVSphereStorageClassSpec(storageclassname, scParameters)
+ sc, err := client.StorageV1().StorageClasses().Create(scSpec)
+ Expect(err).NotTo(HaveOccurred())
+ defer client.StorageV1().StorageClasses().Delete(sc.Name, nil)
+
+ By("Creating statefulset")
+ statefulsetTester := framework.NewStatefulSetTester(client)
+ statefulset := statefulsetTester.CreateStatefulSet(manifestPath, namespace)
+ replicas := *(statefulset.Spec.Replicas)
+ // Waiting for pods status to be Ready
+ statefulsetTester.WaitForStatusReadyReplicas(statefulset, replicas)
+ Expect(statefulsetTester.CheckMount(statefulset, mountPath)).NotTo(HaveOccurred())
+ ssPodsBeforeScaleDown := statefulsetTester.GetPodList(statefulset)
+ Expect(ssPodsBeforeScaleDown.Items).NotTo(BeEmpty(), fmt.Sprintf("Unable to get list of Pods from the Statefulset: %v", statefulset.Name))
+ Expect(len(ssPodsBeforeScaleDown.Items) == int(replicas)).To(BeTrue(), "Number of Pods in the statefulset should match with number of replicas")
+
+ // Get the list of Volumes attached to Pods before scale down
+ volumesBeforeScaleDown := make(map[string]string)
+ for _, sspod := range ssPodsBeforeScaleDown.Items {
+ _, err := client.CoreV1().Pods(namespace).Get(sspod.Name, metav1.GetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ for _, volumespec := range sspod.Spec.Volumes {
+ if volumespec.PersistentVolumeClaim != nil {
+ volumePath := getvSphereVolumePathFromClaim(client, statefulset.Namespace, volumespec.PersistentVolumeClaim.ClaimName)
+ volumesBeforeScaleDown[volumePath] = volumespec.PersistentVolumeClaim.ClaimName
+ }
+ }
+ }
+
+ By(fmt.Sprintf("Scaling down statefulsets to number of Replica: %v", replicas-1))
+ _, scaledownErr := statefulsetTester.Scale(statefulset, replicas-1)
+ Expect(scaledownErr).NotTo(HaveOccurred())
+ statefulsetTester.WaitForStatusReadyReplicas(statefulset, replicas-1)
+
+ vsp, err := vsphere.GetVSphere()
+ Expect(err).NotTo(HaveOccurred())
+
+ // After scale down, verify vsphere volumes are detached from deleted pods
+ By("Verify Volumes are detached from Nodes after Statefulsets is scaled down")
+ for _, sspod := range ssPodsBeforeScaleDown.Items {
+ _, err := client.CoreV1().Pods(namespace).Get(sspod.Name, metav1.GetOptions{})
+ if err != nil {
+ Expect(apierrs.IsNotFound(err), BeTrue())
+ for _, volumespec := range sspod.Spec.Volumes {
+ if volumespec.PersistentVolumeClaim != nil {
+ vSpherediskPath := getvSphereVolumePathFromClaim(client, statefulset.Namespace, volumespec.PersistentVolumeClaim.ClaimName)
+ framework.Logf("Waiting for Volume: %q to detach from Node: %q", vSpherediskPath, sspod.Spec.NodeName)
+ Expect(waitForVSphereDiskToDetach(vsp, vSpherediskPath, types.NodeName(sspod.Spec.NodeName))).NotTo(HaveOccurred())
+ }
+ }
+ }
+ }
+
+ By(fmt.Sprintf("Scaling up statefulsets to number of Replica: %v", replicas))
+ _, scaleupErr := statefulsetTester.Scale(statefulset, replicas)
+ Expect(scaleupErr).NotTo(HaveOccurred())
+ statefulsetTester.WaitForStatusReplicas(statefulset, replicas)
+ statefulsetTester.WaitForStatusReadyReplicas(statefulset, replicas)
+
+ ssPodsAfterScaleUp := statefulsetTester.GetPodList(statefulset)
+ Expect(ssPodsAfterScaleUp.Items).NotTo(BeEmpty(), fmt.Sprintf("Unable to get list of Pods from the Statefulset: %v", statefulset.Name))
+ Expect(len(ssPodsAfterScaleUp.Items) == int(replicas)).To(BeTrue(), "Number of Pods in the statefulset should match with number of replicas")
+
+ // After scale up, verify all vsphere volumes are attached to node VMs.
+ By("Verify all volumes are attached to Nodes after Statefulsets is scaled up")
+ for _, sspod := range ssPodsAfterScaleUp.Items {
+ err := framework.WaitForPodsReady(client, statefulset.Namespace, sspod.Name, 0)
+ Expect(err).NotTo(HaveOccurred())
+ pod, err := client.CoreV1().Pods(namespace).Get(sspod.Name, metav1.GetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ for _, volumespec := range pod.Spec.Volumes {
+ if volumespec.PersistentVolumeClaim != nil {
+ vSpherediskPath := getvSphereVolumePathFromClaim(client, statefulset.Namespace, volumespec.PersistentVolumeClaim.ClaimName)
+ framework.Logf("Verify Volume: %q is attached to the Node: %q", vSpherediskPath, sspod.Spec.NodeName)
+ // Verify scale up has re-attached the same volumes and not introduced new volume
+ Expect(volumesBeforeScaleDown[vSpherediskPath] == "").To(BeFalse())
+ isVolumeAttached, verifyDiskAttachedError := verifyVSphereDiskAttached(vsp, vSpherediskPath, types.NodeName(sspod.Spec.NodeName))
+ Expect(isVolumeAttached).To(BeTrue())
+ Expect(verifyDiskAttachedError).NotTo(HaveOccurred())
+ }
+ }
+ }
+ })
+})
diff --git a/test/e2e/storage/vsphere_utils.go b/test/e2e/storage/vsphere_utils.go
index a0b15ff3432..e3b93d0b355 100644
--- a/test/e2e/storage/vsphere_utils.go
+++ b/test/e2e/storage/vsphere_utils.go
@@ -36,7 +36,6 @@ import (
"k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib"
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/kubernetes/test/e2e/framework"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
// Sanity check for vSphere testing. Verify the persistent disk attached to the node.
@@ -245,7 +244,7 @@ func getVSpherePodSpecWithClaim(claimName string, nodeSelectorKV map[string]stri
Containers: []v1.Container{
{
Name: "volume-tester",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"/bin/sh"},
Args: []string{"-c", command},
VolumeMounts: []v1.VolumeMount{
@@ -310,7 +309,7 @@ func getVSpherePodSpecWithVolumePaths(volumePaths []string, keyValuelabel map[st
Containers: []v1.Container{
{
Name: "vsphere-e2e-container-" + string(uuid.NewUUID()),
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: commands,
VolumeMounts: volumeMounts,
},
@@ -355,3 +354,12 @@ func verifyVSphereVolumesAccessible(pod *v1.Pod, persistentvolumes []*v1.Persist
Expect(err).NotTo(HaveOccurred())
}
}
+
+// Get vSphere Volume Path from PVC
+func getvSphereVolumePathFromClaim(client clientset.Interface, namespace string, claimName string) string {
+ pvclaim, err := client.CoreV1().PersistentVolumeClaims(namespace).Get(claimName, metav1.GetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ pv, err := client.CoreV1().PersistentVolumes().Get(pvclaim.Spec.VolumeName, metav1.GetOptions{})
+ Expect(err).NotTo(HaveOccurred())
+ return pv.Spec.VsphereVolume.VolumePath
+}
diff --git a/test/e2e/testing-manifests/statefulset/cockroachdb/statefulset.yaml b/test/e2e/testing-manifests/statefulset/cockroachdb/statefulset.yaml
index e998d5add4a..1404ccadb91 100644
--- a/test/e2e/testing-manifests/statefulset/cockroachdb/statefulset.yaml
+++ b/test/e2e/testing-manifests/statefulset/cockroachdb/statefulset.yaml
@@ -92,8 +92,6 @@ spec:
volumeClaimTemplates:
- metadata:
name: datadir
- annotations:
- volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes:
- "ReadWriteOnce"
diff --git a/test/e2e/testing-manifests/statefulset/etcd/statefulset.yaml b/test/e2e/testing-manifests/statefulset/etcd/statefulset.yaml
index c7800cd4e8f..4ddeb8be398 100644
--- a/test/e2e/testing-manifests/statefulset/etcd/statefulset.yaml
+++ b/test/e2e/testing-manifests/statefulset/etcd/statefulset.yaml
@@ -166,8 +166,6 @@ spec:
volumeClaimTemplates:
- metadata:
name: datadir
- annotations:
- volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes:
- "ReadWriteOnce"
@@ -175,4 +173,3 @@ spec:
requests:
# upstream recommended max is 700M
storage: 1Gi
-
diff --git a/test/e2e/testing-manifests/statefulset/mysql-galera/statefulset.yaml b/test/e2e/testing-manifests/statefulset/mysql-galera/statefulset.yaml
index 5403371ceb0..4d982ba218a 100644
--- a/test/e2e/testing-manifests/statefulset/mysql-galera/statefulset.yaml
+++ b/test/e2e/testing-manifests/statefulset/mysql-galera/statefulset.yaml
@@ -77,8 +77,6 @@ spec:
volumeClaimTemplates:
- metadata:
name: datadir
- annotations:
- volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
diff --git a/test/e2e/testing-manifests/statefulset/nginx/service.yaml b/test/e2e/testing-manifests/statefulset/nginx/service.yaml
new file mode 100644
index 00000000000..5499b375c34
--- /dev/null
+++ b/test/e2e/testing-manifests/statefulset/nginx/service.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: nginx
+ labels:
+ app: nginx
+spec:
+ ports:
+ - port: 80
+ name: web
+ clusterIP: None
+ selector:
+ app: nginx
\ No newline at end of file
diff --git a/test/e2e/testing-manifests/statefulset/nginx/statefulset.yaml b/test/e2e/testing-manifests/statefulset/nginx/statefulset.yaml
new file mode 100644
index 00000000000..a483fd5dd3f
--- /dev/null
+++ b/test/e2e/testing-manifests/statefulset/nginx/statefulset.yaml
@@ -0,0 +1,34 @@
+apiVersion: apps/v1beta2
+kind: StatefulSet
+metadata:
+ name: web
+spec:
+ serviceName: "nginx"
+ replicas: 3
+ selector:
+ matchLabels:
+ app: nginx
+ template:
+ metadata:
+ labels:
+ app: nginx
+ spec:
+ containers:
+ - name: nginx
+ image: gcr.io/google_containers/nginx-slim:0.8
+ ports:
+ - containerPort: 80
+ name: web
+ volumeMounts:
+ - name: www
+ mountPath: /usr/share/nginx/html
+ volumeClaimTemplates:
+ - metadata:
+ name: www
+ annotations:
+ volume.beta.kubernetes.io/storage-class: nginx-sc
+ spec:
+ accessModes: [ "ReadWriteOnce" ]
+ resources:
+ requests:
+ storage: 1Gi
\ No newline at end of file
diff --git a/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml b/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml
index dfdd3e29336..e324ef5613f 100644
--- a/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml
+++ b/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml
@@ -71,8 +71,6 @@ spec:
volumeClaimTemplates:
- metadata:
name: datadir
- annotations:
- volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
diff --git a/test/e2e/testing-manifests/statefulset/zookeeper/statefulset.yaml b/test/e2e/testing-manifests/statefulset/zookeeper/statefulset.yaml
index 762ededbb22..4160bdff42d 100644
--- a/test/e2e/testing-manifests/statefulset/zookeeper/statefulset.yaml
+++ b/test/e2e/testing-manifests/statefulset/zookeeper/statefulset.yaml
@@ -78,8 +78,6 @@ spec:
volumeClaimTemplates:
- metadata:
name: datadir
- annotations:
- volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
diff --git a/test/e2e/upgrades/apps/deployments.go b/test/e2e/upgrades/apps/deployments.go
index 743c2edd5a7..cafd631f883 100644
--- a/test/e2e/upgrades/apps/deployments.go
+++ b/test/e2e/upgrades/apps/deployments.go
@@ -21,75 +21,63 @@ import (
extensions "k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/types"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
- "k8s.io/kubernetes/pkg/util/version"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/upgrades"
. "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
imageutils "k8s.io/kubernetes/test/utils/image"
)
+const (
+ deploymentName = "dp"
+)
+
// TODO: Test that the deployment stays available during master (and maybe
// node and cluster upgrades).
// DeploymentUpgradeTest tests that a deployment is using the same replica
// sets before and after a cluster upgrade.
type DeploymentUpgradeTest struct {
- oldD *extensions.Deployment
- updatedD *extensions.Deployment
- oldRS *extensions.ReplicaSet
- newRS *extensions.ReplicaSet
+ oldDeploymentUID types.UID
+ oldRSUID types.UID
+ newRSUID types.UID
}
func (DeploymentUpgradeTest) Name() string { return "[sig-apps] deployment-upgrade" }
-func (DeploymentUpgradeTest) Skip(upgCtx upgrades.UpgradeContext) bool {
- // The Deployment upgrade test currently relies on implementation details to probe the
- // ReplicaSets belonging to a Deployment. As of 1.7, the client code we call into no
- // longer supports talking to a server <1.6. (see #47685)
- minVersion := version.MustParseSemantic("v1.6.0")
-
- for _, vCtx := range upgCtx.Versions {
- if vCtx.Version.LessThan(minVersion) {
- return true
- }
- }
- return false
-}
-
-var _ upgrades.Skippable = DeploymentUpgradeTest{}
-
-// Setup creates a deployment and makes sure it has a new and an old replica set running.
-// This calls in to client code and should not be expected to work against a cluster more than one minor version away from the current version.
+// Setup creates a deployment and makes sure it has a new and an old replicaset running.
func (t *DeploymentUpgradeTest) Setup(f *framework.Framework) {
- deploymentName := "deployment-hash-test"
c := f.ClientSet
nginxImage := imageutils.GetE2EImage(imageutils.NginxSlim)
ns := f.Namespace.Name
+ deploymentClient := c.ExtensionsV1beta1().Deployments(ns)
+ rsClient := c.ExtensionsV1beta1().ReplicaSets(ns)
- By(fmt.Sprintf("Creating a deployment %q in namespace %q", deploymentName, ns))
+ By(fmt.Sprintf("Creating a deployment %q with 1 replica in namespace %q", deploymentName, ns))
d := framework.NewDeployment(deploymentName, int32(1), map[string]string{"test": "upgrade"}, "nginx", nginxImage, extensions.RollingUpdateDeploymentStrategyType)
- deployment, err := c.Extensions().Deployments(ns).Create(d)
- framework.ExpectNoError(err)
-
- // Wait for it to be updated to revision 1
- By(fmt.Sprintf("Waiting deployment %q to be updated to revision 1", deploymentName))
- err = framework.WaitForDeploymentRevisionAndImage(c, ns, deploymentName, "1", nginxImage)
+ deployment, err := deploymentClient.Create(d)
framework.ExpectNoError(err)
By(fmt.Sprintf("Waiting deployment %q to complete", deploymentName))
- framework.ExpectNoError(framework.WaitForDeploymentStatusValid(c, deployment))
+ framework.ExpectNoError(framework.WaitForDeploymentCompletes(c, deployment))
- rs, err := deploymentutil.GetNewReplicaSet(deployment, c.ExtensionsV1beta1())
+ By(fmt.Sprintf("Getting replicaset revision 1 of deployment %q", deploymentName))
+ rsSelector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
framework.ExpectNoError(err)
- if rs == nil {
- framework.ExpectNoError(fmt.Errorf("expected a new replica set for deployment %q, found none", deployment.Name))
+ rsList, err := rsClient.List(metav1.ListOptions{LabelSelector: rsSelector.String()})
+ framework.ExpectNoError(err)
+ rss := rsList.Items
+ if len(rss) != 1 {
+ framework.ExpectNoError(fmt.Errorf("expected one replicaset, got %d", len(rss)))
}
+ t.oldRSUID = rss[0].UID
- // Store the old replica set - should be the same after the upgrade.
- t.oldRS = rs
+ By(fmt.Sprintf("Waiting for revision of the deployment %q to become 1", deploymentName))
+ framework.ExpectNoError(framework.WaitForDeploymentRevision(c, deployment, "1"))
// Trigger a new rollout so that we have some history.
By(fmt.Sprintf("Triggering a new rollout for deployment %q", deploymentName))
@@ -98,89 +86,87 @@ func (t *DeploymentUpgradeTest) Setup(f *framework.Framework) {
})
framework.ExpectNoError(err)
- // Use observedGeneration to determine if the controller noticed the pod template update.
- framework.Logf("Wait deployment %q to be observed by the deployment controller", deploymentName)
- framework.ExpectNoError(framework.WaitForObservedDeployment(c, ns, deploymentName, deployment.Generation))
-
- // Wait for it to be updated to revision 2
- By(fmt.Sprintf("Waiting deployment %q to be updated to revision 2", deploymentName))
- framework.ExpectNoError(framework.WaitForDeploymentRevisionAndImage(c, ns, deploymentName, "2", nginxImage))
-
By(fmt.Sprintf("Waiting deployment %q to complete", deploymentName))
- framework.ExpectNoError(framework.WaitForDeploymentStatus(c, deployment))
+ framework.ExpectNoError(framework.WaitForDeploymentCompletes(c, deployment))
- rs, err = deploymentutil.GetNewReplicaSet(deployment, c.ExtensionsV1beta1())
+ By(fmt.Sprintf("Getting replicasets revision 1 and 2 of deployment %q", deploymentName))
+ rsList, err = rsClient.List(metav1.ListOptions{LabelSelector: rsSelector.String()})
framework.ExpectNoError(err)
- if rs == nil {
- framework.ExpectNoError(fmt.Errorf("expected a new replica set for deployment %q", deployment.Name))
+ rss = rsList.Items
+ if len(rss) != 2 {
+ framework.ExpectNoError(fmt.Errorf("expected 2 replicaset, got %d", len(rss)))
}
- if rs.UID == t.oldRS.UID {
- framework.ExpectNoError(fmt.Errorf("expected a new replica set different from the previous one"))
+ By(fmt.Sprintf("Checking replicaset of deployment %q that is created before rollout survives the rollout", deploymentName))
+ switch t.oldRSUID {
+ case rss[0].UID:
+ t.newRSUID = rss[1].UID
+ case rss[1].UID:
+ t.newRSUID = rss[0].UID
+ default:
+ framework.ExpectNoError(fmt.Errorf("old replicaset with UID %q does not survive rollout", t.oldRSUID))
}
- // Store new replica set - should be the same after the upgrade.
- t.newRS = rs
- deployment, err = c.Extensions().Deployments(ns).Get(deployment.Name, metav1.GetOptions{})
- framework.ExpectNoError(err)
- t.oldD = deployment
+ By(fmt.Sprintf("Waiting for revision of the deployment %q to become 2", deploymentName))
+ framework.ExpectNoError(framework.WaitForDeploymentRevision(c, deployment, "2"))
+
+ t.oldDeploymentUID = deployment.UID
}
-// Test checks whether the replica sets for a deployment are the same after an upgrade.
+// Test checks whether the replicasets for a deployment are the same after an upgrade.
func (t *DeploymentUpgradeTest) Test(f *framework.Framework, done <-chan struct{}, upgrade upgrades.UpgradeType) {
// Block until upgrade is done
- By(fmt.Sprintf("Waiting for upgrade to finish before checking replica sets for deployment %q", t.oldD.Name))
+ By(fmt.Sprintf("Waiting for upgrade to finish before checking replicasets for deployment %q", deploymentName))
<-done
c := f.ClientSet
+ ns := f.Namespace.Name
+ deploymentClient := c.ExtensionsV1beta1().Deployments(ns)
+ rsClient := c.ExtensionsV1beta1().ReplicaSets(ns)
- deployment, err := c.Extensions().Deployments(t.oldD.Namespace).Get(t.oldD.Name, metav1.GetOptions{})
+ deployment, err := deploymentClient.Get(deploymentName, metav1.GetOptions{})
framework.ExpectNoError(err)
- t.updatedD = deployment
- By(fmt.Sprintf("Waiting for deployment %q to complete adoption", deployment.Name))
- framework.ExpectNoError(framework.WaitForDeploymentStatus(c, deployment))
+ By(fmt.Sprintf("Checking UID to verify deployment %q survives upgrade", deploymentName))
+ Expect(deployment.UID).To(Equal(t.oldDeploymentUID))
- By(fmt.Sprintf("Checking that replica sets for deployment %q are the same as prior to the upgrade", t.updatedD.Name))
- _, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(t.updatedD, c.ExtensionsV1beta1())
+ By(fmt.Sprintf("Verifying deployment %q does not create new replicasets", deploymentName))
+ rsSelector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
framework.ExpectNoError(err)
- if newRS == nil {
- By(t.spewDeploymentAndReplicaSets(newRS, allOldRSs))
- framework.ExpectNoError(fmt.Errorf("expected a new replica set for deployment %q", t.updatedD.Name))
+ rsList, err := rsClient.List(metav1.ListOptions{LabelSelector: rsSelector.String()})
+ framework.ExpectNoError(err)
+ rss := rsList.Items
+ if len(rss) != 2 {
+ framework.ExpectNoError(fmt.Errorf("expected 2 replicaset, got %d", len(rss)))
}
- if newRS.UID != t.newRS.UID {
- By(t.spewDeploymentAndReplicaSets(newRS, allOldRSs))
- framework.ExpectNoError(fmt.Errorf("expected new replica set:\n%#v\ngot new replica set:\n%#v\n", t.newRS, newRS))
- }
- if len(allOldRSs) != 1 {
- By(t.spewDeploymentAndReplicaSets(newRS, allOldRSs))
- errString := fmt.Sprintf("expected one old replica set, got %d\n", len(allOldRSs))
- for i := range allOldRSs {
- rs := allOldRSs[i]
- errString += fmt.Sprintf("%#v\n", rs)
- }
- framework.ExpectNoError(fmt.Errorf(errString))
- }
- if allOldRSs[0].UID != t.oldRS.UID {
- By(t.spewDeploymentAndReplicaSets(newRS, allOldRSs))
- framework.ExpectNoError(fmt.Errorf("expected old replica set:\n%#v\ngot old replica set:\n%#v\n", t.oldRS, allOldRSs[0]))
+
+ switch t.oldRSUID {
+ case rss[0].UID:
+ Expect(rss[1].UID).To(Equal(t.newRSUID))
+ case rss[1].UID:
+ Expect(rss[0].UID).To(Equal(t.newRSUID))
+ default:
+ framework.ExpectNoError(fmt.Errorf("new replicasets are created during upgrade of deployment %q", deploymentName))
}
+
+ By(fmt.Sprintf("Verifying revision of the deployment %q is still 2", deploymentName))
+ Expect(deployment.Annotations[deploymentutil.RevisionAnnotation]).To(Equal("2"))
+
+ By(fmt.Sprintf("Waiting for deployment %q to complete adoption", deploymentName))
+ framework.ExpectNoError(framework.WaitForDeploymentCompletes(c, deployment))
+
+ // Verify the upgraded deployment is active by scaling up the deployment by 1
+ By(fmt.Sprintf("Scaling up replicaset of deployment %q by 1", deploymentName))
+ _, err = framework.UpdateDeploymentWithRetries(c, ns, deploymentName, func(deployment *extensions.Deployment) {
+ *deployment.Spec.Replicas = *deployment.Spec.Replicas + 1
+ })
+ framework.ExpectNoError(err)
+
+ By(fmt.Sprintf("Waiting for deployment %q to complete after scaling", deploymentName))
+ framework.ExpectNoError(framework.WaitForDeploymentCompletes(c, deployment))
}
// Teardown cleans up any remaining resources.
func (t *DeploymentUpgradeTest) Teardown(f *framework.Framework) {
// rely on the namespace deletion to clean up everything
}
-
-func (t *DeploymentUpgradeTest) spewDeploymentAndReplicaSets(newRS *extensions.ReplicaSet, allOldRSs []*extensions.ReplicaSet) string {
- msg := fmt.Sprintf("deployment prior to the upgrade:\n%#v\n", t.oldD)
- msg += fmt.Sprintf("old replica sets prior to the upgrade:\n%#v\n", t.oldRS)
- msg += fmt.Sprintf("new replica sets prior to the upgrade:\n%#v\n", t.newRS)
- msg += fmt.Sprintf("deployment after the upgrade:\n%#v\n", t.updatedD)
- msg += fmt.Sprintf("new replica set after the upgrade:\n%#v\n", newRS)
- msg += fmt.Sprintf("old replica sets after the upgrade:\n")
- for i := range allOldRSs {
- msg += fmt.Sprintf("%#v\n", allOldRSs[i])
- }
- return msg
-}
diff --git a/test/e2e/upgrades/configmaps.go b/test/e2e/upgrades/configmaps.go
index 476c283c37c..af39c3b1b1f 100644
--- a/test/e2e/upgrades/configmaps.go
+++ b/test/e2e/upgrades/configmaps.go
@@ -118,7 +118,7 @@ func (t *ConfigMapUpgradeTest) testPod(f *framework.Framework) {
},
{
Name: "configmap-env-test",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"sh", "-c", "env"},
Env: []v1.EnvVar{
{
diff --git a/test/e2e/upgrades/secrets.go b/test/e2e/upgrades/secrets.go
index 03fe8656378..807c47f6c1a 100644
--- a/test/e2e/upgrades/secrets.go
+++ b/test/e2e/upgrades/secrets.go
@@ -114,7 +114,7 @@ func (t *SecretUpgradeTest) testPod(f *framework.Framework) {
},
{
Name: "secret-env-test",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"sh", "-c", "env"},
Env: []v1.EnvVar{
{
diff --git a/test/e2e/upgrades/sysctl.go b/test/e2e/upgrades/sysctl.go
index 373360c407d..5ef0422ee3f 100644
--- a/test/e2e/upgrades/sysctl.go
+++ b/test/e2e/upgrades/sysctl.go
@@ -30,7 +30,6 @@ import (
"k8s.io/kubernetes/pkg/kubelet/sysctl"
"k8s.io/kubernetes/test/e2e/framework"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
// SecretUpgradeTest tests that a pod with sysctls runs before and after an upgrade. During
@@ -132,7 +131,7 @@ func sysctlTestPod(name string, sysctls map[string]string) *v1.Pod {
Containers: []v1.Container{
{
Name: "test-container",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: append([]string{"/bin/sysctl"}, keys...),
},
},
diff --git a/test/e2e_node/docker_test.go b/test/e2e_node/docker_test.go
index 6142eba8b20..d8ecc68a1a7 100644
--- a/test/e2e_node/docker_test.go
+++ b/test/e2e_node/docker_test.go
@@ -24,7 +24,6 @@ import (
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/test/e2e/framework"
- imageutils "k8s.io/kubernetes/test/utils/image"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -55,12 +54,12 @@ var _ = framework.KubeDescribe("Docker features [Feature:Docker]", func() {
Containers: []v1.Container{
{
Name: "test-container-1",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"/bin/top"},
},
{
Name: "test-container-2",
- Image: imageutils.GetBusyBoxImage(),
+ Image: "busybox",
Command: []string{"/bin/sleep"},
Args: []string{"10000"},
},
diff --git a/test/e2e_node/security_context_test.go b/test/e2e_node/security_context_test.go
index 08b395fc4bd..7e30d167fc9 100644
--- a/test/e2e_node/security_context_test.go
+++ b/test/e2e_node/security_context_test.go
@@ -341,7 +341,7 @@ var _ = framework.KubeDescribe("Security Context", func() {
createAndWaitUserPod := func(readOnlyRootFilesystem bool) string {
podName := fmt.Sprintf("busybox-readonly-%v-%s", readOnlyRootFilesystem, uuid.NewUUID())
podClient.Create(makeUserPod(podName,
- imageutils.GetBusyBoxImage(),
+ "busybox",
[]string{"sh", "-c", "touch checkfile"},
readOnlyRootFilesystem,
))
diff --git a/test/e2e_node/util.go b/test/e2e_node/util.go
index 3cec9f54dbc..e9fc1a653a8 100644
--- a/test/e2e_node/util.go
+++ b/test/e2e_node/util.go
@@ -45,7 +45,6 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
- imageutils "k8s.io/kubernetes/test/utils/image"
)
// TODO(random-liu): Get this automatically from kubelet flag.
@@ -53,7 +52,7 @@ var kubeletAddress = flag.String("kubelet-address", "http://127.0.0.1:10255", "H
var startServices = flag.Bool("start-services", true, "If true, start local node services")
var stopServices = flag.Bool("stop-services", true, "If true, stop local node services after running tests")
-var busyboxImage = imageutils.GetBusyBoxImage()
+var busyboxImage = "busybox"
func getNodeSummary() (*stats.Summary, error) {
req, err := http.NewRequest("GET", *kubeletAddress+"/stats/summary", nil)
diff --git a/test/integration/scheduler/predicates_test.go b/test/integration/scheduler/predicates_test.go
index 0fe1fc78879..beb5873fd78 100644
--- a/test/integration/scheduler/predicates_test.go
+++ b/test/integration/scheduler/predicates_test.go
@@ -30,6 +30,8 @@ import (
// This file tests the scheduler predicates functionality.
+const pollInterval = 100 * time.Millisecond
+
// TestInterPodAffinity verifies that scheduler's inter pod affinity and
// anti-affinity predicate functions works correctly.
func TestInterPodAffinity(t *testing.T) {
@@ -808,6 +810,7 @@ func TestInterPodAffinity(t *testing.T) {
test: "nodes[0] and nodes[1] have same topologyKey and label value. nodes[0] has an existing pod that matches the inter pod affinity rule. The new pod can not be scheduled onto either of the two nodes.",
},
}
+
for _, test := range tests {
for _, pod := range test.pods {
var nsName string
@@ -820,7 +823,7 @@ func TestInterPodAffinity(t *testing.T) {
if err != nil {
t.Fatalf("Test Failed: error, %v, while creating pod during test: %v", err, test.test)
}
- err = wait.Poll(time.Second, wait.ForeverTestTimeout, podScheduled(cs, createdPod.Namespace, createdPod.Name))
+ err = wait.Poll(pollInterval, wait.ForeverTestTimeout, podScheduled(cs, createdPod.Namespace, createdPod.Name))
if err != nil {
t.Errorf("Test Failed: error, %v, while waiting for pod during test, %v", err, test)
}
@@ -831,12 +834,20 @@ func TestInterPodAffinity(t *testing.T) {
t.Fatalf("Test Failed: error, %v, while creating pod during test: %v", err, test.test)
}
} else {
- err = wait.Poll(time.Second, wait.ForeverTestTimeout, podScheduled(cs, testPod.Namespace, testPod.Name))
- if err != nil && err != wait.ErrWaitTimeout {
- t.Errorf("Test Failed: error, %v, while waiting for pod to get scheduled, %v", err, test.test)
+ waitTime := wait.ForeverTestTimeout
+ if !test.fits {
+ waitTime = 2 * time.Second
}
- if (err == nil) != test.fits {
- t.Errorf("Test Failed: %v, err %v, test.fits %v", test.test, err, test.fits)
+
+ err = wait.Poll(pollInterval, waitTime, podScheduled(cs, testPod.Namespace, testPod.Name))
+ if test.fits {
+ if err != nil {
+ t.Errorf("Test Failed: %v, err %v, test.fits %v", test.test, err, test.fits)
+ }
+ } else {
+ if err != wait.ErrWaitTimeout {
+ t.Errorf("Test Failed: error, %v, while waiting for pod to get scheduled, %v", err, test.test)
+ }
}
for _, pod := range test.pods {
@@ -850,7 +861,7 @@ func TestInterPodAffinity(t *testing.T) {
if err != nil {
t.Errorf("Test Failed: error, %v, while deleting pod during test: %v", err, test.test)
}
- err = wait.Poll(time.Second, wait.ForeverTestTimeout, podDeleted(cs, nsName, pod.Name))
+ err = wait.Poll(pollInterval, wait.ForeverTestTimeout, podDeleted(cs, nsName, pod.Name))
if err != nil {
t.Errorf("Test Failed: error, %v, while waiting for pod to get deleted, %v", err, test.test)
}
@@ -859,7 +870,7 @@ func TestInterPodAffinity(t *testing.T) {
if err != nil {
t.Errorf("Test Failed: error, %v, while deleting pod during test: %v", err, test.test)
}
- err = wait.Poll(time.Second, wait.ForeverTestTimeout, podDeleted(cs, context.ns.Name, test.pod.Name))
+ err = wait.Poll(pollInterval, wait.ForeverTestTimeout, podDeleted(cs, context.ns.Name, test.pod.Name))
if err != nil {
t.Errorf("Test Failed: error, %v, while waiting for pod to get deleted, %v", err, test.test)
}
diff --git a/test/integration/scheduler/scheduler_test.go b/test/integration/scheduler/scheduler_test.go
index 46ad59a66b6..5bdd78d341d 100644
--- a/test/integration/scheduler/scheduler_test.go
+++ b/test/integration/scheduler/scheduler_test.go
@@ -384,7 +384,7 @@ func TestUnschedulableNodes(t *testing.T) {
}
// There are no schedulable nodes - the pod shouldn't be scheduled.
- err = waitForPodToSchedule(context.clientSet, myPod)
+ err = waitForPodToScheduleWithTimeout(context.clientSet, myPod, 2*time.Second)
if err == nil {
t.Errorf("Pod scheduled successfully on unschedulable nodes")
}
diff --git a/test/integration/scheduler/util.go b/test/integration/scheduler/util.go
index 8e9ba588a95..c291599b995 100644
--- a/test/integration/scheduler/util.go
+++ b/test/integration/scheduler/util.go
@@ -332,13 +332,13 @@ func podScheduled(c clientset.Interface, podNamespace, podName string) wait.Cond
// waitForPodToScheduleWithTimeout waits for a pod to get scheduled and returns
// an error if it does not scheduled within the given timeout.
func waitForPodToScheduleWithTimeout(cs clientset.Interface, pod *v1.Pod, timeout time.Duration) error {
- return wait.Poll(time.Second, timeout, podScheduled(cs, pod.Namespace, pod.Name))
+ return wait.Poll(100*time.Millisecond, timeout, podScheduled(cs, pod.Namespace, pod.Name))
}
// waitForPodToSchedule waits for a pod to get scheduled and returns an error if
-// it does not scheduled within the timeout duration (30 seconds).
+// it does not get scheduled within the timeout duration (30 seconds).
func waitForPodToSchedule(cs clientset.Interface, pod *v1.Pod) error {
- return waitForPodToScheduleWithTimeout(cs, pod, wait.ForeverTestTimeout)
+ return waitForPodToScheduleWithTimeout(cs, pod, 30*time.Second)
}
// deletePod deletes the given pod in the given namespace.
diff --git a/test/utils/deployment.go b/test/utils/deployment.go
index a531e769508..f2616ff25fc 100644
--- a/test/utils/deployment.go
+++ b/test/utils/deployment.go
@@ -244,3 +244,26 @@ func WaitForObservedDeployment(c clientset.Interface, ns, deploymentName string,
return c.Extensions().Deployments(ns).Get(deploymentName, metav1.GetOptions{})
}, desiredGeneration, 2*time.Second, 1*time.Minute)
}
+
+// Pool until deployment status and its underlying resources reach the desired state.
+func WaitForDeploymentCompletes(c clientset.Interface, d *extensions.Deployment, logf LogfFn, pollInterval, pollTimeout time.Duration) error {
+ var reason string
+ err := wait.PollImmediate(pollInterval, pollTimeout, func() (bool, error) {
+ deployment, err := c.ExtensionsV1beta1().Deployments(d.Namespace).Get(d.Name, metav1.GetOptions{})
+ if err != nil {
+ return false, err
+ }
+ // When the deployment status and its underlying resources reach the desired state, we're done
+ if deploymentutil.DeploymentComplete(d, &deployment.Status) {
+ return true, nil
+ }
+ reason = fmt.Sprintf("deployment status: %#v", deployment.Status)
+ logf(reason)
+ return false, nil
+ })
+
+ if err == wait.ErrWaitTimeout {
+ err = fmt.Errorf("timeout waiting for deployment to complete: %v, most recent deployment status: %s", err, reason)
+ }
+ return err
+}
diff --git a/test/utils/image/manifest.go b/test/utils/image/manifest.go
index dda151abe64..1d03dea5ec1 100644
--- a/test/utils/image/manifest.go
+++ b/test/utils/image/manifest.go
@@ -86,21 +86,3 @@ var (
func GetE2EImage(image ImageConfig) string {
return fmt.Sprintf("%s/%s-%s:%s", image.registry, image.name, runtime.GOARCH, image.version)
}
-
-// GetBusyboxImage returns multi-arch busybox docker image
-func GetBusyBoxImage() string {
- switch arch := runtime.GOARCH; arch {
- case "amd64":
- return "busybox"
- case "arm":
- return "arm32v6/busybox"
- case "arm64":
- return "arm64v8/busybox"
- case "ppc64le":
- return "ppc64le/busybox"
- case "s390x":
- return "s390x/busybox"
- default:
- return ""
- }
-}
diff --git a/vendor/google.golang.org/grpc/.travis.yml b/vendor/google.golang.org/grpc/.travis.yml
index b3577c7ae20..9032f8dcdfa 100644
--- a/vendor/google.golang.org/grpc/.travis.yml
+++ b/vendor/google.golang.org/grpc/.travis.yml
@@ -1,19 +1,20 @@
language: go
go:
- - 1.6.3
- - 1.7
- - 1.8
+ - 1.6.x
+ - 1.7.x
+ - 1.8.x
go_import_path: google.golang.org/grpc
before_install:
- - go get github.com/golang/lint/golint
+ - if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then go get -u github.com/golang/lint/golint honnef.co/go/tools/cmd/staticcheck; fi
- go get -u golang.org/x/tools/cmd/goimports github.com/axw/gocov/gocov github.com/mattn/goveralls golang.org/x/tools/cmd/cover
script:
- '! gofmt -s -d -l . 2>&1 | read'
- '! goimports -l . | read'
- - '! golint ./... | grep -vE "(_mock|_string|\.pb)\.go:"'
- - '! go tool vet -all . 2>&1 | grep -vE "constant [0-9]+ not a string in call to Errorf" | grep -vF .pb.go:' # https://github.com/golang/protobuf/issues/214
+ - 'if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then ! golint ./... | grep -vE "(_mock|_string|\.pb)\.go:"; fi'
+ - 'if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then ! go tool vet -all . 2>&1 | grep -vF .pb.go:; fi' # https://github.com/golang/protobuf/issues/214
- make test testrace
+ - 'if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then staticcheck -ignore google.golang.org/grpc/transport/transport_test.go:SA2002 ./...; fi' # TODO(menghanl): fix these
diff --git a/vendor/google.golang.org/grpc/AUTHORS b/vendor/google.golang.org/grpc/AUTHORS
new file mode 100644
index 00000000000..e491a9e7f78
--- /dev/null
+++ b/vendor/google.golang.org/grpc/AUTHORS
@@ -0,0 +1 @@
+Google Inc.
diff --git a/vendor/google.golang.org/grpc/BUILD b/vendor/google.golang.org/grpc/BUILD
index 9b550cb77b9..f68202ea2c1 100644
--- a/vendor/google.golang.org/grpc/BUILD
+++ b/vendor/google.golang.org/grpc/BUILD
@@ -27,6 +27,7 @@ go_library(
"//vendor/golang.org/x/net/http2:go_default_library",
"//vendor/golang.org/x/net/trace:go_default_library",
"//vendor/google.golang.org/grpc/codes:go_default_library",
+ "//vendor/google.golang.org/grpc/connectivity:go_default_library",
"//vendor/google.golang.org/grpc/credentials:go_default_library",
"//vendor/google.golang.org/grpc/grpclb/grpc_lb_v1:go_default_library",
"//vendor/google.golang.org/grpc/grpclog:go_default_library",
@@ -54,6 +55,7 @@ filegroup(
srcs = [
":package-srcs",
"//vendor/google.golang.org/grpc/codes:all-srcs",
+ "//vendor/google.golang.org/grpc/connectivity:all-srcs",
"//vendor/google.golang.org/grpc/credentials:all-srcs",
"//vendor/google.golang.org/grpc/grpclb/grpc_lb_v1:all-srcs",
"//vendor/google.golang.org/grpc/grpclog:all-srcs",
diff --git a/vendor/google.golang.org/grpc/CONTRIBUTING.md b/vendor/google.golang.org/grpc/CONTRIBUTING.md
index 36cd6f7581b..a5c6e06e255 100644
--- a/vendor/google.golang.org/grpc/CONTRIBUTING.md
+++ b/vendor/google.golang.org/grpc/CONTRIBUTING.md
@@ -1,46 +1,32 @@
# How to contribute
-We definitely welcome patches and contribution to grpc! Here are some guidelines
-and information about how to do so.
+We definitely welcome your patches and contributions to gRPC!
-## Sending patches
-
-### Getting started
-
-1. Check out the code:
-
- $ go get google.golang.org/grpc
- $ cd $GOPATH/src/google.golang.org/grpc
-
-1. Create a fork of the grpc-go repository.
-1. Add your fork as a remote:
-
- $ git remote add fork git@github.com:$YOURGITHUBUSERNAME/grpc-go.git
-
-1. Make changes, commit them.
-1. Run the test suite:
-
- $ make test
-
-1. Push your changes to your fork:
-
- $ git push fork ...
-
-1. Open a pull request.
+If you are new to github, please start by reading [Pull Request howto](https://help.github.com/articles/about-pull-requests/)
## Legal requirements
In order to protect both you and ourselves, you will need to sign the
[Contributor License Agreement](https://cla.developers.google.com/clas).
-## Filing Issues
-When filing an issue, make sure to answer these five questions:
+## Guidelines for Pull Requests
+How to get your contributions merged smoothly and quickly.
+
+- Create **small PRs** that are narrowly focused on **addressing a single concern**. We often times receive PRs that are trying to fix several things at a time, but only one fix is considered acceptable, nothing gets merged and both author's & review's time is wasted. Create more PRs to address different concerns and everyone will be happy.
+
+- For speculative changes, consider opening an issue and discussing it first. If you are suggesting a behavioral or API change, consider starting with a [gRFC proposal](https://github.com/grpc/proposal).
+
+- Provide a good **PR description** as a record of **what** change is being made and **why** it was made. Link to a github issue if it exists.
+
+- Don't fix code style and formatting unless you are already changing that line to address an issue. PRs with irrelevant changes won't be merged. If you do want to fix formatting or style, do that in a separate PR.
+
+- Unless your PR is trivial, you should expect there will be reviewer comments that you'll need to address before merging. We expect you to be reasonably responsive to those comments, otherwise the PR will be closed after 2-3 weeks of inactivity.
+
+- Maintain **clean commit history** and use **meaningful commit messages**. PRs with messy commit history are difficult to review and won't be merged. Use `rebase -i upstream/master` to curate your commit history and/or to bring in latest changes from master (but avoid rebasing in the middle of a code review).
+
+- Keep your PR up to date with upstream/master (if there are merge conflicts, we can't really merge your change).
+
+- **All tests need to be passing** before your change can be merged. We recommend you **run tests locally** before creating your PR to catch breakages early on.
-1. What version of Go are you using (`go version`)?
-2. What operating system and processor architecture are you using?
-3. What did you do?
-4. What did you expect to see?
-5. What did you see instead?
-
-### Contributing code
-Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.
+- Exceptions to the rules can be made if there's a compelling reason for doing so.
+
diff --git a/vendor/google.golang.org/grpc/LICENSE b/vendor/google.golang.org/grpc/LICENSE
index f4988b45079..d6456956733 100644
--- a/vendor/google.golang.org/grpc/LICENSE
+++ b/vendor/google.golang.org/grpc/LICENSE
@@ -1,28 +1,202 @@
-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:
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- * 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.
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-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.
+ 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/vendor/google.golang.org/grpc/PATENTS b/vendor/google.golang.org/grpc/PATENTS
deleted file mode 100644
index 69b47959fab..00000000000
--- a/vendor/google.golang.org/grpc/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the gRPC project.
-
-Google 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,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of gRPC, where such license applies only to those patent
-claims, both currently owned or controlled by Google and acquired in
-the future, licensable by Google that are necessarily infringed by this
-implementation of gRPC. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute or
-order or agree to the institution of patent litigation against any
-entity (including a cross-claim or counterclaim in a lawsuit) alleging
-that this implementation of gRPC or any code incorporated within this
-implementation of gRPC constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of gRPC
-shall terminate as of the date such litigation is filed.
diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md
index ae0236f92f3..72c7325cc7d 100644
--- a/vendor/google.golang.org/grpc/README.md
+++ b/vendor/google.golang.org/grpc/README.md
@@ -2,7 +2,7 @@
[](https://travis-ci.org/grpc/grpc-go) [](https://godoc.org/google.golang.org/grpc)
-The Go implementation of [gRPC](http://www.grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the [gRPC Quick Start](http://www.grpc.io/docs/) guide.
+The Go implementation of [gRPC](https://grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the [gRPC Quick Start: Go](https://grpc.io/docs/quickstart/go.html) guide.
Installation
------------
@@ -26,9 +26,13 @@ Documentation
-------------
See [API documentation](https://godoc.org/google.golang.org/grpc) for package and API descriptions and find examples in the [examples directory](examples/).
+Performance
+-----------
+See the current benchmarks for some of the languages supported in [this dashboard](https://performance-dot-grpc-testing.appspot.com/explore?dashboard=5652536396611584&widget=490377658&container=1286539696).
+
Status
------
-GA
+General Availability [Google Cloud Platform Launch Stages](https://cloud.google.com/terms/launch-stages).
FAQ
---
diff --git a/vendor/google.golang.org/grpc/backoff.go b/vendor/google.golang.org/grpc/backoff.go
index c99024ee302..090fbe87c52 100644
--- a/vendor/google.golang.org/grpc/backoff.go
+++ b/vendor/google.golang.org/grpc/backoff.go
@@ -1,3 +1,21 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
package grpc
import (
diff --git a/vendor/google.golang.org/grpc/balancer.go b/vendor/google.golang.org/grpc/balancer.go
index 9d943fbadae..cde472c8120 100644
--- a/vendor/google.golang.org/grpc/balancer.go
+++ b/vendor/google.golang.org/grpc/balancer.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2016, Google Inc.
- * All rights reserved.
+ * Copyright 2016 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -35,6 +20,7 @@ package grpc
import (
"fmt"
+ "net"
"sync"
"golang.org/x/net/context"
@@ -60,6 +46,10 @@ type BalancerConfig struct {
// use to dial to a remote load balancer server. The Balancer implementations
// can ignore this if it does not need to talk to another party securely.
DialCreds credentials.TransportCredentials
+ // Dialer is the custom dialer the Balancer implementation can use to dial
+ // to a remote load balancer server. The Balancer implementations
+ // can ignore this if it doesn't need to talk to remote balancer.
+ Dialer func(context.Context, string) (net.Conn, error)
}
// BalancerGetOptions configures a Get call.
@@ -167,7 +157,7 @@ type roundRobin struct {
func (rr *roundRobin) watchAddrUpdates() error {
updates, err := rr.w.Next()
if err != nil {
- grpclog.Printf("grpc: the naming watcher stops working due to %v.\n", err)
+ grpclog.Warningf("grpc: the naming watcher stops working due to %v.", err)
return err
}
rr.mu.Lock()
@@ -183,7 +173,7 @@ func (rr *roundRobin) watchAddrUpdates() error {
for _, v := range rr.addrs {
if addr == v.addr {
exist = true
- grpclog.Println("grpc: The name resolver wanted to add an existing address: ", addr)
+ grpclog.Infoln("grpc: The name resolver wanted to add an existing address: ", addr)
break
}
}
@@ -200,7 +190,7 @@ func (rr *roundRobin) watchAddrUpdates() error {
}
}
default:
- grpclog.Println("Unknown update.Op ", update.Op)
+ grpclog.Errorln("Unknown update.Op ", update.Op)
}
}
// Make a copy of rr.addrs and write it onto rr.addrCh so that gRPC internals gets notified.
@@ -211,6 +201,10 @@ func (rr *roundRobin) watchAddrUpdates() error {
if rr.done {
return ErrClientConnClosing
}
+ select {
+ case <-rr.addrCh:
+ default:
+ }
rr.addrCh <- open
return nil
}
@@ -233,7 +227,7 @@ func (rr *roundRobin) Start(target string, config BalancerConfig) error {
return err
}
rr.w = w
- rr.addrCh = make(chan []Address)
+ rr.addrCh = make(chan []Address, 1)
go func() {
for {
if err := rr.watchAddrUpdates(); err != nil {
@@ -385,6 +379,9 @@ func (rr *roundRobin) Notify() <-chan []Address {
func (rr *roundRobin) Close() error {
rr.mu.Lock()
defer rr.mu.Unlock()
+ if rr.done {
+ return errBalancerClosed
+ }
rr.done = true
if rr.w != nil {
rr.w.Close()
diff --git a/vendor/google.golang.org/grpc/call.go b/vendor/google.golang.org/grpc/call.go
index af34a71316f..797190f1471 100644
--- a/vendor/google.golang.org/grpc/call.go
+++ b/vendor/google.golang.org/grpc/call.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -73,7 +58,10 @@ func recvResponse(ctx context.Context, dopts dialOptions, t transport.ClientTran
}
}
for {
- if err = recv(p, dopts.codec, stream, dopts.dc, reply, dopts.maxMsgSize, inPayload); err != nil {
+ if c.maxReceiveMessageSize == nil {
+ return Errorf(codes.Internal, "callInfo maxReceiveMessageSize field uninitialized(nil)")
+ }
+ if err = recv(p, dopts.codec, stream, dopts.dc, reply, *c.maxReceiveMessageSize, inPayload); err != nil {
if err == io.EOF {
break
}
@@ -86,14 +74,11 @@ func recvResponse(ctx context.Context, dopts dialOptions, t transport.ClientTran
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, dopts dialOptions, compressor Compressor, callHdr *transport.CallHdr, stream *transport.Stream, t transport.ClientTransport, args interface{}, opts *transport.Options) (err error) {
+func sendRequest(ctx context.Context, dopts dialOptions, compressor Compressor, c *callInfo, 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.
@@ -116,7 +101,13 @@ func sendRequest(ctx context.Context, dopts dialOptions, compressor Compressor,
}
outBuf, err := encode(dopts.codec, args, compressor, cbuf, outPayload)
if err != nil {
- return Errorf(codes.Internal, "grpc: %v", err)
+ return err
+ }
+ if c.maxSendMessageSize == nil {
+ return Errorf(codes.Internal, "callInfo maxSendMessageSize field uninitialized(nil)")
+ }
+ if len(outBuf) > *c.maxSendMessageSize {
+ return Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", len(outBuf), *c.maxSendMessageSize)
}
err = t.Write(stream, outBuf, opts)
if err == nil && outPayload != nil {
@@ -145,14 +136,18 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
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()
- }
+ mc := cc.GetMethodConfig(method)
+ if mc.WaitForReady != nil {
+ c.failFast = !*mc.WaitForReady
}
+
+ if mc.Timeout != nil && *mc.Timeout >= 0 {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithTimeout(ctx, *mc.Timeout)
+ defer cancel()
+ }
+
+ opts = append(cc.dopts.callOptions, opts...)
for _, o := range opts {
if err := o.before(&c); err != nil {
return toRPCErr(err)
@@ -163,6 +158,10 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
o.after(&c)
}
}()
+
+ c.maxSendMessageSize = getMaxSize(mc.MaxReqSize, c.maxSendMessageSize, defaultClientMaxSendMessageSize)
+ c.maxReceiveMessageSize = getMaxSize(mc.MaxRespSize, c.maxReceiveMessageSize, defaultClientMaxReceiveMessageSize)
+
if EnableTracing {
c.traceInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method)
defer c.traceInfo.tr.Finish()
@@ -182,24 +181,22 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
ctx = newContextWithRPCInfo(ctx)
sh := cc.dopts.copts.StatsHandler
if sh != nil {
- ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method})
+ ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method, FailFast: c.failFast})
begin := &stats.Begin{
Client: true,
BeginTime: time.Now(),
FailFast: c.failFast,
}
sh.HandleRPC(ctx, begin)
- }
- defer func() {
- if sh != nil {
+ defer func() {
end := &stats.End{
Client: true,
EndTime: time.Now(),
Error: e,
}
sh.HandleRPC(ctx, end)
- }
- }()
+ }()
+ }
topts := &transport.Options{
Last: true,
Delay: false,
@@ -221,6 +218,9 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
if cc.dopts.cp != nil {
callHdr.SendCompress = cc.dopts.cp.Type()
}
+ if c.creds != nil {
+ callHdr.Creds = c.creds
+ }
gopts := BalancerGetOptions{
BlockingWait: !c.failFast,
@@ -259,7 +259,10 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
}
return toRPCErr(err)
}
- err = sendRequest(ctx, cc.dopts, cc.dopts.cp, callHdr, stream, t, args, topts)
+ if peer, ok := peer.FromContext(stream.Context()); ok {
+ c.peer = peer
+ }
+ err = sendRequest(ctx, cc.dopts, cc.dopts.cp, &c, callHdr, stream, t, args, topts)
if err != nil {
if put != nil {
updateRPCInfoInContext(ctx, rpcInfo{
diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go
index f542d8bd041..e3e3140f1f8 100644
--- a/vendor/google.golang.org/grpc/clientconn.go
+++ b/vendor/google.golang.org/grpc/clientconn.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -35,14 +20,14 @@ package grpc
import (
"errors"
- "fmt"
- "math"
"net"
+ "strings"
"sync"
"time"
"golang.org/x/net/context"
"golang.org/x/net/trace"
+ "google.golang.org/grpc/connectivity"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/keepalive"
@@ -56,8 +41,7 @@ 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.
+ // DEPRECATED: Please use context.DeadlineExceeded instead.
ErrClientConnTimeout = errors.New("grpc: timed out when dialing")
// errNoTransportSecurity indicates that there is no transport security
@@ -79,6 +63,8 @@ var (
errConnClosing = errors.New("grpc: the connection is closing")
// errConnUnavailable indicates that the connection is unavailable.
errConnUnavailable = errors.New("grpc: the connection is unavailable")
+ // errBalancerClosed indicates that the balancer is closed.
+ errBalancerClosed = errors.New("grpc: balancer is closed")
// minimum time to give a connection to complete
minConnectTimeout = 20 * time.Second
)
@@ -86,30 +72,54 @@ 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
- scChan <-chan ServiceConfig
- copts transport.ConnectOptions
- maxMsgSize int
+ 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
+ callOptions []CallOption
}
-const defaultClientMaxMsgSize = math.MaxInt32
+const (
+ defaultClientMaxReceiveMessageSize = 1024 * 1024 * 4
+ defaultClientMaxSendMessageSize = 1024 * 1024 * 4
+)
// 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 {
+// WithInitialWindowSize returns a DialOption which sets the value for initial window size on a stream.
+// The lower bound for window size is 64K and any value smaller than that will be ignored.
+func WithInitialWindowSize(s int32) DialOption {
return func(o *dialOptions) {
- o.maxMsgSize = s
+ o.copts.InitialWindowSize = s
+ }
+}
+
+// WithInitialConnWindowSize returns a DialOption which sets the value for initial window size on a connection.
+// The lower bound for window size is 64K and any value smaller than that will be ignored.
+func WithInitialConnWindowSize(s int32) DialOption {
+ return func(o *dialOptions) {
+ o.copts.InitialConnWindowSize = s
+ }
+}
+
+// WithMaxMsgSize returns a DialOption which sets the maximum message size the client can receive. Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead.
+func WithMaxMsgSize(s int) DialOption {
+ return WithDefaultCallOptions(MaxCallRecvMsgSize(s))
+}
+
+// WithDefaultCallOptions returns a DialOption which sets the default CallOptions for calls over the connection.
+func WithDefaultCallOptions(cos ...CallOption) DialOption {
+ return func(o *dialOptions) {
+ o.callOptions = append(o.callOptions, cos...)
}
}
@@ -204,7 +214,7 @@ func WithTransportCredentials(creds credentials.TransportCredentials) DialOption
}
// WithPerRPCCredentials returns a DialOption which sets
-// credentials which will place auth state on each outbound RPC.
+// credentials and places auth state on each outbound RPC.
func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption {
return func(o *dialOptions) {
o.copts.PerRPCCredentials = append(o.copts.PerRPCCredentials, creds)
@@ -213,6 +223,7 @@ func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption {
// WithTimeout returns a DialOption that configures a timeout for dialing a ClientConn
// initially. This is valid if and only if WithBlock() is present.
+// Deprecated: use DialContext and context.WithTimeout instead.
func WithTimeout(d time.Duration) DialOption {
return func(o *dialOptions) {
o.timeout = d
@@ -241,7 +252,7 @@ func WithStatsHandler(h stats.Handler) DialOption {
}
}
-// FailOnNonTempDialError returns a DialOption that specified if gRPC fails on non-temporary dial errors.
+// FailOnNonTempDialError returns a DialOption that specifies 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.
@@ -295,17 +306,18 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
}
// DialContext creates a client connection to the given target. ctx can be used to
-// cancel or expire the pending connecting. Once this function returns, the
+// cancel or expire the pending connection. Once this function returns, the
// cancellation and expiration of ctx will be noop. Users should call ClientConn.Close
// to terminate all the pending operations after this function returns.
-// This is the EXPERIMENTAL API.
func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) {
cc := &ClientConn{
target: target,
+ csMgr: &connectivityStateManager{},
conns: make(map[Address]*addrConn),
}
+ cc.csEvltr = &connectivityStateEvaluator{csMgr: cc.csMgr}
cc.ctx, cc.cancel = context.WithCancel(context.Background())
- cc.dopts.maxMsgSize = defaultClientMaxMsgSize
+
for _, opt := range opts {
opt(&cc.dopts)
}
@@ -343,15 +355,16 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
}
}()
+ scSet := false
if cc.dopts.scChan != nil {
- // Wait for the initial service config.
+ // Try to get an initial service config.
select {
case sc, ok := <-cc.dopts.scChan:
if ok {
cc.sc = sc
+ scSet = true
}
- case <-ctx.Done():
- return nil, ctx.Err()
+ default:
}
}
// Set defaults.
@@ -382,6 +395,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
}
config := BalancerConfig{
DialCreds: credsClone,
+ Dialer: cc.dopts.copts.Dialer,
}
if err := cc.dopts.balancer.Start(target, config); err != nil {
waitC <- err
@@ -413,7 +427,17 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
return nil, err
}
}
-
+ if cc.dopts.scChan != nil && !scSet {
+ // Blocking 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()
+ }
+ }
if cc.dopts.scChan != nil {
go cc.scWatcher()
}
@@ -421,37 +445,95 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
return cc, nil
}
-// ConnectivityState indicates the state of a client connection.
-type ConnectivityState int
+// connectivityStateEvaluator gets updated by addrConns when their
+// states transition, based on which it evaluates the state of
+// ClientConn.
+// Note: This code will eventually sit in the balancer in the new design.
+type connectivityStateEvaluator struct {
+ csMgr *connectivityStateManager
+ mu sync.Mutex
+ numReady uint64 // Number of addrConns in ready state.
+ numConnecting uint64 // Number of addrConns in connecting state.
+ numTransientFailure uint64 // Number of addrConns in transientFailure.
+}
-const (
- // Idle indicates the ClientConn is idle.
- Idle ConnectivityState = iota
- // Connecting indicates the ClienConn is connecting.
- Connecting
- // Ready indicates the ClientConn is ready for work.
- Ready
- // TransientFailure indicates the ClientConn has seen a failure but expects to recover.
- TransientFailure
- // Shutdown indicates the ClientConn has started shutting down.
- Shutdown
-)
+// recordTransition records state change happening in every addrConn and based on
+// that it evaluates what state the ClientConn is in.
+// It can only transition between connectivity.Ready, connectivity.Connecting and connectivity.TransientFailure. Other states,
+// Idle and connectivity.Shutdown are transitioned into by ClientConn; in the begining of the connection
+// before any addrConn is created ClientConn is in idle state. In the end when ClientConn
+// closes it is in connectivity.Shutdown state.
+// TODO Note that in later releases, a ClientConn with no activity will be put into an Idle state.
+func (cse *connectivityStateEvaluator) recordTransition(oldState, newState connectivity.State) {
+ cse.mu.Lock()
+ defer cse.mu.Unlock()
-func (s ConnectivityState) String() string {
- switch s {
- case Idle:
- return "IDLE"
- case Connecting:
- return "CONNECTING"
- case Ready:
- return "READY"
- case TransientFailure:
- return "TRANSIENT_FAILURE"
- case Shutdown:
- return "SHUTDOWN"
- default:
- panic(fmt.Sprintf("unknown connectivity state: %d", s))
+ // Update counters.
+ for idx, state := range []connectivity.State{oldState, newState} {
+ updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
+ switch state {
+ case connectivity.Ready:
+ cse.numReady += updateVal
+ case connectivity.Connecting:
+ cse.numConnecting += updateVal
+ case connectivity.TransientFailure:
+ cse.numTransientFailure += updateVal
+ }
}
+
+ // Evaluate.
+ if cse.numReady > 0 {
+ cse.csMgr.updateState(connectivity.Ready)
+ return
+ }
+ if cse.numConnecting > 0 {
+ cse.csMgr.updateState(connectivity.Connecting)
+ return
+ }
+ cse.csMgr.updateState(connectivity.TransientFailure)
+}
+
+// connectivityStateManager keeps the connectivity.State of ClientConn.
+// This struct will eventually be exported so the balancers can access it.
+type connectivityStateManager struct {
+ mu sync.Mutex
+ state connectivity.State
+ notifyChan chan struct{}
+}
+
+// updateState updates the connectivity.State of ClientConn.
+// If there's a change it notifies goroutines waiting on state change to
+// happen.
+func (csm *connectivityStateManager) updateState(state connectivity.State) {
+ csm.mu.Lock()
+ defer csm.mu.Unlock()
+ if csm.state == connectivity.Shutdown {
+ return
+ }
+ if csm.state == state {
+ return
+ }
+ csm.state = state
+ if csm.notifyChan != nil {
+ // There are other goroutines waiting on this channel.
+ close(csm.notifyChan)
+ csm.notifyChan = nil
+ }
+}
+
+func (csm *connectivityStateManager) getState() connectivity.State {
+ csm.mu.Lock()
+ defer csm.mu.Unlock()
+ return csm.state
+}
+
+func (csm *connectivityStateManager) getNotifyChan() <-chan struct{} {
+ csm.mu.Lock()
+ defer csm.mu.Unlock()
+ if csm.notifyChan == nil {
+ csm.notifyChan = make(chan struct{})
+ }
+ return csm.notifyChan
}
// ClientConn represents a client connection to an RPC server.
@@ -462,14 +544,38 @@ type ClientConn struct {
target string
authority string
dopts dialOptions
+ csMgr *connectivityStateManager
+ csEvltr *connectivityStateEvaluator // This will eventually be part of balancer.
mu sync.RWMutex
sc ServiceConfig
conns map[Address]*addrConn
- // Keepalive parameter can be udated if a GoAway is received.
+ // Keepalive parameter can be updated if a GoAway is received.
mkp keepalive.ClientParameters
}
+// WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or
+// ctx expires. A true value is returned in former case and false in latter.
+// This is an EXPERIMENTAL API.
+func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState connectivity.State) bool {
+ ch := cc.csMgr.getNotifyChan()
+ if cc.csMgr.getState() != sourceState {
+ return true
+ }
+ select {
+ case <-ctx.Done():
+ return false
+ case <-ch:
+ return true
+ }
+}
+
+// GetState returns the connectivity.State of ClientConn.
+// This is an EXPERIMENTAL API.
+func (cc *ClientConn) GetState() connectivity.State {
+ return cc.csMgr.getState()
+}
+
// 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.
@@ -500,14 +606,18 @@ func (cc *ClientConn) lbWatcher(doneChan chan struct{}) {
}
cc.mu.Unlock()
for _, a := range add {
+ var err error
if doneChan != nil {
- err := cc.resetAddrConn(a, true, nil)
+ err = cc.resetAddrConn(a, true, nil)
if err == nil {
close(doneChan)
doneChan = nil
}
} else {
- cc.resetAddrConn(a, false, nil)
+ err = cc.resetAddrConn(a, false, nil)
+ }
+ if err != nil {
+ grpclog.Warningf("Error creating connection to %v. Err: %v", a, err)
}
}
for _, c := range del {
@@ -537,17 +647,18 @@ func (cc *ClientConn) scWatcher() {
// 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.
+//
+// We should never need to replace an addrConn with a new one. This function is only used
+// as newAddrConn to create new addrConn.
+// TODO rename this function and clean up the code.
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)
+ ac.csEvltr = cc.csEvltr
if EnableTracing {
ac.events = trace.NewEventLog("grpc.ClientConn", ac.addr.Addr)
}
@@ -576,10 +687,7 @@ func (cc *ClientConn) resetAddrConn(addr Address, block bool, tearDownErr error)
cc.mu.Unlock()
if stale != nil {
// There is an addrConn alive on ac.addr already. This could be due to
- // 1) a buggy Balancer notifies duplicated Addresses;
- // 2) goaway was received, a new ac will replace the old ac.
- // The old ac should be deleted from cc.conns, but the
- // underlying transport should drain rather than close.
+ // a buggy Balancer that reports duplicated Addresses.
if tearDownErr == nil {
// tearDownErr is nil if resetAddrConn is called by
// 1) Dial
@@ -610,7 +718,7 @@ func (cc *ClientConn) resetAddrConn(addr Address, block bool, tearDownErr error)
// Start a goroutine connecting to the server asynchronously.
go func() {
if err := ac.resetTransport(false); err != nil {
- grpclog.Printf("Failed to dial %s: %v; please retry.", ac.addr.Addr, err)
+ grpclog.Warningf("Failed to dial %s: %v; please retry.", ac.addr.Addr, err)
if err != errConnClosing {
// Keep this ac in cc.conns, to get the reason it's torn down.
ac.tearDown(err)
@@ -623,12 +731,23 @@ func (cc *ClientConn) resetAddrConn(addr Address, block bool, tearDownErr error)
return nil
}
-// TODO: Avoid the locking here.
-func (cc *ClientConn) getMethodConfig(method string) (m MethodConfig, ok bool) {
+// GetMethodConfig gets the method config of the input method.
+// If there's an exact match for input method (i.e. /service/method), we return
+// the corresponding MethodConfig.
+// If there isn't an exact match for the input method, we look for the default config
+// under the service (i.e /service/). If there is a default MethodConfig for
+// the serivce, we return it.
+// Otherwise, we return an empty MethodConfig.
+func (cc *ClientConn) GetMethodConfig(method string) MethodConfig {
+ // TODO: Avoid the locking here.
cc.mu.RLock()
defer cc.mu.RUnlock()
- m, ok = cc.sc.Methods[method]
- return
+ m, ok := cc.sc.Methods[method]
+ if !ok {
+ i := strings.LastIndex(method, "/")
+ m, _ = cc.sc.Methods[method[:i+1]]
+ }
+ return m
}
func (cc *ClientConn) getTransport(ctx context.Context, opts BalancerGetOptions) (transport.ClientTransport, func(), error) {
@@ -696,6 +815,7 @@ func (cc *ClientConn) Close() error {
}
conns := cc.conns
cc.conns = nil
+ cc.csMgr.updateState(connectivity.Shutdown)
cc.mu.Unlock()
if cc.dopts.balancer != nil {
cc.dopts.balancer.Close()
@@ -716,10 +836,11 @@ type addrConn struct {
dopts dialOptions
events trace.EventLog
- mu sync.Mutex
- state ConnectivityState
- stateCV *sync.Cond
- down func(error) // the handler called when a connection is down.
+ csEvltr *connectivityStateEvaluator
+
+ mu sync.Mutex
+ state connectivity.State
+ down func(error) // the handler called when a connection is down.
// ready is closed and becomes nil when a new transport is up or failed
// due to timeout.
ready chan struct{}
@@ -759,62 +880,41 @@ func (ac *addrConn) errorf(format string, a ...interface{}) {
}
}
-// getState returns the connectivity state of the Conn
-func (ac *addrConn) getState() ConnectivityState {
+// resetTransport recreates a transport to the address for ac.
+// For the old transport:
+// - if drain is true, it will be gracefully closed.
+// - otherwise, it will be closed.
+func (ac *addrConn) resetTransport(drain bool) error {
ac.mu.Lock()
- defer ac.mu.Unlock()
- return ac.state
-}
-
-// waitForStateChange blocks until the state changes to something other than the sourceState.
-func (ac *addrConn) waitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) {
- ac.mu.Lock()
- defer ac.mu.Unlock()
- if sourceState != ac.state {
- return ac.state, nil
+ if ac.state == connectivity.Shutdown {
+ ac.mu.Unlock()
+ return errConnClosing
}
- done := make(chan struct{})
- var err error
- go func() {
- select {
- case <-ctx.Done():
- ac.mu.Lock()
- err = ctx.Err()
- ac.stateCV.Broadcast()
- ac.mu.Unlock()
- case <-done:
- }
- }()
- defer close(done)
- for sourceState == ac.state {
- ac.stateCV.Wait()
- if err != nil {
- return ac.state, err
- }
+ ac.printf("connecting")
+ if ac.down != nil {
+ ac.down(downErrorf(false, true, "%v", errNetworkIO))
+ ac.down = nil
}
- return ac.state, nil
-}
-
-func (ac *addrConn) resetTransport(closeTransport bool) error {
+ oldState := ac.state
+ ac.state = connectivity.Connecting
+ ac.csEvltr.recordTransition(oldState, ac.state)
+ t := ac.transport
+ ac.transport = nil
+ ac.mu.Unlock()
+ if t != nil && !drain {
+ t.Close()
+ }
+ ac.cc.mu.RLock()
+ ac.dopts.copts.KeepaliveParams = ac.cc.mkp
+ ac.cc.mu.RUnlock()
for retries := 0; ; retries++ {
ac.mu.Lock()
- ac.printf("connecting")
- if ac.state == Shutdown {
+ if ac.state == connectivity.Shutdown {
// ac.tearDown(...) has been invoked.
ac.mu.Unlock()
return errConnClosing
}
- if ac.down != nil {
- ac.down(downErrorf(false, true, "%v", errNetworkIO))
- ac.down = nil
- }
- ac.state = Connecting
- ac.stateCV.Broadcast()
- t := ac.transport
ac.mu.Unlock()
- if closeTransport && t != nil {
- t.Close()
- }
sleepTime := ac.dopts.bs.backoff(retries)
timeout := minConnectTimeout
if timeout < sleepTime {
@@ -835,39 +935,43 @@ func (ac *addrConn) resetTransport(closeTransport bool) error {
if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() {
return err
}
- grpclog.Printf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %v", err, ac.addr)
+ grpclog.Warningf("grpc: addrConn.resetTransport failed to create client transport: %v; Reconnecting to %v", err, ac.addr)
ac.mu.Lock()
- if ac.state == Shutdown {
+ if ac.state == connectivity.Shutdown {
// ac.tearDown(...) has been invoked.
ac.mu.Unlock()
return errConnClosing
}
ac.errorf("transient failure: %v", err)
- ac.state = TransientFailure
- ac.stateCV.Broadcast()
+ oldState = ac.state
+ ac.state = connectivity.TransientFailure
+ ac.csEvltr.recordTransition(oldState, ac.state)
if ac.ready != nil {
close(ac.ready)
ac.ready = nil
}
ac.mu.Unlock()
- closeTransport = false
+ timer := time.NewTimer(sleepTime - time.Since(connectTime))
select {
- case <-time.After(sleepTime - time.Since(connectTime)):
+ case <-timer.C:
case <-ac.ctx.Done():
+ timer.Stop()
return ac.ctx.Err()
}
+ timer.Stop()
continue
}
ac.mu.Lock()
ac.printf("ready")
- if ac.state == Shutdown {
+ if ac.state == connectivity.Shutdown {
// ac.tearDown(...) has been invoked.
ac.mu.Unlock()
newTransport.Close()
return errConnClosing
}
- ac.state = Ready
- ac.stateCV.Broadcast()
+ oldState = ac.state
+ ac.state = connectivity.Ready
+ ac.csEvltr.recordTransition(oldState, ac.state)
ac.transport = newTransport
if ac.ready != nil {
close(ac.ready)
@@ -900,19 +1004,25 @@ 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.).
- // If GoAway and some network I/O error happen concurrently, ac and its underlying transport
- // are closed.
- // In both cases, a new ac is created.
+ // If GoAway happens without any network I/O error, the underlying transport
+ // will be gracefully closed, and a new transport will be created.
+ // (The transport will be closed when all the pending RPCs finished or failed.)
+ // If GoAway and some network I/O error happen concurrently, the underlying transport
+ // will be closed, and a new transport will be created.
+ var drain bool
select {
case <-t.Error():
- ac.cc.resetAddrConn(ac.addr, false, errNetworkIO)
default:
- ac.cc.resetAddrConn(ac.addr, false, errConnDrain)
+ drain = true
+ }
+ if err := ac.resetTransport(drain); err != nil {
+ grpclog.Infof("get error from resetTransport %v, transportMonitor returning", err)
+ if err != errConnClosing {
+ // Keep this ac in cc.conns, to get the reason it's torn down.
+ ac.tearDown(err)
+ }
+ return
}
- return
case <-t.Error():
select {
case <-ac.ctx.Done():
@@ -920,24 +1030,32 @@ func (ac *addrConn) transportMonitor() {
return
case <-t.GoAway():
ac.adjustParams(t.GetGoAwayReason())
- ac.cc.resetAddrConn(ac.addr, false, errNetworkIO)
- return
+ if err := ac.resetTransport(false); err != nil {
+ grpclog.Infof("get error from resetTransport %v, transportMonitor returning", err)
+ if err != errConnClosing {
+ // Keep this ac in cc.conns, to get the reason it's torn down.
+ ac.tearDown(err)
+ }
+ return
+ }
default:
}
ac.mu.Lock()
- if ac.state == Shutdown {
+ if ac.state == connectivity.Shutdown {
// ac has been shutdown.
ac.mu.Unlock()
return
}
- ac.state = TransientFailure
- ac.stateCV.Broadcast()
+ oldState := ac.state
+ ac.state = connectivity.TransientFailure
+ ac.csEvltr.recordTransition(oldState, ac.state)
ac.mu.Unlock()
- if err := ac.resetTransport(true); err != nil {
+ if err := ac.resetTransport(false); err != nil {
+ grpclog.Infof("get error from resetTransport %v, transportMonitor returning", err)
ac.mu.Lock()
ac.printf("transport exiting: %v", err)
ac.mu.Unlock()
- grpclog.Printf("grpc: addrConn.transportMonitor exits due to: %v", err)
+ grpclog.Warningf("grpc: addrConn.transportMonitor exits due to: %v", err)
if err != errConnClosing {
// Keep this ac in cc.conns, to get the reason it's torn down.
ac.tearDown(err)
@@ -949,12 +1067,12 @@ func (ac *addrConn) transportMonitor() {
}
// wait blocks until i) the new transport is up or ii) ctx is done or iii) ac is closed or
-// iv) transport is in TransientFailure and there is a balancer/failfast is true.
+// iv) transport is in connectivity.TransientFailure and there is a balancer/failfast is true.
func (ac *addrConn) wait(ctx context.Context, hasBalancer, failfast bool) (transport.ClientTransport, error) {
for {
ac.mu.Lock()
switch {
- case ac.state == Shutdown:
+ case ac.state == connectivity.Shutdown:
if failfast || !hasBalancer {
// RPC is failfast or balancer is nil. This RPC should fail with ac.tearDownErr.
err := ac.tearDownErr
@@ -963,11 +1081,11 @@ func (ac *addrConn) wait(ctx context.Context, hasBalancer, failfast bool) (trans
}
ac.mu.Unlock()
return nil, errConnClosing
- case ac.state == Ready:
+ case ac.state == connectivity.Ready:
ct := ac.transport
ac.mu.Unlock()
return ct, nil
- case ac.state == TransientFailure:
+ case ac.state == connectivity.TransientFailure:
if failfast || hasBalancer {
ac.mu.Unlock()
return nil, errConnUnavailable
@@ -1009,12 +1127,13 @@ func (ac *addrConn) tearDown(err error) {
// address removal and GoAway.
ac.transport.GracefulClose()
}
- if ac.state == Shutdown {
+ if ac.state == connectivity.Shutdown {
return
}
- ac.state = Shutdown
+ oldState := ac.state
+ ac.state = connectivity.Shutdown
ac.tearDownErr = err
- ac.stateCV.Broadcast()
+ ac.csEvltr.recordTransition(oldState, ac.state)
if ac.events != nil {
ac.events.Finish()
ac.events = nil
diff --git a/vendor/google.golang.org/grpc/codec.go b/vendor/google.golang.org/grpc/codec.go
index bd76ebb7f17..905b048e2ac 100644
--- a/vendor/google.golang.org/grpc/codec.go
+++ b/vendor/google.golang.org/grpc/codec.go
@@ -1,35 +1,20 @@
/*
-*
- * 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:
+ * Copyright 2014 gRPC authors.
*
- * * 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.
+ * 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
*
- * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
-*/
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
package grpc
@@ -96,6 +81,7 @@ func (p protoCodec) Marshal(v interface{}) ([]byte, error) {
func (p protoCodec) Unmarshal(data []byte, v interface{}) error {
cb := protoBufferPool.Get().(*cachedProtoBuffer)
cb.SetBuf(data)
+ v.(proto.Message).Reset()
err := cb.Unmarshal(v.(proto.Message))
cb.SetBuf(nil)
protoBufferPool.Put(cb)
diff --git a/vendor/google.golang.org/grpc/codes/codes.go b/vendor/google.golang.org/grpc/codes/codes.go
index 37c5b860bd6..81fe7bf85b3 100644
--- a/vendor/google.golang.org/grpc/codes/codes.go
+++ b/vendor/google.golang.org/grpc/codes/codes.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -44,7 +29,7 @@ const (
// OK is returned on success.
OK Code = 0
- // Canceled indicates the operation was cancelled (typically by the caller).
+ // Canceled indicates the operation was canceled (typically by the caller).
Canceled Code = 1
// Unknown error. An example of where this error may be returned is
diff --git a/vendor/google.golang.org/grpc/connectivity/BUILD b/vendor/google.golang.org/grpc/connectivity/BUILD
new file mode 100644
index 00000000000..d5555d4a28f
--- /dev/null
+++ b/vendor/google.golang.org/grpc/connectivity/BUILD
@@ -0,0 +1,26 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = ["connectivity.go"],
+ importpath = "google.golang.org/grpc/connectivity",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/golang.org/x/net/context:go_default_library",
+ "//vendor/google.golang.org/grpc/grpclog:go_default_library",
+ ],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/vendor/google.golang.org/grpc/connectivity/connectivity.go b/vendor/google.golang.org/grpc/connectivity/connectivity.go
new file mode 100644
index 00000000000..568ef5dc68b
--- /dev/null
+++ b/vendor/google.golang.org/grpc/connectivity/connectivity.go
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Package connectivity defines connectivity semantics.
+// For details, see https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md.
+// All APIs in this package are experimental.
+package connectivity
+
+import (
+ "golang.org/x/net/context"
+ "google.golang.org/grpc/grpclog"
+)
+
+// State indicates the state of connectivity.
+// It can be the state of a ClientConn or SubConn.
+type State int
+
+func (s State) String() string {
+ switch s {
+ case Idle:
+ return "IDLE"
+ case Connecting:
+ return "CONNECTING"
+ case Ready:
+ return "READY"
+ case TransientFailure:
+ return "TRANSIENT_FAILURE"
+ case Shutdown:
+ return "SHUTDOWN"
+ default:
+ grpclog.Errorf("unknown connectivity state: %d", s)
+ return "Invalid-State"
+ }
+}
+
+const (
+ // Idle indicates the ClientConn is idle.
+ Idle State = iota
+ // Connecting indicates the ClienConn is connecting.
+ Connecting
+ // Ready indicates the ClientConn is ready for work.
+ Ready
+ // TransientFailure indicates the ClientConn has seen a failure but expects to recover.
+ TransientFailure
+ // Shutdown indicates the ClientConn has started shutting down.
+ Shutdown
+)
+
+// Reporter reports the connectivity states.
+type Reporter interface {
+ // CurrentState returns the current state of the reporter.
+ CurrentState() State
+ // WaitForStateChange blocks until the reporter's state is different from the given state,
+ // and returns true.
+ // It returns false if <-ctx.Done() can proceed (ctx got timeout or got canceled).
+ WaitForStateChange(context.Context, State) bool
+}
diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go
index d1217344b67..1ccbaff77a6 100644
--- a/vendor/google.golang.org/grpc/credentials/credentials.go
+++ b/vendor/google.golang.org/grpc/credentials/credentials.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -196,14 +181,14 @@ func NewTLS(c *tls.Config) TransportCredentials {
return tc
}
-// NewClientTLSFromCert constructs a TLS from the input certificate for client.
+// NewClientTLSFromCert constructs TLS credentials from the input certificate for client.
// serverNameOverride is for testing only. If set to a non empty string,
// it will override the virtual host name of authority (e.g. :authority header field) in requests.
func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) TransportCredentials {
return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp})
}
-// NewClientTLSFromFile constructs a TLS from the input certificate file for client.
+// NewClientTLSFromFile constructs TLS credentials from the input certificate file for client.
// serverNameOverride is for testing only. If set to a non empty string,
// it will override the virtual host name of authority (e.g. :authority header field) in requests.
func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) {
@@ -218,12 +203,12 @@ func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredent
return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil
}
-// NewServerTLSFromCert constructs a TLS from the input certificate for server.
+// NewServerTLSFromCert constructs TLS credentials from the input certificate for server.
func NewServerTLSFromCert(cert *tls.Certificate) TransportCredentials {
return NewTLS(&tls.Config{Certificates: []tls.Certificate{*cert}})
}
-// NewServerTLSFromFile constructs a TLS from the input certificate file and key
+// NewServerTLSFromFile constructs TLS credentials from the input certificate file and key
// file for server.
func NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error) {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
diff --git a/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go b/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go
index 7597b09e358..60409aac0fb 100644
--- a/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go
+++ b/vendor/google.golang.org/grpc/credentials/credentials_util_go17.go
@@ -3,34 +3,19 @@
/*
*
- * Copyright 2016, Google Inc.
- * All rights reserved.
+ * Copyright 2016 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go b/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go
index 0ecf342da84..93f0e1d8de2 100644
--- a/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go
+++ b/vendor/google.golang.org/grpc/credentials/credentials_util_go18.go
@@ -2,34 +2,19 @@
/*
*
- * Copyright 2017, Google Inc.
- * All rights reserved.
+ * Copyright 2017 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go b/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go
index cfd40dfa34a..d6bbcc9fdd9 100644
--- a/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go
+++ b/vendor/google.golang.org/grpc/credentials/credentials_util_pre_go17.go
@@ -2,34 +2,19 @@
/*
*
- * Copyright 2016, Google Inc.
- * All rights reserved.
+ * Copyright 2016 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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/vendor/google.golang.org/grpc/doc.go b/vendor/google.golang.org/grpc/doc.go
index b4c0e740e9c..9221fd2188a 100644
--- a/vendor/google.golang.org/grpc/doc.go
+++ b/vendor/google.golang.org/grpc/doc.go
@@ -1,6 +1,6 @@
/*
Package grpc implements an RPC system called gRPC.
-See www.grpc.io for more information about gRPC.
+See grpc.io for more information about gRPC.
*/
package grpc
diff --git a/vendor/google.golang.org/grpc/go16.go b/vendor/google.golang.org/grpc/go16.go
index b61c57e88de..f3dbf21700f 100644
--- a/vendor/google.golang.org/grpc/go16.go
+++ b/vendor/google.golang.org/grpc/go16.go
@@ -1,34 +1,20 @@
// +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:
+ * Copyright 2016 gRPC authors.
*
- * * 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.
+ * 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
*
- * 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.
+ * 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.
*
*/
@@ -36,10 +22,15 @@ package grpc
import (
"fmt"
+ "io"
"net"
"net/http"
+ "os"
"golang.org/x/net/context"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+ "google.golang.org/grpc/transport"
)
// dialContext connects to the address on the named network.
@@ -54,3 +45,54 @@ func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) erro
}
return nil
}
+
+// toRPCErr converts an error into an error from the status package.
+func toRPCErr(err error) error {
+ if _, ok := status.FromError(err); ok {
+ return err
+ }
+ switch e := err.(type) {
+ case transport.StreamError:
+ return status.Error(e.Code, e.Desc)
+ case transport.ConnectionError:
+ return status.Error(codes.Unavailable, e.Desc)
+ default:
+ switch err {
+ case context.DeadlineExceeded:
+ return status.Error(codes.DeadlineExceeded, err.Error())
+ case context.Canceled:
+ return status.Error(codes.Canceled, err.Error())
+ case ErrClientConnClosing:
+ return status.Error(codes.FailedPrecondition, err.Error())
+ }
+ }
+ return status.Error(codes.Unknown, err.Error())
+}
+
+// convertCode converts a standard Go error into its canonical code. Note that
+// this is only used to translate the error returned by the server applications.
+func convertCode(err error) codes.Code {
+ switch err {
+ case nil:
+ return codes.OK
+ case io.EOF:
+ return codes.OutOfRange
+ case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF:
+ return codes.FailedPrecondition
+ case os.ErrInvalid:
+ return codes.InvalidArgument
+ case context.Canceled:
+ return codes.Canceled
+ case context.DeadlineExceeded:
+ return codes.DeadlineExceeded
+ }
+ switch {
+ case os.IsExist(err):
+ return codes.AlreadyExists
+ case os.IsNotExist(err):
+ return codes.NotFound
+ case os.IsPermission(err):
+ return codes.PermissionDenied
+ }
+ return codes.Unknown
+}
diff --git a/vendor/google.golang.org/grpc/go17.go b/vendor/google.golang.org/grpc/go17.go
index 844f0e1899b..a3421d99eb4 100644
--- a/vendor/google.golang.org/grpc/go17.go
+++ b/vendor/google.golang.org/grpc/go17.go
@@ -1,44 +1,36 @@
// +build 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:
+ * Copyright 2016 gRPC authors.
*
- * * 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.
+ * 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
*
- * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
*/
package grpc
import (
+ "context"
+ "io"
"net"
"net/http"
+ "os"
- "golang.org/x/net/context"
+ netctx "golang.org/x/net/context"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+ "google.golang.org/grpc/transport"
)
// dialContext connects to the address on the named network.
@@ -53,3 +45,54 @@ func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) erro
}
return nil
}
+
+// toRPCErr converts an error into an error from the status package.
+func toRPCErr(err error) error {
+ if _, ok := status.FromError(err); ok {
+ return err
+ }
+ switch e := err.(type) {
+ case transport.StreamError:
+ return status.Error(e.Code, e.Desc)
+ case transport.ConnectionError:
+ return status.Error(codes.Unavailable, e.Desc)
+ default:
+ switch err {
+ case context.DeadlineExceeded, netctx.DeadlineExceeded:
+ return status.Error(codes.DeadlineExceeded, err.Error())
+ case context.Canceled, netctx.Canceled:
+ return status.Error(codes.Canceled, err.Error())
+ case ErrClientConnClosing:
+ return status.Error(codes.FailedPrecondition, err.Error())
+ }
+ }
+ return status.Error(codes.Unknown, err.Error())
+}
+
+// convertCode converts a standard Go error into its canonical code. Note that
+// this is only used to translate the error returned by the server applications.
+func convertCode(err error) codes.Code {
+ switch err {
+ case nil:
+ return codes.OK
+ case io.EOF:
+ return codes.OutOfRange
+ case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF:
+ return codes.FailedPrecondition
+ case os.ErrInvalid:
+ return codes.InvalidArgument
+ case context.Canceled, netctx.Canceled:
+ return codes.Canceled
+ case context.DeadlineExceeded, netctx.DeadlineExceeded:
+ return codes.DeadlineExceeded
+ }
+ switch {
+ case os.IsExist(err):
+ return codes.AlreadyExists
+ case os.IsNotExist(err):
+ return codes.NotFound
+ case os.IsPermission(err):
+ return codes.PermissionDenied
+ }
+ return codes.Unknown
+}
diff --git a/vendor/google.golang.org/grpc/grpclb.go b/vendor/google.golang.org/grpc/grpclb.go
index 524e429df3e..619985e6082 100644
--- a/vendor/google.golang.org/grpc/grpclb.go
+++ b/vendor/google.golang.org/grpc/grpclb.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2016, Google Inc.
- * All rights reserved.
+ * Copyright 2016 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -96,8 +81,8 @@ const (
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
+// AddrMetadataGRPCLB contains the information the name resolver for grpclb should provide. The
+// name resolver used by the 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).
@@ -152,6 +137,7 @@ type balancer struct {
func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan []remoteBalancerInfo) error {
updates, err := w.Next()
if err != nil {
+ grpclog.Warningf("grpclb: failed to get next addr update from watcher: %v", err)
return err
}
b.mu.Lock()
@@ -176,13 +162,13 @@ func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan []remoteBalancerIn
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)
+ grpclog.Errorf("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")
+ grpclog.Errorf("The name resolution does not give grpclb addresses")
continue
case GRPCLB:
b.rbs = append(b.rbs, remoteBalancerInfo{
@@ -190,7 +176,7 @@ func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan []remoteBalancerIn
name: md.ServerName,
})
default:
- grpclog.Printf("Received unknow address type %d", md.AddrType)
+ grpclog.Errorf("Received unknow address type %d", md.AddrType)
continue
}
case naming.Delete:
@@ -202,7 +188,7 @@ func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan []remoteBalancerIn
}
}
default:
- grpclog.Println("Unknown update.Op ", update.Op)
+ grpclog.Errorf("Unknown update.Op %v", update.Op)
}
}
// TODO: Fall back to the basic round-robin load balancing if the resulting address is
@@ -249,8 +235,15 @@ func (b *balancer) processServerList(l *lbpb.ServerList, seq int) {
)
for _, s := range servers {
md := metadata.Pairs("lb-token", s.LoadBalanceToken)
+ ip := net.IP(s.IpAddress)
+ ipStr := ip.String()
+ if ip.To4() == nil {
+ // Add square brackets to ipv6 addresses, otherwise net.Dial() and
+ // net.SplitHostPort() will return too many colons error.
+ ipStr = fmt.Sprintf("[%s]", ipStr)
+ }
addr := Address{
- Addr: fmt.Sprintf("%s:%d", net.IP(s.IpAddress), s.Port),
+ Addr: fmt.Sprintf("%s:%d", ipStr, s.Port),
Metadata: &md,
}
sl = append(sl, &grpclbAddrInfo{
@@ -306,6 +299,7 @@ func (b *balancer) sendLoadReport(s *balanceLoadClientStream, interval time.Dura
ClientStats: &stats,
},
}); err != nil {
+ grpclog.Errorf("grpclb: failed to send load report: %v", err)
return
}
}
@@ -316,7 +310,7 @@ func (b *balancer) callRemoteBalancer(lbc *loadBalancerClient, seq int) (retry b
defer cancel()
stream, err := lbc.BalanceLoad(ctx)
if err != nil {
- grpclog.Printf("Failed to perform RPC to the remote balancer %v", err)
+ grpclog.Errorf("grpclb: failed to perform RPC to the remote balancer %v", err)
return
}
b.mu.Lock()
@@ -333,23 +327,25 @@ func (b *balancer) callRemoteBalancer(lbc *loadBalancerClient, seq int) (retry b
},
}
if err := stream.Send(initReq); err != nil {
+ grpclog.Errorf("grpclb: failed to send init request: %v", err)
// TODO: backoff on retry?
return true
}
reply, err := stream.Recv()
if err != nil {
+ grpclog.Errorf("grpclb: failed to recv init response: %v", err)
// TODO: backoff on retry?
return true
}
initResp := reply.GetInitialResponse()
if initResp == nil {
- grpclog.Println("Failed to receive the initial response from the remote balancer.")
+ grpclog.Errorf("grpclb: reply from remote balancer did not include initial response.")
return
}
// TODO: Support delegation.
if initResp.LoadBalancerDelegate != "" {
// delegation
- grpclog.Println("TODO: Delegation is not supported yet.")
+ grpclog.Errorf("TODO: Delegation is not supported yet.")
return
}
streamDone := make(chan struct{})
@@ -364,6 +360,7 @@ func (b *balancer) callRemoteBalancer(lbc *loadBalancerClient, seq int) (retry b
for {
reply, err := stream.Recv()
if err != nil {
+ grpclog.Errorf("grpclb: failed to recv server list: %v", err)
break
}
b.mu.Lock()
@@ -397,6 +394,7 @@ func (b *balancer) Start(target string, config BalancerConfig) error {
w, err := b.r.Resolve(target)
if err != nil {
b.mu.Unlock()
+ grpclog.Errorf("grpclb: failed to resolve address: %v, err: %v", target, err)
return err
}
b.w = w
@@ -406,7 +404,7 @@ func (b *balancer) Start(target string, config BalancerConfig) error {
go func() {
for {
if err := b.watchAddrUpdates(w, balancerAddrsCh); err != nil {
- grpclog.Printf("grpc: the naming watcher stops working due to %v.\n", err)
+ grpclog.Warningf("grpclb: the naming watcher stops working due to %v.\n", err)
close(balancerAddrsCh)
return
}
@@ -490,22 +488,29 @@ func (b *balancer) Start(target string, config BalancerConfig) error {
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 {
+ var (
+ err error
+ dopts []DialOption
+ )
+ if creds := config.DialCreds; creds != nil {
if rb.name != "" {
if err := creds.OverrideServerName(rb.name); err != nil {
- grpclog.Printf("Failed to override the server name in the credentials: %v", err)
+ grpclog.Warningf("grpclb: failed to override the server name in the credentials: %v", err)
continue
}
}
- cc, err = Dial(rb.addr, WithTransportCredentials(creds))
+ dopts = append(dopts, WithTransportCredentials(creds))
+ } else {
+ dopts = append(dopts, WithInsecure())
}
+ if dialer := config.Dialer; dialer != nil {
+ // WithDialer takes a different type of function, so we instead use a special DialOption here.
+ dopts = append(dopts, func(o *dialOptions) { o.copts.Dialer = dialer })
+ }
+ ccError = make(chan struct{})
+ cc, err = Dial(rb.addr, dopts...)
if err != nil {
- grpclog.Printf("Failed to setup a connection to the remote balancer %v: %v", rb.addr, err)
+ grpclog.Warningf("grpclb: failed to setup a connection to the remote balancer %v: %v", rb.addr, err)
close(ccError)
continue
}
@@ -732,6 +737,9 @@ func (b *balancer) Notify() <-chan []Address {
func (b *balancer) Close() error {
b.mu.Lock()
defer b.mu.Unlock()
+ if b.done {
+ return errBalancerClosed
+ }
b.done = true
if b.expTimer != nil {
b.expTimer.Stop()
diff --git a/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto b/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto
index a2502fb284a..b13b3438cf2 100644
--- a/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto
+++ b/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/grpclb.proto
@@ -1,31 +1,16 @@
-// Copyright 2016, Google Inc.
-// All rights reserved.
+// Copyright 2016 gRPC authors.
//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
+// 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
//
-// * 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.
+// http://www.apache.org/licenses/LICENSE-2.0
//
-// 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.
+// 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.
syntax = "proto3";
diff --git a/vendor/google.golang.org/grpc/grpclog/BUILD b/vendor/google.golang.org/grpc/grpclog/BUILD
index 4595e517367..4b225761989 100644
--- a/vendor/google.golang.org/grpc/grpclog/BUILD
+++ b/vendor/google.golang.org/grpc/grpclog/BUILD
@@ -2,7 +2,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
- srcs = ["logger.go"],
+ srcs = [
+ "grpclog.go",
+ "logger.go",
+ "loggerv2.go",
+ ],
importpath = "google.golang.org/grpc/grpclog",
visibility = ["//visibility:public"],
)
diff --git a/vendor/google.golang.org/grpc/grpclog/grpclog.go b/vendor/google.golang.org/grpc/grpclog/grpclog.go
new file mode 100644
index 00000000000..0a6758a2700
--- /dev/null
+++ b/vendor/google.golang.org/grpc/grpclog/grpclog.go
@@ -0,0 +1,135 @@
+/*
+ *
+ * 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 grpclog defines logging for grpc.
+//
+// All logs in transport package only go to verbose level 2.
+// All logs in other packages in grpc are logged in spite of the verbosity level.
+//
+// In the default logger,
+// severity level can be set by environment variable GRPC_GO_LOG_SEVERITY_LEVEL,
+// verbosity level can be set by GRPC_GO_LOG_VERBOSITY_LEVEL.
+package grpclog
+
+import "os"
+
+var logger = newLoggerV2()
+
+// V reports whether verbosity level l is at least the requested verbose level.
+func V(l int) bool {
+ return logger.V(l)
+}
+
+// Info logs to the INFO log.
+func Info(args ...interface{}) {
+ logger.Info(args...)
+}
+
+// Infof logs to the INFO log. Arguments are handled in the manner of fmt.Printf.
+func Infof(format string, args ...interface{}) {
+ logger.Infof(format, args...)
+}
+
+// Infoln logs to the INFO log. Arguments are handled in the manner of fmt.Println.
+func Infoln(args ...interface{}) {
+ logger.Infoln(args...)
+}
+
+// Warning logs to the WARNING log.
+func Warning(args ...interface{}) {
+ logger.Warning(args...)
+}
+
+// Warningf logs to the WARNING log. Arguments are handled in the manner of fmt.Printf.
+func Warningf(format string, args ...interface{}) {
+ logger.Warningf(format, args...)
+}
+
+// Warningln logs to the WARNING log. Arguments are handled in the manner of fmt.Println.
+func Warningln(args ...interface{}) {
+ logger.Warningln(args...)
+}
+
+// Error logs to the ERROR log.
+func Error(args ...interface{}) {
+ logger.Error(args...)
+}
+
+// Errorf logs to the ERROR log. Arguments are handled in the manner of fmt.Printf.
+func Errorf(format string, args ...interface{}) {
+ logger.Errorf(format, args...)
+}
+
+// Errorln logs to the ERROR log. Arguments are handled in the manner of fmt.Println.
+func Errorln(args ...interface{}) {
+ logger.Errorln(args...)
+}
+
+// Fatal logs to the FATAL log. Arguments are handled in the manner of fmt.Print.
+// It calls os.Exit() with exit code 1.
+func Fatal(args ...interface{}) {
+ logger.Fatal(args...)
+ os.Exit(1)
+}
+
+// Fatalf logs to the FATAL log. Arguments are handled in the manner of fmt.Printf.
+// It calles os.Exit() with exit code 1.
+func Fatalf(format string, args ...interface{}) {
+ logger.Fatalf(format, args...)
+ os.Exit(1)
+}
+
+// Fatalln logs to the FATAL log. Arguments are handled in the manner of fmt.Println.
+// It calle os.Exit()) with exit code 1.
+func Fatalln(args ...interface{}) {
+ logger.Fatalln(args...)
+ os.Exit(1)
+}
+
+// Print prints to the logger. Arguments are handled in the manner of fmt.Print.
+// Deprecated: use Info.
+func Print(args ...interface{}) {
+ logger.Info(args...)
+}
+
+// Printf prints to the logger. Arguments are handled in the manner of fmt.Printf.
+// Deprecated: use Infof.
+func Printf(format string, args ...interface{}) {
+ logger.Infof(format, args...)
+}
+
+// Println prints to the logger. Arguments are handled in the manner of fmt.Println.
+// Deprecated: use Infoln.
+func Println(args ...interface{}) {
+ logger.Infoln(args...)
+}
diff --git a/vendor/google.golang.org/grpc/grpclog/logger.go b/vendor/google.golang.org/grpc/grpclog/logger.go
index 2cc09be4894..d03b2397bfa 100644
--- a/vendor/google.golang.org/grpc/grpclog/logger.go
+++ b/vendor/google.golang.org/grpc/grpclog/logger.go
@@ -1,52 +1,25 @@
/*
*
- * Copyright 2015, Google Inc.
- * All rights reserved.
+ * Copyright 2015 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
*/
-/*
-Package grpclog defines logging for grpc.
-*/
package grpclog
-import (
- "log"
- "os"
-)
-
-// Use golang's standard logger by default.
-// Access is not mutex-protected: do not modify except in init()
-// functions.
-var logger Logger = log.New(os.Stderr, "", log.LstdFlags)
-
// Logger mimics golang's standard Logger as an interface.
+// Deprecated: use LoggerV2.
type Logger interface {
Fatal(args ...interface{})
Fatalf(format string, args ...interface{})
@@ -58,36 +31,53 @@ type Logger interface {
// SetLogger sets the logger that is used in grpc. Call only from
// init() functions.
+// Deprecated: use SetLoggerV2.
func SetLogger(l Logger) {
- logger = l
+ logger = &loggerWrapper{Logger: l}
}
-// Fatal is equivalent to Print() followed by a call to os.Exit() with a non-zero exit code.
-func Fatal(args ...interface{}) {
- logger.Fatal(args...)
+// loggerWrapper wraps Logger into a LoggerV2.
+type loggerWrapper struct {
+ Logger
}
-// Fatalf is equivalent to Printf() followed by a call to os.Exit() with a non-zero exit code.
-func Fatalf(format string, args ...interface{}) {
- logger.Fatalf(format, args...)
+func (g *loggerWrapper) Info(args ...interface{}) {
+ g.Logger.Print(args...)
}
-// Fatalln is equivalent to Println() followed by a call to os.Exit()) with a non-zero exit code.
-func Fatalln(args ...interface{}) {
- logger.Fatalln(args...)
+func (g *loggerWrapper) Infoln(args ...interface{}) {
+ g.Logger.Println(args...)
}
-// Print prints to the logger. Arguments are handled in the manner of fmt.Print.
-func Print(args ...interface{}) {
- logger.Print(args...)
+func (g *loggerWrapper) Infof(format string, args ...interface{}) {
+ g.Logger.Printf(format, args...)
}
-// Printf prints to the logger. Arguments are handled in the manner of fmt.Printf.
-func Printf(format string, args ...interface{}) {
- logger.Printf(format, args...)
+func (g *loggerWrapper) Warning(args ...interface{}) {
+ g.Logger.Print(args...)
}
-// Println prints to the logger. Arguments are handled in the manner of fmt.Println.
-func Println(args ...interface{}) {
- logger.Println(args...)
+func (g *loggerWrapper) Warningln(args ...interface{}) {
+ g.Logger.Println(args...)
+}
+
+func (g *loggerWrapper) Warningf(format string, args ...interface{}) {
+ g.Logger.Printf(format, args...)
+}
+
+func (g *loggerWrapper) Error(args ...interface{}) {
+ g.Logger.Print(args...)
+}
+
+func (g *loggerWrapper) Errorln(args ...interface{}) {
+ g.Logger.Println(args...)
+}
+
+func (g *loggerWrapper) Errorf(format string, args ...interface{}) {
+ g.Logger.Printf(format, args...)
+}
+
+func (g *loggerWrapper) V(l int) bool {
+ // Returns true for all verbose level.
+ return true
}
diff --git a/vendor/google.golang.org/grpc/grpclog/loggerv2.go b/vendor/google.golang.org/grpc/grpclog/loggerv2.go
new file mode 100644
index 00000000000..f5193be922f
--- /dev/null
+++ b/vendor/google.golang.org/grpc/grpclog/loggerv2.go
@@ -0,0 +1,204 @@
+/*
+ *
+ * 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 grpclog
+
+import (
+ "io"
+ "io/ioutil"
+ "log"
+ "os"
+ "strconv"
+)
+
+// LoggerV2 does underlying logging work for grpclog.
+type LoggerV2 interface {
+ // Info logs to INFO log. Arguments are handled in the manner of fmt.Print.
+ Info(args ...interface{})
+ // Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println.
+ Infoln(args ...interface{})
+ // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf.
+ Infof(format string, args ...interface{})
+ // Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print.
+ Warning(args ...interface{})
+ // Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println.
+ Warningln(args ...interface{})
+ // Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.
+ Warningf(format string, args ...interface{})
+ // Error logs to ERROR log. Arguments are handled in the manner of fmt.Print.
+ Error(args ...interface{})
+ // Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
+ Errorln(args ...interface{})
+ // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
+ Errorf(format string, args ...interface{})
+ // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print.
+ // This function should call os.Exit() with a non-zero exit code.
+ Fatal(args ...interface{})
+ // Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
+ // This function should call os.Exit() with a non-zero exit code.
+ Fatalln(args ...interface{})
+ // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
+ // This function should call os.Exit() with a non-zero exit code.
+ Fatalf(format string, args ...interface{})
+ // V reports whether verbosity level l is at least the requested verbose level.
+ V(l int) bool
+}
+
+// SetLoggerV2 sets logger that is used in grpc to a V2 logger.
+// Not mutex-protected, should be called before any gRPC functions.
+func SetLoggerV2(l LoggerV2) {
+ logger = l
+}
+
+const (
+ // infoLog indicates Info severity.
+ infoLog int = iota
+ // warningLog indicates Warning severity.
+ warningLog
+ // errorLog indicates Error severity.
+ errorLog
+ // fatalLog indicates Fatal severity.
+ fatalLog
+)
+
+// severityName contains the string representation of each severity.
+var severityName = []string{
+ infoLog: "INFO",
+ warningLog: "WARNING",
+ errorLog: "ERROR",
+ fatalLog: "FATAL",
+}
+
+// loggerT is the default logger used by grpclog.
+type loggerT struct {
+ m []*log.Logger
+ v int
+}
+
+// NewLoggerV2 creates a loggerV2 with the provided writers.
+// Fatal logs will be written to errorW, warningW, infoW, followed by exit(1).
+// Error logs will be written to errorW, warningW and infoW.
+// Warning logs will be written to warningW and infoW.
+// Info logs will be written to infoW.
+func NewLoggerV2(infoW, warningW, errorW io.Writer) LoggerV2 {
+ return NewLoggerV2WithVerbosity(infoW, warningW, errorW, 0)
+}
+
+// NewLoggerV2WithVerbosity creates a loggerV2 with the provided writers and
+// verbosity level.
+func NewLoggerV2WithVerbosity(infoW, warningW, errorW io.Writer, v int) LoggerV2 {
+ var m []*log.Logger
+ m = append(m, log.New(infoW, severityName[infoLog]+": ", log.LstdFlags))
+ m = append(m, log.New(io.MultiWriter(infoW, warningW), severityName[warningLog]+": ", log.LstdFlags))
+ ew := io.MultiWriter(infoW, warningW, errorW) // ew will be used for error and fatal.
+ m = append(m, log.New(ew, severityName[errorLog]+": ", log.LstdFlags))
+ m = append(m, log.New(ew, severityName[fatalLog]+": ", log.LstdFlags))
+ return &loggerT{m: m, v: v}
+}
+
+// newLoggerV2 creates a loggerV2 to be used as default logger.
+// All logs are written to stderr.
+func newLoggerV2() LoggerV2 {
+ errorW := ioutil.Discard
+ warningW := ioutil.Discard
+ infoW := ioutil.Discard
+
+ logLevel := os.Getenv("GRPC_GO_LOG_SEVERITY_LEVEL")
+ switch logLevel {
+ case "", "ERROR", "error": // If env is unset, set level to ERROR.
+ errorW = os.Stderr
+ case "WARNING", "warning":
+ warningW = os.Stderr
+ case "INFO", "info":
+ infoW = os.Stderr
+ }
+
+ var v int
+ vLevel := os.Getenv("GRPC_GO_LOG_VERBOSITY_LEVEL")
+ if vl, err := strconv.Atoi(vLevel); err == nil {
+ v = vl
+ }
+ return NewLoggerV2WithVerbosity(infoW, warningW, errorW, v)
+}
+
+func (g *loggerT) Info(args ...interface{}) {
+ g.m[infoLog].Print(args...)
+}
+
+func (g *loggerT) Infoln(args ...interface{}) {
+ g.m[infoLog].Println(args...)
+}
+
+func (g *loggerT) Infof(format string, args ...interface{}) {
+ g.m[infoLog].Printf(format, args...)
+}
+
+func (g *loggerT) Warning(args ...interface{}) {
+ g.m[warningLog].Print(args...)
+}
+
+func (g *loggerT) Warningln(args ...interface{}) {
+ g.m[warningLog].Println(args...)
+}
+
+func (g *loggerT) Warningf(format string, args ...interface{}) {
+ g.m[warningLog].Printf(format, args...)
+}
+
+func (g *loggerT) Error(args ...interface{}) {
+ g.m[errorLog].Print(args...)
+}
+
+func (g *loggerT) Errorln(args ...interface{}) {
+ g.m[errorLog].Println(args...)
+}
+
+func (g *loggerT) Errorf(format string, args ...interface{}) {
+ g.m[errorLog].Printf(format, args...)
+}
+
+func (g *loggerT) Fatal(args ...interface{}) {
+ g.m[fatalLog].Fatal(args...)
+}
+
+func (g *loggerT) Fatalln(args ...interface{}) {
+ g.m[fatalLog].Fatalln(args...)
+}
+
+func (g *loggerT) Fatalf(format string, args ...interface{}) {
+ g.m[fatalLog].Fatalf(format, args...)
+}
+
+func (g *loggerT) V(l int) bool {
+ return l <= g.v
+}
diff --git a/vendor/google.golang.org/grpc/interceptor.go b/vendor/google.golang.org/grpc/interceptor.go
index a6921614572..06dc825b9fb 100644
--- a/vendor/google.golang.org/grpc/interceptor.go
+++ b/vendor/google.golang.org/grpc/interceptor.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2016, Google Inc.
- * All rights reserved.
+ * Copyright 2016 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -42,15 +27,15 @@ type UnaryInvoker func(ctx context.Context, method string, req, reply interface{
// 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.
+// This is an EXPERIMENTAL API.
type UnaryClientInterceptor func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error
// Streamer is called by StreamClientInterceptor to create a ClientStream.
type Streamer func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error)
// StreamClientInterceptor intercepts the creation of ClientStream. It may return a custom ClientStream to intercept all I/O
-// operations. streamer is the handlder to create a ClientStream and it is the responsibility of the interceptor to call it.
-// This is the EXPERIMENTAL API.
+// operations. streamer is the handler to create a ClientStream and it is the responsibility of the interceptor to call it.
+// This is an EXPERIMENTAL API.
type StreamClientInterceptor func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, streamer Streamer, opts ...CallOption) (ClientStream, error)
// UnaryServerInfo consists of various information about a unary RPC on
diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go
index 5489143a85c..07083832c3c 100644
--- a/vendor/google.golang.org/grpc/internal/internal.go
+++ b/vendor/google.golang.org/grpc/internal/internal.go
@@ -1,32 +1,17 @@
/*
- * Copyright 2016, Google Inc.
- * All rights reserved.
+ * Copyright 2016 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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/vendor/google.golang.org/grpc/keepalive/keepalive.go b/vendor/google.golang.org/grpc/keepalive/keepalive.go
index d492589c96b..f8adc7e6d4f 100644
--- a/vendor/google.golang.org/grpc/keepalive/keepalive.go
+++ b/vendor/google.golang.org/grpc/keepalive/keepalive.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2017, Google Inc.
- * All rights reserved.
+ * Copyright 2017 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -39,8 +24,8 @@ import (
)
// 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.
+// These configure how the client will actively probe to notice when a connection is broken
+// and send pings so intermediaries will be aware of the liveness of the connection.
// 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 {
diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go
index a4f2de026db..9ac47504766 100644
--- a/vendor/google.golang.org/grpc/metadata/metadata.go
+++ b/vendor/google.golang.org/grpc/metadata/metadata.go
@@ -1,38 +1,23 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
*/
// Package 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.
+// Please refer to https://grpc.io/docs/guides/wire.html for more information about custom-metadata.
package metadata
import (
@@ -51,8 +36,14 @@ func DecodeKeyValue(k, v string) (string, string, error) {
// two convenience functions New and Pairs to generate MD.
type MD map[string][]string
-// New creates a MD from given key-value map.
-// Keys are automatically converted to lowercase.
+// New creates an MD from a given key-value map.
+//
+// Only the following ASCII characters are allowed in keys:
+// - digits: 0-9
+// - uppercase letters: A-Z (normalized to lower)
+// - lowercase letters: a-z
+// - special characters: -_.
+// Uppercase letters are automatically converted to lowercase.
func New(m map[string]string) MD {
md := MD{}
for k, val := range m {
@@ -64,7 +55,13 @@ 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.
+//
+// Only the following ASCII characters are allowed in keys:
+// - digits: 0-9
+// - uppercase letters: A-Z (normalized to lower)
+// - lowercase letters: a-z
+// - special characters: -_.
+// Uppercase letters 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)))
@@ -91,9 +88,9 @@ func (md MD) Copy() MD {
return Join(md)
}
-// Join joins any number of MDs into a single MD.
+// Join joins any number of mds into a single MD.
// The order of values for each key is determined by the order in which
-// the MDs containing those values are presented to Join.
+// the mds containing those values are presented to Join.
func Join(mds ...MD) MD {
out := MD{}
for _, md := range mds {
@@ -127,17 +124,17 @@ func FromContext(ctx context.Context) (md MD, ok bool) {
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.
+// FromIncomingContext returns the incoming metadata in ctx if it exists. The
+// returned MD should not be modified. Writing to it may cause races.
+// Modification should be made to 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.
+// FromOutgoingContext returns the outgoing metadata in ctx if it exists. The
+// returned MD should not be modified. 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/vendor/google.golang.org/grpc/naming/naming.go b/vendor/google.golang.org/grpc/naming/naming.go
index c2e0871e6f8..1af7e32f86d 100644
--- a/vendor/google.golang.org/grpc/naming/naming.go
+++ b/vendor/google.golang.org/grpc/naming/naming.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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/vendor/google.golang.org/grpc/peer/peer.go b/vendor/google.golang.org/grpc/peer/peer.go
index bfa6205ba9e..317b8b9d09a 100644
--- a/vendor/google.golang.org/grpc/peer/peer.go
+++ b/vendor/google.golang.org/grpc/peer/peer.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -42,7 +27,8 @@ import (
"google.golang.org/grpc/credentials"
)
-// Peer contains the information of the peer for an RPC.
+// Peer contains the information of the peer for an RPC, such as the address
+// and authentication information.
type Peer struct {
// Addr is the peer address.
Addr net.Addr
diff --git a/vendor/google.golang.org/grpc/proxy.go b/vendor/google.golang.org/grpc/proxy.go
index 10188dc3433..2d40236e218 100644
--- a/vendor/google.golang.org/grpc/proxy.go
+++ b/vendor/google.golang.org/grpc/proxy.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2017, Google Inc.
- * All rights reserved.
+ * Copyright 2017 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go
index 34e1ad03b97..ace206b8f40 100644
--- a/vendor/google.golang.org/grpc/rpc_util.go
+++ b/vendor/google.golang.org/grpc/rpc_util.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -40,11 +25,12 @@ import (
"io"
"io/ioutil"
"math"
- "os"
+ "sync"
"time"
"golang.org/x/net/context"
"google.golang.org/grpc/codes"
+ "google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/peer"
"google.golang.org/grpc/stats"
@@ -60,16 +46,24 @@ type Compressor interface {
Type() string
}
-// NewGZIPCompressor creates a Compressor based on GZIP.
-func NewGZIPCompressor() Compressor {
- return &gzipCompressor{}
+type gzipCompressor struct {
+ pool sync.Pool
}
-type gzipCompressor struct {
+// NewGZIPCompressor creates a Compressor based on GZIP.
+func NewGZIPCompressor() Compressor {
+ return &gzipCompressor{
+ pool: sync.Pool{
+ New: func() interface{} {
+ return gzip.NewWriter(ioutil.Discard)
+ },
+ },
+ }
}
func (c *gzipCompressor) Do(w io.Writer, p []byte) error {
- z := gzip.NewWriter(w)
+ z := c.pool.Get().(*gzip.Writer)
+ z.Reset(w)
if _, err := z.Write(p); err != nil {
return err
}
@@ -89,6 +83,7 @@ type Decompressor interface {
}
type gzipDecompressor struct {
+ pool sync.Pool
}
// NewGZIPDecompressor creates a Decompressor based on GZIP.
@@ -97,11 +92,26 @@ func NewGZIPDecompressor() Decompressor {
}
func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) {
- z, err := gzip.NewReader(r)
- if err != nil {
- return nil, err
+ var z *gzip.Reader
+ switch maybeZ := d.pool.Get().(type) {
+ case nil:
+ newZ, err := gzip.NewReader(r)
+ if err != nil {
+ return nil, err
+ }
+ z = newZ
+ case *gzip.Reader:
+ z = maybeZ
+ if err := z.Reset(r); err != nil {
+ d.pool.Put(z)
+ return nil, err
+ }
}
- defer z.Close()
+
+ defer func() {
+ z.Close()
+ d.pool.Put(z)
+ }()
return ioutil.ReadAll(z)
}
@@ -111,11 +121,14 @@ func (d *gzipDecompressor) Type() string {
// callInfo contains all related configuration and information about an RPC.
type callInfo struct {
- failFast bool
- headerMD metadata.MD
- trailerMD metadata.MD
- peer *peer.Peer
- traceInfo traceInfo // in trace.go
+ failFast bool
+ headerMD metadata.MD
+ trailerMD metadata.MD
+ peer *peer.Peer
+ traceInfo traceInfo // in trace.go
+ maxReceiveMessageSize *int
+ maxSendMessageSize *int
+ creds credentials.PerRPCCredentials
}
var defaultCallInfo = callInfo{failFast: true}
@@ -132,6 +145,14 @@ type CallOption interface {
after(*callInfo)
}
+// EmptyCallOption does not alter the Call configuration.
+// It can be embedded in another structure to carry satellite data for use
+// by interceptors.
+type EmptyCallOption struct{}
+
+func (EmptyCallOption) before(*callInfo) error { return nil }
+func (EmptyCallOption) after(*callInfo) {}
+
type beforeCall func(c *callInfo) error
func (o beforeCall) before(c *callInfo) error { return o(c) }
@@ -173,7 +194,8 @@ func Peer(peer *peer.Peer) CallOption {
// 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. Note: failFast is default to true.
+// https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md.
+// Note: failFast is default to true.
func FailFast(failFast bool) CallOption {
return beforeCall(func(c *callInfo) error {
c.failFast = failFast
@@ -181,6 +203,31 @@ func FailFast(failFast bool) CallOption {
})
}
+// MaxCallRecvMsgSize returns a CallOption which sets the maximum message size the client can receive.
+func MaxCallRecvMsgSize(s int) CallOption {
+ return beforeCall(func(o *callInfo) error {
+ o.maxReceiveMessageSize = &s
+ return nil
+ })
+}
+
+// MaxCallSendMsgSize returns a CallOption which sets the maximum message size the client can send.
+func MaxCallSendMsgSize(s int) CallOption {
+ return beforeCall(func(o *callInfo) error {
+ o.maxSendMessageSize = &s
+ return nil
+ })
+}
+
+// PerRPCCredentials returns a CallOption that sets credentials.PerRPCCredentials
+// for a call.
+func PerRPCCredentials(creds credentials.PerRPCCredentials) CallOption {
+ return beforeCall(func(c *callInfo) error {
+ c.creds = creds
+ return nil
+ })
+}
+
// The format of the payload: compressed or not?
type payloadFormat uint8
@@ -197,7 +244,7 @@ type parser struct {
r io.Reader
// The header of a gRPC message. Find more detail
- // at http://www.grpc.io/docs/guides/wire.html.
+ // at https://grpc.io/docs/guides/wire.html.
header [5]byte
}
@@ -214,8 +261,8 @@ type parser struct {
// No other error values or types must be returned, which also means
// that the underlying io.Reader must not return an incompatible
// error.
-func (p *parser) recvMsg(maxMsgSize int) (pf payloadFormat, msg []byte, err error) {
- if _, err := io.ReadFull(p.r, p.header[:]); err != nil {
+func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byte, err error) {
+ if _, err := p.r.Read(p.header[:]); err != nil {
return 0, nil, err
}
@@ -225,13 +272,13 @@ func (p *parser) recvMsg(maxMsgSize int) (pf payloadFormat, msg []byte, err erro
if length == 0 {
return pf, nil, nil
}
- if length > uint32(maxMsgSize) {
- return 0, nil, Errorf(codes.Internal, "grpc: received message length %d exceeding the max size %d", length, maxMsgSize)
+ if length > uint32(maxReceiveMessageSize) {
+ return 0, nil, Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize)
}
// TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead
// of making it for each message:
msg = make([]byte, int(length))
- if _, err := io.ReadFull(p.r, msg); err != nil {
+ if _, err := p.r.Read(msg); err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
@@ -252,7 +299,7 @@ func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer, outPayl
// TODO(zhaoq): optimize to reduce memory alloc and copying.
b, err = c.Marshal(msg)
if err != nil {
- return nil, err
+ return nil, Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error())
}
if outPayload != nil {
outPayload.Payload = msg
@@ -262,14 +309,14 @@ func encode(c Codec, msg interface{}, cp Compressor, cbuf *bytes.Buffer, outPayl
}
if cp != nil {
if err := cp.Do(cbuf, b); err != nil {
- return nil, err
+ return nil, Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error())
}
b = cbuf.Bytes()
}
length = uint(len(b))
}
if length > math.MaxUint32 {
- return nil, Errorf(codes.InvalidArgument, "grpc: message too large (%d bytes)", length)
+ return nil, Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", length)
}
const (
@@ -310,8 +357,8 @@ 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, inPayload *stats.InPayload) error {
- pf, d, err := p.recvMsg(maxMsgSize)
+func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{}, maxReceiveMessageSize int, inPayload *stats.InPayload) error {
+ pf, d, err := p.recvMsg(maxReceiveMessageSize)
if err != nil {
return err
}
@@ -327,10 +374,10 @@ func recv(p *parser, c Codec, s *transport.Stream, dc Decompressor, m interface{
return Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
}
}
- if len(d) > maxMsgSize {
+ if len(d) > maxReceiveMessageSize {
// TODO: Revisit the error code. Currently keep it consistent with java
// implementation.
- return Errorf(codes.Internal, "grpc: received a message of %d bytes exceeding %d limit", len(d), maxMsgSize)
+ return Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(d), maxReceiveMessageSize)
}
if err := c.Unmarshal(d, m); err != nil {
return Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err)
@@ -398,57 +445,6 @@ func Errorf(c codes.Code, format string, a ...interface{}) error {
return status.Errorf(c, format, a...)
}
-// toRPCErr converts an error into an error from the status package.
-func toRPCErr(err error) error {
- if _, ok := status.FromError(err); ok {
- return err
- }
- switch e := err.(type) {
- case transport.StreamError:
- return status.Error(e.Code, e.Desc)
- case transport.ConnectionError:
- return status.Error(codes.Internal, e.Desc)
- default:
- switch err {
- case context.DeadlineExceeded:
- return status.Error(codes.DeadlineExceeded, err.Error())
- case context.Canceled:
- return status.Error(codes.Canceled, err.Error())
- case ErrClientConnClosing:
- return status.Error(codes.FailedPrecondition, err.Error())
- }
- }
- return status.Error(codes.Unknown, err.Error())
-}
-
-// convertCode converts a standard Go error into its canonical code. Note that
-// this is only used to translate the error returned by the server applications.
-func convertCode(err error) codes.Code {
- switch err {
- case nil:
- return codes.OK
- case io.EOF:
- return codes.OutOfRange
- case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF:
- return codes.FailedPrecondition
- case os.ErrInvalid:
- return codes.InvalidArgument
- case context.Canceled:
- return codes.Canceled
- case context.DeadlineExceeded:
- return codes.DeadlineExceeded
- }
- switch {
- case os.IsExist(err):
- return codes.AlreadyExists
- case os.IsNotExist(err):
- return codes.NotFound
- case os.IsPermission(err):
- return codes.PermissionDenied
- }
- return codes.Unknown
-}
-
// MethodConfig defines the configuration recommended by the service providers for a
// particular method.
// This is EXPERIMENTAL and subject to change.
@@ -456,24 +452,22 @@ 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
+ 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
+ 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
+ MaxReqSize *int
// MaxRespSize is the maximum allowed payload size for an individual response in a
// stream (server->client) in bytes.
- // TODO: support this.
- MaxRespSize uint32
+ MaxRespSize *int
}
// ServiceConfig is provided by the service provider and contains parameters for how
@@ -484,9 +478,38 @@ type ServiceConfig struct {
// via grpc.WithBalancer will override this.
LB Balancer
// Methods contains a map for the methods in this service.
+ // If there is an exact match for a method (i.e. /service/method) in the map, use the corresponding MethodConfig.
+ // If there's no exact match, look for the default config for the service (/service/) and use the corresponding MethodConfig if it exists.
+ // Otherwise, the method has no MethodConfig to use.
Methods map[string]MethodConfig
}
+func min(a, b *int) *int {
+ if *a < *b {
+ return a
+ }
+ return b
+}
+
+func getMaxSize(mcMax, doptMax *int, defaultVal int) *int {
+ if mcMax == nil && doptMax == nil {
+ return &defaultVal
+ }
+ if mcMax != nil && doptMax != nil {
+ return min(mcMax, doptMax)
+ }
+ if mcMax != nil {
+ return mcMax
+ }
+ return doptMax
+}
+
+// SupportPackageIsVersion3 is referenced from generated protocol buffer files.
+// The latest support package version is 4.
+// SupportPackageIsVersion3 is kept for compability. It will be removed in the
+// next support package version update.
+const SupportPackageIsVersion3 = true
+
// SupportPackageIsVersion4 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the grpc package.
//
@@ -496,6 +519,6 @@ type ServiceConfig struct {
const SupportPackageIsVersion4 = true
// Version is the current grpc version.
-const Version = "1.3.0"
+const Version = "1.5.2"
const grpcUA = "grpc-go/" + Version
diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go
index b15f71c6c18..5e9da3d952c 100644
--- a/vendor/google.golang.org/grpc/server.go
+++ b/vendor/google.golang.org/grpc/server.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -61,6 +46,11 @@ import (
"google.golang.org/grpc/transport"
)
+const (
+ defaultServerMaxReceiveMessageSize = 1024 * 1024 * 4
+ defaultServerMaxSendMessageSize = 1024 * 1024 * 4
+)
+
type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error)
// MethodDesc represents an RPC service's method specification.
@@ -96,6 +86,7 @@ type Server struct {
mu sync.Mutex // guards following
lis map[net.Listener]bool
conns map[io.Closer]bool
+ serve bool
drain bool
ctx context.Context
cancel context.CancelFunc
@@ -107,27 +98,49 @@ type Server struct {
}
type options struct {
- creds credentials.TransportCredentials
- codec Codec
- cp Compressor
- dc Decompressor
- 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
+ creds credentials.TransportCredentials
+ codec Codec
+ cp Compressor
+ dc Decompressor
+ unaryInt UnaryServerInterceptor
+ streamInt StreamServerInterceptor
+ inTapHandle tap.ServerInHandle
+ statsHandler stats.Handler
+ maxConcurrentStreams uint32
+ maxReceiveMessageSize int
+ maxSendMessageSize int
+ useHandlerImpl bool // use http.Handler-based server
+ unknownStreamDesc *StreamDesc
+ keepaliveParams keepalive.ServerParameters
+ keepalivePolicy keepalive.EnforcementPolicy
+ initialWindowSize int32
+ initialConnWindowSize int32
}
-var defaultMaxMsgSize = 1024 * 1024 * 4 // use 4MB as the default message size limit
+var defaultServerOptions = options{
+ maxReceiveMessageSize: defaultServerMaxReceiveMessageSize,
+ maxSendMessageSize: defaultServerMaxSendMessageSize,
+}
-// A ServerOption sets options.
+// A ServerOption sets options such as credentials, codec and keepalive parameters, etc.
type ServerOption func(*options)
+// InitialWindowSize returns a ServerOption that sets window size for stream.
+// The lower bound for window size is 64K and any value smaller than that will be ignored.
+func InitialWindowSize(s int32) ServerOption {
+ return func(o *options) {
+ o.initialWindowSize = s
+ }
+}
+
+// InitialConnWindowSize returns a ServerOption that sets window size for a connection.
+// The lower bound for window size is 64K and any value smaller than that will be ignored.
+func InitialConnWindowSize(s int32) ServerOption {
+ return func(o *options) {
+ o.initialConnWindowSize = s
+ }
+}
+
// KeepaliveParams returns a ServerOption that sets keepalive and max-age parameters for the server.
func KeepaliveParams(kp keepalive.ServerParameters) ServerOption {
return func(o *options) {
@@ -163,11 +176,25 @@ func RPCDecompressor(dc Decompressor) ServerOption {
}
}
-// MaxMsgSize returns a ServerOption to set the max message size in bytes for inbound mesages.
-// If this is not set, gRPC uses the default 4MB.
+// MaxMsgSize returns a ServerOption to set the max message size in bytes the server can receive.
+// If this is not set, gRPC uses the default limit. Deprecated: use MaxRecvMsgSize instead.
func MaxMsgSize(m int) ServerOption {
+ return MaxRecvMsgSize(m)
+}
+
+// MaxRecvMsgSize returns a ServerOption to set the max message size in bytes the server can receive.
+// If this is not set, gRPC uses the default 4MB.
+func MaxRecvMsgSize(m int) ServerOption {
return func(o *options) {
- o.maxMsgSize = m
+ o.maxReceiveMessageSize = m
+ }
+}
+
+// MaxSendMsgSize returns a ServerOption to set the max message size in bytes the server can send.
+// If this is not set, gRPC uses the default 4MB.
+func MaxSendMsgSize(m int) ServerOption {
+ return func(o *options) {
+ o.maxSendMessageSize = m
}
}
@@ -192,7 +219,7 @@ func Creds(c credentials.TransportCredentials) ServerOption {
func UnaryInterceptor(i UnaryServerInterceptor) ServerOption {
return func(o *options) {
if o.unaryInt != nil {
- panic("The unary server interceptor has been set.")
+ panic("The unary server interceptor was already set and may not be reset.")
}
o.unaryInt = i
}
@@ -203,7 +230,7 @@ func UnaryInterceptor(i UnaryServerInterceptor) ServerOption {
func StreamInterceptor(i StreamServerInterceptor) ServerOption {
return func(o *options) {
if o.streamInt != nil {
- panic("The stream server interceptor has been set.")
+ panic("The stream server interceptor was already set and may not be reset.")
}
o.streamInt = i
}
@@ -214,7 +241,7 @@ func StreamInterceptor(i StreamServerInterceptor) ServerOption {
func InTapHandle(h tap.ServerInHandle) ServerOption {
return func(o *options) {
if o.inTapHandle != nil {
- panic("The tap handle has been set.")
+ panic("The tap handle was already set and may not be reset.")
}
o.inTapHandle = h
}
@@ -229,7 +256,7 @@ func StatsHandler(h stats.Handler) ServerOption {
// 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
+// handler that will be invoked instead of returning 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.
@@ -248,8 +275,7 @@ func UnknownServiceHandler(streamHandler StreamHandler) ServerOption {
// NewServer creates a gRPC server which has no service registered and has not
// started to accept requests yet.
func NewServer(opt ...ServerOption) *Server {
- var opts options
- opts.maxMsgSize = defaultMaxMsgSize
+ opts := defaultServerOptions
for _, o := range opt {
o(&opts)
}
@@ -288,8 +314,8 @@ func (s *Server) errorf(format string, a ...interface{}) {
}
}
-// RegisterService register a service and its implementation to the gRPC
-// server. Called from the IDL generated code. This must be called before
+// RegisterService registers a service and its implementation to the gRPC
+// server. It is called from the IDL generated code. This must be called before
// invoking Serve.
func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) {
ht := reflect.TypeOf(sd.HandlerType).Elem()
@@ -304,6 +330,9 @@ func (s *Server) register(sd *ServiceDesc, ss interface{}) {
s.mu.Lock()
defer s.mu.Unlock()
s.printf("RegisterService(%q)", sd.ServiceName)
+ if s.serve {
+ grpclog.Fatalf("grpc: Server.RegisterService after Server.Serve for %q", sd.ServiceName)
+ }
if _, ok := s.m[sd.ServiceName]; ok {
grpclog.Fatalf("grpc: Server.RegisterService found duplicate service registration for %q", sd.ServiceName)
}
@@ -334,7 +363,7 @@ type MethodInfo struct {
IsServerStream bool
}
-// ServiceInfo contains unary RPC method info, streaming RPC methid info and metadata for a service.
+// ServiceInfo contains unary RPC method info, streaming RPC method info and metadata for a service.
type ServiceInfo struct {
Methods []MethodInfo
// Metadata is the metadata specified in ServiceDesc when registering service.
@@ -392,6 +421,7 @@ func (s *Server) useTransportAuthenticator(rawConn net.Conn) (net.Conn, credenti
func (s *Server) Serve(lis net.Listener) error {
s.mu.Lock()
s.printf("serving")
+ s.serve = true
if s.lis == nil {
s.mu.Unlock()
lis.Close()
@@ -427,10 +457,12 @@ func (s *Server) Serve(lis net.Listener) error {
s.mu.Lock()
s.printf("Accept error: %v; retrying in %v", err, tempDelay)
s.mu.Unlock()
+ timer := time.NewTimer(tempDelay)
select {
- case <-time.After(tempDelay):
+ case <-timer.C:
case <-s.ctx.Done():
}
+ timer.Stop()
continue
}
s.mu.Lock()
@@ -453,7 +485,7 @@ func (s *Server) handleRawConn(rawConn net.Conn) {
s.mu.Lock()
s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err)
s.mu.Unlock()
- grpclog.Printf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err)
+ grpclog.Warningf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err)
// If serverHandShake returns ErrConnDispatched, keep rawConn open.
if err != credentials.ErrConnDispatched {
rawConn.Close()
@@ -483,12 +515,14 @@ func (s *Server) handleRawConn(rawConn net.Conn) {
// transport.NewServerTransport).
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,
+ MaxStreams: s.opts.maxConcurrentStreams,
+ AuthInfo: authInfo,
+ InTapHandle: s.opts.inTapHandle,
+ StatsHandler: s.opts.statsHandler,
+ KeepaliveParams: s.opts.keepaliveParams,
+ KeepalivePolicy: s.opts.keepalivePolicy,
+ InitialWindowSize: s.opts.initialWindowSize,
+ InitialConnWindowSize: s.opts.initialConnWindowSize,
}
st, err := transport.NewServerTransport("http2", c, config)
if err != nil {
@@ -496,7 +530,7 @@ func (s *Server) serveHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo)
s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err)
s.mu.Unlock()
c.Close()
- grpclog.Println("grpc: Server.Serve failed to create ServerTransport: ", err)
+ grpclog.Warningln("grpc: Server.Serve failed to create ServerTransport: ", err)
return
}
if !s.addConn(st) {
@@ -620,14 +654,11 @@ func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Str
}
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
- // cannot handle.
- //
- // TODO(zhaoq): There exist other options also such as only closing the
- // faulty stream locally and remotely (Other streams can keep going). Find
- // the optimal option.
- grpclog.Fatalf("grpc: Server failed to encode response %v", err)
+ grpclog.Errorln("grpc: server failed to encode response: ", err)
+ return err
+ }
+ if len(p) > s.opts.maxSendMessageSize {
+ return status.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", len(p), s.opts.maxSendMessageSize)
}
err = t.Write(stream, p, opts)
if err == nil && outPayload != nil {
@@ -644,9 +675,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
BeginTime: time.Now(),
}
sh.HandleRPC(stream.Context(), begin)
- }
- defer func() {
- if sh != nil {
+ defer func() {
end := &stats.End{
EndTime: time.Now(),
}
@@ -654,8 +683,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
end.Error = toRPCErr(err)
}
sh.HandleRPC(stream.Context(), end)
- }
- }()
+ }()
+ }
if trInfo != nil {
defer trInfo.tr.Finish()
trInfo.firstLine.client = false
@@ -672,139 +701,137 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
stream.SetSendCompress(s.opts.cp.Type())
}
p := &parser{r: stream}
- for { // TODO: delete
- pf, req, err := p.recvMsg(s.opts.maxMsgSize)
+ pf, req, err := p.recvMsg(s.opts.maxReceiveMessageSize)
+ if err == io.EOF {
+ // The entire stream is done (for unary RPC only).
+ return err
+ }
+ if err == io.ErrUnexpectedEOF {
+ err = Errorf(codes.Internal, io.ErrUnexpectedEOF.Error())
+ }
+ if err != nil {
+ if st, ok := status.FromError(err); ok {
+ if e := t.WriteStatus(stream, st); e != nil {
+ grpclog.Warningf("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.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e)
+ }
+ default:
+ panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", st, st))
+ }
+ }
+ return err
+ }
+
+ if err := checkRecvPayload(pf, stream.RecvCompress(), s.opts.dc); err != nil {
+ if st, ok := status.FromError(err); ok {
+ if e := t.WriteStatus(stream, st); e != nil {
+ grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e)
+ }
+ return err
+ }
+ if e := t.WriteStatus(stream, status.New(codes.Internal, err.Error())); e != nil {
+ grpclog.Warningf("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(),
+ }
+ }
+ 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 {
+ return Errorf(codes.Internal, err.Error())
+ }
+ }
+ if len(req) > s.opts.maxReceiveMessageSize {
+ // TODO: Revisit the error code. Currently keep it consistent with
+ // java implementation.
+ return status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", len(req), s.opts.maxReceiveMessageSize)
+ }
+ if err := s.opts.codec.Unmarshal(req, v); err != nil {
+ 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)
+ }
+ return nil
+ }
+ reply, appErr := md.Handler(srv.server, stream.Context(), df, s.opts.unaryInt)
+ if appErr != nil {
+ 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 {
+ trInfo.tr.LazyLog(stringer(appStatus.Message()), true)
+ trInfo.tr.SetError()
+ }
+ if e := t.WriteStatus(stream, appStatus); e != nil {
+ grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status: %v", e)
+ }
+ return appErr
+ }
+ if trInfo != nil {
+ trInfo.tr.LazyLog(stringer("OK"), false)
+ }
+ opts := &transport.Options{
+ Last: true,
+ Delay: false,
+ }
+ if err := s.sendResponse(t, stream, reply, s.opts.cp, opts); err != nil {
if err == io.EOF {
// The entire stream is done (for unary RPC only).
return err
}
- if err == io.ErrUnexpectedEOF {
- err = Errorf(codes.Internal, io.ErrUnexpectedEOF.Error())
- }
- if err != nil {
- 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)
+ if s, ok := status.FromError(err); ok {
+ if e := t.WriteStatus(stream, s); e != nil {
+ grpclog.Warningf("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.Warningf("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 recvMsg: %v", st, st))
- }
- }
- return err
- }
-
- if err := checkRecvPayload(pf, stream.RecvCompress(), s.opts.dc); err != nil {
- 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)
- }
- 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(),
+ default:
+ panic(fmt.Sprintf("grpc: Unexpected error (%T) from sendResponse: %v", st, st))
}
}
- 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 {
- return Errorf(codes.Internal, err.Error())
- }
- }
- if len(req) > s.opts.maxMsgSize {
- // TODO: Revisit the error code. Currently keep it consistent with
- // java implementation.
- 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 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)
- }
- return nil
- }
- reply, appErr := md.Handler(srv.server, stream.Context(), df, s.opts.unaryInt)
- if appErr != nil {
- 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 {
- trInfo.tr.LazyLog(stringer(appStatus.Message()), true)
- trInfo.tr.SetError()
- }
- if e := t.WriteStatus(stream, appStatus); e != nil {
- grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", e)
- }
- return appErr
- }
- if trInfo != nil {
- trInfo.tr.LazyLog(stringer("OK"), false)
- }
- opts := &transport.Options{
- Last: true,
- Delay: false,
- }
- if err := s.sendResponse(t, stream, reply, s.opts.cp, opts); err != nil {
- 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)
- }
- // 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, ""))
+ return err
}
+ if trInfo != nil {
+ trInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true)
+ }
+ // 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) {
@@ -814,9 +841,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
BeginTime: time.Now(),
}
sh.HandleRPC(stream.Context(), begin)
- }
- defer func() {
- if sh != nil {
+ defer func() {
end := &stats.End{
EndTime: time.Now(),
}
@@ -824,21 +849,22 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
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,
- statsHandler: sh,
+ t: t,
+ s: stream,
+ p: &parser{r: stream},
+ codec: s.opts.codec,
+ cp: s.opts.cp,
+ dc: s.opts.dc,
+ maxReceiveMessageSize: s.opts.maxReceiveMessageSize,
+ maxSendMessageSize: s.opts.maxSendMessageSize,
+ trInfo: trInfo,
+ statsHandler: sh,
}
if ss.cp != nil {
ss.cbuf = new(bytes.Buffer)
@@ -913,12 +939,12 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
trInfo.tr.SetError()
}
errDesc := fmt.Sprintf("malformed method name: %q", stream.Method())
- if err := t.WriteStatus(stream, status.New(codes.InvalidArgument, errDesc)); err != nil {
+ if err := t.WriteStatus(stream, status.New(codes.ResourceExhausted, errDesc)); err != nil {
if trInfo != nil {
trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
trInfo.tr.SetError()
}
- grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err)
+ grpclog.Warningf("grpc: Server.handleStream failed to write status: %v", err)
}
if trInfo != nil {
trInfo.tr.Finish()
@@ -943,7 +969,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
trInfo.tr.SetError()
}
- grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err)
+ grpclog.Warningf("grpc: Server.handleStream failed to write status: %v", err)
}
if trInfo != nil {
trInfo.tr.Finish()
@@ -973,7 +999,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
trInfo.tr.SetError()
}
- grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err)
+ grpclog.Warningf("grpc: Server.handleStream failed to write status: %v", err)
}
if trInfo != nil {
trInfo.tr.Finish()
@@ -1011,8 +1037,9 @@ func (s *Server) Stop() {
s.mu.Unlock()
}
-// GracefulStop stops the gRPC server gracefully. It stops the server to accept new
-// connections and RPCs and blocks until all the pending RPCs are finished.
+// GracefulStop stops the gRPC server gracefully. It stops the server from
+// accepting new connections and RPCs and blocks until all the pending RPCs are
+// finished.
func (s *Server) GracefulStop() {
s.mu.Lock()
defer s.mu.Unlock()
diff --git a/vendor/google.golang.org/grpc/stats/handlers.go b/vendor/google.golang.org/grpc/stats/handlers.go
index 26e1a8e2f08..05b384c6931 100644
--- a/vendor/google.golang.org/grpc/stats/handlers.go
+++ b/vendor/google.golang.org/grpc/stats/handlers.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2016, Google Inc.
- * All rights reserved.
+ * Copyright 2016 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -45,19 +30,22 @@ type ConnTagInfo struct {
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
+ // FailFast indicates if this RPC is failfast.
+ // This field is only valid on client side, it's always false on server side.
+ FailFast bool
}
// 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.
+ // The context used for the rest lifetime of the RPC will be derived from
+ // the returned context.
TagRPC(context.Context, *RPCTagInfo) context.Context
// HandleRPC processes the RPC stats.
HandleRPC(context.Context, RPCStats)
diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go
index c2c9a9dfa23..b0aa5278ae5 100644
--- a/vendor/google.golang.org/grpc/stats/stats.go
+++ b/vendor/google.golang.org/grpc/stats/stats.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2016, Google Inc.
- * All rights reserved.
+ * Copyright 2016 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -49,7 +34,7 @@ type RPCStats interface {
}
// Begin contains stats when an RPC begins.
-// FailFast are only valid if Client is true.
+// FailFast is only valid if this Begin is from client side.
type Begin struct {
// Client is true if this Begin is from client side.
Client bool
@@ -59,7 +44,7 @@ type Begin struct {
FailFast bool
}
-// IsClient indicates if this is from client side.
+// IsClient indicates if the stats information is from client side.
func (s *Begin) IsClient() bool { return s.Client }
func (s *Begin) isRPCStats() {}
@@ -80,19 +65,19 @@ type InPayload struct {
RecvTime time.Time
}
-// IsClient indicates if this is from client side.
+// IsClient indicates if the stats information 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
+ // The following fields are valid only if Client is false.
// FullMethod is the full RPC method string, i.e., /package.service/method.
FullMethod string
// RemoteAddr is the remote address of the corresponding connection.
@@ -103,7 +88,7 @@ type InHeader struct {
Compression string
}
-// IsClient indicates if this is from client side.
+// IsClient indicates if the stats information is from client side.
func (s *InHeader) IsClient() bool { return s.Client }
func (s *InHeader) isRPCStats() {}
@@ -116,7 +101,7 @@ type InTrailer struct {
WireLength int
}
-// IsClient indicates if this is from client side.
+// IsClient indicates if the stats information is from client side.
func (s *InTrailer) IsClient() bool { return s.Client }
func (s *InTrailer) isRPCStats() {}
@@ -137,19 +122,19 @@ type OutPayload struct {
SentTime time.Time
}
-// IsClient indicates if this is from client side.
+// IsClient indicates if this stats information 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
+ // The following fields are valid only if Client is true.
// FullMethod is the full RPC method string, i.e., /package.service/method.
FullMethod string
// RemoteAddr is the remote address of the corresponding connection.
@@ -160,7 +145,7 @@ type OutHeader struct {
Compression string
}
-// IsClient indicates if this is from client side.
+// IsClient indicates if this stats information is from client side.
func (s *OutHeader) IsClient() bool { return s.Client }
func (s *OutHeader) isRPCStats() {}
@@ -173,7 +158,7 @@ type OutTrailer struct {
WireLength int
}
-// IsClient indicates if this is from client side.
+// IsClient indicates if this stats information is from client side.
func (s *OutTrailer) IsClient() bool { return s.Client }
func (s *OutTrailer) isRPCStats() {}
diff --git a/vendor/google.golang.org/grpc/status/status.go b/vendor/google.golang.org/grpc/status/status.go
index 99a4cbe5112..68a3ac2f04d 100644
--- a/vendor/google.golang.org/grpc/status/status.go
+++ b/vendor/google.golang.org/grpc/status/status.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2017, Google Inc.
- * All rights reserved.
+ * Copyright 2017 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go
index 33f1c787b34..1c621ba875a 100644
--- a/vendor/google.golang.org/grpc/stream.go
+++ b/vendor/google.golang.org/grpc/stream.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -44,6 +29,7 @@ import (
"golang.org/x/net/trace"
"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"
@@ -73,11 +59,17 @@ type Stream interface {
// side. On server side, it simply returns the error to the caller.
// SendMsg is called by generated code. Also Users can call SendMsg
// directly when it is really needed in their use cases.
+ // It's safe to have a goroutine calling SendMsg and another goroutine calling
+ // recvMsg on the same stream at the same time.
+ // But it is not safe to call SendMsg on the same stream in different goroutines.
SendMsg(m interface{}) error
// RecvMsg blocks until it receives a message or the stream is
// done. On client side, it returns io.EOF when the stream is done. On
// any other error, it aborts the stream and returns an RPC status. On
// server side, it simply returns the error to the caller.
+ // It's safe to have a goroutine calling SendMsg and another goroutine calling
+ // recvMsg on the same stream at the same time.
+ // But it is not safe to call RecvMsg on the same stream in different goroutines.
RecvMsg(m interface{}) error
}
@@ -93,6 +85,11 @@ type ClientStream interface {
// CloseSend closes the send direction of the stream. It closes the stream
// when non-nil error is met.
CloseSend() error
+ // Stream.SendMsg() may return a non-nil error when something wrong happens sending
+ // the request. The returned error indicates the status of this sending, not the final
+ // status of the RPC.
+ // Always call Stream.RecvMsg() to get the final status if you care about the status of
+ // the RPC.
Stream
}
@@ -113,25 +110,39 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
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)
- }
+ mc := cc.GetMethodConfig(method)
+ if mc.WaitForReady != nil {
+ c.failFast = !*mc.WaitForReady
}
+
+ if mc.Timeout != nil {
+ ctx, cancel = context.WithTimeout(ctx, *mc.Timeout)
+ }
+
+ opts = append(cc.dopts.callOptions, opts...)
for _, o := range opts {
if err := o.before(&c); err != nil {
return nil, toRPCErr(err)
}
}
+ c.maxSendMessageSize = getMaxSize(mc.MaxReqSize, c.maxSendMessageSize, defaultClientMaxSendMessageSize)
+ c.maxReceiveMessageSize = getMaxSize(mc.MaxRespSize, c.maxReceiveMessageSize, defaultClientMaxReceiveMessageSize)
+
callHdr := &transport.CallHdr{
Host: cc.authority,
Method: method,
- Flush: desc.ServerStreams && desc.ClientStreams,
+ // If it's not client streaming, we should already have the request to be sent,
+ // so we don't flush the header.
+ // If it's client streaming, the user may never send a request or send it any
+ // time soon, so we ask the transport to flush the header.
+ Flush: desc.ClientStreams,
}
if cc.dopts.cp != nil {
callHdr.SendCompress = cc.dopts.cp.Type()
}
+ if c.creds != nil {
+ callHdr.Creds = c.creds
+ }
var trInfo traceInfo
if EnableTracing {
trInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method)
@@ -154,24 +165,24 @@ 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})
+ ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: method, FailFast: c.failFast})
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,
+ defer func() {
+ if err != nil {
+ // Only handle end stats if err != nil.
+ end := &stats.End{
+ Client: true,
+ Error: err,
+ }
+ sh.HandleRPC(ctx, end)
}
- sh.HandleRPC(ctx, end)
- }
- }()
+ }()
+ }
gopts := BalancerGetOptions{
BlockingWait: !c.failFast,
}
@@ -211,15 +222,18 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
}
break
}
+ // Set callInfo.peer object from stream's context.
+ if peer, ok := peer.FromContext(s.Context()); ok {
+ c.peer = peer
+ }
cs := &clientStream{
- opts: opts,
- c: c,
- desc: desc,
- codec: cc.dopts.codec,
- cp: cc.dopts.cp,
- dc: cc.dopts.dc,
- maxMsgSize: cc.dopts.maxMsgSize,
- cancel: cancel,
+ opts: opts,
+ c: c,
+ desc: desc,
+ codec: cc.dopts.codec,
+ cp: cc.dopts.cp,
+ dc: cc.dopts.dc,
+ cancel: cancel,
put: put,
t: t,
@@ -263,18 +277,17 @@ 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
- maxMsgSize int
- cancel context.CancelFunc
+ opts []CallOption
+ c callInfo
+ t transport.ClientTransport
+ s *transport.Stream
+ p *parser
+ desc *StreamDesc
+ codec Codec
+ cp Compressor
+ cbuf *bytes.Buffer
+ dc Decompressor
+ cancel context.CancelFunc
tracing bool // set to EnableTracing when the clientStream is created.
@@ -356,7 +369,13 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) {
}
}()
if err != nil {
- return Errorf(codes.Internal, "grpc: %v", err)
+ return err
+ }
+ if cs.c.maxSendMessageSize == nil {
+ return Errorf(codes.Internal, "callInfo maxSendMessageSize field uninitialized(nil)")
+ }
+ if len(out) > *cs.c.maxSendMessageSize {
+ return Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(out), *cs.c.maxSendMessageSize)
}
err = cs.t.Write(cs.s, out, &transport.Options{Last: false})
if err == nil && outPayload != nil {
@@ -373,7 +392,10 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) {
Client: true,
}
}
- err = recv(cs.p, cs.codec, cs.s, cs.dc, m, cs.maxMsgSize, inPayload)
+ if cs.c.maxReceiveMessageSize == nil {
+ return Errorf(codes.Internal, "callInfo maxReceiveMessageSize field uninitialized(nil)")
+ }
+ err = recv(cs.p, cs.codec, cs.s, cs.dc, m, *cs.c.maxReceiveMessageSize, inPayload)
defer func() {
// err != nil indicates the termination of the stream.
if err != nil {
@@ -396,7 +418,10 @@ func (cs *clientStream) RecvMsg(m interface{}) (err error) {
}
// Special handling for client streaming rpc.
// 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)
+ if cs.c.maxReceiveMessageSize == nil {
+ return Errorf(codes.Internal, "callInfo maxReceiveMessageSize field uninitialized(nil)")
+ }
+ err = recv(cs.p, cs.codec, cs.s, cs.dc, m, *cs.c.maxReceiveMessageSize, nil)
cs.closeTransportStream(err)
if err == nil {
return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want "))
@@ -521,15 +546,16 @@ type ServerStream interface {
// serverStream implements a server side Stream.
type serverStream struct {
- t transport.ServerTransport
- s *transport.Stream
- p *parser
- codec Codec
- cp Compressor
- dc Decompressor
- cbuf *bytes.Buffer
- maxMsgSize int
- trInfo *traceInfo
+ t transport.ServerTransport
+ s *transport.Stream
+ p *parser
+ codec Codec
+ cp Compressor
+ dc Decompressor
+ cbuf *bytes.Buffer
+ maxReceiveMessageSize int
+ maxSendMessageSize int
+ trInfo *traceInfo
statsHandler stats.Handler
@@ -585,9 +611,11 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) {
}
}()
if err != nil {
- err = Errorf(codes.Internal, "grpc: %v", err)
return err
}
+ if len(out) > ss.maxSendMessageSize {
+ return Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(out), ss.maxSendMessageSize)
+ }
if err := ss.t.Write(ss.s, out, &transport.Options{Last: false}); err != nil {
return toRPCErr(err)
}
@@ -617,7 +645,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
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 := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxReceiveMessageSize, inPayload); err != nil {
if err == io.EOF {
return err
}
diff --git a/vendor/google.golang.org/grpc/tap/tap.go b/vendor/google.golang.org/grpc/tap/tap.go
index 0f366476742..decb6786b02 100644
--- a/vendor/google.golang.org/grpc/tap/tap.go
+++ b/vendor/google.golang.org/grpc/tap/tap.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2016, Google Inc.
- * All rights reserved.
+ * Copyright 2016 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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/vendor/google.golang.org/grpc/trace.go b/vendor/google.golang.org/grpc/trace.go
index f6747e1dfa4..b419c9e3dea 100644
--- a/vendor/google.golang.org/grpc/trace.go
+++ b/vendor/google.golang.org/grpc/trace.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2015, Google Inc.
- * All rights reserved.
+ * Copyright 2015 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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/vendor/google.golang.org/grpc/transport/BUILD b/vendor/google.golang.org/grpc/transport/BUILD
index d6b3e9fd45f..6c82d464073 100644
--- a/vendor/google.golang.org/grpc/transport/BUILD
+++ b/vendor/google.golang.org/grpc/transport/BUILD
@@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
+ "bdp_estimator.go",
"control.go",
"go16.go",
"go17.go",
@@ -10,6 +11,7 @@ go_library(
"http2_client.go",
"http2_server.go",
"http_util.go",
+ "log.go",
"transport.go",
],
importpath = "google.golang.org/grpc/transport",
diff --git a/vendor/google.golang.org/grpc/transport/bdp_estimator.go b/vendor/google.golang.org/grpc/transport/bdp_estimator.go
new file mode 100644
index 00000000000..643652adeab
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/bdp_estimator.go
@@ -0,0 +1,125 @@
+package transport
+
+import (
+ "sync"
+ "time"
+)
+
+const (
+ // bdpLimit is the maximum value the flow control windows
+ // will be increased to.
+ bdpLimit = (1 << 20) * 4
+ // alpha is a constant factor used to keep a moving average
+ // of RTTs.
+ alpha = 0.9
+ // If the current bdp sample is greater than or equal to
+ // our beta * our estimated bdp and the current bandwidth
+ // sample is the maximum bandwidth observed so far, we
+ // increase our bbp estimate by a factor of gamma.
+ beta = 0.66
+ // To put our bdp to be smaller than or equal to twice the real BDP,
+ // we should multiply our current sample with 4/3, however to round things out
+ // we use 2 as the multiplication factor.
+ gamma = 2
+)
+
+var (
+ // Adding arbitrary data to ping so that its ack can be
+ // identified.
+ // Easter-egg: what does the ping message say?
+ bdpPing = &ping{data: [8]byte{2, 4, 16, 16, 9, 14, 7, 7}}
+)
+
+type bdpEstimator struct {
+ // sentAt is the time when the ping was sent.
+ sentAt time.Time
+
+ mu sync.Mutex
+ // bdp is the current bdp estimate.
+ bdp uint32
+ // sample is the number of bytes received in one measurement cycle.
+ sample uint32
+ // bwMax is the maximum bandwidth noted so far (bytes/sec).
+ bwMax float64
+ // bool to keep track of the begining of a new measurement cycle.
+ isSent bool
+ // Callback to update the window sizes.
+ updateFlowControl func(n uint32)
+ // sampleCount is the number of samples taken so far.
+ sampleCount uint64
+ // round trip time (seconds)
+ rtt float64
+}
+
+// timesnap registers the time bdp ping was sent out so that
+// network rtt can be calculated when its ack is recieved.
+// It is called (by controller) when the bdpPing is
+// being written on the wire.
+func (b *bdpEstimator) timesnap(d [8]byte) {
+ if bdpPing.data != d {
+ return
+ }
+ b.sentAt = time.Now()
+}
+
+// add adds bytes to the current sample for calculating bdp.
+// It returns true only if a ping must be sent. This can be used
+// by the caller (handleData) to make decision about batching
+// a window update with it.
+func (b *bdpEstimator) add(n uint32) bool {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ if b.bdp == bdpLimit {
+ return false
+ }
+ if !b.isSent {
+ b.isSent = true
+ b.sample = n
+ b.sentAt = time.Time{}
+ b.sampleCount++
+ return true
+ }
+ b.sample += n
+ return false
+}
+
+// calculate is called when an ack for a bdp ping is received.
+// Here we calculate the current bdp and bandwidth sample and
+// decide if the flow control windows should go up.
+func (b *bdpEstimator) calculate(d [8]byte) {
+ // Check if the ping acked for was the bdp ping.
+ if bdpPing.data != d {
+ return
+ }
+ b.mu.Lock()
+ rttSample := time.Since(b.sentAt).Seconds()
+ if b.sampleCount < 10 {
+ // Bootstrap rtt with an average of first 10 rtt samples.
+ b.rtt += (rttSample - b.rtt) / float64(b.sampleCount)
+ } else {
+ // Heed to the recent past more.
+ b.rtt += (rttSample - b.rtt) * float64(alpha)
+ }
+ b.isSent = false
+ // The number of bytes accumalated so far in the sample is smaller
+ // than or equal to 1.5 times the real BDP on a saturated connection.
+ bwCurrent := float64(b.sample) / (b.rtt * float64(1.5))
+ if bwCurrent > b.bwMax {
+ b.bwMax = bwCurrent
+ }
+ // If the current sample (which is smaller than or equal to the 1.5 times the real BDP) is
+ // greater than or equal to 2/3rd our perceived bdp AND this is the maximum bandwidth seen so far, we
+ // should update our perception of the network BDP.
+ if float64(b.sample) >= beta*float64(b.bdp) && bwCurrent == b.bwMax && b.bdp != bdpLimit {
+ sampleFloat := float64(b.sample)
+ b.bdp = uint32(gamma * sampleFloat)
+ if b.bdp > bdpLimit {
+ b.bdp = bdpLimit
+ }
+ bdp := b.bdp
+ b.mu.Unlock()
+ b.updateFlowControl(bdp)
+ return
+ }
+ b.mu.Unlock()
+}
diff --git a/vendor/google.golang.org/grpc/transport/control.go b/vendor/google.golang.org/grpc/transport/control.go
index 8d29aee53d4..501eb03c49f 100644
--- a/vendor/google.golang.org/grpc/transport/control.go
+++ b/vendor/google.golang.org/grpc/transport/control.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -46,8 +31,7 @@ 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
infinity = time.Duration(math.MaxInt64)
defaultClientKeepaliveTime = infinity
defaultClientKeepaliveTimeout = time.Duration(20 * time.Second)
@@ -58,6 +42,8 @@ const (
defaultServerKeepaliveTime = time.Duration(2 * time.Hour)
defaultServerKeepaliveTimeout = time.Duration(20 * time.Second)
defaultKeepalivePolicyMinTime = time.Duration(5 * time.Minute)
+ // max window limit set by HTTP2 Specs.
+ maxWindowSize = math.MaxInt32
)
// The following defines various control items which could flow through
@@ -66,6 +52,7 @@ const (
type windowUpdate struct {
streamID uint32
increment uint32
+ flush bool
}
func (*windowUpdate) item() {}
@@ -87,6 +74,8 @@ func (*resetStream) item() {}
type goAway struct {
code http2.ErrCode
debugData []byte
+ headsUp bool
+ closeConn bool
}
func (*goAway) item() {}
@@ -157,16 +146,59 @@ func (qb *quotaPool) acquire() <-chan int {
// inFlow deals with inbound flow control
type inFlow struct {
+ mu sync.Mutex
// The inbound flow control limit for pending data.
limit uint32
-
- mu sync.Mutex
// pendingData is the overall data which have been received but not been
// consumed by applications.
pendingData uint32
// The amount of data the application has consumed but grpc has not sent
// window update for them. Used to reduce window update frequency.
pendingUpdate uint32
+ // delta is the extra window update given by receiver when an application
+ // is reading data bigger in size than the inFlow limit.
+ delta uint32
+}
+
+// newLimit updates the inflow window to a new value n.
+// It assumes that n is always greater than the old limit.
+func (f *inFlow) newLimit(n uint32) uint32 {
+ f.mu.Lock()
+ defer f.mu.Unlock()
+ d := n - f.limit
+ f.limit = n
+ return d
+}
+
+func (f *inFlow) maybeAdjust(n uint32) uint32 {
+ if n > uint32(math.MaxInt32) {
+ n = uint32(math.MaxInt32)
+ }
+ f.mu.Lock()
+ defer f.mu.Unlock()
+ // estSenderQuota is the receiver's view of the maximum number of bytes the sender
+ // can send without a window update.
+ estSenderQuota := int32(f.limit - (f.pendingData + f.pendingUpdate))
+ // estUntransmittedData is the maximum number of bytes the sends might not have put
+ // on the wire yet. A value of 0 or less means that we have already received all or
+ // more bytes than the application is requesting to read.
+ estUntransmittedData := int32(n - f.pendingData) // Casting into int32 since it could be negative.
+ // This implies that unless we send a window update, the sender won't be able to send all the bytes
+ // for this message. Therefore we must send an update over the limit since there's an active read
+ // request from the application.
+ if estUntransmittedData > estSenderQuota {
+ // Sender's window shouldn't go more than 2^31 - 1 as speecified in the HTTP spec.
+ if f.limit+n > maxWindowSize {
+ f.delta = maxWindowSize - f.limit
+ } else {
+ // Send a window update for the whole message and not just the difference between
+ // estUntransmittedData and estSenderQuota. This will be helpful in case the message
+ // is padded; We will fallback on the current available window(at least a 1/4th of the limit).
+ f.delta = n
+ }
+ return f.delta
+ }
+ return 0
}
// onData is invoked when some data frame is received. It updates pendingData.
@@ -174,7 +206,7 @@ func (f *inFlow) onData(n uint32) error {
f.mu.Lock()
defer f.mu.Unlock()
f.pendingData += n
- if f.pendingData+f.pendingUpdate > f.limit {
+ if f.pendingData+f.pendingUpdate > f.limit+f.delta {
return fmt.Errorf("received %d-bytes data exceeding the limit %d bytes", f.pendingData+f.pendingUpdate, f.limit)
}
return nil
@@ -189,6 +221,13 @@ func (f *inFlow) onRead(n uint32) uint32 {
return 0
}
f.pendingData -= n
+ if n > f.delta {
+ n -= f.delta
+ f.delta = 0
+ } else {
+ f.delta -= n
+ n = 0
+ }
f.pendingUpdate += n
if f.pendingUpdate >= f.limit/4 {
wu := f.pendingUpdate
@@ -198,10 +237,10 @@ func (f *inFlow) onRead(n uint32) uint32 {
return 0
}
-func (f *inFlow) resetPendingData() uint32 {
+func (f *inFlow) resetPendingUpdate() uint32 {
f.mu.Lock()
defer f.mu.Unlock()
- n := f.pendingData
- f.pendingData = 0
+ n := f.pendingUpdate
+ f.pendingUpdate = 0
return n
}
diff --git a/vendor/google.golang.org/grpc/transport/go16.go b/vendor/google.golang.org/grpc/transport/go16.go
index ee1c46bad57..7cffee11e0b 100644
--- a/vendor/google.golang.org/grpc/transport/go16.go
+++ b/vendor/google.golang.org/grpc/transport/go16.go
@@ -1,34 +1,20 @@
// +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:
+ * Copyright 2016 gRPC authors.
*
- * * 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.
+ * 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
*
- * 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.
+ * 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.
*
*/
@@ -37,6 +23,8 @@ package transport
import (
"net"
+ "google.golang.org/grpc/codes"
+
"golang.org/x/net/context"
)
@@ -44,3 +32,14 @@ import (
func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address)
}
+
+// ContextErr converts the error from context package into a StreamError.
+func ContextErr(err error) StreamError {
+ switch err {
+ case context.DeadlineExceeded:
+ return streamErrorf(codes.DeadlineExceeded, "%v", err)
+ case context.Canceled:
+ return streamErrorf(codes.Canceled, "%v", err)
+ }
+ return streamErrorf(codes.Internal, "Unexpected error from context packet: %v", err)
+}
diff --git a/vendor/google.golang.org/grpc/transport/go17.go b/vendor/google.golang.org/grpc/transport/go17.go
index 356f13ff197..2464e69faf5 100644
--- a/vendor/google.golang.org/grpc/transport/go17.go
+++ b/vendor/google.golang.org/grpc/transport/go17.go
@@ -1,46 +1,46 @@
// +build 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:
+ * Copyright 2016 gRPC authors.
*
- * * 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.
+ * 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
*
- * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
*/
package transport
import (
+ "context"
"net"
- "golang.org/x/net/context"
+ "google.golang.org/grpc/codes"
+
+ netctx "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{}).DialContext(ctx, network, address)
}
+
+// ContextErr converts the error from context package into a StreamError.
+func ContextErr(err error) StreamError {
+ switch err {
+ case context.DeadlineExceeded, netctx.DeadlineExceeded:
+ return streamErrorf(codes.DeadlineExceeded, "%v", err)
+ case context.Canceled, netctx.Canceled:
+ return streamErrorf(codes.Canceled, "%v", err)
+ }
+ return streamErrorf(codes.Internal, "Unexpected error from context packet: %v", err)
+}
diff --git a/vendor/google.golang.org/grpc/transport/handler_server.go b/vendor/google.golang.org/grpc/transport/handler_server.go
index 24f306babbb..27372b50894 100644
--- a/vendor/google.golang.org/grpc/transport/handler_server.go
+++ b/vendor/google.golang.org/grpc/transport/handler_server.go
@@ -1,32 +1,18 @@
/*
- * 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:
+ * Copyright 2016 gRPC authors.
*
- * * 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.
+ * 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
*
- * 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.
+ * 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.
*
*/
@@ -102,15 +88,6 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request) (ServerTr
continue
}
for _, v := range vv {
- if k == "user-agent" {
- // user-agent is special. Copying logic of http_util.go.
- if i := strings.LastIndex(v, " "); i == -1 {
- // There is no application user agent string being set
- continue
- } else {
- v = v[:i]
- }
- }
v, err := decodeMetadataHeader(k, v)
if err != nil {
return nil, streamErrorf(codes.InvalidArgument, "malformed binary metadata: %v", err)
@@ -179,11 +156,18 @@ func (a strAddr) String() string { return string(a) }
// do runs fn in the ServeHTTP goroutine.
func (ht *serverHandlerTransport) do(fn func()) error {
+ // Avoid a panic writing to closed channel. Imperfect but maybe good enough.
select {
- case ht.writes <- fn:
- return nil
case <-ht.closedCh:
return ErrConnClosing
+ default:
+ select {
+ case ht.writes <- fn:
+ return nil
+ case <-ht.closedCh:
+ return ErrConnClosing
+ }
+
}
}
@@ -309,13 +293,13 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace
req := ht.req
s := &Stream{
- id: 0, // irrelevant
- windowHandler: func(int) {}, // nothing
- cancel: cancel,
- buf: newRecvBuffer(),
- st: ht,
- method: req.URL.Path,
- recvCompress: req.Header.Get("grpc-encoding"),
+ id: 0, // irrelevant
+ requestRead: func(int) {},
+ cancel: cancel,
+ buf: newRecvBuffer(),
+ st: ht,
+ method: req.URL.Path,
+ recvCompress: req.Header.Get("grpc-encoding"),
}
pr := &peer.Peer{
Addr: ht.RemoteAddr(),
@@ -326,7 +310,10 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace
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}
+ s.trReader = &transportReader{
+ reader: &recvBufferReader{ctx: s.ctx, recv: s.buf},
+ windowHandler: func(int) {},
+ }
// readerDone is closed when the Body.Read-ing goroutine exits.
readerDone := make(chan struct{})
@@ -338,11 +325,11 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace
for buf := make([]byte, readSize); ; {
n, err := req.Body.Read(buf)
if n > 0 {
- s.buf.put(&recvMsg{data: buf[:n:n]})
+ s.buf.put(recvMsg{data: buf[:n:n]})
buf = buf[n:]
}
if err != nil {
- s.buf.put(&recvMsg{err: mapRecvMsgError(err)})
+ s.buf.put(recvMsg{err: mapRecvMsgError(err)})
return
}
if len(buf) == 0 {
diff --git a/vendor/google.golang.org/grpc/transport/http2_client.go b/vendor/google.golang.org/grpc/transport/http2_client.go
index 380fff665fb..d4fc6815e31 100644
--- a/vendor/google.golang.org/grpc/transport/http2_client.go
+++ b/vendor/google.golang.org/grpc/transport/http2_client.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -48,7 +33,6 @@ import (
"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"
@@ -91,7 +75,7 @@ type http2Client struct {
// controlBuf delivers all the control related tasks (e.g., window
// updates, reset streams, and various settings) to the controller.
- controlBuf *recvBuffer
+ controlBuf *controlBuffer
fc *inFlow
// sendQuotaPool provides flow control to outbound message.
sendQuotaPool *quotaPool
@@ -101,6 +85,8 @@ type http2Client struct {
// The scheme used: https if TLS is on, http otherwise.
scheme string
+ isSecure bool
+
creds []credentials.PerRPCCredentials
// Boolean to keep track of reading activity on transport.
@@ -110,6 +96,10 @@ type http2Client struct {
statsHandler stats.Handler
+ initialWindowSize int32
+
+ bdpEst *bdpEstimator
+
mu sync.Mutex // guard the following variables
state transportState // the state of underlying connection
activeStreams map[uint32]*Stream
@@ -117,8 +107,6 @@ type http2Client struct {
maxStreams int
// the per-stream outbound flow control window size set by the peer.
streamSendQuota uint32
- // goAwayID records the Last-Stream-ID in the GoAway frame from the server.
- 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
@@ -169,9 +157,9 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) (
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(isTemporary(err), err, "transport: error while dialing: %v", err)
}
- return nil, connectionErrorf(true, err, "transport: %v", err)
+ return nil, connectionErrorf(true, err, "transport: Error while dialing %v", err)
}
// Any further errors will close the underlying connection
defer func(conn net.Conn) {
@@ -179,7 +167,10 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) (
conn.Close()
}
}(conn)
- var authInfo credentials.AuthInfo
+ var (
+ isSecure bool
+ authInfo credentials.AuthInfo
+ )
if creds := opts.TransportCredentials; creds != nil {
scheme = "https"
conn, authInfo, err = creds.ClientHandshake(ctx, addr.Addr, conn)
@@ -187,8 +178,9 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) (
// Credentials handshake errors are typically considered permanent
// to avoid retrying on e.g. bad certificates.
temp := isTemporary(err)
- return nil, connectionErrorf(temp, err, "transport: %v", err)
+ return nil, connectionErrorf(temp, err, "transport: authentication handshake failed: %v", err)
}
+ isSecure = true
}
kp := opts.KeepaliveParams
// Validate keepalive parameters.
@@ -198,6 +190,12 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) (
if kp.Timeout == 0 {
kp.Timeout = defaultClientKeepaliveTimeout
}
+ dynamicWindow := true
+ icwz := int32(initialWindowSize)
+ if opts.InitialConnWindowSize >= defaultWindowSize {
+ icwz = opts.InitialConnWindowSize
+ dynamicWindow = false
+ }
var buf bytes.Buffer
t := &http2Client{
ctx: ctx,
@@ -209,27 +207,39 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) (
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),
- controlBuf: newRecvBuffer(),
- fc: &inFlow{limit: initialConnWindowSize},
- sendQuotaPool: newQuotaPool(defaultWindowSize),
- scheme: scheme,
- state: reachable,
- activeStreams: make(map[uint32]*Stream),
- creds: opts.PerRPCCredentials,
- maxStreams: defaultMaxStreamsClient,
- streamsQuota: newQuotaPool(defaultMaxStreamsClient),
- streamSendQuota: defaultWindowSize,
- kp: kp,
- statsHandler: opts.StatsHandler,
+ 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),
+ controlBuf: newControlBuffer(),
+ fc: &inFlow{limit: uint32(icwz)},
+ sendQuotaPool: newQuotaPool(defaultWindowSize),
+ scheme: scheme,
+ state: reachable,
+ activeStreams: make(map[uint32]*Stream),
+ isSecure: isSecure,
+ creds: opts.PerRPCCredentials,
+ maxStreams: defaultMaxStreamsClient,
+ streamsQuota: newQuotaPool(defaultMaxStreamsClient),
+ streamSendQuota: defaultWindowSize,
+ kp: kp,
+ statsHandler: opts.StatsHandler,
+ initialWindowSize: initialWindowSize,
+ }
+ if opts.InitialWindowSize >= defaultWindowSize {
+ t.initialWindowSize = opts.InitialWindowSize
+ dynamicWindow = false
+ }
+ if dynamicWindow {
+ t.bdpEst = &bdpEstimator{
+ bdp: initialWindowSize,
+ updateFlowControl: t.updateFlowControl,
+ }
}
// Make sure awakenKeepalive can't be written upon.
// keepalive routine will make it writable, if need be.
@@ -252,29 +262,29 @@ func newHTTP2Client(ctx context.Context, addr TargetInfo, opts ConnectOptions) (
n, err := t.conn.Write(clientPreface)
if err != nil {
t.Close()
- return nil, connectionErrorf(true, err, "transport: %v", err)
+ return nil, connectionErrorf(true, err, "transport: failed to write client preface: %v", err)
}
if n != len(clientPreface) {
t.Close()
return nil, connectionErrorf(true, err, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface))
}
- if initialWindowSize != defaultWindowSize {
+ if t.initialWindowSize != defaultWindowSize {
err = t.framer.writeSettings(true, http2.Setting{
ID: http2.SettingInitialWindowSize,
- Val: uint32(initialWindowSize),
+ Val: uint32(t.initialWindowSize),
})
} else {
err = t.framer.writeSettings(true)
}
if err != nil {
t.Close()
- return nil, connectionErrorf(true, err, "transport: %v", err)
+ return nil, connectionErrorf(true, err, "transport: failed to write initial settings frame: %v", err)
}
// Adjust the connection flow control window if needed.
- if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
+ if delta := uint32(icwz - defaultWindowSize); delta > 0 {
if err := t.framer.writeWindowUpdate(true, 0, delta); err != nil {
t.Close()
- return nil, connectionErrorf(true, err, "transport: %v", err)
+ return nil, connectionErrorf(true, err, "transport: failed to write window update: %v", err)
}
}
go t.controller()
@@ -294,23 +304,29 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream {
method: callHdr.Method,
sendCompress: callHdr.SendCompress,
buf: newRecvBuffer(),
- fc: &inFlow{limit: initialWindowSize},
+ fc: &inFlow{limit: uint32(t.initialWindowSize)},
sendQuotaPool: newQuotaPool(int(t.streamSendQuota)),
headerChan: make(chan struct{}),
}
t.nextID += 2
- s.windowHandler = func(n int) {
- t.updateWindow(s, uint32(n))
+ s.requestRead = func(n int) {
+ t.adjustWindow(s, uint32(n))
}
// The client side stream context should have exactly the same life cycle with the user provided context.
// That means, s.ctx should be read-only. And s.ctx is done iff ctx is done.
// So we use the original context here instead of creating a copy.
s.ctx = ctx
- s.dec = &recvBufferReader{
- ctx: s.ctx,
- goAway: s.goAway,
- recv: s.buf,
+ s.trReader = &transportReader{
+ reader: &recvBufferReader{
+ ctx: s.ctx,
+ goAway: s.goAway,
+ recv: s.buf,
+ },
+ windowHandler: func(n int) {
+ t.updateWindow(s, uint32(n))
+ },
}
+
return s
}
@@ -324,10 +340,13 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
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 {
+ var (
+ authData = make(map[string]string)
+ audience string
+ )
+ // Create an audience string only if needed.
+ if len(t.creds) > 0 || callHdr.Creds != nil {
// Construct URI required to get auth request metadata.
var port string
if pos := strings.LastIndex(t.target, ":"); pos != -1 {
@@ -338,17 +357,39 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
}
pos := strings.LastIndex(callHdr.Method, "/")
if pos == -1 {
- return nil, streamErrorf(codes.InvalidArgument, "transport: malformed method name: %q", callHdr.Method)
+ pos = len(callHdr.Method)
}
- audience := "https://" + callHdr.Host + port + callHdr.Method[:pos]
+ audience = "https://" + callHdr.Host + port + callHdr.Method[:pos]
+ }
+ for _, c := range t.creds {
data, err := c.GetRequestMetadata(ctx, audience)
if err != nil {
- return nil, streamErrorf(codes.InvalidArgument, "transport: %v", err)
+ return nil, streamErrorf(codes.Internal, "transport: %v", err)
}
for k, v := range data {
+ // Capital header names are illegal in HTTP/2.
+ k = strings.ToLower(k)
authData[k] = v
}
}
+ callAuthData := make(map[string]string)
+ // Check if credentials.PerRPCCredentials were provided via call options.
+ // Note: if these credentials are provided both via dial options and call
+ // options, then both sets of credentials will be applied.
+ if callCreds := callHdr.Creds; callCreds != nil {
+ if !t.isSecure && callCreds.RequireTransportSecurity() {
+ return nil, streamErrorf(codes.Unauthenticated, "transport: cannot send secure credentials on an insecure conneciton")
+ }
+ data, err := callCreds.GetRequestMetadata(ctx, audience)
+ if err != nil {
+ return nil, streamErrorf(codes.Internal, "transport: %v", err)
+ }
+ for k, v := range data {
+ // Capital header names are illegal in HTTP/2
+ k = strings.ToLower(k)
+ callAuthData[k] = v
+ }
+ }
t.mu.Lock()
if t.activeStreams == nil {
t.mu.Unlock()
@@ -391,7 +432,6 @@ 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.
@@ -427,16 +467,15 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
}
for k, v := range authData {
- // Capital header names are illegal in HTTP/2.
- k = strings.ToLower(k)
- t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
+ t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
+ }
+ for k, v := range callAuthData {
+ t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: encodeMetadataHeader(k, v)})
}
var (
- hasMD bool
endHeaders bool
)
if md, ok := metadata.FromOutgoingContext(ctx); ok {
- hasMD = true
for k, vv := range md {
// HTTP doesn't allow you to set pseudoheaders after non pseudoheaders were set.
if isReservedHeader(k) {
@@ -468,7 +507,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
endHeaders = true
}
var flush bool
- if endHeaders && (hasMD || callHdr.Flush) {
+ if callHdr.Flush && endHeaders {
flush = true
}
if first {
@@ -493,7 +532,9 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
return nil, connectionErrorf(true, err, "transport: %v", err)
}
}
+ s.mu.Lock()
s.bytesSent = true
+ s.mu.Unlock()
if t.statsHandler != nil {
outHeader := &stats.OutHeader{
@@ -504,7 +545,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
LocalAddr: t.localAddr,
Compression: callHdr.SendCompress,
}
- t.statsHandler.HandleRPC(s.clientStatsCtx, outHeader)
+ t.statsHandler.HandleRPC(s.ctx, outHeader)
}
t.writableChan <- 0
return s, nil
@@ -518,6 +559,10 @@ func (t *http2Client) CloseStream(s *Stream, err error) {
t.mu.Unlock()
return
}
+ if err != nil {
+ // notify in-flight streams, before the deletion
+ s.write(recvMsg{err: err})
+ }
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.
@@ -547,11 +592,6 @@ func (t *http2Client) CloseStream(s *Stream, err error) {
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})
- }
- }
if s.state == streamDone {
s.mu.Unlock()
return
@@ -620,24 +660,6 @@ func (t *http2Client) GracefulClose() error {
t.mu.Unlock()
return nil
}
- // Notify the streams which were initiated after the server sent GOAWAY.
- select {
- case <-t.goAway:
- n := t.prevGoAwayID
- if n == 0 && t.nextID > 1 {
- n = t.nextID - 2
- }
- m := t.goAwayID + 2
- if m == 2 {
- m = 1
- }
- for i := m; i <= n; i += 2 {
- if s, ok := t.activeStreams[i]; ok {
- close(s.goAway)
- }
- }
- default:
- }
if t.state == draining {
t.mu.Unlock()
return nil
@@ -760,6 +782,24 @@ func (t *http2Client) getStream(f http2.Frame) (*Stream, bool) {
return s, ok
}
+// adjustWindow sends out extra window update over the initial window size
+// of stream if the application is requesting data larger in size than
+// the window.
+func (t *http2Client) adjustWindow(s *Stream, n uint32) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.state == streamDone {
+ return
+ }
+ if w := s.fc.maybeAdjust(n); w > 0 {
+ // Piggyback conneciton's window update along.
+ if cw := t.fc.resetPendingUpdate(); cw > 0 {
+ t.controlBuf.put(&windowUpdate{0, cw, false})
+ }
+ t.controlBuf.put(&windowUpdate{s.id, w, true})
+ }
+}
+
// updateWindow adjusts the inbound quota for the stream and the transport.
// Window updates will deliver to the controller for sending when
// the cumulative quota exceeds the corresponding threshold.
@@ -769,41 +809,74 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) {
if s.state == streamDone {
return
}
- if w := t.fc.onRead(n); w > 0 {
- t.controlBuf.put(&windowUpdate{0, w})
- }
if w := s.fc.onRead(n); w > 0 {
- t.controlBuf.put(&windowUpdate{s.id, w})
+ if cw := t.fc.resetPendingUpdate(); cw > 0 {
+ t.controlBuf.put(&windowUpdate{0, cw, false})
+ }
+ t.controlBuf.put(&windowUpdate{s.id, w, true})
}
}
+// updateFlowControl updates the incoming flow control windows
+// for the transport and the stream based on the current bdp
+// estimation.
+func (t *http2Client) updateFlowControl(n uint32) {
+ t.mu.Lock()
+ for _, s := range t.activeStreams {
+ s.fc.newLimit(n)
+ }
+ t.initialWindowSize = int32(n)
+ t.mu.Unlock()
+ t.controlBuf.put(&windowUpdate{0, t.fc.newLimit(n), false})
+ t.controlBuf.put(&settings{
+ ack: false,
+ ss: []http2.Setting{
+ {
+ ID: http2.SettingInitialWindowSize,
+ Val: uint32(n),
+ },
+ },
+ })
+}
+
func (t *http2Client) handleData(f *http2.DataFrame) {
size := f.Header().Length
- if err := t.fc.onData(uint32(size)); err != nil {
- t.notifyError(connectionErrorf(true, err, "%v", err))
- return
+ var sendBDPPing bool
+ if t.bdpEst != nil {
+ sendBDPPing = t.bdpEst.add(uint32(size))
+ }
+ // Decouple connection's flow control from application's read.
+ // An update on connection's flow control should not depend on
+ // whether user application has read the data or not. Such a
+ // restriction is already imposed on the stream's flow control,
+ // and therefore the sender will be blocked anyways.
+ // Decoupling the connection flow control will prevent other
+ // active(fast) streams from starving in presence of slow or
+ // inactive streams.
+ //
+ // Furthermore, if a bdpPing is being sent out we can piggyback
+ // connection's window update for the bytes we just received.
+ if sendBDPPing {
+ t.controlBuf.put(&windowUpdate{0, uint32(size), false})
+ t.controlBuf.put(bdpPing)
+ } else {
+ if err := t.fc.onData(uint32(size)); err != nil {
+ t.notifyError(connectionErrorf(true, err, "%v", err))
+ return
+ }
+ if w := t.fc.onRead(uint32(size)); w > 0 {
+ t.controlBuf.put(&windowUpdate{0, w, true})
+ }
}
// Select the right stream to dispatch.
s, ok := t.getStream(f)
if !ok {
- if w := t.fc.onRead(uint32(size)); w > 0 {
- t.controlBuf.put(&windowUpdate{0, w})
- }
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()
- // The stream has been closed. Release the corresponding quota.
- if w := t.fc.onRead(uint32(size)); w > 0 {
- t.controlBuf.put(&windowUpdate{0, w})
- }
return
}
if err := s.fc.onData(uint32(size)); err != nil {
@@ -816,7 +889,7 @@ func (t *http2Client) handleData(f *http2.DataFrame) {
}
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})
+ t.controlBuf.put(&windowUpdate{s.id, w, true})
}
}
s.mu.Unlock()
@@ -859,7 +932,7 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
}
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)
+ warningf("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error %v", f.ErrCode)
statusCode = codes.Unknown
}
s.finish(status.Newf(statusCode, "stream terminated by RST_STREAM with error code: %d", f.ErrCode))
@@ -881,7 +954,11 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame) {
}
func (t *http2Client) handlePing(f *http2.PingFrame) {
- if f.IsAck() { // Do nothing.
+ if f.IsAck() {
+ // Maybe it's a BDP ping.
+ if t.bdpEst != nil {
+ t.bdpEst.calculate(f.Data)
+ }
return
}
pingAck := &ping{ack: true}
@@ -890,36 +967,56 @@ 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 {
- t.mu.Unlock()
- t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: stream ID %d is even", f.LastStreamID))
- return
- }
- select {
- case <-t.goAway:
- id := t.goAwayID
- // t.goAway has been closed (i.e.,multiple GoAways).
- if id < f.LastStreamID {
- t.mu.Unlock()
- t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: previously recv GOAWAY frame with LastStramID %d, currently recv %d", id, f.LastStreamID))
- return
- }
- t.prevGoAwayID = id
- t.goAwayID = f.LastStreamID
- t.mu.Unlock()
- return
- default:
- t.setGoAwayReason(f)
- }
- t.goAwayID = f.LastStreamID
- close(t.goAway)
+ if t.state != reachable && t.state != draining {
+ t.mu.Unlock()
+ return
}
+ if f.ErrCode == http2.ErrCodeEnhanceYourCalm {
+ infof("Client received GoAway with http2.ErrCodeEnhanceYourCalm.")
+ }
+ id := f.LastStreamID
+ if id > 0 && id%2 != 1 {
+ t.mu.Unlock()
+ t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: stream ID %d is even", f.LastStreamID))
+ return
+ }
+ // A client can recieve multiple GoAways from server (look at https://github.com/grpc/grpc-go/issues/1387).
+ // The idea is that the first GoAway will be sent with an ID of MaxInt32 and the second GoAway will be sent after an RTT delay
+ // with the ID of the last stream the server will process.
+ // Therefore, when we get the first GoAway we don't really close any streams. While in case of second GoAway we
+ // close all streams created after the second GoAwayId. This way streams that were in-flight while the GoAway from server
+ // was being sent don't get killed.
+ select {
+ case <-t.goAway: // t.goAway has been closed (i.e.,multiple GoAways).
+ // If there are multiple GoAways the first one should always have an ID greater than the following ones.
+ if id > t.prevGoAwayID {
+ t.mu.Unlock()
+ t.notifyError(connectionErrorf(true, nil, "received illegal http2 GOAWAY frame: previously recv GOAWAY frame with LastStramID %d, currently recv %d", id, f.LastStreamID))
+ return
+ }
+ default:
+ t.setGoAwayReason(f)
+ close(t.goAway)
+ t.state = draining
+ }
+ // All streams with IDs greater than the GoAwayId
+ // and smaller than the previous GoAway ID should be killed.
+ upperLimit := t.prevGoAwayID
+ if upperLimit == 0 { // This is the first GoAway Frame.
+ upperLimit = math.MaxUint32 // Kill all streams after the GoAway ID.
+ }
+ for streamID, stream := range t.activeStreams {
+ if streamID > id && streamID <= upperLimit {
+ close(stream.goAway)
+ }
+ }
+ t.prevGoAwayID = id
+ active := len(t.activeStreams)
t.mu.Unlock()
+ if active == 0 {
+ t.Close()
+ }
}
// setGoAwayReason sets the value of t.goAwayReason based
@@ -960,20 +1057,20 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
if !ok {
return
}
+ s.mu.Lock()
s.bytesReceived = true
+ s.mu.Unlock()
var state decodeState
- for _, hf := range frame.Fields {
- 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
+ if err := state.decodeResponseHeader(frame); 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
}
endStream := frame.StreamEnded()
@@ -985,13 +1082,13 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
Client: true,
WireLength: int(frame.Header().Length),
}
- t.statsHandler.HandleRPC(s.clientStatsCtx, inHeader)
+ t.statsHandler.HandleRPC(s.ctx, inHeader)
} else {
inTrailer := &stats.InTrailer{
Client: true,
WireLength: int(frame.Header().Length),
}
- t.statsHandler.HandleRPC(s.clientStatsCtx, inTrailer)
+ t.statsHandler.HandleRPC(s.ctx, inTrailer)
}
}
}()
@@ -1091,7 +1188,7 @@ func (t *http2Client) reader() {
case *http2.WindowUpdateFrame:
t.handleWindowUpdate(frame)
default:
- grpclog.Printf("transport: http2Client.reader got unhandled frame type %v.", frame)
+ errorf("transport: http2Client.reader got unhandled frame type %v.", frame)
}
}
}
@@ -1115,7 +1212,7 @@ func (t *http2Client) applySettings(ss []http2.Setting) {
t.mu.Lock()
for _, stream := range t.activeStreams {
// Adjust the sending quota for each stream.
- stream.sendQuotaPool.add(int(s.Val - t.streamSendQuota))
+ stream.sendQuotaPool.add(int(s.Val) - int(t.streamSendQuota))
}
t.streamSendQuota = s.Val
t.mu.Unlock()
@@ -1134,7 +1231,7 @@ func (t *http2Client) controller() {
case <-t.writableChan:
switch i := i.(type) {
case *windowUpdate:
- t.framer.writeWindowUpdate(true, i.streamID, i.increment)
+ t.framer.writeWindowUpdate(i.flush, i.streamID, i.increment)
case *settings:
if i.ack {
t.framer.writeSettingsAck(true)
@@ -1153,9 +1250,12 @@ func (t *http2Client) controller() {
case *flushIO:
t.framer.flushWrite()
case *ping:
+ if !i.ack {
+ t.bdpEst.timesnap(i.data)
+ }
t.framer.writePing(true, i.ack, i.data)
default:
- grpclog.Printf("transport: http2Client.controller got unexpected item type %v\n", i)
+ errorf("transport: http2Client.controller got unexpected item type %v\n", i)
}
t.writableChan <- 0
continue
@@ -1242,7 +1342,7 @@ func (t *http2Client) notifyError(err error) {
if t.state == reachable {
t.state = unreachable
close(t.errorChan)
- grpclog.Printf("transport: http2Client.notifyError got notified that the client transport was broken %v.", err)
+ infof("transport: http2Client.notifyError got notified that the client transport was broken %v.", err)
}
t.mu.Unlock()
}
diff --git a/vendor/google.golang.org/grpc/transport/http2_server.go b/vendor/google.golang.org/grpc/transport/http2_server.go
index 14cd19c64c6..92ab4d9c3f8 100644
--- a/vendor/google.golang.org/grpc/transport/http2_server.go
+++ b/vendor/google.golang.org/grpc/transport/http2_server.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -51,7 +36,6 @@ import (
"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"
@@ -84,18 +68,15 @@ type http2Server struct {
framer *framer
hBuf *bytes.Buffer // the buffer for HPACK encoding
hEnc *hpack.Encoder // HPACK encoder
-
// The max number of concurrent streams.
maxStreams uint32
// controlBuf delivers all the control related tasks (e.g., window
// updates, reset streams, and various settings) to the controller.
- controlBuf *recvBuffer
+ controlBuf *controlBuffer
fc *inFlow
// sendQuotaPool provides flow control to outbound message.
sendQuotaPool *quotaPool
-
- stats stats.Handler
-
+ stats stats.Handler
// Flag to keep track of reading activity on transport.
// 1 is true and 0 is false.
activity uint32 // Accessed atomically.
@@ -111,9 +92,19 @@ type http2Server struct {
// 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.
+ resetPingStrikes uint32 // Accessed atomically.
+ initialWindowSize int32
+ bdpEst *bdpEstimator
- mu sync.Mutex // guard the following
+ mu sync.Mutex // guard the following
+
+ // drainChan is initialized when drain(...) is called the first time.
+ // After which the server writes out the first GoAway(with ID 2^31-1) frame.
+ // Then an independent goroutine will be launched to later send the second GoAway.
+ // During this time we don't want to write another first GoAway(with ID 2^31 -1) frame.
+ // Thus call to drain(...) will be a no-op if drainChan is already initialized since draining is
+ // already underway.
+ drainChan chan struct{}
state transportState
activeStreams map[uint32]*Stream
// the per-stream outbound flow control window size set by the peer.
@@ -130,28 +121,39 @@ type http2Server struct {
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
+ var isettings []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 {
- settings = append(settings, http2.Setting{
+ isettings = append(isettings, http2.Setting{
ID: http2.SettingMaxConcurrentStreams,
Val: maxStreams,
})
}
- if initialWindowSize != defaultWindowSize {
- settings = append(settings, http2.Setting{
- ID: http2.SettingInitialWindowSize,
- Val: uint32(initialWindowSize)})
+ dynamicWindow := true
+ iwz := int32(initialWindowSize)
+ if config.InitialWindowSize >= defaultWindowSize {
+ iwz = config.InitialWindowSize
+ dynamicWindow = false
}
- if err := framer.writeSettings(true, settings...); err != nil {
+ icwz := int32(initialWindowSize)
+ if config.InitialConnWindowSize >= defaultWindowSize {
+ icwz = config.InitialConnWindowSize
+ dynamicWindow = false
+ }
+ if iwz != defaultWindowSize {
+ isettings = append(isettings, http2.Setting{
+ ID: http2.SettingInitialWindowSize,
+ Val: uint32(iwz)})
+ }
+ if err := framer.writeSettings(true, isettings...); err != nil {
return nil, connectionErrorf(true, err, "transport: %v", err)
}
// Adjust the connection flow control window if needed.
- if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
+ if delta := uint32(icwz - defaultWindowSize); delta > 0 {
if err := framer.writeWindowUpdate(true, 0, delta); err != nil {
return nil, connectionErrorf(true, err, "transport: %v", err)
}
@@ -180,28 +182,35 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err
}
var buf bytes.Buffer
t := &http2Server{
- ctx: context.Background(),
- conn: conn,
- 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),
- state: reachable,
- writableChan: make(chan int, 1),
- shutdownChan: make(chan struct{}),
- activeStreams: make(map[uint32]*Stream),
- streamSendQuota: defaultWindowSize,
- stats: config.StatsHandler,
- kp: kp,
- idle: time.Now(),
- kep: kep,
+ ctx: context.Background(),
+ conn: conn,
+ remoteAddr: conn.RemoteAddr(),
+ localAddr: conn.LocalAddr(),
+ authInfo: config.AuthInfo,
+ framer: framer,
+ hBuf: &buf,
+ hEnc: hpack.NewEncoder(&buf),
+ maxStreams: maxStreams,
+ inTapHandle: config.InTapHandle,
+ controlBuf: newControlBuffer(),
+ fc: &inFlow{limit: uint32(icwz)},
+ sendQuotaPool: newQuotaPool(defaultWindowSize),
+ state: reachable,
+ writableChan: make(chan int, 1),
+ shutdownChan: make(chan struct{}),
+ activeStreams: make(map[uint32]*Stream),
+ streamSendQuota: defaultWindowSize,
+ stats: config.StatsHandler,
+ kp: kp,
+ idle: time.Now(),
+ kep: kep,
+ initialWindowSize: iwz,
+ }
+ if dynamicWindow {
+ t.bdpEst = &bdpEstimator{
+ bdp: initialWindowSize,
+ updateFlowControl: t.updateFlowControl,
+ }
}
if t.stats != nil {
t.ctx = t.stats.TagConn(t.ctx, &stats.ConnTagInfo{
@@ -224,7 +233,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
id: frame.Header().StreamID,
st: t,
buf: buf,
- fc: &inFlow{limit: initialWindowSize},
+ fc: &inFlow{limit: uint32(t.initialWindowSize)},
}
var state decodeState
@@ -263,10 +272,14 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
if len(state.mdata) > 0 {
s.ctx = metadata.NewIncomingContext(s.ctx, state.mdata)
}
-
- s.dec = &recvBufferReader{
- ctx: s.ctx,
- recv: s.buf,
+ s.trReader = &transportReader{
+ reader: &recvBufferReader{
+ ctx: s.ctx,
+ recv: s.buf,
+ },
+ windowHandler: func(n int) {
+ t.updateWindow(s, uint32(n))
+ },
}
s.recvCompress = state.encoding
s.method = state.method
@@ -277,7 +290,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
}
s.ctx, err = t.inTapHandle(s.ctx, info)
if err != nil {
- // TODO: Log the real error.
+ warningf("transport: http2Server.operateHeaders got an error from InTapHandle: %v", err)
t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream})
return
}
@@ -295,7 +308,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
if s.id%2 != 1 || s.id <= t.maxStreamID {
t.mu.Unlock()
// illegal gRPC stream id.
- grpclog.Println("transport: http2Server.HandleStreams received an illegal stream id: ", s.id)
+ errorf("transport: http2Server.HandleStreams received an illegal stream id: %v", s.id)
return true
}
t.maxStreamID = s.id
@@ -305,8 +318,8 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
t.idle = time.Time{}
}
t.mu.Unlock()
- s.windowHandler = func(n int) {
- t.updateWindow(s, uint32(n))
+ s.requestRead = func(n int) {
+ t.adjustWindow(s, uint32(n))
}
s.ctx = traceCtx(s.ctx, s.method)
if t.stats != nil {
@@ -331,12 +344,15 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
// Check the validity of client preface.
preface := make([]byte, len(clientPreface))
if _, err := io.ReadFull(t.conn, preface); err != nil {
- grpclog.Printf("transport: http2Server.HandleStreams failed to receive the preface from client: %v", err)
+ // Only log if it isn't a simple tcp accept check (ie: tcp balancer doing open/close socket)
+ if err != io.EOF {
+ errorf("transport: http2Server.HandleStreams failed to receive the preface from client: %v", err)
+ }
t.Close()
return
}
if !bytes.Equal(preface, clientPreface) {
- grpclog.Printf("transport: http2Server.HandleStreams received bogus greeting from client: %q", preface)
+ errorf("transport: http2Server.HandleStreams received bogus greeting from client: %q", preface)
t.Close()
return
}
@@ -347,14 +363,14 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
return
}
if err != nil {
- grpclog.Printf("transport: http2Server.HandleStreams failed to read frame: %v", err)
+ errorf("transport: http2Server.HandleStreams failed to read initial settings frame: %v", err)
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)
+ errorf("transport: http2Server.HandleStreams saw invalid preface type %T from client", frame)
t.Close()
return
}
@@ -378,7 +394,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
t.Close()
return
}
- grpclog.Printf("transport: http2Server.HandleStreams failed to read frame: %v", err)
+ warningf("transport: http2Server.HandleStreams failed to read frame: %v", err)
t.Close()
return
}
@@ -401,7 +417,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
case *http2.GoAwayFrame:
// TODO: Handle GoAway from the client appropriately.
default:
- grpclog.Printf("transport: http2Server.HandleStreams found unhandled frame type %v.", frame)
+ errorf("transport: http2Server.HandleStreams found unhandled frame type %v.", frame)
}
}
}
@@ -421,6 +437,23 @@ func (t *http2Server) getStream(f http2.Frame) (*Stream, bool) {
return s, true
}
+// adjustWindow sends out extra window update over the initial window size
+// of stream if the application is requesting data larger in size than
+// the window.
+func (t *http2Server) adjustWindow(s *Stream, n uint32) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.state == streamDone {
+ return
+ }
+ if w := s.fc.maybeAdjust(n); w > 0 {
+ if cw := t.fc.resetPendingUpdate(); cw > 0 {
+ t.controlBuf.put(&windowUpdate{0, cw, false})
+ }
+ t.controlBuf.put(&windowUpdate{s.id, w, true})
+ }
+}
+
// updateWindow adjusts the inbound quota for the stream and the transport.
// Window updates will deliver to the controller for sending when
// the cumulative quota exceeds the corresponding threshold.
@@ -430,42 +463,76 @@ func (t *http2Server) updateWindow(s *Stream, n uint32) {
if s.state == streamDone {
return
}
- if w := t.fc.onRead(n); w > 0 {
- t.controlBuf.put(&windowUpdate{0, w})
- }
if w := s.fc.onRead(n); w > 0 {
- t.controlBuf.put(&windowUpdate{s.id, w})
+ if cw := t.fc.resetPendingUpdate(); cw > 0 {
+ t.controlBuf.put(&windowUpdate{0, cw, false})
+ }
+ t.controlBuf.put(&windowUpdate{s.id, w, true})
}
}
+// updateFlowControl updates the incoming flow control windows
+// for the transport and the stream based on the current bdp
+// estimation.
+func (t *http2Server) updateFlowControl(n uint32) {
+ t.mu.Lock()
+ for _, s := range t.activeStreams {
+ s.fc.newLimit(n)
+ }
+ t.initialWindowSize = int32(n)
+ t.mu.Unlock()
+ t.controlBuf.put(&windowUpdate{0, t.fc.newLimit(n), false})
+ t.controlBuf.put(&settings{
+ ack: false,
+ ss: []http2.Setting{
+ {
+ ID: http2.SettingInitialWindowSize,
+ Val: uint32(n),
+ },
+ },
+ })
+
+}
+
func (t *http2Server) handleData(f *http2.DataFrame) {
size := f.Header().Length
- if err := t.fc.onData(uint32(size)); err != nil {
- grpclog.Printf("transport: http2Server %v", err)
- t.Close()
- return
+ var sendBDPPing bool
+ if t.bdpEst != nil {
+ sendBDPPing = t.bdpEst.add(uint32(size))
+ }
+ // Decouple connection's flow control from application's read.
+ // An update on connection's flow control should not depend on
+ // whether user application has read the data or not. Such a
+ // restriction is already imposed on the stream's flow control,
+ // and therefore the sender will be blocked anyways.
+ // Decoupling the connection flow control will prevent other
+ // active(fast) streams from starving in presence of slow or
+ // inactive streams.
+ //
+ // Furthermore, if a bdpPing is being sent out we can piggyback
+ // connection's window update for the bytes we just received.
+ if sendBDPPing {
+ t.controlBuf.put(&windowUpdate{0, uint32(size), false})
+ t.controlBuf.put(bdpPing)
+ } else {
+ if err := t.fc.onData(uint32(size)); err != nil {
+ errorf("transport: http2Server %v", err)
+ t.Close()
+ return
+ }
+ if w := t.fc.onRead(uint32(size)); w > 0 {
+ t.controlBuf.put(&windowUpdate{0, w, true})
+ }
}
// Select the right stream to dispatch.
s, ok := t.getStream(f)
if !ok {
- if w := t.fc.onRead(uint32(size)); w > 0 {
- t.controlBuf.put(&windowUpdate{0, w})
- }
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()
- // The stream has been closed. Release the corresponding quota.
- if w := t.fc.onRead(uint32(size)); w > 0 {
- t.controlBuf.put(&windowUpdate{0, w})
- }
return
}
if err := s.fc.onData(uint32(size)); err != nil {
@@ -476,7 +543,7 @@ func (t *http2Server) handleData(f *http2.DataFrame) {
}
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})
+ t.controlBuf.put(&windowUpdate{s.id, w, true})
}
}
s.mu.Unlock()
@@ -527,7 +594,15 @@ const (
)
func (t *http2Server) handlePing(f *http2.PingFrame) {
- if f.IsAck() { // Do nothing.
+ if f.IsAck() {
+ if f.Data == goAwayPing.data && t.drainChan != nil {
+ close(t.drainChan)
+ return
+ }
+ // Maybe it's a BDP ping.
+ if t.bdpEst != nil {
+ t.bdpEst.calculate(f.Data)
+ }
return
}
pingAck := &ping{ack: true}
@@ -563,7 +638,7 @@ func (t *http2Server) handlePing(f *http2.PingFrame) {
if t.pingStrikes > maxPingStrikes {
// Send goaway and close the connection.
- t.controlBuf.put(&goAway{code: http2.ErrCodeEnhanceYourCalm, debugData: []byte("too_many_pings")})
+ t.controlBuf.put(&goAway{code: http2.ErrCodeEnhanceYourCalm, debugData: []byte("too_many_pings"), closeConn: true})
}
}
@@ -759,13 +834,6 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) (err 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 {
@@ -829,6 +897,9 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) (err error) {
if r.Len() == 0 && t.framer.adjustNumWriters(0) == 1 && !opts.Last {
forceFlush = true
}
+ // Reset ping strikes when sending data since this might cause
+ // the peer to send ping.
+ atomic.StoreUint32(&t.resetPingStrikes, 1)
if err := t.framer.writeData(forceFlush, s.id, false, p); err != nil {
t.Close()
return connectionErrorf(true, err, "transport: %v", err)
@@ -847,7 +918,7 @@ func (t *http2Server) applySettings(ss []http2.Setting) {
t.mu.Lock()
defer t.mu.Unlock()
for _, stream := range t.activeStreams {
- stream.sendQuotaPool.add(int(s.Val - t.streamSendQuota))
+ stream.sendQuotaPool.add(int(s.Val) - int(t.streamSendQuota))
}
t.streamSendQuota = s.Val
}
@@ -892,23 +963,18 @@ func (t *http2Server) keepalive() {
continue
}
val := t.kp.MaxConnectionIdle - time.Since(idle)
+ t.mu.Unlock()
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()
+ t.drain(http2.ErrCodeNo, []byte{})
// 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()
+ t.drain(http2.ErrCodeNo, []byte{})
maxAge.Reset(t.kp.MaxConnectionAgeGrace)
select {
case <-maxAge.C:
@@ -940,6 +1006,8 @@ func (t *http2Server) keepalive() {
}
}
+var goAwayPing = &ping{data: [8]byte{1, 6, 1, 8, 0, 3, 3, 9}}
+
// 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() {
@@ -951,7 +1019,7 @@ func (t *http2Server) controller() {
case <-t.writableChan:
switch i := i.(type) {
case *windowUpdate:
- t.framer.writeWindowUpdate(true, i.streamID, i.increment)
+ t.framer.writeWindowUpdate(i.flush, i.streamID, i.increment)
case *settings:
if i.ack {
t.framer.writeSettingsAck(true)
@@ -969,18 +1037,47 @@ func (t *http2Server) controller() {
return
}
sid := t.maxStreamID
- t.state = draining
- t.mu.Unlock()
- t.framer.writeGoAway(true, sid, i.code, i.debugData)
- if i.code == http2.ErrCodeEnhanceYourCalm {
- t.Close()
+ if !i.headsUp {
+ // Stop accepting more streams now.
+ t.state = draining
+ t.mu.Unlock()
+ t.framer.writeGoAway(true, sid, i.code, i.debugData)
+ if i.closeConn {
+ // Abruptly close the connection following the GoAway.
+ t.Close()
+ }
+ t.writableChan <- 0
+ continue
}
+ t.mu.Unlock()
+ // For a graceful close, send out a GoAway with stream ID of MaxUInt32,
+ // Follow that with a ping and wait for the ack to come back or a timer
+ // to expire. During this time accept new streams since they might have
+ // originated before the GoAway reaches the client.
+ // After getting the ack or timer expiration send out another GoAway this
+ // time with an ID of the max stream server intends to process.
+ t.framer.writeGoAway(true, math.MaxUint32, http2.ErrCodeNo, []byte{})
+ t.framer.writePing(true, false, goAwayPing.data)
+ go func() {
+ timer := time.NewTimer(time.Minute)
+ defer timer.Stop()
+ select {
+ case <-t.drainChan:
+ case <-timer.C:
+ case <-t.shutdownChan:
+ return
+ }
+ t.controlBuf.put(&goAway{code: i.code, debugData: i.debugData})
+ }()
case *flushIO:
t.framer.flushWrite()
case *ping:
+ if !i.ack {
+ t.bdpEst.timesnap(i.data)
+ }
t.framer.writePing(true, i.ack, i.data)
default:
- grpclog.Printf("transport: http2Server.controller got unexpected item type %v\n", i)
+ errorf("transport: http2Server.controller got unexpected item type %v\n", i)
}
t.writableChan <- 0
continue
@@ -1036,11 +1133,6 @@ func (t *http2Server) closeStream(s *Stream) {
// called to interrupt the potential blocking on other goroutines.
s.cancel()
s.mu.Lock()
- if q := s.fc.resetPendingData(); q > 0 {
- if w := t.fc.onRead(q); w > 0 {
- t.controlBuf.put(&windowUpdate{0, w})
- }
- }
if s.state == streamDone {
s.mu.Unlock()
return
@@ -1054,7 +1146,17 @@ func (t *http2Server) RemoteAddr() net.Addr {
}
func (t *http2Server) Drain() {
- t.controlBuf.put(&goAway{code: http2.ErrCodeNo})
+ t.drain(http2.ErrCodeNo, []byte{})
+}
+
+func (t *http2Server) drain(code http2.ErrCode, debugData []byte) {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ if t.drainChan != nil {
+ return
+ }
+ t.drainChan = make(chan struct{})
+ t.controlBuf.put(&goAway{code: code, debugData: debugData, headsUp: true})
}
var rgen = rand.New(rand.NewSource(time.Now().UnixNano()))
diff --git a/vendor/google.golang.org/grpc/transport/http_util.go b/vendor/google.golang.org/grpc/transport/http_util.go
index 795d5d18a4f..685c6fbf967 100644
--- a/vendor/google.golang.org/grpc/transport/http_util.go
+++ b/vendor/google.golang.org/grpc/transport/http_util.go
@@ -1,33 +1,18 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * 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.
*
*/
@@ -40,6 +25,7 @@ import (
"fmt"
"io"
"net"
+ "net/http"
"strconv"
"strings"
"sync/atomic"
@@ -50,7 +36,6 @@ import (
"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/status"
)
@@ -88,6 +73,24 @@ var (
codes.ResourceExhausted: http2.ErrCodeEnhanceYourCalm,
codes.PermissionDenied: http2.ErrCodeInadequateSecurity,
}
+ httpStatusConvTab = map[int]codes.Code{
+ // 400 Bad Request - INTERNAL.
+ http.StatusBadRequest: codes.Internal,
+ // 401 Unauthorized - UNAUTHENTICATED.
+ http.StatusUnauthorized: codes.Unauthenticated,
+ // 403 Forbidden - PERMISSION_DENIED.
+ http.StatusForbidden: codes.PermissionDenied,
+ // 404 Not Found - UNIMPLEMENTED.
+ http.StatusNotFound: codes.Unimplemented,
+ // 429 Too Many Requests - UNAVAILABLE.
+ http.StatusTooManyRequests: codes.Unavailable,
+ // 502 Bad Gateway - UNAVAILABLE.
+ http.StatusBadGateway: codes.Unavailable,
+ // 503 Service Unavailable - UNAVAILABLE.
+ http.StatusServiceUnavailable: codes.Unavailable,
+ // 504 Gateway timeout - UNAVAILABLE.
+ http.StatusGatewayTimeout: codes.Unavailable,
+ }
)
// Records the states during HPACK decoding. Must be reset once the
@@ -100,8 +103,9 @@ type decodeState struct {
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
+ rawStatusCode *int
rawStatusMsg string
+ httpStatus *int
// Server side only fields.
timeoutSet bool
timeout time.Duration
@@ -159,7 +163,7 @@ func validContentType(t string) bool {
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)
+ d.statusGen = status.New(codes.Code(int32(*(d.rawStatusCode))), d.rawStatusMsg)
}
return d.statusGen
}
@@ -193,6 +197,44 @@ func decodeMetadataHeader(k, v string) (string, error) {
return v, nil
}
+func (d *decodeState) decodeResponseHeader(frame *http2.MetaHeadersFrame) error {
+ for _, hf := range frame.Fields {
+ if err := d.processHeaderField(hf); err != nil {
+ return err
+ }
+ }
+
+ // If grpc status exists, no need to check further.
+ if d.rawStatusCode != nil || d.statusGen != nil {
+ return nil
+ }
+
+ // If grpc status doesn't exist and http status doesn't exist,
+ // then it's a malformed header.
+ if d.httpStatus == nil {
+ return streamErrorf(codes.Internal, "malformed header: doesn't contain status(gRPC or HTTP)")
+ }
+
+ if *(d.httpStatus) != http.StatusOK {
+ code, ok := httpStatusConvTab[*(d.httpStatus)]
+ if !ok {
+ code = codes.Unknown
+ }
+ return streamErrorf(code, http.StatusText(*(d.httpStatus)))
+ }
+
+ // gRPC status doesn't exist and http status is OK.
+ // Set rawStatusCode to be unknown and return nil error.
+ // So that, if the stream has ended this Unknown status
+ // will be propogated to the user.
+ // Otherwise, it will be ignored. In which case, status from
+ // a later trailer, that has StreamEnded flag set, is propogated.
+ code := int(codes.Unknown)
+ d.rawStatusCode = &code
+ return nil
+
+}
+
func (d *decodeState) processHeaderField(f hpack.HeaderField) error {
switch f.Name {
case "content-type":
@@ -206,7 +248,7 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) error {
if err != nil {
return streamErrorf(codes.Internal, "transport: malformed grpc-status: %v", err)
}
- d.rawStatusCode = int32(code)
+ d.rawStatusCode = &code
case "grpc-message":
d.rawStatusMsg = decodeGrpcMessage(f.Value)
case "grpc-status-details-bin":
@@ -227,6 +269,12 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) error {
}
case ":path":
d.method = f.Value
+ case ":status":
+ code, err := strconv.Atoi(f.Value)
+ if err != nil {
+ return streamErrorf(codes.Internal, "transport: malformed http-status: %v", err)
+ }
+ d.httpStatus = &code
default:
if !isReservedHeader(f.Name) || isWhitelistedPseudoHeader(f.Name) {
if d.mdata == nil {
@@ -234,7 +282,7 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) error {
}
v, err := decodeMetadataHeader(f.Name, f.Value)
if err != nil {
- grpclog.Printf("Failed to decode (%q, %q): %v", f.Name, f.Value, err)
+ errorf("Failed to decode metadata header (%q, %q): %v", f.Name, f.Value, err)
return nil
}
d.mdata[f.Name] = append(d.mdata[f.Name], v)
diff --git a/vendor/google.golang.org/grpc/transport/log.go b/vendor/google.golang.org/grpc/transport/log.go
new file mode 100644
index 00000000000..ac8e358c5c8
--- /dev/null
+++ b/vendor/google.golang.org/grpc/transport/log.go
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// This file contains wrappers for grpclog functions.
+// The transport package only logs to verbose level 2 by default.
+
+package transport
+
+import "google.golang.org/grpc/grpclog"
+
+const logLevel = 2
+
+func infof(format string, args ...interface{}) {
+ if grpclog.V(logLevel) {
+ grpclog.Infof(format, args...)
+ }
+}
+
+func warningf(format string, args ...interface{}) {
+ if grpclog.V(logLevel) {
+ grpclog.Warningf(format, args...)
+ }
+}
+
+func errorf(format string, args ...interface{}) {
+ if grpclog.V(logLevel) {
+ grpclog.Errorf(format, args...)
+ }
+}
+
+func fatalf(format string, args ...interface{}) {
+ if grpclog.V(logLevel) {
+ grpclog.Fatalf(format, args...)
+ }
+}
diff --git a/vendor/google.golang.org/grpc/transport/transport.go b/vendor/google.golang.org/grpc/transport/transport.go
index 87dc27e5bba..6dc63e4539a 100644
--- a/vendor/google.golang.org/grpc/transport/transport.go
+++ b/vendor/google.golang.org/grpc/transport/transport.go
@@ -1,44 +1,26 @@
/*
*
- * Copyright 2014, Google Inc.
- * All rights reserved.
+ * Copyright 2014 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * 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
*
- * * 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.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
*/
-/*
-Package transport defines and implements message oriented communication channel
-to complete various transactions (e.g., an RPC).
-*/
+// Package transport defines and implements message oriented communication
+// channel to complete various transactions (e.g., an RPC).
package transport
import (
- "bytes"
"fmt"
"io"
"net"
@@ -65,28 +47,25 @@ type recvMsg struct {
err error
}
-func (*recvMsg) item() {}
-
-// All items in an out of a recvBuffer should be the same type.
-type item interface {
- item()
-}
-
-// recvBuffer is an unbounded channel of item.
+// recvBuffer is an unbounded channel of recvMsg structs.
+// Note recvBuffer differs from controlBuffer only in that recvBuffer
+// holds a channel of only recvMsg structs instead of objects implementing "item" interface.
+// recvBuffer is written to much more often than
+// controlBuffer and using strict recvMsg structs helps avoid allocation in "recvBuffer.put"
type recvBuffer struct {
- c chan item
+ c chan recvMsg
mu sync.Mutex
- backlog []item
+ backlog []recvMsg
}
func newRecvBuffer() *recvBuffer {
b := &recvBuffer{
- c: make(chan item, 1),
+ c: make(chan recvMsg, 1),
}
return b
}
-func (b *recvBuffer) put(r item) {
+func (b *recvBuffer) put(r recvMsg) {
b.mu.Lock()
defer b.mu.Unlock()
if len(b.backlog) == 0 {
@@ -105,17 +84,18 @@ func (b *recvBuffer) load() {
if len(b.backlog) > 0 {
select {
case b.c <- b.backlog[0]:
+ b.backlog[0] = recvMsg{}
b.backlog = b.backlog[1:]
default:
}
}
}
-// get returns the channel that receives an item in the buffer.
+// get returns the channel that receives a recvMsg in the buffer.
//
-// Upon receipt of an item, the caller should call load to send another
-// item onto the channel if there is any.
-func (b *recvBuffer) get() <-chan item {
+// Upon receipt of a recvMsg, the caller should call load to send another
+// recvMsg onto the channel if there is any.
+func (b *recvBuffer) get() <-chan recvMsg {
return b.c
}
@@ -125,7 +105,7 @@ type recvBufferReader struct {
ctx context.Context
goAway chan struct{}
recv *recvBuffer
- last *bytes.Reader // Stores the remaining data in the previous calls.
+ last []byte // Stores the remaining data in the previous calls.
err error
}
@@ -137,26 +117,81 @@ func (r *recvBufferReader) Read(p []byte) (n int, err error) {
return 0, r.err
}
defer func() { r.err = err }()
- if r.last != nil && r.last.Len() > 0 {
+ if r.last != nil && len(r.last) > 0 {
// Read remaining data left in last call.
- return r.last.Read(p)
+ copied := copy(p, r.last)
+ r.last = r.last[copied:]
+ return copied, nil
}
select {
case <-r.ctx.Done():
return 0, ContextErr(r.ctx.Err())
case <-r.goAway:
return 0, ErrStreamDrain
- case i := <-r.recv.get():
+ case m := <-r.recv.get():
r.recv.load()
- m := i.(*recvMsg)
if m.err != nil {
return 0, m.err
}
- r.last = bytes.NewReader(m.data)
- return r.last.Read(p)
+ copied := copy(p, m.data)
+ r.last = m.data[copied:]
+ return copied, nil
}
}
+// All items in an out of a controlBuffer should be the same type.
+type item interface {
+ item()
+}
+
+// controlBuffer is an unbounded channel of item.
+type controlBuffer struct {
+ c chan item
+ mu sync.Mutex
+ backlog []item
+}
+
+func newControlBuffer() *controlBuffer {
+ b := &controlBuffer{
+ c: make(chan item, 1),
+ }
+ return b
+}
+
+func (b *controlBuffer) put(r item) {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ if len(b.backlog) == 0 {
+ select {
+ case b.c <- r:
+ return
+ default:
+ }
+ }
+ b.backlog = append(b.backlog, r)
+}
+
+func (b *controlBuffer) load() {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ if len(b.backlog) > 0 {
+ select {
+ case b.c <- b.backlog[0]:
+ b.backlog[0] = nil
+ b.backlog = b.backlog[1:]
+ default:
+ }
+ }
+}
+
+// get returns the channel that receives an item in the buffer.
+//
+// Upon receipt of an item, the caller should call load to send another
+// item onto the channel if there is any.
+func (b *controlBuffer) get() <-chan item {
+ return b.c
+}
+
type streamState uint8
const (
@@ -171,11 +206,6 @@ 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.
@@ -189,14 +219,17 @@ type Stream struct {
recvCompress string
sendCompress string
buf *recvBuffer
- dec io.Reader
+ trReader io.Reader
fc *inFlow
recvQuota uint32
+
+ // TODO: Remote this unused variable.
// The accumulated inbound quota pending for window update.
updateQuota uint32
- // The handler to control the window update procedure for both this
- // particular stream and the associated transport.
- windowHandler func(int)
+
+ // Callback to state application's intentions to read data. This
+ // is used to adjust flow control, if need be.
+ requestRead func(int)
sendQuotaPool *quotaPool
// Close headerChan to indicate the end of reception of header metadata.
@@ -251,16 +284,24 @@ func (s *Stream) GoAway() <-chan struct{} {
// Header acquires the key-value pairs of header metadata once it
// is available. It blocks until i) the metadata is ready or ii) there is no
-// header metadata or iii) the stream is cancelled/expired.
+// header metadata or iii) the stream is canceled/expired.
func (s *Stream) Header() (metadata.MD, error) {
+ var err error
select {
case <-s.ctx.Done():
- return nil, ContextErr(s.ctx.Err())
+ err = ContextErr(s.ctx.Err())
case <-s.goAway:
- return nil, ErrStreamDrain
+ err = ErrStreamDrain
case <-s.headerChan:
return s.header.Copy(), nil
}
+ // Even if the stream is closed, header is returned if available.
+ select {
+ case <-s.headerChan:
+ return s.header.Copy(), nil
+ default:
+ }
+ return nil, err
}
// Trailer returns the cached trailer metedata. Note that if it is not called
@@ -321,19 +362,38 @@ func (s *Stream) SetTrailer(md metadata.MD) error {
}
func (s *Stream) write(m recvMsg) {
- s.buf.put(&m)
+ s.buf.put(m)
}
-// Read reads all the data available for this Stream from the transport and
+// Read reads all p bytes from the wire for this stream.
+func (s *Stream) Read(p []byte) (n int, err error) {
+ // Don't request a read if there was an error earlier
+ if er := s.trReader.(*transportReader).er; er != nil {
+ return 0, er
+ }
+ s.requestRead(len(p))
+ return io.ReadFull(s.trReader, p)
+}
+
+// tranportReader reads all the data available for this Stream from the transport and
// passes them into the decoder, which converts them into a gRPC message stream.
// The error is io.EOF when the stream is done or another non-nil error if
// the stream broke.
-func (s *Stream) Read(p []byte) (n int, err error) {
- n, err = s.dec.Read(p)
+type transportReader struct {
+ reader io.Reader
+ // The handler to control the window update procedure for both this
+ // particular stream and the associated transport.
+ windowHandler func(int)
+ er error
+}
+
+func (t *transportReader) Read(p []byte) (n int, err error) {
+ n, err = t.reader.Read(p)
if err != nil {
+ t.er = err
return
}
- s.windowHandler(n)
+ t.windowHandler(n)
return
}
@@ -392,12 +452,14 @@ const (
// 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
+ MaxStreams uint32
+ AuthInfo credentials.AuthInfo
+ InTapHandle tap.ServerInHandle
+ StatsHandler stats.Handler
+ KeepaliveParams keepalive.ServerParameters
+ KeepalivePolicy keepalive.EnforcementPolicy
+ InitialWindowSize int32
+ InitialConnWindowSize int32
}
// NewServerTransport creates a ServerTransport with conn or non-nil error
@@ -425,6 +487,10 @@ type ConnectOptions struct {
KeepaliveParams keepalive.ClientParameters
// StatsHandler stores the handler for stats.
StatsHandler stats.Handler
+ // InitialWindowSize sets the intial window size for a stream.
+ InitialWindowSize int32
+ // InitialConnWindowSize sets the intial window size for a connection.
+ InitialConnWindowSize int32
}
// TargetInfo contains the information of the target such as network address and metadata.
@@ -468,10 +534,15 @@ type CallHdr struct {
// outbound message.
SendCompress string
+ // Creds specifies credentials.PerRPCCredentials for a call.
+ Creds credentials.PerRPCCredentials
+
// Flush indicates whether a new stream command should be sent
// to the peer without waiting for the first data. This is
- // only a hint. The transport may modify the flush decision
+ // only a hint.
+ // If it's true, the transport may modify the flush decision
// for performance purposes.
+ // If it's false, new stream will never be flushed.
Flush bool
}
@@ -507,7 +578,7 @@ type ClientTransport interface {
// once the transport is initiated.
Error() <-chan struct{}
- // GoAway returns a channel that is closed when ClientTranspor
+ // GoAway returns a channel that is closed when ClientTransport
// receives the draining signal from the server (e.g., GOAWAY frame in
// HTTP/2).
GoAway() <-chan struct{}
@@ -613,17 +684,6 @@ func (e StreamError) Error() string {
return fmt.Sprintf("stream error: code = %s desc = %q", e.Code, e.Desc)
}
-// ContextErr converts the error from context package into a StreamError.
-func ContextErr(err error) StreamError {
- switch err {
- case context.DeadlineExceeded:
- return streamErrorf(codes.DeadlineExceeded, "%v", err)
- case context.Canceled:
- return streamErrorf(codes.Canceled, "%v", err)
- }
- panic(fmt.Sprintf("Unexpected error from context packet: %v", err))
-}
-
// wait blocks until it can receive from ctx.Done, closing, or proceed.
// If it receives from ctx.Done, it returns 0, the StreamError for ctx.Err.
// If it receives from done, it returns 0, io.EOF if ctx is not done; otherwise
diff --git a/vendor/k8s.io/sample-controller b/vendor/k8s.io/sample-controller
new file mode 120000
index 00000000000..f2c555613e5
--- /dev/null
+++ b/vendor/k8s.io/sample-controller
@@ -0,0 +1 @@
+../../staging/src/k8s.io/sample-controller
\ No newline at end of file