Skip to content

fix(platform): correct what disabledPackages does to ouroboros - #4098

Merged
Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
fix/disabled-packages-does-not-trigger-ouroboros-hook
Sep 7, 2026
Merged

Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
fix/disabled-packages-does-not-trigger-ouroboros-hook

Conversation

@lexfrei

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

Copy link
Copy Markdown
Contributor

What this PR does

bundles.disabledPackages does not uninstall anything. Two comments in the platform chart said it does, offered next to kubectl delete package.cozystack.io cozystack.ouroboros as if the two were interchangeable.

A name in that list only stops _helpers.tpl emitting the Package document, which is the same suppression you already get from leaving publishing.proxyProtocol false. Every emitted Package carries helm.sh/resource-policy: keep, and that annotation is there precisely so disabling a package stops deleting it, so Helm leaves the Package CR alone. The CR stays, the HelmRelease it owns stays, ouroboros keeps running, and the pre-delete hook never fires because nothing uninstalls the release. Deleting the Package CR is what gets there: GC takes the HelmRelease, Flux uninstalls, the hook runs on the way out.

There was a second cost. The guard in the system bundle looks up the live Package CR and never reads disabledPackages, so an operator who followed the old advice hit the guard anyway with no idea why. New test case pins that.

Comments only in the templates, so rendered output is unchanged. Chart suite green at 156 tests.

Screenshots

Not a UI change.

Downstream repositories

Walked the trigger map against the diff. One repo is reached, and I left its box empty rather than tick it without a link.

cozystack/website has the same wrong instruction verbatim in three files: content/en/docs/next/networking/hairpin-proxy-protocol.md:122, and the identical line under v1.4/ and v1.5/. It tells the reader that removing the Package CR "(or add it to bundles.disabledPackages)" triggers helm uninstall and fires the pre-delete hook. It also contradicts operations/configuration/components.md:72 on the same site, which says disabledPackages will not remove components that are already installed. The site fix is cozystack/website#683. It turned out to be four files rather than three: origin/main there also carries a v1.6 tree, and all four copies were byte-identical.

Nothing else is reached: no package added or renamed, no values.schema.json, no version enum, no default, no key the Ansible role sets, nothing under hack/.

Release note

fix(platform): the platform chart no longer says `bundles.disabledPackages` uninstalls a package. A name in that list only stops the Package document being rendered. `helm.sh/resource-policy: keep` leaves the existing Package CR on the cluster and the component keeps running, so deleting the Package CR is what uninstalls it.

Summary by CodeRabbit

  • Documentation

    • Clarified proxy protocol safety guidance, including the effects of disabling the Ouroboros package and the limitations of using bundles.disabledPackages.
    • Documented that disabling package rendering does not remove an existing live package or stop its associated resources.
  • Tests

    • Added regression coverage confirming that disabling the package does not bypass the proxy protocol safety guard when the live package remains active.

Both the publishing.proxyProtocol comment in values.yaml and the
disable-hazard guard comment in the system bundle told operators that
adding a package name to bundles.disabledPackages triggers the vendored
ouroboros chart's pre-delete Corefile cleanup hook, alongside an
explicit `kubectl delete package.cozystack.io cozystack.ouroboros`.

It does not. A name in disabledPackages only makes the rendering
helper in _helpers.tpl skip emitting the Package document, which is
the same suppression that leaving proxyProtocol false already
performs. Every emitted Package carries helm.sh/resource-policy: keep,
so Helm does not prune the Package it has stopped rendering — that
annotation was added precisely to stop disabling a package from
deleting it. The Package CR survives, the HelmRelease it owns via
ownerReference survives with it, ouroboros keeps running and keeps
re-applying its rewrite block to kube-system/coredns, and the
pre-delete hook never runs because nothing uninstalls the release.

No platform values setting reaches that hook; the operator has to
delete the Package CR. Anyone who followed the old advice was left
with ouroboros still installed and, on the proxyProtocol false
transition, still facing the render guard with no idea why.

Pins the behaviour with a case asserting the guard still fails while
cozystack.ouroboros sits in disabledPackages and the Package CR is
live.

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <[email protected]>
@github-actions github-actions Bot added size/M This PR changes 30-99 lines, ignoring generated files area/platform Issues or PRs related to platform infrastructure (bundle, flux, talos, installer) kind/bug Categorizes issue or PR as related to a bug labels Sep 6, 2026
@coderabbitai

coderabbitai Bot commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: f1f18889-b17f-4682-a883-1e0a60c26027

📥 Commits

Reviewing files that changed from the base of the PR and between 86d62bb and cd6a9b3.

📒 Files selected for processing (3)
  • packages/core/platform/templates/bundles/system.yaml
  • packages/core/platform/tests/bundles_proxy_protocol_lookup_test.yaml
  • packages/core/platform/values.yaml

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

The change clarifies that bundles.disabledPackages suppresses Package rendering but does not remove the live Package. A regression test confirms that the proxy protocol safety guard still fails when cleanup is not acknowledged.

Changes

Proxy protocol guard

Layer / File(s) Summary
Guard documentation and regression test
packages/core/platform/templates/bundles/system.yaml, packages/core/platform/values.yaml, packages/core/platform/tests/bundles_proxy_protocol_lookup_test.yaml
Comments document the Package cleanup behavior. The Helm test verifies that disabling cozystack.ouroboros does not bypass the live Package lookup guard.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to cd6a9

This clarifies that disabling ouroboros rendering does not remove an existing Package or bypass the proxy-protocol cleanup guard, with a regression test preserving that behavior. No merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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…
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: correcting the documented behavior of bundles.disabledPackages for ouroboros. It is concise and specific.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/disabled-packages-does-not-trigger-ouroboros-hook

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.

Verdict

LGTM with non-blocking notes

The comments now say what the code does. disabledPackages gates nothing except the {{- if not (has $name $disabled) }} around the Package document in _helpers.tpl, helm.sh/resource-policy: keep is unconditional on both emitters, and nothing between the platform chart and helm-controller uninstalls a release when the document stops rendering. I checked the reverse reading too, that the code drifted and the old prose was the intended contract. It is the other way round. The keep annotation went in deliberately in 1.1.5 and 1.2.1 (#2273, #2297/#2298), and that changelog entry says in as many words that the deletion behaviour was what contradicted the documented contract. This restores it.

Three MINOR notes, none blocking.

Findings

  • [MINOR] packages/core/platform/tests/bundles_proxy_protocol_lookup_test.yaml:55, the absence asserts in this file and its siblings pass with the forbidden document present
  • [MINOR] packages/core/platform/values.yaml:271, deleting the Package CR is not the only route to the pre-delete hook
  • [MINOR] packages/core/platform/values.yaml:257, the vendored ouroboros version in these comments is a release behind

Still open

The test you added is not vacuous: it asserts failedTemplate with an error pattern, and it goes red when the guard stops firing. Its neighbours are another matter. The sweep in the first finding is worth doing on its own account: right now no assert anywhere in this chart would notice bundles.disabledPackages regressing.

One corner the guard does not cover, and your new comments describe it correctly. Leave proxyProtocol at true and add cozystack.ouroboros to disabledPackages: the document stops rendering, keep retains the live Package, ouroboros keeps running, and the guard never fires because it keys on not .Values.publishing.proxyProtocol. Benign in itself, since the ingress side stays configured for PROXY protocol, but it is a second route to "the operator thinks the package is gone and it is not" with no acknowledgement gate on it.

Left unverified

The uninstall chain the comments assert is intact on a static reading only. internal/operator/package_reconciler.go:290 puts a controller ownerReference from the Package onto the HelmRelease, and nothing under internal/operator/, api/ or packages/core/platform/sources/ sets uninstall or DisableHooks, so Flux's hooks-enabled default applies and the chart's helm.sh/hook: pre-delete Job should fire. I did not run that against a cluster.

Findings not anchored to changed lines

These reference code outside this PR's diff (unchanged files, or lines outside a hunk), so GitHub cannot render them inline.

[MINOR] packages/core/platform/tests/bundles_proxy_protocol_lookup_test.yaml:55 the absence asserts in this file and its siblings pass with the forbidden document present

The new case you added is real coverage. The ones next to it are not. containsDocument with not: true scoped by documentIndex: -1 only searches the last rendered document, and the sibling asserts that omit any: entirely search only the first, so a cozystack.ouroboros (or cozystack.velero) Package rendered anywhere in the middle satisfies the negation. Five asserts across bundles_proxy_protocol_lookup_test.yaml:55-60, bundles_proxy_protocol_lookup_nil_test.yaml:31, bundles_proxy_protocol_test.yaml:21,153,170 and bundles_velero_default_test.yaml:36-45 have that shape. Concretely: the test titled "bundles.disabledPackages suppresses cozystack.ouroboros even when proxyProtocol is true" cannot fail if suppression stops working, which is the exact mechanism this PR's new comments assert. I made disabledPackages inert in the emitter and the whole suite stayed green:

$ review-helper mutate . --mutations mut-disabled-inert-full.json --test 'cd packages/core/platform && helm unittest .'
  make bundles.disabledPackages inert in the Package emitter GAP: the suite stayed green without the fix
      file: packages/core/platform/templates/_helpers.tpl
      | Charts:      1 passed, 1 total
      | Test Suites: 34 passed, 34 total
      | Tests:       156 passed, 156 total

(mutation: {{- if not (has $name $disabled) -}} becomes {{- if true -}} in templates/_helpers.tpl:10)

Control, same mutation with any: true moved inside the matcher on the velero assert:

  CONTROL: disabledPackages inert AND the velero absence assert scoped with any:true covered: the suite went red
      | 			DocumentIndex:	28
      | 			Expected NOT to contain document:
      | 				Kind = Package, apiVersion = cozystack.io/v1alpha1, Name = cozystack.velero
      | Tests:       1 failed, 1 passed, 2 total

And the same control on the file you touched, injecting the forbidden Package by flipping that case to proxyProtocol: true: the current documentIndex: -1 shape stays green (Tests: 4 passed), the any: true shape goes red at DocumentIndex: 15. Fix is mechanical, drop documentIndex: -1 and put any: true inside the containsDocument: map as a sibling of apiVersion/kind/name:

      - containsDocument:
          apiVersion: cozystack.io/v1alpha1
          kind: Package
          name: cozystack.ouroboros
          any: true
        not: true

Kept at MINOR because this PR's own required regression test is non-vacuous and the behaviour these asserts fail to pin is unchanged here. It rises if you consider the suppression assertion load-bearing for the comments this PR just wrote.

# Package it no longer renders. The Package CR stays, so does the
# HelmRelease it owns, ouroboros keeps running, and the pre-delete
# hook never fires. No platform values setting reaches that hook:
# the operator has to delete the Package CR.

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.

[MINOR] deleting the Package CR is not the only route to the pre-delete hook

"No platform values setting reaches that hook" holds: no values key emits a components[].enabled entry and no bundle template builds one. The second half is narrower than the code. Setting spec.components.ouroboros.enabled: false on the live Package CR reaches the same place: internal/operator/package_reconciler.go:915-919 drops a disabled component from desiredReleases, and :951-957 then deletes the HelmRelease as orphaned, which is a Flux uninstall and therefore the pre-delete hook. packages/core/platform/sources/ouroboros.yaml declares the ouroboros component with an install: block, so it is in that set, and once proxyProtocol is false the platform no longer re-renders the Package, so a hand edit survives.

Either say "the operator deletes the Package CR (or disables its component on the live CR)" or keep the recommendation and drop the exclusivity.

# path that triggers the chart's pre-delete Helm hook
# THAT is the path that triggers the chart's pre-delete Helm hook
# (charts/ouroboros/templates/coredns-cleanup-hook.yaml, vendored at
# 0.8.0) — the hook quiesces the controller, sed-strips the

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.

[MINOR] the vendored ouroboros version in these comments is a release behind

Three places still say the hook lives in chart 0.8.0: values.yaml:257, values.yaml:311 and templates/bundles/system.yaml:177. The vendored chart has been 0.8.1 since d542f6636 (2026-07-16):

$ git show d542f6636 -- packages/system/ouroboros/charts/ouroboros/Chart.yaml
-appVersion: 0.8.0
+appVersion: 0.8.1
-version: 0.8.0
+version: 0.8.1
$ grep -n '^version' packages/system/ouroboros/charts/ouroboros/Chart.yaml
25:version: 0.8.1

Pre-existing, and two of the three sit inside the comment blocks this PR is rewriting, so it is cheap to correct in the same pass. The version-specific claim at values.yaml:311 ("In the chart 0.8.0 that path is mostly safe") is the one that will read as stale first.

@lexfrei
Aleksei Sviridkin (lexfrei) merged commit a6caad7 into main Sep 7, 2026
19 checks passed
@lexfrei
Aleksei Sviridkin (lexfrei) deleted the fix/disabled-packages-does-not-trigger-ouroboros-hook branch September 7, 2026 22:52
Aleksei Sviridkin (lexfrei) added a commit to cozystack/website that referenced this pull request Sep 8, 2026
The disable sequence said an operator reaches the ouroboros cleanup hook
either by deleting the Package CR or by putting the name in
`bundles.disabledPackages`. The second one does not work.

`bundles.disabledPackages` is read in one place, the platform chart's
package helper, and all it does there is decide whether the Package
document gets emitted. Every emitted Package carries an unconditional
`helm.sh/resource-policy: keep`, so Helm leaves behind a Package it has
stopped rendering. The Package stays, so does the HelmRelease it owns,
ouroboros keeps running, and the pre-delete hook that strips the rewrite
block from `kube-system/coredns` never fires. Follow the old wording and
the disable looks clean while the rewrite is still live.

That annotation landed in v1.1.5 so that disabling a package stops
deleting it, several releases before the oldest version this page exists
in.

cozystack/cozystack#4098 fixes the same claim in the platform values and
the render guard message.

`hugo --gc --minify` builds clean. `hack/check-i18n.sh` exits 1, but the
four stale-translation errors are on
`content/{de,hi,ru,zh-cn}/_index.md` and are already on main, so
i18n-lint will be red for something this PR did not touch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/platform Issues or PRs related to platform infrastructure (bundle, flux, talos, installer) kind/bug Categorizes issue or PR as related to a bug size/M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants