Upgrade k8s package verison (#5358)

* upgrade k8s package version

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

* Script upgrade and code formatting.

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
hongzhouzi
2022-11-15 14:56:38 +08:00
committed by GitHub
parent 5f91c1663a
commit 44167aa47a
3106 changed files with 321340 additions and 172080 deletions

4
vendor/k8s.io/utils/clock/README.md generated vendored Normal file
View File

@@ -0,0 +1,4 @@
# Clock
This package provides an interface for time-based operations. It allows
mocking time for testing.

178
vendor/k8s.io/utils/clock/clock.go generated vendored Normal file
View File

@@ -0,0 +1,178 @@
/*
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 clock
import "time"
// PassiveClock allows for injecting fake or real clocks into code
// that needs to read the current time but does not support scheduling
// activity in the future.
type PassiveClock interface {
Now() time.Time
Since(time.Time) time.Duration
}
// Clock allows for injecting fake or real clocks into code that
// needs to do arbitrary things based on time.
type Clock interface {
PassiveClock
// After returns the channel of a new Timer.
// This method does not allow to free/GC the backing timer before it fires. Use
// NewTimer instead.
After(d time.Duration) <-chan time.Time
// NewTimer returns a new Timer.
NewTimer(d time.Duration) Timer
// Sleep sleeps for the provided duration d.
// Consider making the sleep interruptible by using 'select' on a context channel and a timer channel.
Sleep(d time.Duration)
// Tick returns the channel of a new Ticker.
// This method does not allow to free/GC the backing ticker. Use
// NewTicker from WithTicker instead.
Tick(d time.Duration) <-chan time.Time
}
// WithTicker allows for injecting fake or real clocks into code that
// needs to do arbitrary things based on time.
type WithTicker interface {
Clock
// NewTicker returns a new Ticker.
NewTicker(time.Duration) Ticker
}
// WithDelayedExecution allows for injecting fake or real clocks into
// code that needs to make use of AfterFunc functionality.
type WithDelayedExecution interface {
Clock
// AfterFunc executes f in its own goroutine after waiting
// for d duration and returns a Timer whose channel can be
// closed by calling Stop() on the Timer.
AfterFunc(d time.Duration, f func()) Timer
}
// WithTickerAndDelayedExecution allows for injecting fake or real clocks
// into code that needs Ticker and AfterFunc functionality
type WithTickerAndDelayedExecution interface {
WithTicker
// AfterFunc executes f in its own goroutine after waiting
// for d duration and returns a Timer whose channel can be
// closed by calling Stop() on the Timer.
AfterFunc(d time.Duration, f func()) Timer
}
// Ticker defines the Ticker interface.
type Ticker interface {
C() <-chan time.Time
Stop()
}
var _ = WithTicker(RealClock{})
// RealClock really calls time.Now()
type RealClock struct{}
// Now returns the current time.
func (RealClock) Now() time.Time {
return time.Now()
}
// Since returns time since the specified timestamp.
func (RealClock) Since(ts time.Time) time.Duration {
return time.Since(ts)
}
// After is the same as time.After(d).
// This method does not allow to free/GC the backing timer before it fires. Use
// NewTimer instead.
func (RealClock) After(d time.Duration) <-chan time.Time {
return time.After(d)
}
// NewTimer is the same as time.NewTimer(d)
func (RealClock) NewTimer(d time.Duration) Timer {
return &realTimer{
timer: time.NewTimer(d),
}
}
// AfterFunc is the same as time.AfterFunc(d, f).
func (RealClock) AfterFunc(d time.Duration, f func()) Timer {
return &realTimer{
timer: time.AfterFunc(d, f),
}
}
// Tick is the same as time.Tick(d)
// This method does not allow to free/GC the backing ticker. Use
// NewTicker instead.
func (RealClock) Tick(d time.Duration) <-chan time.Time {
return time.Tick(d)
}
// NewTicker returns a new Ticker.
func (RealClock) NewTicker(d time.Duration) Ticker {
return &realTicker{
ticker: time.NewTicker(d),
}
}
// Sleep is the same as time.Sleep(d)
// Consider making the sleep interruptible by using 'select' on a context channel and a timer channel.
func (RealClock) Sleep(d time.Duration) {
time.Sleep(d)
}
// Timer allows for injecting fake or real timers into code that
// needs to do arbitrary things based on time.
type Timer interface {
C() <-chan time.Time
Stop() bool
Reset(d time.Duration) bool
}
var _ = Timer(&realTimer{})
// realTimer is backed by an actual time.Timer.
type realTimer struct {
timer *time.Timer
}
// C returns the underlying timer's channel.
func (r *realTimer) C() <-chan time.Time {
return r.timer.C
}
// Stop calls Stop() on the underlying timer.
func (r *realTimer) Stop() bool {
return r.timer.Stop()
}
// Reset calls Reset() on the underlying timer.
func (r *realTimer) Reset(d time.Duration) bool {
return r.timer.Reset(d)
}
type realTicker struct {
ticker *time.Ticker
}
func (r *realTicker) C() <-chan time.Time {
return r.ticker.C
}
func (r *realTicker) Stop() {
r.ticker.Stop()
}

361
vendor/k8s.io/utils/clock/testing/fake_clock.go generated vendored Normal file
View File

@@ -0,0 +1,361 @@
/*
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 testing
import (
"sync"
"time"
"k8s.io/utils/clock"
)
var (
_ = clock.PassiveClock(&FakePassiveClock{})
_ = clock.WithTicker(&FakeClock{})
_ = clock.Clock(&IntervalClock{})
)
// FakePassiveClock implements PassiveClock, but returns an arbitrary time.
type FakePassiveClock struct {
lock sync.RWMutex
time time.Time
}
// FakeClock implements clock.Clock, but returns an arbitrary time.
type FakeClock struct {
FakePassiveClock
// waiters are waiting for the fake time to pass their specified time
waiters []*fakeClockWaiter
}
type fakeClockWaiter struct {
targetTime time.Time
stepInterval time.Duration
skipIfBlocked bool
destChan chan time.Time
fired bool
afterFunc func()
}
// NewFakePassiveClock returns a new FakePassiveClock.
func NewFakePassiveClock(t time.Time) *FakePassiveClock {
return &FakePassiveClock{
time: t,
}
}
// NewFakeClock constructs a fake clock set to the provided time.
func NewFakeClock(t time.Time) *FakeClock {
return &FakeClock{
FakePassiveClock: *NewFakePassiveClock(t),
}
}
// Now returns f's time.
func (f *FakePassiveClock) Now() time.Time {
f.lock.RLock()
defer f.lock.RUnlock()
return f.time
}
// Since returns time since the time in f.
func (f *FakePassiveClock) Since(ts time.Time) time.Duration {
f.lock.RLock()
defer f.lock.RUnlock()
return f.time.Sub(ts)
}
// SetTime sets the time on the FakePassiveClock.
func (f *FakePassiveClock) SetTime(t time.Time) {
f.lock.Lock()
defer f.lock.Unlock()
f.time = t
}
// After is the fake version of time.After(d).
func (f *FakeClock) After(d time.Duration) <-chan time.Time {
f.lock.Lock()
defer f.lock.Unlock()
stopTime := f.time.Add(d)
ch := make(chan time.Time, 1) // Don't block!
f.waiters = append(f.waiters, &fakeClockWaiter{
targetTime: stopTime,
destChan: ch,
})
return ch
}
// NewTimer constructs a fake timer, akin to time.NewTimer(d).
func (f *FakeClock) NewTimer(d time.Duration) clock.Timer {
f.lock.Lock()
defer f.lock.Unlock()
stopTime := f.time.Add(d)
ch := make(chan time.Time, 1) // Don't block!
timer := &fakeTimer{
fakeClock: f,
waiter: fakeClockWaiter{
targetTime: stopTime,
destChan: ch,
},
}
f.waiters = append(f.waiters, &timer.waiter)
return timer
}
// AfterFunc is the Fake version of time.AfterFunc(d, cb).
func (f *FakeClock) AfterFunc(d time.Duration, cb func()) clock.Timer {
f.lock.Lock()
defer f.lock.Unlock()
stopTime := f.time.Add(d)
ch := make(chan time.Time, 1) // Don't block!
timer := &fakeTimer{
fakeClock: f,
waiter: fakeClockWaiter{
targetTime: stopTime,
destChan: ch,
afterFunc: cb,
},
}
f.waiters = append(f.waiters, &timer.waiter)
return timer
}
// Tick constructs a fake ticker, akin to time.Tick
func (f *FakeClock) Tick(d time.Duration) <-chan time.Time {
if d <= 0 {
return nil
}
f.lock.Lock()
defer f.lock.Unlock()
tickTime := f.time.Add(d)
ch := make(chan time.Time, 1) // hold one tick
f.waiters = append(f.waiters, &fakeClockWaiter{
targetTime: tickTime,
stepInterval: d,
skipIfBlocked: true,
destChan: ch,
})
return ch
}
// NewTicker returns a new Ticker.
func (f *FakeClock) NewTicker(d time.Duration) clock.Ticker {
f.lock.Lock()
defer f.lock.Unlock()
tickTime := f.time.Add(d)
ch := make(chan time.Time, 1) // hold one tick
f.waiters = append(f.waiters, &fakeClockWaiter{
targetTime: tickTime,
stepInterval: d,
skipIfBlocked: true,
destChan: ch,
})
return &fakeTicker{
c: ch,
}
}
// Step moves the clock by Duration and notifies anyone that's called After,
// Tick, or NewTimer.
func (f *FakeClock) Step(d time.Duration) {
f.lock.Lock()
defer f.lock.Unlock()
f.setTimeLocked(f.time.Add(d))
}
// SetTime sets the time.
func (f *FakeClock) SetTime(t time.Time) {
f.lock.Lock()
defer f.lock.Unlock()
f.setTimeLocked(t)
}
// Actually changes the time and checks any waiters. f must be write-locked.
func (f *FakeClock) setTimeLocked(t time.Time) {
f.time = t
newWaiters := make([]*fakeClockWaiter, 0, len(f.waiters))
for i := range f.waiters {
w := f.waiters[i]
if !w.targetTime.After(t) {
if w.skipIfBlocked {
select {
case w.destChan <- t:
w.fired = true
default:
}
} else {
w.destChan <- t
w.fired = true
}
if w.afterFunc != nil {
w.afterFunc()
}
if w.stepInterval > 0 {
for !w.targetTime.After(t) {
w.targetTime = w.targetTime.Add(w.stepInterval)
}
newWaiters = append(newWaiters, w)
}
} else {
newWaiters = append(newWaiters, f.waiters[i])
}
}
f.waiters = newWaiters
}
// HasWaiters returns true if After or AfterFunc has been called on f but not yet satisfied (so you can
// write race-free tests).
func (f *FakeClock) HasWaiters() bool {
f.lock.RLock()
defer f.lock.RUnlock()
return len(f.waiters) > 0
}
// Sleep is akin to time.Sleep
func (f *FakeClock) Sleep(d time.Duration) {
f.Step(d)
}
// IntervalClock implements clock.PassiveClock, but each invocation of Now steps the clock forward the specified duration.
// IntervalClock technically implements the other methods of clock.Clock, but each implementation is just a panic.
//
// Deprecated: See SimpleIntervalClock for an alternative that only has the methods of PassiveClock.
type IntervalClock struct {
Time time.Time
Duration time.Duration
}
// Now returns i's time.
func (i *IntervalClock) Now() time.Time {
i.Time = i.Time.Add(i.Duration)
return i.Time
}
// Since returns time since the time in i.
func (i *IntervalClock) Since(ts time.Time) time.Duration {
return i.Time.Sub(ts)
}
// After is unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) After(d time.Duration) <-chan time.Time {
panic("IntervalClock doesn't implement After")
}
// NewTimer is unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) NewTimer(d time.Duration) clock.Timer {
panic("IntervalClock doesn't implement NewTimer")
}
// AfterFunc is unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) AfterFunc(d time.Duration, f func()) clock.Timer {
panic("IntervalClock doesn't implement AfterFunc")
}
// Tick is unimplemented, will panic.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) Tick(d time.Duration) <-chan time.Time {
panic("IntervalClock doesn't implement Tick")
}
// NewTicker has no implementation yet and is omitted.
// TODO: make interval clock use FakeClock so this can be implemented.
func (*IntervalClock) NewTicker(d time.Duration) clock.Ticker {
panic("IntervalClock doesn't implement NewTicker")
}
// Sleep is unimplemented, will panic.
func (*IntervalClock) Sleep(d time.Duration) {
panic("IntervalClock doesn't implement Sleep")
}
var _ = clock.Timer(&fakeTimer{})
// fakeTimer implements clock.Timer based on a FakeClock.
type fakeTimer struct {
fakeClock *FakeClock
waiter fakeClockWaiter
}
// C returns the channel that notifies when this timer has fired.
func (f *fakeTimer) C() <-chan time.Time {
return f.waiter.destChan
}
// Stop stops the timer and returns true if the timer has not yet fired, or false otherwise.
func (f *fakeTimer) Stop() bool {
f.fakeClock.lock.Lock()
defer f.fakeClock.lock.Unlock()
newWaiters := make([]*fakeClockWaiter, 0, len(f.fakeClock.waiters))
for i := range f.fakeClock.waiters {
w := f.fakeClock.waiters[i]
if w != &f.waiter {
newWaiters = append(newWaiters, w)
}
}
f.fakeClock.waiters = newWaiters
return !f.waiter.fired
}
// Reset resets the timer to the fake clock's "now" + d. It returns true if the timer has not yet
// fired, or false otherwise.
func (f *fakeTimer) Reset(d time.Duration) bool {
f.fakeClock.lock.Lock()
defer f.fakeClock.lock.Unlock()
active := !f.waiter.fired
f.waiter.fired = false
f.waiter.targetTime = f.fakeClock.time.Add(d)
var isWaiting bool
for i := range f.fakeClock.waiters {
w := f.fakeClock.waiters[i]
if w == &f.waiter {
isWaiting = true
break
}
}
if !isWaiting {
f.fakeClock.waiters = append(f.fakeClock.waiters, &f.waiter)
}
return active
}
type fakeTicker struct {
c <-chan time.Time
}
func (t *fakeTicker) C() <-chan time.Time {
return t.c
}
func (t *fakeTicker) Stop() {
}

View File

@@ -0,0 +1,44 @@
/*
Copyright 2021 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 testing
import (
"time"
"k8s.io/utils/clock"
)
var (
_ = clock.PassiveClock(&SimpleIntervalClock{})
)
// SimpleIntervalClock implements clock.PassiveClock, but each invocation of Now steps the clock forward the specified duration
type SimpleIntervalClock struct {
Time time.Time
Duration time.Duration
}
// Now returns i's time.
func (i *SimpleIntervalClock) Now() time.Time {
i.Time = i.Time.Add(i.Duration)
return i.Time
}
// Since returns time since the time in i.
func (i *SimpleIntervalClock) Since(ts time.Time) time.Duration {
return i.Time.Sub(ts)
}

10
vendor/k8s.io/utils/exec/exec.go generated vendored
View File

@@ -19,6 +19,7 @@ package exec
import (
"context"
"io"
"io/fs"
osexec "os/exec"
"syscall"
"time"
@@ -98,17 +99,18 @@ func New() Interface {
// Command is part of the Interface interface.
func (executor *executor) Command(cmd string, args ...string) Cmd {
return (*cmdWrapper)(osexec.Command(cmd, args...))
return (*cmdWrapper)(maskErrDotCmd(osexec.Command(cmd, args...)))
}
// CommandContext is part of the Interface interface.
func (executor *executor) CommandContext(ctx context.Context, cmd string, args ...string) Cmd {
return (*cmdWrapper)(osexec.CommandContext(ctx, cmd, args...))
return (*cmdWrapper)(maskErrDotCmd(osexec.CommandContext(ctx, cmd, args...)))
}
// LookPath is part of the Interface interface
func (executor *executor) LookPath(file string) (string, error) {
return osexec.LookPath(file)
path, err := osexec.LookPath(file)
return path, handleError(maskErrDot(err))
}
// Wraps exec.Cmd so we can capture errors.
@@ -198,6 +200,8 @@ func handleError(err error) error {
switch e := err.(type) {
case *osexec.ExitError:
return &ExitErrorWrapper{e}
case *fs.PathError:
return ErrExecutableNotFound
case *osexec.Error:
if e.Err == osexec.ErrNotFound {
return ErrExecutableNotFound

32
vendor/k8s.io/utils/exec/fixup_go118.go generated vendored Normal file
View File

@@ -0,0 +1,32 @@
//go:build !go1.19
// +build !go1.19
/*
Copyright 2022 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 (
osexec "os/exec"
)
func maskErrDotCmd(cmd *osexec.Cmd) *osexec.Cmd {
return cmd
}
func maskErrDot(err error) error {
return err
}

40
vendor/k8s.io/utils/exec/fixup_go119.go generated vendored Normal file
View File

@@ -0,0 +1,40 @@
//go:build go1.19
// +build go1.19
/*
Copyright 2022 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 (
"errors"
osexec "os/exec"
)
// maskErrDotCmd reverts the behavior of osexec.Cmd to what it was before go1.19
// specifically set the Err field to nil (LookPath returns a new error when the file
// is resolved to the current directory.
func maskErrDotCmd(cmd *osexec.Cmd) *osexec.Cmd {
cmd.Err = maskErrDot(cmd.Err)
return cmd
}
func maskErrDot(err error) error {
if err != nil && errors.Is(err, osexec.ErrDot) {
return nil
}
return err
}

View File

@@ -0,0 +1,27 @@
Copyright (c) 2012 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

View File

@@ -0,0 +1,133 @@
/*
Copyright 2013 Google Inc.
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 lru implements an LRU cache.
package golang_lru
import "container/list"
// Cache is an LRU cache. It is not safe for concurrent access.
type Cache struct {
// MaxEntries is the maximum number of cache entries before
// an item is evicted. Zero means no limit.
MaxEntries int
// OnEvicted optionally specifies a callback function to be
// executed when an entry is purged from the cache.
OnEvicted func(key Key, value interface{})
ll *list.List
cache map[interface{}]*list.Element
}
// A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators
type Key interface{}
type entry struct {
key Key
value interface{}
}
// New creates a new Cache.
// If maxEntries is zero, the cache has no limit and it's assumed
// that eviction is done by the caller.
func New(maxEntries int) *Cache {
return &Cache{
MaxEntries: maxEntries,
ll: list.New(),
cache: make(map[interface{}]*list.Element),
}
}
// Add adds a value to the cache.
func (c *Cache) Add(key Key, value interface{}) {
if c.cache == nil {
c.cache = make(map[interface{}]*list.Element)
c.ll = list.New()
}
if ee, ok := c.cache[key]; ok {
c.ll.MoveToFront(ee)
ee.Value.(*entry).value = value
return
}
ele := c.ll.PushFront(&entry{key, value})
c.cache[key] = ele
if c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries {
c.RemoveOldest()
}
}
// Get looks up a key's value from the cache.
func (c *Cache) Get(key Key) (value interface{}, ok bool) {
if c.cache == nil {
return
}
if ele, hit := c.cache[key]; hit {
c.ll.MoveToFront(ele)
return ele.Value.(*entry).value, true
}
return
}
// Remove removes the provided key from the cache.
func (c *Cache) Remove(key Key) {
if c.cache == nil {
return
}
if ele, hit := c.cache[key]; hit {
c.removeElement(ele)
}
}
// RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() {
if c.cache == nil {
return
}
ele := c.ll.Back()
if ele != nil {
c.removeElement(ele)
}
}
func (c *Cache) removeElement(e *list.Element) {
c.ll.Remove(e)
kv := e.Value.(*entry)
delete(c.cache, kv.key)
if c.OnEvicted != nil {
c.OnEvicted(kv.key, kv.value)
}
}
// Len returns the number of items in the cache.
func (c *Cache) Len() int {
if c.cache == nil {
return 0
}
return c.ll.Len()
}
// Clear purges all stored items from the cache.
func (c *Cache) Clear() {
if c.OnEvicted != nil {
for _, e := range c.cache {
kv := e.Value.(*entry)
c.OnEvicted(kv.key, kv.value)
}
}
c.ll = nil
c.cache = nil
}

View File

@@ -0,0 +1,236 @@
// Copyright 2009 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.
// IP address manipulations
//
// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
// An IPv4 address can be converted to an IPv6 address by
// adding a canonical prefix (10 zeros, 2 0xFFs).
// This library accepts either size of byte slice but always
// returns 16-byte addresses.
package net
///////////////////////////////////////////////////////////////////////////////
// NOTE: This file was forked because we need to maintain backwards-compatible
// IP parsing logic, which was changed in a correct but incompatible way in
// go-1.17.
//
// See https://issue.k8s.io/100895
///////////////////////////////////////////////////////////////////////////////
import (
stdnet "net"
)
//
// Lean on the standard net lib as much as possible.
//
type IP = stdnet.IP
type IPNet = stdnet.IPNet
type ParseError = stdnet.ParseError
const IPv4len = stdnet.IPv4len
const IPv6len = stdnet.IPv6len
var CIDRMask = stdnet.CIDRMask
var IPv4 = stdnet.IPv4
// Parse IPv4 address (d.d.d.d).
func parseIPv4(s string) IP {
var p [IPv4len]byte
for i := 0; i < IPv4len; i++ {
if len(s) == 0 {
// Missing octets.
return nil
}
if i > 0 {
if s[0] != '.' {
return nil
}
s = s[1:]
}
n, c, ok := dtoi(s)
if !ok || n > 0xFF {
return nil
}
//
// NOTE: This correct check was added for go-1.17, but is a
// backwards-incompatible change for kubernetes users, who might have
// stored data which uses these leading zeroes already.
//
// See https://issue.k8s.io/100895
//
//if c > 1 && s[0] == '0' {
// // Reject non-zero components with leading zeroes.
// return nil
//}
s = s[c:]
p[i] = byte(n)
}
if len(s) != 0 {
return nil
}
return IPv4(p[0], p[1], p[2], p[3])
}
// parseIPv6 parses s as a literal IPv6 address described in RFC 4291
// and RFC 5952.
func parseIPv6(s string) (ip IP) {
ip = make(IP, IPv6len)
ellipsis := -1 // position of ellipsis in ip
// Might have leading ellipsis
if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
ellipsis = 0
s = s[2:]
// Might be only ellipsis
if len(s) == 0 {
return ip
}
}
// Loop, parsing hex numbers followed by colon.
i := 0
for i < IPv6len {
// Hex number.
n, c, ok := xtoi(s)
if !ok || n > 0xFFFF {
return nil
}
// If followed by dot, might be in trailing IPv4.
if c < len(s) && s[c] == '.' {
if ellipsis < 0 && i != IPv6len-IPv4len {
// Not the right place.
return nil
}
if i+IPv4len > IPv6len {
// Not enough room.
return nil
}
ip4 := parseIPv4(s)
if ip4 == nil {
return nil
}
ip[i] = ip4[12]
ip[i+1] = ip4[13]
ip[i+2] = ip4[14]
ip[i+3] = ip4[15]
s = ""
i += IPv4len
break
}
// Save this 16-bit chunk.
ip[i] = byte(n >> 8)
ip[i+1] = byte(n)
i += 2
// Stop at end of string.
s = s[c:]
if len(s) == 0 {
break
}
// Otherwise must be followed by colon and more.
if s[0] != ':' || len(s) == 1 {
return nil
}
s = s[1:]
// Look for ellipsis.
if s[0] == ':' {
if ellipsis >= 0 { // already have one
return nil
}
ellipsis = i
s = s[1:]
if len(s) == 0 { // can be at end
break
}
}
}
// Must have used entire string.
if len(s) != 0 {
return nil
}
// If didn't parse enough, expand ellipsis.
if i < IPv6len {
if ellipsis < 0 {
return nil
}
n := IPv6len - i
for j := i - 1; j >= ellipsis; j-- {
ip[j+n] = ip[j]
}
for j := ellipsis + n - 1; j >= ellipsis; j-- {
ip[j] = 0
}
} else if ellipsis >= 0 {
// Ellipsis must represent at least one 0 group.
return nil
}
return ip
}
// ParseIP parses s as an IP address, returning the result.
// The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6
// ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form.
// If s is not a valid textual representation of an IP address,
// ParseIP returns nil.
func ParseIP(s string) IP {
for i := 0; i < len(s); i++ {
switch s[i] {
case '.':
return parseIPv4(s)
case ':':
return parseIPv6(s)
}
}
return nil
}
// ParseCIDR parses s as a CIDR notation IP address and prefix length,
// like "192.0.2.0/24" or "2001:db8::/32", as defined in
// RFC 4632 and RFC 4291.
//
// It returns the IP address and the network implied by the IP and
// prefix length.
// For example, ParseCIDR("192.0.2.1/24") returns the IP address
// 192.0.2.1 and the network 192.0.2.0/24.
func ParseCIDR(s string) (IP, *IPNet, error) {
i := indexByteString(s, '/')
if i < 0 {
return nil, nil, &ParseError{Type: "CIDR address", Text: s}
}
addr, mask := s[:i], s[i+1:]
iplen := IPv4len
ip := parseIPv4(addr)
if ip == nil {
iplen = IPv6len
ip = parseIPv6(addr)
}
n, i, ok := dtoi(mask)
if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
return nil, nil, &ParseError{Type: "CIDR address", Text: s}
}
m := CIDRMask(n, 8*iplen)
return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
}
// This is copied from go/src/internal/bytealg, which includes versions
// optimized for various platforms. Those optimizations are elided here so we
// don't have to maintain them.
func indexByteString(s string, c byte) int {
for i := 0; i < len(s); i++ {
if s[i] == c {
return i
}
}
return -1
}

View File

@@ -0,0 +1,59 @@
// Copyright 2009 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.
// Simple file i/o and string manipulation, to avoid
// depending on strconv and bufio and strings.
package net
///////////////////////////////////////////////////////////////////////////////
// NOTE: This file was forked because it is used by other code that needed to
// be forked, not because it is used on its own.
///////////////////////////////////////////////////////////////////////////////
// Bigger than we need, not too big to worry about overflow
const big = 0xFFFFFF
// Decimal to integer.
// Returns number, characters consumed, success.
func dtoi(s string) (n int, i int, ok bool) {
n = 0
for i = 0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
n = n*10 + int(s[i]-'0')
if n >= big {
return big, i, false
}
}
if i == 0 {
return 0, 0, false
}
return n, i, true
}
// Hexadecimal to integer.
// Returns number, characters consumed, success.
func xtoi(s string) (n int, i int, ok bool) {
n = 0
for i = 0; i < len(s); i++ {
if '0' <= s[i] && s[i] <= '9' {
n *= 16
n += int(s[i] - '0')
} else if 'a' <= s[i] && s[i] <= 'f' {
n *= 16
n += int(s[i]-'a') + 10
} else if 'A' <= s[i] && s[i] <= 'F' {
n *= 16
n += int(s[i]-'A') + 10
} else {
break
}
if n >= big {
return 0, i, false
}
}
if i == 0 {
return 0, i, false
}
return n, i, true
}

79
vendor/k8s.io/utils/lru/lru.go generated vendored Normal file
View File

@@ -0,0 +1,79 @@
/*
Copyright 2021 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 lru
import (
"sync"
groupcache "k8s.io/utils/internal/third_party/forked/golang/golang-lru"
)
type Key = groupcache.Key
// Cache is a thread-safe fixed size LRU cache.
type Cache struct {
cache *groupcache.Cache
lock sync.RWMutex
}
// New creates an LRU of the given size.
func New(size int) *Cache {
return &Cache{
cache: groupcache.New(size),
}
}
// Add adds a value to the cache.
func (c *Cache) Add(key Key, value interface{}) {
c.lock.Lock()
defer c.lock.Unlock()
c.cache.Add(key, value)
}
// Get looks up a key's value from the cache.
func (c *Cache) Get(key Key) (value interface{}, ok bool) {
c.lock.Lock()
defer c.lock.Unlock()
return c.cache.Get(key)
}
// Remove removes the provided key from the cache.
func (c *Cache) Remove(key Key) {
c.lock.Lock()
defer c.lock.Unlock()
c.cache.Remove(key)
}
// RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() {
c.lock.Lock()
defer c.lock.Unlock()
c.cache.RemoveOldest()
}
// Len returns the number of items in the cache.
func (c *Cache) Len() int {
c.lock.RLock()
defer c.lock.RUnlock()
return c.cache.Len()
}
// Clear purges all stored items from the cache.
func (c *Cache) Clear() {
c.lock.Lock()
defer c.lock.Unlock()
c.cache.Clear()
}

4
vendor/k8s.io/utils/net/ipnet.go generated vendored
View File

@@ -30,7 +30,7 @@ func ParseIPNets(specs ...string) (IPNetSet, error) {
ipnetset := make(IPNetSet)
for _, spec := range specs {
spec = strings.TrimSpace(spec)
_, ipnet, err := net.ParseCIDR(spec)
_, ipnet, err := ParseCIDRSloppy(spec)
if err != nil {
return nil, err
}
@@ -128,7 +128,7 @@ type IPSet map[string]net.IP
func ParseIPSet(items ...string) (IPSet, error) {
ipset := make(IPSet)
for _, item := range items {
ip := net.ParseIP(strings.TrimSpace(item))
ip := ParseIPSloppy(strings.TrimSpace(item))
if ip == nil {
return nil, fmt.Errorf("error parsing IP %q", item)
}

32
vendor/k8s.io/utils/net/net.go generated vendored
View File

@@ -30,7 +30,7 @@ import (
func ParseCIDRs(cidrsString []string) ([]*net.IPNet, error) {
cidrs := make([]*net.IPNet, 0, len(cidrsString))
for _, cidrString := range cidrsString {
_, cidr, err := net.ParseCIDR(cidrString)
_, cidr, err := ParseCIDRSloppy(cidrString)
if err != nil {
return nil, fmt.Errorf("failed to parse cidr value:%q with error:%v", cidrString, err)
}
@@ -71,7 +71,7 @@ func IsDualStackIPs(ips []net.IP) (bool, error) {
func IsDualStackIPStrings(ips []string) (bool, error) {
parsedIPs := make([]net.IP, 0, len(ips))
for _, ip := range ips {
parsedIP := net.ParseIP(ip)
parsedIP := ParseIPSloppy(ip)
parsedIPs = append(parsedIPs, parsedIP)
}
return IsDualStackIPs(parsedIPs)
@@ -120,14 +120,14 @@ func IsIPv6(netIP net.IP) bool {
// IsIPv6String returns if ip is IPv6.
func IsIPv6String(ip string) bool {
netIP := net.ParseIP(ip)
netIP := ParseIPSloppy(ip)
return IsIPv6(netIP)
}
// IsIPv6CIDRString returns if cidr is IPv6.
// This assumes cidr is a valid CIDR.
func IsIPv6CIDRString(cidr string) bool {
ip, _, _ := net.ParseCIDR(cidr)
ip, _, _ := ParseCIDRSloppy(cidr)
return IsIPv6(ip)
}
@@ -137,6 +137,30 @@ func IsIPv6CIDR(cidr *net.IPNet) bool {
return IsIPv6(ip)
}
// IsIPv4 returns if netIP is IPv4.
func IsIPv4(netIP net.IP) bool {
return netIP != nil && netIP.To4() != nil
}
// IsIPv4String returns if ip is IPv4.
func IsIPv4String(ip string) bool {
netIP := ParseIPSloppy(ip)
return IsIPv4(netIP)
}
// IsIPv4CIDR returns if a cidr is ipv4
func IsIPv4CIDR(cidr *net.IPNet) bool {
ip := cidr.IP
return IsIPv4(ip)
}
// IsIPv4CIDRString returns if cidr is IPv4.
// This assumes cidr is a valid CIDR.
func IsIPv4CIDRString(cidr string) bool {
ip, _, _ := ParseCIDRSloppy(cidr)
return IsIPv4(ip)
}
// ParsePort parses a string representing an IP port. If the string is not a
// valid port number, this returns an error.
func ParsePort(port string, allowZero bool) (int, error) {

33
vendor/k8s.io/utils/net/parse.go generated vendored Normal file
View File

@@ -0,0 +1,33 @@
/*
Copyright 2021 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 net
import (
forkednet "k8s.io/utils/internal/third_party/forked/golang/net"
)
// ParseIPSloppy is identical to Go's standard net.ParseIP, except that it allows
// leading '0' characters on numbers. Go used to allow this and then changed
// the behavior in 1.17. We're choosing to keep it for compat with potential
// stored values.
var ParseIPSloppy = forkednet.ParseIP
// ParseCIDRSloppy is identical to Go's standard net.ParseCIDR, except that it allows
// leading '0' characters on numbers. Go used to allow this and then changed
// the behavior in 1.17. We're choosing to keep it for compat with potential
// stored values.
var ParseCIDRSloppy = forkednet.ParseCIDR

2
vendor/k8s.io/utils/net/port.go generated vendored
View File

@@ -71,7 +71,7 @@ func NewLocalPort(desc, ip string, ipFamily IPFamily, port int, protocol Protoco
return nil, fmt.Errorf("Invalid IP family %s", ipFamily)
}
if ip != "" {
parsedIP := net.ParseIP(ip)
parsedIP := ParseIPSloppy(ip)
if parsedIP == nil {
return nil, fmt.Errorf("invalid ip address %s", ip)
}

View File

@@ -19,6 +19,7 @@ package pointer
import (
"fmt"
"reflect"
"time"
)
// AllPtrFieldsNil tests whether all pointer fields in a struct are nil. This is useful when,
@@ -46,41 +47,254 @@ func AllPtrFieldsNil(obj interface{}) bool {
return true
}
// Int32Ptr returns a pointer to an int32
func Int32Ptr(i int32) *int32 {
// Int returns a pointer to an int
func Int(i int) *int {
return &i
}
// Int64Ptr returns a pointer to an int64
func Int64Ptr(i int64) *int64 {
return &i
}
// IntPtr is a function variable referring to Int.
// Deprecated: Use Int instead.
var IntPtr = Int // for back-compat
// Int32PtrDerefOr dereference the int32 ptr and returns it if not nil,
// else returns def.
func Int32PtrDerefOr(ptr *int32, def int32) int32 {
// IntDeref dereferences the int ptr and returns it if not nil, or else
// returns def.
func IntDeref(ptr *int, def int) int {
if ptr != nil {
return *ptr
}
return def
}
// BoolPtr returns a pointer to a bool
func BoolPtr(b bool) *bool {
// IntPtrDerefOr is a function variable referring to IntDeref.
// Deprecated: Use IntDeref instead.
var IntPtrDerefOr = IntDeref // for back-compat
// Int32 returns a pointer to an int32.
func Int32(i int32) *int32 {
return &i
}
// Int32Ptr is a function variable referring to Int32.
// Deprecated: Use Int32 instead.
var Int32Ptr = Int32 // for back-compat
// Int32Deref dereferences the int32 ptr and returns it if not nil, or else
// returns def.
func Int32Deref(ptr *int32, def int32) int32 {
if ptr != nil {
return *ptr
}
return def
}
// Int32PtrDerefOr is a function variable referring to Int32Deref.
// Deprecated: Use Int32Deref instead.
var Int32PtrDerefOr = Int32Deref // for back-compat
// Int32Equal returns true if both arguments are nil or both arguments
// dereference to the same value.
func Int32Equal(a, b *int32) bool {
if (a == nil) != (b == nil) {
return false
}
if a == nil {
return true
}
return *a == *b
}
// Int64 returns a pointer to an int64.
func Int64(i int64) *int64 {
return &i
}
// Int64Ptr is a function variable referring to Int64.
// Deprecated: Use Int64 instead.
var Int64Ptr = Int64 // for back-compat
// Int64Deref dereferences the int64 ptr and returns it if not nil, or else
// returns def.
func Int64Deref(ptr *int64, def int64) int64 {
if ptr != nil {
return *ptr
}
return def
}
// Int64PtrDerefOr is a function variable referring to Int64Deref.
// Deprecated: Use Int64Deref instead.
var Int64PtrDerefOr = Int64Deref // for back-compat
// Int64Equal returns true if both arguments are nil or both arguments
// dereference to the same value.
func Int64Equal(a, b *int64) bool {
if (a == nil) != (b == nil) {
return false
}
if a == nil {
return true
}
return *a == *b
}
// Bool returns a pointer to a bool.
func Bool(b bool) *bool {
return &b
}
// StringPtr returns a pointer to the passed string.
func StringPtr(s string) *string {
// BoolPtr is a function variable referring to Bool.
// Deprecated: Use Bool instead.
var BoolPtr = Bool // for back-compat
// BoolDeref dereferences the bool ptr and returns it if not nil, or else
// returns def.
func BoolDeref(ptr *bool, def bool) bool {
if ptr != nil {
return *ptr
}
return def
}
// BoolPtrDerefOr is a function variable referring to BoolDeref.
// Deprecated: Use BoolDeref instead.
var BoolPtrDerefOr = BoolDeref // for back-compat
// BoolEqual returns true if both arguments are nil or both arguments
// dereference to the same value.
func BoolEqual(a, b *bool) bool {
if (a == nil) != (b == nil) {
return false
}
if a == nil {
return true
}
return *a == *b
}
// String returns a pointer to a string.
func String(s string) *string {
return &s
}
// Float32Ptr returns a pointer to the passed float32.
func Float32Ptr(i float32) *float32 {
// StringPtr is a function variable referring to String.
// Deprecated: Use String instead.
var StringPtr = String // for back-compat
// StringDeref dereferences the string ptr and returns it if not nil, or else
// returns def.
func StringDeref(ptr *string, def string) string {
if ptr != nil {
return *ptr
}
return def
}
// StringPtrDerefOr is a function variable referring to StringDeref.
// Deprecated: Use StringDeref instead.
var StringPtrDerefOr = StringDeref // for back-compat
// StringEqual returns true if both arguments are nil or both arguments
// dereference to the same value.
func StringEqual(a, b *string) bool {
if (a == nil) != (b == nil) {
return false
}
if a == nil {
return true
}
return *a == *b
}
// Float32 returns a pointer to a float32.
func Float32(i float32) *float32 {
return &i
}
// Float64Ptr returns a pointer to the passed float64.
func Float64Ptr(i float64) *float64 {
// Float32Ptr is a function variable referring to Float32.
// Deprecated: Use Float32 instead.
var Float32Ptr = Float32
// Float32Deref dereferences the float32 ptr and returns it if not nil, or else
// returns def.
func Float32Deref(ptr *float32, def float32) float32 {
if ptr != nil {
return *ptr
}
return def
}
// Float32PtrDerefOr is a function variable referring to Float32Deref.
// Deprecated: Use Float32Deref instead.
var Float32PtrDerefOr = Float32Deref // for back-compat
// Float32Equal returns true if both arguments are nil or both arguments
// dereference to the same value.
func Float32Equal(a, b *float32) bool {
if (a == nil) != (b == nil) {
return false
}
if a == nil {
return true
}
return *a == *b
}
// Float64 returns a pointer to a float64.
func Float64(i float64) *float64 {
return &i
}
// Float64Ptr is a function variable referring to Float64.
// Deprecated: Use Float64 instead.
var Float64Ptr = Float64
// Float64Deref dereferences the float64 ptr and returns it if not nil, or else
// returns def.
func Float64Deref(ptr *float64, def float64) float64 {
if ptr != nil {
return *ptr
}
return def
}
// Float64PtrDerefOr is a function variable referring to Float64Deref.
// Deprecated: Use Float64Deref instead.
var Float64PtrDerefOr = Float64Deref // for back-compat
// Float64Equal returns true if both arguments are nil or both arguments
// dereference to the same value.
func Float64Equal(a, b *float64) bool {
if (a == nil) != (b == nil) {
return false
}
if a == nil {
return true
}
return *a == *b
}
// Duration returns a pointer to a time.Duration.
func Duration(d time.Duration) *time.Duration {
return &d
}
// DurationDeref dereferences the time.Duration ptr and returns it if not nil, or else
// returns def.
func DurationDeref(ptr *time.Duration, def time.Duration) time.Duration {
if ptr != nil {
return *ptr
}
return def
}
// DurationEqual returns true if both arguments are nil or both arguments
// dereference to the same value.
func DurationEqual(a, b *time.Duration) bool {
if (a == nil) != (b == nil) {
return false
}
if a == nil {
return true
}
return *a == *b
}

82
vendor/k8s.io/utils/strings/slices/slices.go generated vendored Normal file
View File

@@ -0,0 +1,82 @@
/*
Copyright 2021 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 slices defines various functions useful with slices of string type.
// The goal is to be as close as possible to
// https://github.com/golang/go/issues/45955. Ideal would be if we can just
// replace "stringslices" if the "slices" package becomes standard.
package slices
// Equal reports whether two slices are equal: the same length and all
// elements equal. If the lengths are different, Equal returns false.
// Otherwise, the elements are compared in index order, and the
// comparison stops at the first unequal pair.
func Equal(s1, s2 []string) bool {
if len(s1) != len(s2) {
return false
}
for i, n := range s1 {
if n != s2[i] {
return false
}
}
return true
}
// Filter appends to d each element e of s for which keep(e) returns true.
// It returns the modified d. d may be s[:0], in which case the kept
// elements will be stored in the same slice.
// if the slices overlap in some other way, the results are unspecified.
// To create a new slice with the filtered results, pass nil for d.
func Filter(d, s []string, keep func(string) bool) []string {
for _, n := range s {
if keep(n) {
d = append(d, n)
}
}
return d
}
// Contains reports whether v is present in s.
func Contains(s []string, v string) bool {
return Index(s, v) >= 0
}
// Index returns the index of the first occurrence of v in s, or -1 if
// not present.
func Index(s []string, v string) int {
// "Contains" may be replaced with "Index(s, v) >= 0":
// https://github.com/golang/go/issues/45955#issuecomment-873377947
for i, n := range s {
if n == v {
return i
}
}
return -1
}
// Functions below are not in https://github.com/golang/go/issues/45955
// Clone returns a new clone of s.
func Clone(s []string) []string {
// https://github.com/go101/go101/wiki/There-is-not-a-perfect-way-to-clone-slices-in-Go
if s == nil {
return nil
}
c := make([]string, len(s))
copy(c, s)
return c
}

24
vendor/k8s.io/utils/trace/trace.go generated vendored
View File

@@ -26,6 +26,10 @@ import (
"k8s.io/klog/v2"
)
var klogV = func(lvl klog.Level) bool {
return klog.V(lvl).Enabled()
}
// Field is a key value pair that provides additional details about the trace.
type Field struct {
Key string
@@ -52,7 +56,7 @@ func writeTraceItemSummary(b *bytes.Buffer, msg string, totalTime time.Duration,
b.WriteString(" ")
}
b.WriteString(fmt.Sprintf("%vms (%v)", durationToMilliseconds(totalTime), startTime.Format("15:04:00.000")))
b.WriteString(fmt.Sprintf("%vms (%v)", durationToMilliseconds(totalTime), startTime.Format("15:04:05.000")))
}
func durationToMilliseconds(timeDuration time.Duration) int64 {
@@ -80,7 +84,7 @@ func (s traceStep) time() time.Time {
func (s traceStep) writeItem(b *bytes.Buffer, formatter string, startTime time.Time, stepThreshold *time.Duration) {
stepDuration := s.stepTime.Sub(startTime)
if stepThreshold == nil || *stepThreshold == 0 || stepDuration >= *stepThreshold {
if stepThreshold == nil || *stepThreshold == 0 || stepDuration >= *stepThreshold || klogV(4) {
b.WriteString(fmt.Sprintf("%s---", formatter))
writeTraceItemSummary(b, s.msg, stepDuration, s.stepTime, s.fields)
}
@@ -106,7 +110,7 @@ func (t *Trace) time() time.Time {
}
func (t *Trace) writeItem(b *bytes.Buffer, formatter string, startTime time.Time, stepThreshold *time.Duration) {
if t.durationIsWithinThreshold() {
if t.durationIsWithinThreshold() || klogV(4) {
b.WriteString(fmt.Sprintf("%v[", formatter))
writeTraceItemSummary(b, t.name, t.TotalTime(), t.startTime, t.fields)
if st := t.calculateStepThreshold(); st != nil {
@@ -168,13 +172,13 @@ func (t *Trace) Log() {
// LogIfLong only logs the trace if the duration of the trace exceeds the threshold.
// Only steps that took longer than their share or the given threshold are logged.
// If klog is at verbosity level 4 or higher, the trace and its steps are logged regardless of threshold.
// If the Trace is nested it is not immediately logged. Instead, it is logged when the trace it is nested within
// is logged.
// If klog is at verbosity level 4 or higher and the trace took longer than the threshold,
// all substeps and subtraces are logged. Otherwise, only those which took longer than
// their own threshold.
// If the Trace is nested it is not immediately logged. Instead, it is logged when the trace it
// is nested within is logged.
func (t *Trace) LogIfLong(threshold time.Duration) {
if !klog.V(4).Enabled() { // don't set threshold if verbosity is level 4 of higher
t.threshold = &threshold
}
t.threshold = &threshold
t.Log()
}
@@ -193,7 +197,7 @@ func (t *Trace) logTrace() {
}
// if any step took more than it's share of the total allowed time, it deserves a higher log level
buffer.WriteString(fmt.Sprintf("(%v) (total time: %vms):", t.startTime.Format("02-Jan-2006 15:04:00.000"), totalTime.Milliseconds()))
buffer.WriteString(fmt.Sprintf("(%v) (total time: %vms):", t.startTime.Format("02-Jan-2006 15:04:05.000"), totalTime.Milliseconds()))
stepThreshold := t.calculateStepThreshold()
t.writeTraceSteps(&buffer, fmt.Sprintf("\nTrace[%d]: ", traceNum), stepThreshold)
buffer.WriteString(fmt.Sprintf("\nTrace[%d]: [%v] [%v] END\n", traceNum, t.endTime.Sub(t.startTime), totalTime))