From 30be0a3c204a9703bbd8dd62b8b8e38f9ad5d24b Mon Sep 17 00:00:00 2001 From: Ben Luddy Date: Mon, 28 Oct 2024 12:09:02 -0400 Subject: [PATCH] Allow nondeterministic object encoding in HTTP response bodies. Kubernetes-commit: dee76a460ec80f15dc199c93e506586687d42291 --- .../handlers/responsewriters/writers.go | 7 ++++++- pkg/endpoints/handlers/watch.go | 20 +++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/pkg/endpoints/handlers/responsewriters/writers.go b/pkg/endpoints/handlers/responsewriters/writers.go index 218d18efa..9b9e10ad1 100644 --- a/pkg/endpoints/handlers/responsewriters/writers.go +++ b/pkg/endpoints/handlers/responsewriters/writers.go @@ -285,7 +285,12 @@ func WriteObjectNegotiated(s runtime.NegotiatedSerializer, restrictions negotiat audit.LogResponseObject(req.Context(), object, gv, s) - encoder := s.EncoderForVersion(serializer.Serializer, gv) + var encoder runtime.Encoder + if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + encoder = s.EncoderForVersion(runtime.UseNondeterministicEncoding(serializer.Serializer), gv) + } else { + encoder = s.EncoderForVersion(serializer.Serializer, gv) + } request.TrackSerializeResponseObjectLatency(req.Context(), func() { if listGVKInContentType { SerializeObject(generateMediaTypeWithGVK(serializer.MediaType, mediaType.Convert), encoder, w, req, statusCode, object) diff --git a/pkg/endpoints/handlers/watch.go b/pkg/endpoints/handlers/watch.go index 7443e3d57..938e8ef5b 100644 --- a/pkg/endpoints/handlers/watch.go +++ b/pkg/endpoints/handlers/watch.go @@ -76,8 +76,12 @@ func serveWatchHandler(watcher watch.Interface, scope *RequestScope, mediaTypeOp return nil, err } framer := serializer.StreamSerializer.Framer - streamSerializer := serializer.StreamSerializer.Serializer - encoder := scope.Serializer.EncoderForVersion(streamSerializer, scope.Kind.GroupVersion()) + var encoder runtime.Encoder + if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + encoder = scope.Serializer.EncoderForVersion(runtime.UseNondeterministicEncoding(serializer.StreamSerializer.Serializer), scope.Kind.GroupVersion()) + } else { + encoder = scope.Serializer.EncoderForVersion(serializer.StreamSerializer.Serializer, scope.Kind.GroupVersion()) + } useTextFraming := serializer.EncodesAsText if framer == nil { return nil, fmt.Errorf("no framer defined for %q available for embedded encoding", serializer.MediaType) @@ -98,9 +102,17 @@ func serveWatchHandler(watcher watch.Interface, scope *RequestScope, mediaTypeOp if !ok { return nil, fmt.Errorf("no encoder for %q exists in the requested target %#v", serializer.MediaType, contentSerializer) } - negotiatedEncoder = contentSerializer.EncoderForVersion(info.Serializer, contentKind.GroupVersion()) + if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + negotiatedEncoder = contentSerializer.EncoderForVersion(runtime.UseNondeterministicEncoding(info.Serializer), contentKind.GroupVersion()) + } else { + negotiatedEncoder = contentSerializer.EncoderForVersion(info.Serializer, contentKind.GroupVersion()) + } } else { - negotiatedEncoder = scope.Serializer.EncoderForVersion(serializer.Serializer, contentKind.GroupVersion()) + if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + negotiatedEncoder = scope.Serializer.EncoderForVersion(runtime.UseNondeterministicEncoding(serializer.Serializer), contentKind.GroupVersion()) + } else { + negotiatedEncoder = scope.Serializer.EncoderForVersion(serializer.Serializer, contentKind.GroupVersion()) + } } var memoryAllocator runtime.MemoryAllocator