Skip to content

fix(cluster-install): version-gate OIDC install order; add OCI VMDK and cnpg webhook gotchas#19

Open
Aleksei Sviridkin (lexfrei) wants to merge 1 commit into
mainfrom
fix/cluster-install-oidc-sequence-and-oci-gotchas
Open

fix(cluster-install): version-gate OIDC install order; add OCI VMDK and cnpg webhook gotchas#19
Aleksei Sviridkin (lexfrei) wants to merge 1 commit into
mainfrom
fix/cluster-install-oidc-sequence-and-oci-gotchas

Conversation

@lexfrei

@lexfrei Aleksei Sviridkin (lexfrei) commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Corrects the cluster-install skill's OIDC install-order guidance and adds two provider gotchas that each cost a long real-world debug session.

OIDC at install deadlocks on current releases. The skill previously told the operator to bake authentication.oidc.enabled: true into the Platform Package from the start (its canonical values template hard-set it on). On installer versions ≥ 1.5.0 that deadlocks the install: the flag switches the system bundle to the oidc engine variant, which makes the dashboard dependsOn Keycloak. The dashboard's gatekeeper then needs the root ingress, but the root ingress and the root Tenant CR sit behind the dashboard in the reconcile graph, so the platform plateaus partway (~65% of HelmReleases) and never converges — the root Tenant CR never even appears, so patching it cannot rescue the stall.

Corrected to the supported sequence (matching the project's own e2e, hack/e2e-install-cozystack.bats): apply the Platform Package with OIDC off, let every HelmRelease converge, patch the root Tenant host + ingress, wait for the root ingress controller, and only then flip OIDC on. The root Tenant patch is reframed as what brings up the root ingress with the right domain, not as the deadlock fix, and the values-template default flips to OIDC-off.

Version-gated, not absolute. On v1.4.x the OIDC-off token-proxy dashboard is genuinely broken (its /ping liveness CrashLoops; fixed by a startupProbe backstop in v1.5.0), so OIDC must be enabled at install there; v1.3.x uses a bundled self-issued OIDC with no Keycloak in isp-full. The guidance, the template default, and the provider-pitfalls Keycloak note all carry the three-band gate (v1.3.x / v1.4.x / v1.5.0+) rather than an absolute rule. The underlying deadlock is also fixed on main (post-v1.6.0-rc.2) by defaulting the gatekeeper's OIDC backend to the in-cluster Keycloak URL, so the guidance notes that OIDC-off-then-flip remains the recommended, e2e-verified sequence on all versions rather than presenting the deadlock as permanent.

Off→on toggle hazard. Disabling OIDC after it was enabled strands keycloak-configure in Terminating (its Helm pre-delete teardown fails on RBAC, the release secret sticks in uninstalling); recovery steps are included. Installing OIDC-off and flipping it on once avoids the churn.

New failure-mode docs. OCI Talos image boot: current Talos disk images (1.11.5+) do not boot on OCI when imported from qcow2 (UEFI shell / empty BIOS console, API never answers; siderolabs/talos#12557) — the same disk imported as a stream-optimized VMDK with BIOS firmware boots fine; added with the practice of verifying boot on a throwaway instance before recreating the cluster. cnpg webhook: on Cilium + KubeOVN the cloudnative-pg operator flaps on leader-election during early convergence and restarts with a new pod IP, and Cilium's host-side service BPF keeps the stale endpoint, so the apiserver gets connection refused on the webhook ClusterIP (failurePolicy: Fail blocks Keycloak and every postgres-backed release) while pods reach it fine; added the host-network-vs-pod-network diagnostic and the operator rollout-restart recovery.

The claims were checked against the monorepo source (engine variant selection, the oidc-variant dashboard→keycloak-configure dependency, the e2e install sequence, incloud-web-gatekeeper naming, and the v1.5.0 token-proxy startupProbe fix).

Summary by CodeRabbit

  • Documentation

    • Updated cluster installation guidance with a safer, version-aware OIDC setup sequence.
    • Added instructions for configuring the root tenant for public URLs before enabling OIDC.
    • Expanded troubleshooting for stalled OIDC setups, Keycloak recovery, CNPG webhooks, and OCI disk imports.
    • Updated installation examples and provider-specific guidance for recent platform versions.
  • Chores

    • Incremented the plugin version to 1.15.1.

…nd cnpg gotchas

Correct the OIDC install-order guidance and add two provider gotchas that
each cost a long real-world debug session.

OIDC install order, version-gated. On installer_version >= 1.5.0, enabling
authentication.oidc.enabled in the Platform Package at install time
deadlocks the install: the flag switches the system bundle to the oidc
engine variant, which makes the dashboard dependsOn Keycloak. The
dashboard's gatekeeper then needs the root ingress, but the root ingress
and the root Tenant CR sit behind the dashboard in the reconcile graph, so
the platform plateaus partway and never converges; the root Tenant CR does
not even appear, so patching it cannot rescue the stall. Reframe Phase 4 /
Phase 8 to the supported sequence (matching cozystack's own e2e): apply the
Platform Package with OIDC off, let every HelmRelease converge, patch the
root Tenant host + ingress, wait for the root ingress controller, and only
then flip OIDC on. Flip the canonical Platform Package template default to
OIDC-off to match (it previously baked OIDC on at install, which was the
actual landmine). Present the root Tenant patch as what brings up the root
ingress with the right domain, not as the deadlock fix. Document the
off->on toggle hazard (disabling OIDC strands keycloak-configure in
Terminating) with revision-agnostic recovery, rewrite the stalled-install
recovery to disable OIDC first, and correct the gatekeeper Deployment name
to incloud-web-gatekeeper.

Keep the v1.4.x path intact: on v1.4.x the OIDC-off token-proxy dashboard
is broken (/ping liveness CrashLoop, fixed by a startupProbe backstop in
v1.5.0), so OIDC must be enabled at install there. The guidance, the
values-template default, and the provider-pitfalls Keycloak note are all
version-gated (v1.3.x self-issued OIDC / v1.4.x OIDC-at-install / v1.5.0+
OIDC-off-then-flip) rather than stated absolutely.

OCI Talos image boot. Current Talos disk images (1.11.5+) do not boot on
OCI when imported from qcow2 (UEFI shell / empty BIOS console, API never
answers). The same disk imported as a streamOptimized VMDK with firmware
BIOS boots fine. Add the workaround and the practice of verifying boot on
a throwaway instance before recreating the whole cluster.

cnpg webhook unreachable from the apiserver. On Cilium + KubeOVN the
cloudnative-pg operator flaps on leader-election during early KubeOVN
convergence and restarts with a new pod IP; Cilium's host-side service BPF
keeps the stale endpoint, so the apiserver gets connection refused on the
webhook ClusterIP (failurePolicy=Fail blocks keycloak and every
postgres-backed release) while pods reach it fine. Add the
host-network-vs-pod-network diagnostic and the rollout-restart recovery.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The cluster-install documentation now describes deferred OIDC enablement for installer versions 1.5.0 and newer, including root-tenant ingress preparation and recovery procedures. It also adds OCI image troubleshooting, CNPG webhook diagnostics, updated Keycloak guidance, and a plugin version bump.

Cluster installation guidance

Layer / File(s) Summary
OIDC installation sequence
plugins/cozystack/skills/cluster-install/SKILL.md, plugins/cozystack/skills/cluster-install/references/values-template.md, plugins/cozystack/skills/cluster-install/references/provider-pitfalls.md
Documents installing with OIDC disabled, patching tenants/root, waiting for ingress readiness, and enabling OIDC once after convergence, with version-specific Keycloak behavior and guardrails.
Failure recovery and diagnostics
plugins/cozystack/skills/cluster-install/references/known-failures.md
Updates gatekeeper log collection, expands OIDC stall avoidance and recovery, and adds CNPG webhook connectivity diagnosis and recovery steps.
Provider and release guidance
plugins/cozystack/skills/cluster-install/references/provider-pitfalls.md, plugins/cozystack/.claude-plugin/plugin.json
Adds OCI VMDK import and BIOS troubleshooting guidance and increments the plugin version to 1.15.1.

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

Sequence Diagram(s)

sequenceDiagram
  participant Installer
  participant PlatformPackage
  participant RootTenant as tenants/root
  participant Ingress as root-ingress-controller
  participant AuthProxy as auth-proxy
  Installer->>PlatformPackage: apply with OIDC disabled
  Installer->>RootTenant: patch host and ingress
  Installer->>Ingress: wait for availability
  Installer->>PlatformPackage: enable OIDC once
  PlatformPackage->>AuthProxy: roll out and verify auth-proxy
Loading

Possibly related PRs

  • cozystack/ccp#14: Related OIDC/Keycloak sequencing and tenants/root ingress patch guidance.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the PR’s main changes: version-gated OIDC install flow plus OCI VMDK and CNPG webhook troubleshooting notes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cluster-install-oidc-sequence-and-oci-gotchas

Warning

Tools execution failed with the following error:

Failed to run tools: 14 UNAVAILABLE: read ECONNRESET


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.

@lexfrei
Aleksei Sviridkin (lexfrei) marked this pull request as ready for review July 20, 2026 13:35

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request updates the cozystack plugin to version 1.15.1 and significantly refines the cluster-install skill documentation. It introduces a critical installation sequence change for installer versions >= 1.5.0, recommending that OIDC be disabled during initial install to avoid deadlocks and enabled only after convergence. It also adds troubleshooting sections for CNPG webhook issues on Cilium and OCI Talos boot failures. The review feedback is highly accurate, pointing out that the --force flag is invalid for flux reconcile hr and that the standard busybox version of nc does not support the -z and -v flags.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

--type merge --patch '{"metadata":{"finalizers":null}}'
kubectl --context $CTX --namespace cozy-keycloak delete secret \
--selector owner=helm,name=keycloak-configure,status=uninstalling
flux --context $CTX --namespace cozy-keycloak reconcile hr keycloak-configure --force

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The flux reconcile helmrelease (or flux reconcile hr) command does not support a --force flag. Running this command with --force will result in an unknown flag: --force error. Remove the --force flag to ensure the command executes successfully.

Suggested change
flux --context $CTX --namespace cozy-keycloak reconcile hr keycloak-configure --force
flux --context $CTX --namespace cozy-keycloak reconcile hr keycloak-configure

Comment on lines +101 to +105
kubectl --context $CTX run nc-pod --rm --stdin --tty --restart=Never \
--image=busybox -- nc -zvw3 $WEBHOOK_CIP 443 # from pod network → OK
kubectl --context $CTX run nc-host --rm --stdin --tty --restart=Never \
--overrides='{"spec":{"hostNetwork":true}}' \
--image=busybox -- nc -zvw3 $WEBHOOK_CIP 443 # from host network → refused

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The standard busybox image's nc (netcat) utility does not support the -z (zero-I/O mode) or -v (verbose) flags. Running nc -zvw3 in a standard busybox container will fail with nc: invalid option -- 'z'. To perform a reliable port check using busybox, redirect /dev/null to stdin and use the -w flag for timeout.

Suggested change
kubectl --context $CTX run nc-pod --rm --stdin --tty --restart=Never \
--image=busybox -- nc -zvw3 $WEBHOOK_CIP 443 # from pod network → OK
kubectl --context $CTX run nc-host --rm --stdin --tty --restart=Never \
--overrides='{"spec":{"hostNetwork":true}}' \
--image=busybox -- nc -zvw3 $WEBHOOK_CIP 443 # from host network → refused
kubectl --context $CTX run nc-pod --rm --stdin --tty --restart=Never \
--image=busybox -- sh -c "nc -w3 $WEBHOOK_CIP 443 < /dev/null" # from pod network → OK
kubectl --context $CTX run nc-host --rm --stdin --tty --restart=Never \
--overrides='{"spec":{"hostNetwork":true}}' \
--image=busybox -- sh -c "nc -w3 $WEBHOOK_CIP 443 < /dev/null" # from host network → refused

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/cozystack/skills/cluster-install/references/known-failures.md`:
- Line 74: The documented recovery flow incorrectly skips OIDC re-enablement
when OIDC is already disabled. Update the post-convergence instructions in the
“apply the tenant patch alone” path to skip only disabling OIDC, then enable it
exactly once after root-ingress-controller is Available and wait for the
incloud-web-gatekeeper rollout when dashboard SSO is requested.

In `@plugins/cozystack/skills/cluster-install/SKILL.md`:
- Line 688: Update the OIDC-off-then-flip recommendation in the cluster
installation guidance to apply only to installer versions v1.5.0 and newer,
replacing the “all versions” wording while preserving the existing v1.4.x
exception.
- Line 3: Normalize all internal skill references to slash-prefixed links:
update the references in plugins/cozystack/skills/cluster-install/SKILL.md:3-3
to /cozystack:cluster-upgrade, /cozystack:cluster-install, and
/cozystack:talos-bootstrap; update
plugins/cozystack/skills/cluster-install/references/provider-pitfalls.md:20-20
to /cozystack:talos-bootstrap and :116-116 to /cozystack:cluster-install; update
plugins/cozystack/skills/cluster-install/references/known-failures.md:43-43 to
/cozystack:cluster-install. Ensure each link resolves to an existing skill
directory.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6ba221a6-f082-4009-98e7-369beae808b6

📥 Commits

Reviewing files that changed from the base of the PR and between a0b3e6d and 53b1a3f.

📒 Files selected for processing (5)
  • plugins/cozystack/.claude-plugin/plugin.json
  • plugins/cozystack/skills/cluster-install/SKILL.md
  • plugins/cozystack/skills/cluster-install/references/known-failures.md
  • plugins/cozystack/skills/cluster-install/references/provider-pitfalls.md
  • plugins/cozystack/skills/cluster-install/references/values-template.md

- the dashboard (token-proxy container) and the rest of the chain reach Ready; the cluster converges to `N/N Ready`.

The whole cluster typically reaches `N/N Ready` within 5 min of the patch.
Once every HR is Ready and `root-ingress-controller` is Available, re-enable OIDC exactly once (SKILL.md Phase 8 step 3) and wait for the `incloud-web-gatekeeper` rollout. If the cluster was already OIDC-off (the operator followed the skill and only the tenant patch was missing), skip the disable/re-enable steps and apply the tenant patch alone.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not skip the post-convergence OIDC flip when OIDC is already off.

If the operator followed the new flow and only the tenant patch was missing, “apply the tenant patch alone” leaves OIDC disabled even when dashboard SSO was requested. Skip only the disable step; still enable OIDC exactly once after ingress is ready.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/cozystack/skills/cluster-install/references/known-failures.md` at
line 74, The documented recovery flow incorrectly skips OIDC re-enablement when
OIDC is already disabled. Update the post-convergence instructions in the “apply
the tenant patch alone” path to skip only disabling OIDC, then enable it exactly
once after root-ingress-controller is Available and wait for the
incloud-web-gatekeeper rollout when dashboard SSO is requested.

---
name: cluster-install
description: Use when installing Cozystack on an existing Kubernetes cluster (kubeadm / k3s / RKE2 / managed). Discovers cluster facts, validates node readiness via kubectl debug, recommends an installer + platform variant, gathers values interactively, creates the ZFS pool on each storage node through kubectl debug (cozystack standardises on ZFS for LINSTOR — LVM / LVM-thin paths are not supported), installs extractedprism (per-node kube-apiserver HA proxy, generic variant default), installs the cozy-installer chart, applies the Platform Package, patches the root Tenant for ingress (breaks the OIDC chicken-and-egg), waits until every HelmRelease is Ready, prints a NOTES-style access summary, and offers an issue-template handoff to cozystack/* on fatal failure. Not for Kubernetes bootstrap and not for upgrades — see `cozystack:cluster-upgrade` for that. Talos node-prep is out of scope — `cozystack:cluster-install` refuses if Talos nodes are missing cozystack-tuned extensions and points at `cozystack:talos-bootstrap`.
description: Use when installing Cozystack on an existing Kubernetes cluster (kubeadm / k3s / RKE2 / managed). Discovers cluster facts, validates node readiness via kubectl debug, recommends an installer + platform variant, gathers values interactively, creates the ZFS pool on each storage node through kubectl debug (cozystack standardises on ZFS for LINSTOR — LVM / LVM-thin paths are not supported), installs extractedprism (per-node kube-apiserver HA proxy, generic variant default), installs the cozy-installer chart, applies the Platform Package (on current releases OIDC is enabled after convergence, not at install), patches the root Tenant host + ingress, waits until every HelmRelease is Ready, prints a NOTES-style access summary, and offers an issue-template handoff to cozystack/* on fatal failure. Not for Kubernetes bootstrap and not for upgrades — see `cozystack:cluster-upgrade` for that. Talos node-prep is out of scope — `cozystack:cluster-install` refuses if Talos nodes are missing cozystack-tuned extensions and points at `cozystack:talos-bootstrap`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Normalize all internal skill references to slash-prefixed links.

  • plugins/cozystack/skills/cluster-install/SKILL.md#L3-L3: use /cozystack:cluster-upgrade, /cozystack:cluster-install, and /cozystack:talos-bootstrap.
  • plugins/cozystack/skills/cluster-install/references/provider-pitfalls.md#L20-L20: use /cozystack:talos-bootstrap.
  • plugins/cozystack/skills/cluster-install/references/provider-pitfalls.md#L116-L116: use /cozystack:cluster-install.
  • plugins/cozystack/skills/cluster-install/references/known-failures.md#L43-L43: use /cozystack:cluster-install.

As per coding guidelines, internal skill references must follow /<plugin>:<skill> and resolve to an actual skill directory.

📍 Affects 3 files
  • plugins/cozystack/skills/cluster-install/SKILL.md#L3-L3 (this comment)
  • plugins/cozystack/skills/cluster-install/references/provider-pitfalls.md#L20-L20
  • plugins/cozystack/skills/cluster-install/references/provider-pitfalls.md#L116-L116
  • plugins/cozystack/skills/cluster-install/references/known-failures.md#L43-L43
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/cozystack/skills/cluster-install/SKILL.md` at line 3, Normalize all
internal skill references to slash-prefixed links: update the references in
plugins/cozystack/skills/cluster-install/SKILL.md:3-3 to
/cozystack:cluster-upgrade, /cozystack:cluster-install, and
/cozystack:talos-bootstrap; update
plugins/cozystack/skills/cluster-install/references/provider-pitfalls.md:20-20
to /cozystack:talos-bootstrap and :116-116 to /cozystack:cluster-install; update
plugins/cozystack/skills/cluster-install/references/known-failures.md:43-43 to
/cozystack:cluster-install. Ensure each link resolves to an existing skill
directory.

Source: Coding guidelines

So for a usable dashboard the skill must enable OIDC. This is exactly what cozystack's own e2e (`hack/e2e-install-cozystack.bats`) does — patch the root tenant host, then enable OIDC and expose Keycloak:
**Install with OIDC OFF, converge, THEN flip it on (installer_version ≥ 1.5.0).** On 1.6.x, setting `authentication.oidc.enabled: true` in the Platform Package before the platform has converged DEADLOCKS the install. The flag switches the system bundle to the `oidc` engine variant (`packages/core/platform/templates/bundles/system.yaml` selects `cozystack.cozystack-engine` variant `oidc` when `authentication.oidc.enabled`), which pulls Keycloak into the dashboard's dependency chain: on the `oidc` variant the `dashboard` component `dependsOn: keycloak-configure` and the engine itself `dependsOn cozystack.keycloak, cozystack.keycloak-operator` (`packages/core/platform/sources/cozystack-engine.yaml`); on the `default` variant the dashboard depends only on `cozystack-api`/`cozystack-controller`/`application-definition-crd`. The dashboard's gatekeeper (oauth2-proxy) then also needs to reach Keycloak's public URL, which is only served once the root ingress is up — but the root ingress and the root Tenant CR sit behind the dashboard in the reconcile graph. Net cycle: dashboard needs Keycloak + ingress, ingress needs the dashboard-gated chain, so the install plateaus partway (e.g. ~65% of HRs) and never converges. Patching a tenant CR does NOT rescue this — on the `oidc` variant the tenant CR does not even appear until the dashboard-gated chain unblocks, which with OIDC on it never does.

The underlying deadlock is fixed on `main` (post-v1.6.0-rc.2) by defaulting the gatekeeper's OIDC backend to the in-cluster Keycloak URL, so the gatekeeper skips external discovery and no longer needs the root ingress at startup; this is not yet in a released tag. OIDC-off-then-flip remains the recommended, e2e-verified sequence on all versions.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Limit the OIDC-off sequence to installer versions ≥ 1.5.0.

Line 688 says this remains recommended “on all versions,” contradicting the preceding v1.4.x exception, where OIDC must be enabled at install. Change this to “v1.5.0+” to avoid breaking v1.4.x installations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/cozystack/skills/cluster-install/SKILL.md` at line 688, Update the
OIDC-off-then-flip recommendation in the cluster installation guidance to apply
only to installer versions v1.5.0 and newer, replacing the “all versions”
wording while preserving the existing v1.4.x exception.

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.

1 participant