From 3aa771113215afac10ce652930afd022fc59b175 Mon Sep 17 00:00:00 2001 From: Christian Schlotter Date: Mon, 20 Jan 2025 11:23:34 +0100 Subject: [PATCH] clustercache: Prevent concurrent map read/write when creating a cache --- controllers/clustercache/cluster_accessor_client.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/controllers/clustercache/cluster_accessor_client.go b/controllers/clustercache/cluster_accessor_client.go index 55fe61ca6024..e6e640ef23a2 100644 --- a/controllers/clustercache/cluster_accessor_client.go +++ b/controllers/clustercache/cluster_accessor_client.go @@ -19,6 +19,7 @@ package clustercache import ( "context" "fmt" + "maps" "net/http" "sync" "time" @@ -213,13 +214,19 @@ func createUncachedClient(scheme *runtime.Scheme, config *rest.Config, httpClien // createCachedClient creates a cached client for the given cluster, based on the rest.Config. func createCachedClient(ctx context.Context, clusterAccessorConfig *clusterAccessorConfig, config *rest.Config, httpClient *http.Client, mapper meta.RESTMapper) (client.Client, *stoppableCache, error) { - // Create the cache for the cluster. + // The byObject map needs to be cloned to not hit concurrent read/writes on the Namespaces map. + byObject := maps.Clone(clusterAccessorConfig.Cache.ByObject) + for k, v := range byObject { + v.Namespaces = maps.Clone(v.Namespaces) + byObject[k] = v + } + cacheOptions := cache.Options{ HTTPClient: httpClient, Scheme: clusterAccessorConfig.Scheme, Mapper: mapper, SyncPeriod: clusterAccessorConfig.Cache.SyncPeriod, - ByObject: clusterAccessorConfig.Cache.ByObject, + ByObject: byObject, } remoteCache, err := cache.New(config, cacheOptions) if err != nil {