From 2ce10227cbd559785d71406277c2ca345cce56c4 Mon Sep 17 00:00:00 2001 From: Alexander Zielenski <351783+alexzielenski@users.noreply.github.com> Date: Wed, 31 Aug 2022 12:15:34 -0700 Subject: [PATCH 1/5] allow noop-ignoring transformer to be configurable --- .../apiserver/pkg/endpoints/groupversion.go | 1 + .../handlers/fieldmanager/equality.go | 27 ++++++++++++------- .../apiserver/pkg/endpoints/handlers/patch.go | 4 +-- .../apiserver/pkg/endpoints/handlers/rest.go | 5 ++-- .../pkg/endpoints/handlers/update.go | 4 +-- .../apiserver/pkg/endpoints/installer.go | 2 ++ .../src/k8s.io/apiserver/pkg/server/config.go | 18 +++++++++++++ .../apiserver/pkg/server/genericapiserver.go | 3 +++ 8 files changed, 49 insertions(+), 15 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go b/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go index d7f85106ee44..cadbe75380cb 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go @@ -82,6 +82,7 @@ type APIGroupVersion struct { Namer runtime.Namer UnsafeConvertor runtime.ObjectConvertor TypeConverter fieldmanager.TypeConverter + AvoidNoopTransformer *fieldmanager.AvoidNoopTransformer EquivalentResourceRegistry runtime.EquivalentResourceRegistry diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go index 366d88fcc50b..9e5d8d4eaf78 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go @@ -50,9 +50,12 @@ var ( avoidNoopTimestampUpdatesEnabled = determineAvoidNoopTimestampUpdatesEnabled() ) -var avoidTimestampEqualities = func() conversion.Equalities { - var eqs = equality.Semantic.Copy() +type AvoidNoopTransformer struct { + equalities conversion.Equalities +} +func NewAvoidNoopTransformer(toAdd ...interface{}) (*AvoidNoopTransformer, error) { + var eqs = equality.Semantic.Copy() err := eqs.AddFunc( func(a, b metav1.ManagedFieldsEntry) bool { // Two objects' managed fields are equivalent if, ignoring timestamp, @@ -64,16 +67,22 @@ var avoidTimestampEqualities = func() conversion.Equalities { ) if err != nil { - panic(err) + return nil, fmt.Errorf("failed to instantiate semantic equalities: %w", err) } - return eqs -}() + err = eqs.AddFuncs(toAdd...) + if err != nil { + return nil, fmt.Errorf("failed to instantiate semantic equalities: %w", err) + } + + return &AvoidNoopTransformer{ + equalities: eqs, + }, nil +} // IgnoreManagedFieldsTimestampsTransformer reverts timestamp updates // if the non-managed parts of the object are equivalent -func IgnoreManagedFieldsTimestampsTransformer( - _ context.Context, +func (a AvoidNoopTransformer) Transform(_ context.Context, newObj runtime.Object, oldObj runtime.Object, ) (res runtime.Object, err error) { @@ -154,11 +163,11 @@ func IgnoreManagedFieldsTimestampsTransformer( // This condition ensures the managed fields are always compared first. If // this check fails, the if statement will short circuit. If the check // succeeds the slow path is taken which compares entire objects. - if !avoidTimestampEqualities.DeepEqualWithNilDifferentFromEmpty(oldManagedFields, newManagedFields) { + if !a.equalities.DeepEqualWithNilDifferentFromEmpty(oldManagedFields, newManagedFields) { return newObj, nil } - if avoidTimestampEqualities.DeepEqualWithNilDifferentFromEmpty(newObj, oldObj) { + if a.equalities.DeepEqualWithNilDifferentFromEmpty(newObj, oldObj) { // Remove any changed timestamps, so that timestamp is not the only // change seen by etcd. // diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go index 1800b8f5b0b4..6eac8fa6dcd5 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go @@ -654,8 +654,8 @@ func (p *patcher) patchResource(ctx context.Context, scope *RequestScope) (runti } transformers := []rest.TransformFunc{p.applyPatch, p.applyAdmission, dedupOwnerReferencesTransformer} - if scope.FieldManager != nil { - transformers = append(transformers, fieldmanager.IgnoreManagedFieldsTimestampsTransformer) + if scope.AvoidNoopTransformer != nil { + transformers = append(transformers, scope.AvoidNoopTransformer.Transform) } wasCreated := false diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go index 7f005a37167c..72e14a42c1db 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go @@ -90,8 +90,9 @@ type RequestScope struct { EquivalentResourceMapper runtime.EquivalentResourceMapper - TableConvertor rest.TableConvertor - FieldManager *fieldmanager.FieldManager + TableConvertor rest.TableConvertor + FieldManager *fieldmanager.FieldManager + AvoidNoopTransformer *fieldmanager.AvoidNoopTransformer Resource schema.GroupVersionResource Kind schema.GroupVersionKind diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go index 2c856c5fec44..ce6d035f72a9 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go @@ -190,8 +190,8 @@ func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interfa // like normalized fields, defaulted fields and other // mutations. // Only makes sense when SSA field manager is being used - if scope.FieldManager != nil { - transformers = append(transformers, fieldmanager.IgnoreManagedFieldsTimestampsTransformer) + if scope.AvoidNoopTransformer != nil { + transformers = append(transformers, scope.AvoidNoopTransformer.Transform) } createAuthorizerAttributes := authorizer.AttributesRecord{ diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go index 7881373b898a..77ce60bf5da2 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go @@ -613,6 +613,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if err != nil { return nil, nil, fmt.Errorf("failed to create field manager: %v", err) } + + reqScope.AvoidNoopTransformer = a.group.AvoidNoopTransformer } for _, action := range actions { producedObject := storageMeta.ProducesObject(action.Verb) diff --git a/staging/src/k8s.io/apiserver/pkg/server/config.go b/staging/src/k8s.io/apiserver/pkg/server/config.go index d21ea2ef0009..5dcc6660542f 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/config.go @@ -50,6 +50,7 @@ import ( "k8s.io/apiserver/pkg/endpoints/discovery" "k8s.io/apiserver/pkg/endpoints/filterlatency" genericapifilters "k8s.io/apiserver/pkg/endpoints/filters" + "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" apiopenapi "k8s.io/apiserver/pkg/endpoints/openapi" apirequest "k8s.io/apiserver/pkg/endpoints/request" genericfeatures "k8s.io/apiserver/pkg/features" @@ -257,6 +258,17 @@ type Config struct { // StorageVersionManager holds the storage versions of the API resources installed by this server. StorageVersionManager storageversion.Manager + + // For each update, the new object is checked to see if it is semantically + // changed from the previous object. If it is semantically unchanged, the + // write is ignored. + // + // SemanticEqualities are functions with the signature: + // func (a, b T) bool + // + // SemanticEqualities can be used to control how the change comparison is + // performed for a type of object, T + SemanticEqualities []interface{} } type RecommendedConfig struct { @@ -662,6 +674,12 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G muxAndDiscoveryCompleteSignals: map[string]<-chan struct{}{}, } + if noopTransformer, err := fieldmanager.NewAvoidNoopTransformer(c.SemanticEqualities...); err != nil { + return nil, err + } else { + s.noopTransformer = noopTransformer + } + for { if c.JSONPatchMaxCopyBytes <= 0 { break diff --git a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go index dbcbcbd89549..a17ae20d37aa 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go +++ b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go @@ -247,6 +247,8 @@ type GenericAPIServer struct { // If enabled, after ShutdownDelayDuration elapses, any incoming request is // rejected with a 429 status code and a 'Retry-After' response. ShutdownSendRetryAfter bool + + noopTransformer *fieldmanager.AvoidNoopTransformer } // DelegationTarget is an interface which allows for composition of API servers with top level handling that works @@ -672,6 +674,7 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A return err } apiGroupVersion.TypeConverter = typeConverter + apiGroupVersion.AvoidNoopTransformer = s.noopTransformer } apiGroupVersion.MaxRequestBodyBytes = s.maxRequestBodyBytes From d5b9cb068acf0aa91d49b00e7017e16f877a1552 Mon Sep 17 00:00:00 2001 From: Alexander Zielenski <351783+alexzielenski@users.noreply.github.com> Date: Wed, 21 Sep 2022 12:12:18 -0700 Subject: [PATCH 2/5] consolidate timestamp equalities initialization --- .../handlers/fieldmanager/equality.go | 67 ++++++++++--------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go index 9e5d8d4eaf78..741ef61e9fb1 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go @@ -22,6 +22,7 @@ import ( "os" "reflect" "strconv" + "sync" "time" "k8s.io/apimachinery/pkg/api/equality" @@ -33,46 +34,52 @@ import ( "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) +var ( + avoidTimestampEqualities conversion.Equalities + initAvoidTimestampEqualities sync.Once +) + +func getAvoidTimestampEqualities() conversion.Equalities { + 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) + } } - } - // enabled by default - return true -} + var eqs = equality.Semantic.Copy() + err := eqs.AddFunc( + func(a, b metav1.ManagedFieldsEntry) bool { + // Two objects' managed fields are equivalent if, ignoring timestamp, + // the objects are deeply equal. + a.Time = nil + b.Time = nil + return reflect.DeepEqual(a, b) + }, + ) -var ( - avoidNoopTimestampUpdatesEnabled = determineAvoidNoopTimestampUpdatesEnabled() -) + if err != nil { + panic(fmt.Errorf("failed to instantiate semantic equalities: %w", err)) + } + + avoidTimestampEqualities = eqs + }) + return avoidTimestampEqualities +} type AvoidNoopTransformer struct { equalities conversion.Equalities } func NewAvoidNoopTransformer(toAdd ...interface{}) (*AvoidNoopTransformer, error) { - var eqs = equality.Semantic.Copy() - err := eqs.AddFunc( - func(a, b metav1.ManagedFieldsEntry) bool { - // Two objects' managed fields are equivalent if, ignoring timestamp, - // the objects are deeply equal. - a.Time = nil - b.Time = nil - return reflect.DeepEqual(a, b) - }, - ) - - if err != nil { - return nil, fmt.Errorf("failed to instantiate semantic equalities: %w", err) - } + var eqs = getAvoidTimestampEqualities().Copy() - err = eqs.AddFuncs(toAdd...) + err := eqs.AddFuncs(toAdd...) if err != nil { - return nil, fmt.Errorf("failed to instantiate semantic equalities: %w", err) + return nil, err } return &AvoidNoopTransformer{ @@ -86,7 +93,7 @@ func (a AvoidNoopTransformer) Transform(_ context.Context, newObj runtime.Object, oldObj runtime.Object, ) (res runtime.Object, err error) { - if !avoidNoopTimestampUpdatesEnabled { + if len(a.equalities.Equalities) == 0 { return newObj, nil } From 39ee615c65d206183f223910a0f86ca0fc55e3e9 Mon Sep 17 00:00:00 2001 From: Alexander Zielenski <351783+alexzielenski@users.noreply.github.com> Date: Wed, 21 Sep 2022 14:22:19 -0700 Subject: [PATCH 3/5] remove extra plumbing --- .../apiserver/pkg/endpoints/groupversion.go | 1 - .../handlers/fieldmanager/equality.go | 41 +++++++++---------- .../apiserver/pkg/endpoints/handlers/patch.go | 4 +- .../apiserver/pkg/endpoints/handlers/rest.go | 5 +-- .../pkg/endpoints/handlers/update.go | 4 +- .../apiserver/pkg/endpoints/installer.go | 2 - .../src/k8s.io/apiserver/pkg/server/config.go | 18 -------- .../apiserver/pkg/server/genericapiserver.go | 3 -- 8 files changed, 26 insertions(+), 52 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go b/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go index cadbe75380cb..d7f85106ee44 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/groupversion.go @@ -82,7 +82,6 @@ type APIGroupVersion struct { Namer runtime.Namer UnsafeConvertor runtime.ObjectConvertor TypeConverter fieldmanager.TypeConverter - AvoidNoopTransformer *fieldmanager.AvoidNoopTransformer EquivalentResourceRegistry runtime.EquivalentResourceRegistry diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go index 741ef61e9fb1..96010162073e 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go @@ -35,6 +35,16 @@ import ( ) var ( + // For each update, the new object is checked to see if it is semantically + // changed from the previous object. If it is semantically unchanged, the + // write is ignored. + // + // SemanticEqualities are functions with the signature: + // func (a, b T) bool + // + // SemanticEqualities can be used to control how the change comparison is + // performed for a type of object, T + CustomEqualities []interface{} avoidTimestampEqualities conversion.Equalities initAvoidTimestampEqualities sync.Once ) @@ -65,35 +75,24 @@ func getAvoidTimestampEqualities() conversion.Equalities { panic(fmt.Errorf("failed to instantiate semantic equalities: %w", err)) } + err = eqs.AddFuncs(CustomEqualities...) + if err != nil { + panic(fmt.Errorf("failed to instantiate semantic equalities: %w", err)) + } + avoidTimestampEqualities = eqs }) return avoidTimestampEqualities } -type AvoidNoopTransformer struct { - equalities conversion.Equalities -} - -func NewAvoidNoopTransformer(toAdd ...interface{}) (*AvoidNoopTransformer, error) { - var eqs = getAvoidTimestampEqualities().Copy() - - err := eqs.AddFuncs(toAdd...) - if err != nil { - return nil, err - } - - return &AvoidNoopTransformer{ - equalities: eqs, - }, nil -} - // IgnoreManagedFieldsTimestampsTransformer reverts timestamp updates // if the non-managed parts of the object are equivalent -func (a AvoidNoopTransformer) Transform(_ context.Context, +func IgnoreManagedFieldsTimestampsTransformer(_ context.Context, newObj runtime.Object, oldObj runtime.Object, ) (res runtime.Object, err error) { - if len(a.equalities.Equalities) == 0 { + equalities := getAvoidTimestampEqualities() + if len(equalities.Equalities) == 0 { return newObj, nil } @@ -170,11 +169,11 @@ func (a AvoidNoopTransformer) Transform(_ context.Context, // This condition ensures the managed fields are always compared first. If // this check fails, the if statement will short circuit. If the check // succeeds the slow path is taken which compares entire objects. - if !a.equalities.DeepEqualWithNilDifferentFromEmpty(oldManagedFields, newManagedFields) { + if !equalities.DeepEqualWithNilDifferentFromEmpty(oldManagedFields, newManagedFields) { return newObj, nil } - if a.equalities.DeepEqualWithNilDifferentFromEmpty(newObj, oldObj) { + if equalities.DeepEqualWithNilDifferentFromEmpty(newObj, oldObj) { // Remove any changed timestamps, so that timestamp is not the only // change seen by etcd. // diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go index 6eac8fa6dcd5..1800b8f5b0b4 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go @@ -654,8 +654,8 @@ func (p *patcher) patchResource(ctx context.Context, scope *RequestScope) (runti } transformers := []rest.TransformFunc{p.applyPatch, p.applyAdmission, dedupOwnerReferencesTransformer} - if scope.AvoidNoopTransformer != nil { - transformers = append(transformers, scope.AvoidNoopTransformer.Transform) + if scope.FieldManager != nil { + transformers = append(transformers, fieldmanager.IgnoreManagedFieldsTimestampsTransformer) } wasCreated := false diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go index 72e14a42c1db..7f005a37167c 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go @@ -90,9 +90,8 @@ type RequestScope struct { EquivalentResourceMapper runtime.EquivalentResourceMapper - TableConvertor rest.TableConvertor - FieldManager *fieldmanager.FieldManager - AvoidNoopTransformer *fieldmanager.AvoidNoopTransformer + TableConvertor rest.TableConvertor + FieldManager *fieldmanager.FieldManager Resource schema.GroupVersionResource Kind schema.GroupVersionKind diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go index ce6d035f72a9..2c856c5fec44 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go @@ -190,8 +190,8 @@ func UpdateResource(r rest.Updater, scope *RequestScope, admit admission.Interfa // like normalized fields, defaulted fields and other // mutations. // Only makes sense when SSA field manager is being used - if scope.AvoidNoopTransformer != nil { - transformers = append(transformers, scope.AvoidNoopTransformer.Transform) + if scope.FieldManager != nil { + transformers = append(transformers, fieldmanager.IgnoreManagedFieldsTimestampsTransformer) } createAuthorizerAttributes := authorizer.AttributesRecord{ diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go index 77ce60bf5da2..7881373b898a 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go @@ -613,8 +613,6 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if err != nil { return nil, nil, fmt.Errorf("failed to create field manager: %v", err) } - - reqScope.AvoidNoopTransformer = a.group.AvoidNoopTransformer } for _, action := range actions { producedObject := storageMeta.ProducesObject(action.Verb) diff --git a/staging/src/k8s.io/apiserver/pkg/server/config.go b/staging/src/k8s.io/apiserver/pkg/server/config.go index 5dcc6660542f..d21ea2ef0009 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/config.go @@ -50,7 +50,6 @@ import ( "k8s.io/apiserver/pkg/endpoints/discovery" "k8s.io/apiserver/pkg/endpoints/filterlatency" genericapifilters "k8s.io/apiserver/pkg/endpoints/filters" - "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" apiopenapi "k8s.io/apiserver/pkg/endpoints/openapi" apirequest "k8s.io/apiserver/pkg/endpoints/request" genericfeatures "k8s.io/apiserver/pkg/features" @@ -258,17 +257,6 @@ type Config struct { // StorageVersionManager holds the storage versions of the API resources installed by this server. StorageVersionManager storageversion.Manager - - // For each update, the new object is checked to see if it is semantically - // changed from the previous object. If it is semantically unchanged, the - // write is ignored. - // - // SemanticEqualities are functions with the signature: - // func (a, b T) bool - // - // SemanticEqualities can be used to control how the change comparison is - // performed for a type of object, T - SemanticEqualities []interface{} } type RecommendedConfig struct { @@ -674,12 +662,6 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G muxAndDiscoveryCompleteSignals: map[string]<-chan struct{}{}, } - if noopTransformer, err := fieldmanager.NewAvoidNoopTransformer(c.SemanticEqualities...); err != nil { - return nil, err - } else { - s.noopTransformer = noopTransformer - } - for { if c.JSONPatchMaxCopyBytes <= 0 { break diff --git a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go index a17ae20d37aa..dbcbcbd89549 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go +++ b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go @@ -247,8 +247,6 @@ type GenericAPIServer struct { // If enabled, after ShutdownDelayDuration elapses, any incoming request is // rejected with a 429 status code and a 'Retry-After' response. ShutdownSendRetryAfter bool - - noopTransformer *fieldmanager.AvoidNoopTransformer } // DelegationTarget is an interface which allows for composition of API servers with top level handling that works @@ -674,7 +672,6 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A return err } apiGroupVersion.TypeConverter = typeConverter - apiGroupVersion.AvoidNoopTransformer = s.noopTransformer } apiGroupVersion.MaxRequestBodyBytes = s.maxRequestBodyBytes From 6ccdb5f9e276ae423b16fd2e57e90fd05fa74ddf Mon Sep 17 00:00:00 2001 From: Alexander Zielenski <351783+alexzielenski@users.noreply.github.com> Date: Wed, 21 Sep 2022 14:24:36 -0700 Subject: [PATCH 4/5] fix typo --- .../pkg/endpoints/handlers/fieldmanager/equality.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go index 96010162073e..0bd869d0b77b 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go @@ -39,10 +39,10 @@ var ( // changed from the previous object. If it is semantically unchanged, the // write is ignored. // - // SemanticEqualities are functions with the signature: + // Customqualities are functions with the signature: // func (a, b T) bool // - // SemanticEqualities can be used to control how the change comparison is + // Customqualities can be used to control how the change comparison is // performed for a type of object, T CustomEqualities []interface{} avoidTimestampEqualities conversion.Equalities @@ -87,7 +87,8 @@ func getAvoidTimestampEqualities() conversion.Equalities { // IgnoreManagedFieldsTimestampsTransformer reverts timestamp updates // if the non-managed parts of the object are equivalent -func IgnoreManagedFieldsTimestampsTransformer(_ context.Context, +func IgnoreManagedFieldsTimestampsTransformer( + _ context.Context, newObj runtime.Object, oldObj runtime.Object, ) (res runtime.Object, err error) { From 7188c75359d67a0accb4e6d2ad2b07a5fa0c71e1 Mon Sep 17 00:00:00 2001 From: Alexander Zielenski <351783+alexzielenski@users.noreply.github.com> Date: Wed, 21 Sep 2022 14:46:39 -0700 Subject: [PATCH 5/5] remove CustomEqualities list --- .../endpoints/handlers/fieldmanager/equality.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go index 0bd869d0b77b..a1f27f1d106e 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/equality.go @@ -35,16 +35,6 @@ import ( ) var ( - // For each update, the new object is checked to see if it is semantically - // changed from the previous object. If it is semantically unchanged, the - // write is ignored. - // - // Customqualities are functions with the signature: - // func (a, b T) bool - // - // Customqualities can be used to control how the change comparison is - // performed for a type of object, T - CustomEqualities []interface{} avoidTimestampEqualities conversion.Equalities initAvoidTimestampEqualities sync.Once ) @@ -75,11 +65,6 @@ func getAvoidTimestampEqualities() conversion.Equalities { panic(fmt.Errorf("failed to instantiate semantic equalities: %w", err)) } - err = eqs.AddFuncs(CustomEqualities...) - if err != nil { - panic(fmt.Errorf("failed to instantiate semantic equalities: %w", err)) - } - avoidTimestampEqualities = eqs }) return avoidTimestampEqualities