From 01ead2c2b77113d7b69c860927ef13e0d60a40f9 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan Date: Fri, 4 Sep 2026 15:50:00 -0700 Subject: [PATCH 1/3] fix(container-cache): render apiVersion on the nvcf-container-cache Service The validateServiceType include added in #1000 ended with "-}}", which trims the newline after it, so "apiVersion: v1" was glued onto the last license comment line and the Service rendered without an apiVersion. helm lint and helm template accept the result because the line is a YAML comment; ArgoCD rejects it on sync with "groupVersion shouldn't be empty". Charts 0.29.0 through 0.30.3 are affected, 0.28.1 is not. Drop the right-hand trim. Add tests/render-apiversion-test.sh, which fails when any rendered document lacks apiVersion or kind, or when a comment line ends in "apiVersion:", across the default, consistent-hash, PVC and PDB renders. The test fails on the previous template. Closes #1585 Co-Authored-By: Balaji Ganesan --- .../deploy/templates/service.yaml | 2 +- .../tests/render-apiversion-test.sh | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100755 deploy/helm/container-cache/tests/render-apiversion-test.sh diff --git a/deploy/helm/container-cache/deploy/templates/service.yaml b/deploy/helm/container-cache/deploy/templates/service.yaml index 65adacef8c..487d3e91b0 100644 --- a/deploy/helm/container-cache/deploy/templates/service.yaml +++ b/deploy/helm/container-cache/deploy/templates/service.yaml @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -{{- include "nvcf-container-cache.validateServiceType" . -}} +{{- include "nvcf-container-cache.validateServiceType" . }} apiVersion: v1 kind: Service metadata: diff --git a/deploy/helm/container-cache/tests/render-apiversion-test.sh b/deploy/helm/container-cache/tests/render-apiversion-test.sh new file mode 100755 index 0000000000..dd28c08578 --- /dev/null +++ b/deploy/helm/container-cache/tests/render-apiversion-test.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Every rendered document must carry apiVersion and kind. A trailing "-}}" on +# a template action placed right after the license header swallows the +# newline and glues "apiVersion: v1" onto the last comment line; helm lint +# accepts the result and ArgoCD then fails the sync with "groupVersion +# shouldn't be empty". Run from the chart subtree: +# bash tests/render-apiversion-test.sh +set -euo pipefail +CHART_DIR="$(cd "$(dirname "$0")/.." && pwd)/deploy" +TMP="$(mktemp -d)" +trap 'rm -rf "$TMP"' EXIT +fail() { echo "FAIL: $*" >&2; exit 1; } + +check() { # $1 label, remaining args: helm --set flags + local label="$1"; shift + helm template t "$CHART_DIR" "$@" > "$TMP/$label.yaml" 2>/dev/null || fail "$label: helm template failed" + # A comment line that ends in "apiVersion:" is the exact symptom. + if grep -nE '^#.*apiVersion:' "$TMP/$label.yaml"; then fail "$label: apiVersion glued onto a comment line"; fi + python3 - "$TMP/$label.yaml" "$label" <<'PY' +import sys, yaml +path, label = sys.argv[1], sys.argv[2] +bad = [] +n = 0 +for d in yaml.safe_load_all(open(path)): + if not d: + continue + n += 1 + if not d.get("apiVersion") or not d.get("kind"): + bad.append((d.get("kind"), (d.get("metadata") or {}).get("name"), d.get("apiVersion"))) +if bad: + print(f"FAIL: {label}: documents without apiVersion/kind: {bad}", file=sys.stderr) + sys.exit(1) +print(f"{label}: {n} documents, all carry apiVersion and kind") +PY +} + +check default +check consistent-hash --set consistentHashRouting.enabled=true --set replicaCount=3 +check pvc --set persistentVolumeClaim.storageClassName=nvcf-cc-sc +check pdb --set podDisruptionBudget.enabled=true --set podDisruptionBudget.minAvailable=1 +echo "PASS: apiVersion render tests" From 1cf563b0e511c68aa60a06e13177eeec30f2baab Mon Sep 17 00:00:00 2001 From: Balaji Ganesan Date: Fri, 4 Sep 2026 16:25:47 -0700 Subject: [PATCH 2/3] ci(helm): validate rendered objects and add container-cache to the chart checks check-helm-charts only ran helm lint and helm template, and neither rejects a document whose apiVersion was trimmed onto a comment line; the container-cache chart also had no CI values file, so it was not checked at all. That is how 0.29.0 through 0.30.3 shipped a Service without an apiVersion. Every rendered document must now carry a top-level apiVersion and kind, and a comment line ending in "apiVersion:" or "kind:" fails the chart with the offending line. container-cache joins the chart map with CI values that enable consistent-hash routing and the PodDisruptionBudget so those templates render in CI too. The checker's self-test gains two cases (glued apiVersion, document with no apiVersion), and the checker fails on the pre-fix container-cache template. Relates to #1585 Co-Authored-By: Balaji Ganesan --- tools/ci/check-helm-charts | 48 ++++++++++++++++- .../helm-validate-values/container-cache.yaml | 8 +++ tools/ci/test-check-helm-charts | 52 +++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 tools/ci/helm-validate-values/container-cache.yaml diff --git a/tools/ci/check-helm-charts b/tools/ci/check-helm-charts index 2198634ea1..4db5acf303 100755 --- a/tools/ci/check-helm-charts +++ b/tools/ci/check-helm-charts @@ -41,6 +41,7 @@ chart_map=( "api-keys-colocated api-keys-colocated/api-keys" "cassandra cassandra/helm" "cloud-functions cloud-functions/nvcf-api" + "container-cache container-cache/deploy" "ess encrypted-secret-store/ess-api" "gateway-routes-vanity gateway-routes/chart" "grpc-proxy grpc-proxy/grpc-proxy" @@ -170,6 +171,51 @@ run_step() { # run_step