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 }