1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-24 07:49:41 +02:00

fix(docker): fix a data race in the Docker transport BE-10873 (#255)

This commit is contained in:
andres-portainer 2024-12-23 09:54:11 -03:00 committed by GitHub
parent eb2a754580
commit ad77cd195c
3 changed files with 60 additions and 53 deletions

View file

@ -11,6 +11,7 @@ import (
"regexp"
"strconv"
"strings"
"sync"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices"
@ -37,6 +38,8 @@ type (
dockerClientFactory *dockerclient.ClientFactory
gitService portainer.GitService
snapshotService portainer.SnapshotService
dockerID string
mu sync.Mutex
}
// TransportParameters is used to create a new Transport
@ -679,9 +682,7 @@ func (transport *Transport) executeGenericResourceDeletionOperation(request *htt
}
if resourceControl != nil {
if err := transport.dataStore.ResourceControl().Delete(resourceControl.ID); err != nil {
return response, err
}
err = transport.dataStore.ResourceControl().Delete(resourceControl.ID)
}
return response, err

View file

@ -14,7 +14,6 @@ import (
"github.com/portainer/portainer/api/internal/snapshot"
"github.com/docker/docker/client"
"github.com/rs/zerolog/log"
)
const volumeObjectIdentifier = "ResourceID"
@ -50,15 +49,6 @@ func (transport *Transport) volumeListOperation(response *http.Response, executo
volumeData := responseObject["Volumes"].([]any)
if transport.snapshotService != nil {
// Filling snapshot data can improve the performance of getVolumeResourceID
if err = transport.snapshotService.FillSnapshotData(transport.endpoint); err != nil {
log.Info().Err(err).
Int("endpoint id", int(transport.endpoint.ID)).
Msg("snapshot is not filled into the endpoint.")
}
}
for _, volumeObject := range volumeData {
volume := volumeObject.(map[string]any)
@ -147,7 +137,7 @@ func (transport *Transport) decorateVolumeResourceCreationOperation(request *htt
}
defer cli.Close()
if _, err = cli.VolumeInspect(context.Background(), volumeID); err == nil {
if _, err := cli.VolumeInspect(context.Background(), volumeID); err == nil {
return &http.Response{
StatusCode: http.StatusConflict,
}, errors.New("a volume with the same name already exists")
@ -222,14 +212,27 @@ func (transport *Transport) getVolumeResourceID(volumeName string) (string, erro
}
func (transport *Transport) getDockerID() (string, error) {
if len(transport.endpoint.Snapshots) > 0 {
dockerID, err := snapshot.FetchDockerID(transport.endpoint.Snapshots[0])
// ignore err - in case of error, just generate not from snapshot
if err == nil {
return dockerID, nil
transport.mu.Lock()
defer transport.mu.Unlock()
// Local cache
if transport.dockerID != "" {
return transport.dockerID, nil
}
// Snapshot cache
if transport.snapshotService != nil {
endpoint := portainer.Endpoint{ID: transport.endpoint.ID}
if err := transport.snapshotService.FillSnapshotData(&endpoint); err == nil {
if dockerID, err := snapshot.FetchDockerID(endpoint.Snapshots[0]); err == nil {
transport.dockerID = dockerID
return dockerID, nil
}
}
}
// Remote value
client, err := transport.dockerClientFactory.CreateClient(transport.endpoint, "", nil)
if err != nil {
return "", err
@ -242,8 +245,11 @@ func (transport *Transport) getDockerID() (string, error) {
}
if info.Swarm.Cluster != nil {
return info.Swarm.Cluster.ID, nil
transport.dockerID = info.Swarm.Cluster.ID
return transport.dockerID, nil
}
return info.ID, nil
transport.dockerID = info.ID
return transport.dockerID, nil
}