Skip to content

feat(monitoring): migrate VictoriaLogs from VLogs to VLCluster - #2153

Merged
Andrei Kvapil (kvaps) merged 4 commits into
mainfrom
feat/migrate-vlogs-to-vlcluster
Mar 11, 2026
Merged

feat(monitoring): migrate VictoriaLogs from VLogs to VLCluster#2153
Andrei Kvapil (kvaps) merged 4 commits into
mainfrom
feat/migrate-vlogs-to-vlcluster

Conversation

@sircthulhu

@sircthulhu Kirill Ilin (sircthulhu) commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

What this PR does

Migrates VictoriaLogs from the deprecated single-node VLogs CR to VLCluster (cluster mode) with vlinsert/vlselect/vlstorage components for reliability and horizontal scalability.

Operator upgrade:

  • Upgrades victoria-metrics-operator from v0.55.0 to v0.68.1 to add VLCluster CRD support

VLCluster deployment:

  • Replaces VLogs (v1beta1) with VLCluster (v1) — 2 replicas per component, consistent with VMCluster
  • Adds VPA for all VLCluster components (vlinsert, vlselect, vlstorage)
  • Updates WorkloadMonitors for the three-component architecture

Endpoint updates:

  • Fluent-bit outputs: vlogs-generic:9428vlinsert-generic:9481
  • Grafana datasource: vlogs-{name}:9428vlselect-{name}:9471
  • ExternalName service: vlogs-genericvlinsert-generic

Migration (35 → 36):

  • Adds helm.sh/resource-policy: keep annotation to existing VLogs resources so they are preserved during upgrade
  • Users need to verify the new VLCluster is working, then optionally migrate historical data and manually delete old VLogs resources

Release note

[monitoring] Migrate VictoriaLogs from single-node VLogs to VLCluster (cluster mode). Old VLogs resources are preserved with `helm.sh/resource-policy: keep` annotation. After upgrade, verify the new cluster is working, then optionally migrate historical data and delete old VLogs resources manually.

Summary by CodeRabbit

  • New Features

    • CRD upgrade workflow with configurable hooks, Job, and ServiceAccount support
    • Monitoring storage split into vlinsert / vlselect / vlstorage with corresponding VPAs
    • Service traffic distribution option and optional shareProcessNamespace toggle
  • Updates

    • VictoriaMetrics Operator bumped to v0.68.1
    • Fluent Bit and Grafana endpoints/ports updated to new monitoring targets
    • Global extra-labels support for resources
    • Migration target advanced to version 36

@coderabbitai

coderabbitai Bot commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 386f6f13-f010-4ee7-acd2-2a400454b015

📥 Commits

Reviewing files that changed from the base of the PR and between b772475 and 9e16630.

📒 Files selected for processing (1)
  • hack/e2e-install-cozystack.bats
🚧 Files skipped from review as they are similar to previous changes (1)
  • hack/e2e-install-cozystack.bats

📝 Walkthrough

Walkthrough

Refactors VLogs into three components (vlinsert, vlselect, vlstorage), updates Fluent Bit targets and Grafana datasource ports/names, upgrades VictoriaMetrics operator/chart with a new CRD-upgrade subchart (hooked Job/CRD apply), adds migration script and bumps migrations target to 36.

Changes

Cohort / File(s) Summary
Fluent Bit & External Service Targets
packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml, packages/system/monitoring-agents/values.yaml, packages/system/cozystack-basics/templates/monitoring-external-services.yaml
HTTP output host and port changed from vlogs-generic.*:9428vlinsert-generic.*:9481; external Service name/externalName renamed accordingly.
VLogs → VLCluster Refactor
packages/system/monitoring/templates/vlogs/vlogs.yaml, packages/system/monitoring/templates/vlogs/grafana-datasource.yaml, packages/system/monitoring/values.yaml
CRD kind/api changed: VLogs → VLCluster; single vlogs block replaced by vlinsert/vlselect/vlstorage blocks; Grafana datasource now points to vlselect:9471; storageClassName for "generic" cleared.
Dashboards, WorkloadMonitors & VPAs
packages/extra/monitoring/templates/dashboard-resourcemap.yaml, packages/extra/monitoring/templates/workloadmonitors.yaml, packages/system/monitoring/templates/vpa.yaml
Per-log-storage resources expanded from 1→3 (vlstorage, vlselect, vlinsert); workload monitors updated to generate three monitors per storage; VPAs added for each component with per-container defaults.
VictoriaMetrics Operator — CRD Upgrade Subchart
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/...
templates/_helpers.yaml, cm.yaml, job.yaml, role.yaml, serviceaccount.yaml, values.yaml, README.md
New crds.upgrade subchart: Helm-hooked ConfigMap, Job, ServiceAccount, ClusterRole/Binding and helpers to apply CRDs server-side; configurable images, forceConflicts, env, volumes, security, and hook metadata.
Operator Chart & Template Changes
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/*, charts/victoria-metrics-common/*
Bumped chart/app versions to v0.68.1; added image.configReloader, crds.upgrade, service.trafficDistribution, shareProcessNamespace; webhook generation made CRD-driven; label handling now includes global.extraLabels; defensive deepCopy for images and other template adjustments.
Helm Packaging & Docs
packages/system/victoria-metrics-operator/charts/.../.helmignore, README.md, RELEASE_NOTES
Replaced blanket *.md ignore with targeted ignores; added README files and updated RELEASE_NOTES/Chart metadata and artifacthub/readme entries.
Migration Script & Version Bump
packages/core/platform/images/migrations/migrations/35, packages/core/platform/values.yaml
Added migration script that annotates VLogs resources with helm.sh/resource-policy=keep and writes cozystack-version ConfigMap; bumped migrations.targetVersion 35→36.
E2E & Misc
hack/e2e-install-cozystack.bats
Adjusted readiness checks from vlogs/genericvlclusters/generic and updated VM readiness fields.

Sequence Diagram(s)

sequenceDiagram
  participant Helm as Helm (render & hooks)
  participant K8s as Kubernetes API
  participant CM as ConfigMap (crd bundle)
  participant Job as Upgrade Job (Pod)
  participant Init as Init Container (busybox)
  participant Kubectl as Main Container (kubectl)

  Helm->>K8s: create ConfigMap (crd bundle) [pre-hook]
  Helm->>K8s: create ServiceAccount, ClusterRole/Binding, Job [pre-hook]
  K8s-->>Job: schedule Pod with init + main containers
  Job->>Init: extract /crds/crd.yaml.bz2 -> /tmp/crd.yaml
  Init-->>Job: files ready
  Job->>Kubectl: kubectl apply --server-side /tmp/crd.yaml (±--force-conflicts)
  Kubectl->>K8s: apply CRDs
  K8s-->>Kubectl: apply responses
  Job->>Helm: Job completes (hook succeeds)
  Helm->>K8s: continue/cleanup per hook policy
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

size:L

Suggested reviewers

  • kvaps
  • lllamnyp

Poem

🐰 I hopped through charts and YAML streams,
I split one VLogs into three bright teams;
Helm hooks hummed, CRD bundles flew in tow,
Jobs applied manifests—watch them grow;
A carrot nudge — migrations set to go! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: migrating VictoriaLogs from the deprecated VLogs CR to the VLCluster CR in cluster mode, which is the primary objective of this changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/migrate-vlogs-to-vlcluster

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 and usage tips.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 significantly upgrades the VictoriaLogs monitoring infrastructure by transitioning from a deprecated single-node setup to a robust, horizontally scalable cluster architecture. This change improves the system's resilience and performance by distributing log ingestion, querying, and storage across dedicated components. The update also includes a major version bump for the VictoriaMetrics operator, ensuring compatibility and leveraging new features, alongside a mechanism to safely manage the transition of existing resources.

Highlights

  • VictoriaLogs Migration: Migrated VictoriaLogs from the single-node VLogs Custom Resource to the distributed VLCluster Custom Resource, enhancing reliability and horizontal scalability by utilizing vlinsert, vlselect, and vlstorage components.
  • Operator Upgrade: Upgraded the victoria-metrics-operator from version v0.55.0 to v0.68.1 to introduce support for the new VLCluster CRD and other operator enhancements.
  • Endpoint and Monitoring Updates: Updated Fluent-bit outputs, Grafana datasources, and external services to reflect the new vlinsert and vlselect component endpoints and ports. WorkloadMonitors were also updated to monitor the three new components with increased replicas.
  • Automated Migration Script: Introduced a new migration script (35 -> 36) that automatically annotates existing VLogs resources with helm.sh/resource-policy: keep to prevent their deletion during the upgrade, allowing for manual verification and data migration.
  • Vertical Pod Autoscalers (VPA): Added Vertical Pod Autoscalers for the vlinsert, vlselect, and vlstorage components of VLCluster to automatically manage resource requests and limits.

🧠 New Feature in Public Preview: You can now enable Memory 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.

Changelog
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
    • Updated Fluent-bit output host and port to point to the new vlinsert-generic service.
  • packages/core/platform/images/migrations/migrations/35
    • Added a new migration script (35 -> 36) to apply helm.sh/resource-policy: keep annotation to existing VLogs resources.
  • packages/core/platform/values.yaml
    • Updated the targetVersion for platform migrations to 36.
  • packages/extra/monitoring/templates/dashboard-resourcemap.yaml
    • Updated the dashboard resource map to include vlstorage, vlselect, and vlinsert components.
  • packages/extra/monitoring/templates/workloadmonitors.yaml
    • Replaced the single VLogs WorkloadMonitor with three distinct WorkloadMonitors for vlstorage, vlselect, and vlinsert components, each configured with 2 replicas.
  • packages/system/cozystack-basics/templates/monitoring-external-services.yaml
    • Renamed the external service from vlogs-generic to vlinsert-generic.
  • packages/system/monitoring-agents/values.yaml
    • Updated Fluent-bit output host and port in values to vlinsert-generic:9481.
  • packages/system/monitoring/templates/vlogs/grafana-datasource.yaml
    • Updated the Grafana datasource URL to point to the new vlselect service and port 9471.
  • packages/system/monitoring/templates/vlogs/vlogs.yaml
    • Migrated the VLogs Custom Resource Definition (CRD) to VLCluster CRD, updating the API version and configuring vlinsert, vlselect, and vlstorage components with 2 replicas each.
  • packages/system/monitoring/templates/vpa.yaml
    • Added Vertical Pod Autoscalers (VPAs) for vlinsert, vlselect, and vlstorage components, defining default min/max allowed CPU and memory resources.
  • packages/system/monitoring/values.yaml
    • Removed the default storageClassName for logsStorages.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/.helmignore
    • Updated the list of files to be ignored by Helm.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.lock
    • Updated the victoria-metrics-common dependency version to 0.0.46 and regenerated the digest.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.yaml
    • Updated the operator's appVersion to v0.68.1 and added a artifacthub.io/readme annotation.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/README.md
    • Added a new README file for the VictoriaMetrics Operator Helm chart.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES
    • Updated the release notes to reflect the operator version 0.59.1 and app version v0.68.1.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/README.md
    • Added a new README file for the CRDs subchart.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/_helpers.yaml
    • Added helper templates for CRD upgrade job naming and service account.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/cm.yaml
    • Added a ConfigMap template for storing CRD definitions for the upgrade job.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/job.yaml
    • Added a Job template for upgrading Custom Resource Definitions (CRDs) using kubectl apply --server-side.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml
    • Added ClusterRole and ClusterRoleBinding templates for the CRD upgrade job to manage CRDs.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml
    • Added a ServiceAccount template for the CRD upgrade job.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml
    • Added new configuration values for the CRD upgrade job, including image details for busybox and kubectl.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore
    • Updated the list of files to be ignored by Helm.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/Chart.yaml
    • Updated the common chart's version to 0.0.46 and added a artifacthub.io/readme annotation.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md
    • Added a new README file for the VictoriaMetrics Common Helm chart.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/RELEASE_NOTES
    • Updated the release notes to reflect the common chart version 0.0.46.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_enterprise.tpl
    • Updated the documentation link for enterprise features.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_helpers.tpl
    • Modified the vm.labels helper to include global extra labels in the merged labels.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_image.tpl
    • Modified image handling logic to ensure deep copying of image values.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/_helpers.tpl
    • Changed the initialization of altNames to an empty list.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/cleanup.yaml
    • Simplified the condition for CRD cleanup and updated the image tag logic for kubectl.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crb.yaml
    • Simplified the condition for CRD cleanup.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crd.yaml
    • Removed the inclusion of labels from CRD metadata when rendering.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/role.yaml
    • Updated CRD parsing logic, added pods/eviction and gateway.networking.k8s.io resources, and removed nodes/proxy from the ClusterRole rules.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/server.yaml
    • Renamed deployment.yaml to server.yaml, added shareProcessNamespace option, and introduced new environment variables for config reloader image and registry.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/service.yaml
    • Added support for trafficDistribution in the service definition.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml
    • Renamed service_account.yaml to serviceaccount.yaml, updated service account name templating, and simplified the condition for CRD cleanup.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/webhook.yaml
    • Updated webhook configuration to dynamically generate validation webhooks based on CRDs and their versions, and added a disabledFor list to selectively disable validation.
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/values.yaml
    • Added a configReloader section for image configuration, updated the crd.cleanup.image.repository to rancher/kubectl, introduced a comprehensive crds.upgrade section for CRD upgrade job configuration, removed operator.useCustomConfigReloader, added shareProcessNamespace, and refactored admissionWebhooks to use a disabledFor list instead of enabledCRDValidation.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize 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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. 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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

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 successfully migrates VictoriaLogs from the single-node VLogs CR to the VLCluster (cluster mode), enhancing reliability and horizontal scalability. The changes include upgrading the VictoriaMetrics operator, updating Fluent-bit outputs and Grafana datasources to reflect the new component names, and introducing new WorkloadMonitor definitions and VPA configurations for the VLCluster components. A migration script is also added to preserve existing VLogs resources during the upgrade process. Overall, the changes align well with the stated objective of moving to a more robust logging solution.


set -euo pipefail

VLOGS=$(kubectl get vlogs.operator.victoriametrics.com --all-namespaces --output jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}' 2>/dev/null || true)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The kubectl get ... 2>/dev/null || true command suppresses all stderr output. While || true correctly handles the scenario where no vlogs resources are found, 2>/dev/null will also hide any other potential errors from kubectl get (e.g., authentication failures, API server connectivity issues). This could lead to silent failures where existing VLogs resources are not annotated as expected, potentially causing data loss if the user relies on them being preserved. Consider logging actual errors to stderr while still allowing the script to proceed if no resources are found.

Suggested change
VLOGS=$(kubectl get vlogs.operator.victoriametrics.com --all-namespaces --output jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}' 2>/dev/null || true)
VLOGS=$(kubectl get vlogs.operator.victoriametrics.com --all-namespaces --output jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}' || true)

Comment on lines 11 to 13
{{- $annotations := mergeOverwrite ((include "vm-operator.crds.annotations" .) | fromYaml) .Values.crds.annotations -}}
{{- $extra := dict "metadata" (dict "annotations" $annotations "labels" $labels) -}}
{{- $extra := dict "metadata" (dict "annotations" $annotations) -}}
{{- range $crds }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The common vm.labels are no longer being applied to the Custom Resource Definitions (CRDs). Previously, $labels was included in the $extra dictionary, ensuring standard labels like app.kubernetes.io/name and helm.sh/chart were present on CRDs. While CRDs are cluster-scoped and not typical application instances, some cluster management tools or GitOps practices might rely on these labels for consistent resource identification, filtering, or lifecycle management. Removing them could potentially break such integrations or make CRD management less consistent with other Helm-managed resources. Please confirm if this change in labeling strategy for CRDs is intentional and if there are no downstream dependencies that rely on these labels.

  {{- $annotations := mergeOverwrite ((include "vm-operator.crds.annotations" .) | fromYaml) .Values.crds.annotations -}}
  {{- $labels := (include "vm.labels" $ctx) | fromYaml -}}
  {{- $extra := dict "metadata" (dict "annotations" $annotations "labels" $labels) -}}

@sircthulhu
Kirill Ilin (sircthulhu) marked this pull request as ready for review March 10, 2026 07:03
@dosubot dosubot Bot added the size/XL This PR changes 500-999 lines, ignoring generated files label Mar 10, 2026
Upgrade from v0.55.0 to v0.68.1 to add VLCluster CRD support,
which is required for migrating VictoriaLogs from single-node
to cluster mode.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
@dosubot dosubot Bot added the kind/feature Categorizes issue or PR as related to a new feature label Mar 10, 2026
Replace deprecated single-node VLogs CR with VLCluster (cluster mode)
for reliability and horizontal scalability.

Changes:
- Replace VLogs (v1beta1) with VLCluster (v1) using vlinsert/vlselect/vlstorage
- Update fluent-bit outputs to vlinsert-generic:9481
- Update Grafana datasource to vlselect:9471
- Update ExternalName service from vlogs-generic to vlinsert-generic
- Add VPA for all VLCluster components
- Update WorkloadMonitors for three-component architecture
- Add migration 35 to preserve old VLogs resources with keep annotation

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
@sircthulhu
Kirill Ilin (sircthulhu) force-pushed the feat/migrate-vlogs-to-vlcluster branch from 5e03ac5 to 62d36ec Compare March 10, 2026 07:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 11

🧹 Nitpick comments (8)
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md (1)

3-3: Use descriptive link text on Line 3.

[here] trips MD059 and is less accessible in rendered docs. Make the link text describe the destination.

📝 Proposed fix
-Chart documentation is available [here](https://docs.victoriametrics.com/helm/victoria-metrics-common/)
+Chart documentation is available in the [VictoriaMetrics Common Helm chart documentation](https://docs.victoriametrics.com/helm/victoria-metrics-common/)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md`
at line 3, Replace the vague link text "[here]" in README.md with a descriptive
phrase (e.g., "VictoriaMetrics Common Helm chart documentation" or
"VictoriaMetrics Common Helm chart docs") so the markdown link reads like
"[VictoriaMetrics Common Helm chart
documentation](https://docs.victoriametrics.com/helm/victoria-metrics-common/)";
just update the link text and keep the existing URL to satisfy
accessibility/MD059.
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES (1)

7-7: Consider expanding release notes with breaking change context.

The operator version v0.68.1 is valid, but the release notes omit important context: VLogs was deprecated in v0.59.0 and became read-only starting v0.61.0. By v0.68.1, users who have not migrated to VLCluster or VLSingle will be running with a read-only VLogs, which is a breaking change affecting deployments and requiring manual migration. Add a note referencing the migration path or link to the operator's VLogs deprecation documentation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES`
at line 7, Update the RELEASE_NOTES entry for v0.68.1 to explicitly call out the
VLogs deprecation and breaking-change impact: mention that VLogs was deprecated
in v0.59.0 and became read-only in v0.61.0, that v0.68.1 will run with read-only
VLogs for users who haven't migrated, and add guidance referencing the supported
migration paths (VLCluster and VLSingle) plus a link to the operator's VLogs
deprecation/migration documentation so operators know they must perform manual
migration.
packages/system/monitoring/templates/vpa.yaml (1)

90-178: Consider extracting a shared VPA helper for the VM and VL blocks.**

This section copies the existing metricsStorages VPA template almost verbatim. A small partial that takes the component name, workload kind, and default limits would make future policy/default changes much less likely to drift between the VM* and VL* resources.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/system/monitoring/templates/vpa.yaml` around lines 90 - 178, The VPA
blocks for vlinsert, vlselect, and vlstorage duplicate the same structure and
the metricsStorages VPA template; extract a Helm partial (e.g., define
"vpa.component") that accepts parameters: component name/alias ({{ .name }}),
workload kind (Deployment/StatefulSet), containerName
(vlinsert/vlselect/vlstorage) and default min/max values, then replace each
repeated block in packages/system/monitoring/templates/vpa.yaml (the range over
.Values.logsStorages and the individual blocks creating vpa-vlinsert-{{ .name
}}, vpa-vlselect-{{ .name }}, vpa-vlstorage-{{ .name }}) with calls to the new
partial via include (or template) passing the appropriate defaults so future
policy/default changes live in one place.
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml (2)

4-4: Unused $fullname variable.

The $fullname variable is defined but never used in this template. Consider removing it to reduce clutter.

Suggested fix
 {{- $ctx := dict "helm" . }}
-{{- $fullname := include "vm.plain.fullname" $ctx }}
 {{- $ns := include "vm.namespace" $ctx }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml`
at line 4, The template defines an unused variable $fullname via include
"vm.plain.fullname" $ctx; remove that declaration from the serviceaccount.yaml
template (the line setting $fullname) to eliminate dead code, and verify no
other references to $fullname remain in this template (keep include usage only
where the resulting value is actually referenced).

20-22: Potential mutation of shared values reference.

Using set on $extraLabels may mutate the original .Values.upgrade.serviceAccount.labels if it's passed by reference. This could cause unexpected side effects in subsequent template renders.

Suggested fix using deepCopy
-  {{- $extraLabels := $sa.labels | default dict }}
-  {{- $_ := set $extraLabels "app.kubernetes.io/component" "upgrade-crds" }}
+  {{- $extraLabels := deepCopy ($sa.labels | default dict) }}
+  {{- $_ := set $extraLabels "app.kubernetes.io/component" "upgrade-crds" }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml`
around lines 20 - 22, $extraLabels is assigned from $sa.labels and then mutated
via set, which can modify the original shared value; to fix, create a defensive
copy (use deepCopy) of $sa.labels before calling set so mutations don't affect
the original .Values, then assign the modified copy into $ctx (referencing
$extraLabels, $sa.labels, set and $ctx in the template).
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml (1)

9-11: Consider pinning the busybox image tag instead of using latest.

Using latest tag creates non-deterministic deployments and can lead to unexpected behavior if the upstream image changes. Consider pinning to a specific version (e.g., 1.36 or 1.37) for reproducible builds.

Suggested fix
   busybox:
     image:
       repository: busybox
-      tag: latest
+      tag: "1.37"
       pullPolicy: IfNotPresent
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml`
around lines 9 - 11, The values.yaml currently pins the init image with
repository "busybox" and tag "latest"; change the tag from "latest" to a
specific, tested version (e.g., "1.36.1" or "1.37.0") to ensure deterministic
deployments, update any references to this image in templates that use the
values (look for usage of values like .Values.initImage.repository and
.Values.initImage.tag or similar), and update chart/README or changelog to
record the chosen pinned version so consumers know which busybox version the
chart relies on.
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crb.yaml (1)

26-31: Unnecessary namespace field on cluster-scoped resource.

ClusterRoleBinding is a cluster-scoped resource; the namespace field in metadata is ignored by Kubernetes. While harmless, removing it improves clarity.

Suggested fix
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
   name: {{ $fullname }}-cleanup-hook
-  namespace: {{ $ns }}
   labels: {{ include "vm.labels" $ctx | nindent 4 }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crb.yaml`
around lines 26 - 31, The ClusterRoleBinding template includes an unnecessary
metadata.namespace entry; remove the `namespace: {{ $ns }}` line from the
ClusterRoleBinding resource (the block that creates the {{ $fullname
}}-cleanup-hook ClusterRoleBinding) so the cluster-scoped resource has no
namespace field while leaving labels ({{ include "vm.labels" $ctx }}) and other
metadata intact.
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/role.yaml (1)

163-169: Inconsistent indentation in RBAC rule.

This rule block uses extra indentation for apiGroups and resources compared to adjacent rules (e.g., lines 170-176). While functional, it reduces consistency.

🔧 Suggested fix for consistent formatting
 - apiGroups:
-    - gateway.networking.k8s.io
+  - gateway.networking.k8s.io
   resources:
-    - httproutes
-    - httproutes/finalizers
+  - httproutes
+  - httproutes/finalizers
   verbs:
-    - '*'
+  - "*"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/role.yaml`
around lines 163 - 169, The RBAC rule block for the Gateway API (the rule
listing apiGroups: gateway.networking.k8s.io and resources: httproutes,
httproutes/finalizers) has extra indentation compared to adjacent rules; update
the YAML so apiGroups, resources and verbs align at the same indentation level
as the other rule entries in the Role template (normalize spacing for the rule
containing httproutes to match the surrounding rules) to keep consistent
formatting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/platform/images/migrations/migrations/35`:
- Line 8: Migration 35 uses "set -euo pipefail" under a POSIX /bin/sh shebang
and also runs a pipeline "kubectl create ... | kubectl apply ..." that would
break or behave inconsistently on dash/Alpine; fix by either switching the
script shebang to "#!/bin/bash" (consistent with migrations 28–30) to allow
pipefail, or make the script POSIX-safe by removing "pipefail" from the "set
-euo pipefail" line and changing the pipeline to a tmpfile approach: capture the
output of "kubectl create ..." into a temporary file (using mktemp), then run
"kubectl apply -f <tmpfile>" and delete the tmpfile, ensuring the first
command's failure doesn't get swallowed; update the script around the "set -euo
pipefail" and the kubectl create | kubectl apply pipeline accordingly.

In `@packages/core/platform/values.yaml`:
- Around line 8-9: The values.yaml update advanced targetVersion to 36 but left
the migrations image pinned to the old immutable digest; update the "image"
value next to "targetVersion" so the referenced migrations image contains the
new 35→36 script (i.e., bump the migrations image tag/digest to the release that
includes the migrations/35 script or use the correct published image name for
migration 36), ensuring the "image" key and "targetVersion" are changed together
so the upgrade path is available.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml`:
- Around line 17-32: The RBAC rule in role.yaml incorrectly combines the create
verb with a resourceNames restriction (apiGroups: "apiextensions.k8s.io",
resources: "customresourcedefinitions", verbs: create, patch, update, get, list,
resourceNames populated from $crds), which prevents create from working on fresh
installs; fix it by splitting into two rules: one rule with verbs: ["create"]
for apiGroups "apiextensions.k8s.io" and resources "customresourcedefinitions"
without any resourceNames, and a second rule with verbs:
["patch","update","get","list"] that includes the existing resourceNames
populated via the same {{- range $crds }} / {{- $crd := fromYaml . }} / {{
$crd.metadata.name }} loop so the named-CRD restrictions only apply to
non-create operations.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore`:
- Around line 24-26: The change directly edits the vendored .helmignore
(removing/adding entries like CHANGELOG.md/_changelog.md/_index.md) inside the
vendored chart—don't patch vendored charts directly; revert this edit in
.helmignore and instead apply the change through the chart vendoring/update flow
or an overlay (e.g., update the upstream chart and re-run the chart vendor sync
or add the ignore via your supported overlay mechanism for charts) so the change
survives upstream syncs.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES`:
- Line 3: The RELEASE_NOTES entry currently shows "**Release date:** 03 Mar
2026" which predates the PR; update the release date line in the RELEASE_NOTES
file to the PR creation date (e.g., "**Release date:** 05 Mar 2026") or a later
valid date so it is not earlier than the PR that introduced it.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/cleanup.yaml`:
- Around line 39-44: The loop building $names can append empty entries when
fromYaml returns an empty/invalid document; update the range over $crds in
cleanup.yaml to skip nil/empty CRD maps by checking that the parsed $crd (result
of fromYaml) has a non-empty .spec.names.singular before appending to $names —
i.e., after parsing with fromYaml, guard on $crd and $crd.spec.names.singular
being present/non-empty and only then append to $names to avoid producing empty
CSV args for kubectl.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crd.yaml`:
- Line 12: The $extra dict currently only injects annotations ({{- $extra :=
dict "metadata" (dict "annotations" $annotations) -}}) so CRDs lose
metadata.labels (vm.labels / .Values.global.extraLabels); update $extra to
include metadata.labels as well (e.g., dict "metadata" (dict "annotations"
$annotations "labels" $labels) or merge in .Values.global.extraLabels) so the
rendered CRDs receive vm.labels/.Values.global.extraLabels like other templates;
ensure you reference the same label variable used elsewhere (vm.labels or
$labels) when modifying the $extra declaration.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml`:
- Line 18: The cleanup ServiceAccount conditional only checks
.Values.crds.cleanup.enabled and must also require .Values.crds.enabled; update
the guard around the ServiceAccount template (the block starting with {{- if
.Values.crds.cleanup.enabled }}) to require both .Values.crds.enabled and
.Values.crds.cleanup.enabled, and apply the same combined guard to the cleanup
Job template (the Job that runs kubectl delete for CRD types) so the cleanup
artifacts are only rendered when CRD management is enabled.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/values.yaml`:
- Around line 67-68: Typo in the YAML comment: update the comment string above
the forceConflicts key to read "--force-conflicts" (replace "conflics" with
"conflicts") so it correctly documents the kubectl flag; locate the comment that
currently reads "# -- Adds `--force-conflics` argument to kubectl" and change it
to "# -- Adds `--force-conflicts` argument to kubectl" while leaving the
forceConflicts: false key unchanged.
- Around line 69-73: The busybox image is pinned to the mutable tag "latest"
(busybox.image.tag) which harms reproducibility; update busybox.image.tag to a
specific, immutable version (e.g., a semver like "1.36.1" or whatever your org
approves), leave busybox.image.repository as "busybox", and ensure any related
deployment/documentation or upgrade notes reflect the chosen pinned version so
CI/rollouts use a fixed artifact instead of latest.
- Around line 247-248: The values.yaml adds the service.trafficDistribution
field which can break Service creation on clusters older than Kubernetes 1.30;
update the chart to only emit the trafficDistribution field when the cluster
supports it (or keep the values.yaml default empty and document compatibility).
Concretely, modify the Service template that uses .Values.trafficDistribution
(e.g., templates/service.yaml / the Service manifest generator) to wrap the
trafficDistribution stanza in a Helm conditional that checks cluster version via
.Capabilities.KubeVersion (use semverCompare to require >= 1.30) or otherwise
only include the field when .Values.trafficDistribution is non-empty, and add a
note in values.yaml describing the Kubernetes version requirement for
trafficDistribution.

---

Nitpick comments:
In `@packages/system/monitoring/templates/vpa.yaml`:
- Around line 90-178: The VPA blocks for vlinsert, vlselect, and vlstorage
duplicate the same structure and the metricsStorages VPA template; extract a
Helm partial (e.g., define "vpa.component") that accepts parameters: component
name/alias ({{ .name }}), workload kind (Deployment/StatefulSet), containerName
(vlinsert/vlselect/vlstorage) and default min/max values, then replace each
repeated block in packages/system/monitoring/templates/vpa.yaml (the range over
.Values.logsStorages and the individual blocks creating vpa-vlinsert-{{ .name
}}, vpa-vlselect-{{ .name }}, vpa-vlstorage-{{ .name }}) with calls to the new
partial via include (or template) passing the appropriate defaults so future
policy/default changes live in one place.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml`:
- Line 4: The template defines an unused variable $fullname via include
"vm.plain.fullname" $ctx; remove that declaration from the serviceaccount.yaml
template (the line setting $fullname) to eliminate dead code, and verify no
other references to $fullname remain in this template (keep include usage only
where the resulting value is actually referenced).
- Around line 20-22: $extraLabels is assigned from $sa.labels and then mutated
via set, which can modify the original shared value; to fix, create a defensive
copy (use deepCopy) of $sa.labels before calling set so mutations don't affect
the original .Values, then assign the modified copy into $ctx (referencing
$extraLabels, $sa.labels, set and $ctx in the template).

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml`:
- Around line 9-11: The values.yaml currently pins the init image with
repository "busybox" and tag "latest"; change the tag from "latest" to a
specific, tested version (e.g., "1.36.1" or "1.37.0") to ensure deterministic
deployments, update any references to this image in templates that use the
values (look for usage of values like .Values.initImage.repository and
.Values.initImage.tag or similar), and update chart/README or changelog to
record the chosen pinned version so consumers know which busybox version the
chart relies on.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md`:
- Line 3: Replace the vague link text "[here]" in README.md with a descriptive
phrase (e.g., "VictoriaMetrics Common Helm chart documentation" or
"VictoriaMetrics Common Helm chart docs") so the markdown link reads like
"[VictoriaMetrics Common Helm chart
documentation](https://docs.victoriametrics.com/helm/victoria-metrics-common/)";
just update the link text and keep the existing URL to satisfy
accessibility/MD059.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES`:
- Line 7: Update the RELEASE_NOTES entry for v0.68.1 to explicitly call out the
VLogs deprecation and breaking-change impact: mention that VLogs was deprecated
in v0.59.0 and became read-only in v0.61.0, that v0.68.1 will run with read-only
VLogs for users who haven't migrated, and add guidance referencing the supported
migration paths (VLCluster and VLSingle) plus a link to the operator's VLogs
deprecation/migration documentation so operators know they must perform manual
migration.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crb.yaml`:
- Around line 26-31: The ClusterRoleBinding template includes an unnecessary
metadata.namespace entry; remove the `namespace: {{ $ns }}` line from the
ClusterRoleBinding resource (the block that creates the {{ $fullname
}}-cleanup-hook ClusterRoleBinding) so the cluster-scoped resource has no
namespace field while leaving labels ({{ include "vm.labels" $ctx }}) and other
metadata intact.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/role.yaml`:
- Around line 163-169: The RBAC rule block for the Gateway API (the rule listing
apiGroups: gateway.networking.k8s.io and resources: httproutes,
httproutes/finalizers) has extra indentation compared to adjacent rules; update
the YAML so apiGroups, resources and verbs align at the same indentation level
as the other rule entries in the Role template (normalize spacing for the rule
containing httproutes to match the surrounding rules) to keep consistent
formatting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1d50520d-5a79-452c-9ef0-3a0deedb84cf

📥 Commits

Reviewing files that changed from the base of the PR and between adacd44 and 62d36ec.

⛔ Files ignored due to path filters (2)
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.lock is excluded by !**/*.lock
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/files/crd.yaml.bz2 is excluded by !**/*.bz2
📒 Files selected for processing (41)
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/core/platform/images/migrations/migrations/35
  • packages/core/platform/values.yaml
  • packages/extra/monitoring/templates/dashboard-resourcemap.yaml
  • packages/extra/monitoring/templates/workloadmonitors.yaml
  • packages/system/cozystack-basics/templates/monitoring-external-services.yaml
  • packages/system/monitoring-agents/values.yaml
  • packages/system/monitoring/templates/vlogs/grafana-datasource.yaml
  • packages/system/monitoring/templates/vlogs/vlogs.yaml
  • packages/system/monitoring/templates/vpa.yaml
  • packages/system/monitoring/values.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/.helmignore
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/README.md
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/README.md
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/crds/crd.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/_helpers.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/cm.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/job.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/Chart.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/RELEASE_NOTES
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_enterprise.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_helpers.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_image.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/crd.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/_helpers.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/cleanup.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crb.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crd.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/role.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/server.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/service.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/webhook.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/values.yaml

# Users will need to manually verify the new cluster is working, then optionally
# migrate historical data and delete old VLogs resources.

set -euo pipefail

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

echo "== Migration script =="
sed -n '1,40p' packages/core/platform/images/migrations/migrations/35

echo
echo "== Image build files under packages/core/platform/images/migrations =="
fd -a 'Dockerfile|Containerfile' packages/core/platform/images/migrations -x sh -c '
  echo "--- $1 ---"
  sed -n "1,160p" "$1"
' sh {}

echo
echo "== Shell-related matches in migration assets =="
rg -n -C2 '^#!/bin/sh|^#!/bin/bash|pipefail' packages/core/platform/images/migrations

Repository: cozystack/cozystack

Length of output: 15667


🏁 Script executed:

#!/bin/bash
set -eu

# Check what /bin/sh is in Alpine 3.22
echo "=== Alpine 3.22 /bin/sh info ==="
docker run --rm alpine:3.22 /bin/sh -c 'ls -la /bin/sh && /bin/sh --version 2>&1 || echo "No version flag"' 2>/dev/null || echo "[Docker unavailable; checking alternative]"

# Check migration history - look for any error handling around pipefail
echo
echo "=== Looking for conditional pipefail or shell detection in migrations ==="
rg -n 'pipefail|SHELL|sh -c|bash' packages/core/platform/images/migrations/run-migrations.sh -A2 -B2

# Check if there are any conditional shebang patterns or known issues
echo
echo "=== Checking commit history or comments around pipefail usage ==="
git log --all --oneline --grep="pipefail\|shell" -- packages/core/platform/images/migrations 2>/dev/null | head -20 || echo "[git search unavailable]"

# Verify the exact shell used by checking for common idioms that would fail with dash
echo
echo "=== Checking for bash-specific constructs in migration 35 ==="
sed -n '1,30p' packages/core/platform/images/migrations/migrations/35 | cat -A

Repository: cozystack/cozystack

Length of output: 1473


🏁 Script executed:

#!/bin/bash
set -eu

echo "=== Migration 28 (bash variant) ==="
sed -n '1,50p' packages/core/platform/images/migrations/migrations/28

echo
echo "=== Migration 29 (bash variant) ==="
sed -n '1,50p' packages/core/platform/images/migrations/migrations/29

echo
echo "=== Commit 880b99f3 details ==="
git show 880b99f3 --stat 2>/dev/null | head -40

echo
echo "=== Check if grep is used in migration 35 ==="
rg -n 'grep|pipe' packages/core/platform/images/migrations/migrations/35

Repository: cozystack/cozystack

Length of output: 4326


Migration 35 uses a POSIX-incompatible shell construct with a pipeline that can fail silently.

Line 8 (set -euo pipefail) in a #!/bin/sh script is incompatible with POSIX /bin/sh (e.g., dash in Alpine). The issue is documented in commit 880b99f, which fixed the same pattern in migrations 28 and 29 by wrapping problematic commands. Migration 35 compounds this with a pipeline on lines 20–21 (kubectl create ... | kubectl apply ...), which will fail if the first command fails and pipefail is active.

Either use #!/bin/bash (like migrations 28, 29, 30) or avoid pipefail by removing it and using a tmpfile:

POSIX-safe fix
 #!/bin/sh
-set -euo pipefail
+set -eu
 
 VLOGS=$(kubectl get vlogs.operator.victoriametrics.com --all-namespaces --output jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}' 2>/dev/null || true)
 for resource in $VLOGS; do
@@ -17,6 +17,11 @@ done
+tmpfile="$(mktemp)"
+trap 'rm -f "$tmpfile"' EXIT
+
 kubectl create configmap --namespace cozy-system cozystack-version \
-  --from-literal=version=36 --dry-run=client --output yaml | kubectl apply --filename -
+  --from-literal=version=36 --dry-run=client --output yaml >"$tmpfile"
+kubectl apply --filename "$tmpfile"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
set -euo pipefail
#!/bin/sh
set -eu
VLOGS=$(kubectl get vlogs.operator.victoriametrics.com --all-namespaces --output jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}' 2>/dev/null || true)
for resource in $VLOGS; do
namespace=$(echo "$resource" | cut -d'/' -f1)
name=$(echo "$resource" | cut -d'/' -f2)
kubectl patch vlog --namespace "$namespace" "$name" --type merge --patch '{"spec":{"logLevel":"info"}}'
done
tmpfile="$(mktemp)"
trap 'rm -f "$tmpfile"' EXIT
kubectl create configmap --namespace cozy-system cozystack-version \
--from-literal=version=36 --dry-run=client --output yaml >"$tmpfile"
kubectl apply --filename "$tmpfile"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/platform/images/migrations/migrations/35` at line 8, Migration
35 uses "set -euo pipefail" under a POSIX /bin/sh shebang and also runs a
pipeline "kubectl create ... | kubectl apply ..." that would break or behave
inconsistently on dash/Alpine; fix by either switching the script shebang to
"#!/bin/bash" (consistent with migrations 28–30) to allow pipefail, or make the
script POSIX-safe by removing "pipefail" from the "set -euo pipefail" line and
changing the pipeline to a tmpfile approach: capture the output of "kubectl
create ..." into a temporary file (using mktemp), then run "kubectl apply -f
<tmpfile>" and delete the tmpfile, ensuring the first command's failure doesn't
get swallowed; update the script around the "set -euo pipefail" and the kubectl
create | kubectl apply pipeline accordingly.

Comment on lines 8 to +9
image: ghcr.io/cozystack/cozystack/platform-migrations:v1.1.0@sha256:d7e8955c1ad8c8fbd4ce42b014c0f849d73d0c3faf0cedaac8e15d647fb2f663
targetVersion: 35
targetVersion: 36

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Bump the migrations image together with targetVersion.

Line 9 advances the platform to migration 36, but Line 8 still pins migrations.image to an immutable v1.1.0@sha256:... digest. The new packages/core/platform/images/migrations/migrations/35 script added in this PR cannot exist in that already-published image, so the 35→36 upgrade path is broken until the image reference is updated as well.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/platform/values.yaml` around lines 8 - 9, The values.yaml
update advanced targetVersion to 36 but left the migrations image pinned to the
old immutable digest; update the "image" value next to "targetVersion" so the
referenced migrations image contains the new 35→36 script (i.e., bump the
migrations image tag/digest to the release that includes the migrations/35
script or use the correct published image name for migration 36), ensuring the
"image" key and "targetVersion" are changed together so the upgrade path is
available.

Comment on lines +17 to +32
rules:
- apiGroups:
- "apiextensions.k8s.io"
resources:
- "customresourcedefinitions"
verbs:
- create
- patch
- update
- get
- list
resourceNames:
{{- range $crds }}
{{- $crd := fromYaml . }}
- {{ $crd.metadata.name }}
{{- end }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Kubernetes RBAC resourceNames create verb behavior

💡 Result:

In Kubernetes RBAC, rules[].resourceNames only matches requests where the API request is for a specific named object (ie, the request URL includes the object name, like GET .../configmaps/my-configmap). As a result:

  • You cannot restrict create of top-level resources using resourceNames. Kubernetes explicitly says resourceNames cannot restrict top-level create (and deletecollection) because “the name of the new object may not be known at authorization time.” create will only be authorized by a rule without resourceNames. [1]
  • Exception: subresource creates can be name-restricted. The “top-level create” limitation does not apply to subresources; Kubernetes calls out pods/exec as an example where resourceNames can be used. [1]
  • get, update, patch, delete can be restricted with resourceNames because those requests typically include the target object name in the URL. [1]
  • list / watch + resourceNames: if you restrict list/watch by resourceNames, the client must also use a metadata.name=... field selector that matches, otherwise authorization will fail. [1]

Sources: Kubernetes RBAC docs (and an example discussion reiterating the same limitation). [1][2]


Kubernetes RBAC resourceNames cannot restrict the create verb. The resourceNames field only applies to requests for existing named resources (like get, update, patch, delete). For create operations, the resource name is not yet known at authorization time, so resourceNames restrictions are ignored. This means the create rule will fail on fresh installs where CRDs don't yet exist, defeating the permission.

Split the rule into two: one for create without resourceNames, and another for patch/update/get/list with the resourceNames restriction.

Proposed fix
 rules:
+  - apiGroups:
+      - "apiextensions.k8s.io"
+    resources:
+      - "customresourcedefinitions"
+    verbs:
+      - create
   - apiGroups:
       - "apiextensions.k8s.io"
     resources:
       - "customresourcedefinitions"
     verbs:
-      - create
       - patch
       - update
       - get
       - list
     resourceNames:
       {{- range $crds }}
         {{- $crd := fromYaml . }}
       - {{ $crd.metadata.name }}
       {{- end }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
rules:
- apiGroups:
- "apiextensions.k8s.io"
resources:
- "customresourcedefinitions"
verbs:
- create
- patch
- update
- get
- list
resourceNames:
{{- range $crds }}
{{- $crd := fromYaml . }}
- {{ $crd.metadata.name }}
{{- end }}
rules:
- apiGroups:
- "apiextensions.k8s.io"
resources:
- "customresourcedefinitions"
verbs:
- create
- apiGroups:
- "apiextensions.k8s.io"
resources:
- "customresourcedefinitions"
verbs:
- patch
- update
- get
- list
resourceNames:
{{- range $crds }}
{{- $crd := fromYaml . }}
- {{ $crd.metadata.name }}
{{- end }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml`
around lines 17 - 32, The RBAC rule in role.yaml incorrectly combines the create
verb with a resourceNames restriction (apiGroups: "apiextensions.k8s.io",
resources: "customresourcedefinitions", verbs: create, patch, update, get, list,
resourceNames populated from $crds), which prevents create from working on fresh
installs; fix it by splitting into two rules: one rule with verbs: ["create"]
for apiGroups "apiextensions.k8s.io" and resources "customresourcedefinitions"
without any resourceNames, and a second rule with verbs:
["patch","update","get","list"] that includes the existing resourceNames
populated via the same {{- range $crds }} / {{- $crd := fromYaml . }} / {{
$crd.metadata.name }} loop so the named-CRD restrictions only apply to
non-create operations.

Comment on lines +24 to +26
CHANGELOG.md
_changelog.md
_index.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid patching .helmignore inside the vendored chart.

This is under packages/system/.../charts/..., so the change will drift from upstream and is likely to be overwritten on the next chart sync. Please move this through the chart vendoring/update flow or another supported overlay point instead of editing the vendored file directly. Based on learnings: Do NOT directly edit upstream Helm charts in vendored charts directory; use proper chart vendoring mechanisms.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore`
around lines 24 - 26, The change directly edits the vendored .helmignore
(removing/adding entries like CHANGELOG.md/_changelog.md/_index.md) inside the
vendored chart—don't patch vendored charts directly; revert this edit in
.helmignore and instead apply the change through the chart vendoring/update flow
or an overlay (e.g., update the upstream chart and re-run the chart vendor sync
or add the ignore via your supported overlay mechanism for charts) so the change
survives upstream syncs.

# Release notes for version 0.59.1

**Release date:** 02 Apr 2025
**Release date:** 03 Mar 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Incorrect release date: predates PR creation.

The release date is set to "03 Mar 2026" but this PR was created on "05 Mar 2026". The release date cannot be earlier than the PR that introduces it.

📅 Proposed fix
-**Release date:** 03 Mar 2026
+**Release date:** 10 Mar 2026
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Release date:** 03 Mar 2026
**Release date:** 10 Mar 2026
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES`
at line 3, The RELEASE_NOTES entry currently shows "**Release date:** 03 Mar
2026" which predates the PR; update the release date line in the RELEASE_NOTES
file to the PR creation date (e.g., "**Release date:** 05 Mar 2026") or a later
valid date so it is not earlier than the PR that introduced it.

{{- $labels := (include "vm.labels" $ctx) | fromYaml -}}
{{- $annotations := mergeOverwrite ((include "vm-operator.crds.annotations" .) | fromYaml) .Values.crds.annotations -}}
{{- $extra := dict "metadata" (dict "annotations" $annotations "labels" $labels) -}}
{{- $extra := dict "metadata" (dict "annotations" $annotations) -}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Restore metadata.labels when patching CRDs.

$extra now adds only annotations, so rendered CRDs stop receiving vm.labels / .Values.global.extraLabels. That's a regression for clusters with required-label policies, and it makes CRDs inconsistent with the rest of the chart.

Possible fix
   {{- $crds := $files.Get "crd.yaml" | splitList "---" }}
   {{- $annotations := mergeOverwrite ((include "vm-operator.crds.annotations" .) | fromYaml) .Values.crds.annotations -}}
-  {{- $extra := dict "metadata" (dict "annotations" $annotations) -}}
+  {{- $_ := set $ctx "extraLabels" .Values.extraLabels -}}
+  {{- $labels := include "vm.labels" $ctx | fromYaml -}}
+  {{- $_ := unset $ctx "extraLabels" -}}
+  {{- $extra := dict "metadata" (dict "annotations" $annotations "labels" $labels) -}}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crd.yaml`
at line 12, The $extra dict currently only injects annotations ({{- $extra :=
dict "metadata" (dict "annotations" $annotations) -}}) so CRDs lose
metadata.labels (vm.labels / .Values.global.extraLabels); update $extra to
include metadata.labels as well (e.g., dict "metadata" (dict "annotations"
$annotations "labels" $labels) or merge in .Values.global.extraLabels) so the
rendered CRDs receive vm.labels/.Values.global.extraLabels like other templates;
ensure you reference the same label variable used elsewhere (vm.labels or
$labels) when modifying the $extra declaration.

automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
{{- end }}
{{- if and .Values.crds.enabled .Values.crds.cleanup.enabled }}
{{- if .Values.crds.cleanup.enabled }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== serviceaccount gating =="
sed -n '1,120p' packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml

echo
echo "== cleanup hook gating =="
fd -p 'cleanup.yaml$' packages/system/victoria-metrics-operator -x sed -n '1,220p' {}

echo
echo "== CRD cleanup defaults =="
fd -p 'values.yaml$' packages/system/victoria-metrics-operator -x rg -n -C2 'crds:|cleanup:|enabled:'

Repository: cozystack/cozystack

Length of output: 6490


🏁 Script executed:

# Check for any validation, conditional logic, or documentation about crds.enabled + crds.cleanup interaction
cd packages/system/victoria-metrics-operator

# Look for values schema or validation
fd -p 'values.schema|Chart.yaml|values-schema' . 2>/dev/null || echo "No schema file found"

# Check if there's any templating logic that links crds.enabled to cleanup
rg -n 'crds\.enabled' . --type yaml --type template

# Check comments/docs in values.yaml about the relationship
sed -n '38,80p' charts/victoria-metrics-operator/values.yaml

Repository: cozystack/cozystack

Length of output: 1717


🏁 Script executed:

# Check the full cleanup job deletion logic to understand scope
sed -n '50,80p' packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/cleanup.yaml

Repository: cozystack/cozystack

Length of output: 461


Keep the cleanup hook behind crds.enabled.

Both the cleanup ServiceAccount (line 18) and the cleanup Job lack a guard for crds.enabled. When a user disables CRD management (crds.enabled: false) but enables cleanup (crds.cleanup.enabled: true), the chart will delete CRDs it does not own during uninstall. The cleanup Job executes kubectl delete on the chart's CRD types with --all, indiscriminately removing all instances in the namespace regardless of ownership.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml`
at line 18, The cleanup ServiceAccount conditional only checks
.Values.crds.cleanup.enabled and must also require .Values.crds.enabled; update
the guard around the ServiceAccount template (the block starting with {{- if
.Values.crds.cleanup.enabled }}) to require both .Values.crds.enabled and
.Values.crds.cleanup.enabled, and apply the same combined guard to the cleanup
Job template (the Job that runs kubectl delete for CRD types) so the cleanup
artifacts are only rendered when CRD management is enabled.

Comment on lines +67 to +68
# -- Adds `--force-conflics` argument to kubectl
forceConflicts: false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Typo in comment: "conflics" → "conflicts".

🔧 Suggested fix
-    # -- Adds `--force-conflics` argument to kubectl
+    # -- Adds `--force-conflicts` argument to kubectl
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# -- Adds `--force-conflics` argument to kubectl
forceConflicts: false
# -- Adds `--force-conflicts` argument to kubectl
forceConflicts: false
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/values.yaml`
around lines 67 - 68, Typo in the YAML comment: update the comment string above
the forceConflicts key to read "--force-conflicts" (replace "conflics" with
"conflicts") so it correctly documents the kubectl flag; locate the comment that
currently reads "# -- Adds `--force-conflics` argument to kubectl" and change it
to "# -- Adds `--force-conflicts` argument to kubectl" while leaving the
forceConflicts: false key unchanged.

Comment on lines +69 to +73
busybox:
image:
repository: busybox
tag: latest
pullPolicy: IfNotPresent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Using latest tag reduces reproducibility.

The busybox:latest tag can lead to inconsistent behavior across environments or over time as the image changes. Consider pinning to a specific version.

🔧 Suggested fix
     busybox:
       image:
         repository: busybox
-        tag: latest
+        tag: "1.36"
         pullPolicy: IfNotPresent
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/values.yaml`
around lines 69 - 73, The busybox image is pinned to the mutable tag "latest"
(busybox.image.tag) which harms reproducibility; update busybox.image.tag to a
specific, immutable version (e.g., a semver like "1.36.1" or whatever your org
approves), leave busybox.image.repository as "busybox", and ensure any related
deployment/documentation or upgrade notes reflect the chosen pinned version so
CI/rollouts use a fixed artifact instead of latest.

Comment on lines +247 to +248
# -- Service traffic distribution. Details are [here](https://kubernetes.io/docs/concepts/services-networking/service/#traffic-distribution)
trafficDistribution: ""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Kubernetes service trafficDistribution feature gate version

💡 Result:

  • Kubernetes v1.30: .spec.trafficDistribution was introduced as alpha, gated by the ServiceTrafficDistribution feature gate. [1]
  • Kubernetes v1.31: the Service trafficDistribution feature graduated to beta and became enabled by default (no feature gate required just to use the field). [2]
  • Kubernetes v1.33: trafficDistribution is stable and enabled by default. [3]

Sources
[1] Kubernetes v1.30.0-beta.0 release announcement (Google Groups) [1]
[2] Kubernetes v1.31.0 release announcement (Google Groups) [2]
[3] Kubernetes Service documentation (Traffic distribution section; feature state v1.33 stable) [3]


Verify trafficDistribution support in target clusters.

The service.trafficDistribution field was introduced as alpha in Kubernetes 1.30 (feature gate required), graduated to beta in 1.31, and became stable in 1.33. Ensure target clusters support this feature, or Service creation may fail on versions below 1.30. Consider the cluster versions you support before relying on this field.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/values.yaml`
around lines 247 - 248, The values.yaml adds the service.trafficDistribution
field which can break Service creation on clusters older than Kubernetes 1.30;
update the chart to only emit the trafficDistribution field when the cluster
supports it (or keep the values.yaml default empty and document compatibility).
Concretely, modify the Service template that uses .Values.trafficDistribution
(e.g., templates/service.yaml / the Service manifest generator) to wrap the
trafficDistribution stanza in a Helm conditional that checks cluster version via
.Capabilities.KubeVersion (use semverCompare to require >= 1.30) or otherwise
only include the field when .Values.trafficDistribution is non-empty, and add a
note in values.yaml describing the Kubernetes version requirement for
trafficDistribution.

@kvaps
Andrei Kvapil (kvaps) force-pushed the feat/migrate-vlogs-to-vlcluster branch from 62d36ec to 5d2e429 Compare March 10, 2026 11:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/Chart.yaml (1)

1-32: 🛠️ Refactor suggestion | 🟠 Major

Don't patch the vendored chart metadata in place.

This Chart.yaml sits in a vendored upstream chart, so these edits will drift from upstream and are likely to be lost on the next vendor refresh. Please carry them through the chart vendoring/update flow instead of modifying the vendored file directly.

As per coding guidelines, "Do NOT directly edit upstream Helm charts in vendored charts directory; use proper chart vendoring mechanisms."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/Chart.yaml`
around lines 1 - 32, This change edits the vendored Chart.yaml for the
victoria-metrics-common chart directly; revert those in-place edits in
Chart.yaml and instead apply the metadata change through the upstream chart
vendoring/update flow (e.g., update the upstream chart repo or chart dependency,
commit a proper vendor update, or add the change into the chart source before
vendoring) so the modification persists through vendor refreshes; locate the
vendored Chart.yaml for the victoria-metrics-common chart (name:
victoria-metrics-common, apiVersion: v2, version: 0.0.46) and remove the manual
edits, then perform the proper chart vendoring/update step to include the
intended annotation changes upstream.
♻️ Duplicate comments (4)
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/cleanup.yaml (1)

39-44: ⚠️ Potential issue | 🟡 Minor

Skip empty CRD documents when building the delete list.

If crd.yaml contains an empty document, this appends an empty resource name and can turn the kubectl delete argument into an invalid CSV list.

Possible fix
           {{- $names := list }}
           {{- $crds := .Files.Get "crd.yaml" | splitList "---" }}
           {{- range $crds }}
             {{- $crd := . | fromYaml }}
-            {{- $names = append $names $crd.spec.names.singular }}
+            {{- if and $crd $crd.spec $crd.spec.names $crd.spec.names.singular }}
+            {{- $names = append $names $crd.spec.names.singular }}
+            {{- end }}
           {{- end }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/cleanup.yaml`
around lines 39 - 44, When building the delete list from the splitList of
"crd.yaml" ($crds) skip empty/invalid documents before appending: inside the
range over $crds, after creating $crd := . | fromYaml, check that $crd is not
nil and that $crd.spec.names.singular exists and is non-empty before doing
$names = append $names $crd.spec.names.singular; this prevents appending empty
strings when the document is blank and avoids producing an invalid CSV for
kubectl delete.
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crd.yaml (1)

12-12: ⚠️ Potential issue | 🟠 Major

Restore metadata.labels on rendered CRDs.

$extra now injects only annotations, so the CRDs stop receiving vm.labels / .Values.global.extraLabels. That is a regression for clusters with required-label policies.

Possible fix
   {{- $crds := $files.Get "crd.yaml" | splitList "---" }}
   {{- $annotations := mergeOverwrite ((include "vm-operator.crds.annotations" .) | fromYaml) .Values.crds.annotations -}}
-  {{- $extra := dict "metadata" (dict "annotations" $annotations) -}}
+  {{- $_ := set $ctx "extraLabels" .Values.extraLabels -}}
+  {{- $labels := include "vm.labels" $ctx | fromYaml -}}
+  {{- $_ := unset $ctx "extraLabels" -}}
+  {{- $extra := dict "metadata" (dict "annotations" $annotations "labels" $labels) -}}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crd.yaml`
at line 12, The rendered CRDs lost metadata.labels because $extra was rebuilt to
include only "annotations"; restore labels by adding a "labels" entry to the
$extra dict so CRDs receive vm.labels / .Values.global.extraLabels again (e.g.
change {{- $extra := dict "metadata" (dict "annotations" $annotations) -}} to
include "labels" referencing the existing $labels or vm.labels variable),
ensuring the dict keys are "metadata" -> (dict "annotations" $annotations
"labels" $labels).
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml (1)

17-32: ⚠️ Potential issue | 🟠 Major

Split create away from the resourceNames restriction.

Kubernetes does not apply resourceNames to top-level create requests. Keeping create in this rule prevents the pre-install hook from creating missing CRDs on a fresh install.

🐛 Proposed fix
 rules:
   - apiGroups:
       - "apiextensions.k8s.io"
     resources:
       - "customresourcedefinitions"
     verbs:
       - create
+  - apiGroups:
+      - "apiextensions.k8s.io"
+    resources:
+      - "customresourcedefinitions"
+    verbs:
       - patch
       - update
       - get
       - list
     resourceNames:
       {{- range $crds }}
         {{- $crd := fromYaml . }}
       - {{ $crd.metadata.name }}
       {{- end }}
Kubernetes RBAC resourceNames create verb customresourcedefinitions
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml`
around lines 17 - 32, The current Role rule lists the create verb alongside a
resourceNames-restricted rule for customresourcedefinitions, which prevents
cluster-level CRD creation; to fix, split the verbs into two rules: keep a rule
with apiGroups: ["apiextensions.k8s.io"] and resources:
["customresourcedefinitions"] containing only verbs that must be
resource-restricted (get, list, patch, update) and resourceNames: (the {{- range
$crds }} ... {{- end }} block), and add a separate rule for the same
apiGroups/resources that includes only the create verb (no resourceNames) so the
pre-install hook can create missing CRDs; locate this in the Role template where
rules, apiGroups, resources, verbs, and resourceNames are defined.
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml (1)

18-27: ⚠️ Potential issue | 🟠 Major

Restore the crds.enabled guard on cleanup hooks.

This cleanup ServiceAccount now renders whenever crds.cleanup.enabled is true, even when the chart is not managing CRDs. That leaves the uninstall cleanup path able to touch CRDs the release never owned. Keep the cleanup hook behind both flags, and mirror the same combined guard in the matching cleanup RBAC/job templates.

🐛 Proposed fix
-{{- if .Values.crds.cleanup.enabled }}
+{{- if and .Values.crds.enabled .Values.crds.cleanup.enabled }}
 ---
 apiVersion: v1
 kind: ServiceAccount
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml`
around lines 18 - 27, The cleanup ServiceAccount is currently gated only by
.Values.crds.cleanup.enabled and should also require .Values.crds.enabled;
update the conditional in
templates/victoria-metrics-operator/templates/serviceaccount.yaml to require
both .Values.crds.enabled and .Values.crds.cleanup.enabled (so the block
creating the ServiceAccount named {{ $fullname }}-cleanup-hook with annotations
from "vm-operator.cleanup.annotations" only renders when both flags are true),
and apply the same combined guard to the corresponding cleanup RBAC and job
templates so cleanup hooks never run when CRD management is disabled.
🧹 Nitpick comments (3)
packages/system/monitoring/templates/vlogs/vlogs.yaml (1)

13-31: Consider making replicaCount configurable via values.

The hardcoded replicaCount: 2 for all components is reasonable for production, but smaller environments or development clusters might benefit from configurable replicas.

🔧 Optional: Make replicaCount configurable

In values.yaml, add optional replica configuration:

logsStorages:
- name: generic
  retentionPeriod: "1"
  storage: 10Gi
  storageClassName: ""
  # Optional: defaults to 2 if not specified
  # replicaCount: 2

Then in the template:

   vlinsert:
-    replicaCount: 2
+    replicaCount: {{ .replicaCount | default 2 }}
     resources: {}
   vlselect:
-    replicaCount: 2
+    replicaCount: {{ .replicaCount | default 2 }}
     resources: {}
   vlstorage:
     retentionPeriod: {{ .retentionPeriod | quote }}
-    replicaCount: 2
+    replicaCount: {{ .replicaCount | default 2 }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/system/monitoring/templates/vlogs/vlogs.yaml` around lines 13 - 31,
The templates currently hardcode replicaCount: 2 for vlinsert, vlselect and
vlstorage; make this driven by the values file (e.g., per-storage entry
replicaCount) and fall back to 2 if unset. Update the vlinsert, vlselect and
vlstorage blocks to use the Helm value (such as
.Values.<yourValuesKey>.replicaCount or the per-storage entry’s .replicaCount)
with the Helm default function to supply 2 when not provided, and add the
optional replicaCount key to values.yaml so users can override replicas in
development or small clusters.
packages/system/monitoring/templates/vpa.yaml (1)

107-118: Expose the new logsStorages VPA knobs in the values surface.

This template now accepts .vlinsert/.vlselect/.vlstorage.{minAllowed,maxAllowed}, but packages/system/monitoring/values.yaml:43-47 only shows the basic logsStorages fields. The fallback logic is fine, but these overrides are effectively undocumented right now.

Also applies to: 136-147, 165-176

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/system/monitoring/templates/vpa.yaml` around lines 107 - 118, The
values surface is missing documented knobs for the VPA overrides used in the
template (.vlinsert, .vlselect, .vlstorage and their minAllowed/maxAllowed
entries), so update packages/system/monitoring/values.yaml to expose and
document these fields under logsStorages for each target (vlinsert, vlselect,
vlstorage) including nested minAllowed and maxAllowed blocks with the same
default CPU/memory values shown in the template (e.g., cpu: 25m / memory: 64Mi
for minAllowed and cpu: 2000m / memory: 4Gi for maxAllowed) so users can
override .vlinsert/.vlselect/.vlstorage.{minAllowed,maxAllowed}; apply the same
additions for the other occurrences mentioned (around the other template
regions).
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md (1)

3-3: Use descriptive link text.

[here] is weak in rendered docs and for screen readers. Please link the chart/docs name instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md`
at line 3, Replace the non-descriptive link text "[here]" in the README.md with
the chart/docs name so the link reads e.g. "victoria-metrics-common" (or
"Victoria Metrics Common chart documentation") and update the markdown link
target to the same URL
(https://docs.victoriametrics.com/helm/victoria-metrics-common/); locate the
line containing "Chart documentation is available [here](...)" in the README.md
and change the link label to the descriptive chart/docs name to improve
accessibility and clarity.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/_helpers.yaml`:
- Around line 1-13: Remove the custom helpers added to the vendored chart and
implement them via the umbrella chart or by re-vendoring upstream: delete the
definitions for "crds.upgrade.name" and "crds.upgrade.serviceAccountName" from
the vendored templates, then add equivalent helper definitions in the umbrella
chart's templates (or include them via a patch during chart vendoring) so the
change is maintained outside the vendored tree; finally update any callers to
reference the umbrella-provided helpers to ensure behavior remains identical.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml`:
- Around line 10-12: The ServiceAccount template always uses include
"crds.upgrade.name" but must honor a user-specified upgrade.serviceAccount.name;
change metadata.name in the ServiceAccount template to prefer
.Values.upgrade.serviceAccount.name and fall back to include "crds.upgrade.name"
(e.g. use Helm default with the include as the fallback) so the ServiceAccount
resource name matches the value resolved by crds.upgrade.serviceAccountName and
the ClusterRoleBinding/upgrade flow.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/README.md`:
- Line 3: Replace the non-descriptive link text "here" in the README.md with a
descriptive phrase such as "VictoriaMetrics Operator documentation" (or
"official VictoriaMetrics Operator documentation") so the link reads "Chart
documentation is available on the VictoriaMetrics Operator documentation" (or
similar); update the single line containing the Markdown link to use the new
descriptive text and keep the same URL.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/server.yaml`:
- Around line 71-79: The template currently only emits VM_CONFIG_RELOADER_IMAGE
when .Values.configReloader.image is set, which breaks compatibility with the
old useCustomConfigReloader path; update the conditional that renders the
VM_CONFIG_RELOADER_IMAGE env var to also handle the legacy flag
(useCustomConfigReloader) by falling back to the old value if present: check
(.Values.operator.useCustomConfigReloader) and, if true, use the legacy image
value (e.g., .Values.operator.configReloaderImage or the prior key used by the
parent chart) as the env value, otherwise continue to use include "vm.image"
$ctx when .Values.configReloader.image exists, so VM_CONFIG_RELOADER_IMAGE is
emitted for upgrades preserving previous behavior.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/service.yaml`:
- Around line 17-19: The template unconditionally renders
Service.spec.trafficDistribution from $service.trafficDistribution which will
break clusters older than Kubernetes v1.30; wrap that block with a
Kubernetes-version guard using Helm's semverCompare (e.g. if semverCompare
">=1.30.0" .Capabilities.KubeVersion.GitVersion) so trafficDistribution is only
emitted on >= v1.30, or alternatively update the chart's kubeVersion in
Chart.yaml to >= 1.30.0; locate the current block referencing
$service.trafficDistribution in the service template and apply the version check
(or bump kubeVersion) accordingly.

---

Outside diff comments:
In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/Chart.yaml`:
- Around line 1-32: This change edits the vendored Chart.yaml for the
victoria-metrics-common chart directly; revert those in-place edits in
Chart.yaml and instead apply the metadata change through the upstream chart
vendoring/update flow (e.g., update the upstream chart repo or chart dependency,
commit a proper vendor update, or add the change into the chart source before
vendoring) so the modification persists through vendor refreshes; locate the
vendored Chart.yaml for the victoria-metrics-common chart (name:
victoria-metrics-common, apiVersion: v2, version: 0.0.46) and remove the manual
edits, then perform the proper chart vendoring/update step to include the
intended annotation changes upstream.

---

Duplicate comments:
In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml`:
- Around line 17-32: The current Role rule lists the create verb alongside a
resourceNames-restricted rule for customresourcedefinitions, which prevents
cluster-level CRD creation; to fix, split the verbs into two rules: keep a rule
with apiGroups: ["apiextensions.k8s.io"] and resources:
["customresourcedefinitions"] containing only verbs that must be
resource-restricted (get, list, patch, update) and resourceNames: (the {{- range
$crds }} ... {{- end }} block), and add a separate rule for the same
apiGroups/resources that includes only the create verb (no resourceNames) so the
pre-install hook can create missing CRDs; locate this in the Role template where
rules, apiGroups, resources, verbs, and resourceNames are defined.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/cleanup.yaml`:
- Around line 39-44: When building the delete list from the splitList of
"crd.yaml" ($crds) skip empty/invalid documents before appending: inside the
range over $crds, after creating $crd := . | fromYaml, check that $crd is not
nil and that $crd.spec.names.singular exists and is non-empty before doing
$names = append $names $crd.spec.names.singular; this prevents appending empty
strings when the document is blank and avoids producing an invalid CSV for
kubectl delete.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crd.yaml`:
- Line 12: The rendered CRDs lost metadata.labels because $extra was rebuilt to
include only "annotations"; restore labels by adding a "labels" entry to the
$extra dict so CRDs receive vm.labels / .Values.global.extraLabels again (e.g.
change {{- $extra := dict "metadata" (dict "annotations" $annotations) -}} to
include "labels" referencing the existing $labels or vm.labels variable),
ensuring the dict keys are "metadata" -> (dict "annotations" $annotations
"labels" $labels).

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml`:
- Around line 18-27: The cleanup ServiceAccount is currently gated only by
.Values.crds.cleanup.enabled and should also require .Values.crds.enabled;
update the conditional in
templates/victoria-metrics-operator/templates/serviceaccount.yaml to require
both .Values.crds.enabled and .Values.crds.cleanup.enabled (so the block
creating the ServiceAccount named {{ $fullname }}-cleanup-hook with annotations
from "vm-operator.cleanup.annotations" only renders when both flags are true),
and apply the same combined guard to the corresponding cleanup RBAC and job
templates so cleanup hooks never run when CRD management is disabled.

---

Nitpick comments:
In `@packages/system/monitoring/templates/vlogs/vlogs.yaml`:
- Around line 13-31: The templates currently hardcode replicaCount: 2 for
vlinsert, vlselect and vlstorage; make this driven by the values file (e.g.,
per-storage entry replicaCount) and fall back to 2 if unset. Update the
vlinsert, vlselect and vlstorage blocks to use the Helm value (such as
.Values.<yourValuesKey>.replicaCount or the per-storage entry’s .replicaCount)
with the Helm default function to supply 2 when not provided, and add the
optional replicaCount key to values.yaml so users can override replicas in
development or small clusters.

In `@packages/system/monitoring/templates/vpa.yaml`:
- Around line 107-118: The values surface is missing documented knobs for the
VPA overrides used in the template (.vlinsert, .vlselect, .vlstorage and their
minAllowed/maxAllowed entries), so update packages/system/monitoring/values.yaml
to expose and document these fields under logsStorages for each target
(vlinsert, vlselect, vlstorage) including nested minAllowed and maxAllowed
blocks with the same default CPU/memory values shown in the template (e.g., cpu:
25m / memory: 64Mi for minAllowed and cpu: 2000m / memory: 4Gi for maxAllowed)
so users can override .vlinsert/.vlselect/.vlstorage.{minAllowed,maxAllowed};
apply the same additions for the other occurrences mentioned (around the other
template regions).

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md`:
- Line 3: Replace the non-descriptive link text "[here]" in the README.md with
the chart/docs name so the link reads e.g. "victoria-metrics-common" (or
"Victoria Metrics Common chart documentation") and update the markdown link
target to the same URL
(https://docs.victoriametrics.com/helm/victoria-metrics-common/); locate the
line containing "Chart documentation is available [here](...)" in the README.md
and change the link label to the descriptive chart/docs name to improve
accessibility and clarity.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 053e5e24-ae87-4671-bc3b-aa86aca16178

📥 Commits

Reviewing files that changed from the base of the PR and between 62d36ec and 5d2e429.

⛔ Files ignored due to path filters (2)
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.lock is excluded by !**/*.lock
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/files/crd.yaml.bz2 is excluded by !**/*.bz2
📒 Files selected for processing (41)
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/core/platform/images/migrations/migrations/35
  • packages/core/platform/values.yaml
  • packages/extra/monitoring/templates/dashboard-resourcemap.yaml
  • packages/extra/monitoring/templates/workloadmonitors.yaml
  • packages/system/cozystack-basics/templates/monitoring-external-services.yaml
  • packages/system/monitoring-agents/values.yaml
  • packages/system/monitoring/templates/vlogs/grafana-datasource.yaml
  • packages/system/monitoring/templates/vlogs/vlogs.yaml
  • packages/system/monitoring/templates/vpa.yaml
  • packages/system/monitoring/values.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/.helmignore
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/README.md
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/README.md
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/crds/crd.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/_helpers.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/cm.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/job.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/Chart.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/RELEASE_NOTES
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_enterprise.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_helpers.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_image.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/crd.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/_helpers.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/cleanup.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crb.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crd.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/role.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/server.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/service.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/webhook.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/values.yaml
🚧 Files skipped from review as they are similar to previous changes (14)
  • packages/core/platform/values.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/README.md
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/.helmignore
  • packages/extra/monitoring/templates/workloadmonitors.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.yaml
  • packages/system/monitoring-agents/values.yaml
  • packages/system/cozystack-basics/templates/monitoring-external-services.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore
  • packages/extra/monitoring/templates/dashboard-resourcemap.yaml
  • packages/core/platform/images/migrations/migrations/35
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crb.yaml

Comment on lines +1 to +13
{{- define "crds.upgrade.name" -}}
{{- print (include "vm.plain.fullname" .) "-upgrade-crds" }}
{{- end -}}

{{- define "crds.upgrade.serviceAccountName" -}}
{{- $Values := (.helm).Values | default .Values }}
{{- $upgrade := $Values.upgrade }}
{{- if $upgrade.serviceAccount.create -}}
{{ default (include "crds.upgrade.name" .) $upgrade.serviceAccount.name }}
{{- else -}}
{{ default "default" $upgrade.serviceAccount.name }}
{{- end -}}
{{- end -}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Avoid adding custom logic directly under the vendored chart tree.

These helpers are being introduced inside packages/system/.../charts/..., which makes the next upstream re-vendor harder to reconcile. Please carry this via the umbrella chart/patching mechanism or re-vendor the upstream chart with the change instead of maintaining local template deltas here.

As per coding guidelines, "Do NOT directly edit upstream Helm charts in vendored charts directory; use proper chart vendoring mechanisms".

🧰 Tools
🪛 YAMLlint (1.38.0)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/_helpers.yaml`
around lines 1 - 13, Remove the custom helpers added to the vendored chart and
implement them via the umbrella chart or by re-vendoring upstream: delete the
definitions for "crds.upgrade.name" and "crds.upgrade.serviceAccountName" from
the vendored templates, then add equivalent helper definitions in the umbrella
chart's templates (or include them via a patch during chart vendoring) so the
change is maintained outside the vendored tree; finally update any callers to
reference the umbrella-provided helpers to ensure behavior remains identical.

Comment on lines +10 to +12
metadata:
name: {{ include "crds.upgrade.name" . }}
namespace: {{ $ns }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Honor upgrade.serviceAccount.name when creating the ServiceAccount.

This resource always uses crds.upgrade.name, but the ClusterRoleBinding and the rest of the upgrade flow resolve the ServiceAccount through crds.upgrade.serviceAccountName. If a user sets upgrade.serviceAccount.name, the chart creates one ServiceAccount and binds/runs another.

🐛 Proposed fix
-  name: {{ include "crds.upgrade.name" . }}
+  name: {{ include "crds.upgrade.serviceAccountName" . }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
metadata:
name: {{ include "crds.upgrade.name" . }}
namespace: {{ $ns }}
metadata:
name: {{ include "crds.upgrade.serviceAccountName" . }}
namespace: {{ $ns }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml`
around lines 10 - 12, The ServiceAccount template always uses include
"crds.upgrade.name" but must honor a user-specified upgrade.serviceAccount.name;
change metadata.name in the ServiceAccount template to prefer
.Values.upgrade.serviceAccount.name and fall back to include "crds.upgrade.name"
(e.g. use Helm default with the include as the fallback) so the ServiceAccount
resource name matches the value resolved by crds.upgrade.serviceAccountName and
the ClusterRoleBinding/upgrade flow.

@@ -0,0 +1,3 @@
# VictoriaMetrics Operator Helm chart

Chart documentation is available [here](https://docs.victoriametrics.com/helm/victoria-metrics-operator/)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if this README exists in the upstream victoria-metrics-operator chart
# and verify vendoring approach

# Check git history to see if this file was added manually or vendored
git log --oneline --follow -- packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/README.md | head -20

# Look for any vendoring documentation or scripts
fd -t f 'vendor|update.*chart' packages/system/victoria-metrics-operator/

# Check if there's a source reference in Chart.yaml
cat packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.yaml | grep -A5 -i 'source\|home\|upstream'

Repository: cozystack/cozystack

Length of output: 721


🌐 Web query:

VictoriaMetrics Operator Helm chart README github.com/VictoriaMetrics/helm-charts

💡 Result:

The charts/victoria-metrics-operator/README.md in github.com/VictoriaMetrics/helm-charts contains only:

  • Title: “VictoriaMetrics Operator Helm chart”
  • Pointer to docs: “Chart documentation is available here” (VictoriaMetrics docs site). [1]

The linked chart documentation page is hosted on docs.victoriametrics.com under the Helm charts section. [2]

Sources: [1], [2]


🏁 Script executed:

# Check the full git history with more context
git log --all --oneline -- packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/README.md

# Check if there are other chart files and their dates
git log --oneline --follow -- packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/ | head -5

# Get the actual Chart.yaml to understand the chart version
cat packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.yaml | head -20

Repository: cozystack/cozystack

Length of output: 1224


Use descriptive link text instead of "here".

The link text "here" is non-descriptive and impacts accessibility and readability. Consider using descriptive text like "VictoriaMetrics Operator documentation" or "the official documentation".

This README is vendored from the upstream VictoriaMetrics Operator Helm chart (confirmed in Chart.yaml sources), and this same non-descriptive link text issue exists in the upstream chart as well. Updating it here is appropriate for local clarity, though be aware it may be overwritten on the next chart vendor update.

Proposed fix for link text
-Chart documentation is available [here](https://docs.victoriametrics.com/helm/victoria-metrics-operator/)
+Chart documentation is available in the [VictoriaMetrics Operator documentation](https://docs.victoriametrics.com/helm/victoria-metrics-operator/)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Chart documentation is available [here](https://docs.victoriametrics.com/helm/victoria-metrics-operator/)
Chart documentation is available in the [VictoriaMetrics Operator documentation](https://docs.victoriametrics.com/helm/victoria-metrics-operator/)
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 3-3: Link text should be descriptive

(MD059, descriptive-link-text)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/README.md`
at line 3, Replace the non-descriptive link text "here" in the README.md with a
descriptive phrase such as "VictoriaMetrics Operator documentation" (or
"official VictoriaMetrics Operator documentation") so the link reads "Chart
documentation is available on the VictoriaMetrics Operator documentation" (or
similar); update the single line containing the Markdown link to use the new
descriptive text and keep the same URL.

Comment on lines +71 to +79
{{- with (((.Values).global).image).registry }}
- name: VM_CONTAINERREGISTRY
value: {{ quote . }}
{{- end -}}
{{- if not (empty (.Values.configReloader).image) }}
- name: VM_CONFIG_RELOADER_IMAGE
{{- $_ := set $ctx "appKey" (list "configReloader") }}
value: {{ include "vm.image" $ctx }}
{{- $_ := unset $ctx "appKey" }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep the existing useCustomConfigReloader path compatible during the upgrade.

The parent chart still sets victoria-metrics-operator.operator.useCustomConfigReloader: true, but this block only emits VM_CONFIG_RELOADER_IMAGE when the new configReloader.image map is populated. With current repo defaults, that turns an existing value into dead config and silently changes operator behavior on upgrade. Please either translate the old setting here or migrate the parent values in the same PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/server.yaml`
around lines 71 - 79, The template currently only emits VM_CONFIG_RELOADER_IMAGE
when .Values.configReloader.image is set, which breaks compatibility with the
old useCustomConfigReloader path; update the conditional that renders the
VM_CONFIG_RELOADER_IMAGE env var to also handle the legacy flag
(useCustomConfigReloader) by falling back to the old value if present: check
(.Values.operator.useCustomConfigReloader) and, if true, use the legacy image
value (e.g., .Values.operator.configReloaderImage or the prior key used by the
parent chart) as the env value, otherwise continue to use include "vm.image"
$ctx when .Values.configReloader.image exists, so VM_CONFIG_RELOADER_IMAGE is
emitted for upgrades preserving previous behavior.

Comment on lines +17 to +19
{{- with $service.trafficDistribution }}
trafficDistribution: {{ . }}
{{- end }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In which Kubernetes version was Service.spec.trafficDistributionintroduced, and from which Kubernetes versions is it accepted in the corev1 Service API?

💡 Result:

  • Introduced in: Kubernetes v1.30 — the Service.spec.trafficDistribution field was added as an alpha feature (“Traffic distribution for services”). [1]
  • Accepted in the core v1 Service API from: Kubernetes v1.30 and later (it’s part of the core/v1 Service schema starting in v1.30). In v1.30 it’s behind the ServiceTrafficDistribution feature gate; in v1.31 the feature moves to beta and is enabled by default, so the field is accepted without needing to enable the gate. [2][3]

Sources: [1] [2] [3]


Gate trafficDistribution by Kubernetes version support.

The Service.spec.trafficDistribution field is accepted only in Kubernetes v1.30 and later (behind the ServiceTrafficDistribution feature gate in v1.30; enabled by default in v1.31+). Rendering this field when set will cause Service creation to fail on clusters running Kubernetes v1.29 or earlier. Either add a version check before rendering or explicitly bump the minimum supported Kubernetes version to v1.30+.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/service.yaml`
around lines 17 - 19, The template unconditionally renders
Service.spec.trafficDistribution from $service.trafficDistribution which will
break clusters older than Kubernetes v1.30; wrap that block with a
Kubernetes-version guard using Helm's semverCompare (e.g. if semverCompare
">=1.30.0" .Capabilities.KubeVersion.GitVersion) so trafficDistribution is only
emitted on >= v1.30, or alternatively update the chart's kubeVersion in
Chart.yaml to >= 1.30.0; locate the current block referencing
$service.trafficDistribution in the service template and apply the version check
(or bump kubeVersion) accordingly.

@sircthulhu
Kirill Ilin (sircthulhu) force-pushed the feat/migrate-vlogs-to-vlcluster branch from 5d2e429 to 62d36ec Compare March 10, 2026 17:04
After migrating VictoriaLogs from VLogs to VLCluster, the e2e test
still waited for the old vlogs/generic resource which no longer exists.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (4)
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore (1)

24-26: ⚠️ Potential issue | 🟠 Major

Avoid patching .helmignore inside the vendored chart.

This change directly edits a file within the vendored upstream chart. As previously noted, modifications to vendored charts should not be made directly—they will drift from upstream and be overwritten during the next chart sync. Apply this change through the proper chart vendoring/update flow or a supported overlay mechanism instead. Based on learnings: Do NOT directly edit upstream Helm charts in vendored charts directory; use proper chart vendoring mechanisms.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore`
around lines 24 - 26, You edited a vendored chart's .helmignore by adding
CHANGELOG.md/_changelog.md/_index.md; revert that direct edit in the vendored
chart (.helmignore) and instead apply the desired ignore changes via the chart
vendoring/update flow or an overlay: restore the vendored chart to upstream
state, then either update the vendored chart properly (run the repo's chart
vendoring command or helm dependency update to pull the upstream .helmignore) or
implement the change via a supported overlay mechanism (e.g., use your
repository's chart overlay/patch system or CI vendoring scripts to inject
.helmignore changes during vendor generation) so upstream updates won't be
overwritten.
packages/core/platform/values.yaml (1)

8-9: ⚠️ Potential issue | 🔴 Critical

Bump the migrations image together with targetVersion.

Line 9 advances the platform to migration 36, but Line 8 still pins an immutable platform-migrations:v1.1.0@sha256:... image. That image cannot contain packages/core/platform/images/migrations/migrations/35, so the 35→36 upgrade path is still broken until both values move together.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/platform/values.yaml` around lines 8 - 9, The targetVersion was
bumped to 36 but the immutable image field still points to
platform-migrations:v1.1.0@sha256:..., so the migrations image must be updated
in tandem; update the image value (the "image" entry) to a new tag/sha that
contains the 35→36 migration (the release that corresponds to targetVersion 36)
so the migrations image and targetVersion remain in sync.
packages/core/platform/images/migrations/migrations/35 (1)

1-1: ⚠️ Potential issue | 🔴 Critical

Make this script POSIX-safe or switch it to Bash.

set -euo pipefail is not portable under the #!/bin/sh shebang on Line 1, and Lines 20-21 rely on that pipeline behavior to surface kubectl create failures. This is the same portability bug raised earlier and it is still present.

POSIX-safe fix
 #!/bin/sh
@@
-set -euo pipefail
+set -eu
@@
-kubectl create configmap --namespace cozy-system cozystack-version \
-  --from-literal=version=36 --dry-run=client --output yaml | kubectl apply --filename -
+tmpfile="$(mktemp)"
+trap 'rm -f "$tmpfile"' EXIT
+
+kubectl create configmap --namespace cozy-system cozystack-version \
+  --from-literal=version=36 --dry-run=client --output yaml >"$tmpfile"
+kubectl apply --filename "$tmpfile"
#!/bin/bash
set -eu

echo "== Migration 35 shebang / shell options / pipeline =="
sed -n '1,25p' packages/core/platform/images/migrations/migrations/35

echo
echo "== Compare with nearby bash-based migrations, if present =="
for n in 28 29 30; do
  f="packages/core/platform/images/migrations/migrations/$n"
  if [ -f "$f" ]; then
    echo "--- $f ---"
    sed -n '1,8p' "$f"
  fi
done

echo
echo "== Migrations image build files =="
fd 'Dockerfile|Containerfile' packages/core/platform/images/migrations -x sh -c '
  echo "--- $1 ---"
  sed -n "1,80p" "$1"
' sh {}

Also applies to: 8-8, 20-21

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/platform/images/migrations/migrations/35` at line 1, The script
uses a non-portable set -euo pipefail under #!/bin/sh and its kubectl pipeline
on Lines 20-21 relies on pipefail; either change the shebang to a Bash
interpreter (e.g. #!/usr/bin/env bash) and keep set -euo pipefail, or make the
script POSIX-safe by replacing set -euo pipefail with set -eu and rewriting the
piped kubectl create sequence (the commands on Lines 20-21) to explicitly check
and propagate the kubectl exit status (e.g., capture/check exit codes or use a
conditional/brace block) so failures are surfaced without relying on pipefail.
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml (1)

17-32: ⚠️ Potential issue | 🟠 Major

Split create out of the resourceNames-scoped CRD rule.

resourceNames does not authorize top-level CRD creates, so this hook role can't create missing CRDs when upgrade mode is enabled. Keep create in its own rule without resourceNames, and keep the named restriction on the non-create verbs.

Suggested fix
 rules:
+  - apiGroups:
+      - "apiextensions.k8s.io"
+    resources:
+      - "customresourcedefinitions"
+    verbs:
+      - create
   - apiGroups:
       - "apiextensions.k8s.io"
     resources:
       - "customresourcedefinitions"
     verbs:
-      - create
       - patch
       - update
       - get
       - list
     resourceNames:
       {{- range $crds }}
         {{- $crd := fromYaml . }}
       - {{ $crd.metadata.name }}
       {{- end }}
Can Kubernetes RBAC `resourceNames` restrict top-level `create` requests for `customresourcedefinitions`, or must `create` be granted in a separate rule without `resourceNames`?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml`
around lines 17 - 32, The RBAC rule currently ties the "create" verb to a rule
that includes resourceNames, which does not allow creating new top-level
customresourcedefinitions; split the rules so that one rule for apiGroups
"apiextensions.k8s.io" and resources "customresourcedefinitions" lists only the
verb "create" (no resourceNames), and keep a separate rule with the same
apiGroups/resources that includes the non-create verbs (patch, update, get,
list) plus the resourceNames block populated from the {{- range $crds }} ... {{-
end }} loop; update the rules array to include both entries so create can
operate cluster-wide while other verbs remain name-scoped.
🧹 Nitpick comments (2)
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/server.yaml (1)

4-7: Unused $env variable.

The $env dict is built by iterating over .Values.env but is never used in the template. The env vars are rendered directly via range .Values.env on lines 57-60. Consider removing this unused code.

Suggested fix
 {{- $ctx := dict "helm" . "noEnterprise" true }}
 {{- $fullname := include "vm.plain.fullname" $ctx }}
 {{- $ns := include "vm.namespace" $ctx }}
-{{- $env := dict -}}
-{{- range .Values.env | default list -}}
-  {{- $_ := set $env .name .value -}}
-{{- end -}}
 ---
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/server.yaml`
around lines 4 - 7, The template builds an unused dict named $env by iterating
.Values.env (the block that defines {{- $env := dict -}} and the subsequent
range/set), which is redundant because the template later renders environment
variables directly from .Values.env; remove the entire $env creation block (the
lines that create and populate $env) or alternatively change the env rendering
to iterate over $env instead—preferably delete the unused $env block to
eliminate dead code.
packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml (1)

9-11: Consider pinning the busybox image tag for reproducibility.

Using tag: latest for the busybox image can lead to unpredictable behavior across deployments and makes builds non-reproducible. Consider pinning to a specific version.

Suggested fix
   busybox:
     image:
       repository: busybox
-      tag: latest
+      tag: "1.36"
       pullPolicy: IfNotPresent
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml`
around lines 9 - 11, The values.yaml currently sets repository: busybox and tag:
latest which makes image pulls non-reproducible; update the tag field to a
specific pinned BusyBox version (e.g., replace tag: latest with a concrete
semver like tag: "1.xx.x") and keep pullPolicy: IfNotPresent (or change to
IfNotPresent only if you want cached behavior), ensuring the repository and tag
fields in the CRD values are updated together so deployments use a fixed BusyBox
image version.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/system/cozystack-basics/templates/monitoring-external-services.yaml`:
- Around line 5-9: Keep the old service name as a temporary alias: add (or keep)
a Service resource named vlogs-generic that points to the new vlinsert-generic
(e.g. make vlogs-generic an ExternalName with externalName:
vlinsert-generic.tenant-root.svc.cluster.local) so existing tenants/components
continue to resolve during rollout; leave both services in place until all
agents/datasources have migrated, then remove vlogs-generic in a follow-up
cleanup.

In `@packages/system/monitoring/values.yaml`:
- Line 47: The values.yaml change set storageClassName to an empty string which
causes templates/vlogs/vlogs.yaml to omit storageClassName and lets the
vlstorage PVC fall back to the cluster default; revert this to the explicit
class used previously by setting storageClassName: "replicated" so the vlogs
template renders the class and the vlstorage PersistentVolumeClaim retains the
intended storage class (reference storageClassName value and vlogs.yaml
rendering of vlstorage PVC).

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/cm.yaml`:
- Line 7: The ConfigMap is using the wrong template helper: replace the
crds.upgrade.serviceAccountName helper in the name field of the cm.yaml template
with the ConfigMap-specific helper used elsewhere for resource names (for
example crds.upgrade.name or crds.upgrade.fullname) so the ConfigMap gets a
consistent, intent-revealing name rather than the ServiceAccount helper which
may return "default" when serviceAccount.create is false.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/job.yaml`:
- Around line 6-7: The failure message refers to the wrong values path; update
the string in the fail call inside the template (the branch using kindIs and
(($app.kubectl).image).tag) so it points to crds.upgrade.kubectl.image.tag
instead of crd.upgrade.kubectl.image.tag; modify the fail message text emitted
by the template (the `fail "`...`" -}}` invocation) to mention the correct
values key `crds.upgrade.kubectl.image.tag`.
- Around line 1-126: This CRD-upgrade Helm hook (the Job resource using template
"crds.upgrade.name", container "kubectl", initContainer "busybox" and values
under .Values.upgrade) was added directly into a vendored upstream chart; remove
this hook and instead implement the CRD upgrade logic in the umbrella chart (or
via proper chart vendoring) by: delete or revert the Job template from the
vendored chart, add an equivalent Job or pre-upgrade hook in the umbrella
chart’s templates referencing the same template names/values (crds.upgrade.name,
crds.upgrade.serviceAccountName, .Values.upgrade.*) and ensure values are
surfaced/overridden from the umbrella chart or through chart dependencies so
future vendoring won’t overwrite your customization.

---

Duplicate comments:
In `@packages/core/platform/images/migrations/migrations/35`:
- Line 1: The script uses a non-portable set -euo pipefail under #!/bin/sh and
its kubectl pipeline on Lines 20-21 relies on pipefail; either change the
shebang to a Bash interpreter (e.g. #!/usr/bin/env bash) and keep set -euo
pipefail, or make the script POSIX-safe by replacing set -euo pipefail with set
-eu and rewriting the piped kubectl create sequence (the commands on Lines
20-21) to explicitly check and propagate the kubectl exit status (e.g.,
capture/check exit codes or use a conditional/brace block) so failures are
surfaced without relying on pipefail.

In `@packages/core/platform/values.yaml`:
- Around line 8-9: The targetVersion was bumped to 36 but the immutable image
field still points to platform-migrations:v1.1.0@sha256:..., so the migrations
image must be updated in tandem; update the image value (the "image" entry) to a
new tag/sha that contains the 35→36 migration (the release that corresponds to
targetVersion 36) so the migrations image and targetVersion remain in sync.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml`:
- Around line 17-32: The RBAC rule currently ties the "create" verb to a rule
that includes resourceNames, which does not allow creating new top-level
customresourcedefinitions; split the rules so that one rule for apiGroups
"apiextensions.k8s.io" and resources "customresourcedefinitions" lists only the
verb "create" (no resourceNames), and keep a separate rule with the same
apiGroups/resources that includes the non-create verbs (patch, update, get,
list) plus the resourceNames block populated from the {{- range $crds }} ... {{-
end }} loop; update the rules array to include both entries so create can
operate cluster-wide while other verbs remain name-scoped.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore`:
- Around line 24-26: You edited a vendored chart's .helmignore by adding
CHANGELOG.md/_changelog.md/_index.md; revert that direct edit in the vendored
chart (.helmignore) and instead apply the desired ignore changes via the chart
vendoring/update flow or an overlay: restore the vendored chart to upstream
state, then either update the vendored chart properly (run the repo's chart
vendoring command or helm dependency update to pull the upstream .helmignore) or
implement the change via a supported overlay mechanism (e.g., use your
repository's chart overlay/patch system or CI vendoring scripts to inject
.helmignore changes during vendor generation) so upstream updates won't be
overwritten.

---

Nitpick comments:
In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml`:
- Around line 9-11: The values.yaml currently sets repository: busybox and tag:
latest which makes image pulls non-reproducible; update the tag field to a
specific pinned BusyBox version (e.g., replace tag: latest with a concrete
semver like tag: "1.xx.x") and keep pullPolicy: IfNotPresent (or change to
IfNotPresent only if you want cached behavior), ensuring the repository and tag
fields in the CRD values are updated together so deployments use a fixed BusyBox
image version.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/server.yaml`:
- Around line 4-7: The template builds an unused dict named $env by iterating
.Values.env (the block that defines {{- $env := dict -}} and the subsequent
range/set), which is redundant because the template later renders environment
variables directly from .Values.env; remove the entire $env creation block (the
lines that create and populate $env) or alternatively change the env rendering
to iterate over $env instead—preferably delete the unused $env block to
eliminate dead code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0c397d02-6170-4473-a9ed-8f58dbd5bd71

📥 Commits

Reviewing files that changed from the base of the PR and between 5d2e429 and b772475.

⛔ Files ignored due to path filters (2)
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.lock is excluded by !**/*.lock
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/files/crd.yaml.bz2 is excluded by !**/*.bz2
📒 Files selected for processing (42)
  • hack/e2e-install-cozystack.bats
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/core/platform/images/migrations/migrations/35
  • packages/core/platform/values.yaml
  • packages/extra/monitoring/templates/dashboard-resourcemap.yaml
  • packages/extra/monitoring/templates/workloadmonitors.yaml
  • packages/system/cozystack-basics/templates/monitoring-external-services.yaml
  • packages/system/monitoring-agents/values.yaml
  • packages/system/monitoring/templates/vlogs/grafana-datasource.yaml
  • packages/system/monitoring/templates/vlogs/vlogs.yaml
  • packages/system/monitoring/templates/vpa.yaml
  • packages/system/monitoring/values.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/.helmignore
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/README.md
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/README.md
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/crds/crd.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/_helpers.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/cm.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/job.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/role.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/serviceaccount.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/values.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/.helmignore
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/Chart.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/README.md
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/RELEASE_NOTES
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_enterprise.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_helpers.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/templates/_image.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/crd.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/_helpers.tpl
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/cleanup.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crb.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crd.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/role.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/server.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/service.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/webhook.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/values.yaml
✅ Files skipped from review due to trivial changes (1)
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/README.md
🚧 Files skipped from review as they are similar to previous changes (11)
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/service.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/RELEASE_NOTES
  • packages/system/monitoring/templates/vlogs/grafana-datasource.yaml
  • packages/system/monitoring-agents/values.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/RELEASE_NOTES
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/crb.yaml
  • packages/extra/monitoring/templates/dashboard-resourcemap.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/templates/serviceaccount.yaml
  • packages/system/monitoring/templates/vpa.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/victoria-metrics-common/Chart.yaml
  • packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/Chart.yaml

Comment on lines +5 to +9
name: vlinsert-generic
namespace: cozy-monitoring
spec:
type: ExternalName
externalName: vlogs-generic.tenant-root.svc.cluster.local
externalName: vlinsert-generic.tenant-root.svc.cluster.local

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep vlogs-generic as a temporary compatibility alias.

This rename deletes the old service name during the same migration that changes agents and datasources. Any tenant/component that has not rolled forward yet will lose its log endpoint. Safer rollout is to add vlinsert-generic and leave vlogs-generic pointing to it until cleanup is complete.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/system/cozystack-basics/templates/monitoring-external-services.yaml`
around lines 5 - 9, Keep the old service name as a temporary alias: add (or
keep) a Service resource named vlogs-generic that points to the new
vlinsert-generic (e.g. make vlogs-generic an ExternalName with externalName:
vlinsert-generic.tenant-root.svc.cluster.local) so existing tenants/components
continue to resolve during rollout; leave both services in place until all
agents/datasources have migrated, then remove vlogs-generic in a follow-up
cleanup.

retentionPeriod: "1"
storage: 10Gi
storageClassName: replicated
storageClassName: ""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Dropping the explicit log storage class changes PVC behavior.

Because packages/system/monitoring/templates/vlogs/vlogs.yaml only renders storageClassName when this value is set, "" makes the new vlstorage PVCs fall back to the cluster default class. That is a behavior change from the previous explicit replicated class and can either reduce durability or leave claims Pending on clusters without a default. Keep replicated here unless the migration is intentionally changing the storage contract.

Suggested fix
-  storageClassName: ""
+  storageClassName: replicated
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
storageClassName: ""
storageClassName: replicated
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/system/monitoring/values.yaml` at line 47, The values.yaml change
set storageClassName to an empty string which causes templates/vlogs/vlogs.yaml
to omit storageClassName and lets the vlstorage PVC fall back to the cluster
default; revert this to the explicit class used previously by setting
storageClassName: "replicated" so the vlogs template renders the class and the
vlstorage PersistentVolumeClaim retains the intended storage class (reference
storageClassName value and vlogs.yaml rendering of vlstorage PVC).

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "crds.upgrade.serviceAccountName" $ctx }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Incorrect helper used for ConfigMap name.

The ConfigMap uses crds.upgrade.serviceAccountName for its name, but this helper is intended for ServiceAccount resolution (it can return "default" if serviceAccount.create is false). This creates a naming inconsistency and could lead to confusing resource names.

Suggested fix
 metadata:
-  name: {{ include "crds.upgrade.serviceAccountName" $ctx }}
+  name: {{ include "crds.upgrade.name" $ctx }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: {{ include "crds.upgrade.serviceAccountName" $ctx }}
name: {{ include "crds.upgrade.name" $ctx }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/cm.yaml`
at line 7, The ConfigMap is using the wrong template helper: replace the
crds.upgrade.serviceAccountName helper in the name field of the cm.yaml template
with the ConfigMap-specific helper used elsewhere for resource names (for
example crds.upgrade.name or crds.upgrade.fullname) so the ConfigMap gets a
consistent, intent-revealing name rather than the ServiceAccount helper which
may return "default" when serviceAccount.create is false.

Comment on lines +1 to +126
{{- if .Values.upgrade.enabled }}
{{- $app := .Values.upgrade }}
{{- if empty (($app.kubectl).image).tag }}
{{- $tag := regexSplit "[+-]" .Capabilities.KubeVersion.Version -1 | first -}}
{{- $_ := set $app.kubectl.image "tag" $tag }}
{{- else if not (kindIs "string" (($app.kubectl).image).tag) }}
{{- fail "`crd.upgrade.kubectl.image.tag` is not string, most probably you need to enquote provided value" -}}
{{- end }}
{{- $ctx := dict "helm" . "noEnterprise" true }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "crds.upgrade.name" $ctx }}
namespace: {{ template "vm.namespace" $ctx }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade,pre-rollback
"helm.sh/hook-weight": "5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
{{- with $app.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- $extraLabels := $app.labels | default dict }}
{{- $_ := set $ctx "extraLabels" $app.labels }}
{{- $_ := set $extraLabels "app.kubernetes.io/component" "upgrade-crds" }}
{{- $_ := set $ctx "extraLabels" $extraLabels }}
labels: {{ include "vm.labels" $ctx | nindent 4 }}
{{- $_ := unset $ctx "extraLabels" }}
spec:
backoffLimit: 3
template:
metadata:
{{- with $app.podLabels }}
labels: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $app.podAnnotations }}
annotations: {{ toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with (.Values.imagePullSecrets | default (.Values.global).imagePullSecrets) }}
imagePullSecrets: {{ toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "crds.upgrade.serviceAccountName" . }}
{{- if ($app.podSecurityContext).enabled }}
securityContext: {{ include "vm.securityContext" (dict "securityContext" $app.podSecurityContext "helm" .) | nindent 8 }}
{{- end }}
initContainers:
- name: busybox
{{- $_ := set $ctx "appKey" (list "upgrade" "busybox") }}
image: {{ include "vm.image" $ctx }}
imagePullPolicy: {{ $app.busybox.image.pullPolicy }}
workingDir: /tmp/
command:
- sh
args:
- -c
- bzcat /crds/crd.yaml.bz2 > /tmp/crd.yaml
{{- with $app.resources }}
resources: {{ toYaml . | nindent 12 }}
{{- end }}
{{- with $app.securityContext }}
securityContext: {{ toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- mountPath: /crds/
name: crds
- mountPath: /tmp/
name: tmp
{{- with $app.extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with $app.env }}
env: {{ toYaml . | nindent 12 }}
{{- end }}
containers:
- name: kubectl
{{- $_ := set $ctx "appKey" (list "upgrade" "kubectl") }}
image: {{ include "vm.image" $ctx }}
imagePullPolicy: {{ $app.kubectl.image.pullPolicy }}
command:
- kubectl
args:
- apply
- --server-side
{{- if $app.forceConflicts }}
- --force-conflicts
{{- end }}
- --filename
- /tmp/crd.yaml
{{- with $app.resources }}
resources: {{ toYaml . | nindent 12 }}
{{- end }}
{{- with $app.securityContext }}
securityContext: {{ toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- mountPath: /tmp/
name: tmp
{{- with $app.extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with $app.env }}
env: {{ toYaml . | nindent 12 }}
{{- end }}
volumes:
- name: tmp
emptyDir: {}
- name: crds
configMap:
name: {{ template "crds.upgrade.name" . }}
{{- with $app.extraVolumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
restartPolicy: OnFailure
{{- with $app.nodeSelector }}
nodeSelector: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $app.tolerations }}
tolerations: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $app.affinity }}
affinity: {{ toYaml . | nindent 8 }}
{{- end }}
{{- with $app.topologySpreadConstraints }}
topologySpreadConstraints: {{ toYaml . | nindent 8 }}
{{- end }}
{{- end }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Move this CRD-upgrade hook out of the vendored chart.

This file is being added under the upstream charts/ tree, so the next re-vendor is likely to overwrite the whole upgrade workflow. Please carry this customization in the umbrella chart or through the chart vendoring/update mechanism instead. The same concern applies to the other touched files under this vendored chart.

As per coding guidelines, "Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory" and "Do NOT directly edit upstream Helm charts in vendored charts directory; use proper chart vendoring mechanisms".

🧰 Tools
🪛 YAMLlint (1.38.0)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/job.yaml`
around lines 1 - 126, This CRD-upgrade Helm hook (the Job resource using
template "crds.upgrade.name", container "kubectl", initContainer "busybox" and
values under .Values.upgrade) was added directly into a vendored upstream chart;
remove this hook and instead implement the CRD upgrade logic in the umbrella
chart (or via proper chart vendoring) by: delete or revert the Job template from
the vendored chart, add an equivalent Job or pre-upgrade hook in the umbrella
chart’s templates referencing the same template names/values (crds.upgrade.name,
crds.upgrade.serviceAccountName, .Values.upgrade.*) and ensure values are
surfaced/overridden from the umbrella chart or through chart dependencies so
future vendoring won’t overwrite your customization.

Comment on lines +6 to +7
{{- else if not (kindIs "string" (($app.kubectl).image).tag) }}
{{- fail "`crd.upgrade.kubectl.image.tag` is not string, most probably you need to enquote provided value" -}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix the values path in the template failure message.

Line 7 points users to crd.upgrade.kubectl.image.tag, but the key added in values.yaml is crds.upgrade.kubectl.image.tag. If this guard fires, the current message sends operators to the wrong setting.

Suggested fix
-  {{- fail "`crd.upgrade.kubectl.image.tag` is not string, most probably you need to enquote provided value" -}}
+  {{- fail "`crds.upgrade.kubectl.image.tag` is not string, most probably you need to quote the provided value" -}}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- else if not (kindIs "string" (($app.kubectl).image).tag) }}
{{- fail "`crd.upgrade.kubectl.image.tag` is not string, most probably you need to enquote provided value" -}}
{{- else if not (kindIs "string" (($app.kubectl).image).tag) }}
{{- fail "`crds.upgrade.kubectl.image.tag` is not string, most probably you need to quote the provided value" -}}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/victoria-metrics-operator/charts/victoria-metrics-operator/charts/crds/templates/job.yaml`
around lines 6 - 7, The failure message refers to the wrong values path; update
the string in the fail call inside the template (the branch using kindIs and
(($app.kubectl).image).tag) so it points to crds.upgrade.kubectl.image.tag
instead of crd.upgrade.kubectl.image.tag; modify the fail message text emitted
by the template (the `fail "`...`" -}}` invocation) to mention the correct
values key `crds.upgrade.kubectl.image.tag`.

The victoria-metrics-operator v0.68.1 renamed VMCluster status field
from .status.clusterStatus to .status.updateStatus.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>

@kvaps Andrei Kvapil (kvaps) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Mar 11, 2026
@kvaps
Andrei Kvapil (kvaps) merged commit 7e2c035 into main Mar 11, 2026
8 of 9 checks passed
@kvaps
Andrei Kvapil (kvaps) deleted the feat/migrate-vlogs-to-vlcluster branch March 11, 2026 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/feature Categorizes issue or PR as related to a new feature lgtm This PR has been approved by a maintainer size/XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants