in step_wait_for_instances_signal.go [237:304]
func waitForGuestAttribute(s *Step, project, zone, name string, ga *GuestAttribute, interval time.Duration) DError {
var keyTokens []string
if ga.Namespace != "" {
keyTokens = append(keyTokens, ga.Namespace)
}
keyTokens = append(keyTokens, ga.KeyName)
varkey := strings.Join(keyTokens, "/")
w := s.w
msg := fmt.Sprintf("Instance %q: watching for key %s", name, varkey)
if ga.SuccessValue != "" {
msg += fmt.Sprintf(", SuccessValue: %q", ga.SuccessValue)
}
w.LogStepInfo(s.name, "WaitForInstancesSignal", msg+".")
// The limit for querying guest attributes is documented as 10 queries/minute.
minInterval, err := time.ParseDuration("6s")
if err == nil && interval < minInterval {
interval = minInterval
}
tick := time.Tick(interval)
var errs int
for {
select {
case <-s.w.Cancel:
return nil
case <-tick:
resp, err := w.ComputeClient.GetGuestAttributes(project, zone, name, "", varkey)
if err != nil {
if apiErr, ok := err.(*googleapi.Error); ok && apiErr.Code == 404 {
// 404 is OK, that means the key isn't present yet. Retry until timeout.
continue
}
status, sErr := w.ComputeClient.InstanceStatus(project, zone, name)
if sErr != nil {
err = fmt.Errorf("%v, error getting InstanceStatus: %v", err, sErr)
errs++
} else {
errs = 0
}
// Wait until machine restarts to get Guest Attributes
if status == "TERMINATED" || status == "STOPPED" || status == "STOPPING" {
continue
}
// Permit up to 3 consecutive non-404 errors getting guest attrs so long as we can get instance
// status.
if errs < 3 {
continue
}
return Errf("WaitForInstancesSignal: instance %q: error getting guest attribute: %v", name, err)
}
if ga.SuccessValue != "" {
if resp.VariableValue != ga.SuccessValue {
errMsg := strings.TrimSpace(resp.VariableValue)
format := "WaitForInstancesSignal bad guest attribute value found for %q: %q"
return Errf(format, name, errMsg)
}
w.LogStepInfo(s.name, "WaitForInstancesSignal", "Instance %q: SuccessValue found for key %q", name, ga.KeyName)
return nil
}
w.LogStepInfo(s.name, "WaitForInstancesSignal", "Instance %q found key %q", name, ga.KeyName)
return nil
}
}
}