constellation/internal/helm/retryaction.go
Moritz Sanft 968cdc1a38
cli: move cli/internal libraries (#2623)
* cli: move internal packages

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* cli: fix buildfiles

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* bazel: fix exclude dir

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* cli: move back libraries that will not be used by TF provider

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

---------

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>
2023-11-22 14:52:56 +01:00

72 lines
1.7 KiB
Go

/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package helm
import (
"context"
"fmt"
"time"
"github.com/edgelesssys/constellation/v2/internal/retry"
)
const (
// maximumRetryAttempts is the maximum number of attempts to retry a helm install.
maximumRetryAttempts = 3
)
type retrieableApplier interface {
apply(context.Context) error
ReleaseName() string
IsAtomic() bool
}
// retryApply retries the given retriable action.
func retryApply(ctx context.Context, action retrieableApplier, retryInterval time.Duration, log debugLog) error {
var retries int
retriable := func(err error) bool {
// abort after maximumRetryAttempts tries.
if retries >= maximumRetryAttempts {
return false
}
retries++
// only retry if atomic is set
// otherwise helm doesn't uninstall the release on failure
return action.IsAtomic()
}
doer := applyDoer{
applier: action,
log: log,
}
retrier := retry.NewIntervalRetrier(doer, retryInterval, retriable)
retryLoopStartTime := time.Now()
if err := retrier.Do(ctx); err != nil {
return fmt.Errorf("helm install: %w", err)
}
retryLoopFinishDuration := time.Since(retryLoopStartTime)
log.Debugf("Helm chart %q installation finished after %s", action.ReleaseName(), retryLoopFinishDuration)
return nil
}
// applyDoer is a helper struct to enable retrying helm actions.
type applyDoer struct {
applier retrieableApplier
log debugLog
}
// Do tries to apply the action.
func (i applyDoer) Do(ctx context.Context) error {
i.log.Debugf("Trying to apply Helm chart %s", i.applier.ReleaseName())
if err := i.applier.apply(ctx); err != nil {
i.log.Debugf("Helm chart installation %s failed: %v", i.applier.ReleaseName(), err)
return err
}
return nil
}