diff --git a/helm/litellm-helm/Chart.lock b/helm/litellm-helm/Chart.lock index f13578d8d35..d626fbb472b 100644 --- a/helm/litellm-helm/Chart.lock +++ b/helm/litellm-helm/Chart.lock @@ -5,5 +5,5 @@ dependencies: - name: redis repository: oci://registry-1.docker.io/bitnamicharts version: 18.19.1 -digest: sha256:8660fe6287f9941d08c0902f3f13731079b8cecd2a5da2fbc54e5b7aae4a6f62 -generated: "2024-03-10T02:28:52.275022+05:30" +digest: sha256:38962e231f6596b93f82a8412bbe4cf5de696caecf5775dfbbd163383eb1c009 +generated: "2026-07-28T10:21:22.511401-07:00" diff --git a/helm/litellm-helm/Chart.yaml b/helm/litellm-helm/Chart.yaml index 0aef2442bfe..8ca217825b8 100644 --- a/helm/litellm-helm/Chart.yaml +++ b/helm/litellm-helm/Chart.yaml @@ -18,7 +18,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.1.0 +version: 1.1.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to @@ -32,10 +32,10 @@ annotations: dependencies: - name: "postgresql" - version: ">=13.3.0" + version: "14.3.1" repository: oci://registry-1.docker.io/bitnamicharts condition: db.deployStandalone - name: redis - version: ">=18.0.0" + version: "18.19.1" repository: oci://registry-1.docker.io/bitnamicharts condition: redis.enabled diff --git a/helm/litellm-helm/README.md b/helm/litellm-helm/README.md index 0edc4d2504b..4e0884dd08c 100644 --- a/helm/litellm-helm/README.md +++ b/helm/litellm-helm/README.md @@ -130,6 +130,16 @@ Set `billingMetrics.caSecretName` only when the collector is a private or test o | `db.deployStandalone` | Deploy a standalone, single instance deployment of Postgres, using the Bitnami postgresql chart. This is useful for getting started but doesn't provide HA or (by default) data backups. | `true` | | `postgresql.*` | If `db.deployStandalone` is `true`, configuration passed to the Bitnami postgresql chart. See the [Bitnami Documentation](https://github.com/bitnami/charts/tree/main/bitnami/postgresql) for full configuration details. See [values.yaml](./values.yaml) for the default configuration. | See [values.yaml](./values.yaml) | | `postgresql.auth.*` | If `db.deployStandalone` is `true`, care should be taken to ensure the default `password` and `postgres-password` values are **NOT** used. | `NoTaGrEaTpAsSwOrD` | +| `postgresql.image.*` | If `db.deployStandalone` is `true`, the image for the bundled Postgres. Pinned to a `docker.io/bitnamilegacy` build because Bitnami retired the versioned tags under `docker.io/bitnami`. | `bitnamilegacy/postgresql:16.2.0-debian-12-r6` | +| `redis.image.*` | If `redis.enabled` is `true`, the image for the bundled Redis. Pinned to a `docker.io/bitnamilegacy` build for the same reason. | `bitnamilegacy/redis:7.2.4-debian-12-r9` | + +#### Bundled Postgres image + +Bitnami removed the versioned tags from `docker.io/bitnami` and republished the archived builds under `docker.io/bitnamilegacy`, so the image defaults that ship inside the `postgresql` and `redis` subcharts no longer pull. The chart pins both to the `bitnamilegacy` copies of the exact builds those subchart versions were released with, which keeps the on-disk data directory layout unchanged for existing installs. + +Keep `postgresql.image.tag` pinned. `docker.io/bitnami/postgresql` still publishes a floating `latest`, and pointing the bundled Postgres at a different major version starts the server against a data directory it cannot read (`database files are incompatible with server`). There is no in-place way back, so crossing a major version means dumping the database with the old image and restoring it into the new one. The chart refuses to render when the tag is empty or `latest`. + +Those images no longer receive updates. For anything beyond getting started, run Postgres outside the chart and point at it with `db.useExisting`. #### Example Postgres `db.useExisting` Secret diff --git a/helm/litellm-helm/templates/_helpers.tpl b/helm/litellm-helm/templates/_helpers.tpl index 387bc3d5dc4..8f2acb20fce 100644 --- a/helm/litellm-helm/templates/_helpers.tpl +++ b/helm/litellm-helm/templates/_helpers.tpl @@ -146,3 +146,18 @@ Get redis service port {{ .Values.redis.master.service.ports.redis }} {{- end -}} {{- end -}} + +{{/* +Reject an unpinned image tag for the bundled PostgreSQL. +A floating tag lets a chart upgrade start a newer PostgreSQL major against the +existing PersistentVolumeClaim. The server then refuses to start on a data +directory written by another major version, and the only way back is a dump +taken before the change, which by that point no longer exists. +*/}} +{{- define "litellm.validateBundledPostgresImageTag" -}} +{{- $tag := .Values.postgresql.image.tag | default "" | toString -}} +{{- $digest := .Values.postgresql.image.digest | default "" | toString -}} +{{- if and (eq $digest "") (or (eq $tag "") (eq $tag "latest")) -}} +{{- fail (printf "postgresql.image.tag must be pinned to an explicit version when db.deployStandalone is true (got %q). An unpinned tag can start a different PostgreSQL major against the existing data directory, which makes the database unreadable and is not recoverable in place. Crossing a major version requires a dump and restore." $tag) -}} +{{- end -}} +{{- end -}} diff --git a/helm/litellm-helm/templates/secret-dbcredentials.yaml b/helm/litellm-helm/templates/secret-dbcredentials.yaml index 8851f5802f2..8ab89a4579e 100644 --- a/helm/litellm-helm/templates/secret-dbcredentials.yaml +++ b/helm/litellm-helm/templates/secret-dbcredentials.yaml @@ -1,4 +1,5 @@ {{- if .Values.db.deployStandalone -}} +{{- include "litellm.validateBundledPostgresImageTag" . -}} apiVersion: v1 kind: Secret metadata: diff --git a/helm/litellm-helm/templates/tests/test-servicemonitor.yaml b/helm/litellm-helm/templates/tests/test-servicemonitor.yaml index c2a4f84ec21..ef8475339c3 100644 --- a/helm/litellm-helm/templates/tests/test-servicemonitor.yaml +++ b/helm/litellm-helm/templates/tests/test-servicemonitor.yaml @@ -10,7 +10,7 @@ metadata: spec: containers: - name: test - image: bitnami/kubectl:latest + image: docker.io/bitnamilegacy/kubectl:1.29.2-debian-12-r3 command: ['sh', '-c'] args: - | diff --git a/helm/litellm-helm/tests/bundled_db_images_tests.yaml b/helm/litellm-helm/tests/bundled_db_images_tests.yaml new file mode 100644 index 00000000000..8f0860c2721 --- /dev/null +++ b/helm/litellm-helm/tests/bundled_db_images_tests.yaml @@ -0,0 +1,94 @@ +suite: test bundled database images +templates: + - charts/postgresql/templates/primary/statefulset.yaml + - charts/redis/templates/master/application.yaml + - charts/redis/templates/configmap.yaml + - charts/redis/templates/health-configmap.yaml + - charts/redis/templates/scripts-configmap.yaml + - charts/redis/templates/secret.yaml + - secret-dbcredentials.yaml + - templates/tests/test-servicemonitor.yaml +tests: + - it: should pull the bundled postgres from a repository that still publishes the pinned tag + template: charts/postgresql/templates/primary/statefulset.yaml + set: + db.deployStandalone: true + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: docker.io/bitnamilegacy/postgresql:16.2.0-debian-12-r6 + + - it: should pull the bundled postgres metrics exporter from the same repository + template: charts/postgresql/templates/primary/statefulset.yaml + set: + db.deployStandalone: true + postgresql.metrics.enabled: true + asserts: + - equal: + path: spec.template.spec.containers[1].image + value: docker.io/bitnamilegacy/postgres-exporter:0.15.0-debian-12-r14 + + - it: should run the bundled postgres init container from the same repository + template: charts/postgresql/templates/primary/statefulset.yaml + set: + db.deployStandalone: true + postgresql.volumePermissions.enabled: true + asserts: + - equal: + path: spec.template.spec.initContainers[0].image + value: docker.io/bitnamilegacy/os-shell:12-debian-12-r16 + + - it: should pull the bundled redis from a repository that still publishes the pinned tag + template: charts/redis/templates/master/application.yaml + set: + redis.enabled: true + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: docker.io/bitnamilegacy/redis:7.2.4-debian-12-r9 + + - it: should reject a floating postgres tag that could cross a major version on an existing volume + template: secret-dbcredentials.yaml + set: + db.deployStandalone: true + postgresql.image.tag: latest + asserts: + - failedTemplate: + errorMessage: 'postgresql.image.tag must be pinned to an explicit version when db.deployStandalone is true (got "latest"). An unpinned tag can start a different PostgreSQL major against the existing data directory, which makes the database unreadable and is not recoverable in place. Crossing a major version requires a dump and restore.' + + - it: should reject an empty postgres tag + template: secret-dbcredentials.yaml + set: + db.deployStandalone: true + postgresql.image.tag: "" + asserts: + - failedTemplate: + errorMessage: 'postgresql.image.tag must be pinned to an explicit version when db.deployStandalone is true (got ""). An unpinned tag can start a different PostgreSQL major against the existing data directory, which makes the database unreadable and is not recoverable in place. Crossing a major version requires a dump and restore.' + + - it: should accept an empty postgres tag when the image is pinned by digest + template: secret-dbcredentials.yaml + set: + db.deployStandalone: true + postgresql.image.tag: "" + postgresql.image.digest: sha256:0d0e2f1a5b3c4d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6 + asserts: + - hasDocuments: + count: 1 + + - it: should run the servicemonitor test pod from a pinned image + template: templates/tests/test-servicemonitor.yaml + set: + serviceMonitor.enabled: true + asserts: + - equal: + path: spec.containers[0].image + value: docker.io/bitnamilegacy/kubectl:1.29.2-debian-12-r3 + + - it: should not constrain the postgres tag when the bundled database is not deployed + template: secret-dbcredentials.yaml + set: + db.deployStandalone: false + postgresql.image.tag: latest + asserts: + - hasDocuments: + count: 0 diff --git a/helm/litellm-helm/values.yaml b/helm/litellm-helm/values.yaml index 0529e74d6e4..7235bb0bd78 100644 --- a/helm/litellm-helm/values.yaml +++ b/helm/litellm-helm/values.yaml @@ -328,8 +328,32 @@ lifecycle: {} # Settings for Bitnami postgresql chart (if db.deployStandalone is true, ignored # otherwise) +# +# Bitnami retired the versioned tags under docker.io/bitnami and republished the +# archived builds under docker.io/bitnamilegacy, so the subchart's own image +# defaults no longer resolve. The repository below points at the same build the +# subchart was released with, which keeps the on-disk data directory layout +# identical for existing installs. +# +# Keep the tag pinned. docker.io/bitnami still publishes a floating `latest`, +# and starting a newer PostgreSQL major against an existing data directory +# leaves the server refusing to boot ("database files are incompatible with +# server") with no way back other than a dump taken beforehand. Crossing a major +# version is a dump-and-restore, not an image bump. The chart refuses to render +# an unpinned tag for this reason postgresql: architecture: standalone + image: + repository: bitnamilegacy/postgresql + tag: 16.2.0-debian-12-r6 + volumePermissions: + image: + repository: bitnamilegacy/os-shell + tag: 12-debian-12-r16 + metrics: + image: + repository: bitnamilegacy/postgres-exporter + tag: 0.15.0-debian-12-r14 auth: username: litellm database: litellm @@ -359,9 +383,36 @@ postgresql: # When `redis.sentinel.enabled` is set, the coordination block is rendered with # `sentinel_nodes` and `service_name` (from `redis.sentinel.masterSet`) instead # of host/port, because a plain Redis client cannot talk to the sentinel port +# +# The image repositories carry the same bitnamilegacy repoint as postgresql +# above; the versioned tags the subchart ships with are gone from +# docker.io/bitnami redis: enabled: false architecture: standalone + image: + repository: bitnamilegacy/redis + tag: 7.2.4-debian-12-r9 + sentinel: + image: + repository: bitnamilegacy/redis-sentinel + tag: 7.2.4-debian-12-r7 + metrics: + image: + repository: bitnamilegacy/redis-exporter + tag: 1.58.0-debian-12-r4 + volumePermissions: + image: + repository: bitnamilegacy/os-shell + tag: 12-debian-12-r16 + sysctl: + image: + repository: bitnamilegacy/os-shell + tag: 12-debian-12-r16 + kubectl: + image: + repository: bitnamilegacy/kubectl + tag: 1.29.2-debian-12-r3 coordination: # Set to false to keep the bundled Redis for response caching only and leave # `general_settings.coordination_redis` out of the rendered config. A