// migRollingUpdatePoll (CKE/GKE-only) polls the progress of the MIG rolling // update with ID id until it is complete. It returns an error if this takes // longer than nt times the number of nodes. func migRollingUpdatePoll(id string, nt time.Duration) error { // Two keys and a val. status, progress, done := "status", "statusMessage", "ROLLED_OUT" start, timeout := time.Now(), nt*time.Duration(framework.TestContext.CloudConfig.NumNodes) var errLast error framework.Logf("Waiting up to %v for MIG rolling update to complete.", timeout) if wait.Poll(restartPoll, timeout, func() (bool, error) { // A `rolling-updates describe` call outputs what we want to stdout. output, _, err := retryCmd("gcloud", "alpha", "compute", "rolling-updates", fmt.Sprintf("--project=%s", framework.TestContext.CloudConfig.ProjectID), fmt.Sprintf("--zone=%s", framework.TestContext.CloudConfig.Zone), "describe", id) if err != nil { errLast = fmt.Errorf("Error calling rolling-updates describe %s: %v", id, err) framework.Logf("%v", errLast) return false, nil } // The 'describe' call probably succeeded; parse the output and try to // find the line that looks like "status: <status>" and see whether it's // done. framework.Logf("Waiting for MIG rolling update: %s (%v elapsed)", framework.ParseKVLines(output, progress), time.Since(start)) if st := framework.ParseKVLines(output, status); st == done { return true, nil } return false, nil }) != nil { return fmt.Errorf("timeout waiting %v for MIG rolling update to complete. Last error: %v", timeout, errLast) } framework.Logf("MIG rolling update complete after %v", time.Since(start)) return nil }
// migTemplate (GCE-only) returns the name of the MIG template that the // nodes of the cluster use. func migTemplate() (string, error) { var errLast error var templ string key := "instanceTemplate" if wait.Poll(framework.Poll, framework.SingleCallTimeout, func() (bool, error) { // TODO(mikedanese): make this hit the compute API directly instead of // shelling out to gcloud. // An `instance-groups managed describe` call outputs what we want to stdout. output, _, err := retryCmd("gcloud", "compute", "instance-groups", "managed", fmt.Sprintf("--project=%s", framework.TestContext.CloudConfig.ProjectID), "describe", fmt.Sprintf("--zone=%s", framework.TestContext.CloudConfig.Zone), framework.TestContext.CloudConfig.NodeInstanceGroup) if err != nil { errLast = fmt.Errorf("gcloud compute instance-groups managed describe call failed with err: %v", err) return false, nil } // The 'describe' call probably succeeded; parse the output and try to // find the line that looks like "instanceTemplate: url/to/<templ>" and // return <templ>. if val := framework.ParseKVLines(output, key); len(val) > 0 { url := strings.Split(val, "/") templ = url[len(url)-1] framework.Logf("MIG group %s using template: %s", framework.TestContext.CloudConfig.NodeInstanceGroup, templ) return true, nil } errLast = fmt.Errorf("couldn't find %s in output to get MIG template. Output: %s", key, output) return false, nil }) != nil { return "", fmt.Errorf("migTemplate() failed with last error: %v", errLast) } return templ, nil }