Repository navigation
[tcp-balancer] Fix HAProxy 3.3 startup regression - #2321
Asish Kumar (officialasishkumar) wants to merge 4 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (2)
📝 WalkthroughWalkthroughRenamed HAProxy backend identifiers to add a Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request updates the HAProxy configuration by renaming backends to include a '_backend' suffix and modifies the deployment to use a versioned HAProxy image. The reviewer noted that while the image is now versioned, the current Chart.yaml appVersion (2.9.7) is incompatible with the intended HAProxy 3.3+ requirement, and recommends updating the Chart.yaml to reflect a compatible version.
| topologyKey: kubernetes.io/hostname | ||
| containers: | ||
| - image: haproxy:latest | ||
| - image: "haproxy:{{ .Chart.AppVersion }}" |
There was a problem hiding this comment.
This change pins the HAProxy image to {{ .Chart.AppVersion }}, but the appVersion in Chart.yaml is "2.9.7". The goal of this PR is to fix compatibility with HAProxy 3.3+, but this change will result in using haproxy:2.9.7.
To align with the PR's goal, the appVersion in Chart.yaml should be updated to a HAProxy 3.3+ version. This will ensure the new configuration is used with a compatible HAProxy version.
There was a problem hiding this comment.
Good catch. Updated appVersion in Chart.yaml from 2.9.7 to 3.3.6 so the deployment template now pulls the correct HAProxy 3.3 image.
Signed-off-by: Asish Kumar <[email protected]>
Updated Chart.yaml appVersion from 2.9.7 to 3.3.6 to match the configuration changes in this PR. The deployment template references .Chart.AppVersion for the image tag, so this ensures the correct HAProxy 3.3 image is used rather than the old 2.9.7 version. Signed-off-by: Asish Kumar <[email protected]>
0222254 to
79270a5
Compare
There was a problem hiding this comment.
Pull request overview
Fixes a HAProxy 3.3+ breaking change in the tcp-balancer Helm chart by ensuring frontend/backend names no longer collide and by pinning the HAProxy image tag to the chart’s appVersion (instead of :latest), aligning with issue #1966.
Changes:
- Renamed generated HAProxy backends (e.g.,
http_backend,https_backend) to avoid name collisions with frontends on HAProxy 3.3+. - Updated the Deployment to use
haproxy:{{ .Chart.AppVersion }}rather thanhaproxy:latest. - Bumped chart
appVersionto3.3.6.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/apps/tcp-balancer/templates/deployment.yaml | Pins HAProxy image tag to the chart appVersion to prevent unexpected breakage from :latest. |
| packages/apps/tcp-balancer/templates/configmap.yaml | Renames backends and updates default_backend references to prevent HAProxy 3.3 name-collision startup failure. |
| packages/apps/tcp-balancer/Chart.yaml | Updates appVersion to 3.3.6 to match the intended HAProxy version used by the chart. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
hi guys, thank you for the contribution. |
|
Dear all, |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
NOT LGTM — the rename itself is correct and verified, but the PR rewrites frontend blocks that contain a second fatal config bug with the same "pod won't start" symptom, and the fix ships without any regression test.
Business context: haproxy:latest started resolving to 3.3+, where identical frontend/backend names are a fatal config error, so tcp-balancer pods fail to start (#1966).
Blockers
B1: Undefined ACL whitelist is a fatal config error in the same frontends this PR rewrites
File: packages/apps/tcp-balancer/templates/configmap.yaml:92-98 (and the talos block below)
Issue: tcp-request content accept if whitelist / tcp-request content reject render unconditionally in the kubernetes/talos frontends, while acl whitelist src ... only renders when .Values.whitelist is non-empty (default: []). Same trap in http/https when whitelistHTTP: true with an empty whitelist.
Evidence: rendered the chart with kubernetesAndTalos.endpoints set and the default empty whitelist, then validated with haproxy:3.3.6 haproxy -c:
[ALERT] config : parsing [...] : 'tcp-request content accept' : error detected in frontend 'kubernetes' while parsing 'if' condition : no such ACL : 'whitelist'
[ALERT] config : Fatal errors found in configuration.
This is fatal on every HAProxy version, not just 3.3 — pre-existing, but it produces the exact failure mode this PR claims to fix, in the exact lines it touches.
Impact: any kubernetesAndTalos deployment without a whitelist keeps crash-looping even after this fix.
Fix: move the acl + accept + reject trio inside one shared {{- with $.Values.whitelist }} guard (empty whitelist → no filtering).
B2: No regression test pinning the fix
File: packages/apps/tcp-balancer/ (no tests/ directory)
Issue: CI runs make unit-tests (hack/helm-unit-tests.sh, auto-discovers per-chart tests/, see packages/apps/mongodb/tests/ for the pattern), but nothing asserts the renamed backends or the pinned image. The next template refactor can silently reintroduce the collision.
Fix: add a minimal helm-unittest suite asserting (a) every backend name in the rendered haproxy.cfg differs from every frontend name, (b) the deployment image equals haproxy:<appVersion> and never latest, (c) once B1 is fixed — accept if whitelist never renders without a matching acl whitelist line.
B3: kubernetesAndTalos is used by the template but declared nowhere
File: packages/apps/tcp-balancer/values.yaml, values.schema.json, README.md
Issue: the PR renames backends inside the kubernetesAndTalos blocks, but that key is absent from values.yaml, the schema, the README and the generated types — the values contract for the area being modified is out of sync with the template.
Fix: add the @param annotations and run make generate in the package.
Non-blocking follow-ups
- HAProxy 3.3 is a short-term branch (EOL 2027-Q1). Consider pinning an LTS instead — 3.2.x (supported to 2030) or 3.4.x (to 2031); at minimum bump to the current patch (3.3.10 — 3.3.6 is four patch releases behind). The renamed config validates on 3.2/3.3 alike.
- The identical bug (
haproxy:latest+frontend http/backend http) exists inpackages/apps/http-cache; the config half is already addressed by open PR #2654 — no action needed here, noting for completeness. - PR title isn't in Conventional Commits format (
fix(tcp-balancer): ...), so the auto-labeler applied noarea/*label; the title also feeds the changelog. - Please squash the appVersion follow-up commit into the main commit — this repo merges with merge commits, so both messages land in history as-is.
| bind :::6443 v4v6 | ||
| mode tcp | ||
| default_backend kubernetes | ||
| default_backend kubernetes_backend |
There was a problem hiding this comment.
B1: this kubernetes frontend (and the talos one below) renders tcp-request content accept if whitelist unconditionally, but the acl whitelist line only renders when .Values.whitelist is non-empty. With the default empty whitelist, HAProxy fails to start: no such ACL : 'whitelist' (verified with haproxy:3.3.6 haproxy -c). Same symptom as #1966, fatal on every HAProxy version. Please wrap the acl + accept + reject trio in one shared {{- with $.Values.whitelist }} guard while you're touching these blocks.
There was a problem hiding this comment.
Guarded the whitelist ACL, accept, and reject lines together in 57ccc6d. Rendered both empty and non-empty whitelist configs and validated them with HAProxy 3.4.1.
| topologyKey: kubernetes.io/hostname | ||
| containers: | ||
| - image: haproxy:latest | ||
| - image: "haproxy:{{ .Chart.AppVersion }}" |
There was a problem hiding this comment.
Pinning to appVersion is the right move, but note HAProxy 3.3 is a short-term branch (EOL 2027-Q1). Consider an LTS instead — 3.2.x (supported to 2030) or 3.4.x (to 2031). The renamed config validates fine on both.
There was a problem hiding this comment.
Updated the chart to HAProxy 3.4.1 in 57ccc6d and validated the rendered config with that image.
| type: application | ||
| version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process | ||
| appVersion: "2.9.7" | ||
| appVersion: "3.3.6" |
There was a problem hiding this comment.
3.3.6 is four patch releases behind (current 3.3 tag is 3.3.10), and 3.3 itself is a short-term branch — see the comment on the deployment image line: an LTS (3.2.x / 3.4.x) would be a better long-term pin.
There was a problem hiding this comment.
Updated appVersion to 3.4.1 in 57ccc6d.
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
Re-reviewing on 57ccc6d3. The whitelist ACL problem I raised in June is genuinely fixed, and the rename is complete: all four frontend and backend pairs renamed with every default_backend updated, and backendoptions takes a mode string rather than a backend name so it was never affected. Pinning the image to {{ .Chart.AppVersion }} instead of haproxy:latest is the right move and I would take that on its own.
Still NOT LGTM, because the fix introduced a new state that is worse in one specific way.
With whitelistHTTP: true and whitelist left empty, the http frontend now renders with no access-control rules at all. I rendered both branches to be sure. On main that combination emits tcp-request content accept if whitelist while the acl whitelist line is inside the with block and never emitted, so HAProxy refuses to start with no such ACL: 'whitelist'. On this branch the whole block is gone and the frontend comes up clean, passing everything. Nobody's working configuration changes, since that combination never started, so this is not a regression against a functioning setup. But an explicit security opt-in silently becoming a no-op is worse than a loud crash, because the crash gets noticed within a minute and this does not.
The fix is small: a fail when whitelistHTTP is true and whitelist is empty, matching the pattern already at templates/configmap.yaml:11. This is only needed for the http and https pair. For the kubernetes and talos frontends an empty list correctly means no filtering, because there whitelist is itself the toggle.
Still carried from June, and it is the reason this file has now shipped two independent fatal-config bugs: packages/apps/tcp-balancer has no tests/ directory. CI discovers per-chart helm unittest suites automatically, and a handful of app charts already have them. A suite pinning the rendered config for the default case, the whitelist-set case and the new failure case would have caught both bugs and costs very little.
One correction to my own earlier review: I flagged .Values.kubernetesAndTalos being referenced at configmap.yaml:88 while absent from values.yaml, the schema, the README and the API type. That is entirely pre-existing and this diff neither introduces nor worsens it, so I am not holding the PR on it. It is worth a follow-up while the file is open in front of you.
Two smaller things. haproxy:3.4.2 shipped in July, so the pin is one patch behind the current LTS line, though 3.4 is the right line to be on. And the PR title and one commit message still say 3.3 while the value is 3.4.1, which will read oddly in the changelog.
Non-blocking observation worth acting on separately: nothing will ever bump this pin. .github/renovate.json sets enabledManagers without the helm managers and has no custom matcher for chart image literals, which is the same rot the existing custom matchers were written to prevent. An entry covering chart appVersion image pins would keep this from going stale the way latest did, just in the opposite direction.
Separately from the code: DCO is red. The head commit and the merge commit carry no Signed-off-by, and the two signed commits use a different address than the others. That blocks merge regardless of the review.
…s on 3.3+ (#4366) ## What this PR does `haproxy:latest` now resolves to 3.3 and newer. Since 3.3 a backend named like a frontend is a fatal config error, so every tcp-balancer pod fails at config parse (#1966). We hit it on Cozystack 1.6.1 with `haproxy:3.4.4` behind the tag. - backends get a `_backend` suffix and every `default_backend` follows; the rename is the one from #2321 by @officialasishkumar - the image is `haproxy:{{ .Chart.AppVersion }}` with `appVersion: 3.4.4`, the current 3.4 LTS tag - the whitelist `acl`, `accept` and `reject` lines of each frontend render inside one guard - `tests/` holds helm-unittest suites, and the package `Makefile` gets the `test` target the sweep looks for - the `whitelistHTTP` description says it needs a non-empty `whitelist` Two inputs change behaviour on upgrade. On `main` both fail at config parse with `no such ACL : 'whitelist'` on every HAProxy version, because the `acl` line sits inside the `with` and `accept if whitelist` does not: - `whitelistHTTP: true` with an empty `whitelist` now fails the render with `whitelistHTTP is enabled but whitelist is empty`. Its HelmRelease upgrade fails and the release stays on its old revision, which is already crash-looping. - `kubernetesAndTalos` with an empty `whitelist` now starts, and ports 6443 and 50000 accept any source. With `external: true` the Service is a LoadBalancer and carries both ports. `whitelist` is the only switch those frontends have, so an empty list means no filtering. Every other input renders the same config apart from the backend names. The image and the `checksum/config` annotation change, so the Deployment rolls, and for releases already crash-looping on `latest` the rollout is the fix. Validation: renders of `main` and of this branch for the default, whitelist and empty-whitelist inputs were checked with `haproxy -c` on 2.9.7 and 3.4.4. `helm unittest .` passes 9/9, and removing the `reject` or `accept` line from any single frontend turns a test red. Fixes #1966 ### Screenshots Not a UI change. ### Downstream repositories Walked the trigger map against the diff: chart templates, `Chart.yaml`, the package `Makefile`, `tests/`, and a description-only change in `values.yaml` with its generated carriers. No field is added, removed or renamed and no default changes, so nothing in the map fires. - [x] No downstream repository is affected by this change - [ ] [cozystack/website](https://github.com/cozystack/website) - follow-up: - [ ] [cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack) - follow-up: - [ ] [cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack) - follow-up: - [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up: - [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up: - [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) - follow-up: - [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) - follow-up: - [ ] [cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server) - follow-up: - [ ] [cozystack/external-apps-example](https://github.com/cozystack/external-apps-example) - follow-up: - [ ] [cozystack/examples](https://github.com/cozystack/examples) - follow-up: - [ ] [cozystack/community](https://github.com/cozystack/community) - follow-up: ### Release note ```release-note fix(tcp-balancer): rename HAProxy backends and pin the image to the chart appVersion so the balancer starts on HAProxy 3.3+. whitelistHTTP with an empty whitelist now fails the render; kubernetesAndTalos with an empty whitelist leaves ports 6443 and 50000 unfiltered. ```
What this PR does
Fixes the
tcp-balancerchart so it starts correctly with HAProxy 3.3+.haproxy.cfgso they no longer collide with frontend namesappVersioninstead of pullinghaproxy:latestFixes #1966
Validation
haproxy.cfgwithhaproxy:3.3 haproxy -c -f /usr/local/etc/haproxy/haproxy.cfgRelease note
Summary by CodeRabbit
Release Notes