refactor b2d retrieval for fusion/vbox

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
Evan Hazlett 2015-01-15 13:44:59 -05:00
parent 3212d0c509
commit 090e3328c8
6 changed files with 151 additions and 75 deletions

View File

@ -210,7 +210,7 @@ func cmdCreate(c *cli.Context) {
log.Infof("%q has been created and is now the active machine", name)
// TODO @ehazlett: this will likely change but at least show how to connect for now
log.Infof("To connect, use docker $(machine config %s)", name)
log.Infof("To connect: docker $(machine config %s) ps", name)
}
func cmdConfig(c *cli.Context) {

View File

@ -41,7 +41,7 @@ var (
`sudo mkdir -p /.docker/authorized-keys.d/
sudo chown -R {{ .UserName }} /.docker
while [ -e /var/run/docker.pid ]; do sleep 1; done
sudo curl -L -o /usr/bin/docker https://get.docker.com/builds/Linux/x86_64/docker-latest
sudo curl -s -L -o /usr/bin/docker https://get.docker.com/builds/Linux/x86_64/docker-latest
`))
)

View File

@ -3,12 +3,10 @@ package virtualbox
import (
"archive/tar"
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
@ -20,10 +18,10 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
"github.com/docker/docker/utils"
"github.com/docker/machine/drivers"
"github.com/docker/machine/ssh"
"github.com/docker/machine/state"
"github.com/docker/machine/utils"
)
const (
@ -133,14 +131,13 @@ func (d *Driver) Create() error {
if d.Boot2DockerURL != "" {
isoURL = d.Boot2DockerURL
log.Infof("Downloading boot2docker.iso from %s...", isoURL)
if err := downloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil {
if err := utils.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 = getLatestReleaseURL()
isoURL, err = utils.GetLatestBoot2DockerReleaseURL()
if err != nil {
return err
}
@ -159,7 +156,7 @@ func (d *Driver) Create() error {
}
}
if err := downloadISO(imgPath, "boot2docker.iso", isoURL); err != nil {
if err := utils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil {
return err
}
}
@ -398,13 +395,13 @@ func (d *Driver) Upgrade() error {
return err
}
isoURL, err := getLatestReleaseURL()
isoURL, err := utils.GetLatestBoot2DockerReleaseURL()
if err != nil {
return err
}
log.Infof("Downloading boot2docker...")
if err := downloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil {
if err := utils.DownloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil {
return err
}
@ -445,7 +442,7 @@ func (d *Driver) GetState() (state.State, error) {
func (d *Driver) setMachineNameIfNotSet() {
if d.MachineName == "" {
d.MachineName = fmt.Sprintf("docker-host-%s", utils.GenerateRandomID())
d.MachineName = fmt.Sprintf("docker-machine-unknown")
}
}
@ -534,57 +531,6 @@ func (d *Driver) diskPath() string {
return filepath.Join(d.storePath, "disk.vmdk")
}
// 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 getLatestReleaseURL() (string, error) {
rsp, err := http.Get("https://api.github.com/repos/boot2docker/boot2docker/releases")
if err != nil {
return "", err
}
defer rsp.Body.Close()
var t []struct {
TagName string `json:"tag_name"`
}
if err := json.NewDecoder(rsp.Body).Decode(&t); err != nil {
return "", err
}
if len(t) == 0 {
return "", fmt.Errorf("no releases found")
}
tag := t[0].TagName
url := fmt.Sprintf("https://github.com/boot2docker/boot2docker/releases/download/%s/boot2docker.iso", tag)
return url, nil
}
// Download boot2docker ISO image for the given tag and save it at dest.
func downloadISO(dir, file, url string) error {
rsp, err := http.Get(url)
if err != nil {
return err
}
defer rsp.Body.Close()
// Download to a temp file first then rename it to avoid partial download.
f, err := ioutil.TempFile(dir, file+".tmp")
if err != nil {
return err
}
defer os.Remove(f.Name())
if _, err := io.Copy(f, rsp.Body); err != nil {
// TODO: display download progress?
return err
}
if err := f.Close(); err != nil {
return err
}
if err := os.Rename(f.Name(), filepath.Join(dir, file)); err != nil {
return err
}
return nil
}
// Make a boot2docker VM disk image.
func (d *Driver) generateDiskImage(size int) error {
log.Debugf("Creating %d MB hard disk image...", size)

View File

@ -23,6 +23,7 @@ import (
"github.com/docker/machine/drivers"
"github.com/docker/machine/ssh"
"github.com/docker/machine/state"
"github.com/docker/machine/utils"
cssh "golang.org/x/crypto/ssh"
)
@ -129,16 +130,49 @@ func (d *Driver) GetState() (state.State, error) {
func (d *Driver) Create() error {
var isoURL string
var (
isoURL string
err error
)
if d.Boot2DockerURL != "" {
isoURL = d.Boot2DockerURL
} else {
isoURL = "https://github.com/boot2docker/boot2docker/releases/download/v1.4.1/boot2docker.iso"
}
log.Infof("Downloading boot2docker...")
if err := downloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil {
log.Infof("Downloading boot2docker.iso from %s...", isoURL)
if err := utils.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()
if err != nil {
return err
}
// todo: use real constant for .docker
rootPath := filepath.Join(drivers.GetHomeDir(), ".docker")
imgPath := filepath.Join(rootPath, "images")
commonIsoPath := filepath.Join(imgPath, "boot2docker.iso")
if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) {
log.Infof("Downloading boot2docker.iso to %s...", commonIsoPath)
// just in case boot2docker.iso has been manually deleted
if _, err := os.Stat(imgPath); os.IsNotExist(err) {
if err := os.Mkdir(imgPath, 0700); err != nil {
return err
}
}
if err := utils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil {
return err
}
}
isoDest := filepath.Join(d.storePath, "boot2docker.iso")
if err := utils.CopyFile(commonIsoPath, isoDest); err != nil {
return err
}
}
log.Infof("Creating SSH key...")
if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil {

View File

@ -22,6 +22,7 @@ import (
"github.com/docker/machine/drivers/vmwarevsphere/errors"
"github.com/docker/machine/ssh"
"github.com/docker/machine/state"
"github.com/docker/machine/utils"
cssh "golang.org/x/crypto/ssh"
)
@ -224,16 +225,49 @@ func (d *Driver) Create() error {
return err
}
var isoURL string
var (
isoURL string
err error
)
if d.Boot2DockerURL != "" {
isoURL = d.Boot2DockerURL
} else {
isoURL = "https://github.com/boot2docker/boot2docker/releases/download/v1.4.1/boot2docker.iso"
}
log.Infof("Downloading boot2docker...")
if err := downloadISO(d.storePath, "boot2docker.iso", isoURL); err != nil {
log.Infof("Downloading boot2docker.iso from %s...", isoURL)
if err := utils.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()
if err != nil {
return err
}
// todo: use real constant for .docker
rootPath := filepath.Join(drivers.GetHomeDir(), ".docker")
imgPath := filepath.Join(rootPath, "images")
commonIsoPath := filepath.Join(imgPath, "boot2docker.iso")
if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) {
log.Infof("Downloading boot2docker.iso to %s...", commonIsoPath)
// just in case boot2docker.iso has been manually deleted
if _, err := os.Stat(imgPath); os.IsNotExist(err) {
if err := os.Mkdir(imgPath, 0700); err != nil {
return err
}
}
if err := utils.DownloadISO(imgPath, "boot2docker.iso", isoURL); err != nil {
return err
}
}
isoDest := filepath.Join(d.storePath, "boot2docker.iso")
if err := utils.CopyFile(commonIsoPath, isoDest); err != nil {
return err
}
}
log.Infof("Generating SSH Keypair...")
if err := ssh.GenerateSSHKey(d.sshKeyPath()); err != nil {

62
utils/b2d.go Normal file
View File

@ -0,0 +1,62 @@
package utils
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
)
// 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) {
rsp, err := http.Get("https://api.github.com/repos/boot2docker/boot2docker/releases")
if err != nil {
return "", err
}
defer rsp.Body.Close()
var t []struct {
TagName string `json:"tag_name"`
}
if err := json.NewDecoder(rsp.Body).Decode(&t); err != nil {
return "", err
}
if len(t) == 0 {
return "", fmt.Errorf("no releases found")
}
tag := t[0].TagName
url := fmt.Sprintf("https://github.com/boot2docker/boot2docker/releases/download/%s/boot2docker.iso", tag)
return url, nil
}
// Download boot2docker ISO image for the given tag and save it at dest.
func DownloadISO(dir, file, url string) error {
rsp, err := http.Get(url)
if err != nil {
return err
}
defer rsp.Body.Close()
// Download to a temp file first then rename it to avoid partial download.
f, err := ioutil.TempFile(dir, file+".tmp")
if err != nil {
return err
}
defer os.Remove(f.Name())
if _, err := io.Copy(f, rsp.Body); err != nil {
// TODO: display download progress?
return err
}
if err := f.Close(); err != nil {
return err
}
if err := os.Rename(f.Name(), filepath.Join(dir, file)); err != nil {
return err
}
return nil
}