in common/gcp/instance.go [99:151]
func WaitForSerialOutput(successMatch string, failureMatches []string, port int64, interval, timeout time.Duration, project, zone, instanceName string, client daisyCompute.Client) error {
var start int64
var errs int
tick := time.Tick(interval)
timedout := time.Tick(timeout)
for {
select {
case <-timedout:
return fmt.Errorf("timed out waiting for %q", successMatch)
case <-tick:
resp, err := client.GetSerialPortOutput(project, zone, instanceName, port, start)
if err != nil {
status, sErr := client.InstanceStatus(project, zone, instanceName)
if sErr != nil {
err = fmt.Errorf("%v, error getting InstanceStatus: %v", err, sErr)
} else {
err = fmt.Errorf("%v, InstanceStatus: %q", err, status)
}
// Wait until machine restarts to evaluate SerialOutput.
if status == "TERMINATED" || status == "STOPPED" || status == "STOPPING" {
continue
}
// Retry up to 3 times in a row on any error if we successfully got InstanceStatus.
if errs < 3 {
errs++
continue
}
return err
}
start = resp.Next
for _, ln := range strings.Split(resp.Contents, "\n") {
if len(failureMatches) > 0 {
for _, failureMatch := range failureMatches {
if i := strings.Index(ln, failureMatch); i != -1 {
errMsg := strings.TrimSpace(ln[i:])
format := "WaitForSerialOutput FailureMatch found for %q: %q"
return fmt.Errorf(format, instanceName, errMsg)
}
}
}
if successMatch != "" {
if i := strings.Index(strings.ToLower(ln), strings.ToLower(successMatch)); i != -1 {
return nil
}
}
}
errs = 0
}
}
}