mirror of https://github.com/docker/docs.git
Merge pull request #784 from hairyhenderson/softlayer-wait-for-transactions
Wait for any activeTransactions to finish during Create
This commit is contained in:
commit
ca8ae29ad2
|
@ -295,27 +295,37 @@ func (d *Driver) GetState() (state.State, error) {
|
||||||
return vmState, nil
|
return vmState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Driver) GetActiveTransaction() (string, error) {
|
||||||
|
t, err := d.getClient().VirtualGuest().ActiveTransaction(d.Id)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Driver) PreCreateCheck() error {
|
func (d *Driver) PreCreateCheck() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Create() error {
|
func (d *Driver) waitForStart() {
|
||||||
waitForStart := func() {
|
|
||||||
log.Infof("Waiting for host to become available")
|
log.Infof("Waiting for host to become available")
|
||||||
for {
|
for {
|
||||||
s, err := d.GetState()
|
s, err := d.GetState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debugf("Failed to GetState - %+v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if s == state.Running {
|
if s == state.Running {
|
||||||
break
|
break
|
||||||
|
} else {
|
||||||
|
log.Debugf("Still waiting - state is %s...", s)
|
||||||
}
|
}
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getIp := func() {
|
func (d *Driver) getIp() (string, error) {
|
||||||
log.Infof("Getting Host IP")
|
log.Infof("Getting Host IP")
|
||||||
for {
|
for {
|
||||||
var (
|
var (
|
||||||
|
@ -334,13 +344,40 @@ func (d *Driver) Create() error {
|
||||||
// not a perfect regex, but should be just fine for our needs
|
// not a perfect regex, but should be just fine for our needs
|
||||||
exp := regexp.MustCompile(`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`)
|
exp := regexp.MustCompile(`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`)
|
||||||
if exp.MatchString(ip) {
|
if exp.MatchString(ip) {
|
||||||
d.IPAddress = ip
|
return ip, nil
|
||||||
break
|
|
||||||
}
|
}
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Driver) waitForSetupTransactions() {
|
||||||
|
log.Infof("Waiting for host setup transactions to complete")
|
||||||
|
// sometimes we'll hit a case where there's no active transaction, but if
|
||||||
|
// we check again in a few seconds, it moves to the next transaction. We
|
||||||
|
// don't want to get false-positives, so we check a few times in a row to make sure!
|
||||||
|
noActiveCount, maxNoActiveCount := 0, 3
|
||||||
|
for {
|
||||||
|
t, err := d.GetActiveTransaction()
|
||||||
|
if err != nil {
|
||||||
|
noActiveCount = 0
|
||||||
|
log.Debugf("Failed to GetActiveTransaction - %+v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if t == "" {
|
||||||
|
if noActiveCount == maxNoActiveCount {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
noActiveCount++
|
||||||
|
} else {
|
||||||
|
noActiveCount = 0
|
||||||
|
log.Debugf("Still waiting - active transaction is %s...", t)
|
||||||
|
}
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Driver) Create() error {
|
||||||
log.Infof("Creating SSH key...")
|
log.Infof("Creating SSH key...")
|
||||||
key, err := d.createSSHKey()
|
key, err := d.createSSHKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -355,8 +392,9 @@ func (d *Driver) Create() error {
|
||||||
return fmt.Errorf("Error creating host: %q", err)
|
return fmt.Errorf("Error creating host: %q", err)
|
||||||
}
|
}
|
||||||
d.Id = id
|
d.Id = id
|
||||||
getIp()
|
d.getIp()
|
||||||
waitForStart()
|
d.waitForStart()
|
||||||
|
d.waitForSetupTransactions()
|
||||||
ssh.WaitForTCP(d.IPAddress + ":22")
|
ssh.WaitForTCP(d.IPAddress + ":22")
|
||||||
|
|
||||||
cmd, err := drivers.GetSSHCommandFromDriver(d, "sudo apt-get update && DEBIAN_FRONTEND=noninteractive sudo apt-get install -yq curl")
|
cmd, err := drivers.GetSSHCommandFromDriver(d, "sudo apt-get update && DEBIAN_FRONTEND=noninteractive sudo apt-get install -yq curl")
|
||||||
|
|
|
@ -180,6 +180,39 @@ func (c *virtualGuest) PowerState(id int) (string, error) {
|
||||||
return s.Name, nil
|
return s.Name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *virtualGuest) ActiveTransaction(id int) (string, error) {
|
||||||
|
type transactionStatus struct {
|
||||||
|
AverageDuration string `json:"averageDuration"`
|
||||||
|
FriendlyName string `json:"friendlyName"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
type transaction struct {
|
||||||
|
CreateDate string `json:"createDate"`
|
||||||
|
ElapsedSeconds int `json:"elapsedSeconds"`
|
||||||
|
GuestID int `json:"guestId"`
|
||||||
|
HardwareID int `json:"hardwareId"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
ModifyDate string `json:"modifyDate"`
|
||||||
|
StatusChangeDate string `json:"statusChangeDate"`
|
||||||
|
TransactionStatus transactionStatus `json:"transactionStatus"`
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
method = "GET"
|
||||||
|
uri = fmt.Sprintf("%s/%v/getActiveTransaction.json", c.namespace(), id)
|
||||||
|
)
|
||||||
|
|
||||||
|
data, err := c.newRequest(method, uri, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
var t transaction
|
||||||
|
if err := json.Unmarshal(data, &t); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.TransactionStatus.Name, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *virtualGuest) Create(spec *HostSpec) (int, error) {
|
func (c *virtualGuest) Create(spec *HostSpec) (int, error) {
|
||||||
var (
|
var (
|
||||||
method = "POST"
|
method = "POST"
|
||||||
|
|
Loading…
Reference in New Issue