fix(platform): fix a data race in GetPlatform() BE-11522 (#253)

pull/12455/head
andres-portainer 2024-12-19 09:37:50 -03:00 committed by GitHub
parent 1c62bd6ca5
commit 8d1c90f912
1 changed files with 37 additions and 26 deletions

View File

@ -5,10 +5,12 @@ import (
"fmt"
"slices"
"strings"
"sync"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices"
"github.com/portainer/portainer/api/internal/endpointutils"
"github.com/rs/zerolog/log"
)
@ -21,38 +23,46 @@ type service struct {
dataStore dataservices.DataStore
environment *portainer.Endpoint
platform ContainerPlatform
mu sync.Mutex
}
func NewService(dataStore dataservices.DataStore) (Service, error) {
func NewService(dataStore dataservices.DataStore) (*service, error) {
return &service{dataStore: dataStore}, nil
}
return &service{
dataStore: dataStore,
}, nil
func (service *service) loadEnvAndPlatform() error {
if service.environment != nil {
return nil
}
environment, platform, err := guessLocalEnvironment(service.dataStore)
if err != nil {
return err
}
service.environment = environment
service.platform = platform
return nil
}
func (service *service) GetLocalEnvironment() (*portainer.Endpoint, error) {
if service.environment == nil {
environment, platform, err := guessLocalEnvironment(service.dataStore)
if err != nil {
return nil, err
}
service.mu.Lock()
defer service.mu.Unlock()
service.environment = environment
service.platform = platform
if err := service.loadEnvAndPlatform(); err != nil {
return nil, err
}
return service.environment, nil
}
func (service *service) GetPlatform() (ContainerPlatform, error) {
if service.environment == nil {
environment, platform, err := guessLocalEnvironment(service.dataStore)
if err != nil {
return "", err
}
service.mu.Lock()
defer service.mu.Unlock()
service.environment = environment
service.platform = platform
if err := service.loadEnvAndPlatform(); err != nil {
return "", err
}
return service.platform, nil
@ -90,15 +100,16 @@ func guessLocalEnvironment(dataStore dataservices.DataStore) (*portainer.Endpoin
}
for _, endpoint := range endpoints {
if slices.Contains(endpointTypes, endpoint.Type) {
if platform != PlatformDocker {
return &endpoint, platform, nil
}
if !slices.Contains(endpointTypes, endpoint.Type) {
continue
}
dockerPlatform := checkDockerEnvTypeForUpgrade(&endpoint)
if dockerPlatform != "" {
return &endpoint, dockerPlatform, nil
}
if platform != PlatformDocker {
return &endpoint, platform, nil
}
if dockerPlatform := checkDockerEnvTypeForUpgrade(&endpoint); dockerPlatform != "" {
return &endpoint, dockerPlatform, nil
}
}