fix(gitops): add singleflight behavior to RedeployWhenChanged calls EE-6377 (#10734)

pull/11002/head
andres-portainer 2024-01-22 19:41:48 -03:00 committed by GitHub
parent 77c38306b2
commit 85ae705833
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 2 deletions

View File

@ -3,6 +3,7 @@ package deployments
import (
"crypto/tls"
"fmt"
"strconv"
"time"
portainer "github.com/portainer/portainer/api"
@ -16,6 +17,7 @@ import (
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"golang.org/x/sync/singleflight"
)
type StackAuthorMissingErr struct {
@ -27,11 +29,11 @@ func (e *StackAuthorMissingErr) Error() string {
return fmt.Sprintf("stack's %v author %s is missing", e.stackID, e.authorName)
}
var singleflightGroup = &singleflight.Group{}
// RedeployWhenChanged pull and redeploy the stack when git repo changed
// Stack will always be redeployed if force deployment is set to true
func RedeployWhenChanged(stackID portainer.StackID, deployer StackDeployer, datastore dataservices.DataStore, gitService portainer.GitService) error {
log.Debug().Int("stack_id", int(stackID)).Msg("redeploying stack")
stack, err := datastore.Stack().Read(stackID)
if dataservices.IsErrObjectNotFound(err) {
return scheduler.NewPermanentError(errors.WithMessagef(err, "failed to get the stack %v", stackID))
@ -39,6 +41,24 @@ func RedeployWhenChanged(stackID portainer.StackID, deployer StackDeployer, data
return errors.WithMessagef(err, "failed to get the stack %v", stackID)
}
// Webhook
if stack.AutoUpdate != nil && stack.AutoUpdate.Webhook != "" {
return redeployWhenChanged(stack, deployer, datastore, gitService)
}
// Polling
_, err, _ = singleflightGroup.Do(strconv.Itoa(int(stackID)), func() (any, error) {
return nil, redeployWhenChanged(stack, deployer, datastore, gitService)
})
return err
}
func redeployWhenChanged(stack *portainer.Stack, deployer StackDeployer, datastore dataservices.DataStore, gitService portainer.GitService) error {
stackID := stack.ID
log.Debug().Int("stack_id", int(stackID)).Msg("redeploying stack")
if stack.GitConfig == nil {
return nil // do nothing if it isn't a git-based stack
}