Files
Nikolas Garza 31ea4944b5 fix(helm): wait for the object store at startup and keep the MinIO PVC on retire (#16431)
## Description

Fixes two Helm issues from the v5.0 bug bash:
[ENG-4445](https://linear.app/onyx-app/issue/ENG-4445/helm-the-copy-job-and-api-server-crash-loop-at-startup-before)
and
[ENG-4447](https://linear.app/onyx-app/issue/ENG-4447/helm-retiring-minio-needs-a-manual-pvc-keep-annotation-and-leaves-pvcs).

**Why**
- The api server's startup bucket check and the legacy copy's
`ensure_bucket` fail with `EndpointConnectionError` until SeaweedFS is
ready, so on the 0.8 → 0.9 upgrade they crash-loop and the copy spends
its `backoffLimit`.
- An install upgraded with `--reuse-values` never gets
`helm.sh/resource-policy: keep` on `<release>-minio`, so the upgrade
that sets `minio.enabled: false` deletes the PVC and MinIO's data unless
the admin annotates it by hand.

**What**
- A `wait-for-object-store` init container on the app image polls the
object store's `/healthz` before the api server and the copy Job start.
It takes the guarded container's resources and securityContext. External
object storage gets none.
- With MinIO disabled, `minio-retired-pvc.yaml` renders the existing
MinIO claim from its live spec with `keep`, so Helm updates it instead
of deleting it. MIGRATION.md drops the manual step and says how to
delete the claim.
- The copy Job's name hash changes, so a release still on MinIO reruns
the copy once (idempotent). Chart 0.9.21.

## How Has This Been Tested?

kind with Helm 4, starting from a MinIO-only install with no keep
annotation, then `--reuse-values` upgrades. Main's chart: the copy Job
restarted twice before SeaweedFS was ready, and retiring MinIO deleted
`onyx-minio`. This branch: the api and copy Job waited about 18 s in
`wait-for-object-store` (six one-line logs each) with 0 restarts, the
copy completed, and retiring MinIO kept `onyx-minio` with the same UID,
`keep` added and the MinIO data still on the volume. A second upgrade
changed nothing. `test_object_store_wait_render.py` renders the init
container in each case and runs the wait against a refused, then 503,
then 200 store. All 81 render tests pass.

## Additional Options

- [x] [Optional] Please cherry-pick this PR to the latest release
version.
2026-10-22 00:39:08 +00:00
..