func WaitForSerialOutput()

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
		}
	}
}