Skip to content

Commit

Permalink
Merge pull request docker#2618 from dgageot/2189-update-b2d-cache-in-…
Browse files Browse the repository at this point in the history
…precreatecheck

Update b2d cache in PreCreateCheck
  • Loading branch information
nathanleclaire committed Dec 19, 2015
2 parents ecfe9a1 + a7bd9e0 commit 204af9f
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 65 deletions.
23 changes: 17 additions & 6 deletions drivers/hyperv/hyperv.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (

type Driver struct {
*drivers.BaseDriver
boot2DockerURL string
Boot2DockerURL string
boot2DockerLoc string
vSwitch string
diskImage string
Expand Down Expand Up @@ -73,7 +73,7 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag {
}

func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error {
d.boot2DockerURL = flags.String("hyperv-boot2docker-url")
d.Boot2DockerURL = flags.String("hyperv-boot2docker-url")
d.boot2DockerLoc = flags.String("hyperv-boot2docker-location")
d.vSwitch = flags.String("hyperv-virtual-switch")
d.DiskSize = flags.Int("hyperv-disk-size")
Expand Down Expand Up @@ -139,16 +139,27 @@ func (d *Driver) GetState() (state.State, error) {
return state.None, nil
}

func (d *Driver) Create() error {
err := hypervAvailable()
if err != nil {
// PreCreateCheck checks that the machine creation process can be started safely.
func (d *Driver) PreCreateCheck() error {
if err := hypervAvailable(); err != nil {
return err
}

// Downloading boot2docker to cache should be done here to make sure
// that a download failure will not leave a machine half created.
b2dutils := mcnutils.NewB2dUtils(d.StorePath)
if err := b2dutils.UpdateISOCache(d.Boot2DockerURL); err != nil {
return err
}

return nil
}

func (d *Driver) Create() error {
d.setMachineNameIfNotSet()

b2dutils := mcnutils.NewB2dUtils(d.StorePath)
if err := b2dutils.CopyIsoToMachineDir(d.boot2DockerURL, d.MachineName); err != nil {
if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil {
return err
}

Expand Down
7 changes: 7 additions & 0 deletions drivers/virtualbox/virtualbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,13 @@ func (d *Driver) PreCreateCheck() error {
log.Warn("This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory.")
}

// Downloading boot2docker to cache should be done here to make sure
// that a download failure will not leave a machine half created.
b2dutils := mcnutils.NewB2dUtils(d.StorePath)
if err := b2dutils.UpdateISOCache(d.Boot2DockerURL); err != nil {
return err
}

return nil
}

Expand Down
13 changes: 12 additions & 1 deletion drivers/vmwarefusion/fusion_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,18 @@ func (d *Driver) GetState() (state.State, error) {
return state.Stopped, nil
}

// PreCreateCheck checks that the machine creation process can be started safely.
func (d *Driver) PreCreateCheck() error {
// Downloading boot2docker to cache should be done here to make sure
// that a download failure will not leave a machine half created.
b2dutils := mcnutils.NewB2dUtils(d.StorePath)
if err := b2dutils.UpdateISOCache(d.Boot2DockerURL); err != nil {
return err
}

return nil
}

func (d *Driver) Create() error {
b2dutils := mcnutils.NewB2dUtils(d.StorePath)
if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil {
Expand All @@ -214,7 +226,6 @@ func (d *Driver) Create() error {

// download cloud-init config drive
if d.ConfigDriveURL != "" {
log.Infof("Downloading %s from %s", isoConfigDrive, d.ConfigDriveURL)
if err := b2dutils.DownloadISO(d.ResolveStorePath("."), isoConfigDrive, d.ConfigDriveURL); err != nil {
return err
}
Expand Down
20 changes: 16 additions & 4 deletions drivers/vmwarevsphere/vsphere.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,28 @@ func (d *Driver) GetState() (state.State, error) {
return state.None, nil
}

// PreCreateCheck checks that the machine creation process can be started safely.
func (d *Driver) PreCreateCheck() error {
if err := d.checkVsphereConfig(); err != nil {
return err
}

// Downloading boot2docker to cache should be done here to make sure
// that a download failure will not leave a machine half created.
b2dutils := mcnutils.NewB2dUtils(d.StorePath)
if err := b2dutils.UpdateISOCache(d.Boot2DockerURL); err != nil {
return err
}

return nil
}

// Create has the following implementation:
// 1. check whether the docker directory contains the boot2docker ISO
// 2. generate an SSH keypair and bundle it in a tar.
// 3. create a virtual machine with the boot2docker ISO mounted;
// 4. reconfigure the virtual machine network and disk size;
func (d *Driver) Create() error {
if err := d.checkVsphereConfig(); err != nil {
return err
}

b2dutils := mcnutils.NewB2dUtils(d.StorePath)
if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil {
return err
Expand Down
85 changes: 34 additions & 51 deletions libmachine/mcnutils/b2d.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,9 @@ func getClient() *http.Client {
Dial: defaultTimeout,
}

client := http.Client{
return &http.Client{
Transport: &transport,
}

return &client
}

func getRequest(apiURL string) (*http.Request, error) {
Expand Down Expand Up @@ -204,11 +202,7 @@ func (*b2dReleaseGetter) download(dir, file, isoURL string) error {
return err
}

if err := os.Rename(f.Name(), dest); err != nil {
return err
}

return nil
return os.Rename(f.Name(), dest)
}

// iso is an ISO volume.
Expand Down Expand Up @@ -305,6 +299,7 @@ func NewB2dUtils(storePath string) *B2dUtils {

// DownloadISO downloads boot2docker ISO image for the given tag and save it at dest.
func (b *B2dUtils) DownloadISO(dir, file, isoURL string) error {
log.Infof("Downloading %s from %s...", b.path(), isoURL)
return b.download(dir, file, isoURL)
}

Expand Down Expand Up @@ -351,72 +346,60 @@ func (b *B2dUtils) DownloadLatestBoot2Docker(apiURL string) error {
}

func (b *B2dUtils) DownloadISOFromURL(latestReleaseURL string) error {
log.Infof("Downloading %s to %s...", latestReleaseURL, b.path())
if err := b.DownloadISO(b.imgCachePath, b.filename(), latestReleaseURL); err != nil {
return err
}

return nil
return b.DownloadISO(b.imgCachePath, b.filename(), latestReleaseURL)
}

func (b *B2dUtils) CopyIsoToMachineDir(isoURL, machineName string) error {
// TODO: This is a bit off-color.
machineDir := filepath.Join(b.storePath, "machines", machineName)
machineIsoPath := filepath.Join(machineDir, b.filename())

// just in case the cache dir has been manually deleted,
// check for it and recreate it if it's gone
func (b *B2dUtils) UpdateISOCache(isoURL string) error {
// recreate the cache dir if it has been manually deleted
if _, err := os.Stat(b.imgCachePath); os.IsNotExist(err) {
log.Infof("Image cache does not exist, creating it at %s...", b.imgCachePath)
log.Infof("Image cache directory does not exist, creating it at %s...", b.imgCachePath)
if err := os.Mkdir(b.imgCachePath, 0700); err != nil {
return err
}
}

// By default just copy the existing "cached" iso to the machine's directory...
if isoURL == "" {
return b.copyDefaultISOToMachine(machineIsoPath)
if isoURL != "" {
// Non-default B2D are not cached
return nil
}

// if ISO is specified, check if it matches a github releases url or fallback to a direct download
downloadURL, err := b.getReleaseURL(isoURL)
if err != nil {
return err
exists := b.exists()
if !exists {
log.Info("No default Boot2Docker ISO found locally, downloading the latest release...")
return b.DownloadLatestBoot2Docker("")
}

log.Infof("Downloading %s from %s...", b.filename(), downloadURL)
return b.DownloadISO(machineDir, b.filename(), downloadURL)
latest := b.isLatest()
if !latest {
log.Info("Default Boot2Docker ISO is out-of-date, downloading the latest release...")
return b.DownloadLatestBoot2Docker("")
}

return nil
}

func (b *B2dUtils) copyDefaultISOToMachine(machineIsoPath string) error {
// just in case the cache dir has been manually deleted,
// check for it and recreate it if it's gone
if _, err := os.Stat(b.imgCachePath); os.IsNotExist(err) {
log.Infof("Image cache directory does not exist, creating it at %s...", b.imgCachePath)
if err := os.Mkdir(b.imgCachePath, 0700); err != nil {
return err
}
func (b *B2dUtils) CopyIsoToMachineDir(isoURL, machineName string) error {
if err := b.UpdateISOCache(isoURL); err != nil {
return err
}

exists := b.exists()
latest := b.isLatest()
// TODO: This is a bit off-color.
machineDir := filepath.Join(b.storePath, "machines", machineName)
machineIsoPath := filepath.Join(machineDir, b.filename())

if exists && latest {
log.Infof("Latest Boot2Docker ISO found locally, copying it to %s...", machineIsoPath)
// By default just copy the existing "cached" iso to the machine's directory...
if isoURL == "" {
log.Infof("Copying %s to %s...", b.path(), machineIsoPath)
return CopyFile(b.path(), machineIsoPath)
}

if !exists {
log.Info("No default Boot2Docker ISO found locally, downloading the latest release...")
} else if !latest {
log.Info("Default Boot2Docker ISO is out-of-date, downloading the latest release...")
}
if err := b.DownloadLatestBoot2Docker(""); err != nil {
// if ISO is specified, check if it matches a github releases url or fallback to a direct download
downloadURL, err := b.getReleaseURL(isoURL)
if err != nil {
return err
}

log.Infof("Copying %s to %s...", b.path(), machineIsoPath)
return CopyFile(b.path(), machineIsoPath)
return b.DownloadISO(machineDir, b.filename(), downloadURL)
}

// isLatest checks the latest release tag and
Expand Down
7 changes: 4 additions & 3 deletions libmachine/mcnutils/b2d_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,14 @@ func TestCopyDefaultISOToMachine(t *testing.T) {
imgCachePath: imgCachePath,
}

dir := filepath.Join(storePath, tt.machineName)
dir := filepath.Join(storePath, "machines", tt.machineName)
err = os.MkdirAll(dir, 0700)

assert.NoError(t, err, "machine: %s", tt.machineName)

err = b.CopyIsoToMachineDir("", tt.machineName)
assert.NoError(t, err)

dest := filepath.Join(dir, b.filename())
err = b.copyDefaultISOToMachine(dest)
_, pathErr := os.Stat(dest)

assert.NoError(t, err, "machine: %s", tt.machineName)
Expand Down

0 comments on commit 204af9f

Please sign in to comment.