Update ingress godeps
This commit is contained in:
parent
d43021b3f1
commit
28db8fb16d
1068 changed files with 461467 additions and 117300 deletions
83
vendor/k8s.io/kubernetes/pkg/util/cache/cache.go
generated
vendored
Normal file
83
vendor/k8s.io/kubernetes/pkg/util/cache/cache.go
generated
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
shardsCount int = 32
|
||||
)
|
||||
|
||||
type Cache []*cacheShard
|
||||
|
||||
func NewCache(maxSize int) Cache {
|
||||
if maxSize < shardsCount {
|
||||
maxSize = shardsCount
|
||||
}
|
||||
cache := make(Cache, shardsCount)
|
||||
for i := 0; i < shardsCount; i++ {
|
||||
cache[i] = &cacheShard{
|
||||
items: make(map[uint64]interface{}),
|
||||
maxSize: maxSize / shardsCount,
|
||||
}
|
||||
}
|
||||
return cache
|
||||
}
|
||||
|
||||
func (c Cache) getShard(index uint64) *cacheShard {
|
||||
return c[index%uint64(shardsCount)]
|
||||
}
|
||||
|
||||
// Returns true if object already existed, false otherwise.
|
||||
func (c *Cache) Add(index uint64, obj interface{}) bool {
|
||||
return c.getShard(index).add(index, obj)
|
||||
}
|
||||
|
||||
func (c *Cache) Get(index uint64) (obj interface{}, found bool) {
|
||||
return c.getShard(index).get(index)
|
||||
}
|
||||
|
||||
type cacheShard struct {
|
||||
items map[uint64]interface{}
|
||||
sync.RWMutex
|
||||
maxSize int
|
||||
}
|
||||
|
||||
// Returns true if object already existed, false otherwise.
|
||||
func (s *cacheShard) add(index uint64, obj interface{}) bool {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
_, isOverwrite := s.items[index]
|
||||
if !isOverwrite && len(s.items) >= s.maxSize {
|
||||
var randomKey uint64
|
||||
for randomKey = range s.items {
|
||||
break
|
||||
}
|
||||
delete(s.items, randomKey)
|
||||
}
|
||||
s.items[index] = obj
|
||||
return isOverwrite
|
||||
}
|
||||
|
||||
func (s *cacheShard) get(index uint64) (obj interface{}, found bool) {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
obj, found = s.items[index]
|
||||
return
|
||||
}
|
||||
66
vendor/k8s.io/kubernetes/pkg/util/cache/lruexpirecache.go
generated
vendored
Normal file
66
vendor/k8s.io/kubernetes/pkg/util/cache/lruexpirecache.go
generated
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/groupcache/lru"
|
||||
)
|
||||
|
||||
type LRUExpireCache struct {
|
||||
cache *lru.Cache
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func NewLRUExpireCache(maxSize int) *LRUExpireCache {
|
||||
return &LRUExpireCache{cache: lru.New(maxSize)}
|
||||
}
|
||||
|
||||
type cacheEntry struct {
|
||||
value interface{}
|
||||
expireTime time.Time
|
||||
}
|
||||
|
||||
func (c *LRUExpireCache) Add(key lru.Key, value interface{}, ttl time.Duration) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
c.cache.Add(key, &cacheEntry{value, time.Now().Add(ttl)})
|
||||
// Remove entry from cache after ttl.
|
||||
time.AfterFunc(ttl, func() { c.remove(key) })
|
||||
}
|
||||
|
||||
func (c *LRUExpireCache) Get(key lru.Key) (interface{}, bool) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
e, ok := c.cache.Get(key)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
if time.Now().After(e.(*cacheEntry).expireTime) {
|
||||
go c.remove(key)
|
||||
return nil, false
|
||||
}
|
||||
return e.(*cacheEntry).value, true
|
||||
}
|
||||
|
||||
func (c *LRUExpireCache) remove(key lru.Key) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
c.cache.Remove(key)
|
||||
}
|
||||
138
vendor/k8s.io/kubernetes/pkg/util/certificates/csr.go
generated
vendored
Normal file
138
vendor/k8s.io/kubernetes/pkg/util/certificates/csr.go
generated
vendored
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
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 certificates
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
cryptorand "crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"k8s.io/kubernetes/pkg/apis/certificates"
|
||||
)
|
||||
|
||||
// ParseCertificateRequestObject extracts the CSR from the API object and decodes it.
|
||||
func ParseCertificateRequestObject(obj *certificates.CertificateSigningRequest) (*x509.CertificateRequest, error) {
|
||||
// extract PEM from request object
|
||||
pemBytes := obj.Spec.Request
|
||||
block, _ := pem.Decode(pemBytes)
|
||||
if block == nil || block.Type != "CERTIFICATE REQUEST" {
|
||||
return nil, errors.New("PEM block type must be CERTIFICATE REQUEST")
|
||||
}
|
||||
csr, err := x509.ParseCertificateRequest(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return csr, nil
|
||||
}
|
||||
|
||||
// GeneratePrivateKey returns PEM data containing a generated ECDSA private key
|
||||
func GeneratePrivateKey() ([]byte, error) {
|
||||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), cryptorand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
derBytes, err := x509.MarshalECPrivateKey(privateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
privateKeyPemBlock := &pem.Block{
|
||||
Type: "EC PRIVATE KEY",
|
||||
Bytes: derBytes,
|
||||
}
|
||||
return pem.EncodeToMemory(privateKeyPemBlock), nil
|
||||
}
|
||||
|
||||
// ParsePrivateKey returns a private key parsed from a PEM block in the supplied data.
|
||||
// Recognizes PEM blocks for "EC PRIVATE KEY" and "RSA PRIVATE KEY"
|
||||
func ParsePrivateKey(keyData []byte) (interface{}, error) {
|
||||
for {
|
||||
var privateKeyPemBlock *pem.Block
|
||||
privateKeyPemBlock, keyData = pem.Decode(keyData)
|
||||
if privateKeyPemBlock == nil {
|
||||
// we read all the PEM blocks and didn't recognize one
|
||||
return nil, fmt.Errorf("no private key PEM block found")
|
||||
}
|
||||
|
||||
switch privateKeyPemBlock.Type {
|
||||
case "EC PRIVATE KEY":
|
||||
return x509.ParseECPrivateKey(privateKeyPemBlock.Bytes)
|
||||
case "RSA PRIVATE KEY":
|
||||
return x509.ParsePKCS1PrivateKey(privateKeyPemBlock.Bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NewCertificateRequest generates a PEM-encoded CSR using the supplied private key, subject, and SANs.
|
||||
// privateKey must be a *ecdsa.PrivateKey or *rsa.PrivateKey.
|
||||
func NewCertificateRequest(privateKey interface{}, subject *pkix.Name, dnsSANs []string, ipSANs []net.IP) (csr []byte, err error) {
|
||||
var sigType x509.SignatureAlgorithm
|
||||
|
||||
switch privateKey := privateKey.(type) {
|
||||
case *ecdsa.PrivateKey:
|
||||
switch privateKey.Curve {
|
||||
case elliptic.P224(), elliptic.P256():
|
||||
sigType = x509.ECDSAWithSHA256
|
||||
case elliptic.P384():
|
||||
sigType = x509.ECDSAWithSHA384
|
||||
case elliptic.P521():
|
||||
sigType = x509.ECDSAWithSHA512
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown elliptic curve: %v", privateKey.Curve)
|
||||
}
|
||||
case *rsa.PrivateKey:
|
||||
keySize := privateKey.N.BitLen()
|
||||
switch {
|
||||
case keySize >= 4096:
|
||||
sigType = x509.SHA512WithRSA
|
||||
case keySize >= 3072:
|
||||
sigType = x509.SHA384WithRSA
|
||||
default:
|
||||
sigType = x509.SHA256WithRSA
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported key type: %T", privateKey)
|
||||
}
|
||||
|
||||
template := &x509.CertificateRequest{
|
||||
Subject: *subject,
|
||||
SignatureAlgorithm: sigType,
|
||||
DNSNames: dnsSANs,
|
||||
IPAddresses: ipSANs,
|
||||
}
|
||||
|
||||
csr, err = x509.CreateCertificateRequest(cryptorand.Reader, template, privateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
csrPemBlock := &pem.Block{
|
||||
Type: "CERTIFICATE REQUEST",
|
||||
Bytes: csr,
|
||||
}
|
||||
|
||||
return pem.EncodeToMemory(csrPemBlock), nil
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
package clock
|
||||
|
||||
import (
|
||||
"sync"
|
||||
140
vendor/k8s.io/kubernetes/pkg/util/config/config.go
generated
vendored
Normal file
140
vendor/k8s.io/kubernetes/pkg/util/config/config.go
generated
vendored
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
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 config
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
)
|
||||
|
||||
type Merger interface {
|
||||
// Invoked when a change from a source is received. May also function as an incremental
|
||||
// merger if you wish to consume changes incrementally. Must be reentrant when more than
|
||||
// one source is defined.
|
||||
Merge(source string, update interface{}) error
|
||||
}
|
||||
|
||||
// MergeFunc implements the Merger interface
|
||||
type MergeFunc func(source string, update interface{}) error
|
||||
|
||||
func (f MergeFunc) Merge(source string, update interface{}) error {
|
||||
return f(source, update)
|
||||
}
|
||||
|
||||
// Mux is a class for merging configuration from multiple sources. Changes are
|
||||
// pushed via channels and sent to the merge function.
|
||||
type Mux struct {
|
||||
// Invoked when an update is sent to a source.
|
||||
merger Merger
|
||||
|
||||
// Sources and their lock.
|
||||
sourceLock sync.RWMutex
|
||||
// Maps source names to channels
|
||||
sources map[string]chan interface{}
|
||||
}
|
||||
|
||||
// NewMux creates a new mux that can merge changes from multiple sources.
|
||||
func NewMux(merger Merger) *Mux {
|
||||
mux := &Mux{
|
||||
sources: make(map[string]chan interface{}),
|
||||
merger: merger,
|
||||
}
|
||||
return mux
|
||||
}
|
||||
|
||||
// Channel returns a channel where a configuration source
|
||||
// can send updates of new configurations. Multiple calls with the same
|
||||
// source will return the same channel. This allows change and state based sources
|
||||
// to use the same channel. Different source names however will be treated as a
|
||||
// union.
|
||||
func (m *Mux) Channel(source string) chan interface{} {
|
||||
if len(source) == 0 {
|
||||
panic("Channel given an empty name")
|
||||
}
|
||||
m.sourceLock.Lock()
|
||||
defer m.sourceLock.Unlock()
|
||||
channel, exists := m.sources[source]
|
||||
if exists {
|
||||
return channel
|
||||
}
|
||||
newChannel := make(chan interface{})
|
||||
m.sources[source] = newChannel
|
||||
go wait.Until(func() { m.listen(source, newChannel) }, 0, wait.NeverStop)
|
||||
return newChannel
|
||||
}
|
||||
|
||||
func (m *Mux) listen(source string, listenChannel <-chan interface{}) {
|
||||
for update := range listenChannel {
|
||||
m.merger.Merge(source, update)
|
||||
}
|
||||
}
|
||||
|
||||
// Accessor is an interface for retrieving the current merge state.
|
||||
type Accessor interface {
|
||||
// MergedState returns a representation of the current merge state.
|
||||
// Must be reentrant when more than one source is defined.
|
||||
MergedState() interface{}
|
||||
}
|
||||
|
||||
// AccessorFunc implements the Accessor interface.
|
||||
type AccessorFunc func() interface{}
|
||||
|
||||
func (f AccessorFunc) MergedState() interface{} {
|
||||
return f()
|
||||
}
|
||||
|
||||
type Listener interface {
|
||||
// OnUpdate is invoked when a change is made to an object.
|
||||
OnUpdate(instance interface{})
|
||||
}
|
||||
|
||||
// ListenerFunc receives a representation of the change or object.
|
||||
type ListenerFunc func(instance interface{})
|
||||
|
||||
func (f ListenerFunc) OnUpdate(instance interface{}) {
|
||||
f(instance)
|
||||
}
|
||||
|
||||
type Broadcaster struct {
|
||||
// Listeners for changes and their lock.
|
||||
listenerLock sync.RWMutex
|
||||
listeners []Listener
|
||||
}
|
||||
|
||||
// NewBroadcaster registers a set of listeners that support the Listener interface
|
||||
// and notifies them all on changes.
|
||||
func NewBroadcaster() *Broadcaster {
|
||||
return &Broadcaster{}
|
||||
}
|
||||
|
||||
// Add registers listener to receive updates of changes.
|
||||
func (b *Broadcaster) Add(listener Listener) {
|
||||
b.listenerLock.Lock()
|
||||
defer b.listenerLock.Unlock()
|
||||
b.listeners = append(b.listeners, listener)
|
||||
}
|
||||
|
||||
// Notify notifies all listeners.
|
||||
func (b *Broadcaster) Notify(instance interface{}) {
|
||||
b.listenerLock.RLock()
|
||||
listeners := b.listeners
|
||||
b.listenerLock.RUnlock()
|
||||
for _, listener := range listeners {
|
||||
listener.OnUpdate(instance)
|
||||
}
|
||||
}
|
||||
53
vendor/k8s.io/kubernetes/pkg/util/config/configuration_map.go
generated
vendored
Normal file
53
vendor/k8s.io/kubernetes/pkg/util/config/configuration_map.go
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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 config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ConfigurationMap map[string]string
|
||||
|
||||
func (m *ConfigurationMap) String() string {
|
||||
pairs := []string{}
|
||||
for k, v := range *m {
|
||||
pairs = append(pairs, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
sort.Strings(pairs)
|
||||
return strings.Join(pairs, ",")
|
||||
}
|
||||
|
||||
func (m *ConfigurationMap) Set(value string) error {
|
||||
for _, s := range strings.Split(value, ",") {
|
||||
if len(s) == 0 {
|
||||
continue
|
||||
}
|
||||
arr := strings.SplitN(s, "=", 2)
|
||||
if len(arr) == 2 {
|
||||
(*m)[strings.TrimSpace(arr[0])] = strings.TrimSpace(arr[1])
|
||||
} else {
|
||||
(*m)[strings.TrimSpace(arr[0])] = ""
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*ConfigurationMap) Type() string {
|
||||
return "mapStringString"
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
// +build !linux
|
||||
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
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.
|
||||
|
|
@ -16,16 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
func RunInResourceContainer(containerName string) error {
|
||||
return errors.New("resource-only containers unsupported in this platform")
|
||||
}
|
||||
|
||||
func ApplyRLimitForSelf(maxOpenFiles uint64) error {
|
||||
return errors.New("SetRLimit unsupported in this platform")
|
||||
}
|
||||
// Package config provides utility objects for decoupling sources of configuration and the
|
||||
// actual configuration state. Consumers must implement the Merger interface to unify
|
||||
// the sources of change into an object.
|
||||
package config
|
||||
212
vendor/k8s.io/kubernetes/pkg/util/config/feature_gate.go
generated
vendored
Normal file
212
vendor/k8s.io/kubernetes/pkg/util/config/feature_gate.go
generated
vendored
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
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 config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
flagName = "feature-gates"
|
||||
|
||||
// All known feature keys
|
||||
// To add a new feature, define a key for it below and add
|
||||
// a featureSpec entry to knownFeatures.
|
||||
|
||||
// allAlphaGate is a global toggle for alpha features. Per-feature key
|
||||
// values override the default set by allAlphaGate. Examples:
|
||||
// AllAlpha=false,NewFeature=true will result in newFeature=true
|
||||
// AllAlpha=true,NewFeature=false will result in newFeature=false
|
||||
allAlphaGate = "AllAlpha"
|
||||
externalTrafficLocalOnly = "AllowExtTrafficLocalEndpoints"
|
||||
dynamicKubeletConfig = "DynamicKubeletConfig"
|
||||
dynamicVolumeProvisioning = "DynamicVolumeProvisioning"
|
||||
// TODO: Define gate/accessor for AppArmor
|
||||
)
|
||||
|
||||
var (
|
||||
// Default values for recorded features. Every new feature gate should be
|
||||
// represented here.
|
||||
knownFeatures = map[string]featureSpec{
|
||||
allAlphaGate: {false, alpha},
|
||||
externalTrafficLocalOnly: {false, alpha},
|
||||
dynamicKubeletConfig: {false, alpha},
|
||||
dynamicVolumeProvisioning: {true, alpha},
|
||||
}
|
||||
|
||||
// Special handling for a few gates.
|
||||
specialFeatures = map[string]func(f *featureGate, val bool){
|
||||
allAlphaGate: setUnsetAlphaGates,
|
||||
}
|
||||
|
||||
// DefaultFeatureGate is a shared global FeatureGate.
|
||||
DefaultFeatureGate = &featureGate{
|
||||
known: knownFeatures,
|
||||
special: specialFeatures,
|
||||
}
|
||||
)
|
||||
|
||||
type featureSpec struct {
|
||||
enabled bool
|
||||
prerelease prerelease
|
||||
}
|
||||
|
||||
type prerelease string
|
||||
|
||||
const (
|
||||
// Values for prerelease.
|
||||
alpha = prerelease("ALPHA")
|
||||
beta = prerelease("BETA")
|
||||
ga = prerelease("")
|
||||
)
|
||||
|
||||
// FeatureGate parses and stores flag gates for known features from
|
||||
// a string like feature1=true,feature2=false,...
|
||||
type FeatureGate interface {
|
||||
AddFlag(fs *pflag.FlagSet)
|
||||
|
||||
// Every feature gate should add method here following this template:
|
||||
//
|
||||
// // owner: @username
|
||||
// // alpha: v1.4
|
||||
// MyFeature() bool
|
||||
|
||||
// owner: @girishkalele
|
||||
// alpha: v1.4
|
||||
ExternalTrafficLocalOnly() bool
|
||||
|
||||
// owner: @saad-ali
|
||||
// alpha: v1.3
|
||||
DynamicVolumeProvisioning() bool
|
||||
|
||||
// owner: mtaufen
|
||||
// alpha: v1.4
|
||||
DynamicKubeletConfig() bool
|
||||
}
|
||||
|
||||
// featureGate implements FeatureGate as well as pflag.Value for flag parsing.
|
||||
type featureGate struct {
|
||||
known map[string]featureSpec
|
||||
special map[string]func(*featureGate, bool)
|
||||
enabled map[string]bool
|
||||
}
|
||||
|
||||
func setUnsetAlphaGates(f *featureGate, val bool) {
|
||||
for k, v := range f.known {
|
||||
if v.prerelease == alpha {
|
||||
if _, found := f.enabled[k]; !found {
|
||||
f.enabled[k] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set, String, and Type implement pflag.Value
|
||||
|
||||
// Set Parses a string of the form // "key1=value1,key2=value2,..." into a
|
||||
// map[string]bool of known keys or returns an error.
|
||||
func (f *featureGate) Set(value string) error {
|
||||
f.enabled = make(map[string]bool)
|
||||
for _, s := range strings.Split(value, ",") {
|
||||
if len(s) == 0 {
|
||||
continue
|
||||
}
|
||||
arr := strings.SplitN(s, "=", 2)
|
||||
k := strings.TrimSpace(arr[0])
|
||||
_, ok := f.known[k]
|
||||
if !ok {
|
||||
return fmt.Errorf("unrecognized key: %s", k)
|
||||
}
|
||||
if len(arr) != 2 {
|
||||
return fmt.Errorf("missing bool value for %s", k)
|
||||
}
|
||||
v := strings.TrimSpace(arr[1])
|
||||
boolValue, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid value of %s: %s, err: %v", k, v, err)
|
||||
}
|
||||
f.enabled[k] = boolValue
|
||||
|
||||
// Handle "special" features like "all alpha gates"
|
||||
if fn, found := f.special[k]; found {
|
||||
fn(f, boolValue)
|
||||
}
|
||||
}
|
||||
|
||||
glog.Infof("feature gates: %v", f.enabled)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *featureGate) String() string {
|
||||
pairs := []string{}
|
||||
for k, v := range f.enabled {
|
||||
pairs = append(pairs, fmt.Sprintf("%s=%t", k, v))
|
||||
}
|
||||
sort.Strings(pairs)
|
||||
return strings.Join(pairs, ",")
|
||||
}
|
||||
|
||||
func (f *featureGate) Type() string {
|
||||
return "mapStringBool"
|
||||
}
|
||||
|
||||
// ExternalTrafficLocalOnly returns value for AllowExtTrafficLocalEndpoints
|
||||
func (f *featureGate) ExternalTrafficLocalOnly() bool {
|
||||
return f.lookup(externalTrafficLocalOnly)
|
||||
}
|
||||
|
||||
// DynamicKubeletConfig returns value for dynamicKubeletConfig
|
||||
func (f *featureGate) DynamicKubeletConfig() bool {
|
||||
return f.lookup(dynamicKubeletConfig)
|
||||
}
|
||||
|
||||
// DynamicVolumeProvisioning returns value for dynamicVolumeProvisioning
|
||||
func (f *featureGate) DynamicVolumeProvisioning() bool {
|
||||
return f.lookup(dynamicVolumeProvisioning)
|
||||
}
|
||||
|
||||
func (f *featureGate) lookup(key string) bool {
|
||||
defaultValue := f.known[key].enabled
|
||||
if f.enabled != nil {
|
||||
if v, ok := f.enabled[key]; ok {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
|
||||
}
|
||||
|
||||
// AddFlag adds a flag for setting global feature gates to the specified FlagSet.
|
||||
func (f *featureGate) AddFlag(fs *pflag.FlagSet) {
|
||||
var known []string
|
||||
for k, v := range f.known {
|
||||
pre := ""
|
||||
if v.prerelease != ga {
|
||||
pre = fmt.Sprintf("%s - ", v.prerelease)
|
||||
}
|
||||
known = append(known, fmt.Sprintf("%s=true|false (%sdefault=%t)", k, pre, v.enabled))
|
||||
}
|
||||
fs.Var(f, flagName, ""+
|
||||
"A set of key=value pairs that describe feature gates for alpha/experimental features. "+
|
||||
"Options are:\n"+strings.Join(known, "\n"))
|
||||
}
|
||||
48
vendor/k8s.io/kubernetes/pkg/util/crypto/crypto.go
generated
vendored
48
vendor/k8s.io/kubernetes/pkg/util/crypto/crypto.go
generated
vendored
|
|
@ -33,14 +33,14 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// ShouldGenSelfSignedCerts returns false if the certificate or key files already exists,
|
||||
// otherwise returns true.
|
||||
func ShouldGenSelfSignedCerts(certPath, keyPath string) bool {
|
||||
// FoundCertOrKey returns true if the certificate or key files already exists,
|
||||
// otherwise returns false.
|
||||
func FoundCertOrKey(certPath, keyPath string) bool {
|
||||
if canReadFile(certPath) || canReadFile(keyPath) {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
// If the file represented by path exists and
|
||||
|
|
@ -109,24 +109,46 @@ func GenerateSelfSignedCert(host, certPath, keyPath string, alternateIPs []net.I
|
|||
}
|
||||
|
||||
// Write cert
|
||||
if err := os.MkdirAll(filepath.Dir(certPath), os.FileMode(0755)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(certPath, certBuffer.Bytes(), os.FileMode(0644)); err != nil {
|
||||
if err := WriteCertToPath(certPath, certBuffer.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write key
|
||||
if err := os.MkdirAll(filepath.Dir(keyPath), os.FileMode(0755)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(keyPath, keyBuffer.Bytes(), os.FileMode(0600)); err != nil {
|
||||
if err := WriteKeyToPath(keyPath, keyBuffer.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteCertToPath writes the pem-encoded certificate data to certPath.
|
||||
// The certificate file will be created with file mode 0644.
|
||||
// If the certificate file already exists, it will be overwritten.
|
||||
// The parent directory of the certPath will be created as needed with file mode 0755.
|
||||
func WriteCertToPath(certPath string, data []byte) error {
|
||||
if err := os.MkdirAll(filepath.Dir(certPath), os.FileMode(0755)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(certPath, data, os.FileMode(0644)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteKeyToPath writes the pem-encoded key data to keyPath.
|
||||
// The key file will be created with file mode 0600.
|
||||
// If the key file already exists, it will be overwritten.
|
||||
// The parent directory of the keyPath will be created as needed with file mode 0755.
|
||||
func WriteKeyToPath(keyPath string, data []byte) error {
|
||||
if err := os.MkdirAll(filepath.Dir(keyPath), os.FileMode(0755)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(keyPath, data, os.FileMode(0600)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CertPoolFromFile returns an x509.CertPool containing the certificates in the given PEM-encoded file.
|
||||
// Returns an error if the file could not be read, a certificate could not be parsed, or if the file does not contain any certificates
|
||||
func CertPoolFromFile(filename string) (*x509.CertPool, error) {
|
||||
|
|
|
|||
18
vendor/k8s.io/kubernetes/pkg/util/exec/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/pkg/util/exec/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
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 exec provides an injectable interface and implementations for running commands.
|
||||
package exec
|
||||
167
vendor/k8s.io/kubernetes/pkg/util/exec/exec.go
generated
vendored
Normal file
167
vendor/k8s.io/kubernetes/pkg/util/exec/exec.go
generated
vendored
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
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 exec
|
||||
|
||||
import (
|
||||
"io"
|
||||
osexec "os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// ErrExecutableNotFound is returned if the executable is not found.
|
||||
var ErrExecutableNotFound = osexec.ErrNotFound
|
||||
|
||||
// Interface is an interface that presents a subset of the os/exec API. Use this
|
||||
// when you want to inject fakeable/mockable exec behavior.
|
||||
type Interface interface {
|
||||
// Command returns a Cmd instance which can be used to run a single command.
|
||||
// This follows the pattern of package os/exec.
|
||||
Command(cmd string, args ...string) Cmd
|
||||
|
||||
// LookPath wraps os/exec.LookPath
|
||||
LookPath(file string) (string, error)
|
||||
}
|
||||
|
||||
// Cmd is an interface that presents an API that is very similar to Cmd from os/exec.
|
||||
// As more functionality is needed, this can grow. Since Cmd is a struct, we will have
|
||||
// to replace fields with get/set method pairs.
|
||||
type Cmd interface {
|
||||
// CombinedOutput runs the command and returns its combined standard output
|
||||
// and standard error. This follows the pattern of package os/exec.
|
||||
CombinedOutput() ([]byte, error)
|
||||
// Output runs the command and returns standard output, but not standard err
|
||||
Output() ([]byte, error)
|
||||
SetDir(dir string)
|
||||
SetStdin(in io.Reader)
|
||||
SetStdout(out io.Writer)
|
||||
}
|
||||
|
||||
// ExitError is an interface that presents an API similar to os.ProcessState, which is
|
||||
// what ExitError from os/exec is. This is designed to make testing a bit easier and
|
||||
// probably loses some of the cross-platform properties of the underlying library.
|
||||
type ExitError interface {
|
||||
String() string
|
||||
Error() string
|
||||
Exited() bool
|
||||
ExitStatus() int
|
||||
}
|
||||
|
||||
// Implements Interface in terms of really exec()ing.
|
||||
type executor struct{}
|
||||
|
||||
// New returns a new Interface which will os/exec to run commands.
|
||||
func New() Interface {
|
||||
return &executor{}
|
||||
}
|
||||
|
||||
// Command is part of the Interface interface.
|
||||
func (executor *executor) Command(cmd string, args ...string) Cmd {
|
||||
return (*cmdWrapper)(osexec.Command(cmd, args...))
|
||||
}
|
||||
|
||||
// LookPath is part of the Interface interface
|
||||
func (executor *executor) LookPath(file string) (string, error) {
|
||||
return osexec.LookPath(file)
|
||||
}
|
||||
|
||||
// Wraps exec.Cmd so we can capture errors.
|
||||
type cmdWrapper osexec.Cmd
|
||||
|
||||
func (cmd *cmdWrapper) SetDir(dir string) {
|
||||
cmd.Dir = dir
|
||||
}
|
||||
|
||||
func (cmd *cmdWrapper) SetStdin(in io.Reader) {
|
||||
cmd.Stdin = in
|
||||
}
|
||||
|
||||
func (cmd *cmdWrapper) SetStdout(out io.Writer) {
|
||||
cmd.Stdout = out
|
||||
}
|
||||
|
||||
// CombinedOutput is part of the Cmd interface.
|
||||
func (cmd *cmdWrapper) CombinedOutput() ([]byte, error) {
|
||||
out, err := (*osexec.Cmd)(cmd).CombinedOutput()
|
||||
if err != nil {
|
||||
return out, handleError(err)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (cmd *cmdWrapper) Output() ([]byte, error) {
|
||||
out, err := (*osexec.Cmd)(cmd).Output()
|
||||
if err != nil {
|
||||
return out, handleError(err)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func handleError(err error) error {
|
||||
if ee, ok := err.(*osexec.ExitError); ok {
|
||||
// Force a compile fail if exitErrorWrapper can't convert to ExitError.
|
||||
var x ExitError = &ExitErrorWrapper{ee}
|
||||
return x
|
||||
}
|
||||
if ee, ok := err.(*osexec.Error); ok {
|
||||
if ee.Err == osexec.ErrNotFound {
|
||||
return ErrExecutableNotFound
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ExitErrorWrapper is an implementation of ExitError in terms of os/exec ExitError.
|
||||
// Note: standard exec.ExitError is type *os.ProcessState, which already implements Exited().
|
||||
type ExitErrorWrapper struct {
|
||||
*osexec.ExitError
|
||||
}
|
||||
|
||||
var _ ExitError = ExitErrorWrapper{}
|
||||
|
||||
// ExitStatus is part of the ExitError interface.
|
||||
func (eew ExitErrorWrapper) ExitStatus() int {
|
||||
ws, ok := eew.Sys().(syscall.WaitStatus)
|
||||
if !ok {
|
||||
panic("can't call ExitStatus() on a non-WaitStatus exitErrorWrapper")
|
||||
}
|
||||
return ws.ExitStatus()
|
||||
}
|
||||
|
||||
// CodeExitError is an implementation of ExitError consisting of an error object
|
||||
// and an exit code (the upper bits of os.exec.ExitStatus).
|
||||
type CodeExitError struct {
|
||||
Err error
|
||||
Code int
|
||||
}
|
||||
|
||||
var _ ExitError = CodeExitError{}
|
||||
|
||||
func (e CodeExitError) Error() string {
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
func (e CodeExitError) String() string {
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
func (e CodeExitError) Exited() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (e CodeExitError) ExitStatus() int {
|
||||
return e.Code
|
||||
}
|
||||
112
vendor/k8s.io/kubernetes/pkg/util/exec/fake_exec.go
generated
vendored
Normal file
112
vendor/k8s.io/kubernetes/pkg/util/exec/fake_exec.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
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 exec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// A simple scripted Interface type.
|
||||
type FakeExec struct {
|
||||
CommandScript []FakeCommandAction
|
||||
CommandCalls int
|
||||
LookPathFunc func(string) (string, error)
|
||||
}
|
||||
|
||||
type FakeCommandAction func(cmd string, args ...string) Cmd
|
||||
|
||||
func (fake *FakeExec) Command(cmd string, args ...string) Cmd {
|
||||
if fake.CommandCalls > len(fake.CommandScript)-1 {
|
||||
panic(fmt.Sprintf("ran out of Command() actions. Could not handle command [%d]: %s args: %v", fake.CommandCalls, cmd, args))
|
||||
}
|
||||
i := fake.CommandCalls
|
||||
fake.CommandCalls++
|
||||
return fake.CommandScript[i](cmd, args...)
|
||||
}
|
||||
|
||||
func (fake *FakeExec) LookPath(file string) (string, error) {
|
||||
return fake.LookPathFunc(file)
|
||||
}
|
||||
|
||||
// A simple scripted Cmd type.
|
||||
type FakeCmd struct {
|
||||
Argv []string
|
||||
CombinedOutputScript []FakeCombinedOutputAction
|
||||
CombinedOutputCalls int
|
||||
CombinedOutputLog [][]string
|
||||
Dirs []string
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
}
|
||||
|
||||
func InitFakeCmd(fake *FakeCmd, cmd string, args ...string) Cmd {
|
||||
fake.Argv = append([]string{cmd}, args...)
|
||||
return fake
|
||||
}
|
||||
|
||||
type FakeCombinedOutputAction func() ([]byte, error)
|
||||
|
||||
func (fake *FakeCmd) SetDir(dir string) {
|
||||
fake.Dirs = append(fake.Dirs, dir)
|
||||
}
|
||||
|
||||
func (fake *FakeCmd) SetStdin(in io.Reader) {
|
||||
fake.Stdin = in
|
||||
}
|
||||
|
||||
func (fake *FakeCmd) SetStdout(out io.Writer) {
|
||||
fake.Stdout = out
|
||||
}
|
||||
|
||||
func (fake *FakeCmd) CombinedOutput() ([]byte, error) {
|
||||
if fake.CombinedOutputCalls > len(fake.CombinedOutputScript)-1 {
|
||||
panic("ran out of CombinedOutput() actions")
|
||||
}
|
||||
if fake.CombinedOutputLog == nil {
|
||||
fake.CombinedOutputLog = [][]string{}
|
||||
}
|
||||
i := fake.CombinedOutputCalls
|
||||
fake.CombinedOutputLog = append(fake.CombinedOutputLog, append([]string{}, fake.Argv...))
|
||||
fake.CombinedOutputCalls++
|
||||
return fake.CombinedOutputScript[i]()
|
||||
}
|
||||
|
||||
func (fake *FakeCmd) Output() ([]byte, error) {
|
||||
return nil, fmt.Errorf("unimplemented")
|
||||
}
|
||||
|
||||
// A simple fake ExitError type.
|
||||
type FakeExitError struct {
|
||||
Status int
|
||||
}
|
||||
|
||||
func (fake *FakeExitError) String() string {
|
||||
return fmt.Sprintf("exit %d", fake.Status)
|
||||
}
|
||||
|
||||
func (fake *FakeExitError) Error() string {
|
||||
return fake.String()
|
||||
}
|
||||
|
||||
func (fake *FakeExitError) Exited() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (fake *FakeExitError) ExitStatus() int {
|
||||
return fake.Status
|
||||
}
|
||||
8
vendor/k8s.io/kubernetes/pkg/util/flowcontrol/backoff.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/util/flowcontrol/backoff.go
generated
vendored
|
|
@ -20,7 +20,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/pkg/util/clock"
|
||||
"k8s.io/kubernetes/pkg/util/integer"
|
||||
)
|
||||
|
||||
|
|
@ -31,13 +31,13 @@ type backoffEntry struct {
|
|||
|
||||
type Backoff struct {
|
||||
sync.Mutex
|
||||
Clock util.Clock
|
||||
Clock clock.Clock
|
||||
defaultDuration time.Duration
|
||||
maxDuration time.Duration
|
||||
perItemBackoff map[string]*backoffEntry
|
||||
}
|
||||
|
||||
func NewFakeBackOff(initial, max time.Duration, tc *util.FakeClock) *Backoff {
|
||||
func NewFakeBackOff(initial, max time.Duration, tc *clock.FakeClock) *Backoff {
|
||||
return &Backoff{
|
||||
perItemBackoff: map[string]*backoffEntry{},
|
||||
Clock: tc,
|
||||
|
|
@ -49,7 +49,7 @@ func NewFakeBackOff(initial, max time.Duration, tc *util.FakeClock) *Backoff {
|
|||
func NewBackOff(initial, max time.Duration) *Backoff {
|
||||
return &Backoff{
|
||||
perItemBackoff: map[string]*backoffEntry{},
|
||||
Clock: util.RealClock{},
|
||||
Clock: clock.RealClock{},
|
||||
defaultDuration: initial,
|
||||
maxDuration: max,
|
||||
}
|
||||
|
|
|
|||
28
vendor/k8s.io/kubernetes/pkg/util/flowcontrol/throttle.go
generated
vendored
28
vendor/k8s.io/kubernetes/pkg/util/flowcontrol/throttle.go
generated
vendored
|
|
@ -35,10 +35,13 @@ type RateLimiter interface {
|
|||
// Usually we use token bucket rate limiter. In that case,
|
||||
// 1.0 means no tokens are available; 0.0 means we have a full bucket of tokens to use.
|
||||
Saturation() float64
|
||||
// QPS returns QPS of this rate limiter
|
||||
QPS() float32
|
||||
}
|
||||
|
||||
type tokenBucketRateLimiter struct {
|
||||
limiter *ratelimit.Bucket
|
||||
qps float32
|
||||
}
|
||||
|
||||
// NewTokenBucketRateLimiter creates a rate limiter which implements a token bucket approach.
|
||||
|
|
@ -48,7 +51,10 @@ type tokenBucketRateLimiter struct {
|
|||
// The maximum number of tokens in the bucket is capped at 'burst'.
|
||||
func NewTokenBucketRateLimiter(qps float32, burst int) RateLimiter {
|
||||
limiter := ratelimit.NewBucketWithRate(float64(qps), int64(burst))
|
||||
return &tokenBucketRateLimiter{limiter}
|
||||
return &tokenBucketRateLimiter{
|
||||
limiter: limiter,
|
||||
qps: qps,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tokenBucketRateLimiter) TryAccept() bool {
|
||||
|
|
@ -69,6 +75,10 @@ func (t *tokenBucketRateLimiter) Accept() {
|
|||
func (t *tokenBucketRateLimiter) Stop() {
|
||||
}
|
||||
|
||||
func (t *tokenBucketRateLimiter) QPS() float32 {
|
||||
return t.qps
|
||||
}
|
||||
|
||||
type fakeAlwaysRateLimiter struct{}
|
||||
|
||||
func NewFakeAlwaysRateLimiter() RateLimiter {
|
||||
|
|
@ -87,16 +97,18 @@ func (t *fakeAlwaysRateLimiter) Stop() {}
|
|||
|
||||
func (t *fakeAlwaysRateLimiter) Accept() {}
|
||||
|
||||
func (t *fakeAlwaysRateLimiter) QPS() float32 {
|
||||
return 1
|
||||
}
|
||||
|
||||
type fakeNeverRateLimiter struct {
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewFakeNeverRateLimiter() RateLimiter {
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
return &fakeNeverRateLimiter{
|
||||
wg: wg,
|
||||
}
|
||||
rl := fakeNeverRateLimiter{}
|
||||
rl.wg.Add(1)
|
||||
return &rl
|
||||
}
|
||||
|
||||
func (t *fakeNeverRateLimiter) TryAccept() bool {
|
||||
|
|
@ -114,3 +126,7 @@ func (t *fakeNeverRateLimiter) Stop() {
|
|||
func (t *fakeNeverRateLimiter) Accept() {
|
||||
t.wg.Wait()
|
||||
}
|
||||
|
||||
func (t *fakeNeverRateLimiter) QPS() float32 {
|
||||
return 1
|
||||
}
|
||||
|
|
|
|||
29
vendor/k8s.io/kubernetes/pkg/util/intstr/generated.pb.go
generated
vendored
29
vendor/k8s.io/kubernetes/pkg/util/intstr/generated.pb.go
generated
vendored
|
|
@ -40,8 +40,13 @@ var _ = proto.Marshal
|
|||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
func (m *IntOrString) Reset() { *m = IntOrString{} }
|
||||
func (*IntOrString) ProtoMessage() {}
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
const _ = proto.GoGoProtoPackageIsVersion1
|
||||
|
||||
func (m *IntOrString) Reset() { *m = IntOrString{} }
|
||||
func (*IntOrString) ProtoMessage() {}
|
||||
func (*IntOrString) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*IntOrString)(nil), "k8s.io.kubernetes.pkg.util.intstr.IntOrString")
|
||||
|
|
@ -345,3 +350,23 @@ var (
|
|||
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 256 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x32, 0xcc, 0xb6, 0x28, 0xd6,
|
||||
0xcb, 0xcc, 0xd7, 0xcf, 0x2e, 0x4d, 0x4a, 0x2d, 0xca, 0x4b, 0x2d, 0x49, 0x2d, 0xd6, 0x2f, 0xc8,
|
||||
0x4e, 0xd7, 0x2f, 0x2d, 0xc9, 0xcc, 0xd1, 0xcf, 0xcc, 0x2b, 0x29, 0x2e, 0x29, 0xd2, 0x4f, 0x4f,
|
||||
0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52, 0x84,
|
||||
0x68, 0xd1, 0x43, 0x68, 0xd1, 0x03, 0x6a, 0xd1, 0x03, 0x69, 0xd1, 0x83, 0x68, 0x91, 0xd2, 0x4d,
|
||||
0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0x4f, 0xcf, 0xd7, 0x07,
|
||||
0xeb, 0x4c, 0x2a, 0x4d, 0x03, 0xf3, 0xc0, 0x1c, 0x30, 0x0b, 0x62, 0xa2, 0xd2, 0x44, 0x46, 0x2e,
|
||||
0x6e, 0xcf, 0xbc, 0x12, 0xff, 0xa2, 0xe0, 0x92, 0xa2, 0xcc, 0xbc, 0x74, 0x21, 0x0d, 0x2e, 0x96,
|
||||
0x92, 0xca, 0x82, 0x54, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x66, 0x27, 0x91, 0x13, 0xf7, 0xe4, 0x19,
|
||||
0x1e, 0xdd, 0x93, 0x67, 0x09, 0x01, 0x8a, 0xfd, 0x82, 0xd2, 0x41, 0x60, 0x15, 0x42, 0x6a, 0x5c,
|
||||
0x6c, 0x40, 0x2b, 0xc3, 0x12, 0x73, 0x24, 0x98, 0x80, 0x6a, 0x59, 0x9d, 0xf8, 0xa0, 0x6a, 0xd9,
|
||||
0x3c, 0xc1, 0xa2, 0x41, 0x50, 0x59, 0x90, 0x3a, 0xa0, 0xbb, 0x40, 0xea, 0x98, 0x81, 0xea, 0x38,
|
||||
0x11, 0xea, 0x82, 0xc1, 0xa2, 0x41, 0x50, 0x59, 0x2b, 0x8e, 0x19, 0x0b, 0xe4, 0x19, 0x1a, 0xee,
|
||||
0x28, 0x30, 0x38, 0x69, 0x9c, 0x78, 0x28, 0xc7, 0x70, 0x01, 0x88, 0x6f, 0x00, 0x71, 0xc3, 0x23,
|
||||
0x39, 0xc6, 0x13, 0x40, 0x7c, 0x01, 0x88, 0x1f, 0x00, 0xf1, 0x84, 0xc7, 0x72, 0x0c, 0x51, 0x6c,
|
||||
0x10, 0xcf, 0x02, 0x02, 0x00, 0x00, 0xff, 0xff, 0x68, 0x57, 0xfb, 0xfa, 0x43, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
|||
63
vendor/k8s.io/kubernetes/pkg/util/line_delimiter.go
generated
vendored
63
vendor/k8s.io/kubernetes/pkg/util/line_delimiter.go
generated
vendored
|
|
@ -1,63 +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 util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A Line Delimiter is a filter that will
|
||||
type LineDelimiter struct {
|
||||
output io.Writer
|
||||
delimiter []byte
|
||||
buf bytes.Buffer
|
||||
}
|
||||
|
||||
// NewLineDelimiter allocates a new io.Writer that will split input on lines
|
||||
// and bracket each line with the delimiter string. This can be useful in
|
||||
// output tests where it is difficult to see and test trailing whitespace.
|
||||
func NewLineDelimiter(output io.Writer, delimiter string) *LineDelimiter {
|
||||
return &LineDelimiter{output: output, delimiter: []byte(delimiter)}
|
||||
}
|
||||
|
||||
// Write writes buf to the LineDelimiter ld. The only errors returned are ones
|
||||
// encountered while writing to the underlying output stream.
|
||||
func (ld *LineDelimiter) Write(buf []byte) (n int, err error) {
|
||||
return ld.buf.Write(buf)
|
||||
}
|
||||
|
||||
// Flush all lines up until now. This will assume insert a linebreak at the current point of the stream.
|
||||
func (ld *LineDelimiter) Flush() (err error) {
|
||||
lines := strings.Split(ld.buf.String(), "\n")
|
||||
for _, line := range lines {
|
||||
if _, err = ld.output.Write(ld.delimiter); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = ld.output.Write([]byte(line)); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = ld.output.Write(ld.delimiter); err != nil {
|
||||
return
|
||||
}
|
||||
if _, err = ld.output.Write([]byte("\n")); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
61
vendor/k8s.io/kubernetes/pkg/util/logs.go
generated
vendored
61
vendor/k8s.io/kubernetes/pkg/util/logs.go
generated
vendored
|
|
@ -1,61 +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 util
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
)
|
||||
|
||||
var logFlushFreq = pflag.Duration("log-flush-frequency", 5*time.Second, "Maximum number of seconds between log flushes")
|
||||
|
||||
// TODO(thockin): This is temporary until we agree on log dirs and put those into each cmd.
|
||||
func init() {
|
||||
flag.Set("logtostderr", "true")
|
||||
}
|
||||
|
||||
// GlogWriter serves as a bridge between the standard log package and the glog package.
|
||||
type GlogWriter struct{}
|
||||
|
||||
// Write implements the io.Writer interface.
|
||||
func (writer GlogWriter) Write(data []byte) (n int, err error) {
|
||||
glog.Info(string(data))
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
// InitLogs initializes logs the way we want for kubernetes.
|
||||
func InitLogs() {
|
||||
log.SetOutput(GlogWriter{})
|
||||
log.SetFlags(0)
|
||||
// The default glog flush interval is 30 seconds, which is frighteningly long.
|
||||
go wait.Until(glog.Flush, *logFlushFreq, wait.NeverStop)
|
||||
}
|
||||
|
||||
// FlushLogs flushes logs immediately.
|
||||
func FlushLogs() {
|
||||
glog.Flush()
|
||||
}
|
||||
|
||||
// NewLogger creates a new log.Logger which sends logs to glog.Info.
|
||||
func NewLogger(prefix string) *log.Logger {
|
||||
return log.New(GlogWriter{}, prefix, 0)
|
||||
}
|
||||
6
vendor/k8s.io/kubernetes/pkg/util/net/http.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/util/net/http.go
generated
vendored
|
|
@ -77,10 +77,8 @@ func SetOldTransportDefaults(t *http.Transport) *http.Transport {
|
|||
// for the Proxy, Dial, and TLSHandshakeTimeout fields if unset
|
||||
func SetTransportDefaults(t *http.Transport) *http.Transport {
|
||||
t = SetOldTransportDefaults(t)
|
||||
// Allow clients to disable http2 if needed.
|
||||
if s := os.Getenv("DISABLE_HTTP2"); len(s) > 0 {
|
||||
glog.Infof("HTTP2 has been explicitly disabled")
|
||||
} else {
|
||||
// Allow HTTP2 clients but default off for now
|
||||
if s := os.Getenv("ENABLE_HTTP2"); len(s) > 0 {
|
||||
if err := http2.ConfigureTransport(t); err != nil {
|
||||
glog.Warningf("Transport failed http2 configuration: %v", err)
|
||||
}
|
||||
|
|
|
|||
7
vendor/k8s.io/kubernetes/pkg/util/net/port_range.go
generated
vendored
7
vendor/k8s.io/kubernetes/pkg/util/net/port_range.go
generated
vendored
|
|
@ -71,12 +71,17 @@ func (pr *PortRange) Set(value string) error {
|
|||
high, err = strconv.Atoi(value[hyphenIndex+1:])
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse port range: %s", value)
|
||||
return fmt.Errorf("unable to parse port range: %s: %v", value, err)
|
||||
}
|
||||
|
||||
if low > 65535 || high > 65535 {
|
||||
return fmt.Errorf("the port range cannot be greater than 65535: %s", value)
|
||||
}
|
||||
|
||||
if high < low {
|
||||
return fmt.Errorf("end port cannot be less than start port: %s", value)
|
||||
}
|
||||
|
||||
pr.Base = low
|
||||
pr.Size = 1 + high - low
|
||||
return nil
|
||||
|
|
|
|||
17
vendor/k8s.io/kubernetes/pkg/util/net/sets/README.md
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/util/net/sets/README.md
generated
vendored
|
|
@ -1,17 +0,0 @@
|
|||
This package contains hand-coded set implementations that should be similar to
|
||||
the autogenerated ones in `pkg/util/sets`.
|
||||
|
||||
We can't simply use net.IPNet as a map-key in Go (because it contains a
|
||||
`[]byte`).
|
||||
|
||||
We could use the same workaround we use here (a string representation as the
|
||||
key) to autogenerate sets. If we do that, or decide on an alternate approach,
|
||||
we should replace the implementations in this package with the autogenerated
|
||||
versions.
|
||||
|
||||
It is expected that callers will alias this import as `netsets`
|
||||
i.e. `import netsets "k8s.io/kubernetes/pkg/util/net/sets"`
|
||||
|
||||
|
||||
|
||||
[]()
|
||||
28
vendor/k8s.io/kubernetes/pkg/util/net/sets/doc.go
generated
vendored
Normal file
28
vendor/k8s.io/kubernetes/pkg/util/net/sets/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// This package contains hand-coded set implementations that should be similar
|
||||
// to the autogenerated ones in pkg/util/sets.
|
||||
// We can't simply use net.IPNet as a map-key in Go (because it contains a
|
||||
// []byte).
|
||||
// We could use the same workaround we use here (a string representation as the
|
||||
// key) to autogenerate sets. If we do that, or decide on an alternate
|
||||
// approach, we should replace the implementations in this package with the
|
||||
// autogenerated versions.
|
||||
// It is expected that callers will alias this import as "netsets" i.e. import
|
||||
// netsets "k8s.io/kubernetes/pkg/util/net/sets"
|
||||
|
||||
package sets
|
||||
2
vendor/k8s.io/kubernetes/pkg/util/pod/pod.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/util/pod/pod.go
generated
vendored
|
|
@ -70,7 +70,7 @@ func UpdatePodWithRetries(podClient unversionedcore.PodInterface, pod *api.Pod,
|
|||
|
||||
// Handle returned error from wait poll
|
||||
if err == wait.ErrWaitTimeout {
|
||||
err = fmt.Errorf("timed out trying to update pod: %+v", oldPod)
|
||||
err = fmt.Errorf("timed out trying to update pod: %#v", oldPod)
|
||||
}
|
||||
// Ignore the pod not found error, but the pod isn't updated.
|
||||
if errors.IsNotFound(err) {
|
||||
|
|
|
|||
24
vendor/k8s.io/kubernetes/pkg/util/replicaset/replicaset.go
generated
vendored
24
vendor/k8s.io/kubernetes/pkg/util/replicaset/replicaset.go
generated
vendored
|
|
@ -66,7 +66,7 @@ func UpdateRSWithRetries(rsClient unversionedextensions.ReplicaSetInterface, rs
|
|||
|
||||
// Handle returned error from wait poll
|
||||
if err == wait.ErrWaitTimeout {
|
||||
err = fmt.Errorf("timed out trying to update RS: %+v", oldRs)
|
||||
err = fmt.Errorf("timed out trying to update RS: %#v", oldRs)
|
||||
}
|
||||
// Ignore the RS not found error, but the RS isn't updated.
|
||||
if errors.IsNotFound(err) {
|
||||
|
|
@ -108,3 +108,25 @@ func MatchingPodsFunc(rs *extensions.ReplicaSet) (func(api.Pod) bool, error) {
|
|||
return selector.Matches(podLabelsSelector)
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ReplicaSetIsInactive returns a condition that will be true when a replica set is inactive ie.
|
||||
// it has zero running replicas.
|
||||
func ReplicaSetIsInactive(c unversionedextensions.ExtensionsInterface, replicaSet *extensions.ReplicaSet) wait.ConditionFunc {
|
||||
|
||||
// If we're given a ReplicaSet where the status lags the spec, it either means that the
|
||||
// ReplicaSet is stale, or that the ReplicaSet manager hasn't noticed the update yet.
|
||||
// Polling status.Replicas is not safe in the latter case.
|
||||
desiredGeneration := replicaSet.Generation
|
||||
|
||||
return func() (bool, error) {
|
||||
rs, err := c.ReplicaSets(replicaSet.Namespace).Get(replicaSet.Name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return rs.Status.ObservedGeneration >= desiredGeneration &&
|
||||
rs.Spec.Replicas == 0 &&
|
||||
rs.Status.Replicas == 0 &&
|
||||
rs.Status.FullyLabeledReplicas == 0, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
49
vendor/k8s.io/kubernetes/pkg/util/resource_container_linux.go
generated
vendored
49
vendor/k8s.io/kubernetes/pkg/util/resource_container_linux.go
generated
vendored
|
|
@ -1,49 +0,0 @@
|
|||
// +build linux
|
||||
|
||||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
)
|
||||
|
||||
// Creates resource-only containerName if it does not already exist and moves
|
||||
// the current process to it.
|
||||
//
|
||||
// containerName must be an absolute container name.
|
||||
func RunInResourceContainer(containerName string) error {
|
||||
manager := fs.Manager{
|
||||
Cgroups: &configs.Cgroup{
|
||||
Parent: "/",
|
||||
Name: containerName,
|
||||
Resources: &configs.Resources{
|
||||
AllowAllDevices: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return manager.Apply(os.Getpid())
|
||||
}
|
||||
|
||||
func ApplyRLimitForSelf(maxOpenFiles uint64) {
|
||||
syscall.Setrlimit(syscall.RLIMIT_NOFILE, &syscall.Rlimit{Max: maxOpenFiles, Cur: maxOpenFiles})
|
||||
}
|
||||
58
vendor/k8s.io/kubernetes/pkg/util/runner.go
generated
vendored
58
vendor/k8s.io/kubernetes/pkg/util/runner.go
generated
vendored
|
|
@ -1,58 +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 util
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Runner is an abstraction to make it easy to start and stop groups of things that can be
|
||||
// described by a single function which waits on a channel close to exit.
|
||||
type Runner struct {
|
||||
lock sync.Mutex
|
||||
loopFuncs []func(stop chan struct{})
|
||||
stop *chan struct{}
|
||||
}
|
||||
|
||||
// NewRunner makes a runner for the given function(s). The function(s) should loop until
|
||||
// the channel is closed.
|
||||
func NewRunner(f ...func(stop chan struct{})) *Runner {
|
||||
return &Runner{loopFuncs: f}
|
||||
}
|
||||
|
||||
// Start begins running.
|
||||
func (r *Runner) Start() {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
if r.stop == nil {
|
||||
c := make(chan struct{})
|
||||
r.stop = &c
|
||||
for i := range r.loopFuncs {
|
||||
go r.loopFuncs[i](*r.stop)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stop stops running.
|
||||
func (r *Runner) Stop() {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
if r.stop != nil {
|
||||
close(*r.stop)
|
||||
r.stop = nil
|
||||
}
|
||||
}
|
||||
54
vendor/k8s.io/kubernetes/pkg/util/runtime/runtime.go
generated
vendored
54
vendor/k8s.io/kubernetes/pkg/util/runtime/runtime.go
generated
vendored
|
|
@ -18,23 +18,32 @@ package runtime
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
"runtime"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// For testing, bypass HandleCrash.
|
||||
var ReallyCrash bool
|
||||
var (
|
||||
// ReallyCrash controls the behavior of HandleCrash and now defaults
|
||||
// true. It's still exposed so components can optionally set to false
|
||||
// to restore prior behavior.
|
||||
ReallyCrash = true
|
||||
)
|
||||
|
||||
// PanicHandlers is a list of functions which will be invoked when a panic happens.
|
||||
var PanicHandlers = []func(interface{}){logPanic}
|
||||
|
||||
//TODO search the public functions
|
||||
// HandleCrash simply catches a crash and logs an error. Meant to be called via defer.
|
||||
// Additional context-specific handlers can be provided, and will be called in case of panic
|
||||
// HandleCrash simply catches a crash and logs an error. Meant to be called via
|
||||
// defer. Additional context-specific handlers can be provided, and will be
|
||||
// called in case of panic. HandleCrash actually crashes, after calling the
|
||||
// handlers and logging the panic message.
|
||||
//
|
||||
// TODO: remove this function. We are switching to a world where it's safe for
|
||||
// apiserver to panic, since it will be restarted by kubelet. At the beginning
|
||||
// of the Kubernetes project, nothing was going to restart apiserver and so
|
||||
// catching panics was important. But it's actually much simpler for montoring
|
||||
// software if we just exit when an unexpected panic happens.
|
||||
func HandleCrash(additionalHandlers ...func(interface{})) {
|
||||
if ReallyCrash {
|
||||
return
|
||||
}
|
||||
if r := recover(); r != nil {
|
||||
for _, fn := range PanicHandlers {
|
||||
fn(r)
|
||||
|
|
@ -42,11 +51,20 @@ func HandleCrash(additionalHandlers ...func(interface{})) {
|
|||
for _, fn := range additionalHandlers {
|
||||
fn(r)
|
||||
}
|
||||
if ReallyCrash {
|
||||
// Actually proceed to panic.
|
||||
panic(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// logPanic logs the caller tree when a panic occurs.
|
||||
func logPanic(r interface{}) {
|
||||
callers := getCallers(r)
|
||||
glog.Errorf("Observed a panic: %#v (%v)\n%v", r, r, callers)
|
||||
}
|
||||
|
||||
func getCallers(r interface{}) string {
|
||||
callers := ""
|
||||
for i := 0; true; i++ {
|
||||
_, file, line, ok := runtime.Caller(i)
|
||||
|
|
@ -55,7 +73,8 @@ func logPanic(r interface{}) {
|
|||
}
|
||||
callers = callers + fmt.Sprintf("%v:%v\n", file, line)
|
||||
}
|
||||
glog.Errorf("Recovered from panic: %#v (%v)\n%v", r, r, callers)
|
||||
|
||||
return callers
|
||||
}
|
||||
|
||||
// ErrorHandlers is a list of functions which will be invoked when an unreturnable
|
||||
|
|
@ -92,3 +111,18 @@ func GetCaller() string {
|
|||
}
|
||||
return f.Name()
|
||||
}
|
||||
|
||||
// RecoverFromPanic replaces the specified error with an error containing the
|
||||
// original error, and the call tree when a panic occurs. This enables error
|
||||
// handlers to handle errors and panics the same way.
|
||||
func RecoverFromPanic(err *error) {
|
||||
if r := recover(); r != nil {
|
||||
callers := getCallers(r)
|
||||
|
||||
*err = fmt.Errorf(
|
||||
"recovered from panic %q. (err=%v) Call stack:\n%v",
|
||||
r,
|
||||
*err,
|
||||
callers)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
9
vendor/k8s.io/kubernetes/pkg/util/sets/byte.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/util/sets/byte.go
generated
vendored
|
|
@ -174,6 +174,15 @@ func (s Byte) List() []byte {
|
|||
return []byte(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Byte) UnsortedList() []byte {
|
||||
res := make([]byte, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s Byte) PopAny() (byte, bool) {
|
||||
for key := range s {
|
||||
|
|
|
|||
9
vendor/k8s.io/kubernetes/pkg/util/sets/int.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/util/sets/int.go
generated
vendored
|
|
@ -174,6 +174,15 @@ func (s Int) List() []int {
|
|||
return []int(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Int) UnsortedList() []int {
|
||||
res := make([]int, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s Int) PopAny() (int, bool) {
|
||||
for key := range s {
|
||||
|
|
|
|||
9
vendor/k8s.io/kubernetes/pkg/util/sets/int64.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/util/sets/int64.go
generated
vendored
|
|
@ -174,6 +174,15 @@ func (s Int64) List() []int64 {
|
|||
return []int64(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Int64) UnsortedList() []int64 {
|
||||
res := make([]int64, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s Int64) PopAny() (int64, bool) {
|
||||
for key := range s {
|
||||
|
|
|
|||
9
vendor/k8s.io/kubernetes/pkg/util/sets/string.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/util/sets/string.go
generated
vendored
|
|
@ -174,6 +174,15 @@ func (s String) List() []string {
|
|||
return []string(res)
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s String) UnsortedList() []string {
|
||||
res := make([]string, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Returns a single element from the set.
|
||||
func (s String) PopAny() (string, bool) {
|
||||
for key := range s {
|
||||
|
|
|
|||
21
vendor/k8s.io/kubernetes/pkg/util/sysctl/sysctl.go
generated
vendored
21
vendor/k8s.io/kubernetes/pkg/util/sysctl/sysctl.go
generated
vendored
|
|
@ -37,8 +37,25 @@ const (
|
|||
KernelPanicRebootTimeout = 10 // seconds after a panic for the kernel to reboot
|
||||
)
|
||||
|
||||
// An injectable interface for running sysctl commands.
|
||||
type Interface interface {
|
||||
// GetSysctl returns the value for the specified sysctl setting
|
||||
GetSysctl(sysctl string) (int, error)
|
||||
// SetSysctl modifies the specified sysctl flag to the new value
|
||||
SetSysctl(sysctl string, newVal int) error
|
||||
}
|
||||
|
||||
// New returns a new Interface for accessing sysctl
|
||||
func New() Interface {
|
||||
return &procSysctl{}
|
||||
}
|
||||
|
||||
// procSysctl implements Interface by reading and writing files under /proc/sys
|
||||
type procSysctl struct {
|
||||
}
|
||||
|
||||
// GetSysctl returns the value for the specified sysctl setting
|
||||
func GetSysctl(sysctl string) (int, error) {
|
||||
func (_ *procSysctl) GetSysctl(sysctl string) (int, error) {
|
||||
data, err := ioutil.ReadFile(path.Join(sysctlBase, sysctl))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
|
|
@ -51,6 +68,6 @@ func GetSysctl(sysctl string) (int, error) {
|
|||
}
|
||||
|
||||
// SetSysctl modifies the specified sysctl flag to the new value
|
||||
func SetSysctl(sysctl string, newVal int) error {
|
||||
func (_ *procSysctl) SetSysctl(sysctl string, newVal int) error {
|
||||
return ioutil.WriteFile(path.Join(sysctlBase, sysctl), []byte(strconv.Itoa(newVal)), 0640)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"sync"
|
||||
56
vendor/k8s.io/kubernetes/pkg/util/validation/validation.go
generated
vendored
56
vendor/k8s.io/kubernetes/pkg/util/validation/validation.go
generated
vendored
|
|
@ -121,20 +121,41 @@ func IsDNS1123Subdomain(value string) []string {
|
|||
return errs
|
||||
}
|
||||
|
||||
const dns952LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?"
|
||||
const DNS952LabelMaxLength int = 24
|
||||
const dns1035LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?"
|
||||
const DNS1035LabelMaxLength int = 63
|
||||
|
||||
var dns952LabelRegexp = regexp.MustCompile("^" + dns952LabelFmt + "$")
|
||||
var dns1035LabelRegexp = regexp.MustCompile("^" + dns1035LabelFmt + "$")
|
||||
|
||||
// IsDNS952Label tests for a string that conforms to the definition of a label in
|
||||
// DNS (RFC 952).
|
||||
func IsDNS952Label(value string) []string {
|
||||
// IsDNS1035Label tests for a string that conforms to the definition of a label in
|
||||
// DNS (RFC 1035).
|
||||
func IsDNS1035Label(value string) []string {
|
||||
var errs []string
|
||||
if len(value) > DNS952LabelMaxLength {
|
||||
errs = append(errs, MaxLenError(DNS952LabelMaxLength))
|
||||
if len(value) > DNS1035LabelMaxLength {
|
||||
errs = append(errs, MaxLenError(DNS1035LabelMaxLength))
|
||||
}
|
||||
if !dns952LabelRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(dns952LabelFmt, "my-name", "abc-123"))
|
||||
if !dns1035LabelRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(dns1035LabelFmt, "my-name", "abc-123"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// wildcard definition - RFC 1034 section 4.3.3.
|
||||
// examples:
|
||||
// - valid: *.bar.com, *.foo.bar.com
|
||||
// - invalid: *.*.bar.com, *.foo.*.com, *bar.com, f*.bar.com, *
|
||||
const wildcardDNF1123SubdomainFmt = "\\*\\." + dns1123SubdomainFmt
|
||||
|
||||
// IsWildcardDNS1123Subdomain tests for a string that conforms to the definition of a
|
||||
// wildcard subdomain in DNS (RFC 1034 section 4.3.3).
|
||||
func IsWildcardDNS1123Subdomain(value string) []string {
|
||||
wildcardDNS1123SubdomainRegexp := regexp.MustCompile("^\\*\\." + dns1123SubdomainFmt + "$")
|
||||
|
||||
var errs []string
|
||||
if len(value) > DNS1123SubdomainMaxLength {
|
||||
errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
|
||||
}
|
||||
if !wildcardDNS1123SubdomainRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(wildcardDNF1123SubdomainFmt, "*.example.com"))
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
|
@ -247,19 +268,26 @@ func IsHTTPHeaderName(value string) []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
const configMapKeyFmt = "\\.?" + dns1123SubdomainFmt
|
||||
const configMapKeyFmt = `[-._a-zA-Z0-9]+`
|
||||
|
||||
var configMapKeyRegexp = regexp.MustCompile("^" + configMapKeyFmt + "$")
|
||||
|
||||
// IsConfigMapKey tests for a string that conforms to the definition of a
|
||||
// subdomain in DNS (RFC 1123), except that a leading dot is allowed
|
||||
// IsConfigMapKey tests for a string that is a valid key for a ConfigMap or Secret
|
||||
func IsConfigMapKey(value string) []string {
|
||||
var errs []string
|
||||
if len(value) > DNS1123SubdomainMaxLength {
|
||||
errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
|
||||
}
|
||||
if !configMapKeyRegexp.MatchString(value) {
|
||||
errs = append(errs, RegexError(configMapKeyFmt, "key.name"))
|
||||
errs = append(errs, RegexError(configMapKeyFmt, "key.name", "KEY_NAME", "key-name"))
|
||||
}
|
||||
if value == "." {
|
||||
errs = append(errs, `must not be '.'`)
|
||||
}
|
||||
if value == ".." {
|
||||
errs = append(errs, `must not be '..'`)
|
||||
} else if strings.HasPrefix(value, "..") {
|
||||
errs = append(errs, `must not start with '..'`)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
|
|
|||
29
vendor/k8s.io/kubernetes/pkg/util/wait/wait.go
generated
vendored
29
vendor/k8s.io/kubernetes/pkg/util/wait/wait.go
generated
vendored
|
|
@ -20,8 +20,6 @@ import (
|
|||
"errors"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/runtime"
|
||||
)
|
||||
|
||||
// For any test of the style:
|
||||
|
|
@ -64,13 +62,14 @@ func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) {
|
|||
// stop channel is already closed. Pass NeverStop to Until if you
|
||||
// don't want it stop.
|
||||
func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding bool, stopCh <-chan struct{}) {
|
||||
select {
|
||||
case <-stopCh:
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
for {
|
||||
|
||||
select {
|
||||
case <-stopCh:
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
jitteredPeriod := period
|
||||
if jitterFactor > 0.0 {
|
||||
jitteredPeriod = Jitter(period, jitterFactor)
|
||||
|
|
@ -82,22 +81,18 @@ func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding b
|
|||
}
|
||||
|
||||
func() {
|
||||
defer runtime.HandleCrash()
|
||||
f()
|
||||
}()
|
||||
|
||||
if sliding {
|
||||
t = time.NewTimer(jitteredPeriod)
|
||||
} else {
|
||||
// The timer we created could already have fired, so be
|
||||
// careful and check stopCh first.
|
||||
select {
|
||||
case <-stopCh:
|
||||
return
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: b/c there is no priority selection in golang
|
||||
// it is possible for this to race, meaning we could
|
||||
// trigger t.C and stopCh, and t.C select falls through.
|
||||
// In order to mitigate we re-check stopCh at the beginning
|
||||
// of every loop to prevent extra executions of f().
|
||||
select {
|
||||
case <-stopCh:
|
||||
return
|
||||
|
|
|
|||
20
vendor/k8s.io/kubernetes/pkg/util/workqueue/delaying_queue.go
generated
vendored
20
vendor/k8s.io/kubernetes/pkg/util/workqueue/delaying_queue.go
generated
vendored
|
|
@ -20,7 +20,7 @@ import (
|
|||
"sort"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/pkg/util/clock"
|
||||
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -34,17 +34,22 @@ type DelayingInterface interface {
|
|||
|
||||
// NewDelayingQueue constructs a new workqueue with delayed queuing ability
|
||||
func NewDelayingQueue() DelayingInterface {
|
||||
return newDelayingQueue(util.RealClock{})
|
||||
return newDelayingQueue(clock.RealClock{}, "")
|
||||
}
|
||||
|
||||
func newDelayingQueue(clock util.Clock) DelayingInterface {
|
||||
func NewNamedDelayingQueue(name string) DelayingInterface {
|
||||
return newDelayingQueue(clock.RealClock{}, name)
|
||||
}
|
||||
|
||||
func newDelayingQueue(clock clock.Clock, name string) DelayingInterface {
|
||||
ret := &delayingType{
|
||||
Interface: New(),
|
||||
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()
|
||||
|
|
@ -57,7 +62,7 @@ type delayingType struct {
|
|||
Interface
|
||||
|
||||
// clock tracks time for delayed firing
|
||||
clock util.Clock
|
||||
clock clock.Clock
|
||||
|
||||
// stopCh lets us signal a shutdown to the waiting loop
|
||||
stopCh chan struct{}
|
||||
|
|
@ -71,6 +76,9 @@ type delayingType struct {
|
|||
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
|
||||
|
|
@ -92,6 +100,8 @@ func (q *delayingType) AddAfter(item interface{}, duration time.Duration) {
|
|||
return
|
||||
}
|
||||
|
||||
q.metrics.retry()
|
||||
|
||||
// immediately add things with no delay
|
||||
if duration <= 0 {
|
||||
q.Add(item)
|
||||
|
|
|
|||
153
vendor/k8s.io/kubernetes/pkg/util/workqueue/metrics.go
generated
vendored
Normal file
153
vendor/k8s.io/kubernetes/pkg/util/workqueue/metrics.go
generated
vendored
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
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"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type queueMetrics interface {
|
||||
add(item t)
|
||||
get(item t)
|
||||
done(item t)
|
||||
}
|
||||
|
||||
type defaultQueueMetrics struct {
|
||||
depth prometheus.Gauge
|
||||
adds prometheus.Counter
|
||||
latency prometheus.Summary
|
||||
workDuration prometheus.Summary
|
||||
addTimes map[t]time.Time
|
||||
processingStartTimes map[t]time.Time
|
||||
}
|
||||
|
||||
func newQueueMetrics(name string) queueMetrics {
|
||||
var ret *defaultQueueMetrics
|
||||
if len(name) == 0 {
|
||||
return ret
|
||||
}
|
||||
|
||||
ret = &defaultQueueMetrics{
|
||||
depth: prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Subsystem: name,
|
||||
Name: "depth",
|
||||
Help: "Current depth of workqueue: " + name,
|
||||
}),
|
||||
adds: prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Subsystem: name,
|
||||
Name: "adds",
|
||||
Help: "Total number of adds handled by workqueue: " + name,
|
||||
}),
|
||||
latency: prometheus.NewSummary(prometheus.SummaryOpts{
|
||||
Subsystem: name,
|
||||
Name: "queue_latency",
|
||||
Help: "How long an item stays in workqueue" + name + " before being requested.",
|
||||
}),
|
||||
workDuration: prometheus.NewSummary(prometheus.SummaryOpts{
|
||||
Subsystem: name,
|
||||
Name: "work_duration",
|
||||
Help: "How long processing an item from workqueue" + name + " takes.",
|
||||
}),
|
||||
addTimes: map[t]time.Time{},
|
||||
processingStartTimes: map[t]time.Time{},
|
||||
}
|
||||
|
||||
prometheus.Register(ret.depth)
|
||||
prometheus.Register(ret.adds)
|
||||
prometheus.Register(ret.latency)
|
||||
prometheus.Register(ret.workDuration)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
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 prometheus.Counter
|
||||
}
|
||||
|
||||
func newRetryMetrics(name string) retryMetrics {
|
||||
var ret *defaultRetryMetrics
|
||||
if len(name) == 0 {
|
||||
return ret
|
||||
}
|
||||
|
||||
ret = &defaultRetryMetrics{
|
||||
retries: prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Subsystem: name,
|
||||
Name: "retries",
|
||||
Help: "Total number of retries handled by workqueue: " + name,
|
||||
}),
|
||||
}
|
||||
|
||||
prometheus.Register(ret.retries)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (m *defaultRetryMetrics) retry() {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
|
||||
m.retries.Inc()
|
||||
}
|
||||
19
vendor/k8s.io/kubernetes/pkg/util/workqueue/queue.go
generated
vendored
19
vendor/k8s.io/kubernetes/pkg/util/workqueue/queue.go
generated
vendored
|
|
@ -31,10 +31,15 @@ type Interface interface {
|
|||
|
||||
// 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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +62,8 @@ type Type struct {
|
|||
cond *sync.Cond
|
||||
|
||||
shuttingDown bool
|
||||
|
||||
metrics queueMetrics
|
||||
}
|
||||
|
||||
type empty struct{}
|
||||
|
|
@ -86,10 +93,14 @@ func (q *Type) Add(item interface{}) {
|
|||
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()
|
||||
}
|
||||
|
|
@ -116,9 +127,14 @@ func (q *Type) Get() (item interface{}, shutdown bool) {
|
|||
// 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
|
||||
}
|
||||
|
||||
|
|
@ -128,6 +144,9 @@ func (q *Type) Get() (item interface{}, shutdown bool) {
|
|||
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)
|
||||
|
|
|
|||
7
vendor/k8s.io/kubernetes/pkg/util/workqueue/rate_limitting_queue.go
generated
vendored
7
vendor/k8s.io/kubernetes/pkg/util/workqueue/rate_limitting_queue.go
generated
vendored
|
|
@ -40,6 +40,13 @@ func NewRateLimitingQueue(rateLimiter RateLimiter) RateLimitingInterface {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
52
vendor/k8s.io/kubernetes/pkg/util/workqueue/timed_queue.go
generated
vendored
Normal file
52
vendor/k8s.io/kubernetes/pkg/util/workqueue/timed_queue.go
generated
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
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
|
||||
}
|
||||
79
vendor/k8s.io/kubernetes/pkg/util/yaml/decoder.go
generated
vendored
79
vendor/k8s.io/kubernetes/pkg/util/yaml/decoder.go
generated
vendored
|
|
@ -45,7 +45,7 @@ func ToJSON(data []byte) ([]byte, error) {
|
|||
// separating individual documents. It first converts the YAML
|
||||
// body to JSON, then unmarshals the JSON.
|
||||
type YAMLToJSONDecoder struct {
|
||||
scanner *bufio.Scanner
|
||||
reader Reader
|
||||
}
|
||||
|
||||
// NewYAMLToJSONDecoder decodes YAML documents from the provided
|
||||
|
|
@ -53,10 +53,9 @@ type YAMLToJSONDecoder struct {
|
|||
// the YAML spec) into its own chunk, converting it to JSON via
|
||||
// yaml.YAMLToJSON, and then passing it to json.Decoder.
|
||||
func NewYAMLToJSONDecoder(r io.Reader) *YAMLToJSONDecoder {
|
||||
scanner := bufio.NewScanner(r)
|
||||
scanner.Split(splitYAMLDocument)
|
||||
reader := bufio.NewReader(r)
|
||||
return &YAMLToJSONDecoder{
|
||||
scanner: scanner,
|
||||
reader: NewYAMLReader(reader),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,17 +63,18 @@ func NewYAMLToJSONDecoder(r io.Reader) *YAMLToJSONDecoder {
|
|||
// an error. The decoding rules match json.Unmarshal, not
|
||||
// yaml.Unmarshal.
|
||||
func (d *YAMLToJSONDecoder) Decode(into interface{}) error {
|
||||
if d.scanner.Scan() {
|
||||
data, err := yaml.YAMLToJSON(d.scanner.Bytes())
|
||||
bytes, err := d.reader.Read()
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(bytes) != 0 {
|
||||
data, err := yaml.YAMLToJSON(bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(data, into)
|
||||
}
|
||||
err := d.scanner.Err()
|
||||
if err == nil {
|
||||
err = io.EOF
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -137,6 +137,7 @@ func (d *YAMLDecoder) Close() error {
|
|||
}
|
||||
|
||||
const yamlSeparator = "\n---"
|
||||
const separator = "---\n"
|
||||
|
||||
// splitYAMLDocument is a bufio.SplitFunc for splitting YAML streams into individual documents.
|
||||
func splitYAMLDocument(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||
|
|
@ -222,6 +223,64 @@ func (d *YAMLOrJSONDecoder) Decode(into interface{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
type Reader interface {
|
||||
Read() ([]byte, error)
|
||||
}
|
||||
|
||||
type YAMLReader struct {
|
||||
reader Reader
|
||||
}
|
||||
|
||||
func NewYAMLReader(r *bufio.Reader) *YAMLReader {
|
||||
return &YAMLReader{
|
||||
reader: &LineReader{reader: r},
|
||||
}
|
||||
}
|
||||
|
||||
// Read returns a full YAML document.
|
||||
func (r *YAMLReader) Read() ([]byte, error) {
|
||||
var buffer bytes.Buffer
|
||||
for {
|
||||
line, err := r.reader.Read()
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if string(line) == separator || err == io.EOF {
|
||||
if buffer.Len() != 0 {
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
if err == io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
buffer.Write(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type LineReader struct {
|
||||
reader *bufio.Reader
|
||||
}
|
||||
|
||||
// Read returns a single line (with '\n' ended) from the underlying reader.
|
||||
// An error is returned iff there is an error with the underlying reader.
|
||||
func (r *LineReader) Read() ([]byte, error) {
|
||||
var (
|
||||
isPrefix bool = true
|
||||
err error = nil
|
||||
line []byte
|
||||
buffer bytes.Buffer
|
||||
)
|
||||
|
||||
for isPrefix && err == nil {
|
||||
line, isPrefix, err = r.reader.ReadLine()
|
||||
buffer.Write(line)
|
||||
}
|
||||
buffer.WriteByte('\n')
|
||||
return buffer.Bytes(), err
|
||||
}
|
||||
|
||||
// GuessJSONStream scans the provided reader up to size, looking
|
||||
// for an open brace indicating this is JSON. It will return the
|
||||
// bufio.Reader it creates for the consumer.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue