Skip to content

chore: remove 8 deprecated KFTO v1 training image sources and Tekton … - #979

Merged
openshift-merge-bot[bot] merged 2 commits into
opendatahub-io:mainfrom
abhijeet-dhumal:cleanup-deprecated-runtime-images
Aug 6, 2026
Merged

chore: remove 8 deprecated KFTO v1 training image sources and Tekton …#979
openshift-merge-bot[bot] merged 2 commits into
opendatahub-io:mainfrom
abhijeet-dhumal:cleanup-deprecated-runtime-images

Conversation

@abhijeet-dhumal

@abhijeet-dhumal abhijeet-dhumal commented Aug 3, 2026

Copy link
Copy Markdown
Member

Description

Remove 8 deprecated KFTO v1 training image sources and their 24 associated
Tekton pipelines (pull-request + push). Conforma exceptions for these images
have expired and they are decommissioned for RHOAI 3.6.

Ref: RHOAIENG-78708

Removed image directories

  • py311-cuda121-torch241
  • py311-cuda124-torch251
  • py311-rocm62-torch241
  • py311-rocm62-torch251
  • py312-cuda128-torch280
  • py312-cuda128-torch290
  • py312-rocm64-torch280
  • py312-rocm64-torch290

Retained (Trainer v2)

  • py312-cuda130-torch210-openmpi41
  • py312-rocm64-torch29-openmpi41

Docs updated

  • ARCHITECTURE.md training image listing
  • images/runtime/training/README.md examples and flash-attn status

How Has This Been Tested?

  • Verified remaining Trainer v2 image directories are intact
  • Grep-confirmed zero stale references to deleted paths in .tekton/, ARCHITECTURE.md, and README.md
  • Test/example quay.io/modh/training:py311-* references are out of scope (tracked under RHOAIENG-78705)

Summary by CodeRabbit

  • Removed

    • Retired multiple CUDA- and ROCm-based training runtime images and their automated build pipelines.
    • Removed related build configurations, dependency files, licenses, and support materials.
  • Documentation

    • Updated the runtime image inventory to reflect two OpenMPI-based variants.
    • Modernized dependency-management guidance with pyproject.toml, requirements.txt, and uv.
    • Updated training runtime examples to use the CUDA 13.0/PyTorch 2.10 image.
    • Refreshed Flash Attention guidance and verification commands.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The diff removes legacy CUDA and ROCm training image definitions, including Dockerfiles, dependency manifests, licenses, READMEs, and associated Tekton PipelineRuns. It removes older runtime and training image build pipelines with image publishing, scanning, signing, and tagging tasks. It updates the architecture inventory and training runtime documentation to reference CUDA 13.0/Torch 2.10 and ROCm 6.4/Torch 2.9 OpenMPI 4.1 images.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 10
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies removal of deprecated KFTO v1 training image sources and Tekton pipelines, which matches the main changes.
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.
Contribution Quality And Spam Detection ✅ Passed No CWE/CVE applies: the 69-file diff deletes deprecated images and Tekton pipelines, updates docs, adds no source, validation, tests, or scanner-style fix, and the author has prior repository history.
No Hardcoded Secrets ✅ Passed The cumulative diff adds 57 lines only; scans found zero secret assignments, credential URLs, private-key markers, or long base64 strings.
No Weak Cryptography ✅ Passed The patch adds no MD5, SHA-1, DES, RC4, 3DES, Blowfish, ECB, crypto APIs, custom crypto, or secret comparisons; changes are deletions, docs, and one image-path comment.
No Injection Vectors ✅ Passed PR adds only documentation and a Dockerfile comment; its hardcoded podman/uv example has no CWE-78, CWE-79, CWE-89, CWE-94, or CWE-502 pattern.
No Privileged Containers ✅ Passed The commit adds no privileged settings. Dockerfile.cuda uses USER 0 only for documented package/build steps and ends with USER 1001; deleted manifests contained no flagged settings.
No Sensitive Data In Logs ✅ Passed The diff adds only documentation and a Dockerfile comment; no logging statements or sensitive-data literals were added, and the remaining changes delete pipeline files.

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

@abhijeet-dhumal
abhijeet-dhumal force-pushed the cleanup-deprecated-runtime-images branch from d6b4baf to b0124a2 Compare August 3, 2026 08:37
@abhijeet-dhumal
abhijeet-dhumal marked this pull request as ready for review August 3, 2026 08:39
@openshift-ci
openshift-ci Bot requested review from chipspeak and sutaakar August 3, 2026 08:39
@abhijeet-dhumal
abhijeet-dhumal requested review from ChughShilpa, efazal, kapil27 and robert-bell and removed request for chipspeak August 3, 2026 08:40

@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: 4

🤖 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 `@ARCHITECTURE.md`:
- Around line 130-132: Update the stale training-image references in the Tekton
pull-request pipelines and benchmarks/osu-benchmarks/Dockerfile.cuda to use the
existing training/py312-cuda130-torch210-openmpi41 and
training/py312-rocm64-torch29-openmpi41 paths, or remove the retired pipelines
if they are no longer supported.

In `@images/runtime/training/README.md`:
- Line 37: Update the OpenMPI image dependency workflow instructions to use each
image’s pyproject.toml and requirements.txt with uv, replacing
Pipfile/Pipfile.lock edits and Pipenv commands. Regenerate requirements.txt
after updating dependencies, and change the flash-attn checks to validate
flash-attn==2.8.3 in both OpenMPI image directories so the documented CVE
workflow matches the Dockerfiles’ built dependency set.
- Around line 53-58: Update the py312-cuda130-torch210-openmpi41 lock-file
workflow to reference pyproject.toml and requirements.txt, replacing the
Pipfile/Pipfile.lock and pipenv lock steps with the Dockerfile’s uv pip compile
workflow. Remove the unnecessary openmpi41 qualifier from Python dependency
resolution while keeping OpenMPI handling separate.
- Line 57: Update the training image reference in the README command to use the
approved `@sha256` digest instead of the mutable :odh-stable tag. Before
documenting the container execution, verify the image signature and provenance
so only the approved image can generate the lock file.
🪄 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: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 4a078480-e27b-4982-841d-7bddb0bea879

📥 Commits

Reviewing files that changed from the base of the PR and between 86a3c05 and b0124a2.

⛔ Files ignored due to path filters (8)
  • images/runtime/training/py311-cuda121-torch241/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py311-cuda124-torch251/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py311-rocm62-torch241/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py311-rocm62-torch251/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py312-cuda128-torch280/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py312-cuda128-torch290/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py312-rocm64-torch280/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py312-rocm64-torch290/Pipfile.lock is excluded by !**/*.lock
📒 Files selected for processing (58)
  • .tekton/odh-training-cuda121-torch24-py311-pull-request.yaml
  • .tekton/odh-training-cuda121-torch24-py311-push.yaml
  • .tekton/odh-training-cuda124-torch25-py311-pull-request.yaml
  • .tekton/odh-training-cuda124-torch25-py311-push.yaml
  • .tekton/odh-training-cuda128-torch28-py312-pull-request.yaml
  • .tekton/odh-training-cuda128-torch28-py312-push.yaml
  • .tekton/odh-training-cuda128-torch29-py312-pull-request.yaml
  • .tekton/odh-training-cuda128-torch29-py312-push.yaml
  • .tekton/odh-training-rocm62-torch24-py311-pull-request.yaml
  • .tekton/odh-training-rocm62-torch24-py311-push.yaml
  • .tekton/odh-training-rocm62-torch25-py311-pull-request.yaml
  • .tekton/odh-training-rocm62-torch25-py311-push.yaml
  • .tekton/odh-training-rocm64-torch28-py312-pull-request.yaml
  • .tekton/odh-training-rocm64-torch28-py312-push.yaml
  • .tekton/odh-training-rocm64-torch29-py312-pull-request.yaml
  • .tekton/odh-training-rocm64-torch29-py312-push.yaml
  • .tekton/training-push-py311-cuda121-torch241.yaml
  • .tekton/training-push-py311-cuda124-torch251.yaml
  • .tekton/training-push-py311-rocm62-torch241.yaml
  • .tekton/training-push-py311-rocm62-torch251.yaml
  • .tekton/training-runtime-py312-cuda128-torch290-pull-request.yaml
  • .tekton/training-runtime-py312-cuda128-torch290-push.yaml
  • .tekton/training-runtime-py312-rocm64-torch290-pull-request.yaml
  • .tekton/training-runtime-py312-rocm64-torch290-push.yaml
  • ARCHITECTURE.md
  • images/runtime/training/README.md
  • images/runtime/training/py311-cuda121-torch241/Dockerfile
  • images/runtime/training/py311-cuda121-torch241/LICENSE.md
  • images/runtime/training/py311-cuda121-torch241/Pipfile
  • images/runtime/training/py311-cuda121-torch241/README.md
  • images/runtime/training/py311-cuda124-torch251/Dockerfile
  • images/runtime/training/py311-cuda124-torch251/LICENSE.md
  • images/runtime/training/py311-cuda124-torch251/Pipfile
  • images/runtime/training/py311-cuda124-torch251/README.md
  • images/runtime/training/py311-rocm62-torch241/Dockerfile
  • images/runtime/training/py311-rocm62-torch241/LICENSE.md
  • images/runtime/training/py311-rocm62-torch241/Pipfile
  • images/runtime/training/py311-rocm62-torch241/README.md
  • images/runtime/training/py311-rocm62-torch251/Dockerfile
  • images/runtime/training/py311-rocm62-torch251/LICENSE.md
  • images/runtime/training/py311-rocm62-torch251/Pipfile
  • images/runtime/training/py311-rocm62-torch251/README.md
  • images/runtime/training/py312-cuda128-torch280/Dockerfile
  • images/runtime/training/py312-cuda128-torch280/LICENSE.md
  • images/runtime/training/py312-cuda128-torch280/Pipfile
  • images/runtime/training/py312-cuda128-torch280/README.md
  • images/runtime/training/py312-cuda128-torch290/Dockerfile
  • images/runtime/training/py312-cuda128-torch290/LICENSE.md
  • images/runtime/training/py312-cuda128-torch290/Pipfile
  • images/runtime/training/py312-cuda128-torch290/README.md
  • images/runtime/training/py312-rocm64-torch280/Dockerfile
  • images/runtime/training/py312-rocm64-torch280/LICENSE.md
  • images/runtime/training/py312-rocm64-torch280/Pipfile
  • images/runtime/training/py312-rocm64-torch280/README.md
  • images/runtime/training/py312-rocm64-torch290/Dockerfile
  • images/runtime/training/py312-rocm64-torch290/LICENSE.md
  • images/runtime/training/py312-rocm64-torch290/Pipfile
  • images/runtime/training/py312-rocm64-torch290/README.md
💤 Files with no reviewable changes (56)
  • images/runtime/training/py311-cuda124-torch251/README.md
  • images/runtime/training/py312-rocm64-torch280/LICENSE.md
  • images/runtime/training/py312-rocm64-torch280/README.md
  • images/runtime/training/py311-rocm62-torch251/LICENSE.md
  • images/runtime/training/py311-rocm62-torch241/LICENSE.md
  • images/runtime/training/py312-cuda128-torch280/README.md
  • images/runtime/training/py311-rocm62-torch251/README.md
  • images/runtime/training/py311-cuda124-torch251/LICENSE.md
  • .tekton/odh-training-cuda128-torch28-py312-pull-request.yaml
  • images/runtime/training/py311-cuda121-torch241/LICENSE.md
  • images/runtime/training/py312-cuda128-torch290/Dockerfile
  • images/runtime/training/py312-cuda128-torch280/Dockerfile
  • images/runtime/training/py312-rocm64-torch290/Pipfile
  • images/runtime/training/py312-rocm64-torch290/README.md
  • images/runtime/training/py311-rocm62-torch241/Dockerfile
  • images/runtime/training/py311-cuda121-torch241/Dockerfile
  • images/runtime/training/py311-rocm62-torch251/Dockerfile
  • images/runtime/training/py311-rocm62-torch241/README.md
  • images/runtime/training/py312-cuda128-torch290/Pipfile
  • images/runtime/training/py311-cuda121-torch241/README.md
  • images/runtime/training/py312-cuda128-torch280/Pipfile
  • .tekton/odh-training-rocm62-torch24-py311-push.yaml
  • images/runtime/training/py311-cuda124-torch251/Dockerfile
  • images/runtime/training/py311-cuda124-torch251/Pipfile
  • .tekton/odh-training-rocm62-torch25-py311-push.yaml
  • .tekton/training-push-py311-rocm62-torch251.yaml
  • .tekton/odh-training-cuda121-torch24-py311-pull-request.yaml
  • .tekton/training-runtime-py312-cuda128-torch290-pull-request.yaml
  • images/runtime/training/py312-cuda128-torch280/LICENSE.md
  • images/runtime/training/py311-rocm62-torch251/Pipfile
  • .tekton/training-runtime-py312-rocm64-torch290-push.yaml
  • images/runtime/training/py312-rocm64-torch290/Dockerfile
  • .tekton/odh-training-cuda121-torch24-py311-push.yaml
  • .tekton/training-runtime-py312-rocm64-torch290-pull-request.yaml
  • .tekton/odh-training-cuda128-torch28-py312-push.yaml
  • images/runtime/training/py312-rocm64-torch280/Pipfile
  • .tekton/odh-training-cuda124-torch25-py311-pull-request.yaml
  • .tekton/training-push-py311-cuda124-torch251.yaml
  • images/runtime/training/py312-cuda128-torch290/LICENSE.md
  • .tekton/odh-training-cuda128-torch29-py312-push.yaml
  • .tekton/odh-training-rocm62-torch25-py311-pull-request.yaml
  • .tekton/odh-training-cuda128-torch29-py312-pull-request.yaml
  • images/runtime/training/py311-cuda121-torch241/Pipfile
  • .tekton/odh-training-rocm62-torch24-py311-pull-request.yaml
  • images/runtime/training/py312-rocm64-torch290/LICENSE.md
  • images/runtime/training/py311-rocm62-torch241/Pipfile
  • .tekton/odh-training-cuda124-torch25-py311-push.yaml
  • .tekton/odh-training-rocm64-torch29-py312-push.yaml
  • .tekton/training-runtime-py312-cuda128-torch290-push.yaml
  • .tekton/odh-training-rocm64-torch28-py312-pull-request.yaml
  • images/runtime/training/py312-cuda128-torch290/README.md
  • .tekton/odh-training-rocm64-torch29-py312-pull-request.yaml
  • images/runtime/training/py312-rocm64-torch280/Dockerfile
  • .tekton/training-push-py311-cuda121-torch241.yaml
  • .tekton/training-push-py311-rocm62-torch241.yaml
  • .tekton/odh-training-rocm64-torch28-py312-push.yaml

Comment thread ARCHITECTURE.md
Comment thread images/runtime/training/README.md Outdated
Comment thread images/runtime/training/README.md Outdated
# 1. Start container
podman run --rm -d --name pipenv-lock \
quay.io/opendatahub/odh-training-cuda128-torch28-py312-rhel9:odh-stable \
quay.io/opendatahub/odh-training-cuda130-torch210-py312-rhel9:odh-stable \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

printf '%s\n' '--- README context ---'
sed -n '45,70p' images/runtime/training/README.md
printf '%s\n' '--- related image references ---'
rg -n --glob '!*node_modules*' 'odh-training-cuda130-torch210-py312-rhel9|odh-stable|cosign|signature|digest' images .github 2>/dev/null | head -200

Repository: opendatahub-io/distributed-workloads

Length of output: 1227


🏁 Script executed:

set -eu
image='opendatahub/odh-training-cuda130-torch210-py312-rhel9'
tag='odh-stable'

printf '%s\n' '--- Quay tag metadata ---'
curl -fsSL "https://quay.io/api/v1/repository/${image}/tag/?specificTag=${tag}" |
  python3 -c 'import json,sys; d=json.load(sys.stdin); print(json.dumps(d, indent=2, sort_keys=True))' |
  sed -n '1,160p'

printf '%s\n' '--- registry manifest headers ---'
curl -sSI -H 'Accept: application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.distribution.manifest.list.v2+json' \
  "https://quay.io/v2/${image}/manifests/${tag}" |
  sed -n '1,80p'

printf '%s\n' '--- local guidance for image trust ---'
rg -n -i --glob '*.md' --glob '*.yaml' --glob '*.yml' --glob '*.sh' \
  'quay.io|cosign|sigstore|signature|provenance|slsa|digest|image pin' . 2>/dev/null | head -240

Repository: opendatahub-io/distributed-workloads

Length of output: 7108


🏁 Script executed:

set -eu
image='opendatahub/odh-training-cuda130-torch210-py312-rhel9'
tag='odh-stable'
scope="repository:${image}:pull"

auth_json="$(curl -fsSLG \
  --data-urlencode 'service=quay.io' \
  --data-urlencode "scope=${scope}" \
  'https://quay.io/v2/auth')"
token="$(printf '%s' "$auth_json" | python3 -c 'import json,sys; print(json.load(sys.stdin)["token"])')"

printf '%s\n' '--- resolved manifest digest ---'
curl -fsSI \
  -H "Authorization: Bearer ${token}" \
  -H 'Accept: application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json' \
  "https://quay.io/v2/${image}/manifests/${tag}" |
  tr -d '\r' |
  grep -Ei '^(HTTP/|docker-content-digest:|content-type:)' || true

printf '%s\n' '--- README image notes ---'
sed -n '88,108p' images/runtime/training/README.md

Repository: opendatahub-io/distributed-workloads

Length of output: 1010


Pin the training image to an approved digest and verify its provenance.

Replace :odh-stable with @sha256:<approved-digest> before running the container. Verify the image signature and provenance to prevent an unreviewed image from generating a poisoned lock file. This creates CWE-494 risk.

🤖 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 `@images/runtime/training/README.md` at line 57, Update the training image
reference in the README command to use the approved `@sha256` digest instead of
the mutable :odh-stable tag. Before documenting the container execution, verify
the image signature and provenance so only the approved image can generate the
lock file.

Source: Path instructions

@ChughShilpa

Copy link
Copy Markdown
Contributor

Keep this PR on hold until new images are onboarded

@robert-bell robert-bell left a comment

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.

/lgtm

Do we need to ask devops to decommission anything? E.g. konflux offboarding?

@ChughShilpa - ptal if you can.

Comment thread images/runtime/training/README.md Outdated

# 2. Copy Pipfile
podman cp py312-cuda128-torch280/Pipfile pipenv-lock:/opt/app-root/src/
podman cp py312-cuda130-torch210-openmpi41/Pipfile pipenv-lock:/opt/app-root/src/

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.

nit: needs updating to uv

Comment thread images/runtime/training/README.md Outdated

# 4. Copy lock file back
podman cp pipenv-lock:/opt/app-root/src/Pipfile.lock py312-cuda128-torch280/
podman cp pipenv-lock:/opt/app-root/src/Pipfile.lock py312-cuda130-torch210-openmpi41/

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.

nit: needs updating to uv

Comment thread ARCHITECTURE.md
@ChughShilpa

Copy link
Copy Markdown
Contributor

/lgtm

Do we need to ask devops to decommission anything? E.g. konflux offboarding?

@ChughShilpa - ptal if you can.

Yes devops will do the konflux offboarding

@ChughShilpa

Copy link
Copy Markdown
Contributor

#979 (comment)

@ChughShilpa do you know if it's safe to remove them from a testing/ops perspective? They're not used in prod afaik.

@robert-bell
For released versions, tests used the source code from release branches of https://github.com/red-hat-data-services/distributed-workloads, so it is safe to remove from here

…pipelines

Signed-off-by: abhijeet-dhumal <abhijeetdhumal652@gmail.com>
Signed-off-by: abhijeet-dhumal <abhijeetdhumal652@gmail.com>
@abhijeet-dhumal
abhijeet-dhumal force-pushed the cleanup-deprecated-runtime-images branch from b0124a2 to d8c33de Compare August 6, 2026 07:25
@openshift-ci openshift-ci Bot removed the lgtm label Aug 6, 2026
@abhijeet-dhumal
abhijeet-dhumal marked this pull request as ready for review August 6, 2026 07:26
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@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: 2

Caution

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

⚠️ Outside diff range comments (2)
benchmarks/osu-benchmarks/Dockerfile.cuda (2)

1-5: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Use a builder stage for OSU compilation.

This Dockerfile installs compilers and CUDA development packages, builds OSU, and removes them in the same final stage. The required Dockerfile policy is multi-stage. Move compilation to a builder stage and copy only /usr/local/osu-benchmarks into a clean runtime stage. dnf remove is not a substitute for stage separation.

As per path instructions: “Use multi-stage builds.”

🤖 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 `@benchmarks/osu-benchmarks/Dockerfile.cuda` around lines 1 - 5, Convert the
Dockerfile into a multi-stage build: use a builder stage based on
TRAINING_BASE_IMAGE to install compilers and CUDA development packages and
compile OSU, then create a clean runtime stage from the same base image and copy
only /usr/local/osu-benchmarks from the builder. Remove the same-stage cleanup
approach and preserve the existing TRAINING_BASE_IMAGE build argument.

Source: Path instructions


1-5: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use the published training image as the default base.

CI builds Dockerfile.cuda without a TRAINING_BASE_IMAGE override. The build therefore pulls quay.io/ksuta/odh-mpi-cuda:0.0.14 instead of the repository’s published training image. Set the default to quay.io/opendatahub/odh-training-cuda130-torch210-py312-openmpi41:odh-stable with an approved digest. This prevents an unreviewed base image from entering the benchmark supply chain (CWE-829).

🤖 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 `@benchmarks/osu-benchmarks/Dockerfile.cuda` around lines 1 - 5, Update the
TRAINING_BASE_IMAGE default in Dockerfile.cuda to
quay.io/opendatahub/odh-training-cuda130-torch210-py312-openmpi41:odh-stable and
pin it to the approved image digest, while preserving the existing build-time
override behavior.
🤖 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 `@images/runtime/training/README.md`:
- Around line 59-62: Update the uv pip compile command in the README to remove
the unsafe-best-match index strategy and use first-index with the curated RHAI
index prioritized before PyPI, then regenerate requirements.txt using the
corrected resolver configuration.
- Line 11: Update the runtime training README package-index documentation to
describe each build path accurately: CUDA uses the curated Red Hat RHAI index,
ROCm prioritizes RHAI with PyPI as fallback, and Konflux Dockerfiles use the
hermetic PIP_FIND_LINKS wheel set with --no-index. Align each documented
requirements.txt generation command with its corresponding Dockerfile path.

---

Outside diff comments:
In `@benchmarks/osu-benchmarks/Dockerfile.cuda`:
- Around line 1-5: Convert the Dockerfile into a multi-stage build: use a
builder stage based on TRAINING_BASE_IMAGE to install compilers and CUDA
development packages and compile OSU, then create a clean runtime stage from the
same base image and copy only /usr/local/osu-benchmarks from the builder. Remove
the same-stage cleanup approach and preserve the existing TRAINING_BASE_IMAGE
build argument.
- Around line 1-5: Update the TRAINING_BASE_IMAGE default in Dockerfile.cuda to
quay.io/opendatahub/odh-training-cuda130-torch210-py312-openmpi41:odh-stable and
pin it to the approved image digest, while preserving the existing build-time
override behavior.
🪄 Autofix

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: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 19584549-a187-4d3d-be42-622ad95368ab

📥 Commits

Reviewing files that changed from the base of the PR and between 4c138d2 and d8c33de.

⛔ Files ignored due to path filters (8)
  • images/runtime/training/py311-cuda121-torch241/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py311-cuda124-torch251/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py311-rocm62-torch241/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py311-rocm62-torch251/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py312-cuda128-torch280/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py312-cuda128-torch290/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py312-rocm64-torch280/Pipfile.lock is excluded by !**/*.lock
  • images/runtime/training/py312-rocm64-torch290/Pipfile.lock is excluded by !**/*.lock
📒 Files selected for processing (61)
  • .tekton/odh-training-cuda121-torch24-py311-pull-request.yaml
  • .tekton/odh-training-cuda121-torch24-py311-push.yaml
  • .tekton/odh-training-cuda124-torch25-py311-pull-request.yaml
  • .tekton/odh-training-cuda124-torch25-py311-push.yaml
  • .tekton/odh-training-cuda128-torch28-py312-pull-request.yaml
  • .tekton/odh-training-cuda128-torch28-py312-push.yaml
  • .tekton/odh-training-cuda128-torch29-py312-pull-request.yaml
  • .tekton/odh-training-cuda128-torch29-py312-push.yaml
  • .tekton/odh-training-rocm62-torch24-py311-pull-request.yaml
  • .tekton/odh-training-rocm62-torch24-py311-push.yaml
  • .tekton/odh-training-rocm62-torch25-py311-pull-request.yaml
  • .tekton/odh-training-rocm62-torch25-py311-push.yaml
  • .tekton/odh-training-rocm64-torch28-py312-pull-request.yaml
  • .tekton/odh-training-rocm64-torch28-py312-push.yaml
  • .tekton/odh-training-rocm64-torch29-py312-pull-request.yaml
  • .tekton/odh-training-rocm64-torch29-py312-push.yaml
  • .tekton/training-cuda-pull-request.yaml
  • .tekton/training-push-py311-cuda121-torch241.yaml
  • .tekton/training-push-py311-cuda124-torch251.yaml
  • .tekton/training-push-py311-rocm62-torch241.yaml
  • .tekton/training-push-py311-rocm62-torch251.yaml
  • .tekton/training-rocm-pull-request.yaml
  • .tekton/training-runtime-py312-cuda128-torch290-pull-request.yaml
  • .tekton/training-runtime-py312-cuda128-torch290-push.yaml
  • .tekton/training-runtime-py312-rocm64-torch290-pull-request.yaml
  • .tekton/training-runtime-py312-rocm64-torch290-push.yaml
  • ARCHITECTURE.md
  • benchmarks/osu-benchmarks/Dockerfile.cuda
  • images/runtime/training/README.md
  • images/runtime/training/py311-cuda121-torch241/Dockerfile
  • images/runtime/training/py311-cuda121-torch241/LICENSE.md
  • images/runtime/training/py311-cuda121-torch241/Pipfile
  • images/runtime/training/py311-cuda121-torch241/README.md
  • images/runtime/training/py311-cuda124-torch251/Dockerfile
  • images/runtime/training/py311-cuda124-torch251/LICENSE.md
  • images/runtime/training/py311-cuda124-torch251/Pipfile
  • images/runtime/training/py311-cuda124-torch251/README.md
  • images/runtime/training/py311-rocm62-torch241/Dockerfile
  • images/runtime/training/py311-rocm62-torch241/LICENSE.md
  • images/runtime/training/py311-rocm62-torch241/Pipfile
  • images/runtime/training/py311-rocm62-torch241/README.md
  • images/runtime/training/py311-rocm62-torch251/Dockerfile
  • images/runtime/training/py311-rocm62-torch251/LICENSE.md
  • images/runtime/training/py311-rocm62-torch251/Pipfile
  • images/runtime/training/py311-rocm62-torch251/README.md
  • images/runtime/training/py312-cuda128-torch280/Dockerfile
  • images/runtime/training/py312-cuda128-torch280/LICENSE.md
  • images/runtime/training/py312-cuda128-torch280/Pipfile
  • images/runtime/training/py312-cuda128-torch280/README.md
  • images/runtime/training/py312-cuda128-torch290/Dockerfile
  • images/runtime/training/py312-cuda128-torch290/LICENSE.md
  • images/runtime/training/py312-cuda128-torch290/Pipfile
  • images/runtime/training/py312-cuda128-torch290/README.md
  • images/runtime/training/py312-rocm64-torch280/Dockerfile
  • images/runtime/training/py312-rocm64-torch280/LICENSE.md
  • images/runtime/training/py312-rocm64-torch280/Pipfile
  • images/runtime/training/py312-rocm64-torch280/README.md
  • images/runtime/training/py312-rocm64-torch290/Dockerfile
  • images/runtime/training/py312-rocm64-torch290/LICENSE.md
  • images/runtime/training/py312-rocm64-torch290/Pipfile
  • images/runtime/training/py312-rocm64-torch290/README.md
💤 Files with no reviewable changes (58)
  • images/runtime/training/py311-rocm62-torch241/README.md
  • images/runtime/training/py311-cuda121-torch241/Pipfile
  • .tekton/training-push-py311-cuda124-torch251.yaml
  • images/runtime/training/py312-rocm64-torch280/LICENSE.md
  • images/runtime/training/py312-cuda128-torch280/LICENSE.md
  • images/runtime/training/py311-cuda121-torch241/README.md
  • images/runtime/training/py312-cuda128-torch290/Pipfile
  • .tekton/odh-training-cuda121-torch24-py311-push.yaml
  • .tekton/odh-training-cuda121-torch24-py311-pull-request.yaml
  • images/runtime/training/py311-rocm62-torch241/Dockerfile
  • .tekton/odh-training-cuda128-torch28-py312-pull-request.yaml
  • images/runtime/training/py311-rocm62-torch241/Pipfile
  • images/runtime/training/py312-rocm64-torch290/Dockerfile
  • .tekton/odh-training-rocm62-torch25-py311-pull-request.yaml
  • images/runtime/training/py311-cuda124-torch251/Dockerfile
  • images/runtime/training/py312-cuda128-torch280/Dockerfile
  • .tekton/odh-training-cuda124-torch25-py311-push.yaml
  • images/runtime/training/py312-cuda128-torch280/Pipfile
  • images/runtime/training/py311-cuda124-torch251/README.md
  • .tekton/training-push-py311-cuda121-torch241.yaml
  • images/runtime/training/py312-rocm64-torch290/README.md
  • images/runtime/training/py312-rocm64-torch280/README.md
  • .tekton/training-cuda-pull-request.yaml
  • .tekton/odh-training-rocm64-torch29-py312-pull-request.yaml
  • .tekton/odh-training-rocm62-torch24-py311-pull-request.yaml
  • .tekton/training-runtime-py312-cuda128-torch290-pull-request.yaml
  • .tekton/odh-training-cuda128-torch29-py312-pull-request.yaml
  • images/runtime/training/py312-rocm64-torch290/Pipfile
  • images/runtime/training/py312-rocm64-torch280/Pipfile
  • .tekton/odh-training-rocm64-torch28-py312-pull-request.yaml
  • images/runtime/training/py312-cuda128-torch290/README.md
  • images/runtime/training/py311-rocm62-torch251/Pipfile
  • .tekton/training-runtime-py312-rocm64-torch290-push.yaml
  • .tekton/odh-training-rocm64-torch28-py312-push.yaml
  • .tekton/training-rocm-pull-request.yaml
  • images/runtime/training/py312-cuda128-torch290/LICENSE.md
  • images/runtime/training/py311-cuda124-torch251/LICENSE.md
  • images/runtime/training/py312-rocm64-torch280/Dockerfile
  • images/runtime/training/py312-rocm64-torch290/LICENSE.md
  • .tekton/training-runtime-py312-cuda128-torch290-push.yaml
  • .tekton/odh-training-rocm62-torch24-py311-push.yaml
  • .tekton/odh-training-cuda128-torch29-py312-push.yaml
  • images/runtime/training/py312-cuda128-torch290/Dockerfile
  • .tekton/training-push-py311-rocm62-torch241.yaml
  • images/runtime/training/py311-rocm62-torch251/Dockerfile
  • images/runtime/training/py311-rocm62-torch251/LICENSE.md
  • .tekton/odh-training-rocm62-torch25-py311-push.yaml
  • .tekton/odh-training-cuda128-torch28-py312-push.yaml
  • images/runtime/training/py311-rocm62-torch241/LICENSE.md
  • images/runtime/training/py311-cuda121-torch241/LICENSE.md
  • images/runtime/training/py311-cuda124-torch251/Pipfile
  • .tekton/training-runtime-py312-rocm64-torch290-pull-request.yaml
  • images/runtime/training/py311-rocm62-torch251/README.md
  • images/runtime/training/py312-cuda128-torch280/README.md
  • .tekton/odh-training-rocm64-torch29-py312-push.yaml
  • images/runtime/training/py311-cuda121-torch241/Dockerfile
  • .tekton/odh-training-cuda124-torch25-py311-pull-request.yaml
  • .tekton/training-push-py311-rocm62-torch251.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • ARCHITECTURE.md

## CVE Fixes — Python dependency updates

The runtime training images install Python packages from **public PyPI** (unlike universal training images which use the private AIPCC index). Each image uses `Pipfile` + `Pipfile.lock` (pipenv).
The runtime training images install Python packages from **public PyPI** (unlike universal training images which use the private AIPCC index).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 2 -- \
  'public PyPI|index-url|extra-index-url|uv pip install|requirements.txt' \
  images/runtime/training/README.md \
  images/runtime/training/py312-cuda130-torch210-openmpi41 \
  images/runtime/training/py312-rocm64-torch29-openmpi41

Repository: opendatahub-io/distributed-workloads

Length of output: 13829


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

for f in \
  images/runtime/training/README.md \
  images/runtime/training/py312-cuda130-torch210-openmpi41/pyproject.toml \
  images/runtime/training/py312-cuda130-torch210-openmpi41/requirements.txt \
  images/runtime/training/py312-cuda130-torch210-openmpi41/Dockerfile \
  images/runtime/training/py312-cuda130-torch210-openmpi41/Dockerfile.konflux \
  images/runtime/training/py312-rocm64-torch29-openmpi41/pyproject.toml \
  images/runtime/training/py312-rocm64-torch29-openmpi41/requirements.txt \
  images/runtime/training/py312-rocm64-torch29-openmpi41/Dockerfile \
  images/runtime/training/py312-rocm64-torch29-openmpi41/Dockerfile.konflux
do
  if [ -f "$f" ]; then
    echo "===== $f ====="
    cat -n "$f" | sed -n \
      -e '1,12p' \
      -e '/index-url/,+4p' \
      -e '/uv pip install/,+8p' \
      -e '/PIP_FIND_LINKS/,+4p'
  fi
done

echo "===== all relevant source references ====="
rg -n -C 2 --glob '!**/requirements.txt' --glob '!**/README.md' \
  'public-rhai|AIPCC|PIP_FIND_LINKS|pypi\.org|index-url|extra-index-url' \
  images/runtime/training

Repository: opendatahub-io/distributed-workloads

Length of output: 17177


🌐 Web query:

What is console.redhat.com/api/pypi/public-rhai/rhoai/3.4 and is it a public PyPI mirror or a Red Hat RHAI package index?

💡 Result:

The URL console.redhat.com/api/pypi/public-rhai/rhoai/3.4 is part of the Red Hat AI (RHAI) Python package index system [1][2][3]. It is not a general-purpose public PyPI mirror, but rather a curated, maintained repository of Python packages that have been built, vetted, and shipped by Red Hat specifically for use with Red Hat OpenShift AI (RHOAI) workloads [4][5][3]. Key characteristics of this index include: 1. Purpose: It provides a secure, reliable software supply chain for RHOAI environments [4][3]. By using packages from this index, users benefit from Red Hat's testing and vetting processes, which are designed to reduce risks associated with untrusted dependencies [3]. 2. Scope: It is not a complete mirror of the public PyPI registry [3]. It contains a specific, limited collection of packages—primarily those focused on machine learning, data processing, and LLM-related workloads—that are supported for use with RHOAI [3]. 3. Usage: Workbench images in OpenShift AI are typically pre-configured to use this index [4][5][3]. When installing packages in these environments, pip and uv are pre-configured to pull from this specific index to ensure secure and consistent deployments [4][5]. 4. Disconnected Environments: The index supports disconnected environments, where organizations may mirror this content locally to maintain their own internal hosting services for air-gapped deployments [4][6][5]. In summary, it is a specialized, curated package index provided by Red Hat for its AI platform, rather than a general public PyPI mirror [3].

Citations:


Document the package index for each build path.

Replace the “public PyPI” statement. CUDA uses the curated Red Hat RHAI index. ROCm uses RHAI first and PyPI only as a fallback. Konflux Dockerfiles install from the hermetic PIP_FIND_LINKS wheel set with --no-index. Document these sources and keep the requirements.txt generation commands aligned with each Dockerfile path.

🤖 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 `@images/runtime/training/README.md` at line 11, Update the runtime training
README package-index documentation to describe each build path accurately: CUDA
uses the curated Red Hat RHAI index, ROCm prioritizes RHAI with PyPI as
fallback, and Konflux Dockerfiles use the hermetic PIP_FIND_LINKS wheel set with
--no-index. Align each documented requirements.txt generation command with its
corresponding Dockerfile path.

Comment on lines +59 to +62
uv pip compile --python-platform=linux --python-version=3.12 \
--index-url=https://console.redhat.com/api/pypi/public-rhai/rhoai/3.4/rocm6.4-ubi9-test/simple/ \
--extra-index-url=https://pypi.org/simple --index-strategy=unsafe-best-match \
-o requirements.txt pyproject.toml

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

uv pip compile index-strategy unsafe-best-match extra-index-url index priority first-index official docs

💡 Result:

In uv, the index strategy determines how the tool resolves dependencies when multiple package indexes are configured. You can configure this via the --index-strategy command-line flag or the UV_INDEX_STRATEGY environment variable [1][2]. The available strategies are: first-index (Default): uv searches for each package across all configured indexes and limits candidate versions to those found in the first index that contains the package [3][1]. This strategy is designed to prevent "dependency confusion" attacks by stopping at the first index that provides a match [4][5]. unsafe-first-match: uv searches all indexes for a package but prefers the first index that provides a compatible version, even if newer versions are available on subsequent indexes [4][1]. unsafe-best-match: This strategy most closely aligns with standard pip behavior [4][2]. It searches all configured indexes for a package, considers all versions from the combined set of candidates, and selects the "best" (typically the highest compatible) version [4][1]. Note that while this provides the most flexibility, it exposes users to "dependency confusion" risks where malicious actors may publish packages with the same names to public indexes [4][2]. Regarding index priority and configuration: Index Priority: Indexes are consulted in the order they are defined [1]. Indexes provided via command-line arguments take precedence over those defined in configuration files [1]. Among indexes, those defined via --extra-index-url or the [[tool.uv.index]] configuration are given higher priority than the default index (often PyPI) [3][1]. Configuration: While --index-url and --extra-index-url are supported for pip compatibility, the recommended approach is to use [[tool.uv.index]] in your pyproject.toml [1]. When using multiple indexes, the order in which they appear determines the resolution precedence [1][6]. For uv pip compile specifically, the tool does not write index URLs to the output file by default [2]. If you need the index URLs to be included in your generated requirements.txt, you must pass the --emit-index-url flag [2]. Unlike pip-compile, if this flag is used, uv will include all configured index URLs in the output [2].

Citations:


Security Misconfiguration (CWE-427)

Reachability: External

Block the unsafe multi-index resolver configuration.

unsafe-best-match selects the best compatible candidate across both indexes. A public PyPI package can replace a curated RHAI package or satisfy an unpinned transitive dependency. Use first-index with the RHAI index first, or define explicit package-to-index mappings, before regenerating requirements.txt.

🤖 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 `@images/runtime/training/README.md` around lines 59 - 62, Update the uv pip
compile command in the README to remove the unsafe-best-match index strategy and
use first-index with the curated RHAI index prioritized before PyPI, then
regenerate requirements.txt using the corrected resolver configuration.

@ChughShilpa ChughShilpa left a comment

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.

/lgtm

@openshift-ci

openshift-ci Bot commented Aug 6, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ChughShilpa, robert-bell

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-merge-bot
openshift-merge-bot Bot merged commit 6afc6c9 into opendatahub-io:main Aug 6, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants