From 6124ad9da46bf2e65395797df449f802b979d8ee Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 6 Mar 2026 16:55:48 -0800 Subject: [PATCH] kubernetes: lazily initialize kubeclient scheme Use sync.OnceValue to initialize the kubeclient scheme, codec factory, and parameter codec as a single lazy-loaded bundle. Signed-off-by: Tonis Tiigi --- driver/kubernetes/execconn/execconn.go | 2 +- driver/kubernetes/kubeclient/client.go | 12 ++++---- driver/kubernetes/kubeclient/scheme.go | 39 ++++++++++++++++++++------ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/driver/kubernetes/execconn/execconn.go b/driver/kubernetes/execconn/execconn.go index 6592fb05c..1814494a0 100644 --- a/driver/kubernetes/execconn/execconn.go +++ b/driver/kubernetes/execconn/execconn.go @@ -29,7 +29,7 @@ func ExecConn(ctx context.Context, restClient rest.Interface, restConfig *rest.C Stdout: true, Stderr: true, TTY: false, - }, kubeclient.ParameterCodec) + }, kubeclient.ParameterCodec()) exec, err := remotecommand.NewSPDYExecutor(restConfig, "POST", req.URL()) if err != nil { return nil, err diff --git a/driver/kubernetes/kubeclient/client.go b/driver/kubernetes/kubeclient/client.go index 53e553b7f..83e176865 100644 --- a/driver/kubernetes/kubeclient/client.go +++ b/driver/kubernetes/kubeclient/client.go @@ -61,7 +61,7 @@ func newRESTClient(config *rest.Config, httpClient *http.Client, gv schema.Group cfg := *config cfg.GroupVersion = &gv cfg.APIPath = apiPath - cfg.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(Scheme, Codecs).WithoutConversion() + cfg.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(Scheme(), Codecs()).WithoutConversion() if cfg.UserAgent == "" { cfg.UserAgent = rest.DefaultKubernetesUserAgent() } @@ -80,7 +80,7 @@ func (c *deploymentClient) Get(ctx context.Context, name string, opts metav1.Get Namespace(c.namespace). Resource("deployments"). Name(name). - VersionedParams(&opts, ParameterCodec). + VersionedParams(&opts, ParameterCodec()). Do(ctx). Into(result) return result, err @@ -92,7 +92,7 @@ func (c *deploymentClient) Create(ctx context.Context, deployment *appsv1.Deploy UseProtobufAsDefault(). Namespace(c.namespace). Resource("deployments"). - VersionedParams(&opts, ParameterCodec). + VersionedParams(&opts, ParameterCodec()). Body(deployment). Do(ctx). Into(result) @@ -121,7 +121,7 @@ func (c *configMapClient) Create(ctx context.Context, configMap *corev1.ConfigMa UseProtobufAsDefault(). Namespace(c.namespace). Resource("configmaps"). - VersionedParams(&opts, ParameterCodec). + VersionedParams(&opts, ParameterCodec()). Body(configMap). Do(ctx). Into(result) @@ -135,7 +135,7 @@ func (c *configMapClient) Update(ctx context.Context, configMap *corev1.ConfigMa Namespace(c.namespace). Resource("configmaps"). Name(configMap.Name). - VersionedParams(&opts, ParameterCodec). + VersionedParams(&opts, ParameterCodec()). Body(configMap). Do(ctx). Into(result) @@ -164,7 +164,7 @@ func (c *podClient) List(ctx context.Context, opts metav1.ListOptions) (*corev1. UseProtobufAsDefault(). Namespace(c.namespace). Resource("pods"). - VersionedParams(&opts, ParameterCodec). + VersionedParams(&opts, ParameterCodec()). Do(ctx). Into(result) return result, err diff --git a/driver/kubernetes/kubeclient/scheme.go b/driver/kubernetes/kubeclient/scheme.go index c24925352..ebeaf7a13 100644 --- a/driver/kubernetes/kubeclient/scheme.go +++ b/driver/kubernetes/kubeclient/scheme.go @@ -1,6 +1,8 @@ package kubeclient import ( + "sync" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -10,12 +12,33 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" ) -var Scheme = runtime.NewScheme() -var Codecs = serializer.NewCodecFactory(Scheme) -var ParameterCodec = runtime.NewParameterCodec(Scheme) - -func init() { - metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) - utilruntime.Must(corev1.AddToScheme(Scheme)) - utilruntime.Must(appsv1.AddToScheme(Scheme)) +type schemeData struct { + scheme *runtime.Scheme + codecs serializer.CodecFactory + parameterCodec runtime.ParameterCodec +} + +var loadSchemeData = sync.OnceValue(func() schemeData { + s := runtime.NewScheme() + metav1.AddToGroupVersion(s, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(corev1.AddToScheme(s)) + utilruntime.Must(appsv1.AddToScheme(s)) + + return schemeData{ + scheme: s, + codecs: serializer.NewCodecFactory(s), + parameterCodec: runtime.NewParameterCodec(s), + } +}) + +func Scheme() *runtime.Scheme { + return loadSchemeData().scheme +} + +func Codecs() serializer.CodecFactory { + return loadSchemeData().codecs +} + +func ParameterCodec() runtime.ParameterCodec { + return loadSchemeData().parameterCodec }