Skip to content

feat: Support RHOAI RC images - #113

Merged
openshift-merge-bot[bot] merged 16 commits into
openshift-psap:mainfrom
albertoperdomo2:feat/support-rc-images
Jul 15, 2026
Merged

feat: Support RHOAI RC images#113
openshift-merge-bot[bot] merged 16 commits into
openshift-psap:mainfrom
albertoperdomo2:feat/support-rc-images

Conversation

@albertoperdomo2

@albertoperdomo2 albertoperdomo2 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added support for custom catalog publisher metadata.
    • Added configurable pull credentials for catalog and staging registries.
    • Added RHOAI custom catalog deployment and operator setup support.
    • Added registry mirror configuration to streamline image retrieval.
  • Bug Fixes

    • Improved pull-secret propagation and readiness handling during deployment.
    • Improved phase-based credential initialization for optional catalog resources.
  • Tests

    • Expanded coverage for catalog deployment, credentials, registry configuration, and readiness checks.

@albertoperdomo2
albertoperdomo2 requested a review from kpouget July 8, 2026 10:46
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds RHOAI custom catalog deployment orchestration with vault-backed pull secrets, registry mirroring, phase-specific vault initialization, publisher metadata rendering, shared deployment helpers, and expanded tests.

Changes

RHOAI custom catalog and publisher wiring

Layer / File(s) Summary
Publisher parameter and template rendering
projects/cluster/toolbox/deploy_custom_catalog/main.py, projects/cluster/toolbox/deploy_custom_catalog/templates/catalogsource.yaml.j2
Adds an optional publisher argument, carries it through task context, and conditionally renders CatalogSource.spec.publisher.
Vault selection and catalog configuration
projects/llm_d/orchestration/ci.py, projects/llm_d/orchestration/config.d/platform.yaml, vaults/psap-rhoai-rc.yaml, vaults/psap-forge-staging-image-pull.yaml
Adds conditional RHOAI vault initialization and resolver listing, configures catalog metadata and vault-backed secrets, and defines the new vault resources.
RHOAI deployment library
projects/rhoai/library/deploy.py
Adds typed configuration, operator subscription handling, custom catalog deployment, pull-secret merging and propagation checks, and CRD readiness handling.
ICSP application wiring
projects/llm_d/orchestration/prepare_phase.py, projects/llm_d/orchestration/manifests/rhoai-registry-icsp.yaml
Moves RHOAI deployment helpers into the shared library, applies the registry mirror policy, and passes the ICSP callback into operator preparation.
RHOAI orchestration validation
projects/llm_d/tests/test_profiles.py
Tests conditional vault behavior, preparation ordering, explicit vault content lookup, readiness polling, and Docker configuration merging.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CI
  participant prepare_phase
  participant RHOAI_deploy
  participant Vault
  participant OpenShift
  CI->>Vault: initialize phase vaults
  CI->>prepare_phase: start RHOAI preparation
  prepare_phase->>RHOAI_deploy: prepare_rhoai_operator(...)
  RHOAI_deploy->>Vault: resolve pull-secret content
  RHOAI_deploy->>OpenShift: update cluster pull-secret
  RHOAI_deploy->>prepare_phase: apply ICSP
  prepare_phase->>OpenShift: apply ImageContentSourcePolicy
  RHOAI_deploy->>OpenShift: deploy catalog and subscriptions
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main change: enabling support for RHOAI RC images.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Comment thread projects/llm_d/orchestration/ci.py Outdated
Comment thread projects/llm_d/orchestration/prepare_phase.py Outdated
Comment thread projects/llm_d/orchestration/prepare_phase.py
Comment thread vaults/psap-rhoai-rc.yaml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@projects/llm_d/orchestration/prepare_phase.py`:
- Around line 161-171: The MCP readiness check in prepare_phase.py can
incorrectly pass when oc get mcp returns an empty jsonpath result. Update the
logic around the mcp_status handling in the prepare phase so that the code only
considers MachineConfigPools updated when mcp_status is non-empty and does not
contain "False". If the status is empty, treat it as not ready and keep waiting
or raise the same RuntimeError from the existing MCP status check path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 487b5437-4363-4566-aae4-40b7c217c460

📥 Commits

Reviewing files that changed from the base of the PR and between bc2671a and 18afc91.

📒 Files selected for processing (8)
  • projects/cluster/toolbox/deploy_custom_catalog/main.py
  • projects/cluster/toolbox/deploy_custom_catalog/templates/catalogsource.yaml.j2
  • projects/llm_d/orchestration/ci.py
  • projects/llm_d/orchestration/config.d/platform.yaml
  • projects/llm_d/orchestration/manifests/quay-registry-icsp.yaml
  • projects/llm_d/orchestration/prepare_phase.py
  • projects/llm_d/tests/test_profiles.py
  • vaults/psap-rhoai-rc.yaml

Comment thread projects/llm_d/orchestration/prepare_phase.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
projects/rhoai/library/deploy.py (1)

178-179: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

MCP status check still passes on empty output.

This issue was previously flagged on prepare_phase.py and persists in the new location after the code was moved. If oc get mcp returns an empty string (no MachineConfigPools exist yet, or the API is temporarily unavailable), "False" in "" evaluates to False, so the function treats MCPs as fully updated and returns prematurely.

🔒️ Proposed fix
-            if "False" in mcp_status:
-                raise RuntimeError("machine config pools are still updating")
+            if not mcp_status or "False" in mcp_status:
+                raise RuntimeError("machine config pools are still updating")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/rhoai/library/deploy.py` around lines 178 - 179, The MCP readiness
check in deploy.py can incorrectly pass when the `oc get mcp` output is empty,
because the current `mcp_status` test only looks for `"False"`. Update the MCP
status handling in the same block to treat empty output from the
`mcp_status`/`oc get mcp` command as not ready and raise the existing
`RuntimeError` until valid MCP data is present. Keep the fix localized around
the MCP check logic so the moved behavior remains consistent with the previous
`prepare_phase.py` implementation.
🧹 Nitpick comments (1)
projects/rhoai/library/deploy.py (1)

196-206: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated vault path resolution logic.

The vault content path lookup and None-check with error message are duplicated between custom_catalog_pull_secret_path (lines 68-80) and prepare_rhoai_pull_secret (lines 196-206). Extract a shared helper to eliminate the duplication.

♻️ Proposed refactor
+def _resolve_vault_content_path(vault_name: str, content_name: str) -> Path:
+    secret_path = vault.get_vault_content_path(vault_name, content_name)
+    if secret_path is None:
+        raise RuntimeError(
+            "RHOAI pull secret content "
+            f"'{content_name}' was not found in vault "
+            f"'{vault_name}'"
+        )
+    return secret_path
+
+
 def custom_catalog_pull_secret_path(custom_catalog: dict[str, Any]) -> Path:
     catalog = _RhoaiCustomCatalogPullSecretInput.model_validate(custom_catalog)
-    secret_path = vault.get_vault_content_path(
-        catalog.pull_secret.vault.name,
-        catalog.pull_secret.vault.content,
-    )
-    if secret_path is None:
-        raise RuntimeError(
-            "RHOAI pull secret content "
-            f"'{catalog.pull_secret.vault.content}' was not found in vault "
-            f"'{catalog.pull_secret.vault.name}'"
-        )
-    return secret_path
+    return _resolve_vault_content_path(
+        catalog.pull_secret.vault.name,
+        catalog.pull_secret.vault.content,
+    )

Then update prepare_rhoai_pull_secret to use the same helper:

 def prepare_rhoai_pull_secret(custom_catalog: RhoaiCustomCatalogConfig) -> None:
-    pull_secret_path = vault.get_vault_content_path(
+    pull_secret_path = _resolve_vault_content_path(
         custom_catalog.pull_secret.vault.name,
         custom_catalog.pull_secret.vault.content,
     )
-    if pull_secret_path is None:
-        raise RuntimeError(
-            "RHOAI pull secret content "
-            f"'{custom_catalog.pull_secret.vault.content}' was not found in vault "
-            f"'{custom_catalog.pull_secret.vault.name}'"
-        )
     auth_basic = pull_secret_path.read_text(encoding="utf-8").strip()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/rhoai/library/deploy.py` around lines 196 - 206, The vault content
path lookup and missing-path handling in prepare_rhoai_pull_secret duplicates
the logic already present in custom_catalog_pull_secret_path. Extract the shared
resolution-and-error handling into a common helper, then update
prepare_rhoai_pull_secret to call that helper instead of repeating the
get_vault_content_path and RuntimeError logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@projects/rhoai/library/deploy.py`:
- Around line 178-179: The MCP readiness check in deploy.py can incorrectly pass
when the `oc get mcp` output is empty, because the current `mcp_status` test
only looks for `"False"`. Update the MCP status handling in the same block to
treat empty output from the `mcp_status`/`oc get mcp` command as not ready and
raise the existing `RuntimeError` until valid MCP data is present. Keep the fix
localized around the MCP check logic so the moved behavior remains consistent
with the previous `prepare_phase.py` implementation.

---

Nitpick comments:
In `@projects/rhoai/library/deploy.py`:
- Around line 196-206: The vault content path lookup and missing-path handling
in prepare_rhoai_pull_secret duplicates the logic already present in
custom_catalog_pull_secret_path. Extract the shared resolution-and-error
handling into a common helper, then update prepare_rhoai_pull_secret to call
that helper instead of repeating the get_vault_content_path and RuntimeError
logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3eec9ccc-9377-4821-9e54-42a13197607c

📥 Commits

Reviewing files that changed from the base of the PR and between 18afc91 and 3e899f7.

📒 Files selected for processing (5)
  • projects/llm_d/orchestration/config.d/platform.yaml
  • projects/llm_d/orchestration/prepare_phase.py
  • projects/llm_d/tests/test_profiles.py
  • projects/rhoai/library/deploy.py
  • vaults/psap-rhoai-rc.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • projects/llm_d/orchestration/config.d/platform.yaml
  • vaults/psap-rhoai-rc.yaml

Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
@albertoperdomo2
albertoperdomo2 force-pushed the feat/support-rc-images branch from 8069ae3 to 87b0035 Compare July 9, 2026 12:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
projects/llm_d/orchestration/ci.py (1)

139-149: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

vault.phase_vault_list_all is redundant in vault_list_funcs.

list_vaults already calls vault.phase_vault_list_all() internally and returns its result (plus psap-rhoai-rc when enabled). Including both means the base vault list is collected and deduplicated away downstream — harmless but unnecessary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/llm_d/orchestration/ci.py` around lines 139 - 149, The vault list
passed to create_fournos_resolve_entrypoint is redundant because list_vaults
already includes vault.phase_vault_list_all internally. Remove the extra
vault.phase_vault_list_all entry from vault_list_funcs in ci.py and keep
list_vaults as the single source for the base vault list so the command setup
stays minimal and avoids duplicate collection.
projects/llm_d/tests/test_profiles.py (1)

336-365: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test doesn't verify that empty MCP status causes continued polling.

The test name asserts "empty MCP status is treated as not ready," but if the not mcp_status guard were removed, the function would return on the first iteration (empty treated as ready) and the test would still pass — no error is raised either way. Adding an assertion that both MCP outputs were consumed would make the test meaningful:

     rhoai_deploy.wait_for_rhoai_pull_secret_ready(timeout_seconds=1, poll_interval_seconds=0)
+
+    assert not list(mcp_outputs), "both MCP outputs should have been consumed"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/llm_d/tests/test_profiles.py` around lines 336 - 365, The test for
wait_for_rhoai_pull_secret_ready currently only calls the function and does not
prove that an empty MCP status is treated as not ready. Update
test_wait_for_rhoai_pull_secret_ready_treats_empty_mcp_status_as_not_ready to
assert the polling continued past the empty first response by verifying both
mocked mcp outputs were consumed (or otherwise checking multiple oc get mcp
calls occurred). Keep the focus on the
rhoai_deploy.wait_for_rhoai_pull_secret_ready path and the _fake_oc /
mcp_outputs setup so the test fails if the not mcp_status guard is removed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@projects/llm_d/orchestration/ci.py`:
- Around line 139-149: The vault list passed to
create_fournos_resolve_entrypoint is redundant because list_vaults already
includes vault.phase_vault_list_all internally. Remove the extra
vault.phase_vault_list_all entry from vault_list_funcs in ci.py and keep
list_vaults as the single source for the base vault list so the command setup
stays minimal and avoids duplicate collection.

In `@projects/llm_d/tests/test_profiles.py`:
- Around line 336-365: The test for wait_for_rhoai_pull_secret_ready currently
only calls the function and does not prove that an empty MCP status is treated
as not ready. Update
test_wait_for_rhoai_pull_secret_ready_treats_empty_mcp_status_as_not_ready to
assert the polling continued past the empty first response by verifying both
mocked mcp outputs were consumed (or otherwise checking multiple oc get mcp
calls occurred). Keep the focus on the
rhoai_deploy.wait_for_rhoai_pull_secret_ready path and the _fake_oc /
mcp_outputs setup so the test fails if the not mcp_status guard is removed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5513c22b-d4c2-4ece-bb91-bd86616e8fc7

📥 Commits

Reviewing files that changed from the base of the PR and between 3e899f7 and 87b0035.

📒 Files selected for processing (9)
  • projects/cluster/toolbox/deploy_custom_catalog/main.py
  • projects/cluster/toolbox/deploy_custom_catalog/templates/catalogsource.yaml.j2
  • projects/llm_d/orchestration/ci.py
  • projects/llm_d/orchestration/config.d/platform.yaml
  • projects/llm_d/orchestration/manifests/quay-registry-icsp.yaml
  • projects/llm_d/orchestration/prepare_phase.py
  • projects/llm_d/tests/test_profiles.py
  • projects/rhoai/library/deploy.py
  • vaults/psap-rhoai-rc.yaml
🚧 Files skipped from review as they are similar to previous changes (6)
  • projects/cluster/toolbox/deploy_custom_catalog/templates/catalogsource.yaml.j2
  • projects/llm_d/orchestration/config.d/platform.yaml
  • projects/llm_d/orchestration/manifests/quay-registry-icsp.yaml
  • projects/cluster/toolbox/deploy_custom_catalog/main.py
  • vaults/psap-rhoai-rc.yaml
  • projects/rhoai/library/deploy.py

Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d smoke
/cluster forge-smoke-testing
/pipeline forge-full
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310

@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of llm_d smoke 🟢

Execution Engine Configuration

forge:
  args:
  - smoke
  configOverrides:
    platform.rhoai.custom_catalog.enabled: true
    platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
  project: llm_d

Artifact Links

Test Logs

00 Pre-Cleanup 15 seconds

01 Prepare 9 minutes, 15 seconds

02 Preflight 1 second

03 Test 19 minutes, 13 seconds

Test Description

This test validates the llm_d project by running a smoke test on the Qwen3-0.6B model using the approximate-prefix-cache deployment profile. It specifically verifies basic inference functionality and prefix caching behavior by executing a short benchmark with 256 prompt and 128 output tokens at concurrent loads of 1, 4, and 8.

04 Post-Cleanup 16 seconds

🔄 05 Export-Artifacts

Post-processing Status

@psap-forge-bot

Copy link
Copy Markdown
🟢 Submission of llm_d smoke succeeded after 33 minutes 🟢
/test fournos llm_d smoke
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/cluster forge-smoke-testing
/pipeline forge-full

@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d smoke
/cluster forge-smoke-testing
/pipeline forge-full
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta

@psap-forge-bot

Copy link
Copy Markdown

🔴 Execution of llm_d smoke 🔴

Execution Engine Configuration

forge:
  args:
  - smoke
  configOverrides:
    platform.operators.rhods-operator.channel: beta
    platform.rhoai.custom_catalog.enabled: true
    platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
  project: llm_d

Artifact Links

Test Logs

00 Pre-Cleanup 5 seconds

01 Prepare 4 minutes, 20 seconds

02 Preflight 1 second

03 Test 18 minutes, 15 seconds

Test Description

This test validates the llm_d project deployment using the approximate-prefix-cache profile with the Qwen/Qwen3-0.6B model. It executes a short benchmark at concurrent rates of 1, 4, and 8 and a default smoke request, while enabling agentic capabilities.

Failure Review 001 Deploy Llmisvc

001__llmd_test/001__deploy_llmisvc

The wait_service_ready task failed because the LLMInferenceService could not reach a ready state, reporting MinimumReplicasUnavailable after exhausting retry attempts. This was caused by a dual-blocker scenario: the primary inference pod was stuck in ImagePullBackOff due to an inaccessible container image, and the service routing was blocked because the cluster lacks the InferencePool CRD needed to support the configured HTTPProxy mode.

04 Post-Cleanup 13 seconds

🔄 05 Export-Artifacts

Post-processing Status

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of llm_d smoke failed after 25 minutes, 21 seconds 🔴

Error: FournosJobFailureError: FOURNOS Job 'forge-llm-d-20260710-091247' failed: Tasks Completed: 6 (Failed: 1, Cancelled 0), Skipped: 0

/test fournos llm_d smoke
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta
/cluster forge-smoke-testing
/pipeline forge-full

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
projects/rhoai/library/deploy.py (1)

273-344: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the readiness check depend on staging config
wait_for_rhoai_pull_secret_ready() still requires RHOAI_REGISTRIES unconditionally, so a catalog-only deployment can write the catalog creds and then wait forever. Pass the required registry tuple from prepare_rhoai_pull_secret() instead of hardcoding both sets.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/rhoai/library/deploy.py` around lines 273 - 344, Update
prepare_rhoai_pull_secret and wait_for_rhoai_pull_secret_ready so readiness
validation receives the registries required by the current configuration. Use
RHOAI_CATALOG_REGISTRIES for catalog-only deployments and include
RHOAI_REGISTRIES only when staging_pull_secret is configured, passing the
resulting tuple to the readiness check instead of hardcoding both sets.
projects/llm_d/tests/test_profiles.py (1)

311-324: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Wait for MCP after applying the ICSP before deploying the custom catalog. The pull-secret wait only covers the secret update; icsp_applier() here just applies the manifest, and deploy_rhoai_custom_catalog() runs immediately after. If the ICSP triggers a new MachineConfigPool rollout, the catalog can start before the mirror policy reaches all nodes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/llm_d/tests/test_profiles.py` around lines 311 - 324, Update the
deployment flow exercised by prepare_rhoai_operator so it waits for MCP
readiness after icsp_applier() completes and before
deploy_rhoai_custom_catalog() starts. Add or invoke the existing MCP-wait
mechanism at that boundary, preserving the current call ordering and behavior
for the remaining catalog, subscription, and CRD steps.
🧹 Nitpick comments (1)
projects/llm_d/tests/test_profiles.py (1)

395-498: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing coverage for the idempotent "already present" merge path.

This test always starts from an empty {"auths": {}} current secret, so it never exercises prepare_rhoai_pull_secret's early-return branch when the required RHOAI/staging registries are already present (per the _registries_present(...) check in the upstream implementation). Worth adding a companion case to guard against accidental re-merges/MCP-rollouts on repeat runs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@projects/llm_d/tests/test_profiles.py` around lines 395 - 498, The test
coverage only exercises merging into an empty current secret and misses the
idempotent path guarded by _registries_present. Add a companion test for
prepare_rhoai_pull_secret with current_secret already containing the required
RHOAI and staging registry entries, assert the function returns without invoking
merge operations or triggering MCP rollout behavior, and preserve the existing
merge-case coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@projects/rhoai/library/deploy.py`:
- Around line 213-216: Update _registries_present to parse decoded_secret as
JSON and check registry keys for exact matches rather than using substring
membership, ensuring rhaii and rhaii-early-access remain distinct. Preserve the
existing all-registries requirement so the readiness check and
prepare_rhoai_pull_secret short-circuit both reflect actual credential entries.

---

Outside diff comments:
In `@projects/llm_d/tests/test_profiles.py`:
- Around line 311-324: Update the deployment flow exercised by
prepare_rhoai_operator so it waits for MCP readiness after icsp_applier()
completes and before deploy_rhoai_custom_catalog() starts. Add or invoke the
existing MCP-wait mechanism at that boundary, preserving the current call
ordering and behavior for the remaining catalog, subscription, and CRD steps.

In `@projects/rhoai/library/deploy.py`:
- Around line 273-344: Update prepare_rhoai_pull_secret and
wait_for_rhoai_pull_secret_ready so readiness validation receives the registries
required by the current configuration. Use RHOAI_CATALOG_REGISTRIES for
catalog-only deployments and include RHOAI_REGISTRIES only when
staging_pull_secret is configured, passing the resulting tuple to the readiness
check instead of hardcoding both sets.

---

Nitpick comments:
In `@projects/llm_d/tests/test_profiles.py`:
- Around line 395-498: The test coverage only exercises merging into an empty
current secret and misses the idempotent path guarded by _registries_present.
Add a companion test for prepare_rhoai_pull_secret with current_secret already
containing the required RHOAI and staging registry entries, assert the function
returns without invoking merge operations or triggering MCP rollout behavior,
and preserve the existing merge-case coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b2af1880-67eb-40c5-b8fa-37289e246ec1

📥 Commits

Reviewing files that changed from the base of the PR and between 8aec9f5 and 2006a4f.

📒 Files selected for processing (6)
  • projects/llm_d/orchestration/config.d/platform.yaml
  • projects/llm_d/orchestration/manifests/rhoai-registry-icsp.yaml
  • projects/llm_d/orchestration/prepare_phase.py
  • projects/llm_d/tests/test_profiles.py
  • projects/rhoai/library/deploy.py
  • vaults/psap-forge-staging-image-pull.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • projects/llm_d/orchestration/config.d/platform.yaml
  • projects/llm_d/orchestration/prepare_phase.py

Comment thread projects/rhoai/library/deploy.py Outdated
@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d smoke
/cluster forge-smoke-testing
/pipeline forge-full
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta

@psap-forge-bot

Copy link
Copy Markdown

🔴 Execution of llm_d smoke 🔴

Execution Engine Configuration

forge:
  args:
  - smoke
  configOverrides:
    platform.operators.rhods-operator.channel: beta
    platform.rhoai.custom_catalog.enabled: true
    platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
  project: llm_d

Artifact Links

Test Logs

00 Pre-Cleanup 7 seconds

01 Prepare 1 minute, 12 seconds

04 Post-Cleanup 12 seconds

🔄 05 Export-Artifacts

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of llm_d smoke failed after 4 minutes, 12 seconds 🔴

Error: FournosJobFailureError: FOURNOS Job 'forge-llm-d-20260713-104034' failed: Tasks Completed: 4 (Failed: 1, Cancelled 0), Skipped: 2

/test fournos llm_d smoke
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta
/cluster forge-smoke-testing
/pipeline forge-full

Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d smoke
/cluster forge-smoke-testing
/pipeline forge-full
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta

@psap-forge-bot

Copy link
Copy Markdown

🔴 Execution of llm_d smoke 🔴

Execution Engine Configuration

forge:
  args:
  - smoke
  configOverrides:
    platform.operators.rhods-operator.channel: beta
    platform.rhoai.custom_catalog.enabled: true
    platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
  project: llm_d

Artifact Links

Test Logs

00 Pre-Cleanup 6 seconds

01 Prepare 2 minutes, 11 seconds

02 Preflight 1 second

03 Test 1 minute, 40 seconds

Test Description

This test validates the llm_d project by deploying the Qwen/Qwen3-0.6B model using the approximate-prefix-cache deployment profile to evaluate prefix caching functionality. It executes a smoke test followed by a short benchmark measuring performance with 256 prompt tokens and 128 output tokens at concurrency rates of 1, 4, and 8.

Failure Review 001 Deploy Llmisvc

001__llmd_test/001__deploy_llmisvc

The apply_inference_service task failed to deploy the LLMInferenceService manifest because the oc apply command was rejected by the API server with an InternalError. This rejection was caused by the KServe admission webhook llminferenceservice.kserve-webhook-server.v1alpha1.defaulter returning a failure indicating it "could not find the requested resource" during the validation process.

04 Post-Cleanup 12 seconds

🔄 05 Export-Artifacts

Post-processing Status

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of llm_d smoke failed after 6 minutes, 37 seconds 🔴

Error: FournosJobFailureError: FOURNOS Job 'forge-llm-d-20260713-134623' failed: Tasks Completed: 6 (Failed: 1, Cancelled 0), Skipped: 0

/test fournos llm_d smoke
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta
/cluster forge-smoke-testing
/pipeline forge-full

Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d smoke
/cluster forge-smoke-testing
/pipeline forge-full
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta

@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of llm_d smoke 🟢

Execution Engine Configuration

forge:
  args:
  - smoke
  configOverrides:
    platform.operators.rhods-operator.channel: beta
    platform.rhoai.custom_catalog.enabled: true
    platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
  project: llm_d

Artifact Links

Test Logs

00 Pre-Cleanup 6 seconds

01 Prepare 2 minutes, 33 seconds

02 Preflight 1 second

03 Test 19 minutes, 5 seconds

Test Description

This test validates the llm_d project using the Qwen/Qwen3-0.6B model deployed with the approximate-prefix-cache profile. It performs a smoke test for basic functionality and executes a short benchmark with low concurrency rates (1-8) and short sequence lengths to verify performance and stability under light load with prefix caching enabled.

04 Post-Cleanup 15 seconds

🔄 05 Export-Artifacts

Post-processing Status

@psap-forge-bot

Copy link
Copy Markdown
🟢 Submission of llm_d smoke succeeded after 24 minutes, 28 seconds 🟢
/test fournos llm_d smoke
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta
/cluster forge-smoke-testing
/pipeline forge-full

@albertoperdomo2
albertoperdomo2 requested a review from kpouget July 13, 2026 19:45
Comment thread projects/cluster/toolbox/deploy_custom_catalog/main.py Outdated
Comment thread projects/llm_d/orchestration/test_phase.py Outdated
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
@albertoperdomo2
albertoperdomo2 requested a review from kpouget July 15, 2026 07:11
Comment on lines +38 to +47
for deployment_name in SERVING_CONTROL_PLANE_DEPLOYMENTS:
result = oc(
"wait",
"--for=condition=Available",
"--timeout=300s",
f"deployment/{deployment_name}",
"-n",
args.namespace,
check=False,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'll see how to rewrite that in another PR,
I'd like to:

  • remove the for loop, turn it into a @loop(SERVING_CONTROL_PLANE_DEPLOYMENTS)
  • remove the oc wait --timeout=300s, turn it into a polling with @retry

but that will wait :)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I can try to give it a go 😄

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nice :)
second part should be straightforward,
first part, my idea is to have something like Ansible loop
https://github.com/openshift-psap/topsail/blob/main/projects/fine_tuning/toolbox/fine_tuning_run_fine_tuning_job/tasks/main.yml#L123
so that the task body can focus on a single element

something like this [but I don't know how complex this would be to implement]

@retry
@loop(SERVING_CONTROL_PLANE_DEPLOYMENTS, "deploy")
@task
def wait_for_deployments(args, ctx):
    """Wait for all serving control plane deployments to be available"""

   check if ctx.deploy is ready

Comment thread projects/kserve/toolbox/wait_kserve_ready/main.py Outdated
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d smoke
/cluster forge-smoke-testing
/pipeline forge-full
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta

@psap-forge-bot

Copy link
Copy Markdown

🔴 Execution of llm_d smoke 🔴

Execution Engine Configuration

forge:
  args:
  - smoke
  configOverrides:
    platform.operators.rhods-operator.channel: beta
    platform.rhoai.custom_catalog.enabled: true
    platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
  project: llm_d

Artifact Links

Test Logs

00 Pre-Cleanup 11 seconds

01 Prepare 7 minutes, 38 seconds

Failure Review 011 Cluster Deploy Operator Rhcl-Operator

011__cluster_deploy_operator__rhcl-operator

The FORGE test failed when the wait_for_csv_to_appear task timed out after 5 minutes without detecting the rhcl-operator ClusterServiceVersion, despite the InstallPlan being successfully approved. Detailed artifact analysis confirms this was a test timeout caused by OLM reconciliation latency rather than a configuration error; the controller was actively processing a multi-CSV InstallPlan for rhcl-operator and servicemeshoperator3, and the environment required more time than the hardcoded threshold to pull and reconcile these large operator bundles.

04 Post-Cleanup 9 seconds

🔄 05 Export-Artifacts

@psap-forge-bot

Copy link
Copy Markdown
🔴 Submission of llm_d smoke failed after 9 minutes, 56 seconds 🔴

Error: FournosJobFailureError: FOURNOS Job 'forge-llm-d-20260715-085121' failed: Tasks Completed: 4 (Failed: 1, Cancelled 0), Skipped: 2

/test fournos llm_d smoke
/var platform.rhoai.custom_catalog.enabled: true
/var platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
/var platform.operators.rhods-operator.channel: beta
/cluster forge-smoke-testing
/pipeline forge-full

Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
Signed-off-by: Alberto Perdomo <aperdomo@redhat.com>
@albertoperdomo2

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d smoke
/cluster forge-smoke-testing
/pipeline forge-full
/rhoai.rc-image quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310

@psap-forge-bot

Copy link
Copy Markdown

🟢 Execution of llm_d smoke 🟢

Execution Engine Configuration

forge:
  args:
  - smoke
  configOverrides:
    platform.operators.rhods-operator.channel: beta
    platform.rhoai.custom_catalog.enabled: true
    platform.rhoai.custom_catalog.image: quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310
  project: llm_d

Artifact Links

Test Logs

00 Pre-Cleanup 9 seconds

01 Prepare 2 minutes, 36 seconds

02 Preflight 2 seconds

03 Test 11 minutes, 23 seconds

Test Description

This test validates the llm_d project by deploying the Qwen/Qwen3-0.6B model with the approximate-prefix-cache deployment profile and executing a short smoke benchmark. It verifies basic inference functionality and performance under low concurrency (rates 1, 4, 8) using 256 prompt tokens and 128 output tokens.

04 Post-Cleanup 16 seconds

🔄 05 Export-Artifacts

Post-processing Status

@psap-forge-bot

Copy link
Copy Markdown
🟢 Submission of llm_d smoke succeeded after 17 minutes, 1 second 🟢
/test fournos llm_d smoke
/cluster forge-smoke-testing
/pipeline forge-full
/rhoai.rc-image quay.io/rhoai/rhoai-fbc-fragment@sha256:e213152dc5bdaaf5724d269484914f3e1d7b4a4959d4405cb3eca9dd6297b310

@kpouget

kpouget commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

thanks @albertoperdomo2 , let's merge this!
/lgtm
/approve

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 15, 2026
@openshift-ci

openshift-ci Bot commented Jul 15, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kpouget

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 15, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 87a02b0 into openshift-psap:main Jul 15, 2026
7 checks passed
@albertoperdomo2
albertoperdomo2 deleted the feat/support-rc-images branch July 16, 2026 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants