diff --git a/src/pkg/cluster/cluster.go b/src/pkg/cluster/cluster.go index 5db77e0c9c..44e03c9c9b 100644 --- a/src/pkg/cluster/cluster.go +++ b/src/pkg/cluster/cluster.go @@ -12,11 +12,11 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "sigs.k8s.io/cli-utils/pkg/kstatus/watcher" - "github.com/avast/retry-go/v4" pkgkubernetes "github.com/defenseunicorns/pkg/kubernetes" "github.com/zarf-dev/zarf/src/pkg/message" @@ -45,25 +45,26 @@ func NewClusterWithWait(ctx context.Context) (*Cluster, error) { if err != nil { return nil, err } - err = retry.Do(func() error { + // returning false, or an error continues polling, true stops it + err = wait.PollUntilContextCancel(ctx, time.Second, false, func(context.Context) (bool, error) { nodeList, err := c.Clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) if err != nil { - return err + return false, err } if len(nodeList.Items) < 1 { - return fmt.Errorf("cluster does not have any nodes") + return false, fmt.Errorf("cluster does not have any nodes") } pods, err := c.Clientset.CoreV1().Pods(corev1.NamespaceAll).List(ctx, metav1.ListOptions{}) if err != nil { - return err + return false, err } for _, pod := range pods.Items { if pod.Status.Phase == corev1.PodSucceeded || pod.Status.Phase == corev1.PodRunning { - return nil + return true, nil } } - return fmt.Errorf("no pods are in succeeded or running state") - }, retry.Context(ctx), retry.Attempts(0), retry.DelayType(retry.FixedDelay), retry.Delay(time.Second)) + return false, fmt.Errorf("no pods are in succeeded or running state") + }) if err != nil { return nil, err } diff --git a/src/pkg/cluster/data.go b/src/pkg/cluster/data.go index 68148003a7..397025fe0f 100644 --- a/src/pkg/cluster/data.go +++ b/src/pkg/cluster/data.go @@ -17,9 +17,10 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/util/retry" - "github.com/avast/retry-go/v4" "github.com/defenseunicorns/pkg/helpers/v2" "github.com/zarf-dev/zarf/src/api/v1alpha1" @@ -171,13 +172,14 @@ type podFilter func(pod corev1.Pod) bool // If the timeout is reached, an empty list will be returned. // TODO: Test, refactor and/or remove. func waitForPodsAndContainers(ctx context.Context, clientset kubernetes.Interface, target podLookup, include podFilter) ([]corev1.Pod, error) { - readyPods, err := retry.DoWithData(func() ([]corev1.Pod, error) { + var readyPods []corev1.Pod + err := wait.PollUntilContextCancel(ctx, time.Second, false, func(context.Context) (bool, error) { listOpts := metav1.ListOptions{ LabelSelector: target.Selector, } podList, err := clientset.CoreV1().Pods(target.Namespace).List(ctx, listOpts) if err != nil { - return nil, err + return false, err } message.Debugf("Found %d pods for target %#v", len(podList.Items), target) // Sort the pods from newest to oldest @@ -185,7 +187,7 @@ func waitForPodsAndContainers(ctx context.Context, clientset kubernetes.Interfac return podList.Items[i].CreationTimestamp.After(podList.Items[j].CreationTimestamp.Time) }) - readyPods := []corev1.Pod{} + readyPods = []corev1.Pod{} for _, pod := range podList.Items { message.Debugf("Testing pod %q", pod.Name) @@ -227,10 +229,10 @@ func waitForPodsAndContainers(ctx context.Context, clientset kubernetes.Interfac } } if len(readyPods) == 0 { - return nil, fmt.Errorf("no ready pods found") + return false, fmt.Errorf("no ready pods found") } - return readyPods, nil - }, retry.Context(ctx), retry.Attempts(0), retry.DelayType(retry.FixedDelay), retry.Delay(time.Second)) + return true, nil + }) if err != nil { return nil, err } diff --git a/src/pkg/cluster/namespace.go b/src/pkg/cluster/namespace.go index 99d50a5f5e..3288788582 100644 --- a/src/pkg/cluster/namespace.go +++ b/src/pkg/cluster/namespace.go @@ -9,10 +9,10 @@ import ( "fmt" "time" - "github.com/avast/retry-go/v4" corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" "github.com/zarf-dev/zarf/src/pkg/message" ) @@ -29,16 +29,17 @@ func (c *Cluster) DeleteZarfNamespace(ctx context.Context) error { if err != nil { return err } - err = retry.Do(func() error { - _, err := c.Clientset.CoreV1().Namespaces().Get(ctx, ZarfNamespaceName, metav1.GetOptions{}) - if kerrors.IsNotFound(err) { - return nil + // returning false, or an error continues polling, true stops it + err = wait.PollUntilContextCancel(ctx, time.Second, false, func(context.Context) (bool, error) { + _, ierr := c.Clientset.CoreV1().Namespaces().Get(ctx, ZarfNamespaceName, metav1.GetOptions{}) + if kerrors.IsNotFound(ierr) { + return true, nil } - if err != nil { - return err + if ierr != nil { + return false, ierr } - return fmt.Errorf("namespace still exists") - }, retry.Context(ctx), retry.Attempts(0), retry.DelayType(retry.FixedDelay), retry.Delay(time.Second)) + return false, fmt.Errorf("namespace still exists") + }) if err != nil { return err } diff --git a/src/pkg/cluster/state.go b/src/pkg/cluster/state.go index f2279b0221..b3b4d24384 100644 --- a/src/pkg/cluster/state.go +++ b/src/pkg/cluster/state.go @@ -15,8 +15,8 @@ import ( corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" - "github.com/avast/retry-go/v4" "github.com/defenseunicorns/pkg/helpers/v2" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/config/lang" @@ -127,15 +127,13 @@ func (c *Cluster) InitZarfState(ctx context.Context, initOptions types.ZarfInitO // Wait up to 2 minutes for the default service account to be created. // Some clusters seem to take a while to create this, see https://github.com/kubernetes/kubernetes/issues/66689. // The default SA is required for pods to start properly. - saCtx, cancel := context.WithTimeout(ctx, 2*time.Minute) - defer cancel() - err = retry.Do(func() error { - _, err := c.Clientset.CoreV1().ServiceAccounts(ZarfNamespaceName).Get(saCtx, "default", metav1.GetOptions{}) - if err != nil { - return err + err = wait.PollUntilContextTimeout(ctx, time.Second, 2*time.Minute, false, func(saCtx context.Context) (bool, error) { + _, ierr := c.Clientset.CoreV1().ServiceAccounts(ZarfNamespaceName).Get(saCtx, "default", metav1.GetOptions{}) + if ierr != nil { + return false, ierr } - return nil - }, retry.Context(saCtx), retry.Attempts(0), retry.DelayType(retry.FixedDelay), retry.Delay(time.Second)) + return true, nil + }) if err != nil { return fmt.Errorf("unable get default Zarf service account: %w", err) } diff --git a/src/pkg/cluster/zarf.go b/src/pkg/cluster/zarf.go index b38b55d783..638785263d 100644 --- a/src/pkg/cluster/zarf.go +++ b/src/pkg/cluster/zarf.go @@ -16,8 +16,9 @@ import ( corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/retry" - "github.com/avast/retry-go/v4" "github.com/zarf-dev/zarf/src/api/v1alpha1" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/internal/gitea" @@ -157,19 +158,18 @@ func (c *Cluster) RecordPackageDeploymentAndWait(ctx context.Context, pkg v1alph if waitSeconds > 0 { waitDuration = time.Duration(waitSeconds) * time.Second } - waitCtx, cancel := context.WithTimeout(ctx, waitDuration) - defer cancel() - deployedPackage, err = retry.DoWithData(func() (*types.DeployedPackage, error) { - deployedPackage, err = c.GetDeployedPackage(waitCtx, deployedPackage.Name) - if err != nil { - return nil, err + err = wait.PollUntilContextTimeout(ctx, time.Second, waitDuration, false, func(waitCtx context.Context) (bool, error) { + pkg, ierr := c.GetDeployedPackage(waitCtx, deployedPackage.Name) + if ierr != nil { + return false, ierr } + deployedPackage = pkg packageNeedsWait, _, _ = c.PackageSecretNeedsWait(deployedPackage, component, skipWebhooks) if !packageNeedsWait { - return deployedPackage, nil + return true, nil } - return deployedPackage, nil - }, retry.Context(waitCtx), retry.Attempts(0), retry.DelayType(retry.FixedDelay), retry.Delay(time.Second)) + return true, nil + }) if err != nil { return nil, err }