From 7481c6beb03897a2c6518a616ae33d6d5948ebb1 Mon Sep 17 00:00:00 2001 From: Hidde Beydals Date: Tue, 6 Apr 2021 15:35:09 +0200 Subject: [PATCH] Retry reconcile and clone actions once We have observed that the code at times outperforms GitHub mechanics, resulting in not found errors that are only true for a millisecond. Retrying those actions once with a 2 second delay should be more friendly to users. Signed-off-by: Hidde Beydals --- internal/bootstrap/bootstrap.go | 14 ++++++++++++++ internal/bootstrap/bootstrap_plain_git.go | 16 +++++++++++----- internal/bootstrap/bootstrap_provider.go | 14 +++++++++++--- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index a4025478..bb265a57 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -182,3 +182,17 @@ func kustomizationReconciled(ctx context.Context, kube client.Client, objKey cli return false, nil } } + +func retry(retries int, wait time.Duration, fn func() error) (err error) { + for i := 0; ; i++ { + err = fn() + if err == nil { + return + } + if i >= retries { + break + } + time.Sleep(wait) + } + return err +} diff --git a/internal/bootstrap/bootstrap_plain_git.go b/internal/bootstrap/bootstrap_plain_git.go index 8119e79a..b3ee125e 100644 --- a/internal/bootstrap/bootstrap_plain_git.go +++ b/internal/bootstrap/bootstrap_plain_git.go @@ -104,8 +104,11 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest } b.logger.Actionf("cloning branch %q from Git repository %q", b.branch, b.url) - cloned, err := b.git.Clone(ctx, b.url, b.branch) - if err != nil { + var cloned bool + if err = retry(1, 2*time.Second, func() (err error) { + cloned, err = b.git.Clone(ctx, b.url, b.branch) + return + }); err != nil { return fmt.Errorf("failed to clone repository: %w", err) } if cloned { @@ -216,12 +219,15 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options if _, err := b.git.Status(); err != nil { if err == git.ErrNoGitRepository { b.logger.Actionf("cloning branch %q from Git repository %q", b.branch, b.url) - cloned, err := b.git.Clone(ctx, b.url, b.branch) - if err != nil { + var cloned bool + if err = retry(1, 2*time.Second, func() (err error) { + cloned, err = b.git.Clone(ctx, b.url, b.branch) + return + }); err != nil { return fmt.Errorf("failed to clone repository: %w", err) } if cloned { - b.logger.Successf("cloned repository", b.url) + b.logger.Successf("cloned repository") } } return err diff --git a/internal/bootstrap/bootstrap_provider.go b/internal/bootstrap/bootstrap_provider.go index 34c94410..5a0bdea3 100644 --- a/internal/bootstrap/bootstrap_provider.go +++ b/internal/bootstrap/bootstrap_provider.go @@ -278,11 +278,15 @@ func (b *GitProviderBootstrapper) reconcileOrgRepository(ctx context.Context) (g } b.logger.Successf("repository %q created", repoRef.String()) } + // Set default branch before calling Reconcile due to bug described // above. repoInfo.DefaultBranch = repo.Get().DefaultBranch var changed bool - if repo, changed, err = b.provider.OrgRepositories().Reconcile(ctx, repoRef, repoInfo); err != nil { + if err = retry(1, 2*time.Second, func() (err error) { + repo, changed, err = b.provider.OrgRepositories().Reconcile(ctx, repoRef, repoInfo) + return + }); err != nil { return nil, fmt.Errorf("failed to reconcile Git repository %q: %w", repoRef.String(), err) } if changed { @@ -352,12 +356,16 @@ func (b *GitProviderBootstrapper) reconcileUserRepository(ctx context.Context) ( // above. repoInfo.DefaultBranch = repo.Get().DefaultBranch var changed bool - if repo, changed, err = b.provider.UserRepositories().Reconcile(ctx, repoRef, repoInfo); err != nil { - return nil, err + if err = retry(1, 2*time.Second, func() (err error) { + repo, changed, err = b.provider.UserRepositories().Reconcile(ctx, repoRef, repoInfo) + return + }); err != nil { + return nil, fmt.Errorf("failed to reconcile Git repository %q: %w", repoRef.String(), err) } if changed { b.logger.Successf("repository %q reconciled", repoRef.String()) } + return repo, nil }