From 2443a0f568c35215ac9886f96e0fd65d50cb9245 Mon Sep 17 00:00:00 2001 From: andres-portainer <91705312+andres-portainer@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:19:28 -0300 Subject: [PATCH] fix(kubernetes): avoid a deadlock EE-6901 (#11447) --- api/kubernetes/cli/client.go | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/api/kubernetes/cli/client.go b/api/kubernetes/cli/client.go index 9ce5366c7..70c114e54 100644 --- a/api/kubernetes/cli/client.go +++ b/api/kubernetes/cli/client.go @@ -81,21 +81,30 @@ func (factory *ClientFactory) RemoveKubeClient(endpointID portainer.EndpointID) // If no client is registered, it will create a new client, register it, and returns it. func (factory *ClientFactory) GetKubeClient(endpoint *portainer.Endpoint) (*KubeClient, error) { factory.mu.Lock() - defer factory.mu.Unlock() - key := strconv.Itoa(int(endpoint.ID)) - client, ok := factory.endpointClients[key] - if !ok { - var err error + if client, ok := factory.endpointClients[key]; ok { + factory.mu.Unlock() + return client, nil + } + factory.mu.Unlock() - client, err = factory.createCachedAdminKubeClient(endpoint) - if err != nil { - return nil, err - } + // EE-6901: Do not lock + client, err := factory.createCachedAdminKubeClient(endpoint) + if err != nil { + return nil, err + } - factory.endpointClients[key] = client + factory.mu.Lock() + defer factory.mu.Unlock() + + // The lock was released before the client was created, + // so we need to check again + if c, ok := factory.endpointClients[key]; ok { + return c, nil } + factory.endpointClients[key] = client + return client, nil }