feat(flux): upgrade to v2.8.0 + chart fixes for strict SSA & kstatus (folds #2612) - #2602
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request updates the Flux CD stack to version 2.8.x to leverage new Helm controller capabilities. The primary motivation is to enable advanced health checking for Helm releases, which will support more robust dependency management for various system packages. The changes include updating the vendored charts, adjusting the distribution version, and ensuring the new web interface remains disabled by default to maintain existing operational standards. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughBump flux-operator/flux-instance charts to v0.48.0; add Flux Status Web UI (templates, helpers, values/schema); update CRDs to controller-gen v0.20.0; add/gate RBAC, Ingress/HTTPRoute, NetworkPolicy; simplify many HelmRelease upgrade/dependsOn patterns; app template fixes; seaweedfs-db chart + migration; increase e2e timeouts and bump helm-controller image. ChangesFlux Operator Chart
Flux Instance Chart
HelmRelease & app adjustments
Sequence DiagramsequenceDiagram
participant User
participant Ingress
participant HTTPRoute
participant Service
participant Pod
participant HelmChart
User->>Ingress: HTTP request (host/path)
Ingress->>Service: route to service:http-web (port 9080)
HTTPRoute->>Service: optional Gateway routing to 9080
Service->>Pod: forward to container port 9080
HelmChart->>Pod: provide web config secret (if createWebConfigSecret)
HelmChart->>Pod: set args/env (--web-server-only, WEB_SERVER_PORT)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Suggested labels
Suggested reviewers
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Code Review
This pull request updates the FluxCD version to 2.8.x and introduces an opt-in configuration for the Flux Status Web UI in the fluxcd-operator, which is disabled by default. Feedback suggests explicitly disabling the upstream chart's built-in NetworkPolicy for the Web UI to prevent potential resource conflicts with Cozystack's custom Cilium policies.
| web: | ||
| enabled: false |
There was a problem hiding this comment.
Since Cozystack provides a custom CiliumClusterwideNetworkPolicy for the Flux Status Web UI (as mentioned in the PR description), it is recommended to disable the built-in NetworkPolicy created by the upstream chart. This avoids redundant or conflicting resources if a user later opts-in by setting web.enabled: true.
web:
enabled: false
networkPolicy:
create: falseThere was a problem hiding this comment.
Done in d0480f4 — pinned flux-operator.web.networkPolicy.create: false. The Cozystack-shipped CiliumClusterwideNetworkPolicy already restricts ports 8080/8081/9080, so this keeps the Cilium policy as the single source of truth even if a user later opts in to web.enabled: true. helm template with web.enabled=true confirms no upstream NetworkPolicy is rendered.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
packages/system/fluxcd-operator/charts/flux-operator/templates/web-clusterrole.yaml (1)
16-24: Security consideration: Web-server-only mode grants cluster-wide read + user impersonation.When web-server-only mode is enabled, this ClusterRole grants:
- Cluster-wide read access to all API groups and resources
- Impersonation of any user or group
These permissions enable the Flux Web UI to provide multi-tenant views but represent significant privilege. If the web UI were compromised, an attacker would gain cluster-wide read access and could bypass authorization checks via impersonation.
The PR correctly defaults
web.enabled: falseto keep this opt-in. Operators should understand these security implications before enabling the web UI, especially in multi-tenant environments. Consider documenting the security model and recommending network isolation (e.g., internal-only ingress) when the web UI is enabled.🤖 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 `@packages/system/fluxcd-operator/charts/flux-operator/templates/web-clusterrole.yaml` around lines 16 - 24, The ClusterRole in web-clusterrole.yaml currently grants cluster-wide read ("apiGroups":["*"], "resources":["*"], verbs:["get","list","watch"]) and unrestricted impersonation ("resources":["users","groups"], verbs:["impersonate"]), which is overly privileged for the web UI; change the template to narrow permissions by replacing the wildcard apiGroups/resources block (the apiGroups/resources/verbs entries) with only the specific API groups and resources the web UI actually needs, remove the impersonate verbs unless impersonation is strictly required, and if impersonation is required restrict scope by converting to a namespaced Role or by binding the ClusterRole only to the web serviceAccount (instead of granting impersonation to broad subjects); also add a short comment in web-clusterrole.yaml explaining the remaining privileges and a note to operators about the security implications.packages/system/fluxcd-operator/charts/flux-operator/templates/web-standard-roles.yaml (1)
1-131: ⚖️ Poor tradeoffHeads-up on RBAC blast radius when operators opt into the web UI.
Vendored upstream content looks intact and correctly gated by
flux-operator.createWebRoles/flux-operator.createWebRolesAggregation(both requireweb.enabled: true), so this template renders to nothing under the chart's default. No action needed for this PR.Two things worth surfacing in the opt-in docs / release note for downstream operators who enable
web.enabled: true:
flux-web-userandflux-web-admingrant cluster-wideget/list/watchonapiGroups: ["*"], resources: ["*"](lines 16-18, 34-36) — this includessecretsacross all namespaces. Anyone bound to these roles can read every Secret in the cluster.flux-web-editaggregates into the built-ineditClusterRole viarbac.authorization.k8s.io/aggregate-to-edit: "true"(line 87). Every principal with theeditClusterRole (commonly granted to namespace tenants) automatically inherits the Flux verbs (reconcile,suspend,resume,download) on all Flux API groups pluspatch/restarton Deployments/StatefulSets/DaemonSets anddeleteon pods cluster-wide. For a multi-tenant Cozystack cluster this is a meaningful privilege expansion at the moment web is enabled.Combined with CVE-2026-23990 (Web UI OIDC impersonation bypass) noted in the commit message, the web feature should stay opt-in (which this PR does) and the opt-in instructions should warn operators about the aggregation behavior before flipping
createAggregation.Static analysis note: YAMLlint's "expected the node content, but found '-'" at line 1 is a false positive on the leading
{{- if ... }}Helm directive — safe to ignore.🤖 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 `@packages/system/fluxcd-operator/charts/flux-operator/templates/web-standard-roles.yaml` around lines 1 - 131, Add an opt-in warning to the chart README and release notes explaining the RBAC blast radius when enabling the web UI: document that enabling web.enabled (controls used by include "flux-operator.createWebRoles" and include "flux-operator.createWebRolesAggregation") creates ClusterRoles flux-web-user and flux-web-admin which grant cluster-wide get/list/watch on apiGroups:["*"], resources:["*"] (including secrets), and that flux-web-edit is labeled rbac.authorization.k8s.io/aggregate-to-edit:"true" (so it aggregates into the built-in edit role), causing edit-role principals to inherit Flux verbs (reconcile/suspend/resume/download), patch/restart on workloads and pod delete cluster-wide; also mention the related CVE-2026-23990 and recommend keeping the web feature opt-in and warning operators to review aggregation before setting createWebRolesAggregation/createAggregation true.
🤖 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
`@packages/system/fluxcd-operator/charts/flux-operator/templates/httproute.yaml`:
- Around line 1-25: The HTTPRoute resource (httproute.yaml) is rendered when
.Values.web.httpRoute.enabled is true even if the web server is disabled,
risking routing to a non-existent backend on port 9080; update the top
conditional to require both .Values.web.enabled and
.Values.web.httpRoute.enabled so the HTTPRoute (which references the backend
name via include "flux-operator.fullname" and port 9080) is only emitted when
the web server is enabled and the httpRoute feature is enabled.
In `@packages/system/fluxcd-operator/charts/flux-operator/templates/ingress.yaml`:
- Around line 1-42: The Ingress template currently only guards on
.Values.web.ingress.enabled and conditionally renders pathType, which can
produce invalid networking.k8s.io/v1 manifests; change the top-level conditional
so the block only renders when both .Values.web.enabled and
.Values.web.ingress.enabled are true (e.g., require both in the initial {{- if
... -}}), and ensure each path always emits a pathType (use the existing
.pathType when present otherwise render a default like "ImplementationSpecific")
where the backend references include "flux-operator.fullname" and the port name
"http-web".
---
Nitpick comments:
In
`@packages/system/fluxcd-operator/charts/flux-operator/templates/web-clusterrole.yaml`:
- Around line 16-24: The ClusterRole in web-clusterrole.yaml currently grants
cluster-wide read ("apiGroups":["*"], "resources":["*"],
verbs:["get","list","watch"]) and unrestricted impersonation
("resources":["users","groups"], verbs:["impersonate"]), which is overly
privileged for the web UI; change the template to narrow permissions by
replacing the wildcard apiGroups/resources block (the apiGroups/resources/verbs
entries) with only the specific API groups and resources the web UI actually
needs, remove the impersonate verbs unless impersonation is strictly required,
and if impersonation is required restrict scope by converting to a namespaced
Role or by binding the ClusterRole only to the web serviceAccount (instead of
granting impersonation to broad subjects); also add a short comment in
web-clusterrole.yaml explaining the remaining privileges and a note to operators
about the security implications.
In
`@packages/system/fluxcd-operator/charts/flux-operator/templates/web-standard-roles.yaml`:
- Around line 1-131: Add an opt-in warning to the chart README and release notes
explaining the RBAC blast radius when enabling the web UI: document that
enabling web.enabled (controls used by include "flux-operator.createWebRoles"
and include "flux-operator.createWebRolesAggregation") creates ClusterRoles
flux-web-user and flux-web-admin which grant cluster-wide get/list/watch on
apiGroups:["*"], resources:["*"] (including secrets), and that flux-web-edit is
labeled rbac.authorization.k8s.io/aggregate-to-edit:"true" (so it aggregates
into the built-in edit role), causing edit-role principals to inherit Flux verbs
(reconcile/suspend/resume/download), patch/restart on workloads and pod delete
cluster-wide; also mention the related CVE-2026-23990 and recommend keeping the
web feature opt-in and warning operators to review aggregation before setting
createWebRolesAggregation/createAggregation true.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9440b6e7-5190-4b18-9137-2be02e9d88b3
📒 Files selected for processing (28)
packages/system/fluxcd-operator/charts/flux-operator/Chart.yamlpackages/system/fluxcd-operator/charts/flux-operator/README.mdpackages/system/fluxcd-operator/charts/flux-operator/templates/NOTES.txtpackages/system/fluxcd-operator/charts/flux-operator/templates/_helpers.tplpackages/system/fluxcd-operator/charts/flux-operator/templates/admin-clusterrole.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/aggregate-clusterrole.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/crds.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/deployment.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/httproute.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/ingress.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/networkpolicy.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/service.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/web-clusterrole.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/web-secret.yamlpackages/system/fluxcd-operator/charts/flux-operator/templates/web-standard-roles.yamlpackages/system/fluxcd-operator/charts/flux-operator/values.schema.jsonpackages/system/fluxcd-operator/charts/flux-operator/values.yamlpackages/system/fluxcd-operator/patches/networkPolicy.diffpackages/system/fluxcd-operator/values.yamlpackages/system/fluxcd/charts/flux-instance/Chart.yamlpackages/system/fluxcd/charts/flux-instance/README.mdpackages/system/fluxcd/charts/flux-instance/templates/NOTES.txtpackages/system/fluxcd/charts/flux-instance/templates/healthcheck.yamlpackages/system/fluxcd/charts/flux-instance/templates/instance.yamlpackages/system/fluxcd/charts/flux-instance/values.schema.jsonpackages/system/fluxcd/charts/flux-instance/values.yamlpackages/system/fluxcd/values.yaml
da618d0 to
7aac5ca
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
hack/e2e-apps/vminstance.bats (1)
34-37: ⚡ Quick winPrefer teardown-based cleanup instead of inline end-of-test deletes.
Line 34-37 and Line 115-116 only execute on success paths; a prior failure can leak
VMInstance/VMDiskresources and increase cross-test flakiness. Move this cleanup intoteardown()(or shared framework cleanup) and keep the current pre-clean logic.Based on learnings: e2e cleanup in
hack/e2e-appsshould be framework-level teardown rather than inline per-test cleanup.Also applies to: 115-116
🤖 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 `@hack/e2e-apps/vminstance.bats` around lines 34 - 37, The inline resource cleanup that deletes VMDisk/VMInstance (the kubectl -n tenant-test delete vmdisks.apps.cozystack.io $name --ignore-not-found --timeout=3m and the similar delete at lines ~115-116) must be moved from the end of individual tests into the shared teardown() (or the framework-level cleanup) so failures don't leak resources; retain the current pre-test delete as-is, but remove the post-success-only deletes and implement equivalent deletion logic inside teardown() to unconditionally remove VMInstance and VMDisk resources for the test name/scope.
🤖 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 `@hack/e2e-apps/external-dns.bats`:
- Around line 23-25: The script currently calls "kubectl -n tenant-test wait hr
${name}-system --for=condition=ready" without first ensuring the ${name}-system
HelmRelease exists; add the same existence backstop used for ${name} (a loop
using "kubectl -n tenant-test get hr ${name}-system >/dev/null 2>&1; do sleep 2;
done" or equivalent timeout-backed polling) immediately before the wait for
condition=ready to avoid immediate failures, and apply the identical existence
polling change to the other occurrence around lines 48-50 where ${name}-system
is waited on as well.
---
Nitpick comments:
In `@hack/e2e-apps/vminstance.bats`:
- Around line 34-37: The inline resource cleanup that deletes VMDisk/VMInstance
(the kubectl -n tenant-test delete vmdisks.apps.cozystack.io $name
--ignore-not-found --timeout=3m and the similar delete at lines ~115-116) must
be moved from the end of individual tests into the shared teardown() (or the
framework-level cleanup) so failures don't leak resources; retain the current
pre-test delete as-is, but remove the post-success-only deletes and implement
equivalent deletion logic inside teardown() to unconditionally remove VMInstance
and VMDisk resources for the test name/scope.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7a645b39-6f2e-4e42-a763-96c968fdebf4
📒 Files selected for processing (48)
hack/e2e-apps/bucket.batshack/e2e-apps/clickhouse.batshack/e2e-apps/etcd.batshack/e2e-apps/external-dns.batshack/e2e-apps/harbor.batshack/e2e-apps/kafka.batshack/e2e-apps/mariadb.batshack/e2e-apps/mongodb.batshack/e2e-apps/openbao.batshack/e2e-apps/postgres.batshack/e2e-apps/qdrant.batshack/e2e-apps/redis.batshack/e2e-apps/run-kubernetes.shhack/e2e-apps/vminstance.batsinternal/fluxinstall/manifests/fluxcd-tenants.yamlinternal/fluxinstall/manifests/fluxcd.yamlpackages/apps/bucket/templates/helmrelease.yamlpackages/apps/foundationdb/templates/cluster.yamlpackages/apps/harbor/templates/harbor.yamlpackages/apps/kafka/templates/kafka.yamlpackages/apps/kafka/templates/workloadmonitor.yamlpackages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yamlpackages/apps/kubernetes/templates/helmreleases/cert-manager.yamlpackages/apps/kubernetes/templates/helmreleases/cilium.yamlpackages/apps/kubernetes/templates/helmreleases/coredns.yamlpackages/apps/kubernetes/templates/helmreleases/csi.yamlpackages/apps/kubernetes/templates/helmreleases/fluxcd.yamlpackages/apps/kubernetes/templates/helmreleases/gateway-api-crds.yamlpackages/apps/kubernetes/templates/helmreleases/gpu-operator.yamlpackages/apps/kubernetes/templates/helmreleases/hami.yamlpackages/apps/kubernetes/templates/helmreleases/ingress-nginx.yamlpackages/apps/kubernetes/templates/helmreleases/metrics-server.yamlpackages/apps/kubernetes/templates/helmreleases/monitoring-agents.yamlpackages/apps/kubernetes/templates/helmreleases/ouroboros.yamlpackages/apps/kubernetes/templates/helmreleases/prometheus-operator-crds.yamlpackages/apps/kubernetes/templates/helmreleases/velero.yamlpackages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yamlpackages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yamlpackages/apps/kubernetes/templates/helmreleases/victoria-metrics-operator.yamlpackages/apps/kubernetes/templates/helmreleases/volumesnapshot-crd.yamlpackages/apps/nats/templates/nats.yamlpackages/apps/openbao/templates/openbao.yamlpackages/apps/qdrant/templates/qdrant.yamlpackages/apps/tenant/templates/etcd.yamlpackages/apps/tenant/templates/info.yamlpackages/apps/tenant/templates/ingress.yamlpackages/apps/tenant/templates/monitoring.yamlpackages/apps/tenant/templates/seaweedfs.yaml
💤 Files with no reviewable changes (33)
- internal/fluxinstall/manifests/fluxcd-tenants.yaml
- packages/apps/foundationdb/templates/cluster.yaml
- packages/apps/kafka/templates/workloadmonitor.yaml
- packages/apps/bucket/templates/helmrelease.yaml
- packages/apps/openbao/templates/openbao.yaml
- packages/apps/tenant/templates/monitoring.yaml
- packages/apps/kubernetes/templates/helmreleases/ingress-nginx.yaml
- packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
- packages/apps/kubernetes/templates/helmreleases/cilium.yaml
- packages/apps/tenant/templates/ingress.yaml
- packages/apps/kubernetes/templates/helmreleases/fluxcd.yaml
- packages/apps/kubernetes/templates/helmreleases/csi.yaml
- packages/apps/kubernetes/templates/helmreleases/hami.yaml
- packages/apps/harbor/templates/harbor.yaml
- packages/apps/tenant/templates/seaweedfs.yaml
- packages/apps/kubernetes/templates/helmreleases/metrics-server.yaml
- packages/apps/kubernetes/templates/helmreleases/victoria-metrics-operator.yaml
- packages/apps/kubernetes/templates/helmreleases/coredns.yaml
- packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml
- packages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yaml
- packages/apps/kubernetes/templates/helmreleases/cert-manager.yaml
- packages/apps/kubernetes/templates/helmreleases/gpu-operator.yaml
- packages/apps/kubernetes/templates/helmreleases/ouroboros.yaml
- packages/apps/nats/templates/nats.yaml
- packages/apps/kubernetes/templates/helmreleases/prometheus-operator-crds.yaml
- packages/apps/tenant/templates/info.yaml
- packages/apps/qdrant/templates/qdrant.yaml
- packages/apps/tenant/templates/etcd.yaml
- packages/apps/kafka/templates/kafka.yaml
- packages/apps/kubernetes/templates/helmreleases/volumesnapshot-crd.yaml
- packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yaml
- packages/apps/kubernetes/templates/helmreleases/velero.yaml
- packages/apps/kubernetes/templates/helmreleases/gateway-api-crds.yaml
✅ Files skipped from review due to trivial changes (2)
- hack/e2e-apps/etcd.bats
- hack/e2e-apps/bucket.bats
…edfs-system Splits the seaweedfs-system HelmRelease in two so the CNPG Cluster/seaweedfs-db lives in its own HR (seaweedfs-db), and the application HR (seaweedfs-system) dependsOn it. The new HR uses Flux v2 HelmRelease.spec.healthCheckExprs with a CEL expression on Cluster.status.conditions[type=Ready] plus waitStrategy.name: poller, so its Ready=True only flips after the postgres primary is actually serving connections — not just after helm install applied the Cluster CR. This eliminates the seaweedfs-filer CrashLoopBackOff race on a fresh tenant install. With Cilium kubeProxyReplacement: true, socket-LB returns EPERM from connect(2) to ClusterIPs with no Ready endpoints. Pre-split, the filer StatefulSet scheduled concurrently with the CNPG bootstrap (~55–70s of unavailable postgres), each connect() failed EPERM, kubelet exponential restart backoff pushed past the e2e bats 'kubectl wait hr/seaweedfs-system --timeout=2m' window, and the 'Configure Tenant and wait for applications' test failed. healthCheckExprs uses Flux's three-predicate form: route ClusterIsNotReady (the CNPG bootstrap condition) to `inProgress` so the HR keeps polling, keep `failed` for other Ready=False reasons, and rely on the HR `timeout: 10m` as the real backstop for a genuinely stuck cluster. A plain Ready=False predicate would flag the HR failed within seconds of creating the Cluster CR. Migration 42 adopts existing Cluster/seaweedfs-db resources into the new release on upgrade by rewriting meta.helm.sh/release-name and stamping helm.sh/resource-policy: keep so the seaweedfs-system upgrade (which no longer renders the Cluster) does not delete it during the transition. The application HR's dependsOn collapses the db dependency (unconditional) with the existing ingress dependency (guarded by `if eq $ingress .Release.Namespace` so sub-tenants that inherit ingress from a parent namespace don't deadlock on a non-existent local HR) into one list. Requires Flux v2.8.x (helm-controller v1.5.0+) for healthCheckExprs. Provided by the parent PR #2602 in this chain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Bump flux-operator and flux-instance vendored charts from v0.33.0 to v0.48.0, moving the Flux distribution from 2.7.x to 2.8.x. This brings helm-controller v1.5.x, which exposes spec.install.healthCheckExprs on HelmRelease — a prerequisite for adding real readiness gating to dependency-target packages (postgres, mongodb, kafka, etc.). The new flux-operator chart defaults web.enabled=true; override it to false in packages/system/fluxcd-operator/values.yaml so the Flux Status Web UI stays opt-in. Operators wanting it can set web.enabled=true and configure web.config / web.configSecretName / web.ingress per the upstream chart values. Patches reapplied: - kubernetesEnvs.diff: matched cleanly (offset shift only) - networkPolicy.diff: extended to also restrict port 9080 (web UI port); hunk count updated 20 -> 22 Pre-flight: no references to the v0.39-removed --disable-wait-interruption flag anywhere in packages/ or internal/. Verified locally: - helm template renders both packages without errors - web.enabled=false (default): no web Deployment/Service/NetworkPolicy - web.enabled=true: renders web NetworkPolicy on port 9080 - CiliumClusterwideNetworkPolicy lists 8080/8081/9080 - FluxInstance distribution.version: "2.8.x", all 7 components present - Cozystack kustomize patches (concurrent, requeue, storage-adv-addr, events-addr) intact Notable upstream changes between v0.33 and v0.48: - Flux 2.8.x with HelmRelease inventory format change (auto-migrated) - Reliability fixes for stuck FluxInstance/ResourceSet on health-check cancellation (v0.39, v0.46) - New CLI: flux-operator migrate, diff, patch instance, distro mirror - ResourceSetInputProvider: GitLab Environments, GitHub App, Gitea/Forgejo - CVE-2026-23990 (Web UI OIDC impersonation bypass) — N/A while web is off Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
… 2.8.0 Re-render internal/fluxinstall/manifests/fluxcd.yaml via `make update` in packages/core/flux-aio (timoni bundle build against oci://ghcr.io/stefanprodan/modules/flux-aio at the latest tag) so the cozystack-operator binary embeds Flux 2.8.0 instead of 2.7.3. Auto-syncs the helm-controller image into fluxcd-tenants.yaml. Embedded versions now match the chart bump in the prior commit: flux: v2.7.3 -> v2.8.0 helm-controller: v1.4.3 -> v1.5.0 (enables healthCheckExprs) source-controller: v1.7.3 -> v1.8.0 kustomize-controller: v1.7.2 -> v1.8.0 notification-controller:v1.7.4 -> v1.8.0 source-watcher: v2.0.2 -> v2.1.0 Verified by rebuilding cmd/cozystack-operator and running `strings` on the binary -- the expected v1.5.0 / v1.8.0 / v2.1.0 image strings are now embedded in place of the v1.4.x / v1.7.x ones. Structure preserved: - single AIO Deployment named "flux" in namespace cozy-fluxcd - all 5 controllers + source-watcher as containers in one pod - custom tolerations from flux-aio.cue intact - Namespace pod-security label still "privileged" via the Makefile yq post-processing step Net diff is -3664 lines (mostly CRD schema simplification in 2.8). Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
… TPM
`make update` stripped `persistent: true` from upstream's
`preferredTPM: { persistent: true }`, leaving the parent key with a null value.
KubeVirt v1.6's CRD tolerated it; v1.8 (the operator version we bumped to in
6af0bf7) enforces structural schema and rejects null:
VirtualMachineClusterPreference "windows.11" is invalid:
spec.devices.preferredTPM: Invalid value: "null": spec.devices.preferredTPM
in body must be of type object: "null"
Stop stripping the line and regenerate the templates from upstream
common-instancetypes. Persistent TPM state falls back to the cluster default
StorageClass with RWO access mode when `vmStateStorageClass` is unset on the
KubeVirt CR, per pkg/storage/backend-storage/backend-storage.go.
Drive-by from the regen:
- Removed (upstream EOL): centos.7*, centos.stream8*
- Added: debian, oraclelinux, legacy, linux*, fedora.s390x, rhel.{9,10}.s390x,
windows.{xp,7,7.virtio,2k3,2k8,2k8.virtio,2k12,2k12.virtio}, plus new
cx1.*1gi and d1 instancetype variants.
Also regenerates packages/apps/vm-instance instanceProfile enum
(values.schema.json / README.md) from the refreshed preferences.yaml.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
…o spec The chart nested `faultDomain`, `imageType`, `labels`, and `minimumUptimeSecondsForBounce` inside `automationOptions`, but the FoundationDBCluster CRD schema defines all four as direct children of `spec`. Flux v2.7 (helm-controller v1.4.3) used permissive client-side patch and silently dropped the unknown fields; v2.8 (helm-controller v1.5.0) does strict Server-Side Apply and rejects: failed to create typed patch object: .spec.automationOptions.<field>: field not declared in schema This was a latent bug from day one — none of those fields ever actually configured anything. Moving them one level up applies the values to where the operator looks for them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
…m .spec
Same class of bug as the foundationdb misplaced-field fixes. The kafka
chart had:
entityOperator:
template:
pod:
metadata: { labels: { ... } }
spec: ← child of template, not of pod
enableServiceLinks: false
The Strimzi Kafka CRD's `entityOperator.template` has no `spec` key.
`enableServiceLinks` is a direct field of `template.pod` (alongside
metadata, affinity, tolerations, etc.). Flux v2.7's permissive
client-side patch silently dropped the misplaced field; v2.8's strict
Server-Side Apply rejects:
failed to create typed patch object (Kind=Kafka):
.spec.entityOperator.template.spec: field not declared in schema
Move `enableServiceLinks` under `template.pod` where the operator
actually reads it, and fix the inconsistent metadata.labels indentation
(was 9/11 spaces instead of 10/12) while we're here.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
(cherry picked from commit 447f1dc)
tenant-rd now carries release.cozystack.io/helm-install-timeout alongside kubernetes-rd (its parent chart bootstraps the seaweedfs-db CNPG cluster, whose first reconcile exceeds flux's default wait budget). Update the comment that claimed only kubernetes-rd carries it. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
- kafka: assert WorkloadMonitor reads .Values.kafka.replicas / .Values.zookeeper.replicas (regression for the phantom .Values.replicas), and that enableServiceLinks lives under entityOperator.template.pod. - tenant: pin that no swept HelmRelease carries upgrade.force (would have caught the missed gateway.yaml). - seaweedfs-db: baseline render cover for the new split-out chart. - kafka and seaweedfs-db had no `test` Makefile target, so their suites never ran in CI; add one to each. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
|
Aleksei Sviridkin (@lexfrei) thanks — all three blockers are addressed, plus the cheap follow-ups. B1 ( B2 ( B3 ( Follow-ups: foundationdb |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
NOT LGTM — the three earlier blockers are resolved, but the foundationdb imageType change was hand-edited without running make generate, leaving the generated tree inconsistent and the pre-commit check red.
Business context: Flux v2.7.3 → v2.8.0 (helm-controller v1.5, Helm v4 Server-Side Apply + kstatus), plus chart fixes for fields v2.7 silently dropped and v2.8 SSA now rejects.
Blockers
foundationdb imageType default out of sync — make generate not run (pre-commit red)
File: api/apps/v1alpha1/foundationdb/types.go:42
Issue: The imageType default was switched to split in values.yaml, values.schema.json, README.md and the RD schema, but api/apps/v1alpha1/foundationdb/types.go still carries +kubebuilder:default:="unified", and packages/apps/foundationdb/README.md keeps the table column sized for the old longer value.
Evidence: The pre-commit job fails with exit 123 on an uncommitted make generate diff covering exactly these two files. Reproduced locally with cozyvalues-gen 1.5.0: make generate -C packages/apps/foundationdb rewrites types.go to +kubebuilder:default:="split" and reflows the README table — byte-identical to the CI diff. types.go is not touched anywhere in this PR.
Impact: Runtime CR defaulting is unaffected — the dynamic CRD defaults imageType from the RD openAPISchema, which already says split, so the non-disruptive-upgrade guarantee holds. But the pre-commit check is red (merge-blocking) and the generated source tree is internally inconsistent.
Fix: Run make generate -C packages/apps/foundationdb and fold the result into the imageType commit.
Resolved since the previous review (verified)
migrations.targetVersionbumped 43 → 44: migration 43 now falls insideseq CURRENT 43; the file exists and the missing-file guard is intact. The migrations image digest is auto-stamped at build time (same convention as migration 42), so leaving it untouched is correct.- kubevirt-instancetypes: the
gn1.*GPU instancetypes are re-added inextra-instancetypes.yamlbyte-for-byte identical to the previous catalog;common-instancetypesis pinned to a documented commit; only the EOLcentos.7*/centos.stream8*preferences are dropped (release-noted with repoint guidance); both READMEs are regenerated to match. - The tenant gateway HelmRelease no longer sets
upgrade.force; noforce: trueremains anywhere underpackages/(excluding vendored charts); the new invariant suite assertsnotExistsonspec.upgrade.forceacross all six swept HRs and renders each one (non-vacuous). rest.goannotation comment corrected; bothkubernetes-rdandtenant-rdcarry the annotation.- Test coverage added for the WorkloadMonitor replica-path fix, the
enableServiceLinksrelocation, the no-upgrade.forceinvariant, and the new seaweedfs-db chart; the kafka and seaweedfs-dbtestMakefile targets were wired (previously absent, so the pre-existing kafka suites were not running in CI at all). - Kubernetes 1.33 minimum: confirmed accurate — Flux v2.8 supports 1.33/1.34/1.35; the release note documents both the platform and the default-off tenant addon.
Non-blocking follow-ups
- The default-off tenant Flux addon ships Flux v2.8, which requires Kubernetes 1.33+, while tenant clusters can still run v1.30–1.32. This is release-noted but not version-gated; a preflight gate would be more robust than a release note for operators who do not read changelogs.
- No sibling docs PR was found for the user-facing K8s 1.33 prerequisite bump. The requirements page does not appear to pin a minimum, so there may be nothing stale to fix — worth a glance.
… default The imageType default was switched to split in values.yaml/values.schema.json/ RD schema but make generate was not run, leaving the +kubebuilder:default marker in api/apps/v1alpha1/foundationdb/types.go at "unified" and the README param table sized for the old value — failing the pre-commit generate check (exit 123). Regenerated with cozyvalues-gen v1.5.0. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
Re-pull the vendored flux-operator and flux-instance charts from 0.48.0 to the latest v0.50.0 (operator-version bumps only: OpenShift v4.21 compat, OLM base image, Kubernetes client deps — no Flux distribution change). The kubernetesEnvs and networkPolicy patches re-apply cleanly. distribution.version stays 2.8.x, so the tenant Flux toolkit auto-tracks the latest 2.8 patch (currently 2.8.8) at reconcile. The management flux-aio module is already at its latest published build (2.8.0); no newer 2.8.x module exists upstream yet. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
|
Aleksei Sviridkin (@lexfrei) good catch — fixed in Separately bumped the vendored flux-operator/flux-instance charts 0.48.0 → v0.50.0 ( |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
NOT LGTM — two upgrade regressions for existing clusters: migration 43 strips the deletion-protection label off the cozystack-version ConfigMap (undoing migration 42), and dropping the EOL centos.7*/centos.stream8* preferences hard-fails the HelmRelease render of every existing VM that references them, with no migration or compatibility alias.
Business context: Flux v2.7.3 → v2.8.0 (helm-controller v1.5, Helm v4 Server-Side Apply + kstatus), plus chart fixes for fields v2.7 silently dropped and v2.8 SSA now rejects.
Blockers
B1 — Migration 43 strips the no-delete label from the cozystack-version ConfigMap
File: packages/core/platform/images/migrations/migrations/43:30-32
Issue: The version stamp at the end of migration 43 emits a label-less manifest and kubectl applys it under the same client-side field manager migration 42 used:
kubectl create configmap -n cozy-system cozystack-version \
--from-literal=version=44 --dry-run=client -o yaml | kubectl apply -f-Migration 42 deliberately applied this ConfigMap with platform.cozystack.io/no-delete: "true", and its own header warns: "a label-less apply by the same field manager would strip it." Migration 43 performs exactly that label-less apply.
Evidence:
migrations/42applies the ConfigMap with theno-deletelabel via heredoc +kubectl apply, with an explicit comment that a later label-less apply by the same manager would strip it.templates/cozystack-version.yamlonly renders the labeled ConfigMap{{- if not $configMap }}— first install only. On an existing cluster the template renders nothing, so the chart does not restore the label after the migration removes it.templates/deletion-protection.yamldefinescozystack-no-delete-guardrail, a ValidatingAdmissionPolicy matching objects withplatform.cozystack.io/no-delete: "true". Once the label is stripped, the guardrail no longer coverscozystack-version.- The upgrade path that runs migration 43 is not exercised by E2E (fresh installs stamp
version = targetVersionvia the chart and skip the migration hook), so the green E2E run does not validate this.
Impact: Every cluster upgrading through migration 43 loses deletion protection on cozystack-version — the ConfigMap that anchors migration-version tracking. An accidental kubectl delete configmap cozystack-version -n cozy-system then succeeds and can cause migrations to re-run or version detection to break on the next upgrade. This regresses the exact protection migration 42 added.
Fix: Stamp the version with the labeled manifest mirroring migration 42 (include metadata.labels.platform.cozystack.io/no-delete: "true"), and add a test asserting the label survives the stamp. Better: factor the version stamp into a shared helper so future migrations cannot drift from the labeled pattern.
B2 — Removing the EOL centos.7* / centos.stream8* preferences hard-breaks existing VMs on upgrade
File: packages/system/kubevirt-instancetypes/templates/preferences.yaml (removal) + packages/apps/vm-instance/templates/vm.yaml:4-6 (hard fail)
Issue: centos.7, centos.7.desktop, centos.stream8, centos.stream8.desktop, centos.stream8.dpdk are removed from the preference catalog and from the vm-instance schema enum, and are not re-added anywhere. vm.yaml hard-fails the render when a referenced VirtualMachineClusterPreference is absent from the cluster. Any existing VMInstance using one of these profiles fails its HelmRelease render on the next reconcile after upgrade, with no automatic remediation — and the operator cannot patch the object through the API either, because the dynamic CRD enum now rejects the stored value.
Evidence:
origin/main:.../preferences.yamlships these five preferences; HEAD ships none of them, and they are absent fromextra-instancetypes.yaml.vm-instance/values.schema.jsondrops the fivecentos.*enum entries.vm.yaml:4-6:{{- if and .Values.instanceProfile (not (lookup ... "VirtualMachineClusterPreference" "" .Values.instanceProfile)) }}{{- fail ... }}.- The PR already solves this exact failure mode for the in-use
gn1.*instancetypes by re-adding them as deprecated aliases inextra-instancetypes.yaml; the header comment states the purpose verbatim: "vm.yaml fails the Helm render when a referenced VirtualMachineClusterInstancetype is absent ... appended ... to keep those workloads renderable."
Impact: Hard, unrecoverable HelmRelease render failure for every existing VM on these profiles, on a platform whose target operator does not read changelogs. The "repoint manually before upgrading" note in the PR body is the operator-facing symptom, not a mitigation.
Fix: Re-add the five centos.* preferences as deprecated-alias VirtualMachineClusterPreference objects, mirroring the gn1.* treatment in extra-instancetypes.yaml; or ship a repointing migration (same class as migration 43) that rewrites instanceProfile on existing VMInstances. EOL guest OS is not a reason to hard-fail a running VM's reconciliation — the deprecated-alias mechanism already in this PR keeps such objects renderable while hiding them from new use.
Non-blocking follow-ups
- Stale Flux version label on the tenant sharded controller.
internal/fluxinstall/manifests/fluxcd-tenants.yamlbumpshelm-controllertov1.5.0(Flux 2.8.0) but keepsapp.kubernetes.io/version: v2.7.3on theflux-tenantsDeployment (line 8).packages/core/flux-aio/Makefile'supdatetarget only syncs the container image into this file viayq; it never touches the version label, so the label drifts on every bump andmake updatewill not self-correct. Cosmetic (the running image is correct) but misreports the Flux version to anything reading the standard label. Fix: update the label, or extend theyqpatch to carryapp.kubernetes.io/versiontoo. - K8s 1.33 minimum is release-noted but not gated. Flux v2.8 requires Kubernetes 1.33+, while tenant clusters can still run v1.30–1.32 and would deploy this Flux if the (default-off) tenant Flux addon is enabled. A preflight version gate would be more robust than a changelog note. No sibling docs PR is open in the website repo.
Resolved since the prior round (verified)
- foundationdb
imageTypegenerated-tree drift:5c4e927regeneratestypes.goto+kubebuilder:default:="split"and reflows the README; the "Verify generated code" and pre-commit gates are now green. - The
fd59deaflux-operator/flux-instance chart bump v0.48.0 → v0.50.0 is the operator version only;distribution.versionstays pinned at2.8.x, the chart delta is additive (optionalservice.ipFamilyPolicy, AWSCodeCommit CRD validations), and the embedded bootstrap installs raw Flux controllers, so there is no operator/bootstrap skew.
| done | ||
|
|
||
| # Stamp version | ||
| kubectl create configmap -n cozy-system cozystack-version \ |
There was a problem hiding this comment.
This label-less kubectl apply strips the platform.cozystack.io/no-delete label that migration 42 added — see migration 42's own warning that a label-less apply by the same field manager removes it. templates/cozystack-version.yaml only re-creates the labeled ConfigMap when it is absent, so on upgrade the chart does not restore the label and the cozystack-no-delete-guardrail policy stops protecting this ConfigMap. Stamp the version with the labeled manifest as migration 42 does.
There was a problem hiding this comment.
Fixed in 797284ab4. The version stamp now applies a labeled heredoc manifest carrying platform.cozystack.io/no-delete: "true" and version: "44", mirroring migration 42, instead of the label-less kubectl create configmap | kubectl apply. The label is recorded inline by the same field manager, so it survives the stamp and cozystack-version stays covered by the cozystack-no-delete-guardrail ValidatingAdmissionPolicy on upgrade.
| # The gn1.* (GPU NVIDIA) series was removed upstream in common-instancetypes | ||
| # v1.3.0, but existing GPU VMs and tenant Kubernetes GPU worker pools still | ||
| # reference these names, and packages/apps/vm-instance/templates/vm.yaml fails | ||
| # the Helm render when a referenced VirtualMachineClusterInstancetype is absent. |
There was a problem hiding this comment.
The same rationale applies to the centos.7* / centos.stream8* VirtualMachineClusterPreference objects this PR removes: vm.yaml hard-fails the render when a referenced preference is absent, so existing VMs on those profiles break on upgrade. Re-add them here as deprecated aliases (as done for gn1.*) instead of relying on a manual pre-upgrade repoint.
There was a problem hiding this comment.
Fixed in 27edd73bc. The five centos.7, centos.7.desktop, centos.stream8, centos.stream8.desktop, centos.stream8.dpdk VirtualMachineClusterPreference objects are re-added as deprecated aliases in extra-instancetypes.yaml, mirroring the gn1.* treatment, so vm.yaml no longer hard-fails the render. I also extended the vm-instance enum generation to union preference names from extra-instancetypes.yaml, so these profiles stay in values.schema.json and the RD schema — the dynamic CRD no longer rejects existing VMInstance CRs referencing them.
Address review feedback from lexfrei on migrations/43: the version stamp did a label-less `kubectl create configmap | kubectl apply` under the same field manager migration 42 used, stripping the platform.cozystack.io/no-delete label and dropping cozystack-version out of the deletion-protection guardrail on every upgrade through this migration. Replace it with a labeled heredoc manifest mirroring migration 42 so the label survives the stamp. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
…ted aliases
Address review feedback from lexfrei: dropping the centos.7/centos.7.desktop/
centos.stream8{,.desktop,.dpdk} VirtualMachineClusterPreference objects hard-fails
the vm-instance Helm render (vm.yaml fails when a referenced preference is absent)
and makes the dynamic CRD enum reject the stored value for every existing VM on
those profiles on upgrade. Re-add them as deprecated aliases in
extra-instancetypes.yaml, mirroring the gn1.* GPU instancetype treatment, and
extend the vm-instance enum generation to union preference names from
extra-instancetypes.yaml so the retained profiles stay in values.schema.json and
the RD schema.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
|
Aleksei Sviridkin (@lexfrei) both blockers from this round are addressed:
The two non-blocking follow-ups (stale |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
LGTM — both blockers from the prior round are resolved and verified; the only open items are the two known non-blocking follow-ups, both acknowledged.
Business context: Flux v2.7.3 → v2.8.0 (helm-controller v1.5, Helm v4 Server-Side Apply + kstatus), plus chart fixes for fields v2.7 silently dropped and v2.8 SSA now rejects.
Resolved since the prior round (verified)
- B1 — migration 43 no longer strips the
no-deletelabel (797284ab). The version stamp now appliescozystack-versionfrom a labeled heredoc carryingplatform.cozystack.io/no-delete: "true", mirroring migration 42, so the ConfigMap stays under thecozystack-no-delete-guardrailValidatingAdmissionPolicy on upgrade. Same client-side field manager as migration 42 → the relabel is a clean 3-way merge, no conflict. The inline comment documents why the label must be carried here. - B2 — EOL
centos.7*/centos.stream8*preferences retained as deprecated aliases (27edd73b). All five (centos.7,centos.7.desktop,centos.stream8,centos.stream8.desktop,centos.stream8.dpdk) are re-added toextra-instancetypes.yamlverbatim from the pre-removal catalog (only an explanatory comment prepended), markedinstancetype.kubevirt.io/deprecated: "true"+tags: hidden, mirroring thegn1.*treatment — sovm.yaml's lookup/failfinds them and existing VMs keep rendering. The enum generation now unions preference names fromextra-instancetypes.yaml, sovalues.schema.jsonand the RDopenAPISchemaenum both regain the five names and the dynamic CRD no longer rejects the stored values. Evidence: reconstructinginstanceProfile.enumfrom the source catalogs with the Makefile's own yq/jq pipeline reproduces the committed schema byte-for-byte (60 entries); the RD enum matchesvalues.schema.json; there are no object-name collisions betweenextra-instancetypes.yamlandpreferences.yaml/instancetypes.yaml; and the "Verify generated code is up to date" + pre-commit checks are green — so the generated tree is consistent.
Non-blocking follow-ups (carried over, both acknowledged)
internal/fluxinstall/manifests/fluxcd-tenants.yaml:8still readsapp.kubernetes.io/version: v2.7.3while the Deployment now runshelm-controller:v1.5.0(Flux 2.8.0). Cosmetic (the running image is correct) but misreports the version;make updatewon't self-correct since theyqpatch only syncs the image.- K8s 1.33 minimum is release-noted but not gated; a preflight version gate on the default-off tenant Flux addon would be more robust than a changelog note. No sibling website-repo docs PR is open.
No new issues introduced by either commit.
…ment Address non-blocking review feedback from lexfrei: the flux-tenants sharded-controller Deployment carried a stale app.kubernetes.io/version: v2.7.3 while running helm-controller v1.5.0 (Flux 2.8.0). The flux-aio Makefile update target only synced the container image, so the version label drifted on every bump and make update never self-corrected. Bump the label to v2.8.0 and extend the yq patch to carry app.kubernetes.io/version from the source flux Deployment. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
|
Aleksei Sviridkin (@lexfrei) folded in non-blocking follow-up #1 as well: The K8s 1.33 preflight gate (follow-up #2) I'd prefer to keep out of this PR — it's a new feature (version-gating the default-off tenant Flux addon) and the user-facing docs piece lives in the website repo. Happy to open a tracking issue for it if you agree. |
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
LGTM — the last open item (non-blocking follow-up #1) is now resolved and verified; no regressions, CI green.
Business context: Flux v2.7.3 → v2.8.0 (helm-controller v1.5, Helm v4 Server-Side Apply + kstatus), plus chart fixes for fields v2.7 silently dropped and v2.8 SSA now rejects.
Resolved since the prior round (verified)
- Stale Flux version label synced (
910b505d). Theflux-tenantssharded-controller Deployment now carriesapp.kubernetes.io/version: v2.8.0(wasv2.7.3), matching thehelm-controller:v1.5.0it runs. Theflux-aioMakefileupdatetarget was extended with ayqpatch that sources the label from thefluxDeployment influxcd.yaml, so the label self-corrects on future bumps instead of drifting. Evidence: the sourcefluxDeployment influxcd.yamlcarriesv2.8.0; re-running the newyqexpression against the committed tree is a no-op (idempotent);fluxcd-tenants.yamlholds a single document, so the selector-less patch has no collateral; nov2.7.3references remain underinternal/orpackages/.
Non-blocking follow-up (deferred with rationale)
- K8s 1.33 preflight gate on the default-off tenant Flux addon — deferred to a separate change (it is a new feature; the requirement is already captured in the release note). A tracking issue is the right home for it.
…ay.bats tenant teardown (#2558) ## What this PR does Drops the 3× retry loop on `Run E2E tests` and `Install Cozystack into sandbox`. `Prepare environment` keeps its 3× retry — that step is pure infrastructure (Talos image download, sandbox VM boot, network) where transient runner hiccups warrant a retry. On failure, the test step now captures `kubectl get hr -A -o wide` and `kubectl get events -A` under a collapsible group so triage starts with the actual broken-state snapshot. > [!NOTE] > An earlier revision of this PR also doubled every bats timeout. That commit was dropped in a rebase and is intentionally **not restored**: the timeout class that actually matters (per-app HR-Ready waits) has since been standardized at 5m on `main` (7b9f286), making a blanket 2× redundant. **Fixes gateway.bats teardown leakage.** The nested-tenant tests deleted tenants fire-and-forget, parent and child back-to-back. The leftover uninstalls (each blocked on a cleanup Job, parents wedged on still-terminating child namespaces) plus one mid-install child HR occupied exactly 5 workers on the `--concurrent=5` tenants helm-controller shard, starving whichever app test ran next — observed as the harbor HR sitting unreconciled for its whole 5m HR-Ready budget in [run 27020081550](https://github.com/cozystack/cozystack/actions/runs/27020081550), surfaced by this PR's own retry removal + diagnostics dump. Teardown now deletes child→parent with hard `wait hr --for=delete` between, so a wedged tenant uninstall fails gateway.bats itself, not an innocent neighbor. ## Why Audit of 30 successful PR runs found that across 5 sampled failure attempts, **25/25 retries** on `Run E2E tests` failed — the retry loop never recovered a flake, only stretched deterministic failures and tripled diagnostic wall-time. Same data shape on `Install Cozystack`. Beyond wasted CI time, the retry was hiding ~10 deterministic bugs (Helm namespace-ownership conflict, seaweedfs HR timeout, harbor BucketInfo wiring, vminstance disk race, etc.). Each failure looked like a "flake" because the retry sometimes coincided with whatever transient state had cleared — the retry never fixed the bug, just delayed surfacing. ## Dependencies The deterministic bugs the retry was masking are now fixed on `main`: - ✅ **#2508** — installer namespace bootstrap (Helm namespace-ownership conflict on cold install) — merged - ✅ **#2509** — operator HelmRelease config knobs (`seaweedfs-system` 2-min wait race within Flux's 5-min reconcile windows) — merged - ✅ **#2528** — harbor bucket-secret + BucketInfo gating (harbor `ValuesError` on first install) — merged - ✅ **#2529** — objectstorage-controller BucketAccess conflict retry — merged Companion PRs in the #2619 split (independent of this PR, ordering-wise): - **#2602** — Flux v2.8.0 + chart fixes - **#2601** — seaweedfs-system split This PR does NOT depend on #2602/#2601 — it now touches only the workflow file and gateway.bats teardown, both on top of fresh `main`. Surfaced from #2500. ### Release note ```release-note NONE ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * CI prepare-environment step now reports plain attempt counts with clear success/failure messages. * Install and per-app test steps no longer retry; each runs once and fails immediately on error. Failed apps log diagnostics and job proceeds to remaining apps while overall job fails. * **Tests** * End-to-end tests and install/prepare flows use longer, more tolerant timeouts and added existence polling to reduce flakiness and improve diagnostics. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/cozystack/cozystack/pull/2558?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
The kstatus readiness work (#2642) sets WaitStrategy / kustomize.CustomHealthCheck / HelmReleaseSpec.HealthCheckExprs on generated HelmReleases. Those Go types do not exist at helm-controller/api v1.4.3 — the runtime CRD is already v1.5.0 (shipped by #2602), so this closes a Go-types-vs-runtime skew rather than getting ahead of the runtime. The bump is not isolated: helm-controller/api v1.5.x requires k8s 0.35 + controller-runtime 0.23, cascading the k8s stack 0.34 -> 0.35. cozystack replaces k8s.io/apimachinery with a fork carrying the (still-open) upstream ConvertToVersion patch k/k#135537; that single commit is rebased cleanly onto apimachinery v0.35.0 at cozystack/apimachinery@release-1.35-pr135537. The repo builds with no source changes under the new stack. Refs #2642 Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
…2642) (#3273) ## What Adds typed `waitStrategy` + `healthCheckExprs` fields so a package/app can declare the Flux helm-controller v1.5.0 kstatus health gate for the custom resource it wraps — making `HelmRelease.Ready` mean "the CR is actually healthy" instead of "helm applied the CR". This is the operator/apiserver foundation of the kstatus epic (#2642); the API surface was reviewed and approved by the API owner in #3263. Commits (per the review's "isolated step-0" request): 1. `build(deps)` — the dependency bump (see below). 2. `feat(api)` — the fields, plumbing, tests, and regenerated code. 3. `fix(api)` — match the openapi code-generator pin to the 0.35 runtime (fixes an aggregated-apiserver crash the bump surfaced). 4. `fix(api)` — declare `OpenAPIModelName` on the apps types so SSA resolves catalog kinds. 5. `docs(api)` — note that `disableWait` silently defeats `healthCheckExprs`. ## API surface Typed fields on **both** HelmRelease-building paths: - `ApplicationDefinition.spec.release` (apiserver / catalog apps → `convertApplicationToHelmRelease`) - `ComponentInstall` (operator / platform packages → `buildHelmReleaseSpec`) ```go // WaitStrategy maps to HelmReleaseSpec.WaitStrategy.Name — a deliberate scalar // simplification of the upstream {name} object. One of poller|legacy. WaitStrategy string // HealthCheckExprs maps to HelmReleaseSpec.HealthCheckExprs (the upstream // kustomize.CustomHealthCheck type verbatim). HealthCheckExprs []kustomize.CustomHealthCheck ``` `config.ResolveWaitStrategy` is shared by both builders and **couples the default**: `healthCheckExprs` are only evaluated under the `poller` strategy, so when expressions are set and no strategy is given, the generated HelmRelease defaults to `poller`. A package that sets only `healthCheckExprs` is therefore self-contained, independent of the controller's global default. ## The dependency bump (commit 1) The `WaitStrategy` / `kustomize.CustomHealthCheck` / `HelmReleaseSpec.HealthCheckExprs` types do not exist below `helm-controller/api` v1.5.0 — the runtime is already v1.5.0 (shipped by #2602), so this closes a Go-types-vs-runtime skew. It is **not** an isolated bump: v1.5.x requires **k8s 0.35 + controller-runtime 0.23**, cascading the k8s stack 0.34 → 0.35 (and the go directive to 1.26). cozystack replaces `k8s.io/apimachinery` with a fork carrying the still-open upstream `ConvertToVersion` patch (k/k#135537). That single commit rebases cleanly onto apimachinery v0.35.0; published at `cozystack/apimachinery@release-1.35-pr135537`, and `go.mod` pins its pseudo-version. **The repo builds with zero source changes under the new stack.** > Maintainer note: please confirm the `release-1.35-pr135537` fork branch naming, or fold it into the `cozystack` branch as you prefer — the pin can be updated to match. ## Not included (conscious YAGNI) `disableWait` is intentionally omitted. The only known need (the kubernetes tenant-addon deadlock) was resolved child-side, and `waitStrategy: legacy` is not equivalent (legacy still waits Helm-v3-style; `disableWait` skips waiting entirely). Add it later when a concrete leaf needs a true no-gate escape hatch. ## Tests - `config.TestResolveWaitStrategy` — the couple-the-default logic (unset+exprs→poller; explicit legacy honored; unset+no-exprs→nil). - Operator + apiserver cases mirror each other (`TestBuildHelmReleaseSpecHealthCheckExprs` / `TestConvertApplicationToHelmRelease_HealthCheckExprs`). - `go build ./...` clean, `go vet` clean, `gofmt` clean, codegen regenerated and committed. The 4 backupstrategy CRDs regenerate with benign k8s-0.35 PodSpec description drift (DynamicResourceAllocation alpha→stable, toleration Lt/Gt, resizePolicy note) — no functional change. ## Follow-up Phase 3 (per-leaf adoption — postgres/kafka/mongodb/etc. declaring their CEL via these fields) builds on this. The full CRD→CEL catalog is maintained in the epic's readiness audit. Refs #2642 ```release-note feat(api): add `waitStrategy` and `healthCheckExprs` to ApplicationDefinition and ComponentInstall, so a HelmRelease reports Ready only once the custom resource it wraps is actually healthy ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added configurable CEL health-check expressions for application releases and package components. * Added `waitStrategy` support (`poller` and `legacy`) with automatic `poller` selection when health checks are configured and no strategy is set. * Propagated these settings into generated Helm releases, affecting readiness/wait behavior. * **Documentation** * Updated Application and PackageSource schemas to include `healthCheckExprs` and `waitStrategy`. * Extended related Kubernetes CRD documentation, including projected pod certificate annotations and workload reference fields. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
What this PR does
Upgrades Flux v2.7.3 → v2.8.0 across both the vendored tenant chart and the embedded management-cluster manifests, and folds in the chart fixes that become hard errors under the new strict helm-controller v1.5.
Flux v2.8's helm-controller v1.5.0 ships:
--force-conflicts— strict CRD schema enforcement; misplaced fields (silently dropped on v2.7) now fail the apply.upgrade.force: trueis deprecated and now conflicts with SSA.HelmRelease.spec.healthCheckExprs— prerequisite for proper readiness gating (used in PR refactor(seaweedfs): split seaweedfs-system into seaweedfs-db + seaweedfs-system #2601 split).Folds in PR #2612 (kubevirt-instancetypes null TPM fix) since the same Flux upgrade triggers it.
Commits
Flux upgrade itself:
feat(fluxcd): bumpflux-operator/flux-instancevendored charts to v0.48.0; web UI opt-in.feat(flux): regenerate embedded management-cluster manifests viamake updateinpackages/core/flux-aio(timoni bundle build).Chart fixes for strict SSA — fields the chart sent that v2.7 silently dropped, v2.8 rejects:
fix(kubevirt-instancetypes): drop persistent strip that produced nullpreferredTPM(folds fix(kubevirt-instancetypes): drop persistent strip that produced null TPM #2612).fix(foundationdb): relocatefaultDomain,imageType,labels,minimumUptimeSecondsForBouncefrom insideautomationOptionsto direct children ofspec.fix(kafka): placeenableServiceLinksundertemplate.pod, not a phantomtemplate.spec.fix(vm-instance): emitdisk: {}(notdisk:/null) when no bus is set.fix(platform): drop deprecatedupgrade.force: truefrom HelmReleases; fixkafkaWorkloadMonitorreplicaspaths.Ordering / deadlock fixes under v2.8 kstatus:
fix(vpa): break circular wait between parent install and nestedvpa-for-vpaHR.fix(kubernetes): drop lookup-guarded parent-HRdependsOnon tenant addon child HRs (parent waits on child via kstatus, child waited on parent — deadlock).E2E waits for v2.8 kstatus timing:
test(e2e): bump app HR-Ready waits to 5m (was 20s–100s under v2.7's faster dispatch).test(e2e): wait for parent HR Ready before downstream asserts inrun-kubernetes.shandvminstance.bats.Scope discipline
This PR is part of the split of #2619 (the consolidated CI fixes branch) into review-friendly pieces. Companion PRs:
29c6afc8,0e8b46d7,7157158c,dccdeb52,f880b324): the seaweedfs-system → seaweedfs-db + seaweedfs-system split, its adoption migration 43 (targetVersion 44), and the configurable db resources all land here, because the strict-SSAupgrade.forceremoval and the kstatus parent-HR timeout bump only make sense together with the split. refactor(seaweedfs): split seaweedfs-system into seaweedfs-db + seaweedfs-system #2601 is superseded.Run E2E+Install Cozystack) — independent, lands separately.dependsOn, prepull machinery, CSI HR timeout, NFS/OIDC test improvements) — opened as separate PRs.Verification
helm templaterenders cleanly for bothfluxcdandfluxcd-operatorpackages withweb.enabled=false(default) andweb.enabled=true.cmd/cozystack-operatorbinary contains the v1.5.0 / v1.8.0 / v2.1.0 controller image strings.--disable-wait-interruptionflag anywhere inpackages/orinternal/.Release note
Summary by CodeRabbit
New Features
Improvements
Chores
Bug Fixes