Skip to content

fix(kamaji): resolve Gateway API availability once at startup - #4501

Merged
IvanHunters merged 1 commit into
mainfrom
fix/kamaji-gateway-discovery-once
Oct 5, 2026
Merged

IvanHunters merged 1 commit into
mainfrom
fix/kamaji-gateway-discovery-once

Conversation

@lexfrei

@lexfrei Aleksei Sviridkin (lexfrei) commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does

Carries the fix proposed upstream in clastix/kamaji#1327 (not yet merged there; issue clastix/kamaji#1326) as a build patch on the 26.9.4-edge tag that cozystack builds Kamaji from.

In Kamaji 26.9.4-edge, every TenantControlPlane reconcile checks whether the Gateway API is available. The discovery call ignores the reconcile context, so it is bounded only by the client's 32s default timeout, which is longer than the 30s reconcile budget. The watches, however, read availability only once, at startup.

With the patch, Kamaji resolves availability once when the manager starts. The watches, the indexer, the reconciled resources and the admission webhook's Gateway API check all use that one value. A discovery error at startup now stops the manager, so it is no longer mistaken for "Gateway API not installed". A Gateway API installed after Kamaji starts needs a Kamaji restart. On this platform that case does not come up: the kamaji package depends on cert-manager, and cert-manager depends on gateway-api-crds.

The webhook's separate TLSRoute check still runs discovery on each request, as before, and is listed as a follow-up in clastix/kamaji#1327. Kamaji's chart sets no timeoutSeconds on the webhook, so the apiserver's 10s default applies, and a discovery call that can take up to the client's 32s can make that admission time out.

The patch is the upstream commit applied unchanged except for the dropped docs hunk, which is not part of the image. It applies cleanly to 26.9.4-edge with no offsets. It modifies different files than the existing fix-kubelet-config-compat.diff, so the two apply in either order. The upstream tests stay in the patch so that it matches the upstream commit; the image build does not run them. On the patched tree, go build ./... passes, and go test -race passes for ./controllers/..., ./internal/webhook/..., ./internal/utilities/..., ./internal/kubeadm/... and ./cmd/.... I also checked that the new tests can fail: they go red when the availability check is inverted and when the old per-reconcile lookup is put back.

If clastix/kamaji#1327 changes before it merges, this patch should be updated to match. It is dropped once Kamaji ships the change.

Refs #4489. This does not close #4489, because this change does not explain the long stall reported there.

Screenshots

No UI change.

Downstream repositories

Release note

fix(kamaji): Kamaji now checks for the Gateway API once at startup instead of on every TenantControlPlane reconcile, so a slow discovery endpoint can no longer use up the reconcile timeout.

Summary by CodeRabbit

  • Bug Fixes
    • Gateway API availability is now checked at startup and consistently applied to Gateway-related setup and configuration validation.
    • Gateway configuration is rejected if the Gateway API was unavailable when Kamaji started. If you install the required CRDs afterward, restart Kamaji before configuring Gateway resources.
    • Discovery errors now stop startup rather than allowing Kamaji to continue with an uncertain Gateway API status.

Kamaji checked for the Gateway API on every TenantControlPlane
reconcile. That discovery call ignores the reconcile context, so it is
bounded only by the client's 32s default timeout, which is longer than
the 30s reconcile budget. A slow discovery endpoint could therefore use
up the whole reconcile. The result could also disagree with the
watches, which were set up once at startup.

The patch carries the fix proposed upstream in clastix/kamaji#1327,
not yet merged there, onto the Kamaji tag cozystack ships.
Availability is resolved once when the manager starts, and the same
value drives the watches, the indexer, the reconciled resources and the
admission webhook's Gateway API check. A discovery error at startup now
stops the manager, so it is no longer read as "Gateway API not
installed". A Gateway API installed after Kamaji starts needs a Kamaji
restart. On this platform Kamaji depends on cert-manager, which depends
on gateway-api-crds, so the CRDs are already present when Kamaji
starts.

The patch keeps the upstream tests so that it matches the upstream
commit. The docs hunk is left out because it is not part of the image.
Drop this patch once Kamaji ships the change.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <[email protected]>
@github-actions github-actions Bot added area/kamaji Issues or PRs related to Kamaji (hosted control planes for tenant Kubernetes) kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files labels Sep 26, 2026
@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: cozystack/cozystack/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 17573323-706f-4b0d-a90c-652286cefd4a

📥 Commits

Reviewing files that changed from the base of the PR and between b113cc7 and dab250d.

📒 Files selected for processing (1)
  • packages/system/kamaji/images/kamaji/patches/fix-gateway-discovery-once.diff

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

Gateway API availability is resolved once during manager startup. The result controls GatewayListener setup, Gateway resource selection, route ownership watches, and webhook validation. Reconciliation no longer performs Gateway API availability discovery.

Changes

Gateway API availability

Layer / File(s) Summary
Resolve availability at startup
packages/system/kamaji/images/kamaji/patches/fix-gateway-discovery-once.diff
Manager startup resolves Gateway API availability and passes the result to the reconciler and webhook. GatewayListener setup uses the same result.
Use availability in resource reconciliation
packages/system/kamaji/images/kamaji/patches/fix-gateway-discovery-once.diff
Resource construction selects Gateway resources from GatewayAPIAvailable without RESTMapper discovery. The reconciler uses the value to register route ownership watches. Tests verify resource selection and the absence of RESTMapper lookups.
Validate Gateway configuration
packages/system/kamaji/images/kamaji/patches/fix-gateway-discovery-once.diff
Webhook validation rejects Gateway configuration when Gateway APIs were unavailable at startup. TLSRoute availability remains a separate check. Tests cover creation and update cases.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant ManagerStartup
  participant GatewayDiscovery
  participant TenantControlPlaneReconciler
  participant TenantControlPlaneGatewayValidation
  ManagerStartup->>GatewayDiscovery: Resolve Gateway API availability
  GatewayDiscovery-->>ManagerStartup: Availability result or discovery error
  ManagerStartup->>TenantControlPlaneReconciler: Pass GatewayAPIAvailable
  ManagerStartup->>TenantControlPlaneGatewayValidation: Pass GatewayAPIAvailable
Loading

Merge Risk: ⚪ Minimal · up to dab25

The Gateway API availability change is mergeable after normal checks. It does not address the separately reported TenantControlPlane cleanup stall.

Architecture Summary

Architecture risk: 🔵 Low · up to dab25

The change affects 1 system.

Changed systems: packages/system

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — packages/system (library) was modified; 1 changed file maps to changed impact.

Before / after behavior

  • observed — Modified behavior in packages/system/kamaji/images/kamaji/patches/fix-gateway-discovery-once.diff: Manager startup now resolves Gateway API availability once, logs and returns discovery errors, and passes the result to the reconciler and webhook. The same result controls GatewayListener setup instead of performing a separate availability check.
  • observed — Modified behavior in packages/system/kamaji/images/kamaji/patches/fix-gateway-discovery-once.diff: GroupResourceBuilderConfiguration replaces its discovery client with a GatewayAPIAvailable boolean. GetResources uses that value to include or omit Kubernetes and Konnectivity Gateway resources, rather than discovering availability during resource construction.
  • observed — Modified behavior in packages/system/kamaji/images/kamaji/patches/fix-gateway-discovery-once.diff: Adds tests that count RESTMapper lookups and verify GetResources makes none for either availability value. Additional cases verify that both Gateway resource types are included exactly when GatewayAPIAvailable is true.
  • observed — Modified behavior in packages/system/kamaji/images/kamaji/patches/fix-gateway-discovery-once.diff: TenantControlPlaneReconciler replaces its discovery client field with GatewayAPIAvailable, passes that value into resource construction, and uses it to decide whether to register HTTPRoute and GRPCRoute ownership. The previous runtime availability check is removed.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Issue [#4489] requires a deleted TenantControlPlane to lose its finalizer and its Deployment to be removed within seconds. The patch changes only Gateway API discovery, watches, resource selection, an… Implement and test a bounded deletion reconcile for [#4489]. The cleanup path must complete with the reconcile context, remove the finalizer after successful cleanup, and remove the TenantControlPlane and Deployment within the required time…
Out of Scope Changes check ⚠️ Warning Relative to directly linked issue [#4489], the complete PR diff is unrelated. It resolves Gateway API availability at startup and changes Gateway watches, resource reconciliation, and admission behavi… Remove the Gateway API discovery patch from this PR or link it to an active issue that requires this Gateway API behavior. Keep this PR scoped to the [#4489] deletion and cleanup failure.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: resolving Gateway API availability once during startup.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Full details: Linked Issues check

Explanation

Issue [#4489] requires a deleted TenantControlPlane to lose its finalizer and its Deployment to be removed within seconds. The patch changes only Gateway API discovery, watches, resource selection, and webhook validation. It does not change the stalled reconcile or the DataStore cleanup path, and it adds no test for deletion cleanup. The PR description also states that this change does not explain the reported stall.

Resolution

Implement and test a bounded deletion reconcile for [#4489]. The cleanup path must complete with the reconcile context, remove the finalizer after successful cleanup, and remove the TenantControlPlane and Deployment within the required time.

Full details: Out of Scope Changes check

Explanation

Relative to directly linked issue [#4489], the complete PR diff is unrelated. It resolves Gateway API availability at startup and changes Gateway watches, resource reconciliation, and admission behavior. No changed code connects this behavior to the TenantControlPlane finalizer or Deployment cleanup. The PR explicitly disclaims a fix for the [#4489] stall.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@IvanHunters IvanHunters left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. Clean carry of upstream clastix/kamaji#1327 as a build patch on the 26.9.4-edge tag, and it fixes the right thing at the root.

The core change resolves Gateway API availability once at manager startup instead of on every TenantControlPlane reconcile. It holds up on the two questions that matter for a "read a signal once and cache it" change.

A discovery error is no longer swallowed as "not installed". The old utilities.AreGatewayResourcesAvailable returned a bare bool and turned any discovery error into false; the new utilities.GatewayAPIResourcesAvailable returns (bool, error), and cmd/manager/cmd.go now logs and returns that error, which stops the manager. A transient discovery blip crashloops and retries instead of latching "Gateway unavailable" for the life of the process. That is the fix, and it is correct.

A Gateway API CRD installed after startup needs a restart, and the webhook says so: "install the Gateway API CRDs and restart Kamaji". Before this patch the watches were already startup-only while reconcile and the webhook discovered live, so a late install left the controller reconciling Gateway resources it did not watch. After the patch the whole path follows one value and fails closed with a clear message. On this platform the late-install case does not arise: cozystack.kamaji dependsOn cozystack.cert-manager, which dependsOn cozystack.gateway-api-crds, so the CRDs are present before Kamaji starts.

Checked statically and against CI. GatewayAPIResourcesAvailable exists at the 26.9.4-edge tag with the expected signature. The internal/utilities import is dropped only from the two files that stop referencing it and kept where it is still used (cmd.go, and the webhook's TLSRoute check). The removed DiscoveryClient struct fields are read nowhere else. The "Build packages/system/kamaji" job (git apply + go build on the real tag), the in-tree E2E and the unit/controller suites are all green.

Non-blocking:

  • The webhook's separate TLSRoute check still runs live discovery on every admission request and can still hit the apiserver's 10s admission timeout. This one is pre-existing, unchanged here, and already listed as an upstream follow-up, so it is not something this PR introduced.
  • A discovery failure at startup now crashloops the manager instead of silently disabling Gateway support. That is the intended fail-loud behavior, worth knowing about operationally.
  • This is a verbatim carry of an unmerged upstream PR. It needs a re-sync if upstream changes before it merges, and should be dropped once Kamaji ships the change. The description already commits to both.

@IvanHunters
IvanHunters enabled auto-merge October 5, 2026 11:43
@IvanHunters
IvanHunters merged commit f9f7562 into main Oct 5, 2026
20 checks passed
@IvanHunters
IvanHunters deleted the fix/kamaji-gateway-discovery-once branch October 5, 2026 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/kamaji Issues or PRs related to Kamaji (hosted control planes for tenant Kubernetes) kind/bug Categorizes issue or PR as related to a bug size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kamaji: deleted TenantControlPlane stays on its finalizer after a stalled reconcile

2 participants