in pkg/testutils/kustainer/kustainer.go [76:129]
func (c *KustainerContainer) PortForward(ctx context.Context, config *rest.Config) error {
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return fmt.Errorf("failed to create client: %w", err)
}
var podName string
// Wait for pod to exist and be running/ready
err = kwait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Minute, true, func(ctx context.Context) (bool, error) {
pods, err := clientset.CoreV1().Pods("default").List(ctx, metav1.ListOptions{
LabelSelector: "app=kustainer",
})
if err != nil || len(pods.Items) == 0 {
return false, nil
}
pod := pods.Items[0]
if pod.Status.Phase != corev1.PodRunning {
return false, nil
}
for _, cs := range pod.Status.ContainerStatuses {
if !cs.Ready {
return false, nil
}
}
podName = pod.Name
return true, nil
})
if err != nil {
return fmt.Errorf("failed to get ready pod: %w", err)
}
err = kwait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Minute, true, func(ctx context.Context) (bool, error) {
if err := c.waitForLog(ctx, clientset, podName, "Hit 'CTRL-C' or 'CTRL-BREAK' to quit"); err != nil {
return false, nil
}
return true, nil
})
if err != nil {
return fmt.Errorf("failed create container: %w", err)
}
// Retry port-forward on failure, with backoff
var lastErr error
for i := range 5 {
err = c.connect(ctx, config, podName)
if err == nil {
return nil
}
lastErr = err
// Exponential backoff
time.Sleep(time.Second * time.Duration(2<<i))
}
return fmt.Errorf("failed to connect to kustainer after retries: %w", lastErr)
}