func tryUntil(until time.Time, try func() bool) bool {
	for until.After(time.Now()) {
		if try() {
			return true
		}
	}
	return false
}
helper that calls `try()`` in a loop until the deadline `until`
has passed or `try()`returns true, returns whether try ever returned true
package waitforready
import (
	"fmt"
	"strings"
	"time"
	"sigs.k8s.io/kind/pkg/cluster/internal/create/actions"
	"sigs.k8s.io/kind/pkg/cluster/nodes"
	"sigs.k8s.io/kind/pkg/cluster/nodeutils"
	"sigs.k8s.io/kind/pkg/exec"
)
type Action struct {
	waitTime time.Duration
}
func NewAction(waitTime time.Duration) actions.Action {
	return &Action{
		waitTime: waitTime,
	}
}
func (a *Action) Execute(ctx *actions.ActionContext) error {
	if a.waitTime == time.Duration(0) {
		return nil
	}
	ctx.Status.Start(
		fmt.Sprintf(
			"Waiting ≤ %s for control-plane = Ready ⏳",
			formatDuration(a.waitTime),
		),
	)
	allNodes, err := ctx.Nodes()
	if err != nil {
		return err
	}
	controlPlanes, err := nodeutils.ControlPlaneNodes(allNodes)
	if err != nil {
		return err
	}
	node := controlPlanes[0]  
	startTime := time.Now()
	isReady := waitForReady(node, startTime.Add(a.waitTime))
	if !isReady {
		ctx.Status.End(false)
		ctx.Logger.V(0).Info(" • WARNING: Timed out waiting for Ready ⚠️")
		return nil
	}
	ctx.Status.End(true)
	ctx.Logger.V(0).Infof(" • Ready after %s 💚", formatDuration(time.Since(startTime)))
	return nil
}
func waitForReady(node nodes.Node, until time.Time) bool {
	return tryUntil(until, func() bool {
		cmd := node.Command(
			"kubectl",
			"--kubeconfig=/etc/kubernetes/admin.conf",
			"get",
			"nodes",
			"--selector=node-role.kubernetes.io/master",
			"-o=jsonpath='{.items..status.conditions[-1:].status}'",
		)
		lines, err := exec.OutputLines(cmd)
		if err != nil {
			return false
		}
		status := strings.Fields(lines[0])
		for _, s := range status {
			if !strings.Contains(s, "True") {
				return false
			}
		}
		return true
	})
}