1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-19 21:39:40 +02:00

fix(edgestacks): check the version of the edge stack before updating the status BE-11488 (#287)

This commit is contained in:
andres-portainer 2025-01-07 17:31:57 -03:00 committed by GitHub
parent d72b3a9ba2
commit e2b812a611
3 changed files with 17 additions and 2 deletions

View file

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strconv"
"time" "time"
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
@ -20,6 +21,7 @@ type updateStatusPayload struct {
Status *portainer.EdgeStackStatusType Status *portainer.EdgeStackStatusType
EndpointID portainer.EndpointID EndpointID portainer.EndpointID
Time int64 Time int64
Version int
} }
func (payload *updateStatusPayload) Validate(r *http.Request) error { func (payload *updateStatusPayload) Validate(r *http.Request) error {
@ -69,6 +71,10 @@ func (handler *Handler) edgeStackStatusUpdate(w http.ResponseWriter, r *http.Req
var stack *portainer.EdgeStack var stack *portainer.EdgeStack
if err := handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { if err := handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
if r.Context().Err() != nil {
return err
}
stack, err = handler.updateEdgeStackStatus(tx, r, portainer.EdgeStackID(stackID), payload) stack, err = handler.updateEdgeStackStatus(tx, r, portainer.EdgeStackID(stackID), payload)
return err return err
}); err != nil { }); err != nil {
@ -80,6 +86,10 @@ func (handler *Handler) edgeStackStatusUpdate(w http.ResponseWriter, r *http.Req
return httperror.InternalServerError("Unexpected error", err) return httperror.InternalServerError("Unexpected error", err)
} }
if ok, _ := strconv.ParseBool(r.Header.Get("X-Portainer-No-Body")); ok {
return nil
}
return response.JSON(w, stack) return response.JSON(w, stack)
} }
@ -87,18 +97,23 @@ func (handler *Handler) updateEdgeStackStatus(tx dataservices.DataStoreTx, r *ht
stack, err := tx.EdgeStack().EdgeStack(stackID) stack, err := tx.EdgeStack().EdgeStack(stackID)
if err != nil { if err != nil {
if dataservices.IsErrObjectNotFound(err) { if dataservices.IsErrObjectNotFound(err) {
// skip error because agent tries to report on deleted stack // Skip error because agent tries to report on deleted stack
log.Debug(). log.Debug().
Err(err). Err(err).
Int("stackID", int(stackID)). Int("stackID", int(stackID)).
Int("status", int(*payload.Status)). Int("status", int(*payload.Status)).
Msg("Unable to find a stack inside the database, skipping error") Msg("Unable to find a stack inside the database, skipping error")
return nil, nil return nil, nil
} }
return nil, fmt.Errorf("unable to retrieve Edge stack from the database: %w. Environment ID: %d", err, payload.EndpointID) return nil, fmt.Errorf("unable to retrieve Edge stack from the database: %w. Environment ID: %d", err, payload.EndpointID)
} }
if payload.Version > 0 && payload.Version < stack.Version {
return stack, nil
}
endpoint, err := tx.Endpoint().Endpoint(payload.EndpointID) endpoint, err := tx.Endpoint().Endpoint(payload.EndpointID)
if err != nil { if err != nil {
return nil, handler.handlerDBErr(fmt.Errorf("unable to find the environment from the database: %w. Environment ID: %d", err, payload.EndpointID), "unable to find the environment") return nil, handler.handlerDBErr(fmt.Errorf("unable to find the environment from the database: %w. Environment ID: %d", err, payload.EndpointID), "unable to find the environment")

View file

@ -9,7 +9,6 @@ func NewStatus(oldStatus map[portainer.EndpointID]portainer.EdgeStackStatus, rel
status := map[portainer.EndpointID]portainer.EdgeStackStatus{} status := map[portainer.EndpointID]portainer.EdgeStackStatus{}
for _, environmentID := range relatedEnvironmentIDs { for _, environmentID := range relatedEnvironmentIDs {
newEnvStatus := portainer.EdgeStackStatus{ newEnvStatus := portainer.EdgeStackStatus{
Status: []portainer.EdgeStackDeploymentStatus{}, Status: []portainer.EdgeStackDeploymentStatus{},
EndpointID: environmentID, EndpointID: environmentID,

View file

@ -370,6 +370,7 @@ type (
Error string Error string
// EE only feature // EE only feature
RollbackTo *int RollbackTo *int
Version int `json:"Version,omitempty"`
} }
// EdgeStackStatusType represents an edge stack status type // EdgeStackStatusType represents an edge stack status type