Allow timestamp transformer equalities to be configurable (#112158)

* allow noop-ignoring transformer to be configurable

* consolidate timestamp equalities initialization

* remove extra plumbing

* fix typo

* remove CustomEqualities list
This commit is contained in:
Alex Zielenski 2022-09-28 10:56:34 -04:00 committed by GitHub
parent 827c77afcb
commit a9a1cdbd15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -22,6 +22,7 @@ import (
"os" "os"
"reflect" "reflect"
"strconv" "strconv"
"sync"
"time" "time"
"k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/equality"
@ -33,42 +34,41 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
) )
func determineAvoidNoopTimestampUpdatesEnabled() bool {
if avoidNoopTimestampUpdatesString, exists := os.LookupEnv("KUBE_APISERVER_AVOID_NOOP_SSA_TIMESTAMP_UPDATES"); exists {
if ret, err := strconv.ParseBool(avoidNoopTimestampUpdatesString); err == nil {
return ret
} else {
klog.Errorf("failed to parse envar KUBE_APISERVER_AVOID_NOOP_SSA_TIMESTAMP_UPDATES: %v", err)
}
}
// enabled by default
return true
}
var ( var (
avoidNoopTimestampUpdatesEnabled = determineAvoidNoopTimestampUpdatesEnabled() avoidTimestampEqualities conversion.Equalities
initAvoidTimestampEqualities sync.Once
) )
var avoidTimestampEqualities = func() conversion.Equalities { func getAvoidTimestampEqualities() conversion.Equalities {
var eqs = equality.Semantic.Copy() initAvoidTimestampEqualities.Do(func() {
if avoidNoopTimestampUpdatesString, exists := os.LookupEnv("KUBE_APISERVER_AVOID_NOOP_SSA_TIMESTAMP_UPDATES"); exists {
if ret, err := strconv.ParseBool(avoidNoopTimestampUpdatesString); err == nil && !ret {
// leave avoidTimestampEqualities empty.
return
} else {
klog.Errorf("failed to parse envar KUBE_APISERVER_AVOID_NOOP_SSA_TIMESTAMP_UPDATES: %v", err)
}
}
err := eqs.AddFunc( var eqs = equality.Semantic.Copy()
func(a, b metav1.ManagedFieldsEntry) bool { err := eqs.AddFunc(
// Two objects' managed fields are equivalent if, ignoring timestamp, func(a, b metav1.ManagedFieldsEntry) bool {
// the objects are deeply equal. // Two objects' managed fields are equivalent if, ignoring timestamp,
a.Time = nil // the objects are deeply equal.
b.Time = nil a.Time = nil
return reflect.DeepEqual(a, b) b.Time = nil
}, return reflect.DeepEqual(a, b)
) },
)
if err != nil { if err != nil {
panic(err) panic(fmt.Errorf("failed to instantiate semantic equalities: %w", err))
} }
return eqs avoidTimestampEqualities = eqs
}() })
return avoidTimestampEqualities
}
// IgnoreManagedFieldsTimestampsTransformer reverts timestamp updates // IgnoreManagedFieldsTimestampsTransformer reverts timestamp updates
// if the non-managed parts of the object are equivalent // if the non-managed parts of the object are equivalent
@ -77,7 +77,8 @@ func IgnoreManagedFieldsTimestampsTransformer(
newObj runtime.Object, newObj runtime.Object,
oldObj runtime.Object, oldObj runtime.Object,
) (res runtime.Object, err error) { ) (res runtime.Object, err error) {
if !avoidNoopTimestampUpdatesEnabled { equalities := getAvoidTimestampEqualities()
if len(equalities.Equalities) == 0 {
return newObj, nil return newObj, nil
} }
@ -154,11 +155,11 @@ func IgnoreManagedFieldsTimestampsTransformer(
// This condition ensures the managed fields are always compared first. If // This condition ensures the managed fields are always compared first. If
// this check fails, the if statement will short circuit. If the check // this check fails, the if statement will short circuit. If the check
// succeeds the slow path is taken which compares entire objects. // succeeds the slow path is taken which compares entire objects.
if !avoidTimestampEqualities.DeepEqualWithNilDifferentFromEmpty(oldManagedFields, newManagedFields) { if !equalities.DeepEqualWithNilDifferentFromEmpty(oldManagedFields, newManagedFields) {
return newObj, nil return newObj, nil
} }
if avoidTimestampEqualities.DeepEqualWithNilDifferentFromEmpty(newObj, oldObj) { if equalities.DeepEqualWithNilDifferentFromEmpty(newObj, oldObj) {
// Remove any changed timestamps, so that timestamp is not the only // Remove any changed timestamps, so that timestamp is not the only
// change seen by etcd. // change seen by etcd.
// //