github.com/alouche/packer@v0.3.7/builder/digitalocean/wait.go (about)

     1  package digitalocean
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  )
     8  
     9  // waitForState simply blocks until the droplet is in
    10  // a state we expect, while eventually timing out.
    11  func waitForDropletState(desiredState string, dropletId uint, client *DigitalOceanClient, timeout time.Duration) error {
    12  	done := make(chan struct{})
    13  	defer close(done)
    14  
    15  	result := make(chan error, 1)
    16  	go func() {
    17  		attempts := 0
    18  		for {
    19  			attempts += 1
    20  
    21  			log.Printf("Checking droplet status... (attempt: %d)", attempts)
    22  			_, status, err := client.DropletStatus(dropletId)
    23  			if err != nil {
    24  				result <- err
    25  				return
    26  			}
    27  
    28  			if status == desiredState {
    29  				result <- nil
    30  				return
    31  			}
    32  
    33  			// Wait 3 seconds in between
    34  			time.Sleep(3 * time.Second)
    35  
    36  			// Verify we shouldn't exit
    37  			select {
    38  			case <-done:
    39  				// We finished, so just exit the goroutine
    40  				return
    41  			default:
    42  				// Keep going
    43  			}
    44  		}
    45  	}()
    46  
    47  	log.Printf("Waiting for up to %d seconds for droplet to become %s", timeout, desiredState)
    48  	select {
    49  	case err := <-result:
    50  		return err
    51  	case <-time.After(timeout):
    52  		err := fmt.Errorf("Timeout while waiting to for droplet to become '%s'", desiredState)
    53  		return err
    54  	}
    55  }