Skip to content

cluster start: wait for HAProxy to be healthy before returning - #33

Merged
alicefr merged 4 commits into
mainfrom
fix-31
May 29, 2026
Merged

cluster start: wait for HAProxy to be healthy before returning#33
alicefr merged 4 commits into
mainfrom
fix-31

Conversation

@alicefr

@alicefr alicefr commented May 28, 2026

Copy link
Copy Markdown
Collaborator

Poll the Kubernetes API /healthz endpoint through HAProxy until it returns HTTP 200 before completing cluster start. This prevents callers from getting EOF errors when immediately using kubectl.

Fixes: #31

Summary by Sourcery

Bug Fixes:

  • Prevent EOF and connectivity errors by polling the Kubernetes API /healthz endpoint through HAProxy until it returns HTTP 200 during cluster startup.

@sourcery-ai

sourcery-ai Bot commented May 28, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a health check wait loop to the cluster start flow so that cluster start only returns after HAProxy is successfully proxying a healthy Kubernetes API /healthz endpoint, reducing early EOF errors for immediate kubectl use.

Sequence diagram for updated cluster start with HAProxy health wait

sequenceDiagram
    actor User
    participant CLI as runStart
    participant HAProxyManager as Manager
    participant HAProxy
    participant KubeAPI as KubernetesAPI

    User->>CLI: cluster start
    CLI->>HAProxyManager: EnsureHAProxy(ctx, 0)
    HAProxyManager->>HAProxy: start or ensure container
    HAProxy-->>HAProxyManager: ready to accept traffic

    CLI->>HAProxyManager: WaitForHealthy(ctx)
    HAProxyManager->>HAProxyManager: GetPublishedPort(ctx)
    HAProxyManager-->>CLI: [port]

    loop every 2s until 2m
        CLI->>HAProxy: GET /healthz via https://localhost:port
        HAProxy->>KubeAPI: proxy GET /healthz
        KubeAPI-->>HAProxy: HTTP 200 or non-200/error
        HAProxy-->>CLI: HTTP response
        alt HTTP 200
            CLI->>User: cluster start returns successfully and loop ends
        else non-200 or error
            CLI->>CLI: continue waiting
        end
    end
Loading

File-Level Changes

Change Details Files
Introduce an HAProxy health wait routine that polls the Kubernetes API /healthz endpoint over HTTPS via the published HAProxy port until it returns HTTP 200 or times out.
  • Add WaitForHealthy method on the HAProxy manager that resolves the published port and builds an https://localhost:/healthz URL
  • Configure an HTTP client with a 5s timeout and TLS that skips certificate verification for the local proxy call
  • Implement a 2-minute overall timeout and 2-second polling interval via time.After and time.NewTicker, stopping the ticker via defer
  • Log informational messages when waiting for and when detecting that HAProxy is healthy
  • Handle context cancellation, timeout expiration, HTTP errors, and non-200 responses without failing early until success, deadline, or ctx.Done
internal/haproxy/haproxy.go
Block cluster startup completion on HAProxy health by invoking the new wait routine after ensuring the HAProxy load balancer.
  • Call haproxyMgr.WaitForHealthy in runStart immediately after EnsureHAProxy
  • Wrap and return any error from WaitForHealthy with context in the cluster start flow
internal/cli/cluster/start.go

Assessment against linked issues

Issue Objective Addressed Explanation
https://github.com/alicefr/bink/issues/31 Ensure that bink cluster start --expose does not return until the HAProxy load balancer is healthy (i.e., able to successfully proxy to the Kubernetes API), to avoid EOF errors for immediate kubectl usage.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The health check HTTP client ignores the provided context when issuing requests; consider using http.NewRequestWithContext so cancellation and timeouts are driven by ctx rather than only the fixed 5s client timeout.
  • InsecureSkipVerify: true in the TLS config is a security footgun; if possible, either document why this is required or tighten it (e.g., using a proper CA or making the behavior configurable).
  • Using time.After(2 * time.Minute) inside the loop setup will create a timer that can’t be stopped; prefer time.NewTimer with a defer timer.Stop() to avoid potential leaks in long‑running processes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The health check HTTP client ignores the provided context when issuing requests; consider using `http.NewRequestWithContext` so cancellation and timeouts are driven by `ctx` rather than only the fixed 5s client timeout.
- `InsecureSkipVerify: true` in the TLS config is a security footgun; if possible, either document why this is required or tighten it (e.g., using a proper CA or making the behavior configurable).
- Using `time.After(2 * time.Minute)` inside the loop setup will create a timer that can’t be stopped; prefer `time.NewTimer` with a `defer timer.Stop()` to avoid potential leaks in long‑running processes.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Poll the Kubernetes API /healthz endpoint through HAProxy until it
returns HTTP 200 before completing cluster start. This prevents
callers from getting EOF errors when immediately using kubectl.

Fixes: #31
Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Alice Frosi <afrosi@redhat.com>
alicefr added 3 commits May 29, 2026 07:41
Route the kube client through the HAProxy load balancer instead of the
control plane container's direct published port. The direct path goes
through passt port forwarding which is unreliable under CI load, causing
label application to silently fail.

Also make labeling errors fatal so users get a clear failure when
--label flags are not applied.

Fixes #31

Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alicefr
alicefr merged commit e476d9b into main May 29, 2026
6 checks passed
@alicefr
alicefr deleted the fix-31 branch June 18, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cluster start: wait for HAProxy to be healthy before returning

1 participant