Skip to content

Commit

Permalink
libgit2: Update checkout to respect context
Browse files Browse the repository at this point in the history
Update libgit2-git2go checkout with a clone wrapper to respect the
context passed to it. go-git accepts context passed to it during cloning
but the git2go does not accept the context passed to it. This makes the
GitRepository.Spec.Timeout ineffective when using libgit2.

This change updates all the different libgit2 checkouts to use the new
clone function.

This is also needed to shorten the wait time for tests that depend on
failure behavior and should fail early. TestCheckout_ED25519 test would
take 30s without a context with timeout. This helps shorten the time
for such tests.

Signed-off-by: Sunny <[email protected]>
  • Loading branch information
darkowlzz committed Sep 29, 2021
1 parent e3b2458 commit cc7789e
Showing 1 changed file with 38 additions and 12 deletions.
50 changes: 38 additions & 12 deletions pkg/git/libgit2/checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,34 @@ func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef, opt git.CheckoutOpti
}
}

// clone is a wrapper around git2go.Clone that respects the provided context.
func clone(ctx context.Context, path, url string, auth *git.Auth, opts *git2go.CloneOptions) (*git2go.Repository, error) {
var repo *git2go.Repository
errCh := make(chan error, 1)
go func() {
var err error
repo, err = git2go.Clone(url, path, opts)
errCh <- err
}()

select {
case err := <-errCh:
if err != nil {
return nil, fmt.Errorf("unable to clone '%s', error: %w", url, gitutil.LibGit2Error(err))
}
case <-ctx.Done():
return nil, ctx.Err()
}

return repo, nil
}

type CheckoutBranch struct {
branch string
}

func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
cloneOpts := &git2go.CloneOptions{
FetchOptions: &git2go.FetchOptions{
DownloadTags: git2go.DownloadTagsNone,
RemoteCallbacks: git2go.RemoteCallbacks{
Expand All @@ -67,9 +89,10 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, auth *g
},
},
CheckoutBranch: c.branch,
})
}
repo, err := clone(ctx, path, url, auth, cloneOpts)
if err != nil {
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, gitutil.LibGit2Error(err))
return nil, "", err
}
head, err := repo.Head()
if err != nil {
Expand All @@ -87,17 +110,18 @@ type CheckoutTag struct {
}

func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
cloneOpts := &git2go.CloneOptions{
FetchOptions: &git2go.FetchOptions{
DownloadTags: git2go.DownloadTagsAll,
RemoteCallbacks: git2go.RemoteCallbacks{
CredentialsCallback: auth.CredCallback,
CertificateCheckCallback: auth.CertCallback,
},
},
})
}
repo, err := clone(ctx, path, url, auth, cloneOpts)
if err != nil {
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
return nil, "", err
}
ref, err := repo.References.Dwim(c.tag)
if err != nil {
Expand Down Expand Up @@ -131,7 +155,7 @@ type CheckoutCommit struct {
}

func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
cloneOpts := &git2go.CloneOptions{
FetchOptions: &git2go.FetchOptions{
DownloadTags: git2go.DownloadTagsNone,
RemoteCallbacks: git2go.RemoteCallbacks{
Expand All @@ -140,9 +164,10 @@ func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth *g
},
},
CheckoutBranch: c.branch,
})
}
repo, err := clone(ctx, path, url, auth, cloneOpts)
if err != nil {
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
return nil, "", err
}
oid, err := git2go.NewOid(c.commit)
if err != nil {
Expand Down Expand Up @@ -176,17 +201,18 @@ func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, auth *g
return nil, "", fmt.Errorf("semver parse range error: %w", err)
}

repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
cloneOpts := &git2go.CloneOptions{
FetchOptions: &git2go.FetchOptions{
DownloadTags: git2go.DownloadTagsAll,
RemoteCallbacks: git2go.RemoteCallbacks{
CredentialsCallback: auth.CredCallback,
CertificateCheckCallback: auth.CertCallback,
},
},
})
}
repo, err := clone(ctx, path, url, auth, cloneOpts)
if err != nil {
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
return nil, "", err
}

tags := make(map[string]string)
Expand Down

0 comments on commit cc7789e

Please sign in to comment.