mirror of https://github.com/portainer/portainer
fix(gitops): add singleflight behavior to RedeployWhenChanged calls EE-6377 (#10734)
parent
77c38306b2
commit
85ae705833
|
@ -3,6 +3,7 @@ package deployments
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
portainer "github.com/portainer/portainer/api"
|
portainer "github.com/portainer/portainer/api"
|
||||||
|
@ -16,6 +17,7 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"golang.org/x/sync/singleflight"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StackAuthorMissingErr struct {
|
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)
|
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
|
// RedeployWhenChanged pull and redeploy the stack when git repo changed
|
||||||
// Stack will always be redeployed if force deployment is set to true
|
// 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 {
|
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)
|
stack, err := datastore.Stack().Read(stackID)
|
||||||
if dataservices.IsErrObjectNotFound(err) {
|
if dataservices.IsErrObjectNotFound(err) {
|
||||||
return scheduler.NewPermanentError(errors.WithMessagef(err, "failed to get the stack %v", stackID))
|
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)
|
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 {
|
if stack.GitConfig == nil {
|
||||||
return nil // do nothing if it isn't a git-based stack
|
return nil // do nothing if it isn't a git-based stack
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue