Update dependency go modules for k8s v1.28.0

This commit is contained in:
Sneha Aradhey
2023-09-07 17:13:57 +00:00
parent c0955f135d
commit 3ede1a413f
309 changed files with 35415 additions and 8605 deletions

View File

@@ -2,7 +2,6 @@
reviewers:
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- deads2k

View File

@@ -112,8 +112,27 @@ func getItemsPtr(list runtime.Object) (interface{}, error) {
// EachListItem invokes fn on each runtime.Object in the list. Any error immediately terminates
// the loop.
//
// If items passed to fn are retained for different durations, and you want to avoid
// retaining all items in obj as long as any item is referenced, use EachListItemWithAlloc instead.
func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error {
return eachListItem(obj, fn, false)
}
// EachListItemWithAlloc works like EachListItem, but avoids retaining references to the items slice in obj.
// It does this by making a shallow copy of non-pointer items in obj.
//
// If the items passed to fn are not retained, or are retained for the same duration, use EachListItem instead for memory efficiency.
func EachListItemWithAlloc(obj runtime.Object, fn func(runtime.Object) error) error {
return eachListItem(obj, fn, true)
}
// allocNew: Whether shallow copy is required when the elements in Object.Items are struct
func eachListItem(obj runtime.Object, fn func(runtime.Object) error, allocNew bool) error {
if unstructured, ok := obj.(runtime.Unstructured); ok {
if allocNew {
return unstructured.EachListItemWithAlloc(fn)
}
return unstructured.EachListItem(fn)
}
// TODO: Change to an interface call?
@@ -140,8 +159,19 @@ func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error {
for i := 0; i < len; i++ {
raw := items.Index(i)
if takeAddr {
raw = raw.Addr()
if allocNew {
// shallow copy to avoid retaining a reference to the original list item
itemCopy := reflect.New(raw.Type())
// assign to itemCopy and type-assert
itemCopy.Elem().Set(raw)
// reflect.New will guarantee that itemCopy must be a pointer.
raw = itemCopy
} else {
raw = raw.Addr()
}
}
// raw must be a pointer or an interface
// allocate a pointer is cheap
switch item := raw.Interface().(type) {
case *runtime.RawExtension:
if err := fn(item.Object); err != nil {
@@ -166,7 +196,23 @@ func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error {
// ExtractList returns obj's Items element as an array of runtime.Objects.
// Returns an error if obj is not a List type (does not have an Items member).
//
// If items in the returned list are retained for different durations, and you want to avoid
// retaining all items in obj as long as any item is referenced, use ExtractListWithAlloc instead.
func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
return extractList(obj, false)
}
// ExtractListWithAlloc works like ExtractList, but avoids retaining references to the items slice in obj.
// It does this by making a shallow copy of non-pointer items in obj.
//
// If the items in the returned list are not retained, or are retained for the same duration, use ExtractList instead for memory efficiency.
func ExtractListWithAlloc(obj runtime.Object) ([]runtime.Object, error) {
return extractList(obj, true)
}
// allocNew: Whether shallow copy is required when the elements in Object.Items are struct
func extractList(obj runtime.Object, allocNew bool) ([]runtime.Object, error) {
itemsPtr, err := GetItemsPtr(obj)
if err != nil {
return nil, err
@@ -176,10 +222,17 @@ func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
return nil, err
}
list := make([]runtime.Object, items.Len())
if len(list) == 0 {
return list, nil
}
elemType := items.Type().Elem()
isRawExtension := elemType == rawExtensionObjectType
implementsObject := elemType.Implements(objectType)
for i := range list {
raw := items.Index(i)
switch item := raw.Interface().(type) {
case runtime.RawExtension:
switch {
case isRawExtension:
item := raw.Interface().(runtime.RawExtension)
switch {
case item.Object != nil:
list[i] = item.Object
@@ -189,8 +242,18 @@ func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
default:
list[i] = nil
}
case runtime.Object:
list[i] = item
case implementsObject:
list[i] = raw.Interface().(runtime.Object)
case allocNew:
// shallow copy to avoid retaining a reference to the original list item
itemCopy := reflect.New(raw.Type())
// assign to itemCopy and type-assert
itemCopy.Elem().Set(raw)
var ok bool
// reflect.New will guarantee that itemCopy must be a pointer.
if list[i], ok = itemCopy.Interface().(runtime.Object); !ok {
return nil, fmt.Errorf("%v: item[%v]: Expected object, got %#v(%s)", obj, i, raw.Interface(), raw.Kind())
}
default:
var found bool
if list[i], found = raw.Addr().Interface().(runtime.Object); !found {
@@ -201,8 +264,12 @@ func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
return list, nil
}
// objectSliceType is the type of a slice of Objects
var objectSliceType = reflect.TypeOf([]runtime.Object{})
var (
// objectSliceType is the type of a slice of Objects
objectSliceType = reflect.TypeOf([]runtime.Object{})
objectType = reflect.TypeOf((*runtime.Object)(nil)).Elem()
rawExtensionObjectType = reflect.TypeOf(runtime.RawExtension{})
)
// LenList returns the length of this list or 0 if it is not a list.
func LenList(list runtime.Object) int {
@@ -237,7 +304,7 @@ func SetList(list runtime.Object, objects []runtime.Object) error {
slice := reflect.MakeSlice(items.Type(), len(objects), len(objects))
for i := range objects {
dest := slice.Index(i)
if dest.Type() == reflect.TypeOf(runtime.RawExtension{}) {
if dest.Type() == rawExtensionObjectType {
dest = dest.FieldByName("Object")
}

View File

@@ -2,7 +2,6 @@
reviewers:
- thockin
- lavalamp
- smarterclayton
- wojtek-t
- derekwaynecarr

View File

@@ -425,8 +425,6 @@ message LabelSelector {
// relates the key and values.
message LabelSelectorRequirement {
// key is the label key that the selector applies to.
// +patchMergeKey=key
// +patchStrategy=merge
optional string key = 1;
// operator represents a key's relationship to a set of values.

View File

@@ -995,6 +995,24 @@ const (
// CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules)
// values that can not be handled (e.g. an enumerated string).
CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported"
// CauseTypeForbidden is used to report valid (as per formatting rules)
// values which would be accepted under some conditions, but which are not
// permitted by the current conditions (such as security policy). See
// Forbidden().
CauseTypeForbidden CauseType = "FieldValueForbidden"
// CauseTypeTooLong is used to report that the given value is too long.
// This is similar to ErrorTypeInvalid, but the error will not include the
// too-long value. See TooLong().
CauseTypeTooLong CauseType = "FieldValueTooLong"
// CauseTypeTooMany is used to report "too many". This is used to
// report that a given list has too many items. This is similar to FieldValueTooLong,
// but the error indicates quantity instead of length.
CauseTypeTooMany CauseType = "FieldValueTooMany"
// CauseTypeInternal is used to report other errors that are not related
// to user input. See InternalError().
CauseTypeInternal CauseType = "InternalError"
// CauseTypeTypeInvalid is for the value did not match the schema type for that field
CauseTypeTypeInvalid CauseType = "FieldValueTypeInvalid"
// CauseTypeUnexpectedServerResponse is used to report when the server responded to the client
// without the expected return type. The presence of this cause indicates the error may be
// due to an intervening proxy or the server software malfunctioning.
@@ -1207,9 +1225,7 @@ type LabelSelector struct {
// relates the key and values.
type LabelSelectorRequirement struct {
// key is the label key that the selector applies to.
// +patchMergeKey=key
// +patchStrategy=merge
Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key"`
Key string `json:"key" protobuf:"bytes,1,opt,name=key"`
// operator represents a key's relationship to a set of values.
// Valid operators are In, NotIn, Exists and DoesNotExist.
Operator LabelSelectorOperator `json:"operator" protobuf:"bytes,2,opt,name=operator,casttype=LabelSelectorOperator"`

View File

@@ -101,6 +101,11 @@ func (obj *Unstructured) EachListItem(fn func(runtime.Object) error) error {
return nil
}
func (obj *Unstructured) EachListItemWithAlloc(fn func(runtime.Object) error) error {
// EachListItem has allocated a new Object for the user, we can use it directly.
return obj.EachListItem(fn)
}
func (obj *Unstructured) UnstructuredContent() map[string]interface{} {
if obj.Object == nil {
return make(map[string]interface{})

View File

@@ -52,6 +52,15 @@ func (u *UnstructuredList) EachListItem(fn func(runtime.Object) error) error {
return nil
}
func (u *UnstructuredList) EachListItemWithAlloc(fn func(runtime.Object) error) error {
for i := range u.Items {
if err := fn(&Unstructured{Object: u.Items[i].Object}); err != nil {
return err
}
}
return nil
}
// NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.
// This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info.
func (u *UnstructuredList) NewEmptyInstance() runtime.Unstructured {

View File

@@ -45,7 +45,6 @@ func NewCodec(e Encoder, d Decoder) Codec {
// Encode is a convenience wrapper for encoding to a []byte from an Encoder
func Encode(e Encoder, obj Object) ([]byte, error) {
// TODO: reuse buffer
buf := &bytes.Buffer{}
if err := e.Encode(obj, buf); err != nil {
return nil, err

View File

@@ -231,7 +231,7 @@ func (c *fromUnstructuredContext) pushKey(key string) {
}
// FromUnstructuredWIthValidation converts an object from map[string]interface{} representation into a concrete type.
// FromUnstructuredWithValidation converts an object from map[string]interface{} representation into a concrete type.
// It uses encoding/json/Unmarshaler if object implements it or reflection if not.
// It takes a validationDirective that indicates how to behave when it encounters unknown fields.
func (c *unstructuredConverter) FromUnstructuredWithValidation(u map[string]interface{}, obj interface{}, returnUnknownFields bool) error {
@@ -465,7 +465,7 @@ func sliceFromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) e
}
dv.SetBytes(data)
} else {
dv.Set(reflect.Zero(dt))
dv.Set(reflect.MakeSlice(dt, 0, 0))
}
return nil
}

View File

@@ -365,4 +365,9 @@ type Unstructured interface {
// error should terminate the iteration. If IsList() returns false, this method should return an error
// instead of calling the provided function.
EachListItem(func(Object) error) error
// EachListItemWithAlloc works like EachListItem, but avoids retaining references to a slice of items.
// It does this by making a shallow copy of non-pointer items before passing them to fn.
//
// If the items passed to fn are not retained, or are retained for the same duration, use EachListItem instead for memory efficiency.
EachListItemWithAlloc(func(Object) error) error
}

View File

@@ -39,7 +39,7 @@ func ParseResourceArg(arg string) (*GroupVersionResource, GroupResource) {
// ParseKindArg takes the common style of string which may be either `Kind.group.com` or `Kind.version.group.com`
// and parses it out into both possibilities. This code takes no responsibility for knowing which representation was intended
// but with a knowledge of all GroupKinds, calling code can take a very good guess. If there are only two segments, then
// `*GroupVersionResource` is nil.
// `*GroupVersionKind` is nil.
// `Kind.group.com` -> `group=com, version=group, kind=Kind` and `group=group.com, kind=Kind`
func ParseKindArg(arg string) (*GroupVersionKind, GroupKind) {
var gvk *GroupVersionKind

76
vendor/k8s.io/apimachinery/pkg/runtime/splice.go generated vendored Normal file
View File

@@ -0,0 +1,76 @@
/*
Copyright 2023 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 runtime
import (
"bytes"
"io"
)
// Splice is the interface that wraps the Splice method.
//
// Splice moves data from given slice without copying the underlying data for
// efficiency purpose. Therefore, the caller should make sure the underlying
// data is not changed later.
type Splice interface {
Splice([]byte)
io.Writer
Reset()
Bytes() []byte
}
// A spliceBuffer implements Splice and io.Writer interfaces.
type spliceBuffer struct {
raw []byte
buf *bytes.Buffer
}
func NewSpliceBuffer() Splice {
return &spliceBuffer{}
}
// Splice implements the Splice interface.
func (sb *spliceBuffer) Splice(raw []byte) {
sb.raw = raw
}
// Write implements the io.Writer interface.
func (sb *spliceBuffer) Write(p []byte) (n int, err error) {
if sb.buf == nil {
sb.buf = &bytes.Buffer{}
}
return sb.buf.Write(p)
}
// Reset resets the buffer to be empty.
func (sb *spliceBuffer) Reset() {
if sb.buf != nil {
sb.buf.Reset()
}
sb.raw = nil
}
// Bytes returns the data held by the buffer.
func (sb *spliceBuffer) Bytes() []byte {
if sb.buf != nil && len(sb.buf.Bytes()) > 0 {
return sb.buf.Bytes()
}
if sb.raw != nil {
return sb.raw
}
return []byte{}
}

View File

@@ -41,7 +41,8 @@ func (n NamespacedName) String() string {
// MarshalLog emits a struct containing required key/value pair
func (n NamespacedName) MarshalLog() interface{} {
return struct {
Name, Namespace string
Name string `json:"name"`
Namespace string `json:"namespace,omitempty"`
}{
Name: n.Name,
Namespace: n.Namespace,

View File

@@ -40,6 +40,13 @@ func NewExpiringWithClock(clock clock.Clock) *Expiring {
// Expiring is a map whose entries expire after a per-entry timeout.
type Expiring struct {
// AllowExpiredGet causes the expiration check to be skipped on Get.
// It should only be used when a key always corresponds to the exact same value.
// Thus when this field is true, expired keys are considered valid
// until the next call to Set (which causes the GC to run).
// It may not be changed concurrently with calls to Get.
AllowExpiredGet bool
clock clock.Clock
// mu protects the below fields
@@ -70,7 +77,10 @@ func (c *Expiring) Get(key interface{}) (val interface{}, ok bool) {
c.mu.RLock()
defer c.mu.RUnlock()
e, ok := c.cache[key]
if !ok || !c.clock.Now().Before(e.expiry) {
if !ok {
return nil, false
}
if !c.AllowExpiredGet && !c.clock.Now().Before(e.expiry) {
return nil, false
}
return e.val, true

View File

@@ -23,34 +23,20 @@ import (
"strings"
"text/tabwriter"
"github.com/davecgh/go-spew/spew"
"github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/util/dump"
)
// StringDiff diffs a and b and returns a human readable diff.
func StringDiff(a, b string) string {
ba := []byte(a)
bb := []byte(b)
out := []byte{}
i := 0
for ; i < len(ba) && i < len(bb); i++ {
if ba[i] != bb[i] {
break
}
out = append(out, ba[i])
}
out = append(out, []byte("\n\nA: ")...)
out = append(out, ba[i:]...)
out = append(out, []byte("\n\nB: ")...)
out = append(out, bb[i:]...)
out = append(out, []byte("\n\n")...)
return string(out)
}
func legacyDiff(a, b interface{}) string {
return cmp.Diff(a, b)
}
// StringDiff diffs a and b and returns a human readable diff.
// DEPRECATED: use github.com/google/go-cmp/cmp.Diff
func StringDiff(a, b string) string {
return legacyDiff(a, b)
}
// ObjectDiff prints the diff of two go objects and fails if the objects
// contain unhandled unexported fields.
// DEPRECATED: use github.com/google/go-cmp/cmp.Diff
@@ -75,13 +61,8 @@ func ObjectReflectDiff(a, b interface{}) string {
// ObjectGoPrintSideBySide prints a and b as textual dumps side by side,
// enabling easy visual scanning for mismatches.
func ObjectGoPrintSideBySide(a, b interface{}) string {
s := spew.ConfigState{
Indent: " ",
// Extra deep spew.
DisableMethods: true,
}
sA := s.Sdump(a)
sB := s.Sdump(b)
sA := dump.Pretty(a)
sB := dump.Pretty(b)
linesA := strings.Split(sA, "\n")
linesB := strings.Split(sB, "\n")

54
vendor/k8s.io/apimachinery/pkg/util/dump/dump.go generated vendored Normal file
View File

@@ -0,0 +1,54 @@
/*
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 dump
import (
"github.com/davecgh/go-spew/spew"
)
var prettyPrintConfig = &spew.ConfigState{
Indent: " ",
DisableMethods: true,
DisablePointerAddresses: true,
DisableCapacities: true,
}
// The config MUST NOT be changed because that could change the result of a hash operation
var prettyPrintConfigForHash = &spew.ConfigState{
Indent: " ",
SortKeys: true,
DisableMethods: true,
SpewKeys: true,
DisablePointerAddresses: true,
DisableCapacities: true,
}
// Pretty wrap the spew.Sdump with Indent, and disabled methods like error() and String()
// The output may change over time, so for guaranteed output please take more direct control
func Pretty(a interface{}) string {
return prettyPrintConfig.Sdump(a)
}
// ForHash keeps the original Spew.Sprintf format to ensure the same checksum
func ForHash(a interface{}) string {
return prettyPrintConfigForHash.Sprintf("%#v", a)
}
// OneLine outputs the object in one line
func OneLine(a interface{}) string {
return prettyPrintConfig.Sprintf("%#v", a)
}

View File

@@ -54,7 +54,7 @@ const (
// FromInt creates an IntOrString object with an int32 value. It is
// your responsibility not to call this method with a value greater
// than int32.
// TODO: convert to (val int32)
// Deprecated: use FromInt32 instead.
func FromInt(val int) IntOrString {
if val > math.MaxInt32 || val < math.MinInt32 {
klog.Errorf("value: %d overflows int32\n%s\n", val, debug.Stack())
@@ -62,6 +62,11 @@ func FromInt(val int) IntOrString {
return IntOrString{Type: Int, IntVal: int32(val)}
}
// FromInt32 creates an IntOrString object with an int32 value.
func FromInt32(val int32) IntOrString {
return IntOrString{Type: Int, IntVal: val}
}
// FromString creates an IntOrString object with a string value.
func FromString(val string) IntOrString {
return IntOrString{Type: String, StrVal: val}

View File

@@ -56,17 +56,20 @@ func NewFieldManager(f Manager, subresource string) *FieldManager {
// newDefaultFieldManager is a helper function which wraps a Manager with certain default logic.
func NewDefaultFieldManager(f Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, subresource string) *FieldManager {
return NewFieldManager(
NewLastAppliedUpdater(
NewLastAppliedManager(
NewProbabilisticSkipNonAppliedManager(
NewCapManagersManager(
NewBuildManagerInfoManager(
NewManagedFieldsUpdater(
NewStripMetaManager(f),
), kind.GroupVersion(), subresource,
), DefaultMaxUpdateManagers,
), objectCreater, kind, DefaultTrackOnCreateProbability,
), typeConverter, objectConverter, kind.GroupVersion()),
NewVersionCheckManager(
NewLastAppliedUpdater(
NewLastAppliedManager(
NewProbabilisticSkipNonAppliedManager(
NewCapManagersManager(
NewBuildManagerInfoManager(
NewManagedFieldsUpdater(
NewStripMetaManager(f),
), kind.GroupVersion(), subresource,
), DefaultMaxUpdateManagers,
), objectCreater, DefaultTrackOnCreateProbability,
), typeConverter, objectConverter, kind.GroupVersion(),
),
), kind,
), subresource,
)
}

View File

@@ -22,13 +22,11 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
type skipNonAppliedManager struct {
fieldManager Manager
objectCreater runtime.ObjectCreater
gvk schema.GroupVersionKind
beforeApplyManagerName string
probability float32
}
@@ -36,17 +34,16 @@ type skipNonAppliedManager struct {
var _ Manager = &skipNonAppliedManager{}
// NewSkipNonAppliedManager creates a new wrapped FieldManager that only starts tracking managers after the first apply.
func NewSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater, gvk schema.GroupVersionKind) Manager {
return NewProbabilisticSkipNonAppliedManager(fieldManager, objectCreater, gvk, 0.0)
func NewSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater) Manager {
return NewProbabilisticSkipNonAppliedManager(fieldManager, objectCreater, 0.0)
}
// NewProbabilisticSkipNonAppliedManager creates a new wrapped FieldManager that starts tracking managers after the first apply,
// or starts tracking on create with p probability.
func NewProbabilisticSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater, gvk schema.GroupVersionKind, p float32) Manager {
func NewProbabilisticSkipNonAppliedManager(fieldManager Manager, objectCreater runtime.ObjectCreater, p float32) Manager {
return &skipNonAppliedManager{
fieldManager: fieldManager,
objectCreater: objectCreater,
gvk: gvk,
beforeApplyManagerName: "before-first-apply",
probability: p,
}
@@ -78,9 +75,10 @@ func (f *skipNonAppliedManager) Update(liveObj, newObj runtime.Object, managed M
// Apply implements Manager.
func (f *skipNonAppliedManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) {
if len(managed.Fields()) == 0 {
emptyObj, err := f.objectCreater.New(f.gvk)
gvk := appliedObj.GetObjectKind().GroupVersionKind()
emptyObj, err := f.objectCreater.New(gvk)
if err != nil {
return nil, nil, fmt.Errorf("failed to create empty object of type %v: %v", f.gvk, err)
return nil, nil, fmt.Errorf("failed to create empty object of type %v: %v", gvk, err)
}
liveObj, managed, err = f.fieldManager.Update(emptyObj, liveObj, managed, f.beforeApplyManagerName)
if err != nil {

View File

@@ -41,6 +41,9 @@ var _ Manager = &structuredMergeManager{}
// NewStructuredMergeManager creates a new Manager that merges apply requests
// and update managed fields for other types of requests.
func NewStructuredMergeManager(typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectDefaulter runtime.ObjectDefaulter, gv schema.GroupVersion, hub schema.GroupVersion, resetFields map[fieldpath.APIVersion]*fieldpath.Set) (Manager, error) {
if typeConverter == nil {
return nil, fmt.Errorf("typeconverter must not be nil")
}
return &structuredMergeManager{
typeConverter: typeConverter,
objectConverter: objectConverter,

View File

@@ -0,0 +1,52 @@
/*
Copyright 2023 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 internal
import (
"fmt"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
type versionCheckManager struct {
fieldManager Manager
gvk schema.GroupVersionKind
}
var _ Manager = &versionCheckManager{}
// NewVersionCheckManager creates a manager that makes sure that the
// applied object is in the proper version.
func NewVersionCheckManager(fieldManager Manager, gvk schema.GroupVersionKind) Manager {
return &versionCheckManager{fieldManager: fieldManager, gvk: gvk}
}
// Update implements Manager.
func (f *versionCheckManager) Update(liveObj, newObj runtime.Object, managed Managed, manager string) (runtime.Object, Managed, error) {
// Nothing to do for updates, this is checked in many other places.
return f.fieldManager.Update(liveObj, newObj, managed, manager)
}
// Apply implements Manager.
func (f *versionCheckManager) Apply(liveObj, appliedObj runtime.Object, managed Managed, fieldManager string, force bool) (runtime.Object, Managed, error) {
if gvk := appliedObj.GetObjectKind().GroupVersionKind(); gvk != f.gvk {
return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid object type: %v", gvk))
}
return f.fieldManager.Apply(liveObj, appliedObj, managed, fieldManager, force)
}

View File

@@ -20,7 +20,7 @@ import (
"fmt"
"reflect"
"github.com/davecgh/go-spew/spew"
"k8s.io/apimachinery/pkg/util/dump"
"sigs.k8s.io/yaml"
)
@@ -76,7 +76,7 @@ func ToYAMLOrError(v interface{}) string {
func toYAML(v interface{}) (string, error) {
y, err := yaml.Marshal(v)
if err != nil {
return "", fmt.Errorf("yaml marshal failed:%v\n%v\n", err, spew.Sdump(v))
return "", fmt.Errorf("yaml marshal failed:%v\n%v\n", err, dump.Pretty(v))
}
return string(y), nil

View File

@@ -20,6 +20,7 @@ import (
"errors"
"net"
"reflect"
"strings"
"syscall"
)
@@ -47,6 +48,11 @@ func IsConnectionReset(err error) bool {
return false
}
// Returns if the given err is "http2: client connection lost" error.
func IsHTTP2ConnectionLost(err error) bool {
return err != nil && strings.Contains(err.Error(), "http2: client connection lost")
}
// Returns if the given err is "connection refused" error
func IsConnectionRefused(err error) bool {
var errno syscall.Errno

View File

@@ -1182,7 +1182,13 @@ func mergePatchIntoOriginal(original, patch map[string]interface{}, schema Looku
merged = originalFieldValue
case !foundOriginal && foundPatch:
// list was added
merged = patchFieldValue
v, keep := removeDirectives(patchFieldValue)
if !keep {
// Shouldn't be possible since patchFieldValue is a slice
continue
}
merged = v.([]interface{})
case foundOriginal && foundPatch:
merged, err = mergeSliceHandler(originalList, patchList, subschema,
patchStrategy, patchMeta.GetPatchMergeKey(), false, mergeOptions)
@@ -1270,6 +1276,42 @@ func partitionMapsByPresentInList(original, partitionBy []interface{}, mergeKey
return patch, serverOnly, nil
}
// Removes directives from an object and returns value to use instead and whether
// or not the field/index should even be kept
// May modify input
func removeDirectives(obj interface{}) (interface{}, bool) {
if obj == nil {
return obj, true
} else if typedV, ok := obj.(map[string]interface{}); ok {
if _, hasDirective := typedV[directiveMarker]; hasDirective {
return nil, false
}
for k, v := range typedV {
var keep bool
typedV[k], keep = removeDirectives(v)
if !keep {
delete(typedV, k)
}
}
return typedV, true
} else if typedV, ok := obj.([]interface{}); ok {
var res []interface{}
if typedV != nil {
// Make sure res is non-nil if patch is non-nil
res = []interface{}{}
}
for _, v := range typedV {
if newV, keep := removeDirectives(v); keep {
res = append(res, newV)
}
}
return res, true
} else {
return obj, true
}
}
// Merge fields from a patch map into the original map. Note: This may modify
// both the original map and the patch because getting a deep copy of a map in
// golang is highly non-trivial.
@@ -1333,7 +1375,10 @@ func mergeMap(original, patch map[string]interface{}, schema LookupPatchMeta, me
if mergeOptions.IgnoreUnmatchedNulls {
discardNullValuesFromPatch(patchV)
}
original[k] = patchV
original[k], ok = removeDirectives(patchV)
if !ok {
delete(original, k)
}
}
continue
}
@@ -1345,7 +1390,10 @@ func mergeMap(original, patch map[string]interface{}, schema LookupPatchMeta, me
if mergeOptions.IgnoreUnmatchedNulls {
discardNullValuesFromPatch(patchV)
}
original[k] = patchV
original[k], ok = removeDirectives(patchV)
if !ok {
delete(original, k)
}
}
continue
}
@@ -1372,7 +1420,11 @@ func mergeMap(original, patch map[string]interface{}, schema LookupPatchMeta, me
}
original[k], err = mergeSliceHandler(original[k], patchV, subschema, patchStrategy, patchMeta.GetPatchMergeKey(), isDeleteList, mergeOptions)
default:
original[k] = patchV
original[k], ok = removeDirectives(patchV)
if !ok {
// if patchV itself is a directive, then don't keep it
delete(original, k)
}
}
if err != nil {
return nil, err
@@ -1425,7 +1477,8 @@ func mergeSliceHandler(original, patch interface{}, schema LookupPatchMeta,
return nil, err
}
if fieldPatchStrategy == mergeDirective {
// Delete lists are handled the same way regardless of what the field's patch strategy is
if fieldPatchStrategy == mergeDirective || isDeleteList {
return mergeSlice(typedOriginal, typedPatch, schema, fieldPatchMergeKey, mergeOptions, isDeleteList)
} else {
return typedPatch, nil

18
vendor/k8s.io/apimachinery/pkg/util/version/doc.go generated vendored Normal file
View File

@@ -0,0 +1,18 @@
/*
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 version provides utilities for version number comparisons
package version // import "k8s.io/apimachinery/pkg/util/version"

330
vendor/k8s.io/apimachinery/pkg/util/version/version.go generated vendored Normal file
View File

@@ -0,0 +1,330 @@
/*
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 version
import (
"bytes"
"fmt"
"regexp"
"strconv"
"strings"
)
// Version is an opaque representation of a version number
type Version struct {
components []uint
semver bool
preRelease string
buildMetadata string
}
var (
// versionMatchRE splits a version string into numeric and "extra" parts
versionMatchRE = regexp.MustCompile(`^\s*v?([0-9]+(?:\.[0-9]+)*)(.*)*$`)
// extraMatchRE splits the "extra" part of versionMatchRE into semver pre-release and build metadata; it does not validate the "no leading zeroes" constraint for pre-release
extraMatchRE = regexp.MustCompile(`^(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?\s*$`)
)
func parse(str string, semver bool) (*Version, error) {
parts := versionMatchRE.FindStringSubmatch(str)
if parts == nil {
return nil, fmt.Errorf("could not parse %q as version", str)
}
numbers, extra := parts[1], parts[2]
components := strings.Split(numbers, ".")
if (semver && len(components) != 3) || (!semver && len(components) < 2) {
return nil, fmt.Errorf("illegal version string %q", str)
}
v := &Version{
components: make([]uint, len(components)),
semver: semver,
}
for i, comp := range components {
if (i == 0 || semver) && strings.HasPrefix(comp, "0") && comp != "0" {
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
}
num, err := strconv.ParseUint(comp, 10, 0)
if err != nil {
return nil, fmt.Errorf("illegal non-numeric version component %q in %q: %v", comp, str, err)
}
v.components[i] = uint(num)
}
if semver && extra != "" {
extraParts := extraMatchRE.FindStringSubmatch(extra)
if extraParts == nil {
return nil, fmt.Errorf("could not parse pre-release/metadata (%s) in version %q", extra, str)
}
v.preRelease, v.buildMetadata = extraParts[1], extraParts[2]
for _, comp := range strings.Split(v.preRelease, ".") {
if _, err := strconv.ParseUint(comp, 10, 0); err == nil {
if strings.HasPrefix(comp, "0") && comp != "0" {
return nil, fmt.Errorf("illegal zero-prefixed version component %q in %q", comp, str)
}
}
}
}
return v, nil
}
// ParseGeneric parses a "generic" version string. The version string must consist of two
// or more dot-separated numeric fields (the first of which can't have leading zeroes),
// followed by arbitrary uninterpreted data (which need not be separated from the final
// numeric field by punctuation). For convenience, leading and trailing whitespace is
// ignored, and the version can be preceded by the letter "v". See also ParseSemantic.
func ParseGeneric(str string) (*Version, error) {
return parse(str, false)
}
// MustParseGeneric is like ParseGeneric except that it panics on error
func MustParseGeneric(str string) *Version {
v, err := ParseGeneric(str)
if err != nil {
panic(err)
}
return v
}
// ParseSemantic parses a version string that exactly obeys the syntax and semantics of
// the "Semantic Versioning" specification (http://semver.org/) (although it ignores
// leading and trailing whitespace, and allows the version to be preceded by "v"). For
// version strings that are not guaranteed to obey the Semantic Versioning syntax, use
// ParseGeneric.
func ParseSemantic(str string) (*Version, error) {
return parse(str, true)
}
// MustParseSemantic is like ParseSemantic except that it panics on error
func MustParseSemantic(str string) *Version {
v, err := ParseSemantic(str)
if err != nil {
panic(err)
}
return v
}
// MajorMinor returns a version with the provided major and minor version.
func MajorMinor(major, minor uint) *Version {
return &Version{components: []uint{major, minor}}
}
// Major returns the major release number
func (v *Version) Major() uint {
return v.components[0]
}
// Minor returns the minor release number
func (v *Version) Minor() uint {
return v.components[1]
}
// Patch returns the patch release number if v is a Semantic Version, or 0
func (v *Version) Patch() uint {
if len(v.components) < 3 {
return 0
}
return v.components[2]
}
// BuildMetadata returns the build metadata, if v is a Semantic Version, or ""
func (v *Version) BuildMetadata() string {
return v.buildMetadata
}
// PreRelease returns the prerelease metadata, if v is a Semantic Version, or ""
func (v *Version) PreRelease() string {
return v.preRelease
}
// Components returns the version number components
func (v *Version) Components() []uint {
return v.components
}
// WithMajor returns copy of the version object with requested major number
func (v *Version) WithMajor(major uint) *Version {
result := *v
result.components = []uint{major, v.Minor(), v.Patch()}
return &result
}
// WithMinor returns copy of the version object with requested minor number
func (v *Version) WithMinor(minor uint) *Version {
result := *v
result.components = []uint{v.Major(), minor, v.Patch()}
return &result
}
// WithPatch returns copy of the version object with requested patch number
func (v *Version) WithPatch(patch uint) *Version {
result := *v
result.components = []uint{v.Major(), v.Minor(), patch}
return &result
}
// WithPreRelease returns copy of the version object with requested prerelease
func (v *Version) WithPreRelease(preRelease string) *Version {
result := *v
result.components = []uint{v.Major(), v.Minor(), v.Patch()}
result.preRelease = preRelease
return &result
}
// WithBuildMetadata returns copy of the version object with requested buildMetadata
func (v *Version) WithBuildMetadata(buildMetadata string) *Version {
result := *v
result.components = []uint{v.Major(), v.Minor(), v.Patch()}
result.buildMetadata = buildMetadata
return &result
}
// String converts a Version back to a string; note that for versions parsed with
// ParseGeneric, this will not include the trailing uninterpreted portion of the version
// number.
func (v *Version) String() string {
if v == nil {
return "<nil>"
}
var buffer bytes.Buffer
for i, comp := range v.components {
if i > 0 {
buffer.WriteString(".")
}
buffer.WriteString(fmt.Sprintf("%d", comp))
}
if v.preRelease != "" {
buffer.WriteString("-")
buffer.WriteString(v.preRelease)
}
if v.buildMetadata != "" {
buffer.WriteString("+")
buffer.WriteString(v.buildMetadata)
}
return buffer.String()
}
// compareInternal returns -1 if v is less than other, 1 if it is greater than other, or 0
// if they are equal
func (v *Version) compareInternal(other *Version) int {
vLen := len(v.components)
oLen := len(other.components)
for i := 0; i < vLen && i < oLen; i++ {
switch {
case other.components[i] < v.components[i]:
return 1
case other.components[i] > v.components[i]:
return -1
}
}
// If components are common but one has more items and they are not zeros, it is bigger
switch {
case oLen < vLen && !onlyZeros(v.components[oLen:]):
return 1
case oLen > vLen && !onlyZeros(other.components[vLen:]):
return -1
}
if !v.semver || !other.semver {
return 0
}
switch {
case v.preRelease == "" && other.preRelease != "":
return 1
case v.preRelease != "" && other.preRelease == "":
return -1
case v.preRelease == other.preRelease: // includes case where both are ""
return 0
}
vPR := strings.Split(v.preRelease, ".")
oPR := strings.Split(other.preRelease, ".")
for i := 0; i < len(vPR) && i < len(oPR); i++ {
vNum, err := strconv.ParseUint(vPR[i], 10, 0)
if err == nil {
oNum, err := strconv.ParseUint(oPR[i], 10, 0)
if err == nil {
switch {
case oNum < vNum:
return 1
case oNum > vNum:
return -1
default:
continue
}
}
}
if oPR[i] < vPR[i] {
return 1
} else if oPR[i] > vPR[i] {
return -1
}
}
switch {
case len(oPR) < len(vPR):
return 1
case len(oPR) > len(vPR):
return -1
}
return 0
}
// returns false if array contain any non-zero element
func onlyZeros(array []uint) bool {
for _, num := range array {
if num != 0 {
return false
}
}
return true
}
// AtLeast tests if a version is at least equal to a given minimum version. If both
// Versions are Semantic Versions, this will use the Semantic Version comparison
// algorithm. Otherwise, it will compare only the numeric components, with non-present
// components being considered "0" (ie, "1.4" is equal to "1.4.0").
func (v *Version) AtLeast(min *Version) bool {
return v.compareInternal(min) != -1
}
// LessThan tests if a version is less than a given version. (It is exactly the opposite
// of AtLeast, for situations where asking "is v too old?" makes more sense than asking
// "is v new enough?".)
func (v *Version) LessThan(other *Version) bool {
return v.compareInternal(other) == -1
}
// Compare compares v against a version string (which will be parsed as either Semantic
// or non-Semantic depending on v). On success it returns -1 if v is less than other, 1 if
// it is greater than other, or 0 if they are equal.
func (v *Version) Compare(other string) (int, error) {
ov, err := parse(other, v.semver)
if err != nil {
return 0, err
}
return v.compareInternal(ov), nil
}

View File

@@ -27,9 +27,11 @@ import (
// the provided timer until the provided context is cancelled, the condition returns
// true, or the condition returns an error. If sliding is true, the period is computed
// after condition runs. If it is false then period includes the runtime for condition.
// If immediate is false the first delay happens before any call to condition. The
// returned error is the error returned by the last condition or the context error if
// the context was terminated.
// If immediate is false the first delay happens before any call to condition, if
// immediate is true the condition will be invoked before waiting and guarantees that
// the condition is invoked at least once, regardless of whether the context has been
// cancelled. The returned error is the error returned by the last condition or the
// context error if the context was terminated.
//
// This is the common loop construct for all polling in the wait package.
func loopConditionUntilContext(ctx context.Context, t Timer, immediate, sliding bool, condition ConditionWithContextFunc) error {
@@ -38,8 +40,17 @@ func loopConditionUntilContext(ctx context.Context, t Timer, immediate, sliding
var timeCh <-chan time.Time
doneCh := ctx.Done()
// if immediate is true the condition is
// guaranteed to be executed at least once,
// if we haven't requested immediate execution, delay once
if !immediate {
if immediate {
if ok, err := func() (bool, error) {
defer runtime.HandleCrash()
return condition(ctx)
}(); err != nil || ok {
return err
}
} else {
timeCh = t.C()
select {
case <-doneCh:

View File

@@ -38,10 +38,10 @@ func PollUntilContextCancel(ctx context.Context, interval time.Duration, immedia
// a deadline and is equivalent to:
//
// deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout)
// err := PollUntilContextCancel(ctx, interval, immediate, condition)
// err := PollUntilContextCancel(deadlineCtx, interval, immediate, condition)
//
// The deadline context will be cancelled if the Poll succeeds before the timeout, simplifying
// inline usage. All other behavior is identical to PollWithContextTimeout.
// inline usage. All other behavior is identical to PollUntilContextCancel.
func PollUntilContextTimeout(ctx context.Context, interval, timeout time.Duration, immediate bool, condition ConditionWithContextFunc) error {
deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout)
defer deadlineCancel()
@@ -59,7 +59,7 @@ func PollUntilContextTimeout(ctx context.Context, interval, timeout time.Duratio
//
// If you want to Poll something forever, see PollInfinite.
//
// Deprecated: This method does not return errors from context, use PollWithContextTimeout.
// Deprecated: This method does not return errors from context, use PollUntilContextTimeout.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func Poll(interval, timeout time.Duration, condition ConditionFunc) error {
@@ -78,7 +78,7 @@ func Poll(interval, timeout time.Duration, condition ConditionFunc) error {
//
// If you want to Poll something forever, see PollInfinite.
//
// Deprecated: This method does not return errors from context, use PollWithContextTimeout.
// Deprecated: This method does not return errors from context, use PollUntilContextTimeout.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error {
@@ -91,7 +91,7 @@ func PollWithContext(ctx context.Context, interval, timeout time.Duration, condi
// PollUntil always waits interval before the first run of 'condition'.
// 'condition' will always be invoked at least once.
//
// Deprecated: This method does not return errors from context, use PollWithContextCancel.
// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error {
@@ -104,7 +104,7 @@ func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan st
// PollUntilWithContext always waits interval before the first run of 'condition'.
// 'condition' will always be invoked at least once.
//
// Deprecated: This method does not return errors from context, use PollWithContextCancel.
// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
@@ -118,7 +118,7 @@ func PollUntilWithContext(ctx context.Context, interval time.Duration, condition
// Some intervals may be missed if the condition takes too long or the time
// window is too short.
//
// Deprecated: This method does not return errors from context, use PollWithContextCancel.
// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollInfinite(interval time.Duration, condition ConditionFunc) error {
@@ -132,7 +132,7 @@ func PollInfinite(interval time.Duration, condition ConditionFunc) error {
// Some intervals may be missed if the condition takes too long or the time
// window is too short.
//
// Deprecated: This method does not return errors from context, use PollWithContextCancel.
// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
@@ -150,7 +150,7 @@ func PollInfiniteWithContext(ctx context.Context, interval time.Duration, condit
//
// If you want to immediately Poll something forever, see PollImmediateInfinite.
//
// Deprecated: This method does not return errors from context, use PollWithContextTimeout.
// Deprecated: This method does not return errors from context, use PollUntilContextTimeout.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) error {
@@ -168,7 +168,7 @@ func PollImmediate(interval, timeout time.Duration, condition ConditionFunc) err
//
// If you want to immediately Poll something forever, see PollImmediateInfinite.
//
// Deprecated: This method does not return errors from context, use PollWithContextTimeout.
// Deprecated: This method does not return errors from context, use PollUntilContextTimeout.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollImmediateWithContext(ctx context.Context, interval, timeout time.Duration, condition ConditionWithContextFunc) error {
@@ -180,7 +180,7 @@ func PollImmediateWithContext(ctx context.Context, interval, timeout time.Durati
// PollImmediateUntil runs the 'condition' before waiting for the interval.
// 'condition' will always be invoked at least once.
//
// Deprecated: This method does not return errors from context, use PollWithContextCancel.
// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollImmediateUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error {
@@ -193,7 +193,7 @@ func PollImmediateUntil(interval time.Duration, condition ConditionFunc, stopCh
// PollImmediateUntilWithContext runs the 'condition' before waiting for the interval.
// 'condition' will always be invoked at least once.
//
// Deprecated: This method does not return errors from context, use PollWithContextCancel.
// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollImmediateUntilWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {
@@ -207,7 +207,7 @@ func PollImmediateUntilWithContext(ctx context.Context, interval time.Duration,
// Some intervals may be missed if the condition takes too long or the time
// window is too short.
//
// Deprecated: This method does not return errors from context, use PollWithContextCancel.
// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) error {
@@ -222,7 +222,7 @@ func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) erro
// Some intervals may be missed if the condition takes too long or the time
// window is too short.
//
// Deprecated: This method does not return errors from context, use PollWithContextCancel.
// Deprecated: This method does not return errors from context, use PollUntilContextCancel.
// Note that the new method will no longer return ErrWaitTimeout and instead return errors
// defined by the context package. Will be removed in a future release.
func PollImmediateInfiniteWithContext(ctx context.Context, interval time.Duration, condition ConditionWithContextFunc) error {