package plugin import ( "os" "strings" "time" "github.com/cenkalti/backoff/v4" "github.com/rs/zerolog/log" "github.com/thegeeklab/wp-plugin-go/trace" "golang.org/x/sys/execabs" ) // shouldRetry returns true if the command should be re-executed. Currently // this only returns true if the remote ref does not exist. func shouldRetry(s string) bool { return strings.Contains(s, "find remote ref") } func newBackoff(maxRetries uint64) backoff.BackOff { b := backoff.NewExponentialBackOff() b.InitialInterval = daemonBackoffInitialInterval b.Multiplier = daemonBackoffMultiplier return backoff.WithMaxRetries(b, maxRetries) } func retryCmd(cmd *execabs.Cmd) error { backoffOps := func() error { // copy the original command //nolint:gosec retry := execabs.Command(cmd.Args[0], cmd.Args[1:]...) retry.Dir = cmd.Dir retry.Env = cmd.Env retry.Stdout = os.Stdout retry.Stderr = os.Stderr trace.Cmd(cmd) return cmd.Run() } backoffLog := func(err error, delay time.Duration) { log.Error().Msgf("failed to find remote ref: %v: retry in %s", err, delay.Truncate(time.Second)) } return backoff.RetryNotify(backoffOps, newBackoff(daemonBackoffMaxRetries), backoffLog) }