Skip to content

Commit

Permalink
use http get to download file from GitHub
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriziopandini committed Aug 25, 2023
1 parent 82eff49 commit 5c057b4
Showing 1 changed file with 57 additions and 8 deletions.
65 changes: 57 additions & 8 deletions cmd/clusterctl/client/repository/repository_github.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (g *gitHubRepository) GetVersions(ctx context.Context) ([]string, error) {
return versions, nil
}

goProxyClient, err := g.getGoproxyClient()
goProxyClient, err := g.getGoproxyClient(ctx)
if err != nil {
return nil, errors.Wrap(err, "get versions client")
}
Expand Down Expand Up @@ -156,6 +156,27 @@ func (g *gitHubRepository) ComponentsPath() string {

// GetFile returns a file for a given provider version.
func (g *gitHubRepository) GetFile(ctx context.Context, version, path string) ([]byte, error) {
log := logf.Log

cacheID := fmt.Sprintf("%s/%s:%s:%s", g.owner, g.repository, version, path)
if content, ok := cacheFiles[cacheID]; ok {
return content, nil
}

// Try to get the file using http get.
// NOTE: this can be disabled by setting GORPOXY to `direct` or `off` (same knobs used for skipping goproxy requests).
if goProxyClient, _ := g.getGoproxyClient(ctx); goProxyClient != nil {
files, err := g.httpGetFilesFromRelease(ctx, version, path)
if err != nil {
log.V(5).Info("error using httpGet to get file from GitHub releases, falling back to github client", "owner", g.owner, "repository", g.repository, "version", version, "path", path, "error", err)
} else {
cacheFiles[cacheID] = files
return files, nil
}
}

// If the http get request failed (or it is disabled) falls back on using the GITHUB api to download the file

release, err := g.getReleaseByTag(ctx, version)
if err != nil {
if errors.Is(err, errNotFound) {
Expand All @@ -172,6 +193,7 @@ func (g *gitHubRepository) GetFile(ctx context.Context, version, path string) ([
return nil, errors.Wrapf(err, "failed to download files from GitHub release %s", version)
}

cacheFiles[cacheID] = files
return files, nil
}

Expand Down Expand Up @@ -259,7 +281,7 @@ func (g *gitHubRepository) getClient() *github.Client {
// getGoproxyClient returns a go proxy client.
// It returns nil, nil if the environment variable is set to `direct` or `off`
// to skip goproxy requests.
func (g *gitHubRepository) getGoproxyClient() (*goproxy.Client, error) {
func (g *gitHubRepository) getGoproxyClient(_ context.Context) (*goproxy.Client, error) {
if g.injectGoproxyClient != nil {
return g.injectGoproxyClient, nil
}
Expand Down Expand Up @@ -379,13 +401,41 @@ func (g *gitHubRepository) getReleaseByTag(ctx context.Context, tag string) (*gi
return release, nil
}

// downloadFilesFromRelease download a file from release.
func (g *gitHubRepository) downloadFilesFromRelease(ctx context.Context, release *github.RepositoryRelease, fileName string) ([]byte, error) {
cacheID := fmt.Sprintf("%s/%s:%s:%s", g.owner, g.repository, *release.TagName, fileName)
if content, ok := cacheFiles[cacheID]; ok {
return content, nil
// httpGetFilesFromRelease gets a file from github using http get.
func (g *gitHubRepository) httpGetFilesFromRelease(ctx context.Context, version, fileName string) ([]byte, error) {
downloadURL := fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/%s", g.owner, g.repository, version, fileName)
var retryError error
var content []byte
_ = wait.PollUntilContextTimeout(ctx, retryableOperationInterval, retryableOperationTimeout, true, func(ctx context.Context) (bool, error) {
resp, err := http.Get(downloadURL) //nolint:gosec,noctx
if err != nil {
retryError = errors.Wrap(err, "error sending request")
return false, nil
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
retryError = errors.Errorf("error getting file, status code: %d", resp.StatusCode)
return false, nil
}

content, err = io.ReadAll(resp.Body)
if err != nil {
retryError = errors.Wrap(err, "error reading response body")
return false, nil
}

retryError = nil
return true, nil
})
if retryError != nil {
return nil, retryError
}
return content, nil
}

// downloadFilesFromRelease download a file from release.
func (g *gitHubRepository) downloadFilesFromRelease(ctx context.Context, release *github.RepositoryRelease, fileName string) ([]byte, error) {
client := g.getClient()
absoluteFileName := filepath.Join(g.rootPath, fileName)

Expand Down Expand Up @@ -439,7 +489,6 @@ func (g *gitHubRepository) downloadFilesFromRelease(ctx context.Context, release
return nil, retryError
}

cacheFiles[cacheID] = content
return content, nil
}

Expand Down

0 comments on commit 5c057b4

Please sign in to comment.