Introduce universal poll retries function

Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
This commit is contained in:
Nathan LeClaire 2015-03-02 16:59:18 -08:00
parent aa3f54c033
commit 1e983d5ff6
2 changed files with 59 additions and 54 deletions

View File

@ -11,7 +11,6 @@ import (
"path" "path"
"strconv" "strconv"
"strings" "strings"
"time"
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
@ -19,6 +18,7 @@ import (
"github.com/docker/machine/drivers/amazonec2/amz" "github.com/docker/machine/drivers/amazonec2/amz"
"github.com/docker/machine/ssh" "github.com/docker/machine/ssh"
"github.com/docker/machine/state" "github.com/docker/machine/state"
"github.com/docker/machine/utils"
) )
const ( const (
@ -279,6 +279,19 @@ func (d *Driver) PreCreateCheck() error {
return d.checkPrereqs() return d.checkPrereqs()
} }
func (d *Driver) instanceIpAvailable() bool {
ip, err := d.GetIP()
if err != nil {
log.Debug(err)
}
if ip != "" {
d.IPAddress = ip
log.Debugf("Got the IP Address, it's %q", d.IPAddress)
return true
}
return false
}
func (d *Driver) Create() error { func (d *Driver) Create() error {
if err := d.checkPrereqs(); err != nil { if err := d.checkPrereqs(); err != nil {
return err return err
@ -309,18 +322,10 @@ func (d *Driver) Create() error {
} }
d.InstanceId = instance.InstanceId d.InstanceId = instance.InstanceId
log.Debug("waiting for ip address to become available") log.Debug("waiting for ip address to become available")
for { if err := utils.WaitFor(d.instanceIpAvailable); err != nil {
ip, err := d.GetIP() return err
if err != nil {
return err
}
if ip != "" {
d.IPAddress = ip
log.Debugf("Got the IP Address, it's %q", d.IPAddress)
break
}
time.Sleep(5 * time.Second)
} }
if len(instance.NetworkInterfaceSet) > 0 { if len(instance.NetworkInterfaceSet) > 0 {
@ -417,9 +422,6 @@ func (d *Driver) Start() error {
return err return err
} }
if err := d.updateDriver(); err != nil {
return err
}
return nil return nil
} }
@ -519,29 +521,6 @@ func (d *Driver) sshKeyPath() string {
return path.Join(d.storePath, "id_rsa") return path.Join(d.storePath, "id_rsa")
} }
func (d *Driver) updateDriver() error {
inst, err := d.getInstance()
if err != nil {
return err
}
// wait for ipaddress
for {
i, err := d.getInstance()
if err != nil {
return err
}
if i.IpAddress == "" {
time.Sleep(1 * time.Second)
continue
}
d.InstanceId = inst.InstanceId
d.IPAddress = inst.IpAddress
break
}
return nil
}
func (d *Driver) publicSSHKeyPath() string { func (d *Driver) publicSSHKeyPath() string {
return d.sshKeyPath() + ".pub" return d.sshKeyPath() + ".pub"
} }
@ -555,16 +534,20 @@ func (d *Driver) getInstance() (*amz.EC2Instance, error) {
return &instance, nil return &instance, nil
} }
func (d *Driver) instanceIsRunning() bool {
st, err := d.GetState()
if err != nil {
log.Debug(err)
}
if st == state.Running {
return true
}
return false
}
func (d *Driver) waitForInstance() error { func (d *Driver) waitForInstance() error {
for { if err := utils.WaitFor(d.instanceIsRunning); err != nil {
st, err := d.GetState() return err
if err != nil {
return err
}
if st == state.Running {
break
}
time.Sleep(1 * time.Second)
} }
return nil return nil
@ -610,6 +593,17 @@ func (d *Driver) isSwarmMaster() bool {
return d.SwarmMaster return d.SwarmMaster
} }
func (d *Driver) securityGroupAvailableFunc(id string) func() bool {
return func() bool {
_, err := d.getClient().GetSecurityGroupById(id)
if err == nil {
return true
}
log.Debug(err)
return false
}
}
func (d *Driver) configureSecurityGroup(groupName string) error { func (d *Driver) configureSecurityGroup(groupName string) error {
log.Debugf("configuring security group in %s", d.VpcId) log.Debugf("configuring security group in %s", d.VpcId)
@ -638,13 +632,8 @@ func (d *Driver) configureSecurityGroup(groupName string) error {
securityGroup = group securityGroup = group
// wait until created (dat eventual consistency) // wait until created (dat eventual consistency)
log.Debugf("waiting for group (%s) to become available", group.GroupId) log.Debugf("waiting for group (%s) to become available", group.GroupId)
for { if err := utils.WaitFor(d.securityGroupAvailableFunc(group.GroupId)); err != nil {
_, err := d.getClient().GetSecurityGroupById(group.GroupId) return err
if err == nil {
break
}
log.Debug(err)
time.Sleep(1 * time.Second)
} }
} }

View File

@ -1,10 +1,12 @@
package utils package utils
import ( import (
"fmt"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"time"
) )
func GetHomeDir() string { func GetHomeDir() string {
@ -79,3 +81,17 @@ func CopyFile(src, dst string) error {
return nil return nil
} }
func WaitForSpecific(f func() bool, maxAttempts int, waitInterval time.Duration) error {
for i := 0; i < maxAttempts; i++ {
if f() {
return nil
}
time.Sleep(waitInterval)
}
return fmt.Errorf("Maximum number of retries (%d) exceeded", maxAttempts)
}
func WaitFor(f func() bool) error {
return WaitForSpecific(f, 60, 3*time.Second)
}