fix(helm): support omitting image.registry in querydoc chart#2124
Merged
EItanya merged 2 commits intoJul 1, 2026
Merged
Conversation
Signed-off-by: Mike Spinks <mikespinks@gmail.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the QueryDoc (doc2vec) Helm chart to render a valid container image reference when image.registry is empty, enabling users to omit the registry (e.g., Docker Hub/mirrors) without producing a leading-slash invalid image.
Changes:
- Add a
querydoc.imagehelper that builds the image path from non-empty segments viacompact+join. - Switch
templates/deployment.yamlto use the new helper for the container image. - Add a Helm unittest case verifying that an empty
image.registrydoes not produce a leading slash.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| helm/tools/querydoc/templates/_helpers.tpl | Adds querydoc.image helper to compose image references from optional segments. |
| helm/tools/querydoc/templates/deployment.yaml | Uses querydoc.image helper for the Deployment container image field. |
| helm/tools/querydoc/tests/deployment_test.yaml | Adds coverage for empty-registry image rendering (no leading slash). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Mike Spinks <mikespinks@gmail.com>
5141330 to
a042944
Compare
5 tasks
EItanya
approved these changes
Jul 1, 2026
EItanya
pushed a commit
that referenced
this pull request
Jul 1, 2026
## What
Make the grafana-mcp chart render a valid image reference when
`image.registry` is left empty, so the registry can be omitted (e.g. to
pull from a mirror or let the runtime resolve the default registry)
without producing a leading-slash, unpullable reference.
## Why
The image is built inline in `templates/deployment.yaml`:
```gotemplate
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}"
```
The `/` between registry and repository is written unconditionally. If
`image.registry` is set to `""`, the result has a leading slash and is
not a valid image reference, so the pod enters `ImagePullBackOff`:
```
/grafana:latest # invalid reference
```
There is currently no way to omit the registry and let the container
runtime resolve the repository against its default registry / a
configured mirror.
Omitting the registry is a configuration users legitimately need:
- **Air-gapped / mirrored environments.** Registry mirrors are
configured at the container runtime, which rewrites the host — so chart
values should carry only `repository:tag`.
- **Registry rewriting.** Admission controllers (e.g. Kyverno) prepend
an internal registry, so users leave `registry: ""`.
- **Consistency.** Other charts let you omit the registry; grafana-mcp
silently breaks with `ImagePullBackOff`, which reads like a bug.
> Note: the default `registry: mcp` is intentional and unchanged —
`mcp/grafana` resolves to `docker.io/mcp/grafana` (Docker Hub's `mcp`
namespace). This PR only makes an *empty* registry valid; the default
path still renders `mcp/grafana:latest`.
> This is the same 2-segment `registry/repository:tag` leading-slash
shape as the querydoc chart (#2124), and distinct from the
bundled-PostgreSQL `registry//name:tag` double-slash bug (#2120), which
uses a 3-segment shape. All fixed independently.
## Fix
Introduce a `grafana-mcp.image` helper (the chart currently has none)
that builds the path from non-empty segments via `compact` + `join`, and
call it from the deployment:
```gotemplate
{{- define "grafana-mcp.image" -}}
{{- $img := .Values.image -}}
{{- $parts := compact (list $img.registry $img.repository) -}}
{{- printf "%s:%s" (join "/" $parts) $img.tag -}}
{{- end -}}
```
```gotemplate
# templates/deployment.yaml
image: "{{ include "grafana-mcp.image" . }}"
```
Rendered results:
| registry | repository | tag | result |
|---|---|---|---|
| `mcp` | `grafana` | `latest` | `mcp/grafana:latest` (unchanged) |
| `""` | `grafana` | `latest` | `grafana:latest` (fixed) |
## Tests
Added two cases to `helm/tools/grafana-mcp/tests/deployment_test.yaml`
(developed test-first): a default-image regression guard (the suite had
no image assertion), and the empty-registry path.
```yaml
- it: should render the default container image
template: deployment.yaml
asserts:
- equal:
path: spec.template.spec.containers[0].image
value: mcp/grafana:latest
- it: should omit empty registry segment in image
template: deployment.yaml
set:
image:
registry: ""
asserts:
- equal:
path: spec.template.spec.containers[0].image
value: grafana:latest
- notMatchRegex:
path: spec.template.spec.containers[0].image
pattern: "^/"
```
The empty-registry test fails without this change (`/grafana:latest`)
and passes with it — revert the `deployment.yaml`/`_helpers.tpl` hunks
to reproduce.
## How to verify
```bash
make helm-tools # generate grafana-mcp Chart.yaml
helm unittest helm/tools/grafana-mcp # full suite green (incl. new cases)
helm lint helm/tools/grafana-mcp
# test-independent reproduction:
helm template t helm/tools/grafana-mcp --set image.registry="" | grep image:
# before: /grafana:latest
# after: grafana:latest
```
## Scope
Limited to the grafana-mcp chart's image construction. Empty
`repository` is not made valid here — omitting it leaves no image to
pull. This PR only makes `image.registry` optional.
## Checklist
- [x] Commit is DCO signed-off (`git commit -s`).
- [x] `helm unittest helm/tools/grafana-mcp` green; `helm lint
helm/tools/grafana-mcp` clean.
- [x] Default image still renders `mcp/grafana:latest` (regression
guard).
- [x] Diff limited to `templates/_helpers.tpl`,
`templates/deployment.yaml`, and `tests/deployment_test.yaml` (generated
chart files excluded).
- [x] Test fails without the fix, passes with it.
Signed-off-by: Mike Spinks <mikespinks@gmail.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Make the querydoc (doc2vec) chart render a valid image reference when
image.registryis left empty, so the registry can be omitted (e.g. to pull from Docker Hub or a mirror) without producing a leading-slash, unpullable reference.Why
The image is built inline in
templates/deployment.yaml:The
/between registry and repository is written unconditionally. Ifimage.registryis set to"", the result has a leading slash and is not a valid image reference, so the pod entersImagePullBackOff:There is currently no way to omit the registry and let the container runtime resolve the repository against its default registry / a configured mirror.
Omitting the registry is a configuration users legitimately need:
org/imagereference resolves to Docker Hub, so users mirroring the image there wantkagent-dev/doc2vec/mcp:tag, notghcr.io/....repository:tag.registry: "".ImagePullBackOff, which reads like a bug.Fix
Introduce a
querydoc.imagehelper (the chart currently has none) that builds the path from non-empty segments viacompact+join, and call it from the deployment:Rendered results:
ghcr.iokagent-dev/doc2vec/mcp1.1.10ghcr.io/kagent-dev/doc2vec/mcp:1.1.10(unchanged)ghcr.iokagent-dev/doc2vec/mcpv2.0.0ghcr.io/kagent-dev/doc2vec/mcp:v2.0.0(unchanged)""kagent-dev/doc2vec/mcp1.1.10kagent-dev/doc2vec/mcp:1.1.10(fixed)Tests
Added one case to
helm/tools/querydoc/tests/deployment_test.yamlfor the empty-registry path (developed test-first). The existing "should have correct container image" and "should use custom image tag when set" tests already guard the default and custom-tag paths, so no regression test was duplicated.The test fails without this change (
/kagent-dev/doc2vec/mcp:1.1.10) and passes with it — revert thedeployment.yaml/_helpers.tplhunks to reproduce.How to verify
Scope
Limited to the querydoc chart's image construction. Empty
repositoryis not made valid here, because the repository carries the full image path and there is no separate image-name segment — omitting it leaves no image to pull. This PR only makesimage.registryoptional.Checklist
git commit -s).helm unittest helm/tools/querydocgreen;helm lint helm/tools/querydocclean.templates/_helpers.tpl,templates/deployment.yaml, andtests/deployment_test.yaml(generated chart files excluded).