mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 02:08:13 +00:00 
			
		
		
		
	Merge pull request #40606 from deads2k/client-17-sync
Automatic merge from submit-queue (batch tested with PRs 34543, 40606) sync client-go and move util/workqueue The vision of client-go is that it provides enough utilities to build a reasonable controller. It has been copying `util/workqueue`. This makes it authoritative. @liggitt I'm getting really close to making client-go authoritative ptal. approved based on https://github.com/kubernetes/kubernetes/issues/40363
This commit is contained in:
		| @@ -62,7 +62,6 @@ go_library( | ||||
|         "//pkg/genericapiserver/registry/generic/rest:go_default_library", | ||||
|         "//pkg/genericapiserver/registry/rest:go_default_library", | ||||
|         "//pkg/genericapiserver/server:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//pkg/version:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -77,6 +76,7 @@ go_library( | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/transport", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -26,8 +26,8 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
|  | ||||
| 	"k8s.io/kubernetes/cmd/kube-aggregator/pkg/apis/apiregistration" | ||||
| 	informers "k8s.io/kubernetes/cmd/kube-aggregator/pkg/client/informers/apiregistration/internalversion" | ||||
|   | ||||
| @@ -27,7 +27,6 @@ go_library( | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -36,6 +35,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -32,6 +32,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	fed "k8s.io/kubernetes/federation/apis/federation" | ||||
| 	fedv1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||
| @@ -46,7 +47,6 @@ import ( | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
| @@ -28,7 +28,6 @@ go_library( | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -37,6 +36,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/flowcontrol", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -32,6 +32,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	fed "k8s.io/kubernetes/federation/apis/federation" | ||||
| 	fedv1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||
| @@ -47,7 +48,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
| @@ -33,7 +33,6 @@ go_library( | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -45,6 +44,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -25,11 +25,11 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	cache "k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	v1 "k8s.io/kubernetes/pkg/api/v1" | ||||
| 	kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
|  | ||||
| 	"reflect" | ||||
|  | ||||
|   | ||||
| @@ -33,6 +33,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	cache "k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	v1beta1 "k8s.io/kubernetes/federation/apis/federation/v1beta1" | ||||
| 	federationcache "k8s.io/kubernetes/federation/client/cache" | ||||
| 	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" | ||||
| @@ -46,7 +47,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
| @@ -237,7 +237,6 @@ pkg/util/validation | ||||
| pkg/util/validation/field | ||||
| pkg/util/version | ||||
| pkg/util/wait | ||||
| pkg/util/workqueue | ||||
| pkg/util/yaml | ||||
| pkg/version/prometheus | ||||
| pkg/volume | ||||
| @@ -299,6 +298,7 @@ staging/src/k8s.io/client-go/tools/auth | ||||
| staging/src/k8s.io/client-go/tools/metrics | ||||
| staging/src/k8s.io/client-go/util/cert | ||||
| staging/src/k8s.io/client-go/util/homedir | ||||
| staging/src/k8s.io/client-go/util/workqueue | ||||
| test/e2e/perftype | ||||
| test/e2e_node/runner/local | ||||
| test/images/clusterapi-tester | ||||
|   | ||||
| @@ -26,7 +26,6 @@ go_library( | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/cloudflare/cfssl/config", | ||||
|         "//vendor:github.com/cloudflare/cfssl/helpers", | ||||
|         "//vendor:github.com/cloudflare/cfssl/signer", | ||||
| @@ -38,6 +37,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -26,13 +26,13 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	certificates "k8s.io/kubernetes/pkg/apis/certificates/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
|   | ||||
| @@ -27,7 +27,6 @@ go_library( | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//plugin/pkg/scheduler/algorithm/predicates:go_default_library", | ||||
|         "//plugin/pkg/scheduler/schedulercache:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
| @@ -37,6 +36,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -29,6 +29,7 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| @@ -40,7 +41,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache" | ||||
|  | ||||
|   | ||||
| @@ -32,7 +32,6 @@ go_library( | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/labels:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/equality", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -44,6 +43,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/integer", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -36,6 +36,7 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| @@ -46,7 +47,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/controller/deployment/util" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
| @@ -25,7 +25,6 @@ go_library( | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/intstr:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime", | ||||
| @@ -34,6 +33,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| @@ -52,10 +52,10 @@ go_test( | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/intstr:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/uuid", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -28,6 +28,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1" | ||||
| @@ -40,7 +41,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/intstr" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
|   | ||||
| @@ -26,6 +26,7 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/uuid" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1" | ||||
| @@ -35,7 +36,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/intstr" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| type pdbStates map[string]policy.PodDisruptionBudget | ||||
|   | ||||
| @@ -24,7 +24,6 @@ go_library( | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -35,6 +34,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -31,6 +31,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1/endpoints" | ||||
| 	podutil "k8s.io/kubernetes/pkg/api/v1/pod" | ||||
| @@ -40,7 +41,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
|   | ||||
| @@ -21,7 +21,6 @@ go_library( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/controller/garbagecollector/metaonly:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:github.com/golang/groupcache/lru", | ||||
|         "//vendor:github.com/prometheus/client_golang/prometheus", | ||||
| @@ -41,6 +40,7 @@ go_library( | ||||
|         "//vendor:k8s.io/client-go/kubernetes", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/clock", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| @@ -54,7 +54,6 @@ go_test( | ||||
|         "//pkg/api/install:go_default_library", | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/controller/garbagecollector/metaonly:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/stretchr/testify/assert", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/runtime/schema", | ||||
| @@ -65,6 +64,7 @@ go_test( | ||||
|         "//vendor:k8s.io/client-go/dynamic", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/util/clock", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -38,9 +38,9 @@ import ( | ||||
| 	"k8s.io/client-go/dynamic" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
|  | ||||
| 	// import known versions | ||||
| 	_ "k8s.io/client-go/kubernetes" | ||||
|   | ||||
| @@ -36,10 +36,10 @@ import ( | ||||
| 	"k8s.io/client-go/dynamic" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| func TestNewGarbageCollector(t *testing.T) { | ||||
|   | ||||
| @@ -27,13 +27,13 @@ go_library( | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -28,6 +28,7 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	batch "k8s.io/kubernetes/pkg/apis/batch/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| @@ -38,7 +39,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
|   | ||||
| @@ -21,7 +21,6 @@ go_library( | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -35,6 +34,7 @@ go_library( | ||||
|         "//vendor:k8s.io/client-go/discovery", | ||||
|         "//vendor:k8s.io/client-go/dynamic", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -28,11 +28,11 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/dynamic" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
|   | ||||
| @@ -28,7 +28,6 @@ go_library( | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -38,6 +37,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -34,6 +34,7 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| 	extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" | ||||
| @@ -44,7 +45,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
| @@ -25,7 +25,6 @@ go_library( | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/controller/informers:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -36,6 +35,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apiserver/pkg/util/trace", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -34,6 +34,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	utiltrace "k8s.io/apiserver/pkg/util/trace" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	v1core "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| @@ -42,7 +43,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
| @@ -25,7 +25,6 @@ go_library( | ||||
|         "//pkg/quota:go_default_library", | ||||
|         "//pkg/quota/evaluator/core:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/equality", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/meta", | ||||
| @@ -36,6 +35,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -29,13 +29,13 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/quota" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| // ResourceQuotaControllerOptions holds options for creating a quota controller | ||||
|   | ||||
| @@ -24,7 +24,6 @@ go_library( | ||||
|         "//pkg/cloudprovider:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| @@ -34,6 +33,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -33,6 +33,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" | ||||
| @@ -41,7 +42,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
| @@ -31,7 +31,6 @@ go_library( | ||||
|         "//pkg/registry/core/serviceaccount/storage:go_default_library", | ||||
|         "//pkg/serviceaccount:go_default_library", | ||||
|         "//pkg/util/metrics:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/meta", | ||||
| @@ -47,6 +46,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apiserver/pkg/endpoints/request", | ||||
|         "//vendor:k8s.io/apiserver/pkg/storage/storagebackend", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -28,12 +28,12 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/controller/informers" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| // nameIndexFunc is an index function that indexes based on an object's name | ||||
|   | ||||
| @@ -33,6 +33,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" | ||||
| @@ -40,7 +41,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/registry/core/secret" | ||||
| 	"k8s.io/kubernetes/pkg/serviceaccount" | ||||
| 	"k8s.io/kubernetes/pkg/util/metrics" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| // RemoveTokenBackoff is the recommended (empirical) retry interval for removing | ||||
|   | ||||
| @@ -29,7 +29,6 @@ go_library( | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/controller:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:gopkg.in/inf.v0", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -43,6 +42,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -36,8 +36,8 @@ import ( | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| ) | ||||
|   | ||||
| @@ -30,7 +30,6 @@ go_library( | ||||
|         "//pkg/util/goroutinemap:go_default_library", | ||||
|         "//pkg/util/io:go_default_library", | ||||
|         "//pkg/util/mount:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//pkg/volume:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/errors", | ||||
| @@ -42,6 +41,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -24,6 +24,7 @@ import ( | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	storage "k8s.io/kubernetes/pkg/apis/storage/v1beta1" | ||||
| @@ -32,7 +33,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/client/record" | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/util/goroutinemap" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| 	vol "k8s.io/kubernetes/pkg/volume" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
|   | ||||
| @@ -28,6 +28,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apimachinery/pkg/watch" | ||||
| 	"k8s.io/client-go/tools/cache" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	storage "k8s.io/kubernetes/pkg/apis/storage/v1beta1" | ||||
| @@ -37,7 +38,6 @@ import ( | ||||
| 	"k8s.io/kubernetes/pkg/cloudprovider" | ||||
| 	"k8s.io/kubernetes/pkg/controller" | ||||
| 	"k8s.io/kubernetes/pkg/util/goroutinemap" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| 	vol "k8s.io/kubernetes/pkg/volume" | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
|   | ||||
| @@ -98,7 +98,7 @@ filegroup( | ||||
|         "//pkg/util/validation:all-srcs", | ||||
|         "//pkg/util/version:all-srcs", | ||||
|         "//pkg/util/wait:all-srcs", | ||||
|         "//pkg/util/workqueue:all-srcs", | ||||
|         "//pkg/util/workqueue/prometheus:all-srcs", | ||||
|         "//pkg/util/yaml:all-srcs", | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|   | ||||
| @@ -1,69 +0,0 @@ | ||||
| package(default_visibility = ["//visibility:public"]) | ||||
|  | ||||
| licenses(["notice"]) | ||||
|  | ||||
| load( | ||||
|     "@io_bazel_rules_go//go:def.bzl", | ||||
|     "go_library", | ||||
|     "go_test", | ||||
| ) | ||||
|  | ||||
| go_library( | ||||
|     name = "go_default_library", | ||||
|     srcs = [ | ||||
|         "default_rate_limiters.go", | ||||
|         "delaying_queue.go", | ||||
|         "doc.go", | ||||
|         "metrics.go", | ||||
|         "parallelizer.go", | ||||
|         "queue.go", | ||||
|         "rate_limitting_queue.go", | ||||
|         "timed_queue.go", | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//vendor:github.com/juju/ratelimit", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/client-go/util/clock", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| go_test( | ||||
|     name = "go_default_test", | ||||
|     srcs = [ | ||||
|         "default_rate_limiters_test.go", | ||||
|         "delaying_queue_test.go", | ||||
|         "rate_limitting_queue_test.go", | ||||
|         "timed_queue_test.go", | ||||
|     ], | ||||
|     library = ":go_default_library", | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/wait", | ||||
|         "//vendor:k8s.io/client-go/util/clock", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| go_test( | ||||
|     name = "go_default_xtest", | ||||
|     srcs = ["queue_test.go"], | ||||
|     tags = ["automanaged"], | ||||
|     deps = ["//pkg/util/workqueue:go_default_library"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "package-srcs", | ||||
|     srcs = glob(["**"]), | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:private"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "all-srcs", | ||||
|     srcs = [ | ||||
|         ":package-srcs", | ||||
|         "//pkg/util/workqueue/prometheus:all-srcs", | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
| ) | ||||
| @@ -1,26 +0,0 @@ | ||||
| /* | ||||
| Copyright 2014 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 workqueue provides a simple queue that supports the following | ||||
| // features: | ||||
| //  * Fair: items processed in the order in which they are added. | ||||
| //  * Stingy: a single item will not be processed multiple times concurrently, | ||||
| //      and if an item is added multiple times before it can be processed, it | ||||
| //      will only be processed once. | ||||
| //  * Multiple consumers and producers. In particular, it is allowed for an | ||||
| //      item to be reenqueued while it is being processed. | ||||
| //  * Shutdown notifications. | ||||
| package workqueue // import "k8s.io/kubernetes/pkg/util/workqueue" | ||||
| @@ -12,8 +12,8 @@ go_library( | ||||
|     srcs = ["prometheus.go"], | ||||
|     tags = ["automanaged"], | ||||
|     deps = [ | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//vendor:github.com/prometheus/client_golang/prometheus", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ limitations under the License. | ||||
| package prometheus | ||||
|  | ||||
| import ( | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
|  | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| ) | ||||
|   | ||||
| @@ -1,161 +0,0 @@ | ||||
| /* | ||||
| Copyright 2015 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 workqueue_test | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| ) | ||||
|  | ||||
| func TestBasic(t *testing.T) { | ||||
| 	// If something is seriously wrong this test will never complete. | ||||
| 	q := workqueue.New() | ||||
|  | ||||
| 	// Start producers | ||||
| 	const producers = 50 | ||||
| 	producerWG := sync.WaitGroup{} | ||||
| 	producerWG.Add(producers) | ||||
| 	for i := 0; i < producers; i++ { | ||||
| 		go func(i int) { | ||||
| 			defer producerWG.Done() | ||||
| 			for j := 0; j < 50; j++ { | ||||
| 				q.Add(i) | ||||
| 				time.Sleep(time.Millisecond) | ||||
| 			} | ||||
| 		}(i) | ||||
| 	} | ||||
|  | ||||
| 	// Start consumers | ||||
| 	const consumers = 10 | ||||
| 	consumerWG := sync.WaitGroup{} | ||||
| 	consumerWG.Add(consumers) | ||||
| 	for i := 0; i < consumers; i++ { | ||||
| 		go func(i int) { | ||||
| 			defer consumerWG.Done() | ||||
| 			for { | ||||
| 				item, quit := q.Get() | ||||
| 				if item == "added after shutdown!" { | ||||
| 					t.Errorf("Got an item added after shutdown.") | ||||
| 				} | ||||
| 				if quit { | ||||
| 					return | ||||
| 				} | ||||
| 				t.Logf("Worker %v: begin processing %v", i, item) | ||||
| 				time.Sleep(3 * time.Millisecond) | ||||
| 				t.Logf("Worker %v: done processing %v", i, item) | ||||
| 				q.Done(item) | ||||
| 			} | ||||
| 		}(i) | ||||
| 	} | ||||
|  | ||||
| 	producerWG.Wait() | ||||
| 	q.ShutDown() | ||||
| 	q.Add("added after shutdown!") | ||||
| 	consumerWG.Wait() | ||||
| } | ||||
|  | ||||
| func TestAddWhileProcessing(t *testing.T) { | ||||
| 	q := workqueue.New() | ||||
|  | ||||
| 	// Start producers | ||||
| 	const producers = 50 | ||||
| 	producerWG := sync.WaitGroup{} | ||||
| 	producerWG.Add(producers) | ||||
| 	for i := 0; i < producers; i++ { | ||||
| 		go func(i int) { | ||||
| 			defer producerWG.Done() | ||||
| 			q.Add(i) | ||||
| 		}(i) | ||||
| 	} | ||||
|  | ||||
| 	// Start consumers | ||||
| 	const consumers = 10 | ||||
| 	consumerWG := sync.WaitGroup{} | ||||
| 	consumerWG.Add(consumers) | ||||
| 	for i := 0; i < consumers; i++ { | ||||
| 		go func(i int) { | ||||
| 			defer consumerWG.Done() | ||||
| 			// Every worker will re-add every item up to two times. | ||||
| 			// This tests the dirty-while-processing case. | ||||
| 			counters := map[interface{}]int{} | ||||
| 			for { | ||||
| 				item, quit := q.Get() | ||||
| 				if quit { | ||||
| 					return | ||||
| 				} | ||||
| 				counters[item]++ | ||||
| 				if counters[item] < 2 { | ||||
| 					q.Add(item) | ||||
| 				} | ||||
| 				q.Done(item) | ||||
| 			} | ||||
| 		}(i) | ||||
| 	} | ||||
|  | ||||
| 	producerWG.Wait() | ||||
| 	q.ShutDown() | ||||
| 	consumerWG.Wait() | ||||
| } | ||||
|  | ||||
| func TestLen(t *testing.T) { | ||||
| 	q := workqueue.New() | ||||
| 	q.Add("foo") | ||||
| 	if e, a := 1, q.Len(); e != a { | ||||
| 		t.Errorf("Expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	q.Add("bar") | ||||
| 	if e, a := 2, q.Len(); e != a { | ||||
| 		t.Errorf("Expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	q.Add("foo") // should not increase the queue length. | ||||
| 	if e, a := 2, q.Len(); e != a { | ||||
| 		t.Errorf("Expected %v, got %v", e, a) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestReinsert(t *testing.T) { | ||||
| 	q := workqueue.New() | ||||
| 	q.Add("foo") | ||||
|  | ||||
| 	// Start processing | ||||
| 	i, _ := q.Get() | ||||
| 	if i != "foo" { | ||||
| 		t.Errorf("Expected %v, got %v", "foo", i) | ||||
| 	} | ||||
|  | ||||
| 	// Add it back while processing | ||||
| 	q.Add(i) | ||||
|  | ||||
| 	// Finish it up | ||||
| 	q.Done(i) | ||||
|  | ||||
| 	// It should be back on the queue | ||||
| 	i, _ = q.Get() | ||||
| 	if i != "foo" { | ||||
| 		t.Errorf("Expected %v, got %v", "foo", i) | ||||
| 	} | ||||
|  | ||||
| 	// Finish that one up | ||||
| 	q.Done(i) | ||||
|  | ||||
| 	if a := q.Len(); a != 0 { | ||||
| 		t.Errorf("Expected queue to be empty. Has %v items", a) | ||||
| 	} | ||||
| } | ||||
| @@ -1,38 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| ) | ||||
|  | ||||
| func TestNoMemoryLeak(t *testing.T) { | ||||
| 	timedQueue := NewTimedWorkQueue() | ||||
| 	timedQueue.Add(&TimedWorkQueueItem{Object: &v1.Pod{}, StartTime: time.Time{}}) | ||||
| 	item, _ := timedQueue.Get() | ||||
| 	timedQueue.Add(item) | ||||
| 	// The item should still be in the timedQueue. | ||||
| 	timedQueue.Done(item) | ||||
| 	item, _ = timedQueue.Get() | ||||
| 	timedQueue.Done(item) | ||||
| 	if len(timedQueue.Type.processing) != 0 { | ||||
| 		t.Errorf("expect timedQueue.Type.processing to be empty!") | ||||
| 	} | ||||
| } | ||||
| @@ -24,7 +24,6 @@ go_library( | ||||
|         "//pkg/quota:go_default_library", | ||||
|         "//pkg/quota/install:go_default_library", | ||||
|         "//pkg/storage/etcd:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//pkg/util/workqueue/prometheus:go_default_library", | ||||
|         "//vendor:github.com/golang/glog", | ||||
|         "//vendor:github.com/hashicorp/golang-lru", | ||||
| @@ -37,6 +36,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/watch", | ||||
|         "//vendor:k8s.io/apiserver/pkg/admission", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -30,9 +30,9 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/apiserver/pkg/admission" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api" | ||||
| 	"k8s.io/kubernetes/pkg/quota" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| 	_ "k8s.io/kubernetes/pkg/util/workqueue/prometheus" // for workqueue metric registration | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -22,7 +22,6 @@ go_library( | ||||
|         "//pkg/client/clientset_generated/clientset:go_default_library", | ||||
|         "//pkg/client/record:go_default_library", | ||||
|         "//pkg/util/hash:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//plugin/pkg/scheduler/algorithm:go_default_library", | ||||
|         "//plugin/pkg/scheduler/algorithm/predicates:go_default_library", | ||||
|         "//plugin/pkg/scheduler/api:go_default_library", | ||||
| @@ -39,6 +38,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apiserver/pkg/util/trace", | ||||
|         "//vendor:k8s.io/client-go/rest", | ||||
|         "//vendor:k8s.io/client-go/tools/cache", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -21,7 +21,6 @@ go_library( | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/client/legacylisters:go_default_library", | ||||
|         "//pkg/kubelet/qos:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//plugin/pkg/scheduler/algorithm:go_default_library", | ||||
|         "//plugin/pkg/scheduler/algorithm/priorities/util:go_default_library", | ||||
|         "//plugin/pkg/scheduler/schedulercache:go_default_library", | ||||
| @@ -29,6 +28,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/labels", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/util/runtime", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -29,10 +29,10 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/labels" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/client/legacylisters" | ||||
| 	"k8s.io/kubernetes/pkg/kubelet/qos" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" | ||||
| 	priorityutil "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/util" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache" | ||||
|   | ||||
| @@ -28,7 +28,6 @@ go_library( | ||||
|     deps = [ | ||||
|         "//pkg/api/v1:go_default_library", | ||||
|         "//pkg/util/node:go_default_library", | ||||
|         "//pkg/util/workqueue:go_default_library", | ||||
|         "//plugin/pkg/scheduler/algorithm:go_default_library", | ||||
|         "//plugin/pkg/scheduler/algorithm/predicates:go_default_library", | ||||
|         "//plugin/pkg/scheduler/algorithm/priorities/util:go_default_library", | ||||
| @@ -38,6 +37,7 @@ go_library( | ||||
|         "//vendor:k8s.io/apimachinery/pkg/api/resource", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
|         "//vendor:k8s.io/apimachinery/pkg/labels", | ||||
|         "//vendor:k8s.io/client-go/util/workqueue", | ||||
|     ], | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -21,8 +21,8 @@ import ( | ||||
|  | ||||
| 	"github.com/golang/glog" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates" | ||||
| 	priorityutil "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities/util" | ||||
|   | ||||
| @@ -22,9 +22,9 @@ import ( | ||||
| 	"github.com/golang/glog" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/labels" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	utilnode "k8s.io/kubernetes/pkg/util/node" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" | ||||
| 	schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache" | ||||
|   | ||||
| @@ -27,8 +27,8 @@ import ( | ||||
| 	"github.com/golang/glog" | ||||
| 	"k8s.io/apimachinery/pkg/util/errors" | ||||
| 	utiltrace "k8s.io/apiserver/pkg/util/trace" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| 	"k8s.io/kubernetes/pkg/api/v1" | ||||
| 	"k8s.io/kubernetes/pkg/util/workqueue" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" | ||||
| 	"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates" | ||||
| 	schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api" | ||||
|   | ||||
| @@ -78,7 +78,7 @@ save "tools/cache" | ||||
| save "tools/clientcmd" | ||||
| save "tools/metrics" | ||||
| save "transport" | ||||
| save "pkg/third_party" | ||||
| save "third_party" | ||||
| save "plugin" | ||||
| save "util" | ||||
|  | ||||
| @@ -101,9 +101,6 @@ mkcp "/pkg/client/record" "/pkg/client" | ||||
|  | ||||
| mkcp "/pkg/client/unversioned/portforward" "/pkg/client/unversioned" | ||||
|  | ||||
| mkcp "/pkg/util/workqueue" "pkg/util" | ||||
| # remove this folder because it imports prometheus | ||||
| rm -rf "${CLIENT_REPO_TEMP}/pkg/util/workqueue/prometheus" | ||||
| # remove this test because it imports the internal clientset | ||||
| rm "${CLIENT_REPO_TEMP}"/pkg/client/unversioned/portforward/portforward_test.go | ||||
|  | ||||
| @@ -146,9 +143,6 @@ find "${CLIENT_REPO_TEMP}"/pkg/client/record -type f -name "*.go" -print0 | xarg | ||||
| find "${CLIENT_REPO_TEMP}"/pkg/client/record -type f -name "*.go" -print0 | xargs -0 sed -i 's,pkg/api",pkg/api/v1",g' | ||||
| # gofmt the changed files | ||||
|  | ||||
| echo "rewrite conflicting Prometheus registration" | ||||
| sed -i "s/kubernetes_build_info/kubernetes_build_info_copy/g" "${CLIENT_REPO_TEMP}"/pkg/version/version.go | ||||
|  | ||||
| echo "rewrite proto names in proto.RegisterType" | ||||
| find "${CLIENT_REPO_TEMP}" -type f -name "generated.pb.go" -print0 | xargs -0 sed -i "s/k8s\.io\.kubernetes/k8s.io.client-go/g" | ||||
|  | ||||
|   | ||||
							
								
								
									
										86
									
								
								staging/src/k8s.io/client-go/Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										86
									
								
								staging/src/k8s.io/client-go/Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							| @@ -324,151 +324,163 @@ | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/api/errors", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/api/meta", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/apimachinery", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/apimachinery/announced", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/apimachinery/registered", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/conversion", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/fields", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/labels", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/openapi", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/runtime", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/selection", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/types", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/diff", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/errors", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/framer", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/json", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/net", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/rand", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/runtime", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/sets", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch", | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/validation", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/wait", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/util/yaml", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/version", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/pkg/watch", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json", | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil", | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		}, | ||||
| 		{ | ||||
| 			"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect", | ||||
| 			"Rev": "02fccf9462f0fb0287e82cb8a0f1d03b05f8d704" | ||||
| 			"Rev": "e0f5fdb097647ab1d282af70228f0a742cf61c65" | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
|   | ||||
| @@ -375,6 +375,21 @@ func (m *APIResource) MarshalTo(data []byte) (int, error) { | ||||
| 		} | ||||
| 		i += n2 | ||||
| 	} | ||||
| 	if len(m.ShortNames) > 0 { | ||||
| 		for _, s := range m.ShortNames { | ||||
| 			data[i] = 0x2a | ||||
| 			i++ | ||||
| 			l = len(s) | ||||
| 			for l >= 1<<7 { | ||||
| 				data[i] = uint8(uint64(l)&0x7f | 0x80) | ||||
| 				l >>= 7 | ||||
| 				i++ | ||||
| 			} | ||||
| 			data[i] = uint8(l) | ||||
| 			i++ | ||||
| 			i += copy(data[i:], s) | ||||
| 		} | ||||
| 	} | ||||
| 	return i, nil | ||||
| } | ||||
| 
 | ||||
| @@ -1470,6 +1485,12 @@ func (m *APIResource) Size() (n int) { | ||||
| 		l = m.Verbs.Size() | ||||
| 		n += 1 + l + sovGenerated(uint64(l)) | ||||
| 	} | ||||
| 	if len(m.ShortNames) > 0 { | ||||
| 		for _, s := range m.ShortNames { | ||||
| 			l = len(s) | ||||
| 			n += 1 + l + sovGenerated(uint64(l)) | ||||
| 		} | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| @@ -1912,6 +1933,7 @@ func (this *APIResource) String() string { | ||||
| 		`Namespaced:` + fmt.Sprintf("%v", this.Namespaced) + `,`, | ||||
| 		`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, | ||||
| 		`Verbs:` + strings.Replace(fmt.Sprintf("%v", this.Verbs), "Verbs", "Verbs", 1) + `,`, | ||||
| 		`ShortNames:` + fmt.Sprintf("%v", this.ShortNames) + `,`, | ||||
| 		`}`, | ||||
| 	}, "") | ||||
| 	return s | ||||
| @@ -2602,6 +2624,35 @@ func (m *APIResource) Unmarshal(data []byte) error { | ||||
| 				return err | ||||
| 			} | ||||
| 			iNdEx = postIndex | ||||
| 		case 5: | ||||
| 			if wireType != 2 { | ||||
| 				return fmt.Errorf("proto: wrong wireType = %d for field ShortNames", 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.ShortNames = append(m.ShortNames, string(data[iNdEx:postIndex])) | ||||
| 			iNdEx = postIndex | ||||
| 		default: | ||||
| 			iNdEx = preIndex | ||||
| 			skippy, err := skipGenerated(data[iNdEx:]) | ||||
| @@ -6649,136 +6700,137 @@ var ( | ||||
| ) | ||||
| 
 | ||||
| var fileDescriptorGenerated = []byte{ | ||||
| 	// 2089 bytes of a gzipped FileDescriptorProto | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x19, 0x4d, 0x6f, 0x23, 0x49, | ||||
| 	0x35, 0xed, 0xc4, 0x1e, 0xfb, 0x39, 0xce, 0x47, 0x91, 0x01, 0x6f, 0x24, 0xec, 0x6c, 0xef, 0x0a, | ||||
| 	0xcd, 0xc2, 0xac, 0x4d, 0x02, 0xac, 0x86, 0x01, 0x06, 0xe2, 0x38, 0x13, 0x45, 0x3b, 0x99, 0x44, | ||||
| 	0x95, 0x9d, 0x41, 0x2c, 0x23, 0x44, 0xc7, 0x5d, 0x71, 0x9a, 0xb4, 0xbb, 0x9b, 0xaa, 0xb2, 0x27, | ||||
| 	0x61, 0x0f, 0xac, 0x04, 0x08, 0x0e, 0x08, 0xcd, 0x91, 0x03, 0x42, 0x3b, 0x82, 0x1b, 0x37, 0xfe, | ||||
| 	0x04, 0x73, 0x5c, 0x69, 0x2f, 0x1c, 0x90, 0xc5, 0x84, 0x03, 0x47, 0xee, 0x11, 0x07, 0x54, 0xd5, | ||||
| 	0x55, 0xfd, 0x61, 0xc7, 0x9b, 0x36, 0xbb, 0x87, 0x3d, 0xc5, 0xf5, 0xbe, 0xbf, 0xea, 0xbd, 0x57, | ||||
| 	0x1d, 0xd8, 0x3b, 0xbd, 0xc3, 0x1a, 0x8e, 0xdf, 0x3c, 0xed, 0x1f, 0x11, 0xea, 0x11, 0x4e, 0x58, | ||||
| 	0x73, 0x40, 0x3c, 0xdb, 0xa7, 0x4d, 0x85, 0xb0, 0x02, 0xa7, 0x67, 0x75, 0x4e, 0x1c, 0x8f, 0xd0, | ||||
| 	0xf3, 0x66, 0x70, 0xda, 0x15, 0x00, 0xd6, 0xec, 0x11, 0x6e, 0x35, 0x07, 0xeb, 0xcd, 0x2e, 0xf1, | ||||
| 	0x08, 0xb5, 0x38, 0xb1, 0x1b, 0x01, 0xf5, 0xb9, 0x8f, 0x5e, 0x0f, 0xb9, 0x1a, 0x49, 0xae, 0x46, | ||||
| 	0x70, 0xda, 0x15, 0x00, 0xd6, 0x10, 0x5c, 0x8d, 0xc1, 0xfa, 0xea, 0x9b, 0x5d, 0x87, 0x9f, 0xf4, | ||||
| 	0x8f, 0x1a, 0x1d, 0xbf, 0xd7, 0xec, 0xfa, 0x5d, 0xbf, 0x29, 0x99, 0x8f, 0xfa, 0xc7, 0xf2, 0x24, | ||||
| 	0x0f, 0xf2, 0x57, 0x28, 0x74, 0x75, 0xa2, 0x29, 0xb4, 0xef, 0x71, 0xa7, 0x47, 0x46, 0xad, 0x58, | ||||
| 	0x7d, 0xeb, 0x3a, 0x06, 0xd6, 0x39, 0x21, 0x3d, 0x6b, 0x8c, 0x6f, 0x63, 0x3c, 0x18, 0xca, 0xe3, | ||||
| 	0x26, 0x25, 0xcc, 0xef, 0xd3, 0xce, 0xb8, 0xae, 0xf5, 0xab, 0x79, 0xfa, 0xdc, 0x71, 0x9b, 0x8e, | ||||
| 	0xc7, 0x19, 0xa7, 0xa3, 0x2c, 0xe6, 0xdf, 0x66, 0xa1, 0xb8, 0x79, 0xb0, 0xbb, 0x43, 0xfd, 0x7e, | ||||
| 	0x80, 0xd6, 0x60, 0xce, 0xb3, 0x7a, 0xa4, 0x6a, 0xac, 0x19, 0xb7, 0x4a, 0xad, 0xf9, 0x17, 0xc3, | ||||
| 	0xfa, 0xcc, 0xc5, 0xb0, 0x3e, 0xf7, 0xd0, 0xea, 0x11, 0x2c, 0x31, 0xc8, 0x85, 0xe2, 0x80, 0x50, | ||||
| 	0xe6, 0xf8, 0x1e, 0xab, 0xe6, 0xd6, 0x66, 0x6f, 0x95, 0x37, 0xee, 0x35, 0xb2, 0x84, 0xb9, 0x21, | ||||
| 	0x15, 0x3c, 0x0e, 0x59, 0xef, 0xfb, 0xb4, 0xed, 0xb0, 0x8e, 0x3f, 0x20, 0xf4, 0xbc, 0xb5, 0xa4, | ||||
| 	0xb4, 0x14, 0x15, 0x92, 0xe1, 0x48, 0x03, 0xfa, 0xa5, 0x01, 0x4b, 0x01, 0x25, 0xc7, 0x84, 0x52, | ||||
| 	0x62, 0x2b, 0x7c, 0x75, 0x76, 0xcd, 0xf8, 0x14, 0xd4, 0x56, 0x95, 0xda, 0xa5, 0x83, 0x11, 0xf9, | ||||
| 	0x78, 0x4c, 0x23, 0xfa, 0x93, 0x01, 0xab, 0x8c, 0xd0, 0x01, 0xa1, 0x9b, 0xb6, 0x4d, 0x09, 0x63, | ||||
| 	0xad, 0xf3, 0x2d, 0xd7, 0x21, 0x1e, 0xdf, 0xda, 0x6d, 0x63, 0x56, 0x9d, 0x93, 0x71, 0xf8, 0x6e, | ||||
| 	0x36, 0x83, 0x0e, 0x27, 0xc9, 0x69, 0x99, 0xca, 0xa2, 0xd5, 0x89, 0x24, 0x0c, 0x7f, 0x8c, 0x19, | ||||
| 	0xe6, 0x31, 0xcc, 0xeb, 0x44, 0x3e, 0x70, 0x18, 0x47, 0x8f, 0xa1, 0xd0, 0x15, 0x07, 0x56, 0x35, | ||||
| 	0xa4, 0x81, 0x8d, 0x6c, 0x06, 0x6a, 0x19, 0xad, 0x05, 0x65, 0x4f, 0x41, 0x1e, 0x19, 0x56, 0xd2, | ||||
| 	0xcc, 0x8f, 0x0c, 0x28, 0x6f, 0x1e, 0xec, 0x62, 0x55, 0x84, 0x19, 0x8a, 0x66, 0x03, 0x40, 0xfc, | ||||
| 	0x65, 0x81, 0xd5, 0x21, 0x76, 0x35, 0xb7, 0x66, 0xdc, 0x2a, 0xb6, 0x90, 0xa2, 0x83, 0x87, 0x11, | ||||
| 	0x06, 0x27, 0xa8, 0x84, 0xd4, 0x53, 0xc7, 0xb3, 0x65, 0xb6, 0x13, 0x52, 0xdf, 0x76, 0x3c, 0x1b, | ||||
| 	0x4b, 0x0c, 0x7a, 0x00, 0xf9, 0x01, 0xa1, 0x47, 0x22, 0xfe, 0xa2, 0x20, 0xbe, 0x92, 0xcd, 0xbd, | ||||
| 	0xc7, 0x82, 0xa5, 0x55, 0xba, 0x18, 0xd6, 0xf3, 0xf2, 0x27, 0x0e, 0x85, 0x98, 0x7f, 0x35, 0x60, | ||||
| 	0x31, 0xe1, 0x95, 0x8c, 0xe0, 0x1d, 0x98, 0xef, 0x26, 0xea, 0x47, 0x79, 0xb8, 0xa2, 0x6c, 0x99, | ||||
| 	0x4f, 0xd6, 0x16, 0x4e, 0x51, 0x22, 0x02, 0x25, 0x7d, 0x49, 0xf5, 0x3d, 0x59, 0xcf, 0x1c, 0x7e, | ||||
| 	0x6d, 0x43, 0xac, 0x29, 0x01, 0x64, 0x38, 0x96, 0x6c, 0xfe, 0x3b, 0x4c, 0x85, 0xbe, 0x39, 0xe8, | ||||
| 	0x56, 0xe2, 0x76, 0x8a, 0xa4, 0x97, 0x5a, 0xf3, 0x13, 0x6e, 0xd6, 0x35, 0x25, 0x9d, 0xfb, 0x4c, | ||||
| 	0x94, 0xf4, 0xdd, 0xe2, 0xef, 0x3f, 0xa8, 0xcf, 0xbc, 0xff, 0x8f, 0xb5, 0x19, 0xf3, 0xd7, 0x39, | ||||
| 	0xa8, 0xb4, 0x89, 0x4b, 0x38, 0xd9, 0x0f, 0xb8, 0xf4, 0xe0, 0x3e, 0xa0, 0x2e, 0xb5, 0x3a, 0xe4, | ||||
| 	0x80, 0x50, 0xc7, 0xb7, 0x0f, 0x49, 0xc7, 0xf7, 0x6c, 0x26, 0x53, 0x34, 0xdb, 0xfa, 0xfc, 0xc5, | ||||
| 	0xb0, 0x8e, 0x76, 0xc6, 0xb0, 0xf8, 0x0a, 0x0e, 0xe4, 0x42, 0x25, 0xa0, 0xf2, 0xb7, 0xc3, 0x55, | ||||
| 	0x5b, 0x13, 0xe5, 0xf4, 0xb5, 0x6c, 0xbe, 0x1f, 0x24, 0x59, 0x5b, 0xcb, 0x17, 0xc3, 0x7a, 0x25, | ||||
| 	0x05, 0xc2, 0x69, 0xe1, 0xe8, 0x7b, 0xb0, 0xe4, 0xd3, 0xe0, 0xc4, 0xf2, 0xda, 0x24, 0x20, 0x9e, | ||||
| 	0x4d, 0x3c, 0xce, 0x64, 0x89, 0x17, 0x5b, 0x2b, 0xa2, 0x19, 0xed, 0x8f, 0xe0, 0xf0, 0x18, 0xb5, | ||||
| 	0xb9, 0x0b, 0xc5, 0x76, 0x9f, 0x5a, 0x42, 0x1c, 0xfa, 0x0e, 0x14, 0x6d, 0xf5, 0x5b, 0x79, 0xfe, | ||||
| 	0xaa, 0xee, 0xa6, 0x9a, 0xe6, 0x72, 0x58, 0xaf, 0x88, 0x31, 0xd3, 0xd0, 0x00, 0x1c, 0xb1, 0x98, | ||||
| 	0x4f, 0xa0, 0xb2, 0x7d, 0x16, 0xf8, 0x94, 0xeb, 0x98, 0x7e, 0x09, 0x0a, 0x44, 0x02, 0xa4, 0xb4, | ||||
| 	0x62, 0xdc, 0x02, 0x42, 0x32, 0xac, 0xb0, 0xe8, 0x35, 0xc8, 0x93, 0x33, 0xab, 0xc3, 0xd5, 0x5d, | ||||
| 	0xae, 0x28, 0xb2, 0xfc, 0xb6, 0x00, 0xe2, 0x10, 0x67, 0xee, 0x03, 0xec, 0x90, 0x48, 0xf4, 0x26, | ||||
| 	0x2c, 0xea, 0xba, 0x4d, 0x5f, 0xa7, 0x2f, 0x28, 0xe6, 0x45, 0x9c, 0x46, 0xe3, 0x51, 0x7a, 0xf3, | ||||
| 	0x09, 0x94, 0xe4, 0x95, 0x13, 0x3d, 0x40, 0x98, 0x20, 0x6f, 0x9c, 0x92, 0x12, 0x99, 0x20, 0x29, | ||||
| 	0x70, 0x88, 0x8b, 0x9a, 0x48, 0x6e, 0x52, 0x13, 0x49, 0x54, 0x98, 0x0b, 0x95, 0x90, 0x57, 0xf7, | ||||
| 	0xb5, 0x4c, 0x1a, 0x6e, 0x43, 0x51, 0x9b, 0xa9, 0xb4, 0x44, 0xf3, 0x4c, 0x0b, 0xc2, 0x11, 0x45, | ||||
| 	0x42, 0xdb, 0x09, 0xa4, 0xda, 0x47, 0x36, 0x65, 0x6f, 0xc0, 0x0d, 0x75, 0x81, 0x95, 0xae, 0x45, | ||||
| 	0x45, 0x76, 0x43, 0xc7, 0x4c, 0xe3, 0x13, 0x9a, 0x7e, 0x0e, 0xd5, 0x49, 0x43, 0xf0, 0x13, 0x34, | ||||
| 	0xb8, 0xec, 0xa6, 0x98, 0xbf, 0x33, 0x60, 0x29, 0x29, 0x29, 0x7b, 0xfa, 0xb2, 0x2b, 0xb9, 0x7e, | ||||
| 	0x5c, 0x24, 0x22, 0xf2, 0x47, 0x03, 0x56, 0x52, 0xae, 0x4d, 0x95, 0xf1, 0x29, 0x8c, 0x4a, 0x16, | ||||
| 	0xc7, 0xec, 0x14, 0xc5, 0xf1, 0x51, 0x0e, 0x2a, 0x0f, 0xac, 0x23, 0xe2, 0x1e, 0x12, 0x97, 0x74, | ||||
| 	0xb8, 0x4f, 0xd1, 0x7b, 0x50, 0xee, 0x59, 0xbc, 0x73, 0x22, 0xa1, 0x7a, 0xa0, 0xb7, 0xb3, 0xb5, | ||||
| 	0xa8, 0x94, 0xa4, 0xc6, 0x5e, 0x2c, 0x66, 0xdb, 0xe3, 0xf4, 0xbc, 0xf5, 0x39, 0x65, 0x52, 0x39, | ||||
| 	0x81, 0xc1, 0x49, 0x6d, 0x72, 0x0b, 0x93, 0xe7, 0xed, 0xb3, 0x40, 0xf4, 0xe8, 0xe9, 0x97, 0xbf, | ||||
| 	0x94, 0x09, 0x98, 0xfc, 0xb4, 0xef, 0x50, 0xd2, 0x23, 0x1e, 0x8f, 0xb7, 0xb0, 0xbd, 0x11, 0xf9, | ||||
| 	0x78, 0x4c, 0xe3, 0xea, 0x3d, 0x58, 0x1a, 0x35, 0x1e, 0x2d, 0xc1, 0xec, 0x29, 0x39, 0x0f, 0xf3, | ||||
| 	0x85, 0xc5, 0x4f, 0xb4, 0x02, 0xf9, 0x81, 0xe5, 0xf6, 0xd5, 0x6d, 0xc4, 0xe1, 0xe1, 0x6e, 0xee, | ||||
| 	0x8e, 0x61, 0xfe, 0xd9, 0x80, 0xea, 0x24, 0x43, 0xd0, 0x17, 0x13, 0x82, 0x5a, 0x65, 0x65, 0xd5, | ||||
| 	0xec, 0xdb, 0xe4, 0x3c, 0x94, 0xba, 0x0d, 0x45, 0x3f, 0x10, 0x7b, 0xb3, 0x4f, 0x55, 0xd6, 0xdf, | ||||
| 	0xd0, 0x99, 0xdc, 0x57, 0xf0, 0xcb, 0x61, 0xfd, 0x66, 0x4a, 0xbc, 0x46, 0xe0, 0x88, 0x15, 0x99, | ||||
| 	0x50, 0x90, 0xf6, 0x88, 0x9e, 0x2f, 0xa6, 0x33, 0x88, 0xde, 0xfa, 0x58, 0x42, 0xb0, 0xc2, 0x98, | ||||
| 	0xef, 0x41, 0x51, 0x2c, 0x1f, 0x7b, 0x84, 0x5b, 0xa2, 0x80, 0x18, 0x71, 0x8f, 0x1f, 0x38, 0xde, | ||||
| 	0xa9, 0x32, 0x2d, 0x2a, 0xa0, 0x43, 0x05, 0xc7, 0x11, 0xc5, 0x55, 0x2d, 0x36, 0x37, 0x65, 0x8b, | ||||
| 	0xfd, 0x4b, 0x0e, 0xca, 0x42, 0xbb, 0xee, 0xda, 0xdf, 0x82, 0x8a, 0x9b, 0xf4, 0x49, 0x59, 0x71, | ||||
| 	0x53, 0x09, 0x4c, 0x57, 0x29, 0x4e, 0xd3, 0x0a, 0xe6, 0x63, 0x87, 0xb8, 0x76, 0xc4, 0x9c, 0x4b, | ||||
| 	0x33, 0xdf, 0x4f, 0x22, 0x71, 0x9a, 0x56, 0xdc, 0xc5, 0xa7, 0x22, 0xdb, 0x6a, 0x3a, 0x46, 0x77, | ||||
| 	0xf1, 0xfb, 0x02, 0x88, 0x43, 0xdc, 0x55, 0x1e, 0xcf, 0x4d, 0xe7, 0x31, 0xba, 0x0b, 0x0b, 0x62, | ||||
| 	0x3c, 0xfa, 0x7d, 0xae, 0x57, 0x88, 0xbc, 0x1c, 0xa4, 0xe8, 0x62, 0x58, 0x5f, 0x78, 0x27, 0x85, | ||||
| 	0xc1, 0x23, 0x94, 0xe6, 0x2f, 0x00, 0x60, 0xff, 0xe8, 0x27, 0xa4, 0x13, 0x66, 0xeb, 0xfa, 0x45, | ||||
| 	0x58, 0xf4, 0x5b, 0xf5, 0xfe, 0x12, 0x50, 0x15, 0x90, 0xb8, 0xdf, 0x26, 0x70, 0x38, 0x45, 0x89, | ||||
| 	0x9a, 0x50, 0x8a, 0x96, 0x63, 0xd5, 0x4b, 0x96, 0x15, 0x5b, 0x29, 0xda, 0xa0, 0x71, 0x4c, 0x93, | ||||
| 	0x2a, 0x9d, 0xb9, 0x6b, 0x4b, 0xa7, 0x05, 0xb3, 0x7d, 0xc7, 0x96, 0xae, 0x97, 0x5a, 0x5f, 0xd5, | ||||
| 	0xe5, 0xff, 0x68, 0xb7, 0x7d, 0x39, 0xac, 0xbf, 0x3a, 0xe9, 0x01, 0xcb, 0xcf, 0x03, 0xc2, 0x1a, | ||||
| 	0x8f, 0x76, 0xdb, 0x58, 0x30, 0x5f, 0x95, 0x8c, 0xc2, 0x94, 0xc9, 0xd8, 0x00, 0x50, 0x5e, 0x0b, | ||||
| 	0xee, 0x1b, 0x61, 0x22, 0xf4, 0x43, 0x61, 0x27, 0xc2, 0xe0, 0x04, 0x15, 0x62, 0xb0, 0xdc, 0xa1, | ||||
| 	0x44, 0xfe, 0x16, 0xe9, 0x62, 0xdc, 0xea, 0x05, 0xd5, 0xa2, 0xdc, 0xe1, 0xbe, 0x9c, 0xad, 0x3b, | ||||
| 	0x09, 0xb6, 0xd6, 0x2b, 0x4a, 0xcd, 0xf2, 0xd6, 0xa8, 0x30, 0x3c, 0x2e, 0x1f, 0xf9, 0xb0, 0x6c, | ||||
| 	0x8b, 0x6d, 0x34, 0xa5, 0xb4, 0x34, 0xb5, 0xd2, 0x9b, 0x42, 0x61, 0x7b, 0x54, 0x10, 0x1e, 0x97, | ||||
| 	0x8d, 0x7e, 0x04, 0xab, 0x1a, 0x38, 0xbe, 0xd7, 0x56, 0x41, 0x46, 0xaa, 0x26, 0x36, 0xed, 0xf6, | ||||
| 	0x44, 0x2a, 0xfc, 0x31, 0x12, 0x90, 0x0d, 0x05, 0x37, 0x9c, 0x2d, 0x65, 0xd9, 0xd8, 0xbf, 0x9d, | ||||
| 	0xcd, 0x8b, 0xb8, 0xfa, 0x1b, 0xc9, 0x99, 0x12, 0xed, 0x8d, 0x6a, 0x9c, 0x28, 0xd9, 0xe8, 0x0c, | ||||
| 	0xca, 0x96, 0xe7, 0xf9, 0xdc, 0x0a, 0x37, 0xed, 0x79, 0xa9, 0x6a, 0x73, 0x6a, 0x55, 0x9b, 0xb1, | ||||
| 	0x8c, 0x91, 0x19, 0x96, 0xc0, 0xe0, 0xa4, 0x2a, 0xf4, 0x14, 0x16, 0xfd, 0xa7, 0x1e, 0xa1, 0x58, | ||||
| 	0x3c, 0xed, 0x89, 0x27, 0x9e, 0x65, 0x15, 0xa9, 0xfd, 0xeb, 0x19, 0xb5, 0xa7, 0x98, 0xe3, 0x92, | ||||
| 	0x4e, 0xc3, 0x19, 0x1e, 0xd5, 0x82, 0x1a, 0x00, 0xc7, 0x8e, 0x67, 0xb9, 0xce, 0xcf, 0x08, 0x65, | ||||
| 	0xd5, 0x05, 0xd9, 0xf6, 0x17, 0x44, 0x39, 0xdf, 0x8f, 0xa0, 0x38, 0x41, 0x81, 0xbe, 0x01, 0xe5, | ||||
| 	0x8e, 0xdb, 0x67, 0x9c, 0x50, 0xd9, 0x21, 0x16, 0xe5, 0x0d, 0x8a, 0xfc, 0xdb, 0x8a, 0x51, 0x38, | ||||
| 	0x49, 0xb7, 0xfa, 0x4d, 0x28, 0xff, 0x9f, 0x73, 0x51, 0xcc, 0xd5, 0xd1, 0x80, 0x4e, 0x35, 0x57, | ||||
| 	0xff, 0x6b, 0xc0, 0x42, 0x3a, 0x0c, 0xd1, 0x36, 0x66, 0x4c, 0x7c, 0xbc, 0xeb, 0x5e, 0x39, 0x3b, | ||||
| 	0xb1, 0x57, 0xaa, 0x96, 0x34, 0xf7, 0x49, 0x5a, 0xd2, 0x06, 0x80, 0x15, 0x38, 0xba, 0x1b, 0x85, | ||||
| 	0xdd, 0x2d, 0xea, 0x27, 0xf1, 0xc3, 0x19, 0x27, 0xa8, 0x44, 0xc2, 0x3a, 0xbe, 0xc7, 0xa9, 0xef, | ||||
| 	0xba, 0x84, 0xca, 0x0e, 0x56, 0x0c, 0x13, 0xb6, 0x15, 0x41, 0x71, 0x82, 0xc2, 0xdc, 0x87, 0xf4, | ||||
| 	0x8b, 0x0f, 0xdd, 0x0b, 0x0d, 0x0f, 0x7d, 0xbf, 0x3d, 0xb5, 0xd1, 0xe6, 0x6d, 0x28, 0x61, 0xdf, | ||||
| 	0xe7, 0x07, 0x16, 0x3f, 0x61, 0xa8, 0x0e, 0xf9, 0x40, 0xfc, 0x50, 0xcf, 0x79, 0xf9, 0xdd, 0x42, | ||||
| 	0x62, 0x70, 0x08, 0x37, 0x7f, 0x6b, 0xc0, 0x2b, 0x13, 0x5f, 0xd7, 0x22, 0x00, 0x9d, 0xe8, 0xa4, | ||||
| 	0x4c, 0x8a, 0x02, 0x10, 0xd3, 0xe1, 0x04, 0x95, 0x18, 0xdb, 0xa9, 0x27, 0xf9, 0xe8, 0xd8, 0x4e, | ||||
| 	0x69, 0xc3, 0x69, 0x5a, 0xf3, 0x3f, 0x39, 0x28, 0x1c, 0x72, 0x8b, 0xf7, 0x19, 0x7a, 0x02, 0x45, | ||||
| 	0x71, 0x7b, 0x6c, 0x8b, 0x5b, 0x52, 0x73, 0xe6, 0x2f, 0x50, 0x7a, 0xfd, 0x89, 0x27, 0x96, 0x86, | ||||
| 	0xe0, 0x48, 0xa2, 0x78, 0xaa, 0x32, 0xa9, 0x47, 0x99, 0x17, 0xb5, 0x9c, 0x50, 0x3b, 0x56, 0x58, | ||||
| 	0xb1, 0xae, 0xf7, 0x08, 0x63, 0x56, 0x57, 0xd7, 0x5a, 0xb4, 0xae, 0xef, 0x85, 0x60, 0xac, 0xf1, | ||||
| 	0xe8, 0x2d, 0x28, 0x50, 0x62, 0xb1, 0x68, 0x89, 0xa8, 0x69, 0x91, 0x58, 0x42, 0x2f, 0x87, 0xf5, | ||||
| 	0x79, 0x25, 0x5c, 0x9e, 0xb1, 0xa2, 0x46, 0xef, 0xc2, 0x0d, 0x9b, 0x70, 0xcb, 0x71, 0xc3, 0xdd, | ||||
| 	0x21, 0xf3, 0xb7, 0x83, 0x50, 0x58, 0x3b, 0x64, 0x6d, 0x95, 0x85, 0x4d, 0xea, 0x80, 0xb5, 0x40, | ||||
| 	0x71, 0x4f, 0x3a, 0xbe, 0x4d, 0x64, 0x1d, 0xe6, 0xe3, 0x7b, 0xb2, 0xe5, 0xdb, 0x04, 0x4b, 0x8c, | ||||
| 	0xf9, 0xcc, 0x80, 0x72, 0x28, 0x69, 0xcb, 0xea, 0x33, 0x82, 0xd6, 0x23, 0x2f, 0xc2, 0x74, 0xeb, | ||||
| 	0xc1, 0x36, 0xf7, 0xce, 0x79, 0x40, 0x2e, 0x87, 0xf5, 0x92, 0x24, 0x13, 0x87, 0xc8, 0x81, 0x44, | ||||
| 	0x8c, 0x72, 0xd7, 0xc4, 0xe8, 0x35, 0xc8, 0xcb, 0x3d, 0x4d, 0x05, 0x33, 0x5a, 0xcb, 0xe4, 0x2e, | ||||
| 	0x87, 0x43, 0x9c, 0xf9, 0x87, 0x1c, 0x54, 0x52, 0xce, 0x65, 0x58, 0x8d, 0xa2, 0xb7, 0x57, 0x2e, | ||||
| 	0xc3, 0x7b, 0x7e, 0xf2, 0x47, 0xc1, 0x1f, 0x40, 0xa1, 0x23, 0xfc, 0xd3, 0x5f, 0x65, 0xd7, 0xa7, | ||||
| 	0x49, 0x85, 0x8c, 0x4c, 0x5c, 0x49, 0xf2, 0xc8, 0xb0, 0x12, 0x88, 0x76, 0x60, 0x99, 0x12, 0x4e, | ||||
| 	0xcf, 0x37, 0x8f, 0x39, 0xa1, 0xc9, 0x65, 0x31, 0x1f, 0x2f, 0x0f, 0x78, 0x94, 0x00, 0x8f, 0xf3, | ||||
| 	0x98, 0x2e, 0xcc, 0x89, 0xc1, 0x2e, 0xc2, 0xce, 0x52, 0x9f, 0xad, 0xa2, 0xb0, 0x6b, 0x66, 0x8d, | ||||
| 	0x17, 0xd1, 0xf1, 0x2c, 0xcf, 0x0f, 0x8b, 0x3d, 0x1f, 0x47, 0xe7, 0xa1, 0x00, 0xe2, 0x10, 0x77, | ||||
| 	0x77, 0x45, 0x3c, 0x20, 0x7f, 0xf3, 0xbc, 0x3e, 0xf3, 0xec, 0x79, 0x7d, 0xe6, 0x83, 0xe7, 0xea, | ||||
| 	0x31, 0xf9, 0x43, 0x28, 0xc5, 0x6b, 0xc4, 0xa7, 0xac, 0xd2, 0xfc, 0x31, 0x14, 0x45, 0x25, 0xe9, | ||||
| 	0xf5, 0xf7, 0x9a, 0xa6, 0x9f, 0x6e, 0xc7, 0xb9, 0x2c, 0xed, 0xd8, 0xdc, 0x80, 0xf0, 0x3b, 0xad, | ||||
| 	0xe8, 0x84, 0x0e, 0x27, 0xbd, 0x54, 0x27, 0xdc, 0x15, 0x00, 0x1c, 0xc2, 0x13, 0xef, 0xe7, 0x5f, | ||||
| 	0x19, 0x00, 0xf2, 0x9d, 0xb0, 0x3d, 0x10, 0x6f, 0xbb, 0x35, 0x98, 0x13, 0x2d, 0x76, 0xd4, 0x30, | ||||
| 	0x79, 0x05, 0x24, 0x06, 0x3d, 0x82, 0x82, 0x2f, 0xd7, 0x0b, 0xf5, 0xf1, 0xef, 0xcd, 0x89, 0x55, | ||||
| 	0xa3, 0xfe, 0x69, 0xd3, 0xc0, 0xd6, 0xd3, 0xed, 0x33, 0x4e, 0x3c, 0x61, 0x63, 0x5c, 0x31, 0xe1, | ||||
| 	0x8e, 0x82, 0x95, 0xb0, 0xd6, 0xeb, 0x2f, 0x5e, 0xd6, 0x66, 0x3e, 0x7c, 0x59, 0x9b, 0xf9, 0xfb, | ||||
| 	0xcb, 0xda, 0xcc, 0xfb, 0x17, 0x35, 0xe3, 0xc5, 0x45, 0xcd, 0xf8, 0xf0, 0xa2, 0x66, 0xfc, 0xf3, | ||||
| 	0xa2, 0x66, 0x3c, 0xfb, 0x57, 0x6d, 0xe6, 0xdd, 0xdc, 0x60, 0xfd, 0x7f, 0x01, 0x00, 0x00, 0xff, | ||||
| 	0xff, 0x0c, 0x01, 0x08, 0xec, 0xf6, 0x1a, 0x00, 0x00, | ||||
| 	// 2109 bytes of a gzipped FileDescriptorProto | ||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x19, 0x4b, 0x6f, 0x23, 0x49, | ||||
| 	0x39, 0x6d, 0xc7, 0x1e, 0xfb, 0x73, 0x9c, 0x47, 0x31, 0x03, 0xde, 0x48, 0xd8, 0xd9, 0xde, 0x15, | ||||
| 	0x9a, 0x85, 0x59, 0x9b, 0x04, 0x58, 0x0d, 0x03, 0x0c, 0xc4, 0x71, 0x66, 0x14, 0xed, 0x64, 0x12, | ||||
| 	0x55, 0x76, 0x06, 0xb1, 0x8c, 0x10, 0x1d, 0x77, 0xc5, 0x69, 0xd2, 0xee, 0x6e, 0xaa, 0xca, 0x9e, | ||||
| 	0x84, 0x3d, 0xb0, 0xd2, 0x82, 0xe0, 0x80, 0xd0, 0x1c, 0x39, 0x20, 0xb4, 0x23, 0xb8, 0x71, 0xe3, | ||||
| 	0x4f, 0x30, 0xc7, 0x95, 0xb8, 0x70, 0x40, 0x16, 0x13, 0x0e, 0x1c, 0xb9, 0x47, 0x1c, 0x50, 0x55, | ||||
| 	0x57, 0xf5, 0xc3, 0x8e, 0x37, 0x6d, 0x76, 0x0f, 0x7b, 0x8a, 0xeb, 0x7b, 0xd7, 0x57, 0xdf, 0xb3, | ||||
| 	0x03, 0xbb, 0x27, 0xb7, 0x59, 0xd3, 0xf1, 0x5b, 0x27, 0x83, 0x43, 0x42, 0x3d, 0xc2, 0x09, 0x6b, | ||||
| 	0x0d, 0x89, 0x67, 0xfb, 0xb4, 0xa5, 0x10, 0x56, 0xe0, 0xf4, 0xad, 0xee, 0xb1, 0xe3, 0x11, 0x7a, | ||||
| 	0xd6, 0x0a, 0x4e, 0x7a, 0x02, 0xc0, 0x5a, 0x7d, 0xc2, 0xad, 0xd6, 0x70, 0xbd, 0xd5, 0x23, 0x1e, | ||||
| 	0xa1, 0x16, 0x27, 0x76, 0x33, 0xa0, 0x3e, 0xf7, 0xd1, 0xeb, 0x21, 0x57, 0x33, 0xc9, 0xd5, 0x0c, | ||||
| 	0x4e, 0x7a, 0x02, 0xc0, 0x9a, 0x82, 0xab, 0x39, 0x5c, 0x5f, 0x7d, 0xb3, 0xe7, 0xf0, 0xe3, 0xc1, | ||||
| 	0x61, 0xb3, 0xeb, 0xf7, 0x5b, 0x3d, 0xbf, 0xe7, 0xb7, 0x24, 0xf3, 0xe1, 0xe0, 0x48, 0x9e, 0xe4, | ||||
| 	0x41, 0xfe, 0x0a, 0x85, 0xae, 0x4e, 0x35, 0x85, 0x0e, 0x3c, 0xee, 0xf4, 0xc9, 0xb8, 0x15, 0xab, | ||||
| 	0x6f, 0x5d, 0xc5, 0xc0, 0xba, 0xc7, 0xa4, 0x6f, 0x4d, 0xf0, 0x6d, 0x4c, 0x3a, 0x43, 0xdd, 0xb8, | ||||
| 	0x45, 0x09, 0xf3, 0x07, 0xb4, 0x3b, 0xa9, 0x6b, 0xfd, 0x72, 0x9e, 0x01, 0x77, 0xdc, 0x96, 0xe3, | ||||
| 	0x71, 0xc6, 0xe9, 0x38, 0x8b, 0xf9, 0xd7, 0x3c, 0x94, 0x36, 0xf7, 0x77, 0xee, 0x53, 0x7f, 0x10, | ||||
| 	0xa0, 0x35, 0x98, 0xf7, 0xac, 0x3e, 0xa9, 0x19, 0x6b, 0xc6, 0xcd, 0x72, 0x7b, 0xe1, 0xc5, 0xa8, | ||||
| 	0x31, 0x77, 0x3e, 0x6a, 0xcc, 0x3f, 0xb4, 0xfa, 0x04, 0x4b, 0x0c, 0x72, 0xa1, 0x34, 0x24, 0x94, | ||||
| 	0x39, 0xbe, 0xc7, 0x6a, 0xb9, 0xb5, 0xfc, 0xcd, 0xca, 0xc6, 0xdd, 0x66, 0x16, 0x37, 0x37, 0xa5, | ||||
| 	0x82, 0xc7, 0x21, 0xeb, 0x3d, 0x9f, 0x76, 0x1c, 0xd6, 0xf5, 0x87, 0x84, 0x9e, 0xb5, 0x97, 0x95, | ||||
| 	0x96, 0x92, 0x42, 0x32, 0x1c, 0x69, 0x40, 0xbf, 0x30, 0x60, 0x39, 0xa0, 0xe4, 0x88, 0x50, 0x4a, | ||||
| 	0x6c, 0x85, 0xaf, 0xe5, 0xd7, 0x8c, 0x4f, 0x41, 0x6d, 0x4d, 0xa9, 0x5d, 0xde, 0x1f, 0x93, 0x8f, | ||||
| 	0x27, 0x34, 0xa2, 0x3f, 0x1a, 0xb0, 0xca, 0x08, 0x1d, 0x12, 0xba, 0x69, 0xdb, 0x94, 0x30, 0xd6, | ||||
| 	0x3e, 0xdb, 0x72, 0x1d, 0xe2, 0xf1, 0xad, 0x9d, 0x0e, 0x66, 0xb5, 0x79, 0xe9, 0x87, 0xef, 0x66, | ||||
| 	0x33, 0xe8, 0x60, 0x9a, 0x9c, 0xb6, 0xa9, 0x2c, 0x5a, 0x9d, 0x4a, 0xc2, 0xf0, 0xc7, 0x98, 0x61, | ||||
| 	0x1e, 0xc1, 0x82, 0x7e, 0xc8, 0x07, 0x0e, 0xe3, 0xe8, 0x31, 0x14, 0x7b, 0xe2, 0xc0, 0x6a, 0x86, | ||||
| 	0x34, 0xb0, 0x99, 0xcd, 0x40, 0x2d, 0xa3, 0xbd, 0xa8, 0xec, 0x29, 0xca, 0x23, 0xc3, 0x4a, 0x9a, | ||||
| 	0xf9, 0x41, 0x0e, 0x2a, 0x9b, 0xfb, 0x3b, 0x58, 0x05, 0x61, 0x86, 0xa0, 0xd9, 0x00, 0x10, 0x7f, | ||||
| 	0x59, 0x60, 0x75, 0x89, 0x5d, 0xcb, 0xad, 0x19, 0x37, 0x4b, 0x6d, 0xa4, 0xe8, 0xe0, 0x61, 0x84, | ||||
| 	0xc1, 0x09, 0x2a, 0x21, 0xf5, 0xc4, 0xf1, 0x6c, 0xf9, 0xda, 0x09, 0xa9, 0x6f, 0x3b, 0x9e, 0x8d, | ||||
| 	0x25, 0x06, 0x3d, 0x80, 0xc2, 0x90, 0xd0, 0x43, 0xe1, 0x7f, 0x11, 0x10, 0x5f, 0xc9, 0x76, 0xbd, | ||||
| 	0xc7, 0x82, 0xa5, 0x5d, 0x3e, 0x1f, 0x35, 0x0a, 0xf2, 0x27, 0x0e, 0x85, 0xa0, 0x26, 0x00, 0x3b, | ||||
| 	0xf6, 0x29, 0x97, 0xe6, 0xd4, 0x0a, 0x6b, 0xf9, 0x9b, 0xe5, 0xf6, 0xa2, 0xb0, 0xef, 0x20, 0x82, | ||||
| 	0xe2, 0x04, 0x85, 0xf9, 0x17, 0x03, 0x96, 0x12, 0x5e, 0x90, 0x1e, 0xbf, 0x0d, 0x0b, 0xbd, 0x44, | ||||
| 	0xbc, 0x29, 0x8f, 0x5c, 0x57, 0xb6, 0x2f, 0x24, 0x63, 0x11, 0xa7, 0x28, 0x11, 0x81, 0xb2, 0x4e, | ||||
| 	0x6a, 0x9d, 0x57, 0xeb, 0x99, 0x9f, 0x4b, 0xdb, 0x10, 0x6b, 0x4a, 0x00, 0x19, 0x8e, 0x25, 0x9b, | ||||
| 	0xff, 0x36, 0xe4, 0xd3, 0xe9, 0x4c, 0x43, 0x37, 0x13, 0xd9, 0x6c, 0xc8, 0x2b, 0x2f, 0x4c, 0xc9, | ||||
| 	0xc4, 0x2b, 0x52, 0x20, 0xf7, 0x99, 0x48, 0x81, 0x3b, 0xa5, 0xdf, 0x7d, 0xd8, 0x98, 0x7b, 0xff, | ||||
| 	0x1f, 0x6b, 0x73, 0xe6, 0xaf, 0x72, 0x50, 0xed, 0x10, 0x97, 0x70, 0xb2, 0x17, 0x70, 0x79, 0x83, | ||||
| 	0x7b, 0x80, 0x7a, 0xd4, 0xea, 0x92, 0x7d, 0x42, 0x1d, 0xdf, 0x3e, 0x20, 0x5d, 0xdf, 0xb3, 0x99, | ||||
| 	0x7c, 0xa2, 0x7c, 0xfb, 0xf3, 0xe7, 0xa3, 0x06, 0xba, 0x3f, 0x81, 0xc5, 0x97, 0x70, 0x20, 0x17, | ||||
| 	0xaa, 0x01, 0x95, 0xbf, 0x1d, 0xae, 0xca, 0xa0, 0x08, 0xbf, 0xaf, 0x65, 0xbb, 0xfb, 0x7e, 0x92, | ||||
| 	0xb5, 0xbd, 0x72, 0x3e, 0x6a, 0x54, 0x53, 0x20, 0x9c, 0x16, 0x8e, 0xbe, 0x07, 0xcb, 0x3e, 0x0d, | ||||
| 	0x8e, 0x2d, 0xaf, 0x43, 0x02, 0xe2, 0xd9, 0xc4, 0xe3, 0x4c, 0xa6, 0x44, 0xa9, 0x7d, 0x5d, 0x14, | ||||
| 	0xaf, 0xbd, 0x31, 0x1c, 0x9e, 0xa0, 0x36, 0x77, 0xa0, 0xd4, 0x19, 0x50, 0x4b, 0x88, 0x43, 0xdf, | ||||
| 	0x81, 0x92, 0xad, 0x7e, 0xab, 0x9b, 0xbf, 0xaa, 0xab, 0xaf, 0xa6, 0xb9, 0x18, 0x35, 0xaa, 0xa2, | ||||
| 	0x2d, 0x35, 0x35, 0x00, 0x47, 0x2c, 0xe6, 0x13, 0xa8, 0x6e, 0x9f, 0x06, 0x3e, 0xe5, 0xda, 0xa7, | ||||
| 	0x5f, 0x82, 0x22, 0x91, 0x00, 0x29, 0xad, 0x14, 0x97, 0x8c, 0x90, 0x0c, 0x2b, 0x2c, 0x7a, 0x0d, | ||||
| 	0x0a, 0xe4, 0xd4, 0xea, 0x72, 0x95, 0xfb, 0x55, 0x45, 0x56, 0xd8, 0x16, 0x40, 0x1c, 0xe2, 0xcc, | ||||
| 	0x3d, 0x80, 0xfb, 0x24, 0x12, 0xbd, 0x09, 0x4b, 0x3a, 0x6e, 0xd3, 0xe9, 0xf4, 0x05, 0xc5, 0xbc, | ||||
| 	0x84, 0xd3, 0x68, 0x3c, 0x4e, 0x6f, 0x3e, 0x81, 0xb2, 0x4c, 0x39, 0x51, 0x33, 0x84, 0x09, 0x32, | ||||
| 	0xe3, 0x94, 0x94, 0xc8, 0x04, 0x49, 0x81, 0x43, 0x5c, 0x54, 0x74, 0x72, 0xd3, 0x8a, 0x4e, 0x22, | ||||
| 	0xc2, 0x5c, 0xa8, 0x86, 0xbc, 0xba, 0x0e, 0x66, 0xd2, 0x70, 0x0b, 0x4a, 0xda, 0x4c, 0xa5, 0x25, | ||||
| 	0xea, 0x7f, 0x5a, 0x10, 0x8e, 0x28, 0x12, 0xda, 0x8e, 0x21, 0x55, 0x3e, 0xb2, 0x29, 0x7b, 0x03, | ||||
| 	0xae, 0xa9, 0x04, 0x56, 0xba, 0x96, 0x14, 0xd9, 0x35, 0xed, 0x33, 0x8d, 0x4f, 0x68, 0xfa, 0x39, | ||||
| 	0xd4, 0xa6, 0x35, 0xcd, 0x4f, 0x50, 0xe0, 0xb2, 0x9b, 0x62, 0xfe, 0xd6, 0x80, 0xe5, 0xa4, 0xa4, | ||||
| 	0xec, 0xcf, 0x97, 0x5d, 0xc9, 0xd5, 0xed, 0x25, 0xe1, 0x91, 0x3f, 0x18, 0x70, 0x3d, 0x75, 0xb5, | ||||
| 	0x99, 0x5e, 0x7c, 0x06, 0xa3, 0x92, 0xc1, 0x91, 0x9f, 0x21, 0x38, 0xfe, 0x96, 0x83, 0xea, 0x03, | ||||
| 	0xeb, 0x90, 0xb8, 0x07, 0xc4, 0x25, 0x5d, 0xee, 0x53, 0xf4, 0x1e, 0x54, 0xfa, 0x16, 0xef, 0x1e, | ||||
| 	0x4b, 0xa8, 0x1e, 0x00, 0x3a, 0xd9, 0x4a, 0x54, 0x4a, 0x52, 0x73, 0x37, 0x16, 0xb3, 0xed, 0x71, | ||||
| 	0x7a, 0xd6, 0xfe, 0x9c, 0x32, 0xa9, 0x92, 0xc0, 0xe0, 0xa4, 0x36, 0x39, 0xb5, 0xc9, 0xf3, 0xf6, | ||||
| 	0x69, 0x20, 0x6a, 0xf4, 0xec, 0xc3, 0x62, 0xca, 0x04, 0x4c, 0x7e, 0x3a, 0x70, 0x28, 0xe9, 0x13, | ||||
| 	0x8f, 0xc7, 0x53, 0xdb, 0xee, 0x98, 0x7c, 0x3c, 0xa1, 0x71, 0xf5, 0x2e, 0x2c, 0x8f, 0x1b, 0x8f, | ||||
| 	0x96, 0x21, 0x7f, 0x42, 0xce, 0xc2, 0xf7, 0xc2, 0xe2, 0x27, 0xba, 0x0e, 0x85, 0xa1, 0xe5, 0x0e, | ||||
| 	0x54, 0x36, 0xe2, 0xf0, 0x70, 0x27, 0x77, 0xdb, 0x30, 0xff, 0x64, 0x40, 0x6d, 0x9a, 0x21, 0xe8, | ||||
| 	0x8b, 0x09, 0x41, 0xed, 0x8a, 0xb2, 0x2a, 0xff, 0x36, 0x39, 0x0b, 0xa5, 0x6e, 0x43, 0xc9, 0x0f, | ||||
| 	0xc4, 0x9c, 0xed, 0x53, 0xf5, 0xea, 0x6f, 0xe8, 0x97, 0xdc, 0x53, 0xf0, 0x8b, 0x51, 0xe3, 0x46, | ||||
| 	0x4a, 0xbc, 0x46, 0xe0, 0x88, 0x15, 0x99, 0x50, 0x94, 0xf6, 0x88, 0x9a, 0x2f, 0xba, 0x33, 0x88, | ||||
| 	0xda, 0xfa, 0x58, 0x42, 0xb0, 0xc2, 0x98, 0xef, 0x41, 0x49, 0x0c, 0x1f, 0xbb, 0x84, 0x5b, 0x22, | ||||
| 	0x80, 0x18, 0x71, 0x8f, 0x1e, 0x38, 0xde, 0x89, 0x32, 0x2d, 0x0a, 0xa0, 0x03, 0x05, 0xc7, 0x11, | ||||
| 	0xc5, 0x65, 0x25, 0x36, 0x37, 0x63, 0x89, 0xfd, 0x73, 0x0e, 0x2a, 0x42, 0xbb, 0xae, 0xda, 0xdf, | ||||
| 	0x82, 0xaa, 0x9b, 0xbc, 0x93, 0xb2, 0xe2, 0x86, 0x12, 0x98, 0x8e, 0x52, 0x9c, 0xa6, 0x15, 0xcc, | ||||
| 	0x47, 0x0e, 0x71, 0xed, 0x88, 0x39, 0x97, 0x66, 0xbe, 0x97, 0x44, 0xe2, 0x34, 0xad, 0xc8, 0xc5, | ||||
| 	0xa7, 0xe2, 0xb5, 0x55, 0x77, 0x8c, 0x72, 0xf1, 0xfb, 0x02, 0x88, 0x43, 0xdc, 0x65, 0x37, 0x9e, | ||||
| 	0x9f, 0xed, 0xc6, 0xe8, 0x0e, 0x2c, 0x8a, 0xf6, 0xe8, 0x0f, 0xb8, 0x1e, 0x21, 0x0a, 0xb2, 0x91, | ||||
| 	0xa2, 0xf3, 0x51, 0x63, 0xf1, 0x9d, 0x14, 0x06, 0x8f, 0x51, 0x9a, 0x1f, 0x00, 0xc0, 0xde, 0xe1, | ||||
| 	0x4f, 0x48, 0x37, 0x7c, 0xad, 0xab, 0x07, 0x67, 0x51, 0x6f, 0xd5, 0xbe, 0x26, 0xa0, 0xca, 0x21, | ||||
| 	0x71, 0xbd, 0x4d, 0xe0, 0x70, 0x8a, 0x12, 0xb5, 0xa0, 0x1c, 0x0d, 0xd3, 0xaa, 0x96, 0xac, 0x28, | ||||
| 	0xb6, 0x72, 0x34, 0x71, 0xe3, 0x98, 0x26, 0x15, 0x3a, 0xf3, 0x57, 0x86, 0x4e, 0x1b, 0xf2, 0x03, | ||||
| 	0xc7, 0x96, 0x57, 0x2f, 0xb7, 0xbf, 0xaa, 0xc3, 0xff, 0xd1, 0x4e, 0xe7, 0x62, 0xd4, 0x78, 0x75, | ||||
| 	0xda, 0xc2, 0xcb, 0xcf, 0x02, 0xc2, 0x9a, 0x8f, 0x76, 0x3a, 0x58, 0x30, 0x5f, 0xf6, 0x18, 0xc5, | ||||
| 	0x19, 0x1f, 0x63, 0x03, 0x40, 0xdd, 0x5a, 0x70, 0x5f, 0x0b, 0x1f, 0x42, 0x2f, 0x16, 0xf7, 0x23, | ||||
| 	0x0c, 0x4e, 0x50, 0x21, 0x06, 0x2b, 0x5d, 0x4a, 0xe4, 0x6f, 0xf1, 0x5c, 0x8c, 0x5b, 0xfd, 0xa0, | ||||
| 	0x56, 0x92, 0x33, 0xdc, 0x97, 0xb3, 0x55, 0x27, 0xc1, 0xd6, 0x7e, 0x45, 0xa9, 0x59, 0xd9, 0x1a, | ||||
| 	0x17, 0x86, 0x27, 0xe5, 0x23, 0x1f, 0x56, 0x6c, 0x31, 0x8d, 0xa6, 0x94, 0x96, 0x67, 0x56, 0x7a, | ||||
| 	0x43, 0x28, 0xec, 0x8c, 0x0b, 0xc2, 0x93, 0xb2, 0xd1, 0x8f, 0x60, 0x55, 0x03, 0x27, 0xe7, 0xda, | ||||
| 	0x1a, 0x48, 0x4f, 0xd5, 0xc5, 0xa4, 0xdd, 0x99, 0x4a, 0x85, 0x3f, 0x46, 0x02, 0xb2, 0xa1, 0xe8, | ||||
| 	0x86, 0xbd, 0xa5, 0x22, 0x0b, 0xfb, 0xb7, 0xb3, 0xdd, 0x22, 0x8e, 0xfe, 0x66, 0xb2, 0xa7, 0x44, | ||||
| 	0x73, 0xa3, 0x6a, 0x27, 0x4a, 0x36, 0x3a, 0x85, 0x8a, 0xe5, 0x79, 0x3e, 0xb7, 0xc2, 0x49, 0x7b, | ||||
| 	0x41, 0xaa, 0xda, 0x9c, 0x59, 0xd5, 0x66, 0x2c, 0x63, 0xac, 0x87, 0x25, 0x30, 0x38, 0xa9, 0x0a, | ||||
| 	0x3d, 0x85, 0x25, 0xff, 0xa9, 0x47, 0x28, 0x26, 0x47, 0x84, 0x12, 0x4f, 0xac, 0x65, 0x55, 0xa9, | ||||
| 	0xfd, 0xeb, 0x19, 0xb5, 0xa7, 0x98, 0xe3, 0x90, 0x4e, 0xc3, 0x19, 0x1e, 0xd7, 0x22, 0xf6, 0xd0, | ||||
| 	0x23, 0xc7, 0xb3, 0x5c, 0xe7, 0x67, 0x84, 0xb2, 0xda, 0x62, 0xbc, 0x87, 0xde, 0x8b, 0xa0, 0x38, | ||||
| 	0x41, 0x81, 0xbe, 0x01, 0x95, 0xae, 0x3b, 0x60, 0x9c, 0x50, 0x59, 0x21, 0x96, 0x64, 0x06, 0x45, | ||||
| 	0xf7, 0xdb, 0x8a, 0x51, 0x38, 0x49, 0xb7, 0xfa, 0x4d, 0xa8, 0xfc, 0x9f, 0x7d, 0x51, 0xf4, 0xd5, | ||||
| 	0x71, 0x87, 0xce, 0xd4, 0x57, 0xff, 0x6b, 0xc0, 0x62, 0xda, 0x0d, 0xd1, 0x34, 0x66, 0x4c, 0x5d, | ||||
| 	0xf6, 0x75, 0xad, 0xcc, 0x4f, 0xad, 0x95, 0xaa, 0x24, 0xcd, 0x7f, 0x92, 0x92, 0xb4, 0x01, 0x60, | ||||
| 	0x05, 0x8e, 0xae, 0x46, 0x61, 0x75, 0x8b, 0xea, 0x49, 0xbc, 0x38, 0xe3, 0x04, 0x95, 0x78, 0xb0, | ||||
| 	0xae, 0xef, 0x71, 0xea, 0xbb, 0x2e, 0xa1, 0xb2, 0x82, 0x95, 0xc2, 0x07, 0xdb, 0x8a, 0xa0, 0x38, | ||||
| 	0x41, 0x61, 0xee, 0x41, 0x7a, 0xe3, 0x43, 0x77, 0x43, 0xc3, 0xc3, 0xbb, 0xdf, 0x9a, 0xd9, 0x68, | ||||
| 	0xf3, 0x16, 0x94, 0xb1, 0xef, 0xf3, 0x7d, 0x8b, 0x1f, 0x33, 0xd4, 0x80, 0x42, 0x20, 0x7e, 0xa8, | ||||
| 	0x75, 0x5e, 0x7e, 0xe7, 0x90, 0x18, 0x1c, 0xc2, 0xcd, 0xdf, 0x18, 0xf0, 0xca, 0xd4, 0xed, 0x5a, | ||||
| 	0x38, 0xa0, 0x1b, 0x9d, 0x94, 0x49, 0x91, 0x03, 0x62, 0x3a, 0x9c, 0xa0, 0x12, 0x6d, 0x3b, 0xb5, | ||||
| 	0x92, 0x8f, 0xb7, 0xed, 0x94, 0x36, 0x9c, 0xa6, 0x35, 0xff, 0x93, 0x83, 0xe2, 0x01, 0xb7, 0xf8, | ||||
| 	0x80, 0xa1, 0x27, 0x50, 0x12, 0xd9, 0x63, 0x5b, 0xdc, 0x92, 0x9a, 0x33, 0x7f, 0xb1, 0xd2, 0xe3, | ||||
| 	0x4f, 0xdc, 0xb1, 0x34, 0x04, 0x47, 0x12, 0xc5, 0xaa, 0xca, 0xa4, 0x1e, 0x65, 0x5e, 0x54, 0x72, | ||||
| 	0x42, 0xed, 0x58, 0x61, 0xc5, 0xb8, 0xde, 0x27, 0x8c, 0x59, 0x3d, 0x1d, 0x6b, 0xd1, 0xb8, 0xbe, | ||||
| 	0x1b, 0x82, 0xb1, 0xc6, 0xa3, 0xb7, 0xa0, 0x48, 0x89, 0xc5, 0xa2, 0x21, 0xa2, 0xae, 0x45, 0x62, | ||||
| 	0x09, 0xbd, 0x18, 0x35, 0x16, 0x94, 0x70, 0x79, 0xc6, 0x8a, 0x1a, 0xbd, 0x0b, 0xd7, 0x6c, 0xc2, | ||||
| 	0x2d, 0xc7, 0x0d, 0x67, 0x87, 0xcc, 0xdf, 0x0e, 0x42, 0x61, 0x9d, 0x90, 0xb5, 0x5d, 0x11, 0x36, | ||||
| 	0xa9, 0x03, 0xd6, 0x02, 0x45, 0x9e, 0x74, 0x7d, 0x9b, 0xc8, 0x38, 0x2c, 0xc4, 0x79, 0xb2, 0xe5, | ||||
| 	0xdb, 0x04, 0x4b, 0x8c, 0xf9, 0xcc, 0x80, 0x4a, 0x28, 0x69, 0xcb, 0x1a, 0x30, 0x82, 0xd6, 0xa3, | ||||
| 	0x5b, 0x84, 0xcf, 0xad, 0x1b, 0xdb, 0xfc, 0x3b, 0x67, 0x01, 0xb9, 0x18, 0x35, 0xca, 0x92, 0x4c, | ||||
| 	0x1c, 0xa2, 0x0b, 0x24, 0x7c, 0x94, 0xbb, 0xc2, 0x47, 0xaf, 0x41, 0x41, 0xce, 0x69, 0xca, 0x99, | ||||
| 	0xd1, 0x58, 0x26, 0x67, 0x39, 0x1c, 0xe2, 0xcc, 0xdf, 0xe7, 0xa0, 0x9a, 0xba, 0x5c, 0x86, 0xd1, | ||||
| 	0x28, 0xda, 0xbd, 0x72, 0x19, 0xf6, 0xf9, 0xe9, 0x1f, 0x11, 0x7f, 0x00, 0xc5, 0xae, 0xb8, 0x9f, | ||||
| 	0xfe, 0x8a, 0xbb, 0x3e, 0xcb, 0x53, 0x48, 0xcf, 0xc4, 0x91, 0x24, 0x8f, 0x0c, 0x2b, 0x81, 0xe8, | ||||
| 	0x3e, 0xac, 0x50, 0xc2, 0xe9, 0xd9, 0xe6, 0x11, 0x27, 0x34, 0x39, 0x2c, 0x16, 0xe2, 0xe1, 0x01, | ||||
| 	0x8f, 0x13, 0xe0, 0x49, 0x1e, 0xd3, 0x85, 0x79, 0xd1, 0xd8, 0x85, 0xdb, 0x59, 0xea, 0xb3, 0x55, | ||||
| 	0xe4, 0x76, 0xcd, 0xac, 0xf1, 0xc2, 0x3b, 0x9e, 0xe5, 0xf9, 0x61, 0xb0, 0x17, 0x62, 0xef, 0x3c, | ||||
| 	0x14, 0x40, 0x1c, 0xe2, 0xee, 0x5c, 0x17, 0x0b, 0xe4, 0xaf, 0x9f, 0x37, 0xe6, 0x9e, 0x3d, 0x6f, | ||||
| 	0xcc, 0x7d, 0xf8, 0x5c, 0x2d, 0x93, 0x3f, 0x84, 0x72, 0x3c, 0x46, 0x7c, 0xca, 0x2a, 0xcd, 0x1f, | ||||
| 	0x43, 0x49, 0x44, 0x92, 0x1e, 0x7f, 0xaf, 0x28, 0xfa, 0xe9, 0x72, 0x9c, 0xcb, 0x52, 0x8e, 0xcd, | ||||
| 	0x0d, 0x08, 0xbf, 0xeb, 0x8a, 0x4a, 0xe8, 0x70, 0xd2, 0x4f, 0x55, 0xc2, 0x1d, 0x01, 0xc0, 0x21, | ||||
| 	0x3c, 0xb1, 0x3f, 0xff, 0xd2, 0x00, 0x90, 0x7b, 0xc2, 0xf6, 0x50, 0xec, 0x76, 0x6b, 0x30, 0x2f, | ||||
| 	0x4a, 0xec, 0xb8, 0x61, 0x32, 0x05, 0x24, 0x06, 0x3d, 0x82, 0xa2, 0x2f, 0xc7, 0x0b, 0xf5, 0xf1, | ||||
| 	0xef, 0xcd, 0xa9, 0x51, 0xa3, 0xfe, 0xc9, 0xd3, 0xc4, 0xd6, 0xd3, 0xed, 0x53, 0x4e, 0x3c, 0x61, | ||||
| 	0x63, 0x1c, 0x31, 0xe1, 0x8c, 0x82, 0x95, 0xb0, 0xf6, 0xeb, 0x2f, 0x5e, 0xd6, 0xe7, 0x3e, 0x7a, | ||||
| 	0x59, 0x9f, 0xfb, 0xfb, 0xcb, 0xfa, 0xdc, 0xfb, 0xe7, 0x75, 0xe3, 0xc5, 0x79, 0xdd, 0xf8, 0xe8, | ||||
| 	0xbc, 0x6e, 0xfc, 0xf3, 0xbc, 0x6e, 0x3c, 0xfb, 0x57, 0x7d, 0xee, 0xdd, 0xdc, 0x70, 0xfd, 0x7f, | ||||
| 	0x01, 0x00, 0x00, 0xff, 0xff, 0xc3, 0xe1, 0xb9, 0xfd, 0x26, 0x1b, 0x00, 0x00, | ||||
| } | ||||
|   | ||||
| @@ -74,6 +74,9 @@ message APIResource { | ||||
|   // verbs is a list of supported kube verbs (this includes get, list, watch, create, | ||||
|   // update, patch, delete, deletecollection, and proxy) | ||||
|   optional Verbs verbs = 4; | ||||
| 
 | ||||
|   // shortNames is a list of suggested short names of the resource. | ||||
|   repeated string shortNames = 5; | ||||
| } | ||||
| 
 | ||||
| // APIResourceList is a list of APIResource, it is used to expose the name of the | ||||
|   | ||||
| @@ -42,6 +42,7 @@ func AddToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion) | ||||
| 		schema.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal}.WithKind(WatchEventKind), | ||||
| 		&InternalEvent{}, | ||||
| 	) | ||||
| 	// Supports legacy code paths, most callers should use metav1.ParameterCodec for now | ||||
| 	scheme.AddKnownTypes(groupVersion, | ||||
| 		&ListOptions{}, | ||||
| 		&ExportOptions{}, | ||||
| @@ -65,5 +66,8 @@ var ParameterCodec = runtime.NewParameterCodec(scheme) | ||||
| func init() { | ||||
| 	scheme.AddUnversionedTypes(SchemeGroupVersion, | ||||
| 		&ListOptions{}, | ||||
| 		&ExportOptions{}, | ||||
| 		&GetOptions{}, | ||||
| 		&DeleteOptions{}, | ||||
| 	) | ||||
| } | ||||
|   | ||||
| @@ -648,6 +648,8 @@ type APIResource struct { | ||||
| 	// verbs is a list of supported kube verbs (this includes get, list, watch, create, | ||||
| 	// update, patch, delete, deletecollection, and proxy) | ||||
| 	Verbs Verbs `json:"verbs" protobuf:"bytes,4,opt,name=verbs"` | ||||
| 	// shortNames is a list of suggested short names of the resource. | ||||
| 	ShortNames []string `json:"shortNames,omitempty" protobuf:"bytes,5,rep,name=shortNames"` | ||||
| } | ||||
|  | ||||
| // Verbs masks the value so protobuf can generate | ||||
|   | ||||
| @@ -54,6 +54,7 @@ var map_APIResource = map[string]string{ | ||||
| 	"namespaced": "namespaced indicates if a resource is namespaced or not.", | ||||
| 	"kind":       "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')", | ||||
| 	"verbs":      "verbs is a list of supported kube verbs (this includes get, list, watch, create, update, patch, delete, deletecollection, and proxy)", | ||||
| 	"shortNames": "shortNames is a list of suggested short names of the resource.", | ||||
| } | ||||
| 
 | ||||
| func (APIResource) SwaggerDoc() map[string]string { | ||||
|   | ||||
| @@ -115,6 +115,11 @@ func DeepCopy_v1_APIResource(in interface{}, out interface{}, c *conversion.Clon | ||||
| 			*out = make(Verbs, len(*in)) | ||||
| 			copy(*out, *in) | ||||
| 		} | ||||
| 		if in.ShortNames != nil { | ||||
| 			in, out := &in.ShortNames, &out.ShortNames | ||||
| 			*out = make([]string, len(*in)) | ||||
| 			copy(*out, *in) | ||||
| 		} | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -23,7 +23,7 @@ import ( | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"k8s.io/apimachinery/pkg/util/json" | ||||
| 	forkedjson "k8s.io/client-go/third_party/forked/golang/json" | ||||
| 	forkedjson "k8s.io/apimachinery/third_party/forked/golang/json" | ||||
| 
 | ||||
| 	"github.com/davecgh/go-spew/spew" | ||||
| 	"github.com/ghodss/yaml" | ||||
| @@ -69,11 +69,10 @@ func (d *YAMLToJSONDecoder) Decode(into interface{}) error { | ||||
| 	} | ||||
|  | ||||
| 	if len(bytes) != 0 { | ||||
| 		data, err := yaml.YAMLToJSON(bytes) | ||||
| 		err := yaml.Unmarshal(bytes, into) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 			return YAMLSyntaxError{err} | ||||
| 		} | ||||
| 		return json.Unmarshal(data, into) | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
| @@ -184,6 +183,23 @@ type YAMLOrJSONDecoder struct { | ||||
| 	rawData []byte | ||||
| } | ||||
|  | ||||
| type JSONSyntaxError struct { | ||||
| 	Line int | ||||
| 	Err  error | ||||
| } | ||||
|  | ||||
| func (e JSONSyntaxError) Error() string { | ||||
| 	return fmt.Sprintf("json: line %d: %s", e.Line, e.Err.Error()) | ||||
| } | ||||
|  | ||||
| type YAMLSyntaxError struct { | ||||
| 	err error | ||||
| } | ||||
|  | ||||
| func (e YAMLSyntaxError) Error() string { | ||||
| 	return e.err.Error() | ||||
| } | ||||
|  | ||||
| // NewYAMLOrJSONDecoder returns a decoder that will process YAML documents | ||||
| // or JSON documents from the given reader as a stream. bufferSize determines | ||||
| // how far into the stream the decoder will look to figure out whether this | ||||
| @@ -226,7 +242,10 @@ func (d *YAMLOrJSONDecoder) Decode(into interface{}) error { | ||||
|  | ||||
| 			start := strings.LastIndex(js[:syntax.Offset], "\n") + 1 | ||||
| 			line := strings.Count(js[:start], "\n") | ||||
| 			return fmt.Errorf("json: line %d: %s", line, syntax.Error()) | ||||
| 			return JSONSyntaxError{ | ||||
| 				Line: line, | ||||
| 				Err:  fmt.Errorf(syntax.Error()), | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return err | ||||
|   | ||||
| @@ -30,9 +30,9 @@ import ( | ||||
|  | ||||
| 	apierrors "k8s.io/apimachinery/pkg/api/errors" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/third_party/forked/golang/netutil" | ||||
| 	"k8s.io/client-go/pkg/api" | ||||
| 	"k8s.io/client-go/pkg/util/httpstream" | ||||
| 	"k8s.io/client-go/third_party/forked/golang/netutil" | ||||
| ) | ||||
|  | ||||
| // SpdyRoundTripper knows how to upgrade an HTTP request to one that supports | ||||
|   | ||||
| @@ -1,79 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 util | ||||
|  | ||||
| // A simple trie implementation with Add an HasPrefix methods only. | ||||
| type Trie struct { | ||||
| 	children map[byte]*Trie | ||||
| 	wordTail bool | ||||
| 	word     string | ||||
| } | ||||
|  | ||||
| // CreateTrie creates a Trie and add all strings in the provided list to it. | ||||
| func CreateTrie(list []string) Trie { | ||||
| 	ret := Trie{ | ||||
| 		children: make(map[byte]*Trie), | ||||
| 		wordTail: false, | ||||
| 	} | ||||
| 	for _, v := range list { | ||||
| 		ret.Add(v) | ||||
| 	} | ||||
| 	return ret | ||||
| } | ||||
|  | ||||
| // Add adds a word to this trie | ||||
| func (t *Trie) Add(v string) { | ||||
| 	root := t | ||||
| 	for _, b := range []byte(v) { | ||||
| 		child, exists := root.children[b] | ||||
| 		if !exists { | ||||
| 			child = &Trie{ | ||||
| 				children: make(map[byte]*Trie), | ||||
| 				wordTail: false, | ||||
| 			} | ||||
| 			root.children[b] = child | ||||
| 		} | ||||
| 		root = child | ||||
| 	} | ||||
| 	root.wordTail = true | ||||
| 	root.word = v | ||||
| } | ||||
|  | ||||
| // HasPrefix returns true of v has any of the prefixes stored in this trie. | ||||
| func (t *Trie) HasPrefix(v string) bool { | ||||
| 	_, has := t.GetPrefix(v) | ||||
| 	return has | ||||
| } | ||||
|  | ||||
| // GetPrefix is like HasPrefix but return the prefix in case of match or empty string otherwise. | ||||
| func (t *Trie) GetPrefix(v string) (string, bool) { | ||||
| 	root := t | ||||
| 	if root.wordTail { | ||||
| 		return root.word, true | ||||
| 	} | ||||
| 	for _, b := range []byte(v) { | ||||
| 		child, exists := root.children[b] | ||||
| 		if !exists { | ||||
| 			return "", false | ||||
| 		} | ||||
| 		if child.wordTail { | ||||
| 			return child.word, true | ||||
| 		} | ||||
| 		root = child | ||||
| 	} | ||||
| 	return "", false | ||||
| } | ||||
| @@ -1,211 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| import ( | ||||
| 	"math" | ||||
| 	"sync" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/juju/ratelimit" | ||||
| ) | ||||
|  | ||||
| type RateLimiter interface { | ||||
| 	// When gets an item and gets to decide how long that item should wait | ||||
| 	When(item interface{}) time.Duration | ||||
| 	// Forget indicates that an item is finished being retried.  Doesn't matter whether its for perm failing | ||||
| 	// or for success, we'll stop tracking it | ||||
| 	Forget(item interface{}) | ||||
| 	// NumRequeues returns back how many failures the item has had | ||||
| 	NumRequeues(item interface{}) int | ||||
| } | ||||
|  | ||||
| // DefaultControllerRateLimiter is a no-arg constructor for a default rate limiter for a workqueue.  It has | ||||
| // both overall and per-item rate limitting.  The overall is a token bucket and the per-item is exponential | ||||
| func DefaultControllerRateLimiter() RateLimiter { | ||||
| 	return NewMaxOfRateLimiter( | ||||
| 		NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second), | ||||
| 		// 10 qps, 100 bucket size.  This is only for retry speed and its only the overall factor (not per item) | ||||
| 		&BucketRateLimiter{Bucket: ratelimit.NewBucketWithRate(float64(10), int64(100))}, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| // BucketRateLimiter adapts a standard bucket to the workqueue ratelimiter API | ||||
| type BucketRateLimiter struct { | ||||
| 	*ratelimit.Bucket | ||||
| } | ||||
|  | ||||
| var _ RateLimiter = &BucketRateLimiter{} | ||||
|  | ||||
| func (r *BucketRateLimiter) When(item interface{}) time.Duration { | ||||
| 	return r.Bucket.Take(1) | ||||
| } | ||||
|  | ||||
| func (r *BucketRateLimiter) NumRequeues(item interface{}) int { | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| func (r *BucketRateLimiter) Forget(item interface{}) { | ||||
| } | ||||
|  | ||||
| // ItemExponentialFailureRateLimiter does a simple baseDelay*10^<num-failures> limit | ||||
| // dealing with max failures and expiration are up to the caller | ||||
| type ItemExponentialFailureRateLimiter struct { | ||||
| 	failuresLock sync.Mutex | ||||
| 	failures     map[interface{}]int | ||||
|  | ||||
| 	baseDelay time.Duration | ||||
| 	maxDelay  time.Duration | ||||
| } | ||||
|  | ||||
| var _ RateLimiter = &ItemExponentialFailureRateLimiter{} | ||||
|  | ||||
| func NewItemExponentialFailureRateLimiter(baseDelay time.Duration, maxDelay time.Duration) RateLimiter { | ||||
| 	return &ItemExponentialFailureRateLimiter{ | ||||
| 		failures:  map[interface{}]int{}, | ||||
| 		baseDelay: baseDelay, | ||||
| 		maxDelay:  maxDelay, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func DefaultItemBasedRateLimiter() RateLimiter { | ||||
| 	return NewItemExponentialFailureRateLimiter(time.Millisecond, 1000*time.Second) | ||||
| } | ||||
|  | ||||
| func (r *ItemExponentialFailureRateLimiter) When(item interface{}) time.Duration { | ||||
| 	r.failuresLock.Lock() | ||||
| 	defer r.failuresLock.Unlock() | ||||
|  | ||||
| 	exp := r.failures[item] | ||||
| 	r.failures[item] = r.failures[item] + 1 | ||||
|  | ||||
| 	// The backoff is capped such that 'calculated' value never overflows. | ||||
| 	backoff := float64(r.baseDelay.Nanoseconds()) * math.Pow(2, float64(exp)) | ||||
| 	if backoff > math.MaxInt64 { | ||||
| 		return r.maxDelay | ||||
| 	} | ||||
|  | ||||
| 	calculated := time.Duration(backoff) | ||||
| 	if calculated > r.maxDelay { | ||||
| 		return r.maxDelay | ||||
| 	} | ||||
|  | ||||
| 	return calculated | ||||
| } | ||||
|  | ||||
| func (r *ItemExponentialFailureRateLimiter) NumRequeues(item interface{}) int { | ||||
| 	r.failuresLock.Lock() | ||||
| 	defer r.failuresLock.Unlock() | ||||
|  | ||||
| 	return r.failures[item] | ||||
| } | ||||
|  | ||||
| func (r *ItemExponentialFailureRateLimiter) Forget(item interface{}) { | ||||
| 	r.failuresLock.Lock() | ||||
| 	defer r.failuresLock.Unlock() | ||||
|  | ||||
| 	delete(r.failures, item) | ||||
| } | ||||
|  | ||||
| // ItemFastSlowRateLimiter does a quick retry for a certain number of attempts, then a slow retry after that | ||||
| type ItemFastSlowRateLimiter struct { | ||||
| 	failuresLock sync.Mutex | ||||
| 	failures     map[interface{}]int | ||||
|  | ||||
| 	maxFastAttempts int | ||||
| 	fastDelay       time.Duration | ||||
| 	slowDelay       time.Duration | ||||
| } | ||||
|  | ||||
| var _ RateLimiter = &ItemFastSlowRateLimiter{} | ||||
|  | ||||
| func NewItemFastSlowRateLimiter(fastDelay, slowDelay time.Duration, maxFastAttempts int) RateLimiter { | ||||
| 	return &ItemFastSlowRateLimiter{ | ||||
| 		failures:        map[interface{}]int{}, | ||||
| 		fastDelay:       fastDelay, | ||||
| 		slowDelay:       slowDelay, | ||||
| 		maxFastAttempts: maxFastAttempts, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (r *ItemFastSlowRateLimiter) When(item interface{}) time.Duration { | ||||
| 	r.failuresLock.Lock() | ||||
| 	defer r.failuresLock.Unlock() | ||||
|  | ||||
| 	r.failures[item] = r.failures[item] + 1 | ||||
|  | ||||
| 	if r.failures[item] <= r.maxFastAttempts { | ||||
| 		return r.fastDelay | ||||
| 	} | ||||
|  | ||||
| 	return r.slowDelay | ||||
| } | ||||
|  | ||||
| func (r *ItemFastSlowRateLimiter) NumRequeues(item interface{}) int { | ||||
| 	r.failuresLock.Lock() | ||||
| 	defer r.failuresLock.Unlock() | ||||
|  | ||||
| 	return r.failures[item] | ||||
| } | ||||
|  | ||||
| func (r *ItemFastSlowRateLimiter) Forget(item interface{}) { | ||||
| 	r.failuresLock.Lock() | ||||
| 	defer r.failuresLock.Unlock() | ||||
|  | ||||
| 	delete(r.failures, item) | ||||
| } | ||||
|  | ||||
| // MaxOfRateLimiter calls every RateLimiter and returns the worst case response | ||||
| // When used with a token bucket limiter, the burst could be apparently exceeded in cases where particular items | ||||
| // were separately delayed a longer time. | ||||
| type MaxOfRateLimiter struct { | ||||
| 	limiters []RateLimiter | ||||
| } | ||||
|  | ||||
| func (r *MaxOfRateLimiter) When(item interface{}) time.Duration { | ||||
| 	ret := time.Duration(0) | ||||
| 	for _, limiter := range r.limiters { | ||||
| 		curr := limiter.When(item) | ||||
| 		if curr > ret { | ||||
| 			ret = curr | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return ret | ||||
| } | ||||
|  | ||||
| func NewMaxOfRateLimiter(limiters ...RateLimiter) RateLimiter { | ||||
| 	return &MaxOfRateLimiter{limiters: limiters} | ||||
| } | ||||
|  | ||||
| func (r *MaxOfRateLimiter) NumRequeues(item interface{}) int { | ||||
| 	ret := 0 | ||||
| 	for _, limiter := range r.limiters { | ||||
| 		curr := limiter.NumRequeues(item) | ||||
| 		if curr > ret { | ||||
| 			ret = curr | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return ret | ||||
| } | ||||
|  | ||||
| func (r *MaxOfRateLimiter) Forget(item interface{}) { | ||||
| 	for _, limiter := range r.limiters { | ||||
| 		limiter.Forget(item) | ||||
| 	} | ||||
| } | ||||
| @@ -1,184 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| func TestItemExponentialFailureRateLimiter(t *testing.T) { | ||||
| 	limiter := NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1*time.Second) | ||||
|  | ||||
| 	if e, a := 1*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 2*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 4*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 8*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 16*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5, limiter.NumRequeues("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	if e, a := 1*time.Millisecond, limiter.When("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 2*time.Millisecond, limiter.When("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 2, limiter.NumRequeues("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	limiter.Forget("one") | ||||
| 	if e, a := 0, limiter.NumRequeues("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 1*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestItemExponentialFailureRateLimiterOverFlow(t *testing.T) { | ||||
| 	limiter := NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1000*time.Second) | ||||
| 	for i := 0; i < 5; i++ { | ||||
| 		limiter.When("one") | ||||
| 	} | ||||
| 	if e, a := 32*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	for i := 0; i < 1000; i++ { | ||||
| 		limiter.When("overflow1") | ||||
| 	} | ||||
| 	if e, a := 1000*time.Second, limiter.When("overflow1"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	limiter = NewItemExponentialFailureRateLimiter(1*time.Minute, 1000*time.Hour) | ||||
| 	for i := 0; i < 2; i++ { | ||||
| 		limiter.When("two") | ||||
| 	} | ||||
| 	if e, a := 4*time.Minute, limiter.When("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	for i := 0; i < 1000; i++ { | ||||
| 		limiter.When("overflow2") | ||||
| 	} | ||||
| 	if e, a := 1000*time.Hour, limiter.When("overflow2"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestItemFastSlowRateLimiter(t *testing.T) { | ||||
| 	limiter := NewItemFastSlowRateLimiter(5*time.Millisecond, 10*time.Second, 3) | ||||
|  | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 10*time.Second, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 10*time.Second, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5, limiter.NumRequeues("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 2, limiter.NumRequeues("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	limiter.Forget("one") | ||||
| 	if e, a := 0, limiter.NumRequeues("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestMaxOfRateLimiter(t *testing.T) { | ||||
| 	limiter := NewMaxOfRateLimiter( | ||||
| 		NewItemFastSlowRateLimiter(5*time.Millisecond, 3*time.Second, 3), | ||||
| 		NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1*time.Second), | ||||
| 	) | ||||
|  | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 3*time.Second, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 3*time.Second, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5, limiter.NumRequeues("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 2, limiter.NumRequeues("two"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	limiter.Forget("one") | ||||
| 	if e, a := 0, limiter.NumRequeues("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 5*time.Millisecond, limiter.When("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -1,246 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| import ( | ||||
| 	"sort" | ||||
| 	"time" | ||||
|  | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| ) | ||||
|  | ||||
| // DelayingInterface is an Interface that can Add an item at a later time. This makes it easier to | ||||
| // requeue items after failures without ending up in a hot-loop. | ||||
| type DelayingInterface interface { | ||||
| 	Interface | ||||
| 	// AddAfter adds an item to the workqueue after the indicated duration has passed | ||||
| 	AddAfter(item interface{}, duration time.Duration) | ||||
| } | ||||
|  | ||||
| // NewDelayingQueue constructs a new workqueue with delayed queuing ability | ||||
| func NewDelayingQueue() DelayingInterface { | ||||
| 	return newDelayingQueue(clock.RealClock{}, "") | ||||
| } | ||||
|  | ||||
| func NewNamedDelayingQueue(name string) DelayingInterface { | ||||
| 	return newDelayingQueue(clock.RealClock{}, name) | ||||
| } | ||||
|  | ||||
| func newDelayingQueue(clock clock.Clock, name string) DelayingInterface { | ||||
| 	ret := &delayingType{ | ||||
| 		Interface:          NewNamed(name), | ||||
| 		clock:              clock, | ||||
| 		heartbeat:          clock.Tick(maxWait), | ||||
| 		stopCh:             make(chan struct{}), | ||||
| 		waitingTimeByEntry: map[t]time.Time{}, | ||||
| 		waitingForAddCh:    make(chan waitFor, 1000), | ||||
| 		metrics:            newRetryMetrics(name), | ||||
| 	} | ||||
|  | ||||
| 	go ret.waitingLoop() | ||||
|  | ||||
| 	return ret | ||||
| } | ||||
|  | ||||
| // delayingType wraps an Interface and provides delayed re-enquing | ||||
| type delayingType struct { | ||||
| 	Interface | ||||
|  | ||||
| 	// clock tracks time for delayed firing | ||||
| 	clock clock.Clock | ||||
|  | ||||
| 	// stopCh lets us signal a shutdown to the waiting loop | ||||
| 	stopCh chan struct{} | ||||
|  | ||||
| 	// heartbeat ensures we wait no more than maxWait before firing | ||||
| 	// | ||||
| 	// TODO: replace with Ticker (and add to clock) so this can be cleaned up. | ||||
| 	// clock.Tick will leak. | ||||
| 	heartbeat <-chan time.Time | ||||
|  | ||||
| 	// waitingForAdd is an ordered slice of items to be added to the contained work queue | ||||
| 	waitingForAdd []waitFor | ||||
| 	// waitingTimeByEntry holds wait time by entry, so we can lookup pre-existing indexes | ||||
| 	waitingTimeByEntry map[t]time.Time | ||||
| 	// waitingForAddCh is a buffered channel that feeds waitingForAdd | ||||
| 	waitingForAddCh chan waitFor | ||||
|  | ||||
| 	// metrics counts the number of retries | ||||
| 	metrics retryMetrics | ||||
| } | ||||
|  | ||||
| // waitFor holds the data to add and the time it should be added | ||||
| type waitFor struct { | ||||
| 	data    t | ||||
| 	readyAt time.Time | ||||
| } | ||||
|  | ||||
| // ShutDown gives a way to shut off this queue | ||||
| func (q *delayingType) ShutDown() { | ||||
| 	q.Interface.ShutDown() | ||||
| 	close(q.stopCh) | ||||
| } | ||||
|  | ||||
| // AddAfter adds the given item to the work queue after the given delay | ||||
| func (q *delayingType) AddAfter(item interface{}, duration time.Duration) { | ||||
| 	// don't add if we're already shutting down | ||||
| 	if q.ShuttingDown() { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	q.metrics.retry() | ||||
|  | ||||
| 	// immediately add things with no delay | ||||
| 	if duration <= 0 { | ||||
| 		q.Add(item) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	select { | ||||
| 	case <-q.stopCh: | ||||
| 		// unblock if ShutDown() is called | ||||
| 	case q.waitingForAddCh <- waitFor{data: item, readyAt: q.clock.Now().Add(duration)}: | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // maxWait keeps a max bound on the wait time. It's just insurance against weird things happening. | ||||
| // Checking the queue every 10 seconds isn't expensive and we know that we'll never end up with an | ||||
| // expired item sitting for more than 10 seconds. | ||||
| const maxWait = 10 * time.Second | ||||
|  | ||||
| // waitingLoop runs until the workqueue is shutdown and keeps a check on the list of items to be added. | ||||
| func (q *delayingType) waitingLoop() { | ||||
| 	defer utilruntime.HandleCrash() | ||||
|  | ||||
| 	// Make a placeholder channel to use when there are no items in our list | ||||
| 	never := make(<-chan time.Time) | ||||
|  | ||||
| 	for { | ||||
| 		if q.Interface.ShuttingDown() { | ||||
| 			// discard waiting entries | ||||
| 			q.waitingForAdd = nil | ||||
| 			q.waitingTimeByEntry = nil | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		now := q.clock.Now() | ||||
|  | ||||
| 		// Add ready entries | ||||
| 		readyEntries := 0 | ||||
| 		for _, entry := range q.waitingForAdd { | ||||
| 			if entry.readyAt.After(now) { | ||||
| 				break | ||||
| 			} | ||||
| 			q.Add(entry.data) | ||||
| 			delete(q.waitingTimeByEntry, entry.data) | ||||
| 			readyEntries++ | ||||
| 		} | ||||
| 		q.waitingForAdd = q.waitingForAdd[readyEntries:] | ||||
|  | ||||
| 		// Set up a wait for the first item's readyAt (if one exists) | ||||
| 		nextReadyAt := never | ||||
| 		if len(q.waitingForAdd) > 0 { | ||||
| 			nextReadyAt = q.clock.After(q.waitingForAdd[0].readyAt.Sub(now)) | ||||
| 		} | ||||
|  | ||||
| 		select { | ||||
| 		case <-q.stopCh: | ||||
| 			return | ||||
|  | ||||
| 		case <-q.heartbeat: | ||||
| 			// continue the loop, which will add ready items | ||||
|  | ||||
| 		case <-nextReadyAt: | ||||
| 			// continue the loop, which will add ready items | ||||
|  | ||||
| 		case waitEntry := <-q.waitingForAddCh: | ||||
| 			if waitEntry.readyAt.After(q.clock.Now()) { | ||||
| 				q.waitingForAdd = insert(q.waitingForAdd, q.waitingTimeByEntry, waitEntry) | ||||
| 			} else { | ||||
| 				q.Add(waitEntry.data) | ||||
| 			} | ||||
|  | ||||
| 			drained := false | ||||
| 			for !drained { | ||||
| 				select { | ||||
| 				case waitEntry := <-q.waitingForAddCh: | ||||
| 					if waitEntry.readyAt.After(q.clock.Now()) { | ||||
| 						q.waitingForAdd = insert(q.waitingForAdd, q.waitingTimeByEntry, waitEntry) | ||||
| 					} else { | ||||
| 						q.Add(waitEntry.data) | ||||
| 					} | ||||
| 				default: | ||||
| 					drained = true | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // inserts the given entry into the sorted entries list | ||||
| // same semantics as append()... the given slice may be modified, | ||||
| // and the returned value should be used | ||||
| // | ||||
| // TODO: This should probably be converted to use container/heap to improve | ||||
| // running time for a large number of items. | ||||
| func insert(entries []waitFor, knownEntries map[t]time.Time, entry waitFor) []waitFor { | ||||
| 	// if the entry is already in our retry list and the existing time is before the new one, just skip it | ||||
| 	existingTime, exists := knownEntries[entry.data] | ||||
| 	if exists && existingTime.Before(entry.readyAt) { | ||||
| 		return entries | ||||
| 	} | ||||
|  | ||||
| 	// if the entry exists and is scheduled for later, go ahead and remove the entry | ||||
| 	if exists { | ||||
| 		if existingIndex := findEntryIndex(entries, existingTime, entry.data); existingIndex >= 0 && existingIndex < len(entries) { | ||||
| 			entries = append(entries[:existingIndex], entries[existingIndex+1:]...) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	insertionIndex := sort.Search(len(entries), func(i int) bool { | ||||
| 		return entry.readyAt.Before(entries[i].readyAt) | ||||
| 	}) | ||||
|  | ||||
| 	// grow by 1 | ||||
| 	entries = append(entries, waitFor{}) | ||||
| 	// shift items from the insertion point to the end | ||||
| 	copy(entries[insertionIndex+1:], entries[insertionIndex:]) | ||||
| 	// insert the record | ||||
| 	entries[insertionIndex] = entry | ||||
|  | ||||
| 	knownEntries[entry.data] = entry.readyAt | ||||
|  | ||||
| 	return entries | ||||
| } | ||||
|  | ||||
| // findEntryIndex returns the index for an existing entry | ||||
| func findEntryIndex(entries []waitFor, existingTime time.Time, data t) int { | ||||
| 	index := sort.Search(len(entries), func(i int) bool { | ||||
| 		return entries[i].readyAt.After(existingTime) || existingTime == entries[i].readyAt | ||||
| 	}) | ||||
|  | ||||
| 	// we know this is the earliest possible index, but there could be multiple with the same time | ||||
| 	// iterate from here to find the dupe | ||||
| 	for ; index < len(entries); index++ { | ||||
| 		if entries[index].data == data { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return index | ||||
| } | ||||
| @@ -1,236 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/util/wait" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| ) | ||||
|  | ||||
| func TestSimpleQueue(t *testing.T) { | ||||
| 	fakeClock := clock.NewFakeClock(time.Now()) | ||||
| 	q := newDelayingQueue(fakeClock, "") | ||||
|  | ||||
| 	first := "foo" | ||||
|  | ||||
| 	q.AddAfter(first, 50*time.Millisecond) | ||||
| 	if err := waitForWaitingQueueToFill(q); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if q.Len() != 0 { | ||||
| 		t.Errorf("should not have added") | ||||
| 	} | ||||
|  | ||||
| 	fakeClock.Step(60 * time.Millisecond) | ||||
|  | ||||
| 	if err := waitForAdded(q, 1); err != nil { | ||||
| 		t.Errorf("should have added") | ||||
| 	} | ||||
| 	item, _ := q.Get() | ||||
| 	q.Done(item) | ||||
|  | ||||
| 	// step past the next heartbeat | ||||
| 	fakeClock.Step(10 * time.Second) | ||||
|  | ||||
| 	err := wait.Poll(1*time.Millisecond, 30*time.Millisecond, func() (done bool, err error) { | ||||
| 		if q.Len() > 0 { | ||||
| 			return false, fmt.Errorf("added to queue") | ||||
| 		} | ||||
|  | ||||
| 		return false, nil | ||||
| 	}) | ||||
| 	if err != wait.ErrWaitTimeout { | ||||
| 		t.Errorf("expected timeout, got: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if q.Len() != 0 { | ||||
| 		t.Errorf("should not have added") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestDeduping(t *testing.T) { | ||||
| 	fakeClock := clock.NewFakeClock(time.Now()) | ||||
| 	q := newDelayingQueue(fakeClock, "") | ||||
|  | ||||
| 	first := "foo" | ||||
|  | ||||
| 	q.AddAfter(first, 50*time.Millisecond) | ||||
| 	if err := waitForWaitingQueueToFill(q); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
| 	q.AddAfter(first, 70*time.Millisecond) | ||||
| 	if err := waitForWaitingQueueToFill(q); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
| 	if q.Len() != 0 { | ||||
| 		t.Errorf("should not have added") | ||||
| 	} | ||||
|  | ||||
| 	// step past the first block, we should receive now | ||||
| 	fakeClock.Step(60 * time.Millisecond) | ||||
| 	if err := waitForAdded(q, 1); err != nil { | ||||
| 		t.Errorf("should have added") | ||||
| 	} | ||||
| 	item, _ := q.Get() | ||||
| 	q.Done(item) | ||||
|  | ||||
| 	// step past the second add | ||||
| 	fakeClock.Step(20 * time.Millisecond) | ||||
| 	if q.Len() != 0 { | ||||
| 		t.Errorf("should not have added") | ||||
| 	} | ||||
|  | ||||
| 	// test again, but this time the earlier should override | ||||
| 	q.AddAfter(first, 50*time.Millisecond) | ||||
| 	q.AddAfter(first, 30*time.Millisecond) | ||||
| 	if err := waitForWaitingQueueToFill(q); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
| 	if q.Len() != 0 { | ||||
| 		t.Errorf("should not have added") | ||||
| 	} | ||||
|  | ||||
| 	fakeClock.Step(40 * time.Millisecond) | ||||
| 	if err := waitForAdded(q, 1); err != nil { | ||||
| 		t.Errorf("should have added") | ||||
| 	} | ||||
| 	item, _ = q.Get() | ||||
| 	q.Done(item) | ||||
|  | ||||
| 	// step past the second add | ||||
| 	fakeClock.Step(20 * time.Millisecond) | ||||
| 	if q.Len() != 0 { | ||||
| 		t.Errorf("should not have added") | ||||
| 	} | ||||
| 	if q.Len() != 0 { | ||||
| 		t.Errorf("should not have added") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestAddTwoFireEarly(t *testing.T) { | ||||
| 	fakeClock := clock.NewFakeClock(time.Now()) | ||||
| 	q := newDelayingQueue(fakeClock, "") | ||||
|  | ||||
| 	first := "foo" | ||||
| 	second := "bar" | ||||
| 	third := "baz" | ||||
|  | ||||
| 	q.AddAfter(first, 1*time.Second) | ||||
| 	q.AddAfter(second, 50*time.Millisecond) | ||||
| 	if err := waitForWaitingQueueToFill(q); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if q.Len() != 0 { | ||||
| 		t.Errorf("should not have added") | ||||
| 	} | ||||
|  | ||||
| 	fakeClock.Step(60 * time.Millisecond) | ||||
|  | ||||
| 	if err := waitForAdded(q, 1); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
| 	item, _ := q.Get() | ||||
| 	if !reflect.DeepEqual(item, second) { | ||||
| 		t.Errorf("expected %v, got %v", second, item) | ||||
| 	} | ||||
|  | ||||
| 	q.AddAfter(third, 2*time.Second) | ||||
|  | ||||
| 	fakeClock.Step(1 * time.Second) | ||||
| 	if err := waitForAdded(q, 1); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
| 	item, _ = q.Get() | ||||
| 	if !reflect.DeepEqual(item, first) { | ||||
| 		t.Errorf("expected %v, got %v", first, item) | ||||
| 	} | ||||
|  | ||||
| 	fakeClock.Step(2 * time.Second) | ||||
| 	if err := waitForAdded(q, 1); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
| 	item, _ = q.Get() | ||||
| 	if !reflect.DeepEqual(item, third) { | ||||
| 		t.Errorf("expected %v, got %v", third, item) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestCopyShifting(t *testing.T) { | ||||
| 	fakeClock := clock.NewFakeClock(time.Now()) | ||||
| 	q := newDelayingQueue(fakeClock, "") | ||||
|  | ||||
| 	first := "foo" | ||||
| 	second := "bar" | ||||
| 	third := "baz" | ||||
|  | ||||
| 	q.AddAfter(first, 1*time.Second) | ||||
| 	q.AddAfter(second, 500*time.Millisecond) | ||||
| 	q.AddAfter(third, 250*time.Millisecond) | ||||
| 	if err := waitForWaitingQueueToFill(q); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if q.Len() != 0 { | ||||
| 		t.Errorf("should not have added") | ||||
| 	} | ||||
|  | ||||
| 	fakeClock.Step(2 * time.Second) | ||||
|  | ||||
| 	if err := waitForAdded(q, 3); err != nil { | ||||
| 		t.Fatalf("unexpected err: %v", err) | ||||
| 	} | ||||
| 	actualFirst, _ := q.Get() | ||||
| 	if !reflect.DeepEqual(actualFirst, third) { | ||||
| 		t.Errorf("expected %v, got %v", third, actualFirst) | ||||
| 	} | ||||
| 	actualSecond, _ := q.Get() | ||||
| 	if !reflect.DeepEqual(actualSecond, second) { | ||||
| 		t.Errorf("expected %v, got %v", second, actualSecond) | ||||
| 	} | ||||
| 	actualThird, _ := q.Get() | ||||
| 	if !reflect.DeepEqual(actualThird, first) { | ||||
| 		t.Errorf("expected %v, got %v", first, actualThird) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func waitForAdded(q DelayingInterface, depth int) error { | ||||
| 	return wait.Poll(1*time.Millisecond, 10*time.Second, func() (done bool, err error) { | ||||
| 		if q.Len() == depth { | ||||
| 			return true, nil | ||||
| 		} | ||||
|  | ||||
| 		return false, nil | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func waitForWaitingQueueToFill(q DelayingInterface) error { | ||||
| 	return wait.Poll(1*time.Millisecond, 10*time.Second, func() (done bool, err error) { | ||||
| 		if len(q.(*delayingType).waitingForAddCh) == 0 { | ||||
| 			return true, nil | ||||
| 		} | ||||
|  | ||||
| 		return false, nil | ||||
| 	}) | ||||
| } | ||||
| @@ -1,195 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // This file provides abstractions for setting the provider (e.g., prometheus) | ||||
| // of metrics. | ||||
|  | ||||
| type queueMetrics interface { | ||||
| 	add(item t) | ||||
| 	get(item t) | ||||
| 	done(item t) | ||||
| } | ||||
|  | ||||
| // GaugeMetric represents a single numerical value that can arbitrarily go up | ||||
| // and down. | ||||
| type GaugeMetric interface { | ||||
| 	Inc() | ||||
| 	Dec() | ||||
| } | ||||
|  | ||||
| // CounterMetric represents a single numerical value that only ever | ||||
| // goes up. | ||||
| type CounterMetric interface { | ||||
| 	Inc() | ||||
| } | ||||
|  | ||||
| // SummaryMetric captures individual observations. | ||||
| type SummaryMetric interface { | ||||
| 	Observe(float64) | ||||
| } | ||||
|  | ||||
| type noopMetric struct{} | ||||
|  | ||||
| func (noopMetric) Inc()            {} | ||||
| func (noopMetric) Dec()            {} | ||||
| func (noopMetric) Observe(float64) {} | ||||
|  | ||||
| type defaultQueueMetrics struct { | ||||
| 	// current depth of a workqueue | ||||
| 	depth GaugeMetric | ||||
| 	// total number of adds handled by a workqueue | ||||
| 	adds CounterMetric | ||||
| 	// how long an item stays in a workqueue | ||||
| 	latency SummaryMetric | ||||
| 	// how long processing an item from a workqueue takes | ||||
| 	workDuration         SummaryMetric | ||||
| 	addTimes             map[t]time.Time | ||||
| 	processingStartTimes map[t]time.Time | ||||
| } | ||||
|  | ||||
| func (m *defaultQueueMetrics) add(item t) { | ||||
| 	if m == nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	m.adds.Inc() | ||||
| 	m.depth.Inc() | ||||
| 	if _, exists := m.addTimes[item]; !exists { | ||||
| 		m.addTimes[item] = time.Now() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (m *defaultQueueMetrics) get(item t) { | ||||
| 	if m == nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	m.depth.Dec() | ||||
| 	m.processingStartTimes[item] = time.Now() | ||||
| 	if startTime, exists := m.addTimes[item]; exists { | ||||
| 		m.latency.Observe(sinceInMicroseconds(startTime)) | ||||
| 		delete(m.addTimes, item) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (m *defaultQueueMetrics) done(item t) { | ||||
| 	if m == nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if startTime, exists := m.processingStartTimes[item]; exists { | ||||
| 		m.workDuration.Observe(sinceInMicroseconds(startTime)) | ||||
| 		delete(m.processingStartTimes, item) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Gets the time since the specified start in microseconds. | ||||
| func sinceInMicroseconds(start time.Time) float64 { | ||||
| 	return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds()) | ||||
| } | ||||
|  | ||||
| type retryMetrics interface { | ||||
| 	retry() | ||||
| } | ||||
|  | ||||
| type defaultRetryMetrics struct { | ||||
| 	retries CounterMetric | ||||
| } | ||||
|  | ||||
| func (m *defaultRetryMetrics) retry() { | ||||
| 	if m == nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	m.retries.Inc() | ||||
| } | ||||
|  | ||||
| // MetricsProvider generates various metrics used by the queue. | ||||
| type MetricsProvider interface { | ||||
| 	NewDepthMetric(name string) GaugeMetric | ||||
| 	NewAddsMetric(name string) CounterMetric | ||||
| 	NewLatencyMetric(name string) SummaryMetric | ||||
| 	NewWorkDurationMetric(name string) SummaryMetric | ||||
| 	NewRetriesMetric(name string) CounterMetric | ||||
| } | ||||
|  | ||||
| type noopMetricsProvider struct{} | ||||
|  | ||||
| func (_ noopMetricsProvider) NewDepthMetric(name string) GaugeMetric { | ||||
| 	return noopMetric{} | ||||
| } | ||||
|  | ||||
| func (_ noopMetricsProvider) NewAddsMetric(name string) CounterMetric { | ||||
| 	return noopMetric{} | ||||
| } | ||||
|  | ||||
| func (_ noopMetricsProvider) NewLatencyMetric(name string) SummaryMetric { | ||||
| 	return noopMetric{} | ||||
| } | ||||
|  | ||||
| func (_ noopMetricsProvider) NewWorkDurationMetric(name string) SummaryMetric { | ||||
| 	return noopMetric{} | ||||
| } | ||||
|  | ||||
| func (_ noopMetricsProvider) NewRetriesMetric(name string) CounterMetric { | ||||
| 	return noopMetric{} | ||||
| } | ||||
|  | ||||
| var metricsFactory = struct { | ||||
| 	metricsProvider MetricsProvider | ||||
| 	setProviders    sync.Once | ||||
| }{ | ||||
| 	metricsProvider: noopMetricsProvider{}, | ||||
| } | ||||
|  | ||||
| func newQueueMetrics(name string) queueMetrics { | ||||
| 	var ret *defaultQueueMetrics | ||||
| 	if len(name) == 0 { | ||||
| 		return ret | ||||
| 	} | ||||
| 	return &defaultQueueMetrics{ | ||||
| 		depth:                metricsFactory.metricsProvider.NewDepthMetric(name), | ||||
| 		adds:                 metricsFactory.metricsProvider.NewAddsMetric(name), | ||||
| 		latency:              metricsFactory.metricsProvider.NewLatencyMetric(name), | ||||
| 		workDuration:         metricsFactory.metricsProvider.NewWorkDurationMetric(name), | ||||
| 		addTimes:             map[t]time.Time{}, | ||||
| 		processingStartTimes: map[t]time.Time{}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func newRetryMetrics(name string) retryMetrics { | ||||
| 	var ret *defaultRetryMetrics | ||||
| 	if len(name) == 0 { | ||||
| 		return ret | ||||
| 	} | ||||
| 	return &defaultRetryMetrics{ | ||||
| 		retries: metricsFactory.metricsProvider.NewRetriesMetric(name), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // SetProvider sets the metrics provider of the metricsFactory. | ||||
| func SetProvider(metricsProvider MetricsProvider) { | ||||
| 	metricsFactory.setProviders.Do(func() { | ||||
| 		metricsFactory.metricsProvider = metricsProvider | ||||
| 	}) | ||||
| } | ||||
| @@ -1,52 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
|  | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| ) | ||||
|  | ||||
| type DoWorkPieceFunc func(piece int) | ||||
|  | ||||
| // Parallelize is a very simple framework that allow for parallelizing | ||||
| // N independent pieces of work. | ||||
| func Parallelize(workers, pieces int, doWorkPiece DoWorkPieceFunc) { | ||||
| 	toProcess := make(chan int, pieces) | ||||
| 	for i := 0; i < pieces; i++ { | ||||
| 		toProcess <- i | ||||
| 	} | ||||
| 	close(toProcess) | ||||
|  | ||||
| 	if pieces < workers { | ||||
| 		workers = pieces | ||||
| 	} | ||||
|  | ||||
| 	wg := sync.WaitGroup{} | ||||
| 	wg.Add(workers) | ||||
| 	for i := 0; i < workers; i++ { | ||||
| 		go func() { | ||||
| 			defer utilruntime.HandleCrash() | ||||
| 			defer wg.Done() | ||||
| 			for piece := range toProcess { | ||||
| 				doWorkPiece(piece) | ||||
| 			} | ||||
| 		}() | ||||
| 	} | ||||
| 	wg.Wait() | ||||
| } | ||||
| @@ -1,172 +0,0 @@ | ||||
| /* | ||||
| Copyright 2015 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 workqueue | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
| ) | ||||
|  | ||||
| type Interface interface { | ||||
| 	Add(item interface{}) | ||||
| 	Len() int | ||||
| 	Get() (item interface{}, shutdown bool) | ||||
| 	Done(item interface{}) | ||||
| 	ShutDown() | ||||
| 	ShuttingDown() bool | ||||
| } | ||||
|  | ||||
| // New constructs a new workqueue (see the package comment). | ||||
| func New() *Type { | ||||
| 	return NewNamed("") | ||||
| } | ||||
|  | ||||
| func NewNamed(name string) *Type { | ||||
| 	return &Type{ | ||||
| 		dirty:      set{}, | ||||
| 		processing: set{}, | ||||
| 		cond:       sync.NewCond(&sync.Mutex{}), | ||||
| 		metrics:    newQueueMetrics(name), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Type is a work queue (see the package comment). | ||||
| type Type struct { | ||||
| 	// queue defines the order in which we will work on items. Every | ||||
| 	// element of queue should be in the dirty set and not in the | ||||
| 	// processing set. | ||||
| 	queue []t | ||||
|  | ||||
| 	// dirty defines all of the items that need to be processed. | ||||
| 	dirty set | ||||
|  | ||||
| 	// Things that are currently being processed are in the processing set. | ||||
| 	// These things may be simultaneously in the dirty set. When we finish | ||||
| 	// processing something and remove it from this set, we'll check if | ||||
| 	// it's in the dirty set, and if so, add it to the queue. | ||||
| 	processing set | ||||
|  | ||||
| 	cond *sync.Cond | ||||
|  | ||||
| 	shuttingDown bool | ||||
|  | ||||
| 	metrics queueMetrics | ||||
| } | ||||
|  | ||||
| type empty struct{} | ||||
| type t interface{} | ||||
| type set map[t]empty | ||||
|  | ||||
| func (s set) has(item t) bool { | ||||
| 	_, exists := s[item] | ||||
| 	return exists | ||||
| } | ||||
|  | ||||
| func (s set) insert(item t) { | ||||
| 	s[item] = empty{} | ||||
| } | ||||
|  | ||||
| func (s set) delete(item t) { | ||||
| 	delete(s, item) | ||||
| } | ||||
|  | ||||
| // Add marks item as needing processing. | ||||
| func (q *Type) Add(item interface{}) { | ||||
| 	q.cond.L.Lock() | ||||
| 	defer q.cond.L.Unlock() | ||||
| 	if q.shuttingDown { | ||||
| 		return | ||||
| 	} | ||||
| 	if q.dirty.has(item) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	q.metrics.add(item) | ||||
|  | ||||
| 	q.dirty.insert(item) | ||||
| 	if q.processing.has(item) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	q.queue = append(q.queue, item) | ||||
| 	q.cond.Signal() | ||||
| } | ||||
|  | ||||
| // Len returns the current queue length, for informational purposes only. You | ||||
| // shouldn't e.g. gate a call to Add() or Get() on Len() being a particular | ||||
| // value, that can't be synchronized properly. | ||||
| func (q *Type) Len() int { | ||||
| 	q.cond.L.Lock() | ||||
| 	defer q.cond.L.Unlock() | ||||
| 	return len(q.queue) | ||||
| } | ||||
|  | ||||
| // Get blocks until it can return an item to be processed. If shutdown = true, | ||||
| // the caller should end their goroutine. You must call Done with item when you | ||||
| // have finished processing it. | ||||
| func (q *Type) Get() (item interface{}, shutdown bool) { | ||||
| 	q.cond.L.Lock() | ||||
| 	defer q.cond.L.Unlock() | ||||
| 	for len(q.queue) == 0 && !q.shuttingDown { | ||||
| 		q.cond.Wait() | ||||
| 	} | ||||
| 	if len(q.queue) == 0 { | ||||
| 		// We must be shutting down. | ||||
| 		return nil, true | ||||
| 	} | ||||
|  | ||||
| 	item, q.queue = q.queue[0], q.queue[1:] | ||||
|  | ||||
| 	q.metrics.get(item) | ||||
|  | ||||
| 	q.processing.insert(item) | ||||
| 	q.dirty.delete(item) | ||||
|  | ||||
| 	return item, false | ||||
| } | ||||
|  | ||||
| // Done marks item as done processing, and if it has been marked as dirty again | ||||
| // while it was being processed, it will be re-added to the queue for | ||||
| // re-processing. | ||||
| func (q *Type) Done(item interface{}) { | ||||
| 	q.cond.L.Lock() | ||||
| 	defer q.cond.L.Unlock() | ||||
|  | ||||
| 	q.metrics.done(item) | ||||
|  | ||||
| 	q.processing.delete(item) | ||||
| 	if q.dirty.has(item) { | ||||
| 		q.queue = append(q.queue, item) | ||||
| 		q.cond.Signal() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ShutDown will cause q to ignore all new items added to it. As soon as the | ||||
| // worker goroutines have drained the existing items in the queue, they will be | ||||
| // instructed to exit. | ||||
| func (q *Type) ShutDown() { | ||||
| 	q.cond.L.Lock() | ||||
| 	defer q.cond.L.Unlock() | ||||
| 	q.shuttingDown = true | ||||
| 	q.cond.Broadcast() | ||||
| } | ||||
|  | ||||
| func (q *Type) ShuttingDown() bool { | ||||
| 	q.cond.L.Lock() | ||||
| 	defer q.cond.L.Unlock() | ||||
|  | ||||
| 	return q.shuttingDown | ||||
| } | ||||
| @@ -1,69 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| // RateLimitingInterface is an interface that rate limits items being added to the queue. | ||||
| type RateLimitingInterface interface { | ||||
| 	DelayingInterface | ||||
|  | ||||
| 	// AddRateLimited adds an item to the workqueue after the rate limiter says its ok | ||||
| 	AddRateLimited(item interface{}) | ||||
|  | ||||
| 	// Forget indicates that an item is finished being retried.  Doesn't matter whether its for perm failing | ||||
| 	// or for success, we'll stop the rate limiter from tracking it.  This only clears the `rateLimiter`, you | ||||
| 	// still have to call `Done` on the queue. | ||||
| 	Forget(item interface{}) | ||||
|  | ||||
| 	// NumRequeues returns back how many times the item was requeued | ||||
| 	NumRequeues(item interface{}) int | ||||
| } | ||||
|  | ||||
| // NewRateLimitingQueue constructs a new workqueue with rateLimited queuing ability | ||||
| // Remember to call Forget!  If you don't, you may end up tracking failures forever. | ||||
| func NewRateLimitingQueue(rateLimiter RateLimiter) RateLimitingInterface { | ||||
| 	return &rateLimitingType{ | ||||
| 		DelayingInterface: NewDelayingQueue(), | ||||
| 		rateLimiter:       rateLimiter, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func NewNamedRateLimitingQueue(rateLimiter RateLimiter, name string) RateLimitingInterface { | ||||
| 	return &rateLimitingType{ | ||||
| 		DelayingInterface: NewNamedDelayingQueue(name), | ||||
| 		rateLimiter:       rateLimiter, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // rateLimitingType wraps an Interface and provides rateLimited re-enquing | ||||
| type rateLimitingType struct { | ||||
| 	DelayingInterface | ||||
|  | ||||
| 	rateLimiter RateLimiter | ||||
| } | ||||
|  | ||||
| // AddRateLimited AddAfter's the item based on the time when the rate limiter says its ok | ||||
| func (q *rateLimitingType) AddRateLimited(item interface{}) { | ||||
| 	q.DelayingInterface.AddAfter(item, q.rateLimiter.When(item)) | ||||
| } | ||||
|  | ||||
| func (q *rateLimitingType) NumRequeues(item interface{}) int { | ||||
| 	return q.rateLimiter.NumRequeues(item) | ||||
| } | ||||
|  | ||||
| func (q *rateLimitingType) Forget(item interface{}) { | ||||
| 	q.rateLimiter.Forget(item) | ||||
| } | ||||
| @@ -1,75 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| ) | ||||
|  | ||||
| func TestRateLimitingQueue(t *testing.T) { | ||||
| 	limiter := NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1*time.Second) | ||||
| 	queue := NewRateLimitingQueue(limiter).(*rateLimitingType) | ||||
| 	fakeClock := clock.NewFakeClock(time.Now()) | ||||
| 	delayingQueue := &delayingType{ | ||||
| 		Interface:       New(), | ||||
| 		clock:           fakeClock, | ||||
| 		heartbeat:       fakeClock.Tick(maxWait), | ||||
| 		stopCh:          make(chan struct{}), | ||||
| 		waitingForAddCh: make(chan waitFor, 1000), | ||||
| 		metrics:         newRetryMetrics(""), | ||||
| 	} | ||||
| 	queue.DelayingInterface = delayingQueue | ||||
|  | ||||
| 	queue.AddRateLimited("one") | ||||
| 	waitEntry := <-delayingQueue.waitingForAddCh | ||||
| 	if e, a := 1*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	queue.AddRateLimited("one") | ||||
| 	waitEntry = <-delayingQueue.waitingForAddCh | ||||
| 	if e, a := 2*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	if e, a := 2, queue.NumRequeues("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	queue.AddRateLimited("two") | ||||
| 	waitEntry = <-delayingQueue.waitingForAddCh | ||||
| 	if e, a := 1*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	queue.AddRateLimited("two") | ||||
| 	waitEntry = <-delayingQueue.waitingForAddCh | ||||
| 	if e, a := 2*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| 	queue.Forget("one") | ||||
| 	if e, a := 0, queue.NumRequeues("one"); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
| 	queue.AddRateLimited("one") | ||||
| 	waitEntry = <-delayingQueue.waitingForAddCh | ||||
| 	if e, a := 1*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a { | ||||
| 		t.Errorf("expected %v, got %v", e, a) | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -1,52 +0,0 @@ | ||||
| /* | ||||
| Copyright 2016 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 workqueue | ||||
|  | ||||
| import "time" | ||||
|  | ||||
| type TimedWorkQueue struct { | ||||
| 	*Type | ||||
| } | ||||
|  | ||||
| type TimedWorkQueueItem struct { | ||||
| 	StartTime time.Time | ||||
| 	Object    interface{} | ||||
| } | ||||
|  | ||||
| func NewTimedWorkQueue() *TimedWorkQueue { | ||||
| 	return &TimedWorkQueue{New()} | ||||
| } | ||||
|  | ||||
| // Add adds the obj along with the current timestamp to the queue. | ||||
| func (q TimedWorkQueue) Add(timedItem *TimedWorkQueueItem) { | ||||
| 	q.Type.Add(timedItem) | ||||
| } | ||||
|  | ||||
| // Get gets the obj along with its timestamp from the queue. | ||||
| func (q TimedWorkQueue) Get() (timedItem *TimedWorkQueueItem, shutdown bool) { | ||||
| 	origin, shutdown := q.Type.Get() | ||||
| 	if origin == nil { | ||||
| 		return nil, shutdown | ||||
| 	} | ||||
| 	timedItem, _ = origin.(*TimedWorkQueueItem) | ||||
| 	return timedItem, shutdown | ||||
| } | ||||
|  | ||||
| func (q TimedWorkQueue) Done(timedItem *TimedWorkQueueItem) error { | ||||
| 	q.Type.Done(timedItem) | ||||
| 	return nil | ||||
| } | ||||
| @@ -1,501 +0,0 @@ | ||||
| // Copyright 2013 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| // Package json is forked from the Go standard library to enable us to find the | ||||
| // field of a struct that a given JSON key maps to. | ||||
| package json | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"unicode" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
|  | ||||
| // Finds the patchStrategy and patchMergeKey struct tag fields on a given | ||||
| // struct field given the struct type and the JSON name of the field. | ||||
| // TODO: fix the returned errors to be introspectable. | ||||
| func LookupPatchMetadata(t reflect.Type, jsonField string) (reflect.Type, string, string, error) { | ||||
| 	if t.Kind() == reflect.Map { | ||||
| 		return t.Elem(), "", "", nil | ||||
| 	} | ||||
| 	if t.Kind() != reflect.Struct { | ||||
| 		return nil, "", "", fmt.Errorf("merging an object in json but data type is not map or struct, instead is: %s", | ||||
| 			t.Kind().String()) | ||||
| 	} | ||||
| 	jf := []byte(jsonField) | ||||
| 	// Find the field that the JSON library would use. | ||||
| 	var f *field | ||||
| 	fields := cachedTypeFields(t) | ||||
| 	for i := range fields { | ||||
| 		ff := &fields[i] | ||||
| 		if bytes.Equal(ff.nameBytes, jf) { | ||||
| 			f = ff | ||||
| 			break | ||||
| 		} | ||||
| 		// Do case-insensitive comparison. | ||||
| 		if f == nil && ff.equalFold(ff.nameBytes, jf) { | ||||
| 			f = ff | ||||
| 		} | ||||
| 	} | ||||
| 	if f != nil { | ||||
| 		// Find the reflect.Value of the most preferential struct field. | ||||
| 		tjf := t.Field(f.index[0]) | ||||
| 		// we must navigate down all the anonymously included structs in the chain | ||||
| 		for i := 1; i < len(f.index); i++ { | ||||
| 			tjf = tjf.Type.Field(f.index[i]) | ||||
| 		} | ||||
| 		patchStrategy := tjf.Tag.Get("patchStrategy") | ||||
| 		patchMergeKey := tjf.Tag.Get("patchMergeKey") | ||||
| 		return tjf.Type, patchStrategy, patchMergeKey, nil | ||||
| 	} | ||||
| 	return nil, "", "", fmt.Errorf("unable to find api field in struct %s for the json field %q", t.Name(), jsonField) | ||||
| } | ||||
|  | ||||
| // A field represents a single field found in a struct. | ||||
| type field struct { | ||||
| 	name      string | ||||
| 	nameBytes []byte                 // []byte(name) | ||||
| 	equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent | ||||
|  | ||||
| 	tag bool | ||||
| 	// index is the sequence of indexes from the containing type fields to this field. | ||||
| 	// it is a slice because anonymous structs will need multiple navigation steps to correctly | ||||
| 	// resolve the proper fields | ||||
| 	index     []int | ||||
| 	typ       reflect.Type | ||||
| 	omitEmpty bool | ||||
| 	quoted    bool | ||||
| } | ||||
|  | ||||
| func (f field) String() string { | ||||
| 	return fmt.Sprintf("{name: %s, type: %v, tag: %v, index: %v, omitEmpty: %v, quoted: %v}", f.name, f.typ, f.tag, f.index, f.omitEmpty, f.quoted) | ||||
| } | ||||
|  | ||||
| func fillField(f field) field { | ||||
| 	f.nameBytes = []byte(f.name) | ||||
| 	f.equalFold = foldFunc(f.nameBytes) | ||||
| 	return f | ||||
| } | ||||
|  | ||||
| // byName sorts field by name, breaking ties with depth, | ||||
| // then breaking ties with "name came from json tag", then | ||||
| // breaking ties with index sequence. | ||||
| type byName []field | ||||
|  | ||||
| func (x byName) Len() int { return len(x) } | ||||
|  | ||||
| func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } | ||||
|  | ||||
| func (x byName) Less(i, j int) bool { | ||||
| 	if x[i].name != x[j].name { | ||||
| 		return x[i].name < x[j].name | ||||
| 	} | ||||
| 	if len(x[i].index) != len(x[j].index) { | ||||
| 		return len(x[i].index) < len(x[j].index) | ||||
| 	} | ||||
| 	if x[i].tag != x[j].tag { | ||||
| 		return x[i].tag | ||||
| 	} | ||||
| 	return byIndex(x).Less(i, j) | ||||
| } | ||||
|  | ||||
| // byIndex sorts field by index sequence. | ||||
| type byIndex []field | ||||
|  | ||||
| func (x byIndex) Len() int { return len(x) } | ||||
|  | ||||
| func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } | ||||
|  | ||||
| func (x byIndex) Less(i, j int) bool { | ||||
| 	for k, xik := range x[i].index { | ||||
| 		if k >= len(x[j].index) { | ||||
| 			return false | ||||
| 		} | ||||
| 		if xik != x[j].index[k] { | ||||
| 			return xik < x[j].index[k] | ||||
| 		} | ||||
| 	} | ||||
| 	return len(x[i].index) < len(x[j].index) | ||||
| } | ||||
|  | ||||
| // typeFields returns a list of fields that JSON should recognize for the given type. | ||||
| // The algorithm is breadth-first search over the set of structs to include - the top struct | ||||
| // and then any reachable anonymous structs. | ||||
| func typeFields(t reflect.Type) []field { | ||||
| 	// Anonymous fields to explore at the current level and the next. | ||||
| 	current := []field{} | ||||
| 	next := []field{{typ: t}} | ||||
|  | ||||
| 	// Count of queued names for current level and the next. | ||||
| 	count := map[reflect.Type]int{} | ||||
| 	nextCount := map[reflect.Type]int{} | ||||
|  | ||||
| 	// Types already visited at an earlier level. | ||||
| 	visited := map[reflect.Type]bool{} | ||||
|  | ||||
| 	// Fields found. | ||||
| 	var fields []field | ||||
|  | ||||
| 	for len(next) > 0 { | ||||
| 		current, next = next, current[:0] | ||||
| 		count, nextCount = nextCount, map[reflect.Type]int{} | ||||
|  | ||||
| 		for _, f := range current { | ||||
| 			if visited[f.typ] { | ||||
| 				continue | ||||
| 			} | ||||
| 			visited[f.typ] = true | ||||
|  | ||||
| 			// Scan f.typ for fields to include. | ||||
| 			for i := 0; i < f.typ.NumField(); i++ { | ||||
| 				sf := f.typ.Field(i) | ||||
| 				if sf.PkgPath != "" { // unexported | ||||
| 					continue | ||||
| 				} | ||||
| 				tag := sf.Tag.Get("json") | ||||
| 				if tag == "-" { | ||||
| 					continue | ||||
| 				} | ||||
| 				name, opts := parseTag(tag) | ||||
| 				if !isValidTag(name) { | ||||
| 					name = "" | ||||
| 				} | ||||
| 				index := make([]int, len(f.index)+1) | ||||
| 				copy(index, f.index) | ||||
| 				index[len(f.index)] = i | ||||
|  | ||||
| 				ft := sf.Type | ||||
| 				if ft.Name() == "" && ft.Kind() == reflect.Ptr { | ||||
| 					// Follow pointer. | ||||
| 					ft = ft.Elem() | ||||
| 				} | ||||
|  | ||||
| 				// Record found field and index sequence. | ||||
| 				if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { | ||||
| 					tagged := name != "" | ||||
| 					if name == "" { | ||||
| 						name = sf.Name | ||||
| 					} | ||||
| 					fields = append(fields, fillField(field{ | ||||
| 						name:      name, | ||||
| 						tag:       tagged, | ||||
| 						index:     index, | ||||
| 						typ:       ft, | ||||
| 						omitEmpty: opts.Contains("omitempty"), | ||||
| 						quoted:    opts.Contains("string"), | ||||
| 					})) | ||||
| 					if count[f.typ] > 1 { | ||||
| 						// If there were multiple instances, add a second, | ||||
| 						// so that the annihilation code will see a duplicate. | ||||
| 						// It only cares about the distinction between 1 or 2, | ||||
| 						// so don't bother generating any more copies. | ||||
| 						fields = append(fields, fields[len(fields)-1]) | ||||
| 					} | ||||
| 					continue | ||||
| 				} | ||||
|  | ||||
| 				// Record new anonymous struct to explore in next round. | ||||
| 				nextCount[ft]++ | ||||
| 				if nextCount[ft] == 1 { | ||||
| 					next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft})) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	sort.Sort(byName(fields)) | ||||
|  | ||||
| 	// Delete all fields that are hidden by the Go rules for embedded fields, | ||||
| 	// except that fields with JSON tags are promoted. | ||||
|  | ||||
| 	// The fields are sorted in primary order of name, secondary order | ||||
| 	// of field index length. Loop over names; for each name, delete | ||||
| 	// hidden fields by choosing the one dominant field that survives. | ||||
| 	out := fields[:0] | ||||
| 	for advance, i := 0, 0; i < len(fields); i += advance { | ||||
| 		// One iteration per name. | ||||
| 		// Find the sequence of fields with the name of this first field. | ||||
| 		fi := fields[i] | ||||
| 		name := fi.name | ||||
| 		for advance = 1; i+advance < len(fields); advance++ { | ||||
| 			fj := fields[i+advance] | ||||
| 			if fj.name != name { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 		if advance == 1 { // Only one field with this name | ||||
| 			out = append(out, fi) | ||||
| 			continue | ||||
| 		} | ||||
| 		dominant, ok := dominantField(fields[i : i+advance]) | ||||
| 		if ok { | ||||
| 			out = append(out, dominant) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	fields = out | ||||
| 	sort.Sort(byIndex(fields)) | ||||
|  | ||||
| 	return fields | ||||
| } | ||||
|  | ||||
| // dominantField looks through the fields, all of which are known to | ||||
| // have the same name, to find the single field that dominates the | ||||
| // others using Go's embedding rules, modified by the presence of | ||||
| // JSON tags. If there are multiple top-level fields, the boolean | ||||
| // will be false: This condition is an error in Go and we skip all | ||||
| // the fields. | ||||
| func dominantField(fields []field) (field, bool) { | ||||
| 	// The fields are sorted in increasing index-length order. The winner | ||||
| 	// must therefore be one with the shortest index length. Drop all | ||||
| 	// longer entries, which is easy: just truncate the slice. | ||||
| 	length := len(fields[0].index) | ||||
| 	tagged := -1 // Index of first tagged field. | ||||
| 	for i, f := range fields { | ||||
| 		if len(f.index) > length { | ||||
| 			fields = fields[:i] | ||||
| 			break | ||||
| 		} | ||||
| 		if f.tag { | ||||
| 			if tagged >= 0 { | ||||
| 				// Multiple tagged fields at the same level: conflict. | ||||
| 				// Return no field. | ||||
| 				return field{}, false | ||||
| 			} | ||||
| 			tagged = i | ||||
| 		} | ||||
| 	} | ||||
| 	if tagged >= 0 { | ||||
| 		return fields[tagged], true | ||||
| 	} | ||||
| 	// All remaining fields have the same length. If there's more than one, | ||||
| 	// we have a conflict (two fields named "X" at the same level) and we | ||||
| 	// return no field. | ||||
| 	if len(fields) > 1 { | ||||
| 		return field{}, false | ||||
| 	} | ||||
| 	return fields[0], true | ||||
| } | ||||
|  | ||||
| var fieldCache struct { | ||||
| 	sync.RWMutex | ||||
| 	m map[reflect.Type][]field | ||||
| } | ||||
|  | ||||
| // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. | ||||
| func cachedTypeFields(t reflect.Type) []field { | ||||
| 	fieldCache.RLock() | ||||
| 	f := fieldCache.m[t] | ||||
| 	fieldCache.RUnlock() | ||||
| 	if f != nil { | ||||
| 		return f | ||||
| 	} | ||||
|  | ||||
| 	// Compute fields without lock. | ||||
| 	// Might duplicate effort but won't hold other computations back. | ||||
| 	f = typeFields(t) | ||||
| 	if f == nil { | ||||
| 		f = []field{} | ||||
| 	} | ||||
|  | ||||
| 	fieldCache.Lock() | ||||
| 	if fieldCache.m == nil { | ||||
| 		fieldCache.m = map[reflect.Type][]field{} | ||||
| 	} | ||||
| 	fieldCache.m[t] = f | ||||
| 	fieldCache.Unlock() | ||||
| 	return f | ||||
| } | ||||
|  | ||||
| func isValidTag(s string) bool { | ||||
| 	if s == "" { | ||||
| 		return false | ||||
| 	} | ||||
| 	for _, c := range s { | ||||
| 		switch { | ||||
| 		case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): | ||||
| 			// Backslash and quote chars are reserved, but | ||||
| 			// otherwise any punctuation chars are allowed | ||||
| 			// in a tag name. | ||||
| 		default: | ||||
| 			if !unicode.IsLetter(c) && !unicode.IsDigit(c) { | ||||
| 				return false | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	caseMask     = ^byte(0x20) // Mask to ignore case in ASCII. | ||||
| 	kelvin       = '\u212a' | ||||
| 	smallLongEss = '\u017f' | ||||
| ) | ||||
|  | ||||
| // foldFunc returns one of four different case folding equivalence | ||||
| // functions, from most general (and slow) to fastest: | ||||
| // | ||||
| // 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 | ||||
| // 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') | ||||
| // 3) asciiEqualFold, no special, but includes non-letters (including _) | ||||
| // 4) simpleLetterEqualFold, no specials, no non-letters. | ||||
| // | ||||
| // The letters S and K are special because they map to 3 runes, not just 2: | ||||
| //  * S maps to s and to U+017F 'ſ' Latin small letter long s | ||||
| //  * k maps to K and to U+212A 'K' Kelvin sign | ||||
| // See http://play.golang.org/p/tTxjOc0OGo | ||||
| // | ||||
| // The returned function is specialized for matching against s and | ||||
| // should only be given s. It's not curried for performance reasons. | ||||
| func foldFunc(s []byte) func(s, t []byte) bool { | ||||
| 	nonLetter := false | ||||
| 	special := false // special letter | ||||
| 	for _, b := range s { | ||||
| 		if b >= utf8.RuneSelf { | ||||
| 			return bytes.EqualFold | ||||
| 		} | ||||
| 		upper := b & caseMask | ||||
| 		if upper < 'A' || upper > 'Z' { | ||||
| 			nonLetter = true | ||||
| 		} else if upper == 'K' || upper == 'S' { | ||||
| 			// See above for why these letters are special. | ||||
| 			special = true | ||||
| 		} | ||||
| 	} | ||||
| 	if special { | ||||
| 		return equalFoldRight | ||||
| 	} | ||||
| 	if nonLetter { | ||||
| 		return asciiEqualFold | ||||
| 	} | ||||
| 	return simpleLetterEqualFold | ||||
| } | ||||
|  | ||||
| // equalFoldRight is a specialization of bytes.EqualFold when s is | ||||
| // known to be all ASCII (including punctuation), but contains an 's', | ||||
| // 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. | ||||
| // See comments on foldFunc. | ||||
| func equalFoldRight(s, t []byte) bool { | ||||
| 	for _, sb := range s { | ||||
| 		if len(t) == 0 { | ||||
| 			return false | ||||
| 		} | ||||
| 		tb := t[0] | ||||
| 		if tb < utf8.RuneSelf { | ||||
| 			if sb != tb { | ||||
| 				sbUpper := sb & caseMask | ||||
| 				if 'A' <= sbUpper && sbUpper <= 'Z' { | ||||
| 					if sbUpper != tb&caseMask { | ||||
| 						return false | ||||
| 					} | ||||
| 				} else { | ||||
| 					return false | ||||
| 				} | ||||
| 			} | ||||
| 			t = t[1:] | ||||
| 			continue | ||||
| 		} | ||||
| 		// sb is ASCII and t is not. t must be either kelvin | ||||
| 		// sign or long s; sb must be s, S, k, or K. | ||||
| 		tr, size := utf8.DecodeRune(t) | ||||
| 		switch sb { | ||||
| 		case 's', 'S': | ||||
| 			if tr != smallLongEss { | ||||
| 				return false | ||||
| 			} | ||||
| 		case 'k', 'K': | ||||
| 			if tr != kelvin { | ||||
| 				return false | ||||
| 			} | ||||
| 		default: | ||||
| 			return false | ||||
| 		} | ||||
| 		t = t[size:] | ||||
|  | ||||
| 	} | ||||
| 	if len(t) > 0 { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // asciiEqualFold is a specialization of bytes.EqualFold for use when | ||||
| // s is all ASCII (but may contain non-letters) and contains no | ||||
| // special-folding letters. | ||||
| // See comments on foldFunc. | ||||
| func asciiEqualFold(s, t []byte) bool { | ||||
| 	if len(s) != len(t) { | ||||
| 		return false | ||||
| 	} | ||||
| 	for i, sb := range s { | ||||
| 		tb := t[i] | ||||
| 		if sb == tb { | ||||
| 			continue | ||||
| 		} | ||||
| 		if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { | ||||
| 			if sb&caseMask != tb&caseMask { | ||||
| 				return false | ||||
| 			} | ||||
| 		} else { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // simpleLetterEqualFold is a specialization of bytes.EqualFold for | ||||
| // use when s is all ASCII letters (no underscores, etc) and also | ||||
| // doesn't contain 'k', 'K', 's', or 'S'. | ||||
| // See comments on foldFunc. | ||||
| func simpleLetterEqualFold(s, t []byte) bool { | ||||
| 	if len(s) != len(t) { | ||||
| 		return false | ||||
| 	} | ||||
| 	for i, b := range s { | ||||
| 		if b&caseMask != t[i]&caseMask { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // tagOptions is the string following a comma in a struct field's "json" | ||||
| // tag, or the empty string. It does not include the leading comma. | ||||
| type tagOptions string | ||||
|  | ||||
| // parseTag splits a struct field's json tag into its name and | ||||
| // comma-separated options. | ||||
| func parseTag(tag string) (string, tagOptions) { | ||||
| 	if idx := strings.Index(tag, ","); idx != -1 { | ||||
| 		return tag[:idx], tagOptions(tag[idx+1:]) | ||||
| 	} | ||||
| 	return tag, tagOptions("") | ||||
| } | ||||
|  | ||||
| // Contains reports whether a comma-separated list of options | ||||
| // contains a particular substr flag. substr must be surrounded by a | ||||
| // string boundary or commas. | ||||
| func (o tagOptions) Contains(optionName string) bool { | ||||
| 	if len(o) == 0 { | ||||
| 		return false | ||||
| 	} | ||||
| 	s := string(o) | ||||
| 	for s != "" { | ||||
| 		var next string | ||||
| 		i := strings.Index(s, ",") | ||||
| 		if i >= 0 { | ||||
| 			s, next = s[:i], s[i+1:] | ||||
| 		} | ||||
| 		if s == optionName { | ||||
| 			return true | ||||
| 		} | ||||
| 		s = next | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| @@ -1,27 +0,0 @@ | ||||
| package netutil | ||||
|  | ||||
| import ( | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // FROM: http://golang.org/src/net/http/client.go | ||||
| // Given a string of the form "host", "host:port", or "[ipv6::address]:port", | ||||
| // return true if the string includes a port. | ||||
| func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") } | ||||
|  | ||||
| // FROM: http://golang.org/src/net/http/transport.go | ||||
| var portMap = map[string]string{ | ||||
| 	"http":  "80", | ||||
| 	"https": "443", | ||||
| } | ||||
|  | ||||
| // FROM: http://golang.org/src/net/http/transport.go | ||||
| // canonicalAddr returns url.Host but always with a ":port" suffix | ||||
| func CanonicalAddr(url *url.URL) string { | ||||
| 	addr := url.Host | ||||
| 	if !hasPort(addr) { | ||||
| 		return addr + ":" + portMap[url.Scheme] | ||||
| 	} | ||||
| 	return addr | ||||
| } | ||||
| @@ -28,9 +28,9 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/api/errors" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	k8sruntime "k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apimachinery/pkg/util/strategicpatch" | ||||
| 	_ "k8s.io/client-go/pkg/api/install" // To register api.Pod used in tests below | ||||
| 	"k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/pkg/util/strategicpatch" | ||||
| 	restclient "k8s.io/client-go/rest" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| ) | ||||
|   | ||||
| @@ -27,8 +27,8 @@ import ( | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/sets" | ||||
| 	"k8s.io/apimachinery/pkg/util/strategicpatch" | ||||
| 	"k8s.io/client-go/pkg/api/v1" | ||||
| 	"k8s.io/client-go/pkg/util/strategicpatch" | ||||
| 	"k8s.io/client-go/util/clock" | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -23,7 +23,7 @@ import ( | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
|  | ||||
| 	"k8s.io/client-go/pkg/third_party/forked/golang/template" | ||||
| 	"k8s.io/client-go/third_party/forked/golang/template" | ||||
| ) | ||||
|  | ||||
| type JSONPath struct { | ||||
|   | ||||
| @@ -21,7 +21,7 @@ import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"k8s.io/client-go/pkg/util/workqueue" | ||||
| 	"k8s.io/client-go/util/workqueue" | ||||
| ) | ||||
| 
 | ||||
| func TestBasic(t *testing.T) { | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 Kubernetes Submit Queue
					Kubernetes Submit Queue