Repository: kubernetes/kubernetes
File: cmd/kubeadm/app/util/apiclient/wait.go (Go)

Code before:
	err = wait.PollUntilContextTimeout(context.Background(),
		constants.KubernetesAPICallRetryInterval, w.timeout,
		true, func(_ context.Context) (bool, error) {
			hash, err := getStaticPodSingleHash(w.client, nodeName, component)
			if err != nil {
				lastErr = err
				return false, nil
			}
			// Set lastErr to nil to be able to later distinguish between getStaticPodSingleHash() and timeout errors
			lastErr = nil
			// We should continue polling until the UID changes
			if hash == previousHash {
				return false, nil
			}

			return true, nil
		})

	// If lastError is not nil, this must be a getStaticPodSingleHash() error, else if err is not nil there was a poll timeout
	if lastErr != nil {
		return lastErr
	}
	return errors.Wrapf(err, "static Pod hash for component %s on Node %s did not change after %v", component, nodeName, w.timeout)
}

// WaitForStaticPodRunning waits for a static pod to be in Running phase.
func (w *KubeWaiter) WaitForStaticPodRunning(nodeName string, component string) error {
	staticPodName := fmt.Sprintf("%s-%s", component, nodeName)
	klog.V(1).Infof("Waiting for static pod %q to be running", staticPodName)

	var lastError error
	err := wait.PollUntilContextTimeout(
		context.Background(),
		constants.KubernetesAPICallRetryInterval,
		w.timeout,
		true, func(_ context.Context) (bool, error) {
			pod, err := w.client.CoreV1().Pods(metav1.NamespaceSystem).Get(context.Background(), staticPodName, metav1.GetOptions{})
			if err != nil {
				lastError = err
				klog.V(5).Infof("Failed to get static pod %q: %v", staticPodName, err)
				return false, nil
			}

			// Check if the pod is in Running phase
			if pod.Status.Phase == v1.PodRunning {
				klog.V(1).Infof("Static pod %q is running", staticPodName)
				return true, nil
			}
			klog.V(5).Infof("Static pod %q is in phase %q, waiting for Running", staticPodName, pod.Status.Phase)
			return false, nil
		})

Review comment (suggestion):
```suggestion
// WaitForStaticPodRunning waits for a static pod to be in a Running phase.
```

Code after:
		true, func(_ context.Context) (bool, error) {
			hash, err := getStaticPodSingleHash(w.client, nodeName, component)
			if err != nil {
				lastErr = err
				return false, nil
			}
			// Set lastErr to nil to be able to later distinguish between getStaticPodSingleHash() and timeout errors
			lastErr = nil
			// We should continue polling until the UID changes
			if hash == previousHash {
				return false, nil
			}

			return true, nil
		})

	// If lastError is not nil, this must be a getStaticPodSingleHash() error, else if err is not nil there was a poll timeout
	if lastErr != nil {
		return lastErr
	}
	return errors.Wrapf(err, "static Pod hash for component %s on Node %s did not change after %v", component, nodeName, w.timeout)
}

// getStaticPodSingleHash computes hashes for a single Static Pod resource
func getStaticPodSingleHash(client clientset.Interface, nodeName string, component string) (string, error) {

	staticPodName := fmt.Sprintf("%s-%s", component, nodeName)
	staticPod, err := client.CoreV1().Pods(metav1.NamespaceSystem).Get(context.Background(), staticPodName, metav1.GetOptions{})
	if err != nil {
		return "", errors.Wrapf(err, "failed to obtain static Pod hash for component %s on Node %s", component, nodeName)
	}

	staticPodHash := staticPod.Annotations["kubernetes.io/config.hash"]
	return staticPodHash, nil
}

// PrintControlPlaneErrorHelpScreen prints help text on wait ControlPlane components errors.
func PrintControlPlaneErrorHelpScreen(outputWriter io.Writer, criSocket string) {
	context := struct {
		Socket string
	}{
		Socket: criSocket,
	}
	_ = controlPlaneFailTempl.Execute(outputWriter, context)
	_, _ = fmt.Fprintln(outputWriter, "")
}

// PrintKubeletErrorHelpScreen prints help text on kubelet errors.
func PrintKubeletErrorHelpScreen(outputWriter io.Writer) {
	_, _ = fmt.Fprintln(outputWriter, kubeletFailMsg)
}