diff --git a/builder/powervs/step_create_instance.go b/builder/powervs/step_create_instance.go index 747e82f..f675a51 100644 --- a/builder/powervs/step_create_instance.go +++ b/builder/powervs/step_create_instance.go @@ -61,10 +61,21 @@ func (s *StepCreateInstance) Run(_ context.Context, state multistep.StateBag) mu return multistep.ActionHalt } - in, err := instanceClient.Get(insIDs[0]) - if err != nil { + var in *models.PVMInstance + + //nolint:staticcheck // SA1015 this disable staticcheck for the next line + if err := pollUntil(time.Tick(30*time.Second), time.After(5*time.Minute), func() (bool, error) { + in, err = instanceClient.Get(insIDs[0]) + if err != nil || in == nil { + ui.Message("No response or error encountered while retrieving the instance. Retrying...") + return false, nil + } + return true, nil + }); err != nil { ui.Error(fmt.Sprintf("failed to get instance: %v", err)) + return multistep.ActionHalt } + ui.Message(fmt.Sprintf("Instance Created, Name: %s, ID: %s", *in.ServerName, *in.PvmInstanceID)) state.Put("instance", in) diff --git a/builder/powervs/util.go b/builder/powervs/util.go new file mode 100644 index 0000000..e3010e7 --- /dev/null +++ b/builder/powervs/util.go @@ -0,0 +1,24 @@ +package powervs + +import ( + "fmt" + "time" +) + +// pollUntil validates if a certain condition is met at defined poll intervals. +// If a timeout is reached, an associated error is returned to the caller. +// condition contains the use-case specific code that returns true when a certain condition is achieved. +func pollUntil(pollInterval, timeOut <-chan time.Time, condition func() (bool, error)) error { + for { + select { + case <-timeOut: + return fmt.Errorf("timed out while waiting for job to complete") + case <-pollInterval: + if done, err := condition(); err != nil { + return err + } else if done { + return nil + } + } + } +}