Skip to content

Commit 170f421

Browse files
committed
fix(helm): support quickstart image overrides
1 parent 17b8769 commit 170f421

9 files changed

Lines changed: 222 additions & 54 deletions

File tree

deployments/charts/osmo/README.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,24 @@ helm --kube-context kind-osmo upgrade --install osmo deployments/charts/osmo \
7575
--timeout 20m
7676
```
7777

78+
For prerelease OSMO images published below `nvcr.io/nvstaging/osmo`, set the
79+
registry and repository defaults separately. The runtime init and client images
80+
use the same location and tag:
81+
82+
```bash
83+
helm --kube-context kind-osmo upgrade --install osmo deployments/charts/osmo \
84+
--namespace osmo \
85+
--create-namespace \
86+
--values deployments/charts/osmo/profiles/quickstart.yaml \
87+
--set-string compute.backendName=default \
88+
--set-string imageRegistry=nvcr.io \
89+
--set-string imageRepository=nvstaging/osmo \
90+
--set-string imageTag=2026.8.28.3b3d1b0a2.ecolter3910-amd64 \
91+
--set-string 'imagePullSecrets[0].name=osmo-nvcr-pull' \
92+
--wait \
93+
--timeout 20m
94+
```
95+
7896
Inspect the release without reading generated Secret values:
7997

8098
```bash
@@ -510,14 +528,19 @@ above.
510528

511529
## Optional configuration
512530

513-
- Configure the OSMO image registry under `imageRegistry`, a shared
514-
OSMO component tag under `imageTag`, pull credentials under
515-
`imagePullSecrets`, and workflow init/client images under `runtimeImage`.
516-
The chart writes those workflow images into the managed API configuration
517-
unless `configuration.workflow.backend_images` overrides them. Configure
518-
per-component image overrides in each component's `image` block. Configure
519-
dependency images and pull credentials in their native values blocks; for
520-
example, Valkey uses `valkey.image` and `valkey.imagePullSecrets`.
531+
- Configure the OSMO image registry and base repository under `imageRegistry`
532+
and `imageRepository`, a shared OSMO component tag under `imageTag`, pull
533+
credentials under `imagePullSecrets`, and workflow init/client image
534+
overrides under `runtimeImage`. Top-level pull credentials are used as
535+
defaults for workflow pod templates unless a template defines its own list.
536+
A non-empty service-specific
537+
`image.registry` or `image.repository` takes precedence over these
538+
top-level defaults; otherwise the chart uses `nvcr.io/nvidia/osmo` and the
539+
component name. The chart writes the resolved workflow images into the
540+
managed API configuration unless `configuration.workflow.backend_images`
541+
overrides them. Configure dependency images and pull credentials in their
542+
native values blocks; for example, Valkey uses `valkey.image` and
543+
`valkey.imagePullSecrets`.
521544
- Configure replicas, autoscaling, resources, disruption budgets, scheduling,
522545
security contexts, probes, volumes, and ServiceAccounts under `services`,
523546
`gateway`, and `podDefaults`. Directly owned workload extensions use

deployments/charts/osmo/profiles/README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ values take precedence.
1111

1212
| File | Directly installable | Required environment input |
1313
| --- | --- | --- |
14-
| `quickstart.yaml` | Yes, on a development cluster | KAI Scheduler, the CloudNativePG operator, and a default dynamic StorageClass installed separately; `compute.backendName` set explicitly at install time |
14+
| `quickstart.yaml` | Yes, on a development cluster | KAI Scheduler, the CloudNativePG operator, and a default dynamic StorageClass installed separately; the pre-created `osmo-nvcr-pull` Secret; `compute.backendName` set explicitly at install time |
1515
| `kind-self-contained.yaml` | Yes, on kind | KAI Scheduler and the CloudNativePG operator installed separately; `compute.backendName` set explicitly at install time |
1616
| `split-plane-control.yaml` | Base overlay | PostgreSQL, Valkey, and object-storage endpoints; Kubernetes Secrets; and `externalUrl` |
1717
| `split-plane-compute.yaml` | Base overlay | A control-plane `externalUrl`, a compute authentication Secret, and `compute.backendName` set explicitly at install time |
@@ -20,8 +20,11 @@ The quick-start profile is the smallest complete control-and-compute deployment
2020
for browser, CLI, and CPU hello-world verification. It exposes the UI and API
2121
through gateway NodePort `30080` while omitting other optional services. The kind
2222
profile retains a broader local-development surface. Both profiles are
23-
development-only and intentionally use `latest` OSMO images, one replica per
24-
component, generated credentials, and embedded stateful dependencies. The split
23+
development-only and intentionally use `latest` OSMO images by default, one
24+
replica per component, generated credentials, and embedded stateful dependencies.
25+
The quick-start profile also references `osmo-nvcr-pull` for OSMO and workflow
26+
images; override it through top-level `imagePullSecrets` when using another
27+
Secret. The split
2528
profiles contain example names and endpoints; copy them into an environment
2629
values file before installation.
2730

deployments/charts/osmo/profiles/quickstart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ planes:
1212
fullnameOverride: osmo
1313

1414
imageTag: latest
15-
runtimeImage:
16-
tag: latest
15+
imagePullSecrets:
16+
- name: osmo-nvcr-pull
1717

1818
externalUrl: http://osmo-gateway
1919

deployments/charts/osmo/templates/_gateway-envoy-config.tpl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ setting detects this rotation and triggers Envoy to reload.
7878
{{- fail "services.mcp.scopes entries must not be empty" }}
7979
{{- end }}
8080
{{- end }}
81-
{{- $_ := required "services.mcp.image.repository is required when MCP is enabled" $mcp.image.repository }}
81+
{{- if and (not $mcp.image.repository) (not $mcp.image.name) }}
82+
{{- fail "services.mcp.image.repository or image.name is required when MCP is enabled" }}
83+
{{- end }}
8284
{{- if or (lt (int $mcp.port) 1) (gt (int $mcp.port) 65535) }}
8385
{{- fail "services.mcp.port must be between 1 and 65535" }}
8486
{{- end }}

deployments/charts/osmo/templates/_helpers.tpl

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,19 @@ app.kubernetes.io/instance: {{ .Release.Name }}
9090
{{- $root := .root -}}
9191
{{- $image := .image -}}
9292
{{- $registry := $image.registry -}}
93-
{{- if .useSharedRegistry -}}
93+
{{- $repository := $image.repository -}}
94+
{{- if hasKey $image "name" -}}
95+
{{- $registry = $registry | default $root.Values.imageRegistry | default "nvcr.io" -}}
96+
{{- $repository = $repository | default $root.Values.imageRepository | default "nvidia/osmo" -}}
97+
{{- if not $image.repository -}}
98+
{{- $repository = printf "%s/%s" (trimSuffix "/" $repository) $image.name -}}
99+
{{- end -}}
100+
{{- else -}}
101+
{{- if and .useSharedRegistry (not $root.Values.imageRepository) -}}
94102
{{- $registry = $root.Values.imageRegistry | default $registry -}}
95103
{{- end -}}
96-
{{- $repository := required "image.repository is required" $image.repository -}}
104+
{{- $repository = required "image.repository is required" $repository -}}
105+
{{- end -}}
97106
{{- $base := ternary (printf "%s/%s" $registry $repository) $repository (ne $registry "") -}}
98107
{{- if $image.digest -}}
99108
{{- printf "%s@%s" $base $image.digest -}}
@@ -111,12 +120,13 @@ app.kubernetes.io/instance: {{ .Release.Name }}
111120
{{- end -}}
112121

113122
{{- define "osmo.component.imageRepository" -}}
114-
{{- $registry := .Values.imageRegistry | default .Values.runtimeImage.registry -}}
115-
{{- ternary (printf "%s/%s" $registry .Values.runtimeImage.repository) .Values.runtimeImage.repository (ne $registry "") -}}
123+
{{- $registry := .Values.runtimeImage.registry | default .Values.imageRegistry | default "nvcr.io" -}}
124+
{{- $repository := .Values.runtimeImage.repository | default .Values.imageRepository | default "nvidia/osmo" -}}
125+
{{- printf "%s/%s" (trimSuffix "/" $registry) (trimSuffix "/" $repository) -}}
116126
{{- end -}}
117127

118128
{{- define "osmo.component.imageTag" -}}
119-
{{- .Values.runtimeImage.tag | default .Chart.AppVersion -}}
129+
{{- .Values.runtimeImage.tag | default .Values.imageTag | default .Chart.AppVersion -}}
120130
{{- end -}}
121131

122132
{{- define "osmo.compute.agentNamespace" -}}

deployments/charts/osmo/templates/configs.yaml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,20 @@ data:
6969
{{- toYaml $cfg.pools | nindent 6 }}
7070
{{- end }}
7171
{{- if $cfg.podTemplates }}
72+
{{- $podTemplates := deepCopy $cfg.podTemplates }}
73+
{{- if gt (len .Values.imagePullSecrets) 0 }}
74+
{{- range $_, $podTemplate := $podTemplates }}
75+
{{- if kindIs "map" $podTemplate }}
76+
{{- $spec := index $podTemplate "spec" | default dict }}
77+
{{- if and (kindIs "map" $spec) (not (hasKey $spec "imagePullSecrets")) }}
78+
{{- $_ := set $spec "imagePullSecrets" $.Values.imagePullSecrets }}
79+
{{- $_ := set $podTemplate "spec" $spec }}
80+
{{- end }}
81+
{{- end }}
82+
{{- end }}
83+
{{- end }}
7284
pod_templates:
73-
{{- toYaml $cfg.podTemplates | nindent 6 }}
85+
{{- toYaml $podTemplates | nindent 6 }}
7486
{{- end }}
7587
{{- if $cfg.resourceValidations }}
7688
resource_validations:

deployments/charts/osmo/tests/test_osmo_charts.sh

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,46 @@ test_control_umbrella() {
641641
require_not_contains "$TEST_DIRECTORY/kind-self-contained-ui.yaml" \
642642
"scheme: HTTPS"
643643

644+
local quickstart_runtime_tag=2026.8.28.3b3d1b0a2.ecolter3910-amd64
645+
helm_template_with_backend quick-start-runtime "$charts_copy/osmo" \
646+
--namespace osmo \
647+
--api-versions postgresql.cnpg.io/v1 \
648+
-f "$charts_copy/osmo/profiles/quickstart.yaml" \
649+
--set-string imageRegistry=nvcr.io \
650+
--set-string imageRepository=nvstaging/osmo \
651+
--set-string imageTag="$quickstart_runtime_tag" \
652+
--set-string 'imagePullSecrets[0].name=osmo-nvcr-pull' \
653+
>"$TEST_DIRECTORY/quickstart-runtime.yaml"
654+
resource_document "$TEST_DIRECTORY/quickstart-runtime.yaml" ConfigMap \
655+
osmo-api-config >"$TEST_DIRECTORY/quickstart-runtime-config.yaml"
656+
require_contains "$TEST_DIRECTORY/quickstart-runtime-config.yaml" \
657+
"init: nvcr.io/nvstaging/osmo/init-container:$quickstart_runtime_tag"
658+
require_contains "$TEST_DIRECTORY/quickstart-runtime-config.yaml" \
659+
"client: nvcr.io/nvstaging/osmo/client:$quickstart_runtime_tag"
660+
require_contains "$TEST_DIRECTORY/quickstart-runtime-config.yaml" \
661+
"imagePullSecrets:"
662+
require_contains "$TEST_DIRECTORY/quickstart-runtime-config.yaml" \
663+
"name: osmo-nvcr-pull"
664+
resource_document "$TEST_DIRECTORY/quickstart-runtime.yaml" Deployment \
665+
osmo-api >"$TEST_DIRECTORY/quickstart-runtime-api.yaml"
666+
require_contains "$TEST_DIRECTORY/quickstart-runtime-api.yaml" \
667+
"image: nvcr.io/nvstaging/osmo/service:$quickstart_runtime_tag"
668+
require_occurrences "$TEST_DIRECTORY/quickstart-runtime.yaml" \
669+
"image: nvcr.io/nvstaging/osmo/service:$quickstart_runtime_tag" 2
670+
671+
helm_template_with_backend quick-start-workflow-pull-secret "$charts_copy/osmo" \
672+
--namespace osmo \
673+
--api-versions postgresql.cnpg.io/v1 \
674+
-f "$charts_copy/osmo/profiles/quickstart.yaml" \
675+
--set-string 'imagePullSecrets[0].name=sentinel-pull-secret' \
676+
>"$TEST_DIRECTORY/quickstart-workflow-pull-secret.yaml"
677+
resource_document "$TEST_DIRECTORY/quickstart-workflow-pull-secret.yaml" ConfigMap \
678+
osmo-api-config >"$TEST_DIRECTORY/quickstart-workflow-pull-secret-config.yaml"
679+
require_contains "$TEST_DIRECTORY/quickstart-workflow-pull-secret-config.yaml" \
680+
"name: sentinel-pull-secret"
681+
require_not_contains "$TEST_DIRECTORY/quickstart-workflow-pull-secret-config.yaml" \
682+
"name: osmo-nvcr-pull"
683+
644684
helm_template_with_backend quick-start "$charts_copy/osmo" \
645685
--namespace osmo \
646686
--api-versions postgresql.cnpg.io/v1 \
@@ -3627,6 +3667,58 @@ EOF
36273667
require_contains "$TEST_DIRECTORY/osmo-image-mirror.yaml" \
36283668
"name: mirror-secret"
36293669

3670+
helm_template image-family-override "$charts_copy/osmo" \
3671+
-f "$CHARTS_ROOT/osmo/tests/control-external-values.yaml" \
3672+
--set-string imageRegistry=nvcr.io \
3673+
--set-string imageRepository=nvstaging/osmo \
3674+
--set-string imageTag=2026.8.28.3b3d1b0a2.ecolter3910-amd64 \
3675+
--set imagePullSecrets[0].name=nvcr-pull-secret \
3676+
>"$TEST_DIRECTORY/osmo-image-family-override.yaml"
3677+
require_contains "$TEST_DIRECTORY/osmo-image-family-override.yaml" \
3678+
"image: nvcr.io/nvstaging/osmo/worker:2026.8.28.3b3d1b0a2.ecolter3910-amd64"
3679+
require_contains "$TEST_DIRECTORY/osmo-image-family-override.yaml" \
3680+
'image: "docker.io/envoyproxy/envoy:v1.38.1"'
3681+
3682+
helm_template image-priority "$charts_copy/osmo" \
3683+
-f "$CHARTS_ROOT/osmo/tests/control-external-values.yaml" \
3684+
--set-string imageRegistry=nvcr.io \
3685+
--set-string imageRepository=nvstaging/osmo \
3686+
--set-string services.worker.image.registry=registry.example.com \
3687+
--set-string services.worker.image.repository=custom/team/worker \
3688+
--set-string services.worker.image.tag=v2 \
3689+
>"$TEST_DIRECTORY/osmo-image-priority.yaml"
3690+
require_contains "$TEST_DIRECTORY/osmo-image-priority.yaml" \
3691+
"image: registry.example.com/custom/team/worker:v2"
3692+
3693+
helm_template image-field-priority "$charts_copy/osmo" \
3694+
-f "$CHARTS_ROOT/osmo/tests/control-external-values.yaml" \
3695+
--set-string imageRegistry=registry.example.com \
3696+
--set-string imageRepository=team/osmo \
3697+
--set-string imageTag=v1 \
3698+
--set-string services.worker.image.registry=service.example.com \
3699+
--set-string services.router.image.repository=service/router \
3700+
>"$TEST_DIRECTORY/osmo-image-field-priority.yaml"
3701+
require_contains "$TEST_DIRECTORY/osmo-image-field-priority.yaml" \
3702+
"image: service.example.com/team/osmo/worker:v1"
3703+
require_contains "$TEST_DIRECTORY/osmo-image-field-priority.yaml" \
3704+
"image: registry.example.com/service/router:v1"
3705+
3706+
helm_template runtime-priority "$charts_copy/osmo" \
3707+
-f "$CHARTS_ROOT/osmo/tests/control-external-values.yaml" \
3708+
--set-string imageRegistry=nvcr.io \
3709+
--set-string imageRepository=nvstaging/osmo \
3710+
--set-string runtimeImage.registry=registry.example.com \
3711+
--set-string runtimeImage.repository=custom/runtime \
3712+
--set-string runtimeImage.tag=v3 \
3713+
>"$TEST_DIRECTORY/osmo-runtime-priority.yaml"
3714+
resource_document "$TEST_DIRECTORY/osmo-runtime-priority.yaml" Deployment \
3715+
runtime-priority-osmo-api \
3716+
>"$TEST_DIRECTORY/osmo-runtime-priority-api.yaml"
3717+
require_contains "$TEST_DIRECTORY/osmo-runtime-priority-api.yaml" \
3718+
"registry.example.com/custom/runtime"
3719+
require_contains "$TEST_DIRECTORY/osmo-runtime-priority-api.yaml" \
3720+
'"v3"'
3721+
36303722
helm_template embedded-image-pull-secret "$charts_copy/osmo" \
36313723
-f "$charts_copy/osmo/profiles/split-plane-control.yaml" \
36323724
-f "$CHARTS_ROOT/osmo/tests/control-external-values.yaml" \

deployments/charts/osmo/values.schema.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"nameOverride": { "type": "string" },
2828
"fullnameOverride": { "type": "string" },
2929
"imageRegistry": { "type": "string" },
30+
"imageRepository": { "type": "string" },
3031
"imageTag": { "type": "string" },
3132
"imagePullSecrets": { "$ref": "#/definitions/imagePullSecrets" },
3233
"runtimeImage": { "$ref": "#/definitions/runtimeImage" },
@@ -104,7 +105,7 @@
104105
}
105106
}
106107
},
107-
"required": ["planes", "compute", "embeddedDependencies", "externalDependencies", "imageRegistry", "imageTag", "imagePullSecrets", "runtimeImage", "externalUrl", "ingress", "httproute", "monitoring", "secrets", "services", "gateway"],
108+
"required": ["planes", "compute", "embeddedDependencies", "externalDependencies", "imageRegistry", "imageRepository", "imageTag", "imagePullSecrets", "runtimeImage", "externalUrl", "ingress", "httproute", "monitoring", "secrets", "services", "gateway"],
108109
"definitions": {
109110
"enabledBlock": {
110111
"type": "object",
@@ -562,7 +563,7 @@
562563
"type": "object",
563564
"properties": {
564565
"registry": { "type": "string" },
565-
"repository": { "type": "string", "minLength": 1 },
566+
"repository": { "type": "string" },
566567
"tag": { "type": "string" }
567568
},
568569
"required": ["registry", "repository", "tag"]
@@ -571,12 +572,17 @@
571572
"type": "object",
572573
"properties": {
573574
"registry": { "type": "string" },
574-
"repository": { "type": "string", "minLength": 1 },
575+
"repository": { "type": "string" },
576+
"name": { "type": "string", "minLength": 1 },
575577
"tag": { "type": "string" },
576578
"digest": { "type": "string", "pattern": "^$|^sha256:[A-Fa-f0-9]{64}$" },
577579
"pullPolicy": { "type": "string", "enum": ["Always", "IfNotPresent", "Never"] }
578580
},
579-
"required": ["registry", "repository", "tag", "digest", "pullPolicy"]
581+
"required": ["registry", "repository", "tag", "digest", "pullPolicy"],
582+
"anyOf": [
583+
{ "required": ["name"] },
584+
{ "properties": { "repository": { "minLength": 1 } } }
585+
]
580586
},
581587
"probe": {
582588
"type": "object",

0 commit comments

Comments
 (0)