Conversation
1cc159f to
495df97
Compare
495df97 to
7fc41f7
Compare
| global.imageRegistry value redirects them all. A values file still carrying | ||
| a path in registry would render a doubled prefix that fails only at pod | ||
| start, so it fails the render here instead and names the split. */}} | ||
| {{- if contains "/" $ctx.Values.image.registry -}} |
There was a problem hiding this comment.
This guard seems like it might reject the repository's own manifest renderer. hack/render-manifests.sh:63 still passes image.registry=ko://github.com/agent-substrate/substrate/cmd with image.tag=<none>. Its Helm invocation succeeds on main, but fails for me here with image.registry (...) carries a path, so both make helm-template and make helm-template-check stop before generating/checking manifests. I think that script might need to be updated.
There was a problem hiding this comment.
Good catch — fixed in the latest push. Two parts: hack/render-manifests.sh now passes the split (image.registry=ko://github.com, image.repository=agent-substrate/substrate/cmd), and the guard permits a scheme'd registry (://), since a ko importpath prefix is unambiguously not the old host+path shape — same idea as the existing <none> tag sentinel this script already relies on. Verified the composed refs are byte-identical to main's renderer output for all five components, and the guard still rejects a real old-shape value like my.reg/custom/prefix.
7fc41f7 to
ed9f853
Compare
global.imageRegistry redirects every image at once for air-gapped mirrors. Component images now resolve through the same registry/repository split every kagent-family chart uses: image.registry was one string carrying its path (ghcr.io/kagent-dev/substrate) and is now the registry host only, joined onto image.repository, so one global value (which overrides image.registry) redirects the whole family. This is a breaking change for values files that put a full prefix in image.registry: rendered silently they would produce a doubled prefix failing only at pod start, so the render fails instead, naming the split. A default render is byte-identical to main. Single-string images.* references (postgres, rustfs, aws-cli, agentgateway) have their registry segment replaced by the containerd rule (first path segment with a dot or colon), preserving repository paths either way. global.imagePullSecrets merges (union) into every pod spec, which previously had no pull-secret surface at all. global.imagePullPolicy replaces the hardcoded IfNotPresent values as a fallback, via substrate.imagePullPolicy. Verified: a default render is byte-identical to main; the mirror knob redirects all 9 images with paths preserved; the old-shape registry fails loudly at template time; pull secrets land on all 9 pod specs; the pullPolicy fallback fires. Signed-off-by: Jonathan Jamroga <jjamroga@gmail.com>
ed9f853 to
238b46b
Compare
What this gives operators
This PR adds a
global:block for install-wide image settings. Helm passesglobal.*down from a parent chart, so a parent that vendors substrate sets each value once.global.imageRegistry— for air-gapped and private-registry installs. Mirror the images, then set this one value. Every image the chart renders pulls from the mirror. Component images resolve as<your-registry>/kagent-dev/substrate/<component>. The single-stringimages.*references (postgres, rustfs, aws-cli, agentgateway) have their registry segment replaced, digests preserved. Repository paths are identical on every registry, so a mirror copies each image under its existing path.global.imagePullSecrets— the pull secret that mirror needs. The chart merges it (union) into every pod spec. The chart previously had no pull-secret surface at all: a private mirror was unusable regardless of the registry value. A chart-levelimagePullSecretslist is added alongside the global.global.imagePullPolicy— one pull policy for the containers that previously hardcodedIfNotPresent.The breaking change
image.registrywas one string that carried a path:ghcr.io/kagent-dev/substrate. It is now split.image.registryholds the registry host. A newimage.repositoryholds the path prefix ahead of each component name. The other kagent-family charts use this same shape. The shared shape is what makes one mirror value work across all of them.Who this breaks: values files that relocated the component images by overriding
image.registrywith a full prefix.How the break stays safe: it cannot fail silently. A naive render would join the new default repository onto the old-shape override. The doubled prefix would fail only at pod start, as
ImagePullBackOff. Instead, the render fails at template time. The error names the fix:The operator sees one loud
helm upgradeerror with the migration in it. No pod fails to pull. Operators who do not overrideimage.registryare untouched. A default render is byte-identical to main.A boundary, stated
The
images.*values stay single strings, because several are digest-pinned third-party references with no natural registry/repository split. For those, the mirror override replaces the registry segment: the first path segment is treated as a registry only when it contains a.or a:(the containerd rule); otherwise the mirror is prefixed. The rewrite activates only whenglobal.imageRegistryis set. Without it, every reference renders exactly as written.Verification
A default render is byte-identical to main. Verified by render: the mirror value redirects all 9 images with repository paths and digests preserved; the old-shape
image.registryfails at template time with the message above; the merged pull secrets land on all 9 pod specs; the pull-policy fallback fires.🤖 Generated with Claude Code