@@ -5,9 +5,12 @@ package haproxy
55
66import (
77 "context"
8+ "crypto/tls"
89 "fmt"
10+ "net/http"
911 "strings"
1012 "text/template"
13+ "time"
1114
1215 "github.com/bootc-dev/bink/internal/config"
1316 "github.com/bootc-dev/bink/internal/podman"
@@ -202,6 +205,56 @@ func (m *Manager) GetPublishedPort(ctx context.Context) (int, error) {
202205 return m .podman .GetPublishedPort (ctx , m .containerName (), fmt .Sprintf ("%d/tcp" , config .HAProxyPort ))
203206}
204207
208+ // WaitForHealthy polls the Kubernetes API /healthz endpoint through HAProxy
209+ // until it returns HTTP 200, indicating that HAProxy has healthy backends.
210+ func (m * Manager ) WaitForHealthy (ctx context.Context ) error {
211+ port , err := m .GetPublishedPort (ctx )
212+ if err != nil {
213+ return fmt .Errorf ("getting HAProxy published port: %w" , err )
214+ }
215+
216+ client := & http.Client {
217+ Transport : & http.Transport {
218+ TLSClientConfig : & tls.Config {InsecureSkipVerify : true },
219+ },
220+ }
221+
222+ healthURL := fmt .Sprintf ("https://localhost:%d/healthz" , port )
223+ timer := time .NewTimer (2 * time .Minute )
224+ defer timer .Stop ()
225+ ticker := time .NewTicker (2 * time .Second )
226+ defer ticker .Stop ()
227+
228+ logrus .Info ("Waiting for HAProxy to become healthy..." )
229+
230+ for {
231+ select {
232+ case <- ctx .Done ():
233+ return ctx .Err ()
234+ case <- timer .C :
235+ return fmt .Errorf ("timed out waiting for HAProxy to become healthy on port %d" , port )
236+ case <- ticker .C :
237+ reqCtx , cancel := context .WithTimeout (ctx , 5 * time .Second )
238+ req , err := http .NewRequestWithContext (reqCtx , http .MethodGet , healthURL , nil )
239+ if err != nil {
240+ cancel ()
241+ continue
242+ }
243+ resp , err := client .Do (req )
244+ if err != nil {
245+ cancel ()
246+ continue
247+ }
248+ resp .Body .Close ()
249+ cancel ()
250+ if resp .StatusCode == http .StatusOK {
251+ logrus .Info ("HAProxy is healthy" )
252+ return nil
253+ }
254+ }
255+ }
256+ }
257+
205258// discoverBackends finds all control-plane node containers in this cluster
206259// and returns their bridge IPs as backends.
207260func (m * Manager ) discoverBackends (ctx context.Context ) ([]backend , error ) {
0 commit comments