Skip to content

Commit 997e8f2

Browse files
committed
Add handling for multiple urls in fetch
* change Download struct to list of urls * add URLs to Fetch struct * add new handler for Fetch Type "download_list" in Fetcher * Type "download" and "default" will use list with single url * Fetch will iterate through the urls and try them one by one until one is successful
1 parent 3b369d9 commit 997e8f2

File tree

2 files changed

+56
-28
lines changed

2 files changed

+56
-28
lines changed

internal/fetch/download.go

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,42 +17,65 @@ import (
1717

1818
// Download handles direct binary releases
1919
type Download struct {
20-
url string
20+
urls []string
2121
}
2222

2323
// Fetch gets the package and returns location of downloaded file
2424
func (d Download) Fetch(ctx context.Context, dist, v string, mapper mapping.Mapper) (string, error) {
2525
logger := zerolog.Ctx(ctx).With().Str("func", "GithubRelease.Get").Logger()
2626

27-
args := tpl.New(v, mapper)
28-
29-
url, err := args.Render(d.url)
30-
if err != nil {
31-
return "", err
32-
}
33-
34-
logger.Debug().Msgf("fetching version %q for arch %q and OS %q at %s", v, runtime.GOARCH, runtime.GOOS, url)
35-
36-
req, err := http.NewRequest("GET", url, nil)
37-
if err != nil {
38-
return "", err
39-
}
40-
41-
resp, err := http.DefaultClient.Do(req)
42-
if err != nil {
43-
return "", err
44-
}
45-
defer resp.Body.Close()
46-
47-
if resp.StatusCode != http.StatusOK {
48-
return "", fmt.Errorf("unable to download binary at %s: %s", url, resp.Status)
27+
var resp *http.Response
28+
29+
for i, u := range d.urls {
30+
31+
args := tpl.New(v, mapper)
32+
33+
url, err := args.Render(u)
34+
if err != nil {
35+
if len(d.urls)-1 > i {
36+
continue
37+
} else {
38+
return "", err
39+
}
40+
}
41+
42+
logger.Debug().Msgf("fetching version %q for arch %q and OS %q at %s", v, runtime.GOARCH, runtime.GOOS, url)
43+
44+
req, err := http.NewRequest("GET", url, nil)
45+
if err != nil {
46+
if len(d.urls)-1 > i {
47+
continue
48+
} else {
49+
return "", err
50+
}
51+
}
52+
53+
resp, err = http.DefaultClient.Do(req)
54+
if err != nil {
55+
if len(d.urls)-1 > i {
56+
continue
57+
} else {
58+
return "", err
59+
}
60+
}
61+
defer resp.Body.Close()
62+
63+
if resp.StatusCode != http.StatusOK {
64+
if len(d.urls)-1 > i {
65+
logger.Debug().Msgf("unable to download binary at %s: %s, %d urls left to try...", url, resp.Status, len(d.urls)-1-i)
66+
continue
67+
} else {
68+
return "", fmt.Errorf("unable to download binary at %s: %s", url, resp.Status)
69+
}
70+
}
71+
// if we reach this point, download was successful, let's move on
72+
break
4973
}
5074

5175
tmpfile, err := ioutil.TempFile("", v)
5276
if err != nil {
5377
logger.Fatal().Err(err)
5478
}
55-
5679
defer tmpfile.Close()
5780

5881
bar := progressbar.DefaultBytes(

internal/fetch/fetch.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,25 @@ type Fetcher interface {
1414

1515
// Fetch contains fetch configuration
1616
type Fetch struct {
17-
Type string `yaml:"type"`
18-
URL string `yaml:"url"`
17+
Type string `yaml:"type"`
18+
URL string `yaml:"url"`
19+
URLs []string `yaml:"urls"`
1920
}
2021

2122
// Factory returns instances that comply to Fecther interface
2223
func (r Fetch) Factory() Fetcher {
2324
switch r.Type {
2425
case "download":
2526
return Download{
26-
url: r.URL,
27+
urls: []string{r.URL},
28+
}
29+
case "download_list":
30+
return Download{
31+
urls: r.URLs,
2732
}
2833
default:
2934
return Download{
30-
url: r.URL,
35+
urls: []string{r.URL},
3136
}
3237
}
3338
}

0 commit comments

Comments
 (0)