From cdaadc5ebb072f5ccb281bb5b800991683bbafef Mon Sep 17 00:00:00 2001 From: Todd Short Date: Mon, 17 Nov 2025 09:44:48 -0500 Subject: [PATCH] Restore last-applied-config annotation in cache This restores the last-applied-config annotation in the cache, as its absense can cause issues with clients when we update our finalizers. This increases memory utilization until we can solve the finalizer issue. Signed-off-by: Todd Short --- cmd/catalogd/main.go | 3 - cmd/operator-controller/main.go | 3 - .../operator-controller/applier/boxcutter.go | 8 -- internal/shared/util/cache/transform.go | 91 ------------------- 4 files changed, 105 deletions(-) delete mode 100644 internal/shared/util/cache/transform.go diff --git a/cmd/catalogd/main.go b/cmd/catalogd/main.go index af2463e2c..36f7b1675 100644 --- a/cmd/catalogd/main.go +++ b/cmd/catalogd/main.go @@ -59,7 +59,6 @@ import ( "github.com/operator-framework/operator-controller/internal/catalogd/storage" "github.com/operator-framework/operator-controller/internal/catalogd/webhook" sharedcontrollers "github.com/operator-framework/operator-controller/internal/shared/controllers" - cacheutil "github.com/operator-framework/operator-controller/internal/shared/util/cache" fsutil "github.com/operator-framework/operator-controller/internal/shared/util/fs" httputil "github.com/operator-framework/operator-controller/internal/shared/util/http" imageutil "github.com/operator-framework/operator-controller/internal/shared/util/image" @@ -255,8 +254,6 @@ func run(ctx context.Context) error { cacheOptions := crcache.Options{ ByObject: map[client.Object]crcache.ByObject{}, - // Memory optimization: strip managed fields and large annotations from cached objects - DefaultTransform: cacheutil.StripManagedFieldsAndAnnotations(), } saKey, err := sautil.GetServiceAccount() diff --git a/cmd/operator-controller/main.go b/cmd/operator-controller/main.go index 20d55bc3c..2d89111f4 100644 --- a/cmd/operator-controller/main.go +++ b/cmd/operator-controller/main.go @@ -78,7 +78,6 @@ import ( "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render/registryv1" "github.com/operator-framework/operator-controller/internal/operator-controller/scheme" sharedcontrollers "github.com/operator-framework/operator-controller/internal/shared/controllers" - cacheutil "github.com/operator-framework/operator-controller/internal/shared/util/cache" fsutil "github.com/operator-framework/operator-controller/internal/shared/util/fs" httputil "github.com/operator-framework/operator-controller/internal/shared/util/http" imageutil "github.com/operator-framework/operator-controller/internal/shared/util/image" @@ -233,8 +232,6 @@ func run() error { cfg.systemNamespace: {LabelSelector: k8slabels.Everything()}, }, DefaultLabelSelector: k8slabels.Nothing(), - // Memory optimization: strip managed fields and large annotations from cached objects - DefaultTransform: cacheutil.StripAnnotations(), } if features.OperatorControllerFeatureGate.Enabled(features.BoxcutterRuntime) { diff --git a/internal/operator-controller/applier/boxcutter.go b/internal/operator-controller/applier/boxcutter.go index 1914b80e8..0d4443ecc 100644 --- a/internal/operator-controller/applier/boxcutter.go +++ b/internal/operator-controller/applier/boxcutter.go @@ -28,7 +28,6 @@ import ( ocv1 "github.com/operator-framework/operator-controller/api/v1" "github.com/operator-framework/operator-controller/internal/operator-controller/controllers" "github.com/operator-framework/operator-controller/internal/operator-controller/labels" - "github.com/operator-framework/operator-controller/internal/shared/util/cache" ) const ( @@ -68,9 +67,6 @@ func (r *SimpleRevisionGenerator) GenerateRevisionFromHelmRelease( maps.Copy(labels, objectLabels) obj.SetLabels(labels) - // Memory optimization: strip large annotations - // Note: ApplyStripTransform never returns an error in practice - _ = cache.ApplyStripAnnotationsTransform(&obj) sanitizedUnstructured(ctx, &obj) objs = append(objs, ocv1.ClusterExtensionRevisionObject{ @@ -122,10 +118,6 @@ func (r *SimpleRevisionGenerator) GenerateRevision( unstr := unstructured.Unstructured{Object: unstrObj} unstr.SetGroupVersionKind(gvk) - // Memory optimization: strip large annotations - if err := cache.ApplyStripAnnotationsTransform(&unstr); err != nil { - return nil, err - } sanitizedUnstructured(ctx, &unstr) objs = append(objs, ocv1.ClusterExtensionRevisionObject{ diff --git a/internal/shared/util/cache/transform.go b/internal/shared/util/cache/transform.go deleted file mode 100644 index 50a553039..000000000 --- a/internal/shared/util/cache/transform.go +++ /dev/null @@ -1,91 +0,0 @@ -package cache - -import ( - "maps" - - toolscache "k8s.io/client-go/tools/cache" - crcache "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// stripAnnotations removes memory-heavy annotations that aren't needed for controller operations. -func stripAnnotations(obj interface{}) (interface{}, error) { - if metaObj, ok := obj.(client.Object); ok { - // Remove the last-applied-configuration annotation which can be very large - // Clone the annotations map to avoid modifying shared references - annotations := metaObj.GetAnnotations() - if annotations != nil { - annotations = maps.Clone(annotations) - delete(annotations, "kubectl.kubernetes.io/last-applied-configuration") - if len(annotations) == 0 { - metaObj.SetAnnotations(nil) - } else { - metaObj.SetAnnotations(annotations) - } - } - } - return obj, nil -} - -// StripManagedFieldsAndAnnotations returns a cache transform function that removes -// memory-heavy fields that aren't needed for controller operations. -// This significantly reduces memory usage in informer caches by removing: -// - Managed fields (can be several KB per object) -// - kubectl.kubernetes.io/last-applied-configuration annotation (can be very large) -// -// Use this function as a DefaultTransform in controller-runtime cache.Options -// to reduce memory overhead across all cached objects. -// -// Example: -// -// cacheOptions := cache.Options{ -// DefaultTransform: cacheutil.StripManagedFieldsAndAnnotations(), -// } -func StripManagedFieldsAndAnnotations() toolscache.TransformFunc { - // Use controller-runtime's built-in TransformStripManagedFields and compose it - // with our custom annotation stripping transform - managedFieldsTransform := crcache.TransformStripManagedFields() - - return func(obj interface{}) (interface{}, error) { - // First strip managed fields using controller-runtime's transform - obj, err := managedFieldsTransform(obj) - if err != nil { - return obj, err - } - - // Then strip the large annotations - return stripAnnotations(obj) - } -} - -// StripAnnotations returns a cache transform function that removes -// memory-heavy annotation fields that aren't needed for controller operations. -// This significantly reduces memory usage in informer caches by removing: -// - kubectl.kubernetes.io/last-applied-configuration annotation (can be very large) -// -// Use this function as a DefaultTransform in controller-runtime cache.Options -// to reduce memory overhead across all cached objects. -// -// Example: -// -// cacheOptions := cache.Options{ -// DefaultTransform: cacheutil.StripAnnotations(), -// } -func StripAnnotations() toolscache.TransformFunc { - return func(obj interface{}) (interface{}, error) { - // Strip the large annotations - return stripAnnotations(obj) - } -} - -// ApplyStripAnnotationsTransform applies the strip transform directly to an object. -// This is a convenience function for cases where you need to strip fields -// from an object outside of the cache transform context. -// -// Note: This function never returns an error in practice, but returns error -// to satisfy the TransformFunc interface. -func ApplyStripAnnotationsTransform(obj client.Object) error { - transform := StripAnnotations() - _, err := transform(obj) - return err -}