Skip to content

[HYPERSHELL-45] Update gateway and supervisor openshell images to Red Hat ones - #201

Merged
rh-amarin merged 3 commits into
openshift-online:mainfrom
JGiola:feat/use-redhat-openshell-images
Sep 1, 2026
Merged

[HYPERSHELL-45] Update gateway and supervisor openshell images to Red Hat ones#201
rh-amarin merged 3 commits into
openshift-online:mainfrom
JGiola:feat/use-redhat-openshell-images

Conversation

@JGiola

@JGiola JGiola commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

This PR is for using Red Hat images instead of the OpenShell upstream project ones.

It also remove image references in code to avoid having images defined there, now they are required to be set as env variables or inside the gatewayconfig resource.

Right now we will not set MintMaker to update the image until we will have a way to test the full compatibility with the new gateway/supervisor version with more testing.

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Team

Run ID: b95dda54-a6c3-475e-842d-00e6222a9344

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@JGiola
JGiola force-pushed the feat/use-redhat-openshell-images branch from 26e26c9 to 457f787 Compare August 26, 2026 09:56
@JGiola
JGiola marked this pull request as ready for review August 26, 2026 12:57
@JGiola JGiola added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 26, 2026
@JGiola

JGiola commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator Author

Put on hold for engaging with the opendatahub team for solving some open points with the new images.

@JGiola
JGiola force-pushed the feat/use-redhat-openshell-images branch from 457f787 to dc740d8 Compare August 27, 2026 08:18
@JGiola JGiola removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 27, 2026
@JGiola

JGiola commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator Author

Put on hold for engaging with the opendatahub team for solving some open points with the new images.

I didn't see that semver tags were already pushed and available with our concerns already addressed. Removing the on-hold labels

@jsell-rh

jsell-rh commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Amber review

Status: Complete

Verdict

COMMENT (approve-leaning). The core change is sound and convention-aligned: it removes hard-coded upstream ghcr.io/nvidia/openshell image defaults from Go code, resolves gateway/supervisor images from GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE (with an explicit error when neither config nor env is set), and pins the Red Hat images in the base deploy overlay. No blockers or security issues; the findings below are documentation/spec drift and one process-breaking skill inconsistency that should be fixed before merge.

Hi, Amber here. I loaded CLAUDE.md, the security and control-plane conventions specs, and the review guidance, then reviewed the diff against main and cross-checked the other open PRs for coordination issues.

What this PR does well

  • Config over code. Deleting defaultGatewayImage/defaultSupervisorImage and sourcing them from env/GatewayConfig matches the "separate configuration from code" and "image references must match across the stack" conventions. The pins now live in deploy/base/controller.yaml, scripts/kind/lib.sh, and the specs.
  • Proper error handling. manifests.go uses cmp.Or(...) and returns an explicit errors.New(...) when no image is resolvable; the caller in reconciler.go:722 wraps it with fmt.Errorf("apply substitutions for %s: %w", ...). No panic(), no swallowed errors.
  • Test guarantee preserved. The one modified assertion in validation_test.go:16 keeps wantErr: false and still exercises the multi-segment-path/digest regex path - it is not a weakened guarantee, just a new example string.

Findings

1. [Major - Spec Consistency] update-openshell skill now points at consts that no longer exist.
skills/tooling/update-openshell/SKILL.md still declares the "authoritative current version is the pair of consts in config.go: defaultGatewayImage/defaultSupervisorImage" and lists config.go as the "Source of truth - change here first" (L41-L66). This PR deletes those consts. Following the skill after this merge will fail (the grep finds nothing) and the real pins - now in deploy/base/controller.yaml env and scripts/kind/lib.sh - are not in the footprint table. This is the workflow the repo uses to bump OpenShell versions; it will silently drift. Update the "Source of truth" section and footprint table to point at the deploy overlay env vars.

2. [Major - Spec Consistency] Specs still advertise built-in defaults the code no longer provides.
specs/platform/data-model.spec.md:202 and specs/platform/openshell-gateway.spec.md:674,798-799 document image/supervisor_image as optional fields with a code default. After this change DefaultGatewayImage()/DefaultSupervisorImage() return "", and ApplyManifestToNamespace errors out unless the deployment sets the env vars or the Gateway sets the field. The out-of-box default is satisfied by deploy/base/controller.yaml, but the "No / default" spec columns now overstate the guarantee: a control-plane deployed without those env vars (any overlay that doesn't inherit the base env) will fail provisioning. Please reword the specs to say the default is supplied by the control-plane deployment env, not the field itself. (Related: the misconfig error is returned as a generic error and will be retried as if transient rather than marking the Gateway Failed - see inline note.)

3. [Minor - Docs] ibm-cluster skill: broken JSON in the gateway-create example.
skills/deploy/ibm-cluster/SKILL.md:434 - the supervisor_image value is missing its closing quote and trailing comma, so the curl -d '{...}' body is now invalid JSON.

4. [Minor - Docs] ibm-cluster skill: supervisor mirror uses the gateway digest.
skills/deploy/ibm-cluster/SKILL.md:389 copies odh-openshell-supervisor:v0.0.109-rhaiv.0@sha256:a80b79e5... - that digest is the gateway digest. The supervisor digest is sha256:96e21135... per deploy/base/controller.yaml:52. A digest-pinned skopeo copy against the supervisor repo with the gateway digest will pull the wrong content or fail.

5. [Minor - Docs] Typo odh-openshell-gatway (missing "e").
specs/platform/openshell-gateway.spec.md:194,382,425,832 all read odh-openshell-gatway. Correct is odh-openshell-gateway (as used consistently elsewhere in the PR).

6. [Minor - Docs] Stale/self-contradictory "GHCR image tag convention" note.
specs/platform/openshell-gateway.spec.md:382 still says OpenShell images "on GHCR use commit-SHA tags only (no semver tags)" while giving a quay.io semver example and asserting it "corresponds to v0.0.91" (the tag is v0.0.109). Given the PR title ("use semver version") this paragraph should be rewritten for the quay.io/semver reality.

Cross-PR coordination

I listed all currently open PRs against openshift-online/hypershell and compared goals, ownership, data models, and change order with this PR.

Open PRs at review time: #216, #214, #212, #211, #210, #209, #208, #207, #206, #201 (this), #200, #194, #189, #188, #185, #182, #179, #151, #150, #148, #135, #109, #75, #73.

Material conflict - #194 feat(control-plane): adopt upstream OpenShell Helm chart for gateway deployments. This is a genuine design-level collision, not a mere file overlap:

Coordination - #148 docs(specs): add OpenShell branch build spec. #148 introduces a new first-class sandbox_image Gateway field (peer to image/supervisor_image) defaulting to the community base, explicitly to "close the gap where the sandbox default_image is currently hardcoded." This PR leaves defaultSandboxImage hardcoded in config.go while removing the gateway/supervisor code defaults - so the two PRs move the sandbox image in different directions, and both edit the same field tables in specs/platform/data-model.spec.md and specs/platform/openshell-gateway.spec.md. Decision needed: agree on one direction for the sandbox image (keep code default vs. promote to a configurable field) and align the shared spec field tables.

No material conflict found with the remaining open PRs (#211/#150 touch Kind/local-dev but different keys/files; the rest are UI, auth, e2e, docs, or dependency bumps with no competing interface or ordering dependency on this change).

Findings Summary (ordered by severity, highest first)

  1. [Major] update-openshell skill still names deleted config.go consts as the source of truth; deploy-env pins not added to footprint - Spec Consistency (update-openshell/SKILL.md L41-L66)
  2. [Major] Specs advertise image/supervisor_image built-in defaults the code no longer provides (now required unless env/config set) - Spec Consistency (data-model.spec.md L202, openshell-gateway.spec.md L674, L798-799)
  3. [Minor] Broken JSON in ibm-cluster gateway-create example - Docs (ibm-cluster/SKILL.md L434)
  4. [Minor] Supervisor mirror copy uses the gateway digest - Docs (ibm-cluster/SKILL.md L389)
  5. [Minor] Typo odh-openshell-gatway - Docs (openshell-gateway.spec.md L194, L382, L425, L832)
  6. [Minor] Stale/contradictory GHCR tag-convention note - Docs (openshell-gateway.spec.md L382)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass
errors.IsNotFound/error propagation on reconcile paths Pass
No secrets in logs or responses Pass
Reconcile pattern (not create-or-skip) Pass
Image references consistent across manifests Fail (supervisor digest + typo drift in docs)
Configuration separate from code Pass
Test Diff Scrutiny (modified assertions) Pass
Specs consistent with code Fail (defaults documented but removed)
Conventional commit messages Pass

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

COMMENT (approve-leaning). The core change is sound and convention-aligned: it removes hard-coded upstream ghcr.io/nvidia/openshell image defaults from Go code, resolves gateway/supervisor images from GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE (with an explicit error when neither config nor env is set), and pins the Red Hat images in the base deploy overlay. No blockers or security issues; the findings below are documentation/spec drift and one process-breaking skill inconsistency that should be fixed before merge.

Hi, Amber here. I loaded CLAUDE.md, the security and control-plane conventions specs, and the review guidance, then reviewed the diff against main and cross-checked the other open PRs for coordination issues.

What this PR does well

  • Config over code. Deleting defaultGatewayImage/defaultSupervisorImage and sourcing them from env/GatewayConfig matches the "separate configuration from code" and "image references must match across the stack" conventions. The pins now live in deploy/base/controller.yaml, scripts/kind/lib.sh, and the specs.
  • Proper error handling. manifests.go uses cmp.Or(...) and returns an explicit errors.New(...) when no image is resolvable; the caller in reconciler.go:722 wraps it with fmt.Errorf("apply substitutions for %s: %w", ...). No panic(), no swallowed errors.
  • Test guarantee preserved. The one modified assertion in validation_test.go:16 keeps wantErr: false and still exercises the multi-segment-path/digest regex path - it is not a weakened guarantee, just a new example string.

Findings

1. [Major - Spec Consistency] update-openshell skill now points at consts that no longer exist.
skills/tooling/update-openshell/SKILL.md still declares the "authoritative current version is the pair of consts in config.go: defaultGatewayImage/defaultSupervisorImage" and lists config.go as the "Source of truth - change here first" (L41-L66). This PR deletes those consts. Following the skill after this merge will fail (the grep finds nothing) and the real pins - now in deploy/base/controller.yaml env and scripts/kind/lib.sh - are not in the footprint table. This is the workflow the repo uses to bump OpenShell versions; it will silently drift. Update the "Source of truth" section and footprint table to point at the deploy overlay env vars.

2. [Major - Spec Consistency] Specs still advertise built-in defaults the code no longer provides.
specs/platform/data-model.spec.md:202 and specs/platform/openshell-gateway.spec.md:674,798-799 document image/supervisor_image as optional fields with a code default. After this change DefaultGatewayImage()/DefaultSupervisorImage() return "", and ApplyManifestToNamespace errors out unless the deployment sets the env vars or the Gateway sets the field. The out-of-box default is satisfied by deploy/base/controller.yaml, but the "No / default" spec columns now overstate the guarantee: a control-plane deployed without those env vars (any overlay that doesn't inherit the base env) will fail provisioning. Please reword the specs to say the default is supplied by the control-plane deployment env, not the field itself. (Related: the misconfig error is returned as a generic error and will be retried as if transient rather than marking the Gateway Failed - see inline note.)

3. [Minor - Docs] ibm-cluster skill: broken JSON in the gateway-create example.
skills/deploy/ibm-cluster/SKILL.md:434 - the supervisor_image value is missing its closing quote and trailing comma, so the curl -d '{...}' body is now invalid JSON.

4. [Minor - Docs] ibm-cluster skill: supervisor mirror uses the gateway digest.
skills/deploy/ibm-cluster/SKILL.md:389 copies odh-openshell-supervisor:v0.0.109-rhaiv.0@sha256:a80b79e5... - that digest is the gateway digest. The supervisor digest is sha256:96e21135... per deploy/base/controller.yaml:52. A digest-pinned skopeo copy against the supervisor repo with the gateway digest will pull the wrong content or fail.

5. [Minor - Docs] Typo odh-openshell-gatway (missing "e").
specs/platform/openshell-gateway.spec.md:194,382,425,832 all read odh-openshell-gatway. Correct is odh-openshell-gateway (as used consistently elsewhere in the PR).

6. [Minor - Docs] Stale/self-contradictory "GHCR image tag convention" note.
specs/platform/openshell-gateway.spec.md:382 still says OpenShell images "on GHCR use commit-SHA tags only (no semver tags)" while giving a quay.io semver example and asserting it "corresponds to v0.0.91" (the tag is v0.0.109). Given the PR title ("use semver version") this paragraph should be rewritten for the quay.io/semver reality.

Cross-PR coordination

I listed all currently open PRs against openshift-online/hypershell and compared goals, ownership, data models, and change order with this PR.

Open PRs at review time: #216, #214, #212, #211, #210, #209, #208, #207, #206, #201 (this), #200, #194, #189, #188, #185, #182, #179, #151, #150, #148, #135, #109, #75, #73.

Material conflict - #194 feat(control-plane): adopt upstream OpenShell Helm chart for gateway deployments. This is a genuine design-level collision, not a mere file overlap:

  • #194 deletes components/control-plane/internal/gateway/manifests.go in its entirety and replaces the static-YAML placeholder-substitution model (IMAGE_PLACEHOLDER/SUPERVISOR_IMAGE_PLACEHOLDER in ApplyManifestToNamespace) with a Helm-chart deployment (internal/helm/values.go, helm_deploy.go). The exact function this PR edits (ApplyManifestToNamespace, adding cmp.Or + error-on-empty) is removed by #194.
  • Both PRs edit the same config.go image-default lines in opposite directions: this PR removes defaultGatewayImage/defaultSupervisorImage; #194 keeps them and repoints defaultGatewayImage at a personal dev registry (quay.io/bsquizza/openshell-gateway:16112bc) with a mismatched supervisor tag. The two encode incompatible philosophies for image resolution (env-only vs. code const).
  • Both also touch scripts/kind/lib.sh (GATEWAY_IMAGE default) and specs/platform/openshell-gateway.spec.md.
  • Decision needed: maintainers should sequence these and decide whether the env-only image resolution (this PR) carries into #194's Helm values mapping, and reconcile the Red Hat image pins vs. #194's dev-registry defaults. Whichever merges second must be reworked, not auto-merged.

Coordination - #148 docs(specs): add OpenShell branch build spec. #148 introduces a new first-class sandbox_image Gateway field (peer to image/supervisor_image) defaulting to the community base, explicitly to "close the gap where the sandbox default_image is currently hardcoded." This PR leaves defaultSandboxImage hardcoded in config.go while removing the gateway/supervisor code defaults - so the two PRs move the sandbox image in different directions, and both edit the same field tables in specs/platform/data-model.spec.md and specs/platform/openshell-gateway.spec.md. Decision needed: agree on one direction for the sandbox image (keep code default vs. promote to a configurable field) and align the shared spec field tables.

No material conflict found with the remaining open PRs (#211/#150 touch Kind/local-dev but different keys/files; the rest are UI, auth, e2e, docs, or dependency bumps with no competing interface or ordering dependency on this change).

Findings Summary (ordered by severity, highest first)

  1. [Major] update-openshell skill still names deleted config.go consts as the source of truth; deploy-env pins not added to footprint - Spec Consistency (update-openshell/SKILL.md L41-L66)
  2. [Major] Specs advertise image/supervisor_image built-in defaults the code no longer provides (now required unless env/config set) - Spec Consistency (data-model.spec.md L202, openshell-gateway.spec.md L674, L798-799)
  3. [Minor] Broken JSON in ibm-cluster gateway-create example - Docs (ibm-cluster/SKILL.md L434)
  4. [Minor] Supervisor mirror copy uses the gateway digest - Docs (ibm-cluster/SKILL.md L389)
  5. [Minor] Typo odh-openshell-gatway - Docs (openshell-gateway.spec.md L194, L382, L425, L832)
  6. [Minor] Stale/contradictory GHCR tag-convention note - Docs (openshell-gateway.spec.md L382)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass
errors.IsNotFound/error propagation on reconcile paths Pass
No secrets in logs or responses Pass
Reconcile pattern (not create-or-skip) Pass
Image references consistent across manifests Fail (supervisor digest + typo drift in docs)
Configuration separate from code Pass
Test Diff Scrutiny (modified assertions) Pass
Specs consistent with code Fail (defaults documented but removed)
Conventional commit messages Pass

Comment thread components/control-plane/internal/gateway/config.go
Comment thread components/control-plane/internal/gateway/manifests.go
{name: "bare name with tag", ref: "postgres:18", wantErr: false},
{name: "docker hub library path", ref: "docker.io/library/postgres:18", wantErr: false},
{name: "ghcr multi-segment path with tag", ref: "ghcr.io/nvidia/openshell/gateway:0.0.101", wantErr: false},
{name: "ghcr multi-segment path with tag", ref: "quay.io/opendatahub/odh-openshell-gateway:v0.0.109-rhaiv.0@sha256:a80b79e514826e8d57ea137749cf18a6e7f3d92e26bfefe005f3a9c4a55b8bdd", wantErr: false},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assertion still wantErr: false, so the guarantee is preserved - no concern there. Minor: the case is still named "ghcr multi-segment path with tag" but the ref is now a quay.io digest reference. Rename for accuracy.

Comment thread deploy/base/controller.yaml
@@ -44,8 +44,8 @@ The **authoritative** current version is the pair of consts in
`components/control-plane/internal/gateway/config.go`:

```go

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] This "Source of truth" block and the footprint row at L66 reference defaultGatewayImage/defaultSupervisorImage in config.go, which this PR removes. The version-bump workflow will break (grep finds nothing) and the real pins in deploy/base/controller.yaml + scripts/kind/lib.sh are not listed. Update the source-of-truth and footprint table.

Comment thread skills/deploy/ibm-cluster/SKILL.md Outdated
docker://quay.io/opendatahub/odh-openshell-gateway:v0.0.109-rhaiv.0@sha256:a80b79e514826e8d57ea137749cf18a6e7f3d92e26bfefe005f3a9c4a55b8bdd docker://$REG/openshift/openshell-gateway:v0.0.109-rhaiv.0
skopeo copy --dest-tls-verify=false --dest-creds "pusher:$(oc -n hypershell create token pusher)" \
docker://ghcr.io/nvidia/openshell/supervisor:0.0.109 docker://$REG/openshift/openshell-supervisor:0.0.109
docker://quay.io/opendatahub/odh-openshell-supervisor:v0.0.109-rhaiv.0@sha256:a80b79e514826e8d57ea137749cf18a6e7f3d92e26bfefe005f3a9c4a55b8bdd docker://$REG/openshift/openshell-supervisor:v0.0.109-rhaiv.0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] This copies the supervisor image but pins @sha256:a80b79e5..., which is the gateway digest. The supervisor digest is sha256:96e21135... (see deploy/base/controller.yaml:52). A digest-pinned copy with the wrong digest pulls the wrong content or fails.

Comment thread skills/deploy/ibm-cluster/SKILL.md Outdated
"image":"image-registry.openshift-image-registry.svc:5000/openshift/openshell-gateway:0.0.109",
"supervisor_image":"image-registry.openshift-image-registry.svc:5000/openshift/openshell-supervisor:0.0.109",
"image":"image-registry.openshift-image-registry.svc:5000/openshift/openshell-gateway:v0.0.109-rhaiv.0",
"supervisor_image":"image-registry.openshift-image-registry.svc:5000/openshift/openshell-supervisor:v0.0.109-rhaiv.0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] Broken JSON: the supervisor_image value is missing its closing quote and trailing comma, so the curl -d '{...}' payload is now invalid.

- AND the Gateway SHALL not be reconciled until the configuration is corrected

> **GHCR image tag convention:** OpenShell gateway images on GHCR use commit-SHA tags only (no semver tags). For example, `ghcr.io/nvidia/openshell/gateway:21da343c9f838bd9ac85dc61bf44889de1a72873` corresponds to v0.0.91. The GatewayReconciler continuously reconciles the image field, so the gitops overlay must be the source of truth for the image tag - manual image changes on the Deployment will be reverted.
> **GHCR image tag convention:** OpenShell gateway images on GHCR use commit-SHA tags only (no semver tags). For example, `quay.io/opendatahub/odh-openshell-gatway:v0.0.109-rhaiv.0@sha256:a80b79e514826e8d57ea137749cf18a6e7f3d92e26bfefe005f3a9c4a55b8bdd` corresponds to v0.0.91. The GatewayReconciler continuously reconciles the image field, so the gitops overlay must be the source of truth for the image tag - manual image changes on the Deployment will be reverted.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] Two issues on this line: (1) typo odh-openshell-gatway (missing "e", also at L194/L425/L832); (2) the note says GHCR images "use commit-SHA tags only (no semver tags)" and "corresponds to v0.0.91", but the example is now a quay.io semver tag v0.0.109-rhaiv.0. Rewrite for the quay.io/semver reality (the PR title even says "use semver version").

Comment thread specs/platform/data-model.spec.md
@jsell-rh

jsell-rh commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

Verdict

COMMENT. This PR cleanly shifts gateway/supervisor image selection out of hardcoded Go constants and into deploy-time configuration (env vars on the control-plane deployment or the Gateway resource fields), replacing the ghcr.io/nvidia OpenShell images with digest-pinned Red Hat quay images. The design is sound and aligns with the "separate configuration from code" convention; I found only minor issues (a stale path in the update tooling doc, a second source of truth for the sandbox image, and a documented-but-breaking upgrade edge) plus one cross-PR coordination item.

What's good

  • Fail-loud behavior in manifests.go: when neither the Gateway field nor the env-var default resolves an image, ApplyManifestToNamespace returns an explicit error instead of substituting an empty string into the manifest. No panic(), error is returned to the caller.
  • Image references are consistent across the stack: the v0.0.109-rhaiv.0@sha256:a80b... gateway digest and ...supervisor...@sha256:96e2... digest match across deploy/base/controller.yaml, scripts/kind/lib.sh, the specs, and validation_test.go.
  • The modified assertion in validation_test.go only swaps the sample ref (tag -> digest) while keeping wantErr: false; no test guarantee was removed or inverted.
  • Specs and the env-var reference table are updated to reflect the new required GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE variables.

Findings

[Minor] Stale path in the update-openshell skillskills/tooling/update-openshell/SKILL.md (L43-44, L72) now names the source-of-truth file as components/control-plane/deploy/base/controller.yaml, but the file this PR actually edits is the top-level deploy/base/controller.yaml. The spec files in this same PR use the correct deploy/base/controller.yaml path. Since this skill is the maintainer's runbook for exactly this bump, the wrong path will misdirect the next version update.

[Minor] Second source of truth for the sandbox imagedeploy/base/controller.yaml (L53-54) hardcodes GATEWAY_SANDBOX_IMAGE to the same ghcr.io/nvidia/openshell-community/sandboxes/base:latest value that is still the defaultSandboxImage const in config.go. They match today, but two sources will drift. Since DefaultSandboxImage() already falls back to that const, the base env var is redundant unless the intent is to make it the canonical pin (in which case the const should be trimmed the way the gateway/supervisor consts were).

[Minor] Documented but breaking for non-base deployments — removing the constants makes DefaultGatewayImage()/DefaultSupervisorImage() return "" when the env vars are unset, so any control-plane rollout that does not layer over deploy/base (and does not set the Gateway image/supervisor_image fields) will start failing gateway provisioning after upgrade. This is intentional and is called out in the update-openshell skill, and GitOps overlays inherit the base env vars, so the exposure is limited. Worth a one-line note in the PR body / release notes so operators of bespoke manifests add the two env vars before upgrading.

Cross-PR coordination

An open pull request proposes replacing the static-YAML + placeholder-substitution gateway deployment mechanism (the ApplyManifestToNamespace string-replace path and the IMAGE_PLACEHOLDER/SUPERVISOR_IMAGE_PLACEHOLDER markers) with runtime Helm-chart installation, mapping the Gateway resource fields into Helm values. That PR and this one make directly incompatible decisions about the same image-resolution code:

  • This PR deletes the defaultGatewayImage/defaultSupervisorImage constants and makes image defaults env-var-only; the other PR keeps those constants (and repoints them at a different, fork-based registry ref) as the source of truth.
  • This PR adds error handling inside ApplyManifestToNamespace; the other PR removes that function entirely in favor of a Helm values mapping.
  • The two PRs declare different sources of truth for the deployed image (controller-deployment env vars here vs. code constants + Helm chart references there) and different target registries.

Maintainers need to decide which image-configuration model wins and in what order these merge. If the Helm-adoption PR lands first, the env-var-only image defaults and the "controller.yaml is the source of truth" contract from this PR must be re-wired into the Helm values path; if this PR lands first, the other must drop the reintroduced constants and route images through the env vars. Please coordinate the ownership of image resolution and the merge order before either lands. See #194.

Findings Summary (ordered by severity, highest first)

  1. [Minor] Stale source-of-truth path in the update-openshell skill (components/control-plane/deploy/base/... vs top-level deploy/base/...) — Spec/Docs Accuracy (SKILL.md L44, L72)
  2. [Minor] GATEWAY_SANDBOX_IMAGE in base manifest duplicates the defaultSandboxImage const (two sources of truth) — Config Consistency (controller.yaml L53)
  3. [Minor] Env-var-only image defaults are a documented breaking change for control planes not layered over deploy/baseMigration/Compatibility (config.go L42-49)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors returned with context (no silent empty-image substitution) Pass
Config separated from code Pass
Image references consistent across the stack Pass
Test Diff Scrutiny (no inverted/removed guarantees) Pass
Conventional commit messages Pass

@jsell-rh

jsell-rh commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

Verdict

This PR cleanly moves the gateway/supervisor image pins out of hardcoded Go constants and into required GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE env vars (with the per-Gateway image/supervisor_image still taking precedence), and adds a fail-fast when neither a config value nor an env default is available. The change is well-scoped and consistent across code, manifests, specs, and skills; I have one operability suggestion and a cross-PR coordination item, but nothing blocking.

What I verified

  • Config-over-code alignment. Removing defaultGatewayImage/defaultSupervisorImage and reading os.Getenv(...) matches the "Separate configuration from code" convention. The digest pins now live in deploy/base/controller.yaml, and the kind, openshift, and ibm overlays all resources: [../base] and add to the controller env via strategic-merge patch rather than replacing it, so the required vars are inherited on every standard deploy path. Good.
  • Image consistency across the stack. The gateway digest (sha256:a80b79...) and supervisor digest (sha256:96e211...) match across deploy/base/controller.yaml, scripts/kind/lib.sh, the ibm-cluster skill, and the platform specs. The remaining ghcr.io/nvidia/openshell/... and bare 0.0.109 strings are the intentional regex fixture in validation_test.go and historical/illustrative references the update-openshell skill explicitly says not to touch.
  • Error handling. ApplyManifestToNamespace returns a plain errors.New(...) sentinel (no wrapped cause, which is fine here) and the caller wraps it with fmt.Errorf("apply substitutions for %s: %w", ...). No panic(), correct %w propagation.
  • Test diff scrutiny. The validation_test.go change is additive: the existing ghcr case still asserts wantErr: false (only the tag string changed), and a new digest-pinned quay case is added. No pre-existing guarantee was flipped or removed.

Findings

[Minor] Required env vars are only validated deep in the per-gateway reconcile loop. GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE are now effectively required for the controller to provision any gateway, but a missing value only surfaces inside ApplyManifestToNamespace when the first gateway is reconciled, and then re-errors on every retry. Consider validating their presence once at controller startup (cmd/hypershell-controller/main.go) so a misconfigured deployment fails fast and unambiguously instead of appearing healthy until a tenant gateway is created. The default gitops path is covered by deploy/base, so this is robustness, not a defect. Confidence: Medium.

[Minor] Comment nits in config.go. The trimmed doc comments ("Set via GATEWAY_IMAGE" / "Set via GATEWAY_SUPERVISOR_IMAGE") lost their trailing periods and no longer state the now-important behavior that an unset var yields an empty string that the caller rejects. A one-line note would help the next reader. Confidence: High.

Cross-PR coordination

The open PR that adopts the upstream OpenShell Helm chart for gateway deployments makes a directly competing design choice for the same ownership area this PR changes: gateway/supervisor image defaults and injection. That PR keeps defaultGatewayImage/defaultSupervisorImage as hardcoded constants in components/control-plane/internal/gateway/config.go (repointing them to a different registry/tag) and replaces the manifests.go IMAGE_PLACEHOLDER/SUPERVISOR_IMAGE_PLACEHOLDER substitution with Helm values, whereas this PR deletes those constants entirely and makes the images resolve solely from env vars, with a fail-fast in ApplyManifestToNamespace. These two approaches cannot both land as-is: maintainers need to decide whether image resolution is env-var-driven (this PR) or constant/Helm-values-driven, agree on the merge order, and ensure the winning image-default model is carried into the Helm values path. This requires a maintainer decision and coordination between the two authors.

Findings Summary

  1. [Minor] Required image env vars validated only at reconcile time, not controller startup - Operability (config.go L42-49, manifests.go L91-105)
  2. [Minor] config.go doc-comment nits for the new env-var-only resolution - Docs (config.go L40-49)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass
No secrets in logs or responses Pass
Image references consistent across the stack Pass
Separate configuration from code Pass
Reconcile pattern (not create-or-skip) Pass
Test diff scrutiny (no silently flipped assertions) Pass

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

This PR cleanly moves the gateway/supervisor image pins out of hardcoded Go constants and into required GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE env vars (with the per-Gateway image/supervisor_image still taking precedence), and adds a fail-fast when neither a config value nor an env default is available. The change is well-scoped and consistent across code, manifests, specs, and skills; I have one operability suggestion and a cross-PR coordination item, but nothing blocking.

What I verified

  • Config-over-code alignment. Removing defaultGatewayImage/defaultSupervisorImage and reading os.Getenv(...) matches the "Separate configuration from code" convention. The digest pins now live in deploy/base/controller.yaml, and the kind, openshift, and ibm overlays all resources: [../base] and add to the controller env via strategic-merge patch rather than replacing it, so the required vars are inherited on every standard deploy path. Good.
  • Image consistency across the stack. The gateway digest (sha256:a80b79...) and supervisor digest (sha256:96e211...) match across deploy/base/controller.yaml, scripts/kind/lib.sh, the ibm-cluster skill, and the platform specs. The remaining ghcr.io/nvidia/openshell/... and bare 0.0.109 strings are the intentional regex fixture in validation_test.go and historical/illustrative references the update-openshell skill explicitly says not to touch.
  • Error handling. ApplyManifestToNamespace returns a plain errors.New(...) sentinel (no wrapped cause, which is fine here) and the caller wraps it with fmt.Errorf("apply substitutions for %s: %w", ...). No panic(), correct %w propagation.
  • Test diff scrutiny. The validation_test.go change is additive: the existing ghcr case still asserts wantErr: false (only the tag string changed), and a new digest-pinned quay case is added. No pre-existing guarantee was flipped or removed.

Findings

[Minor] Required env vars are only validated deep in the per-gateway reconcile loop. GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE are now effectively required for the controller to provision any gateway, but a missing value only surfaces inside ApplyManifestToNamespace when the first gateway is reconciled, and then re-errors on every retry. Consider validating their presence once at controller startup (cmd/hypershell-controller/main.go) so a misconfigured deployment fails fast and unambiguously instead of appearing healthy until a tenant gateway is created. The default gitops path is covered by deploy/base, so this is robustness, not a defect. Confidence: Medium.

[Minor] Comment nits in config.go. The trimmed doc comments ("Set via GATEWAY_IMAGE" / "Set via GATEWAY_SUPERVISOR_IMAGE") lost their trailing periods and no longer state the now-important behavior that an unset var yields an empty string that the caller rejects. A one-line note would help the next reader. Confidence: High.

Cross-PR coordination

The open PR that adopts the upstream OpenShell Helm chart for gateway deployments makes a directly competing design choice for the same ownership area this PR changes: gateway/supervisor image defaults and injection. That PR keeps defaultGatewayImage/defaultSupervisorImage as hardcoded constants in components/control-plane/internal/gateway/config.go (repointing them to a different registry/tag) and replaces the manifests.go IMAGE_PLACEHOLDER/SUPERVISOR_IMAGE_PLACEHOLDER substitution with Helm values, whereas this PR deletes those constants entirely and makes the images resolve solely from env vars, with a fail-fast in ApplyManifestToNamespace. These two approaches cannot both land as-is: maintainers need to decide whether image resolution is env-var-driven (this PR) or constant/Helm-values-driven, agree on the merge order, and ensure the winning image-default model is carried into the Helm values path. This requires a maintainer decision and coordination between the two authors.

Findings Summary

  1. [Minor] Required image env vars validated only at reconcile time, not controller startup - Operability (config.go L42-49, manifests.go L91-105)
  2. [Minor] config.go doc-comment nits for the new env-var-only resolution - Docs (config.go L40-49)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass
No secrets in logs or responses Pass
Image references consistent across the stack Pass
Separate configuration from code Pass
Reconcile pattern (not create-or-skip) Pass
Test diff scrutiny (no silently flipped assertions) Pass

Comment thread components/control-plane/internal/gateway/config.go
Comment thread components/control-plane/internal/gateway/manifests.go
@jsell-rh

jsell-rh commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

Verdict

COMMENT. This is a focused, well-scoped switch from the upstream ghcr.io/nvidia/openshell/* images to the Red Hat quay.io/opendatahub/odh-openshell-* builds, and it correctly moves the image pin out of code and into deployment configuration (config-separate-from-code). Two things need attention before merge: an image-tag drift between the ROKS e2e script and the mirroring instructions, and the fact that the gateway/supervisor images are now hard-required env vars with no fallback, which is only validated deep in the per-gateway reconcile path.

Summary

The change removes the defaultGatewayImage/defaultSupervisorImage constants, resolves both images from GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE (empty → reconcile error), pins the new digests in deploy/base/controller.yaml, and updates specs/skills so deploy/base/controller.yaml becomes the source of truth. Error handling is clean (errors.New, no panic(), error is wrapped and propagated by the reconciler), the digest pins are internally consistent across the base manifest, specs, kind lib, and the ibm-cluster skill, and the cmp.Or refactor is idiomatic.

Findings

1. [Major] Image-tag drift between the ROKS e2e script and the mirror instructionsImage consistency
components/pr-test/e2e-openshell-roks.sh:67-68 defaults the mirrored refs to openshell-gateway:0.0.109-rhaiv.0 / openshell-supervisor:0.0.109-rhaiv.0 (no v prefix), but skills/deploy/ibm-cluster/SKILL.md:387-389,455-456 mirrors and consumes those same internal-registry images as v0.0.109-rhaiv.0 (with the v). A ROKS e2e run that has to create a gateway would request a tag that the documented mirroring step never produced, yielding ImagePullBackOff. Pick one tag convention (the upstream quay tag carries the v, so v0.0.109-rhaiv.0 is the natural choice) and align both files. Confidence: High.

2. [Major] Gateway/supervisor images are now hard-required with no fallback, validated only at per-gateway reconcile timeReconciliation / optional→required
config.go:43-52 now returns the bare os.Getenv(...) value, and manifests.go:92-94,103-105 fails reconciliation with "... image is not configured and no default is available" when it is empty. This turns a previously-optional setting into a required one with no code fallback and no backfill. It is coordinated in-PR via deploy/base/controller.yaml, but only the base overlay sets these vars — a control plane rolled out with just a new image (env vars not re-applied), or any deployment path that does not inherit base, will silently stop provisioning gateways and only surface the failure once a specific Gateway is reconciled. Recommend validating both env vars at controller startup (fail-fast with a clear message) so a mis-provisioned deployment is caught immediately rather than per-gateway, and calling out the "must set these env vars on upgrade" requirement in the deploy docs. Confidence: Medium.

Findings Summary (ordered by severity, highest first)

  1. [Major] ROKS e2e mirror tag missing the v prefix vs. the ibm-cluster mirror/consume tag — Image consistency (e2e-openshell-roks.sh L67-68)
  2. [Major] Images moved optional→required with no fallback; only validated at reconcile time, not at startup — Reconciliation (config.go L43-52, manifests.go L92-105)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped / returned with context Pass
No secrets in logs or responses Pass
Reconcile pattern (not create-or-skip) Pass
Config separated from code Pass
Image references consistent across the stack Fail
Optional→required change has fallback/backfill Fail
Test diff scrutiny (no silently flipped assertions) Pass
Conventional commit messages Pass

Cross-PR coordination

Another open pull request replaces the gateway deployment mechanism this PR modifies: it deletes components/control-plane/internal/gateway/manifests.go (the placeholder-substitution path this PR edits) and reworks config.go to render gateway images through upstream Helm chart values (image.repository/image.tag, "split at last :"), while keeping hardcoded defaultGatewayImage/defaultSupervisorImage constants pointing at a different registry and pin (quay.io/bsquizza/openshell-gateway:16112bc). This directly conflicts with this PR's core decisions: (a) which image-resolution mechanism wins (placeholder substitution vs Helm values), (b) whether hardcoded default constants exist at all vs. env-var-required-with-no-fallback, (c) the canonical registry and source-of-truth pin (and the update-openshell skill text both PRs rewrite differently), and (d) a Helm "split at last :" mapping would mis-parse the digest-pinned ...:v0.0.109-rhaiv.0@sha256:... references this PR mandates. Maintainers should decide which approach lands first and reconcile the image-defaulting contract and source-of-truth before merging either; that PR is #194.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

COMMENT. This is a focused, well-scoped switch from the upstream ghcr.io/nvidia/openshell/* images to the Red Hat quay.io/opendatahub/odh-openshell-* builds, and it correctly moves the image pin out of code and into deployment configuration (config-separate-from-code). Two things need attention before merge: an image-tag drift between the ROKS e2e script and the mirroring instructions, and the fact that the gateway/supervisor images are now hard-required env vars with no fallback, which is only validated deep in the per-gateway reconcile path.

Summary

The change removes the defaultGatewayImage/defaultSupervisorImage constants, resolves both images from GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE (empty → reconcile error), pins the new digests in deploy/base/controller.yaml, and updates specs/skills so deploy/base/controller.yaml becomes the source of truth. Error handling is clean (errors.New, no panic(), error is wrapped and propagated by the reconciler), the digest pins are internally consistent across the base manifest, specs, kind lib, and the ibm-cluster skill, and the cmp.Or refactor is idiomatic.

Findings

1. [Major] Image-tag drift between the ROKS e2e script and the mirror instructionsImage consistency
components/pr-test/e2e-openshell-roks.sh:67-68 defaults the mirrored refs to openshell-gateway:0.0.109-rhaiv.0 / openshell-supervisor:0.0.109-rhaiv.0 (no v prefix), but skills/deploy/ibm-cluster/SKILL.md:387-389,455-456 mirrors and consumes those same internal-registry images as v0.0.109-rhaiv.0 (with the v). A ROKS e2e run that has to create a gateway would request a tag that the documented mirroring step never produced, yielding ImagePullBackOff. Pick one tag convention (the upstream quay tag carries the v, so v0.0.109-rhaiv.0 is the natural choice) and align both files. Confidence: High.

2. [Major] Gateway/supervisor images are now hard-required with no fallback, validated only at per-gateway reconcile timeReconciliation / optional→required
config.go:43-52 now returns the bare os.Getenv(...) value, and manifests.go:92-94,103-105 fails reconciliation with "... image is not configured and no default is available" when it is empty. This turns a previously-optional setting into a required one with no code fallback and no backfill. It is coordinated in-PR via deploy/base/controller.yaml, but only the base overlay sets these vars — a control plane rolled out with just a new image (env vars not re-applied), or any deployment path that does not inherit base, will silently stop provisioning gateways and only surface the failure once a specific Gateway is reconciled. Recommend validating both env vars at controller startup (fail-fast with a clear message) so a mis-provisioned deployment is caught immediately rather than per-gateway, and calling out the "must set these env vars on upgrade" requirement in the deploy docs. Confidence: Medium.

Findings Summary (ordered by severity, highest first)

  1. [Major] ROKS e2e mirror tag missing the v prefix vs. the ibm-cluster mirror/consume tag — Image consistency (e2e-openshell-roks.sh L67-68)
  2. [Major] Images moved optional→required with no fallback; only validated at reconcile time, not at startup — Reconciliation (config.go L43-52, manifests.go L92-105)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped / returned with context Pass
No secrets in logs or responses Pass
Reconcile pattern (not create-or-skip) Pass
Config separated from code Pass
Image references consistent across the stack Fail
Optional→required change has fallback/backfill Fail
Test diff scrutiny (no silently flipped assertions) Pass
Conventional commit messages Pass

Cross-PR coordination

Another open pull request replaces the gateway deployment mechanism this PR modifies: it deletes components/control-plane/internal/gateway/manifests.go (the placeholder-substitution path this PR edits) and reworks config.go to render gateway images through upstream Helm chart values (image.repository/image.tag, "split at last :"), while keeping hardcoded defaultGatewayImage/defaultSupervisorImage constants pointing at a different registry and pin (quay.io/bsquizza/openshell-gateway:16112bc). This directly conflicts with this PR's core decisions: (a) which image-resolution mechanism wins (placeholder substitution vs Helm values), (b) whether hardcoded default constants exist at all vs. env-var-required-with-no-fallback, (c) the canonical registry and source-of-truth pin (and the update-openshell skill text both PRs rewrite differently), and (d) a Helm "split at last :" mapping would mis-parse the digest-pinned ...:v0.0.109-rhaiv.0@sha256:... references this PR mandates. Maintainers should decide which approach lands first and reconcile the image-defaulting contract and source-of-truth before merging either; that PR is #194.

REG_MIRROR="${REG_MIRROR:-image-registry.openshift-image-registry.svc:5000/openshift}"
GW_IMAGE="${GW_IMAGE:-${REG_MIRROR}/openshell-gateway:0.0.109}"
GW_SUPERVISOR_IMAGE="${GW_SUPERVISOR_IMAGE:-${REG_MIRROR}/openshell-supervisor:0.0.109}"
GW_IMAGE="${GW_IMAGE:-${REG_MIRROR}/openshell-gateway:0.0.109-rhaiv.0}"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This defaults the mirrored refs to tag 0.0.109-rhaiv.0 (no v), but skills/deploy/ibm-cluster/SKILL.md mirrors and consumes the same internal-registry images as v0.0.109-rhaiv.0 (with the v). A create-path e2e run would pull a tag that was never mirrored, causing ImagePullBackOff. Align to v0.0.109-rhaiv.0 for both gateway and supervisor.

Comment thread components/control-plane/internal/gateway/config.go
Comment thread components/control-plane/internal/gateway/manifests.go
@JGiola
JGiola force-pushed the feat/use-redhat-openshell-images branch from 54e0a49 to f8334dd Compare August 31, 2026 11:04
@jsell-rh

jsell-rh commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Amber review: changes requested

Amber review

Status: Complete

Verdict

REQUEST_CHANGES. This PR cleanly retargets the gateway/supervisor images from ghcr.io/nvidia to digest-pinned Red Hat quay.io/opendatahub refs and consolidates the version pin into deployment env vars, and the image references are consistent across every manifest, script, and spec. However, removing the in-code fallback constants turns GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE into hard requirements, and the env vars were only added to deploy/base/controller.yaml — the control-plane manifests that the deploy skills actually apply do not set them, so gateway provisioning regresses to a hard failure on those clusters.

Findings

[Blocker] Required image env vars are missing from the deployed control-plane manifests — Reconciliation / optional→required without fallback (High confidence)

config.go:43-51 drops the defaultGatewayImage/defaultSupervisorImage constants so DefaultGatewayImage()/DefaultSupervisorImage() now return a bare os.Getenv(...). Combined with manifests.go:91-104, a gateway whose image/supervisor_image fields are empty (both are optional per specs/platform/openshell-gateway.spec.md) now hard-fails reconciliation with "gateway image is not configured and no default is available".

The env vars were added only to deploy/base/controller.yaml. But the control-plane deployments that the deploy skills actually apply live in a different tree and do not set them:

  • components/api-server/deploy/openshift/controller.yaml — applied by deploy-cluster (oc kustomize deploy/openshift/ | oc apply -f -)
  • components/api-server/deploy/ibm overlay — applied by ibm-cluster (oc kustomize deploy/ibm | oc apply -f -)
  • components/api-server/deploy/kind/controller.yaml — applied by make kind-up

None of these set GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE. So on a real OpenShift/IBM/kind deployment, any Gateway created without explicit image fields will fail to provision — a regression from the previous working default. This is the optional→required-without-fallback pattern: the "old value" (env var absent) already exists in the deployed manifests. The PR's own updated skills/deploy/ibm-cluster/SKILL.md (~line 442) even documents that the default comes from these env vars "on the control-plane deployment," yet the manifests it deploys don't set them.

Fix: add both env vars to components/api-server/deploy/{kind,openshift}/controller.yaml (and confirm the deploy/ibm overlay inherits/overrides them for the mirror), or keep a safe fallback. Ensure whichever control-plane manifest tree is authoritative carries the pin.

Positive notes

  • Image references (including sha256 digests) are consistent across deploy/base/controller.yaml, scripts/kind/lib.sh, the ibm-cluster/update-openshell skills, and all specs.
  • The validation_test.go change is additive: it keeps the existing ghcr case and adds a new digest+tag case; no existing assertion was flipped, so no guarantee was removed.
  • New error paths in manifests.go are wrapped and propagated correctly by the caller (reconciler.go:834-836).

Cross-PR coordination

Another open pull request proposes shifting gateway deployment from the static-manifest renderer to the upstream OpenShell Helm chart. That work deletes components/control-plane/internal/gateway/manifests.go (the file this PR edits to add the required-image error paths) and takes a different image-defaulting stance — it retains hardcoded defaultGatewayImage/defaultSupervisorImage constants pointed at yet another registry/tag (quay.io/bsquizza/..., commit-SHA tags) rather than this PR's env-var-required, digest-pinned quay.io/opendatahub model. These are competing designs for the same subsystem (where the gateway image default lives and how manifests are rendered). Maintainers need to decide which approach wins and the merge order: if the Helm-chart adoption lands, this PR's env-var image contract must be re-expressed as Helm values mapping, and the manifest edits here become moot; if this PR lands first, the Helm work must adopt the env-var/digest model rather than reintroducing constants.

Findings Summary (ordered by severity, highest first)

  1. [Blocker] Required GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE env vars absent from the control-plane manifests the deploy skills apply (components/api-server/deploy/{kind,openshift,ibm}); gateways without explicit image fields fail to provision after the fallback constants were removed - Reconciliation (config.go:43-51, manifests.go:91-104)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped/propagated with context Pass
No secrets in logs or responses Pass
Image references consistent across the stack Pass
Config separate from code Pass
Reconcile fallback/backfill for optional→required change Fail
Test Diff Scrutiny (no silently flipped assertions) Pass
Conventional commit messages Pass

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

REQUEST_CHANGES. This PR cleanly retargets the gateway/supervisor images from ghcr.io/nvidia to digest-pinned Red Hat quay.io/opendatahub refs and consolidates the version pin into deployment env vars, and the image references are consistent across every manifest, script, and spec. However, removing the in-code fallback constants turns GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE into hard requirements, and the env vars were only added to deploy/base/controller.yaml — the control-plane manifests that the deploy skills actually apply do not set them, so gateway provisioning regresses to a hard failure on those clusters.

Findings

[Blocker] Required image env vars are missing from the deployed control-plane manifests — Reconciliation / optional→required without fallback (High confidence)

config.go:43-51 drops the defaultGatewayImage/defaultSupervisorImage constants so DefaultGatewayImage()/DefaultSupervisorImage() now return a bare os.Getenv(...). Combined with manifests.go:91-104, a gateway whose image/supervisor_image fields are empty (both are optional per specs/platform/openshell-gateway.spec.md) now hard-fails reconciliation with "gateway image is not configured and no default is available".

The env vars were added only to deploy/base/controller.yaml. But the control-plane deployments that the deploy skills actually apply live in a different tree and do not set them:

  • components/api-server/deploy/openshift/controller.yaml — applied by deploy-cluster (oc kustomize deploy/openshift/ | oc apply -f -)
  • components/api-server/deploy/ibm overlay — applied by ibm-cluster (oc kustomize deploy/ibm | oc apply -f -)
  • components/api-server/deploy/kind/controller.yaml — applied by make kind-up

None of these set GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE. So on a real OpenShift/IBM/kind deployment, any Gateway created without explicit image fields will fail to provision — a regression from the previous working default. This is the optional→required-without-fallback pattern: the "old value" (env var absent) already exists in the deployed manifests. The PR's own updated skills/deploy/ibm-cluster/SKILL.md (~line 442) even documents that the default comes from these env vars "on the control-plane deployment," yet the manifests it deploys don't set them.

Fix: add both env vars to components/api-server/deploy/{kind,openshift}/controller.yaml (and confirm the deploy/ibm overlay inherits/overrides them for the mirror), or keep a safe fallback. Ensure whichever control-plane manifest tree is authoritative carries the pin.

Positive notes

  • Image references (including sha256 digests) are consistent across deploy/base/controller.yaml, scripts/kind/lib.sh, the ibm-cluster/update-openshell skills, and all specs.
  • The validation_test.go change is additive: it keeps the existing ghcr case and adds a new digest+tag case; no existing assertion was flipped, so no guarantee was removed.
  • New error paths in manifests.go are wrapped and propagated correctly by the caller (reconciler.go:834-836).

Cross-PR coordination

Another open pull request proposes shifting gateway deployment from the static-manifest renderer to the upstream OpenShell Helm chart. That work deletes components/control-plane/internal/gateway/manifests.go (the file this PR edits to add the required-image error paths) and takes a different image-defaulting stance — it retains hardcoded defaultGatewayImage/defaultSupervisorImage constants pointed at yet another registry/tag (quay.io/bsquizza/..., commit-SHA tags) rather than this PR's env-var-required, digest-pinned quay.io/opendatahub model. These are competing designs for the same subsystem (where the gateway image default lives and how manifests are rendered). Maintainers need to decide which approach wins and the merge order: if the Helm-chart adoption lands, this PR's env-var image contract must be re-expressed as Helm values mapping, and the manifest edits here become moot; if this PR lands first, the Helm work must adopt the env-var/digest model rather than reintroducing constants.

Findings Summary (ordered by severity, highest first)

  1. [Blocker] Required GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE env vars absent from the control-plane manifests the deploy skills apply (components/api-server/deploy/{kind,openshift,ibm}); gateways without explicit image fields fail to provision after the fallback constants were removed - Reconciliation (config.go:43-51, manifests.go:91-104)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped/propagated with context Pass
No secrets in logs or responses Pass
Image references consistent across the stack Pass
Config separate from code Pass
Reconcile fallback/backfill for optional→required change Fail
Test Diff Scrutiny (no silently flipped assertions) Pass
Conventional commit messages Pass

Comment thread components/control-plane/internal/gateway/config.go
Comment thread components/control-plane/internal/gateway/manifests.go
@jsell-rh

jsell-rh commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

Verdict

COMMENT — This is a clean, well-scoped migration from the upstream NVIDIA/ghcr OpenShell images to Red Hat (quay.io/opendatahub/odh-openshell-*) images that also removes the hardcoded default image constants and makes GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE explicit control-plane inputs. The code, deployment overlays, and specs are internally consistent, the optional→required transition is backfilled in deploy/base/controller.yaml, and the empty-image case fails with an explicit error (not a panic) that propagates and marks the gateway Failed. My only in-PR note is a minor fail-fast/observability suggestion; the more important output is cross-PR coordination below.

What looks good

  • manifests.go resolves images with cmp.Or(config.X, images.DefaultX()) and returns an explicit error when the result is empty; the error is wrapped by deployGateway/Handle and parks the gateway at Failed — correct terminal-error handling.
  • Image references are consistent across the stack: deploy/base/controller.yaml, scripts/kind/lib.sh, validation_test.go, and the specs all use the same v0.0.109-rhaiv.0@sha256:… digests.
  • Test diff scrutiny: validation_test.go is purely additive (new digest+tag case, a cosmetic version-literal bump) — no removed guarantee.
  • The optional→required image transition is backfilled: deploy/base/controller.yaml sets both env vars, inherited by the kind and openshift overlays.

Findings

  1. [Minor] Observability / fail-fast. DefaultGatewayImage()/DefaultSupervisorImage() now return the raw env var with no fallback, so a control plane started without these env vars only fails at the first tenant-gateway reconcile (gateway image is not configured…), per namespace, rather than at startup. Any overlay not derived from deploy/base (custom/legacy deployments) inherits this latent failure. Consider validating both variables once at controller startup so a misconfiguration surfaces immediately instead of as a per-gateway Failed state. Confidence: High.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

COMMENT — This is a clean, well-scoped migration from the upstream NVIDIA/ghcr OpenShell images to Red Hat (quay.io/opendatahub/odh-openshell-*) images that also removes the hardcoded default image constants and makes GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE explicit control-plane inputs. The code, deployment overlays, and specs are internally consistent, the optional→required transition is backfilled in deploy/base/controller.yaml, and the empty-image case fails with an explicit error (not a panic) that propagates and marks the gateway Failed. My only in-PR note is a minor fail-fast/observability suggestion; the more important output is cross-PR coordination below.

What looks good

  • manifests.go resolves images with cmp.Or(config.X, images.DefaultX()) and returns an explicit error when the result is empty; the error is wrapped by deployGateway/Handle and parks the gateway at Failed — correct terminal-error handling.
  • Image references are consistent across the stack: deploy/base/controller.yaml, scripts/kind/lib.sh, validation_test.go, and the specs all use the same v0.0.109-rhaiv.0@sha256:… digests.
  • Test diff scrutiny: validation_test.go is purely additive (new digest+tag case, a cosmetic version-literal bump) — no removed guarantee.
  • The optional→required image transition is backfilled: deploy/base/controller.yaml sets both env vars, inherited by the kind and openshift overlays.

Findings

  1. [Minor] Observability / fail-fast. DefaultGatewayImage()/DefaultSupervisorImage() now return the raw env var with no fallback, so a control plane started without these env vars only fails at the first tenant-gateway reconcile (gateway image is not configured…), per namespace, rather than at startup. Any overlay not derived from deploy/base (custom/legacy deployments) inherits this latent failure. Consider validating both variables once at controller startup so a misconfiguration surfaces immediately instead of as a per-gateway Failed state. Confidence: High.

Cross-PR coordination

  • #194 (adopt upstream OpenShell Helm chart for gateway deployments): Competing design and change-order conflict for the exact mechanism this PR edits. This PR keeps the static-manifest IMAGE_PLACEHOLDER/SUPERVISOR_IMAGE_PLACEHOLDER substitution and redefines image resolution so GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE are required (empty → error). #194 removes that placeholder-substitution path entirely in favor of Helm values mapping, retains a hardcoded defaultGatewayImage constant fallback, and sets different default pullspecs in both config.go and scripts/kind/lib.sh. Both PRs modify components/control-plane/internal/gateway/config.go, manifests.go, and scripts/kind/lib.sh with incompatible models. Maintainers must decide which image-resolution design wins, the merge order, and whether the Helm values mapping carries forward this PR's "images are required, no built-in default" contract and the Red Hat pullspecs.

  • #227 (per-gateway resource quotas / GatewayProfile): Structural/ownership and change-order conflict. This PR deletes the legacy components/api-server/deploy/{kind,openshift,ibm} trees (consolidating onto the top-level deploy/ tree), while #227 actively extends those same legacy trees with new functional RBAC (resourcequotas/limitranges verbs) and kustomization edits (components/api-server/deploy/openshift/controller-clusterrbac.yaml, .../kind/controller-clusterrbac.yaml, .../{openshift,ibm}/kustomization.yaml). Whichever merges second is broken: #227's grants would land in files this PR removes, or this PR's deletion would drop #227's grants. Maintainers must sequence these and ensure #227's new RBAC is re-homed in the canonical deploy/base RBAC.

  • #210 (reconcile gateway version for CLI installation): Assumption dependency requiring a decision. #210 derives the OpenShell CLI install version by stripping a --prefixed postfix (v0.0.109-rhaiv.0v0.0.109) and installs the client from the NVIDIA/OpenShell main branch, while this PR switches the runtime gateway to the Red Hat odh-openshell-gateway build that produces exactly that -rhaiv.N version string. The postfix-stripping contract is shaped by this PR's tag scheme, and #210 pairs it with an NVIDIA-upstream CLI source. Maintainers should confirm that the Red Hat runtime image is compatible with the NVIDIA-main OpenShell CLI at the stripped version, and that any future change to this PR's tag scheme is reflected in #210's derivation.

Comment on lines 43 to +51
func (StaticImageDefaults) DefaultGatewayImage() string {
if v := os.Getenv("GATEWAY_IMAGE"); v != "" {
return v
}
return defaultGatewayImage
return os.Getenv("GATEWAY_IMAGE")
}

// DefaultSupervisorImage resolves the supervisor sidecar image used when a
// Gateway resource does not specify one. Overridable via GATEWAY_SUPERVISOR_IMAGE
// for the same ghcr.io-unreachable clusters as DefaultGatewayImage.
// Gateway resource does not specify one. Must be set via GATEWAY_SUPERVISOR_IMAGE environment
// variable; reconciliation will fail if not provided.
func (StaticImageDefaults) DefaultSupervisorImage() string {
if v := os.Getenv("GATEWAY_SUPERVISOR_IMAGE"); v != "" {
return v
}
return defaultSupervisorImage
return os.Getenv("GATEWAY_SUPERVISOR_IMAGE")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] Fail-fast on required image env vars. Both resolvers now return the raw env var with no fallback, so a control plane launched without GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE won't fail until the first tenant-gateway reconcile hits the empty-string check in manifests.go and parks that gateway at Failed (repeated per namespace). The canonical deploy/base/controller.yaml backfills both, so this is not a regression for the standard path — but any overlay not derived from base inherits a latent, deferred failure. Consider validating both variables once at controller startup so misconfiguration surfaces immediately with a single clear error. Confidence: High.

Comment thread components/control-plane/internal/gateway/manifests.go
@JGiola
JGiola force-pushed the feat/use-redhat-openshell-images branch from 37bba1e to 4e33502 Compare August 31, 2026 13:34
@jsell-rh

jsell-rh commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

Verdict

This is a clean, well-documented refactor that removes the hardcoded ghcr.io/nvidia/openshell/* image constants and makes the gateway/supervisor image pins configuration-driven (GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE), pointing at Red Hat (quay.io/opendatahub/odh-openshell-*) digest-pinned images. The change is consistent with "separate configuration from code," properly returns errors (no panics) when an image is unconfigured, and the specs + update-openshell source-of-truth were moved in lockstep; the remaining issues are documentation drift and a few stale image references, none blocking.

Summary

The optional→required config change (removing the in-code fallback defaults) is intentional, called out in the PR description, marked *(required)* in the spec, and given both a resource-level fallback (Gateway.image / supervisor_image) and a manifest-level source (deploy/base/controller.yaml sets both env vars, inherited by the openshift/ibm overlays). Missing values now yield an explicit errors.New(...) propagated up the reconcile stack rather than a panic. This satisfies the Test-Diff-Scrutiny bar for a tightened precondition: the modified validation_test.go case is additive (a new digest-reference case plus a version bump), not a flipped guarantee.

The findings below are documentation/consistency drift introduced by, or adjacent to, this change.

Findings

[Major] Stale ghcr.io/nvidia/openshell/gateway references remain in skills/deploy/gcp-cluster/SKILL.mdImage Consistency
This PR's stated goal is to move off the upstream GHCR images, and update-openshell mandates that "every other occurrence of the version in the repo MUST agree." skills/deploy/gcp-cluster/SKILL.md (lines ~433, ~456, ~547) still creates gateways with ghcr.io/nvidia/openshell/gateway:0.0.109. This file is in the PR's base (merge-base includes the GCP-cluster commit), so it is in scope. It should be updated to the quay.io/opendatahub/odh-openshell-gateway:v0.0.109-rhaiv.0@sha256:... pin, and gcp-cluster should be added to the update-openshell footprint table (which currently lists only deploy-cluster / ibm-cluster). Confidence: High.

[Minor] Dangling /kind skill references after deleting skills/deploy/kind/SKILL.mdDocs Consistency
skills/build/full-stack-pipeline/SKILL.md:174 ("see /kind skill") and skills/RECONCILE.md:42 (... /deploy-cluster or /kind) still point at the removed skill. The same skill docs also reference make kind-rebuild / make image / make image-controller, which this PR removes from components/api-server/Makefile and which do not exist in the root Makefile (the canonical Kind flow is make kind-upscripts/kind/up.sh, plus the kind-*-up swap targets). Please update or drop these references so the documented dev workflow stays runnable. Confidence: High.

[Minor] Orphaned KIND_CLUSTER_NAME and trailing blank line in components/api-server/MakefileCleanup
After removing all the kind-*/image* targets, KIND_CLUSTER_NAME?=hypershell-dev (line 129) has no remaining consumers, and the file ends with an added blank line. Minor cleanup. Confidence: High.

[Minor/nit] validation_test.go fixture tag bumpConsistency
update-openshell/SKILL.md explicitly says "Do NOT change" the example tag in validation_test.go because it exercises the regex, not the deployed version; this PR bumps 0.0.1010.0.109 on the pre-existing case. Harmless (the regex assertion is unchanged), but it contradicts the guidance the same PR reaffirms. Confidence: Medium.

Cross-PR coordination

Two open pull requests have material, non-file-overlap conflicts with this change that need maintainer coordination:

Convention Checklist

Convention Result
No panic() in production code Pass
Errors returned with context / not swallowed Pass
Reconcile surfaces terminal config errors (no silent skip) Pass
SecurityContext on pod specs (unchanged by this PR) N/A
Optional→required config has fallback + migration path Pass
Image references consistent across the stack Fail (gcp-cluster skill)
Docs/skills updated with the change Fail (dangling /kind, stale make targets)
Conventional commit messages Pass
OpenAPI client not manually edited N/A

Findings Summary (highest severity first):

  1. [Major] Stale ghcr.io/nvidia/openshell refs in skills/deploy/gcp-cluster/SKILL.md; add it to the update-openshell footprint — Image Consistency
  2. [Minor] Dangling /kind skill + make kind-rebuild/make image references after deletions — Docs Consistency
  3. [Minor] Orphaned KIND_CLUSTER_NAME + trailing blank line in components/api-server/MakefileCleanup
  4. [Minor/nit] validation_test.go fixture tag bump contradicts update-openshell guidance — Consistency

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

This is a clean, well-documented refactor that removes the hardcoded ghcr.io/nvidia/openshell/* image constants and makes the gateway/supervisor image pins configuration-driven (GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE), pointing at Red Hat (quay.io/opendatahub/odh-openshell-*) digest-pinned images. The change is consistent with "separate configuration from code," properly returns errors (no panics) when an image is unconfigured, and the specs + update-openshell source-of-truth were moved in lockstep; the remaining issues are documentation drift and a few stale image references, none blocking.

Summary

The optional→required config change (removing the in-code fallback defaults) is intentional, called out in the PR description, marked *(required)* in the spec, and given both a resource-level fallback (Gateway.image / supervisor_image) and a manifest-level source (deploy/base/controller.yaml sets both env vars, inherited by the openshift/ibm overlays). Missing values now yield an explicit errors.New(...) propagated up the reconcile stack rather than a panic. This satisfies the Test-Diff-Scrutiny bar for a tightened precondition: the modified validation_test.go case is additive (a new digest-reference case plus a version bump), not a flipped guarantee.

The findings below are documentation/consistency drift introduced by, or adjacent to, this change.

Findings

[Major] Stale ghcr.io/nvidia/openshell/gateway references remain in skills/deploy/gcp-cluster/SKILL.mdImage Consistency
This PR's stated goal is to move off the upstream GHCR images, and update-openshell mandates that "every other occurrence of the version in the repo MUST agree." skills/deploy/gcp-cluster/SKILL.md (lines ~433, ~456, ~547) still creates gateways with ghcr.io/nvidia/openshell/gateway:0.0.109. This file is in the PR's base (merge-base includes the GCP-cluster commit), so it is in scope. It should be updated to the quay.io/opendatahub/odh-openshell-gateway:v0.0.109-rhaiv.0@sha256:... pin, and gcp-cluster should be added to the update-openshell footprint table (which currently lists only deploy-cluster / ibm-cluster). Confidence: High.

[Minor] Dangling /kind skill references after deleting skills/deploy/kind/SKILL.mdDocs Consistency
skills/build/full-stack-pipeline/SKILL.md:174 ("see /kind skill") and skills/RECONCILE.md:42 (... /deploy-cluster or /kind) still point at the removed skill. The same skill docs also reference make kind-rebuild / make image / make image-controller, which this PR removes from components/api-server/Makefile and which do not exist in the root Makefile (the canonical Kind flow is make kind-upscripts/kind/up.sh, plus the kind-*-up swap targets). Please update or drop these references so the documented dev workflow stays runnable. Confidence: High.

[Minor] Orphaned KIND_CLUSTER_NAME and trailing blank line in components/api-server/MakefileCleanup
After removing all the kind-*/image* targets, KIND_CLUSTER_NAME?=hypershell-dev (line 129) has no remaining consumers, and the file ends with an added blank line. Minor cleanup. Confidence: High.

[Minor/nit] validation_test.go fixture tag bumpConsistency
update-openshell/SKILL.md explicitly says "Do NOT change" the example tag in validation_test.go because it exercises the regex, not the deployed version; this PR bumps 0.0.1010.0.109 on the pre-existing case. Harmless (the regex assertion is unchanged), but it contradicts the guidance the same PR reaffirms. Confidence: Medium.

Cross-PR coordination

Two open pull requests have material, non-file-overlap conflicts with this change that need maintainer coordination:

  • #194 (adopt upstream OpenShell Helm chart for gateway deployments) presents a competing design for exactly the mechanism this PR modifies. #194 deletes components/control-plane/internal/gateway/manifests.go (and the manifests/gateway/*.yaml templates) and replaces the placeholder-substitution model with a Helm-values mapping, while also editing internal/gateway/config.go and scripts/kind/lib.sh. This PR instead hardens the placeholder/substitution path (adds cmp.Or + required-image error returns in manifests.go) and removes the in-code image defaults from config.go. The maintainers must decide (a) which image-injection model wins and (b) the merge order: if #194 lands first, this PR's manifests.go edits are moot; if this PR lands first, #194 must carry forward the "required GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE, no hardcoded default" contract into its Helm values mapping.

  • #227 (per-gateway resource quotas / GatewayProfile) invests in the legacy components/api-server/deploy/ tree that this PR removes. This PR (head commit "merge components/api-server/deploy with deploy") deletes components/api-server/deploy/{kind,openshift,ibm}/…, migrating deployment manifests to the top-level deploy/. #227 concurrently adds/renames/modifies manifests in that same tree (e.g. components/api-server/deploy/kind/controller-clusterrbac.yaml, components/api-server/deploy/openshift/kustomization.yaml, components/api-server/deploy/ibm/kustomization.yaml). This is a structural/ownership conflict, not a plain merge conflict: the two PRs disagree on where deployment manifests live. Maintainers must fix a merge order and ensure whichever PR lands second relocates its GatewayProfile RBAC/kustomize changes into the surviving deploy/ layout.

Convention Checklist

Convention Result
No panic() in production code Pass
Errors returned with context / not swallowed Pass
Reconcile surfaces terminal config errors (no silent skip) Pass
SecurityContext on pod specs (unchanged by this PR) N/A
Optional→required config has fallback + migration path Pass
Image references consistent across the stack Fail (gcp-cluster skill)
Docs/skills updated with the change Fail (dangling /kind, stale make targets)
Conventional commit messages Pass
OpenAPI client not manually edited N/A

Findings Summary (highest severity first):

  1. [Major] Stale ghcr.io/nvidia/openshell refs in skills/deploy/gcp-cluster/SKILL.md; add it to the update-openshell footprint — Image Consistency
  2. [Minor] Dangling /kind skill + make kind-rebuild/make image references after deletions — Docs Consistency
  3. [Minor] Orphaned KIND_CLUSTER_NAME + trailing blank line in components/api-server/MakefileCleanup
  4. [Minor/nit] validation_test.go fixture tag bump contradicts update-openshell guidance — Consistency

Comment thread components/control-plane/internal/gateway/config.go
Comment thread components/control-plane/internal/gateway/manifests.go
{name: "bare name with tag", ref: "postgres:18", wantErr: false},
{name: "docker hub library path", ref: "docker.io/library/postgres:18", wantErr: false},
{name: "ghcr multi-segment path with tag", ref: "ghcr.io/nvidia/openshell/gateway:0.0.101", wantErr: false},
{name: "ghcr multi-segment path with tag", ref: "ghcr.io/nvidia/openshell/gateway:0.0.109", wantErr: false},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: update-openshell/SKILL.md explicitly lists this fixture tag under "Do NOT change" (it exercises the reference regex, not the deployed version). The bump from 0.0.1010.0.109 is harmless since wantErr is unchanged, but it contradicts the guidance this PR reaffirms. The new digest-reference case on the next line is a good additive test.

Comment thread components/api-server/Makefile Outdated
@@ -127,74 +127,4 @@ proto-clean:
rm -rf pkg/api/grpc/

KIND_CLUSTER_NAME?=hypershell-dev

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After removing the image*/kind-* targets, KIND_CLUSTER_NAME?=hypershell-dev no longer has any consumer in this file, and the file now ends with a trailing blank line. Minor cleanup — drop the orphaned variable (or the whole tail) so the Makefile doesn't carry a dangling declaration.

@jsell-rh

jsell-rh commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

Verdict

This PR cleanly retires the hardcoded upstream OpenShell image constants and makes GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE explicit, required inputs sourced from the control-plane deployment manifest, with the Red Hat quay.io digests wired through consistently and the specs/docs updated to match. The code changes are sound (proper error returns, no panics, additive test coverage); the only items worth attention are one operational upgrade note and a cross-PR design decision about how gateway images will be resolved going forward.

Summary

The change removes the in-code defaultGatewayImage / defaultSupervisorImage fallbacks so image resolution is now: per-Gateway field → env var → hard error if neither is set (cmp.Or + explicit errors.New, propagated and wrapped by the caller). The env-var defaults are set in deploy/base/controller.yaml and inherited by the kind/openshift/ibm overlays, image digests are consistent across deploy/base, scripts/kind/lib.sh, the validation test, and the specs, and the legacy duplicated components/api-server/deploy/** tree plus stale Makefile kind targets are deleted with no dangling references. This is a deliberate, well-documented optional→required move; the fallback for pre-existing Gateway records with a blank image is the env var applied on every reconcile, so no data backfill is required as long as the deployment carries the env vars.

Findings

[Minor] Optional→required image default is an operational breaking change on in-place upgradesconfig.go (L43-52) and manifests.go (L91-104). Removing the code-level defaults means a control plane that is upgraded by image tag alone, without re-applying the deployment manifest that now carries GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE, will start failing reconciliation for every Gateway that relied on the default (gateway image is not configured and no default is available). Within this repo the mitigation is present (both env vars live in deploy/base/controller.yaml, inherited by all overlays), and the error is explicit rather than a panic, so this is not a blocker. Recommend calling the required rollout order out in the PR description / release notes (apply the manifest, not just bump the image) so downstream GitOps/operator consumers add the env vars before cutover. Confidence: High.

[Nit] errors.New messages are actionable but not env-specificmanifests.go L93, L104. Consider naming the missing env var in the message (e.g. "gateway image is not configured: set the Gateway image field or GATEWAY_IMAGE on the control-plane deployment") to shorten operator triage, since this is now the sole failure mode when the default is absent. Confidence: Medium.

Test Diff Scrutiny

validation_test.go adds one new case (a quay.io digest-pinned reference, wantErr: false) and leaves the existing ghcr.io/nvidia/openshell/gateway:0.0.101 case intact. This is additive — no pre-existing assertion was flipped from accept→reject or optional→required — so no guarantee was silently removed.

Cross-PR coordination

Another open pull request replaces the gateway deployment path wholesale — it removes the very ApplyManifestToNamespace placeholder-substitution function this PR edits and switches image resolution to a Helm values mapping, while keeping (and re-pointing) the defaultGatewayImage / defaultSupervisorImage code constants that this PR deletes. These are two incompatible designs for the same image-resolution code and cannot both land as-is:

Findings Summary (ordered by severity, highest first)

  1. [Minor] Optional→required image default is an in-place-upgrade breaking change; ensure rollout re-applies the manifest env vars - Reconciliation / Config (config.go L43-52, manifests.go L91-104)
  2. [Nit] Failure messages could name the missing env var for faster operator triage - Observability (manifests.go L93, L104)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context (caller) Pass
Reconcile errors propagated, not swallowed Pass
Image references consistent across manifests/specs Pass
Input validated (image reference regex) Pass
No secrets in logs or responses Pass
Test diff additive (no flipped assertions) Pass
OpenAPI client not manually edited Pass (N/A)
Conventional commit messages Pass

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

This PR cleanly retires the hardcoded upstream OpenShell image constants and makes GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE explicit, required inputs sourced from the control-plane deployment manifest, with the Red Hat quay.io digests wired through consistently and the specs/docs updated to match. The code changes are sound (proper error returns, no panics, additive test coverage); the only items worth attention are one operational upgrade note and a cross-PR design decision about how gateway images will be resolved going forward.

Summary

The change removes the in-code defaultGatewayImage / defaultSupervisorImage fallbacks so image resolution is now: per-Gateway field → env var → hard error if neither is set (cmp.Or + explicit errors.New, propagated and wrapped by the caller). The env-var defaults are set in deploy/base/controller.yaml and inherited by the kind/openshift/ibm overlays, image digests are consistent across deploy/base, scripts/kind/lib.sh, the validation test, and the specs, and the legacy duplicated components/api-server/deploy/** tree plus stale Makefile kind targets are deleted with no dangling references. This is a deliberate, well-documented optional→required move; the fallback for pre-existing Gateway records with a blank image is the env var applied on every reconcile, so no data backfill is required as long as the deployment carries the env vars.

Findings

[Minor] Optional→required image default is an operational breaking change on in-place upgradesconfig.go (L43-52) and manifests.go (L91-104). Removing the code-level defaults means a control plane that is upgraded by image tag alone, without re-applying the deployment manifest that now carries GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE, will start failing reconciliation for every Gateway that relied on the default (gateway image is not configured and no default is available). Within this repo the mitigation is present (both env vars live in deploy/base/controller.yaml, inherited by all overlays), and the error is explicit rather than a panic, so this is not a blocker. Recommend calling the required rollout order out in the PR description / release notes (apply the manifest, not just bump the image) so downstream GitOps/operator consumers add the env vars before cutover. Confidence: High.

[Nit] errors.New messages are actionable but not env-specificmanifests.go L93, L104. Consider naming the missing env var in the message (e.g. "gateway image is not configured: set the Gateway image field or GATEWAY_IMAGE on the control-plane deployment") to shorten operator triage, since this is now the sole failure mode when the default is absent. Confidence: Medium.

Test Diff Scrutiny

validation_test.go adds one new case (a quay.io digest-pinned reference, wantErr: false) and leaves the existing ghcr.io/nvidia/openshell/gateway:0.0.101 case intact. This is additive — no pre-existing assertion was flipped from accept→reject or optional→required — so no guarantee was silently removed.

Cross-PR coordination

Another open pull request replaces the gateway deployment path wholesale — it removes the very ApplyManifestToNamespace placeholder-substitution function this PR edits and switches image resolution to a Helm values mapping, while keeping (and re-pointing) the defaultGatewayImage / defaultSupervisorImage code constants that this PR deletes. These are two incompatible designs for the same image-resolution code and cannot both land as-is:

  • #194 — Maintainers must decide which image-resolution model is authoritative: this PR's "no in-code defaults; GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE required, hard-fail otherwise" contract versus #194's "keep hardcoded constants + resolve through Helm chart values." Whichever merges second must be reworked, and if #194 is adopted its values mapping needs to carry (or consciously drop) this PR's required-env-var contract and the Red Hat quay.io/opendatahub/odh-openshell-* digests rather than the developer-registry images it currently pins. A merge-order and design decision is needed before either lands.

Findings Summary (ordered by severity, highest first)

  1. [Minor] Optional→required image default is an in-place-upgrade breaking change; ensure rollout re-applies the manifest env vars - Reconciliation / Config (config.go L43-52, manifests.go L91-104)
  2. [Nit] Failure messages could name the missing env var for faster operator triage - Observability (manifests.go L93, L104)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context (caller) Pass
Reconcile errors propagated, not swallowed Pass
Image references consistent across manifests/specs Pass
Input validated (image reference regex) Pass
No secrets in logs or responses Pass
Test diff additive (no flipped assertions) Pass
OpenAPI client not manually edited Pass (N/A)
Conventional commit messages Pass

Comment thread components/control-plane/internal/gateway/config.go
Comment thread components/control-plane/internal/gateway/manifests.go
@JGiola
JGiola force-pushed the feat/use-redhat-openshell-images branch from e8396c0 to 9f2aae8 Compare September 1, 2026 07:36
@jsell-rh

jsell-rh commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

COMMENT. This is a clean, well-scoped migration off the NVIDIA/GHCR upstream images to Red Hat (quay.io/opendatahub/...) pullspecs, and it correctly turns the gateway/supervisor images into required, digest-pinned deployment inputs instead of code-baked constants. The Go changes are sound (cmp.Or + explicit errors.New, error propagated up the reconcile stack, additive test case), and the env vars are wired into deploy/base/controller.yaml so every overlay that layers on ../base inherits them. My only actionable items are a couple of operability nits and one cross-PR coordination decision the maintainers should make before merge.

Amber Assessment

What this PR does well

  • Removes the hardcoded defaultGatewayImage/defaultSupervisorImage constants and replaces the if x != "" { ... } fallback ladder with cmp.Or(config.X, images.DefaultX()), returning an explicit error when nothing resolves. This is a proper reconcile-time failure (not a panic), and it is wrapped with context at the call site (apply substitutions for %s: %w).
  • Image references are updated consistently across specs, README, kind/lib.sh, e2e scripts, and the deploy overlays. I could not find any lingering reference to the deleted components/api-server/deploy/... trees or to the old ghcr.io/nvidia/openshell/... defaults in code.
  • The one modified pre-existing test (validation_test.go) is additive — it adds a tag+digest acceptance case rather than flipping an existing assertion, so no guarantee was silently removed.
  • Required env vars are set in deploy/base/controller.yaml, and deploy/kind, deploy/openshift, deploy/hub, and (transitively) deploy/ibm all compose ../base, so the new hard requirement is satisfied on every deploy path.

Findings (none blocking)

  1. [Minor] No fail-fast on missing image env varsDefaultGatewayImage()/DefaultSupervisorImage() now read os.Getenv lazily on every reconcile. If an operator forgets to set GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE, the controller starts up healthy and then fails every gateway reconcile at runtime. Consider validating presence once at controller startup so misconfiguration surfaces immediately rather than per-gateway. Confidence: Medium.
  2. [Minor] Error messages don't name the missing knob — the two errors.New("... is not configured and no default is available") messages don't tell the operator which env var to set. Including GATEWAY_IMAGE / GATEWAY_SUPERVISOR_IMAGE (or the Gateway image/supervisor_image field) in the message makes the failure self-diagnosing. Confidence: High.

Cross-PR coordination

Another open pull request reworks the gateway deployment path to install gateways at runtime via the upstream OpenShell Helm chart: it deletes components/control-plane/internal/gateway/manifests.go in its entirety, moves image resolution into a Helm values mapping, and — critically — keeps (and merely re-points) the hardcoded defaultGatewayImage/defaultSupervisorImage constants that this PR deliberately removes. The two PRs encode incompatible designs for the same concern (how the default gateway/supervisor image is resolved and injected): this PR makes the images required, digest-pinned env-var inputs with a hard failure when unset, while the Helm PR relies on non-empty in-code defaults and a different placeholder/values path. They also edit the same lines in internal/gateway/config.go, scripts/kind/lib.sh, and specs/platform/openshell-gateway.spec.md, and set different image pullspecs.

This needs a maintainer decision on merge order and on where the "required, no in-code default" semantics live. If the Helm PR merges first, this PR's env-var-required design, Red Hat pullspecs, and fail-on-empty behavior must be re-applied inside the Helm values mapping (manifests.go will no longer exist). If this PR merges first, the Helm PR must drop its resurrected image constants and carry the required-env-var contract into its values path rather than reintroducing hardcoded defaults. Please coordinate before either lands so the image-resolution contract is not silently reverted.

Findings Summary (ordered by severity, highest first)

  1. [Minor] No startup validation for required GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE; misconfig only surfaces per-reconcile — Operability (config.go L43-L51)
  2. [Minor] Missing-image errors don't name the env var / field to set — Observability (manifests.go L93, L104)

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf/explicit error and context Pass
Reconcile pattern (fail + propagate, no create-or-skip) Pass
No secrets in logs or error messages Pass
Image references consistent across the stack Pass
Test Diff Scrutiny (modified assertion is additive, not a flipped guarantee) Pass
Config separated from code (images now deployment inputs) Pass
Conventional commit messages Pass

Comment thread components/control-plane/internal/gateway/config.go
Comment thread components/control-plane/internal/gateway/manifests.go
Move from the upstream image to the Red Hat downstream ones.
Removed the default versions pinned in code and leave the selection
only via the env variables to avoid doing a new release only to move
the default versions used if a user will not set the variables.

Update SKILLs and specs to point to the new source of truth for the
images versions and remove stale references.
Merge kustomization manifests in a single location to avoid drift
and missing configurations for overlays.

Reconcile SKILLs and specs for the new layout and removed duplicated
instructions in components/api-server/Makefile to handle all things related
to kind in a single location.
@JGiola
JGiola force-pushed the feat/use-redhat-openshell-images branch from 9f2aae8 to bab3708 Compare September 1, 2026 10:24
@jsell-rh

jsell-rh commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

COMMENT. This is a clean, well-scoped switch from upstream ghcr.io/nvidia/openshell gateway/supervisor images to the Red Hat downstream quay.io/opendatahub/odh-openshell-* digests, plus a consolidation of the deploy tree onto top-level /deploy. The code change is sound and image references are consistent across manifests, scripts, and specs; the only in-repo nits are a stale fleet_id in a touched doc example, and cross-PR coordination is required with two other open PRs that redesign gateway image resolution / restructure the same deploy tree.

What I verified

  • Image references consistent across the stack — old ghcr.io/nvidia/openshell/gateway|supervisor refs are fully removed; the new digests appear consistently in deploy/base/controller.yaml, scripts/kind/lib.sh, specs, and skills.
  • Required-image change is fully wiredDefaultGatewayImage()/DefaultSupervisorImage() now return the raw env var (no hardcoded fallback), and ApplyManifestToNamespace fails fast if neither the GatewayConfig field nor the env var is set. Every overlay (base, openshift, hub, kind, ibm) inherits ../base's controller.yaml, which sets GATEWAY_IMAGE and GATEWAY_SUPERVISOR_IMAGE, so no in-tree deployment path regresses. This is a good fail-fast improvement over silently defaulting to an upstream image.
  • Error handling — new error paths use errors.New(...) and propagate through the reconciler with %w wrapping (apply substitutions for %s: %w); no panic(), no secret leakage in messages.
  • Test diff scrutiny — the only test change (validation_test.go) is purely additive (a new accepted tag@sha256 reference case); no pre-existing assertion was flipped.
  • Deleted components/api-server/deploy/** tree — no dangling references remain in Go, Makefiles, scripts, or CI; the removed api-server kind-*/image* Makefile targets are superseded by the top-level Makefile targets and reference an already-removed fleets endpoint.

Findings

  1. [Minor] skills/deploy/gcp-cluster/SKILL.md:432 — the GatewayRelease example payload still sends "fleet_id":"$FLEET_ID", but the Fleet entity and fleet_id were removed on main (this PR's base). This PR edits that exact line to update the image, so it's the right moment to drop the removed field. Spec/Docs Consistency

  2. [Minor] Operational note (components/control-plane/internal/gateway/config.go:44,51) — because the images are now required with no fallback, any out-of-tree/custom control-plane deployment that predates this change must set GATEWAY_IMAGE and GATEWAY_SUPERVISOR_IMAGE or gateway reconciliation will fail. In-tree overlays are covered; worth a one-line callout in the PR/upgrade notes for downstream consumers. Docs Completeness

Cross-PR coordination

Two open pull requests require maintainer coordination or a merge-order decision with this PR:

  • #194 (adopt upstream OpenShell Helm chart for gateway deployments) presents a competing design for the exact mechanism this PR changes. #194 deletes components/control-plane/internal/gateway/manifests.go (the placeholder-substitution path this PR edits), keeps the hardcoded defaultGatewayImage/defaultSupervisorImage constants this PR removes (re-pointing them at different pullspecs), and injects images through Helm values mapping instead of env-var resolution. Maintainers must decide which image-resolution model wins and in which order they land: if #194 merges first, this PR's env-required semantics must be re-expressed as Helm values; if this PR merges first, #194 must carry the "images required, no upstream default" contract into its values mapping rather than reintroducing hardcoded defaults.

  • #227 (per-gateway resource quotas / GatewayProfile) adds and modifies manifests under components/api-server/deploy/kind, .../openshift, and .../ibm — the entire directory tree this PR deletes when consolidating onto top-level /deploy. This is a structural/ownership conflict, not just a text merge: #227's new controller ClusterRBAC (resourcequotas/limitranges) manifests must be re-homed into /deploy and its kustomizations rebased onto the unified layout. Maintainers should agree on merge order (ideally this consolidation first) and where #227's RBAC lands.

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf/%w context Pass
No secrets in logs or error messages Pass
Image references consistent across the stack Pass
Reconcile pattern (not create-or-skip) Pass
Test Diff Scrutiny (no silently flipped assertions) Pass
Conventional commit messages Pass

Findings Summary (ordered by severity, highest first):

  1. [Minor] Stale fleet_id in a touched doc example - Spec/Docs Consistency (gcp-cluster/SKILL.md:432)
  2. [Minor] Required-image change needs an upgrade callout for out-of-tree deployments - Docs Completeness (config.go:44,51)

Comment thread skills/deploy/gcp-cluster/SKILL.md Outdated
RELEASE=$(curl -sk -X POST "$API/gateway_releases" -H 'Content-Type: application/json' \
-H "Authorization: Bearer $TOKEN" \
-d "{\"name\":\"openshell-0.0.109\",\"fleet_id\":\"$FLEET_ID\",\"image\":\"ghcr.io/nvidia/openshell/gateway:0.0.109\"}")
-d "{\"name\":\"openshell-0.0.109\",\"fleet_id\":\"$FLEET_ID\",\"image\":\"quay.io/opendatahub/odh-openshell-gateway:v0.0.109-rhaiv.0\"}")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale field: this payload still sends "fleet_id":"$FLEET_ID", but the Fleet entity and fleet_id were removed on main (this PR's base, #223). Since you're already editing this line to update the image, please drop fleet_id (and the $FLEET_ID capture above it, if it's now unused) so the example matches the current API. [Minor]

Comment thread components/control-plane/internal/gateway/config.go
@JGiola
JGiola force-pushed the feat/use-redhat-openshell-images branch from bab3708 to 0fecf3e Compare September 1, 2026 10:45
@jsell-rh

jsell-rh commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Amber review: comment

Amber review

Status: Complete

View the submitted review.

@jsell-rh jsell-rh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict

COMMENT — This is a clean, well-documented supply-chain change: it retires the NVIDIA OpenShell upstream gateway/supervisor images in favor of digest-pinned Red Hat (quay.io/opendatahub/...) images and makes the image references configuration-driven. The core code change (removing hardcoded image defaults so GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE become required env vars) is intentional and correctly wired through deploy/base/controller.yaml, README, and specs; my only substantive note is that a missing value fails per-reconcile rather than at startup.

What this PR does well

  • Digest-pinned images in deploy/base/controller.yaml and scripts/kind/lib.sh (v0.0.109-rhaiv.0@sha256:...) give immutable, verifiable pulls — good supply-chain hygiene.
  • Config separated from code: the image references now live in manifests/env, not Go constants, matching the "separate configuration from code" convention.
  • Clean error handling: manifests.go returns explicit errors.New(...) when no image is resolvable, and reconciler.go wraps and propagates it (fmt.Errorf("apply substitutions for %s: %w", ...)) — no silently swallowed failures, no secrets in messages, no panic().
  • Additive test change: validation_test.go adds a digest-reference case instead of flipping an existing assertion, so no guarantee is silently removed.
  • Consistent references: the gateway image string matches across deploy/base/controller.yaml, scripts/kind/lib.sh (seed release), and the docs.

Findings

See inline comments. Summary below.

Findings Summary (ordered by severity, highest first):

  1. [Major] Required-image env vars (GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE) are validated only at gateway-reconcile time, not at controller startup; a misconfigured control plane boots healthy and fails every provisioning. Add a fail-fast startup check. — Control-Plane / Config (config.go L44, L51; manifests.go L93, L104)
  2. [Minor] No unit test covers the new "no image configured -> error" path in ApplyManifestToNamespace. Add a table case. — Test Coverage (validation_test.go L17)

The optional->required transition is a contract change, but it is explicitly called out in the PR body/README/specs and backfilled in the same PR via deploy/base/controller.yaml (and the IBM overlay), so it does not meet the Blocker bar for an unannounced tightened precondition.

Convention Checklist:

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context / explicit errors Pass
No secrets in logs or responses Pass
Image references consistent across the stack Pass
Config separated from code Pass
Test Diff Scrutiny (no silently-removed guarantees) Pass
Fail-fast validation of required config Fail

Cross-PR coordination

Two open pull requests have material conflicts with this one and need a maintainer decision on merge order and design ownership:

  • PR #194 (adopt upstream OpenShell Helm chart for gateway deployments) is a competing design for the same concern — how gateway/supervisor images are injected — and rests on the opposite assumption about image defaults. This PR (#201) removes the hardcoded defaultGatewayImage/defaultSupervisorImage constants and makes the env vars required with no fallback (fail-closed). #194 instead keeps those hardcoded constants (repointing them at a personal dev registry) and deletes internal/gateway/manifests.go entirely, moving image resolution into a Helm values mapping. Both PRs also edit config.go's image-default methods and scripts/kind/lib.sh. Maintainers must decide the merge order and, whichever lands second, ensure the "required env var, no hardcoded fallback" policy from #201 is preserved in #194's Helm values path rather than silently reintroducing a fallback (and a non-Red-Hat dev image).

  • PR #227 (per-gateway resource quotas) adds and renames ClusterRBAC resources under components/api-server/deploy/{kind,openshift}/ and edits the kustomizations there. This PR (#201) deletes that entire components/api-server/deploy/ tree as part of unifying on the repo-root deploy/. If #201 merges first, #227's new RBAC lands in a removed, unwired directory and is orphaned; if #227 merges first, #201's deletion must re-home that RBAC into deploy/. Maintainers must coordinate merge order and decide where the new quota RBAC lives in the unified deploy layout.

return v
}
return defaultGatewayImage
return os.Getenv("GATEWAY_IMAGE")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] DefaultGatewayImage/DefaultSupervisorImage now return the bare os.Getenv result with no fallback, so GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE move from optional to required. This is a deliberate, documented fail-closed change (README, PR body, specs, and deploy/base/controller.yaml all updated), which is good — but the missing-value error only surfaces per-gateway at reconcile time (manifests.go:93/:104), not at controller startup. A control plane deployed without these env vars boots healthy and then fails every gateway provisioning with a runtime error.

Recommend validating presence once at startup (fail-fast in cmd/hypershell-controller or internal/config) so a misconfiguration is caught at boot rather than on first reconcile. Confidence: Medium.Control-Plane / Config

supervisorImage = config.SupervisorImage
supervisorImage := cmp.Or(config.SupervisorImage, images.DefaultSupervisorImage())
if supervisorImage == "" {
return nil, errors.New("supervisor image is not configured and no default is available")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good: image resolution now uses cmp.Or(config.X, images.DefaultX()) and returns an explicit error when nothing is configured, and the caller wraps and propagates it (reconciler.go:836). No secrets in the message. One note — since the default is now env-only (see config.go:44), this error is the only guardrail against a missing GATEWAY_IMAGE/GATEWAY_SUPERVISOR_IMAGE; pairing it with a startup-time check would make failures easier to diagnose. Confidence: High.Control-Plane / Error Handling

Comment thread components/control-plane/internal/gateway/validation_test.go
@rh-amarin

Copy link
Copy Markdown
Collaborator

/lgtm

@rh-amarin
rh-amarin added this pull request to the merge queue Sep 1, 2026
Merged via the queue into openshift-online:main with commit fc074da Sep 1, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants