From 206f47e64456f45596324576074ffc14df03ee42 Mon Sep 17 00:00:00 2001 From: Trayan Azarov Date: Fri, 20 Feb 2026 13:47:16 +0200 Subject: [PATCH] Validate and normalize core chart parameters --- README.md | 10 ++-- charts/chromadb-chart/templates/_helpers.tpl | 59 ++++++++++++++++++- .../chromadb-chart/templates/statefulset.yaml | 16 +++-- tests/test_v1_config.sh | 39 ++++++++++++ 4 files changed, 111 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index fc5c4e8..2557975 100644 --- a/README.md +++ b/README.md @@ -48,13 +48,13 @@ Example `values.yaml` file: ```yaml chromadb: - allowReset: "true" + allowReset: true ``` Alternatively you can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. ```bash -helm install chroma chroma/chromadb --set chromadb.allowReset="true" +helm install chroma chroma/chromadb --set chromadb.allowReset=true ``` ## Chart Configuration Values @@ -62,9 +62,9 @@ helm install chroma chroma/chromadb --set chromadb.allowReset="true" | Key | Type | Default | Description | |-----------------------------------------------------|---------|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `chromadb.apiVersion` | string | `1.5.0` (Chart app version) | The ChromaDB version. Supported version `0.4.3` - `1.x` | -| `chromadb.allowReset` | boolean | `false` | Allows resetting the index (delete all data) | -| `chromadb.isPersistent` | boolean | `true` | `< 1.0.0`: controls PVC plus `IS_PERSISTENT` server mode. `>= 1.0.0`: controls only PVC creation/mounting for `persistDirectory`; the Rust server always writes to disk, so data is ephemeral without a PVC. | -| `chromadb.persistDirectory` | string | `/data` | The location to store the index data. This configure both chromadb and underlying persistent volume | +| `chromadb.allowReset` | boolean | `false` | Allows resetting the index (delete all data). Accepts bool or string `true`/`false` (case-insensitive); rendered value is normalized to lowercase. | +| `chromadb.isPersistent` | boolean | `true` | `< 1.0.0`: controls PVC plus `IS_PERSISTENT` server mode. `>= 1.0.0`: controls only PVC creation/mounting for `persistDirectory`; the Rust server always writes to disk, so data is ephemeral without a PVC. Accepts bool or string `true`/`false` (case-insensitive); rendered value is normalized to lowercase. | +| `chromadb.persistDirectory` | string | `/data` | Absolute path where index data is stored. Used for both Chroma server config and mounted persistent volume path. | | `chromadb.anonymizedTelemetry` | boolean | `false` | Legacy PostHog telemetry flag for `< 1.0.0`. **Note**: This has no effect in Chroma `>= 1.0.0`; use `chromadb.telemetry.*` for OTEL. | | `chromadb.corsAllowOrigins` | list | `[]` | List of allowed CORS origins. Wildcard `["*"]` is supported. | | `chromadb.apiImpl` | string | `- "chromadb.api.segment.SegmentAPI"` | Legacy/removed key kept for historical compatibility in docs. The chart does not read this value in current versions. | diff --git a/charts/chromadb-chart/templates/_helpers.tpl b/charts/chromadb-chart/templates/_helpers.tpl index 7f1e3dc..081d2e6 100644 --- a/charts/chromadb-chart/templates/_helpers.tpl +++ b/charts/chromadb-chart/templates/_helpers.tpl @@ -120,6 +120,59 @@ Get the chroma api version {{- end }} {{- end }} +{{/* +Normalize boolean values passed as bool or string. +Returns "true" or "false". +*/}} +{{- define "chromadb.boolValue" -}} +{{- $name := .name -}} +{{- $value := .value -}} +{{- if kindIs "bool" $value -}} + {{- if $value }}true{{ else }}false{{ end -}} +{{- else if kindIs "string" $value -}} + {{- $normalized := lower (trim $value) -}} + {{- if or (eq $normalized "true") (eq $normalized "false") -}} + {{- $normalized -}} + {{- else -}} + {{- fail (printf "%s must be true or false (case-insensitive), got %q" $name $value) -}} + {{- end -}} +{{- else -}} + {{- fail (printf "%s must be a boolean or a string true/false, got type %s" $name (kindOf $value)) -}} +{{- end -}} +{{- end }} + +{{/* +Normalize/validate chromadb.allowReset. +*/}} +{{- define "chromadb.allowReset" -}} +{{- include "chromadb.boolValue" (dict "name" "chromadb.allowReset" "value" .Values.chromadb.allowReset) -}} +{{- end }} + +{{/* +Normalize/validate chromadb.isPersistent. +*/}} +{{- define "chromadb.isPersistent" -}} +{{- include "chromadb.boolValue" (dict "name" "chromadb.isPersistent" "value" .Values.chromadb.isPersistent) -}} +{{- end }} + +{{/* +Validate and normalize the persist directory path. +*/}} +{{- define "chromadb.persistDirectory" -}} +{{- $raw := .Values.chromadb.persistDirectory -}} +{{- if not (kindIs "string" $raw) -}} + {{- fail (printf "chromadb.persistDirectory must be a string absolute path, got type %s" (kindOf $raw)) -}} +{{- end -}} +{{- $path := trim $raw -}} +{{- if eq $path "" -}} + {{- fail "chromadb.persistDirectory must not be empty" -}} +{{- end -}} +{{- if not (hasPrefix "/" $path) -}} + {{- fail (printf "chromadb.persistDirectory must be an absolute path starting with '/': got %q" $raw) -}} +{{- end -}} +{{- $path -}} +{{- end }} + {{/* Build the server config dict for the v1-config ConfigMap. */}} @@ -133,12 +186,14 @@ Build the server config dict for the v1-config ConfigMap. {{- fail (printf "chromadb.maxPayloadSizeBytes must be a positive integer, got: %v" .Values.chromadb.maxPayloadSizeBytes) -}} {{- end -}} {{- $isV1 := semverCompare ">= 1.0.0" (include "chromadb.apiVersion" .) -}} +{{- $allowReset := eq (include "chromadb.allowReset" .) "true" -}} +{{- $persistDirectory := include "chromadb.persistDirectory" . -}} {{- $config := dict -}} {{- $_ := set $config "port" $port -}} {{- $_ := set $config "listen_address" .Values.chromadb.serverHost -}} {{- $_ := set $config "max_payload_size_bytes" $maxPayload -}} -{{- $_ := set $config "persist_path" .Values.chromadb.persistDirectory -}} -{{- $_ := set $config "allow_reset" .Values.chromadb.allowReset -}} +{{- $_ := set $config "persist_path" $persistDirectory -}} +{{- $_ := set $config "allow_reset" $allowReset -}} {{- if .Values.chromadb.corsAllowOrigins -}} {{- $_ := set $config "cors_allow_origins" .Values.chromadb.corsAllowOrigins -}} {{- end -}} diff --git a/charts/chromadb-chart/templates/statefulset.yaml b/charts/chromadb-chart/templates/statefulset.yaml index b09a562..df47975 100644 --- a/charts/chromadb-chart/templates/statefulset.yaml +++ b/charts/chromadb-chart/templates/statefulset.yaml @@ -1,3 +1,7 @@ +{{- $allowReset := include "chromadb.allowReset" . -}} +{{- $isPersistentStr := include "chromadb.isPersistent" . -}} +{{- $isPersistent := eq $isPersistentStr "true" -}} +{{- $persistDirectory := include "chromadb.persistDirectory" . -}} apiVersion: apps/v1 kind: StatefulSet metadata: @@ -86,11 +90,11 @@ spec: fieldPath: metadata.name {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) }} - name: IS_PERSISTENT - value: "{{ .Values.chromadb.isPersistent }}" + value: "{{ $isPersistentStr }}" - name: PERSIST_DIRECTORY - value: "{{ .Values.chromadb.persistDirectory }}" + value: "{{ $persistDirectory }}" - name: ALLOW_RESET - value: "{{ .Values.chromadb.allowReset | default false}}" + value: "{{ $allowReset }}" - name: ANONYMIZED_TELEMETRY value: "{{ .Values.chromadb.anonymizedTelemetry | default false }}" {{- if .Values.chromadb.corsAllowOrigins }} @@ -164,8 +168,8 @@ spec: name: log-config-legacy subPath: log_config.yaml {{- end }} - {{- if eq .Values.chromadb.isPersistent true }} - - mountPath: "{{.Values.chromadb.persistDirectory}}" + {{- if $isPersistent }} + - mountPath: "{{ $persistDirectory }}" name: data {{- end }} {{- if and (semverCompare "< 1.0.0" (include "chromadb.apiVersion" .)) (semverCompare ">= 0.4.7" (include "chromadb.apiVersion" .)) .Values.chromadb.auth.enabled (eq .Values.chromadb.auth.type "basic") }} @@ -225,7 +229,7 @@ spec: name: v1-config defaultMode: 0644 {{- end }} - {{- if eq .Values.chromadb.isPersistent true }} + {{- if $isPersistent }} volumeClaimTemplates: - metadata: name: data diff --git a/tests/test_v1_config.sh b/tests/test_v1_config.sh index 2d3ab33..2b94bb6 100755 --- a/tests/test_v1_config.sh +++ b/tests/test_v1_config.sh @@ -54,6 +54,16 @@ get_statefulset_env_value() { echo "$output" | yq eval ".spec.template.spec.containers[] | select(.name == \"chromadb\") | [.env[]? | select(.name == \"$env_name\") | .value][0] // \"null\"" - } +get_statefulset_value() { + local expr="$1"; shift + local output + output=$(helm template test "$CHART_DIR" "$@" --show-only templates/statefulset.yaml 2>&1) || { + echo "TEMPLATE_ERROR: $output" >&2 + return 1 + } + echo "$output" | yq eval "$expr" - +} + assert_equal() { local desc="$1" actual="$2" expected="$3" if [ "$actual" = "$expected" ]; then @@ -288,6 +298,35 @@ echo "28. extraConfig must reject scalar values" assert_template_fails "extraConfig rejects scalar string values" \ --set 'chromadb.extraConfig=invalid' +echo "" +echo "29. allowReset accepts case-insensitive string booleans" +config=$(get_v1_config --set-string 'chromadb.allowReset=TRUE') +assert_config_key "allow_reset normalizes uppercase TRUE to true" "$config" "allow_reset" "true" + +echo "" +echo "30. isPersistent accepts case-insensitive string booleans" +is_persistent_env=$(get_statefulset_env_value "IS_PERSISTENT" --set 'chromadb.apiVersion=0.6.3' --set-string 'chromadb.isPersistent=FALSE') +assert_equal "IS_PERSISTENT normalizes uppercase FALSE to false" "$is_persistent_env" "false" +pvc_templates=$(get_statefulset_value '.spec.volumeClaimTemplates | length // 0' --set-string 'chromadb.isPersistent=FALSE') +assert_equal "volumeClaimTemplates omitted when isPersistent is false string" "$pvc_templates" "0" + +echo "" +echo "31. allowReset rejects invalid string values" +assert_template_fails "allowReset rejects non-boolean strings" \ + --set-string 'chromadb.allowReset=yes' + +echo "" +echo "32. isPersistent rejects invalid string values" +assert_template_fails "isPersistent rejects non-boolean strings" \ + --set-string 'chromadb.isPersistent=on' + +echo "" +echo "33. persistDirectory must be an absolute path" +assert_template_fails "persistDirectory rejects relative paths" \ + --set-string 'chromadb.persistDirectory=data' +assert_template_fails "persistDirectory rejects empty strings" \ + --set-string 'chromadb.persistDirectory=' + echo "" echo "--- Results: $PASS passed, $FAIL failed ---" [ "$FAIL" -eq 0 ] || exit 1