github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/oracle/oci/client/waiters.go (about)

     1  package oci
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  )
     7  
     8  const (
     9  	defaultWaitDurationMS = 5000
    10  	defaultMaxRetries     = 0
    11  )
    12  
    13  type Waiter struct {
    14  	WaitDurationMS int
    15  	MaxRetries     int
    16  }
    17  
    18  type WaitableService interface {
    19  	GetResourceState(id string) (string, error)
    20  }
    21  
    22  func stringSliceContains(slice []string, value string) bool {
    23  	for _, elem := range slice {
    24  		if elem == value {
    25  			return true
    26  		}
    27  	}
    28  	return false
    29  }
    30  
    31  // NewWaiter creates a waiter with default wait duration and unlimited retry
    32  // operations.
    33  func NewWaiter() *Waiter {
    34  	return &Waiter{WaitDurationMS: defaultWaitDurationMS, MaxRetries: defaultMaxRetries}
    35  }
    36  
    37  // WaitForResourceToReachState polls a resource that implements WaitableService
    38  // repeatedly until it reaches a known state or fails if it reaches an
    39  // unexpected state. The duration of the interval and number of polls is
    40  // determined by the Waiter configuration.
    41  func (w *Waiter) WaitForResourceToReachState(svc WaitableService, id string, waitStates []string, terminalState string) error {
    42  	for i := 0; w.MaxRetries == 0 || i < w.MaxRetries; i++ {
    43  		state, err := svc.GetResourceState(id)
    44  		if err != nil {
    45  			return err
    46  		}
    47  
    48  		if stringSliceContains(waitStates, state) {
    49  			time.Sleep(time.Duration(w.WaitDurationMS) * time.Millisecond)
    50  			continue
    51  		} else if state == terminalState {
    52  			return nil
    53  		}
    54  
    55  		return fmt.Errorf("Unexpected resource state %s, expecting a waiting state %s or terminal state  %s ", state, waitStates, terminalState)
    56  	}
    57  
    58  	return fmt.Errorf("Maximum number of retries (%d) exceeded; resource did not reach state %s", w.MaxRetries, terminalState)
    59  }