diff --git a/drivers/virtualbox/virtualbox.go b/drivers/virtualbox/virtualbox.go index 80f03ff0da..b41bd95fdc 100644 --- a/drivers/virtualbox/virtualbox.go +++ b/drivers/virtualbox/virtualbox.go @@ -132,16 +132,18 @@ func (d *Driver) Create() error { return err } + b2dutils := utils.NewB2dUtils("", "") + if d.Boot2DockerURL != "" { isoURL = d.Boot2DockerURL log.Infof("Downloading boot2docker.iso from %s...", isoURL) - if err := utils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { + if err := b2dutils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { return err } } else { // todo: check latest release URL, download if it's new // until then always use "latest" - isoURL, err = utils.GetLatestBoot2DockerReleaseURL() + isoURL, err = b2dutils.GetLatestBoot2DockerReleaseURL() if err != nil { log.Warnf("Unable to check for the latest release: %s", err) } @@ -160,7 +162,7 @@ func (d *Driver) Create() error { } } - if err := utils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { + if err := b2dutils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { return err } } @@ -399,13 +401,14 @@ func (d *Driver) Upgrade() error { return err } - isoURL, err := utils.GetLatestBoot2DockerReleaseURL() + b2dutils := utils.NewB2dUtils("", "") + isoURL, err := b2dutils.GetLatestBoot2DockerReleaseURL() if err != nil { return err } log.Infof("Downloading boot2docker...") - if err := utils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { + if err := b2dutils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { return err } diff --git a/drivers/vmwarefusion/fusion.go b/drivers/vmwarefusion/fusion.go index 4f327fc18b..fb8c1f72fd 100644 --- a/drivers/vmwarefusion/fusion.go +++ b/drivers/vmwarefusion/fusion.go @@ -140,16 +140,17 @@ func (d *Driver) Create() error { err error ) + b2dutils := utils.NewB2dUtils("", "") if d.Boot2DockerURL != "" { isoURL = d.Boot2DockerURL log.Infof("Downloading boot2docker.iso from %s...", isoURL) - if err := utils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { + if err := b2dutils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { return err } } else { // todo: check latest release URL, download if it's new // until then always use "latest" - isoURL, err = utils.GetLatestBoot2DockerReleaseURL() + isoURL, err = b2dutils.GetLatestBoot2DockerReleaseURL() if err != nil { log.Warnf("Unable to check for the latest release: %s", err) } @@ -168,7 +169,7 @@ func (d *Driver) Create() error { } } - if err := utils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { + if err := b2dutils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { return err } } diff --git a/drivers/vmwarevsphere/vsphere.go b/drivers/vmwarevsphere/vsphere.go index 09000c75d7..8ee064135a 100644 --- a/drivers/vmwarevsphere/vsphere.go +++ b/drivers/vmwarevsphere/vsphere.go @@ -234,16 +234,17 @@ func (d *Driver) Create() error { err error ) + b2dutils := utils.NewB2dUtils("", "") if d.Boot2DockerURL != "" { isoURL = d.Boot2DockerURL log.Infof("Downloading boot2docker.iso from %s...", isoURL) - if err := utils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { + if err := b2dutils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil { return err } } else { // todo: check latest release URL, download if it's new // until then always use "latest" - isoURL, err = utils.GetLatestBoot2DockerReleaseURL() + isoURL, err = b2dutils.GetLatestBoot2DockerReleaseURL() if err != nil { log.Warnf("Unable to check for the latest release: %s", err) } @@ -261,7 +262,7 @@ func (d *Driver) Create() error { } } - if err := utils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { + if err := b2dutils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil { return err } } diff --git a/utils/b2d.go b/utils/b2d.go index b14a932aaa..b18235b870 100644 --- a/utils/b2d.go +++ b/utils/b2d.go @@ -32,12 +32,35 @@ func getClient() *http.Client { return &client } +type B2dUtils struct { + githubApiBaseUrl string + githubBaseUrl string +} + +func NewB2dUtils(githubApiBaseUrl, githubBaseUrl string) *B2dUtils { + defaultBaseApiUrl := "https://api.github.com" + defaultBaseUrl := "https://github.com" + + if githubApiBaseUrl == "" { + githubApiBaseUrl = defaultBaseApiUrl + } + + if githubBaseUrl == "" { + githubBaseUrl = defaultBaseUrl + } + + return &B2dUtils{ + githubApiBaseUrl: githubApiBaseUrl, + githubBaseUrl: githubBaseUrl, + } +} + // Get the latest boot2docker release tag name (e.g. "v0.6.0"). // FIXME: find or create some other way to get the "latest release" of boot2docker since the GitHub API has a pretty low rate limit on API requests -func GetLatestBoot2DockerReleaseURL() (string, error) { +func (b *B2dUtils) GetLatestBoot2DockerReleaseURL() (string, error) { client := getClient() - - rsp, err := client.Get("https://api.github.com/repos/boot2docker/boot2docker/releases") + apiUrl := fmt.Sprintf("%s/repos/boot2docker/boot2docker/releases", b.githubApiBaseUrl) + rsp, err := client.Get(apiUrl) if err != nil { return "", err } @@ -54,14 +77,13 @@ func GetLatestBoot2DockerReleaseURL() (string, error) { } tag := t[0].TagName - url := fmt.Sprintf("https://github.com/boot2docker/boot2docker/releases/download/%s/boot2docker.iso", tag) - return url, nil + isoUrl := fmt.Sprintf("%s/boot2docker/boot2docker/releases/download/%s/boot2docker.iso", b.githubBaseUrl, tag) + return isoUrl, nil } // Download boot2docker ISO image for the given tag and save it at dest. -func DownloadISO(dir, file, url string) error { +func (b *B2dUtils) DownloadISO(dir, file, url string) error { client := getClient() - rsp, err := client.Get(url) if err != nil { return err diff --git a/utils/b2d_test.go b/utils/b2d_test.go index d4b585bf78..2fe5a38103 100644 --- a/utils/b2d_test.go +++ b/utils/b2d_test.go @@ -1 +1,58 @@ package utils + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "path/filepath" + "testing" +) + +func TestGetLatestBoot2DockerReleaseUrl(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + respText := `[{"tag_name": "0.1"}]` + w.Write([]byte(respText)) + })) + defer ts.Close() + + b := NewB2dUtils(ts.URL, ts.URL) + isoUrl, err := b.GetLatestBoot2DockerReleaseURL() + if err != nil { + t.Fatal(err) + } + + expectedUrl := fmt.Sprintf("%s/boot2docker/boot2docker/releases/download/0.1/boot2docker.iso", ts.URL) + if isoUrl != expectedUrl { + t.Fatalf("expected url %s; received %s", isoUrl) + } +} + +func TestDownloadIso(t *testing.T) { + testData := "test-download" + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(testData)) + })) + defer ts.Close() + + filename := "test" + + tmpDir, err := ioutil.TempDir("", "machine-test-") + if err != nil { + t.Fatal(err) + } + + b := NewB2dUtils(ts.URL, ts.URL) + if err := b.DownloadISO(tmpDir, filename, ts.URL); err != nil { + t.Fatal(err) + } + + data, err := ioutil.ReadFile(filepath.Join(tmpDir, filename)) + if err != nil { + t.Fatal(err) + } + + if string(data) != testData { + t.Fatalf("expected data \"%s\"; received \"%s\"", testData, string(data)) + } +}