Skip to content

Commit 1e1726d

Browse files
committed
Merge remote-tracking branch 'upstream/main' into rhoai-3.5-ea.2
2 parents 274a463 + 04d40eb commit 1e1726d

2 files changed

Lines changed: 139 additions & 46 deletions

File tree

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
bin/
2-
.vscode
3-
.claude
2+
.vscode/
3+
.claude/
4+
.cursor/
5+
.codegraph/

examples/deploy-demo/deploy-rhoai.sh

Lines changed: 135 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ KUADRANT_NAMESPACE="${KUADRANT_NAMESPACE:-kuadrant-system}"
2929

3030
OPERATOR_TYPE="${OPERATOR_TYPE:-rhoai}" # rhoai or odh
3131
CUSTOM_CATALOG="${CUSTOM_CATALOG:-}" # custom catalog image (e.g. quay.io/rhoai/rhoai-fbc-fragment:...)
32-
RHOAI_VERSION="${RHOAI_VERSION:-3.4}"
33-
RHOAI_CHANNEL="${RHOAI_CHANNEL:-stable-${RHOAI_VERSION}}"
32+
RHOAI_VERSION="${RHOAI_VERSION:-}"
33+
RHOAI_CHANNEL="${RHOAI_CHANNEL:-}"
3434
ODH_CHANNEL="${ODH_CHANNEL:-fast-3}"
3535
GATEWAY_CLASS_NAME="${GATEWAY_CLASS_NAME:-openshift-default}"
3636
GATEWAY_NAME="${GATEWAY_NAME:-openshift-ai-inference}"
@@ -337,6 +337,103 @@ EOF
337337

338338
# ── 5. RHOAI / ODH operator ─────────────────────────────────────────────────
339339

340+
# Resolve RHOAI version and channel (only called when installation is needed).
341+
# Queries PackageManifest (with retry), then:
342+
# - Version: user-provided RHOAI_VERSION, or highest from stable-X.Y / beta channels
343+
# - Channel: user-provided RHOAI_CHANNEL, or stable-${RHOAI_VERSION} preferred, then beta
344+
resolve_rhoai_info() {
345+
# Short-circuit: if both version and channel are already provided, skip detection
346+
if [ -n "${RHOAI_VERSION}" ] && [ -n "${RHOAI_CHANNEL}" ]; then
347+
log "Using user-specified RHOAI version: ${RHOAI_VERSION}"
348+
log "Using user-specified RHOAI channel: ${RHOAI_CHANNEL}"
349+
return 0
350+
fi
351+
352+
# Fetch PackageManifest (with retry — CatalogSource READY does not guarantee
353+
# PackageManifest is synced yet, especially for custom catalogs)
354+
local manifest_json=""
355+
local retries=0
356+
local max_retries=12 # 12 × 5s = 60s
357+
while [ -z "${manifest_json}" ]; do
358+
if [ -n "${CUSTOM_CATALOG}" ]; then
359+
local catalog_name="${OPERATOR_TYPE}-custom-catalog"
360+
manifest_json=$(kubectl get packagemanifest rhods-operator \
361+
-n openshift-marketplace -o json 2>/dev/null \
362+
| jq --arg cs "${catalog_name}" 'select(.status.catalogSource == $cs)') || true
363+
else
364+
manifest_json=$(kubectl get packagemanifest rhods-operator \
365+
-n openshift-marketplace -o json 2>/dev/null) || true
366+
fi
367+
if [ -n "${manifest_json}" ]; then
368+
break
369+
fi
370+
retries=$((retries + 1))
371+
if [ "${retries}" -ge "${max_retries}" ]; then
372+
die "PackageManifest 'rhods-operator' not found after ${max_retries} attempts. Is the catalog source available?"
373+
fi
374+
log "PackageManifest not yet available, retrying (${retries}/${max_retries})..."
375+
sleep 5
376+
done
377+
378+
# Resolve version
379+
if [ -n "${RHOAI_VERSION}" ]; then
380+
log "Using user-specified RHOAI version: ${RHOAI_VERSION}"
381+
else
382+
local csvs
383+
if [ -n "${RHOAI_CHANNEL}" ]; then
384+
step "Deriving RHOAI version from channel ${RHOAI_CHANNEL}..."
385+
csvs=$(echo "${manifest_json}" | jq -r --arg ch "${RHOAI_CHANNEL}" '
386+
.status.channels[] | select(.name == $ch) | .currentCSV // empty') || true
387+
else
388+
step "Auto-detecting latest RHOAI version..."
389+
csvs=$(echo "${manifest_json}" | jq -r '
390+
.status.channels[] |
391+
select((.name | test("^stable-[0-9]+\\.[0-9]+$")) or .name == "beta") |
392+
.currentCSV // empty') || true
393+
fi
394+
395+
RHOAI_VERSION=$(echo "${csvs}" \
396+
| grep -oE '^rhods-operator\.[0-9]+\.[0-9]+' \
397+
| sed 's/rhods-operator\.//' \
398+
| sort -t. -k1,1n -k2,2n -u | tail -1) || true
399+
400+
if [ -n "${RHOAI_VERSION}" ]; then
401+
log "Latest RHOAI version: ${RHOAI_VERSION}"
402+
else
403+
die "No RHOAI version found for rhods-operator."
404+
fi
405+
fi
406+
407+
# Resolve channel — prefer stable-X.Y > stable-X.x > beta
408+
if [ -n "${RHOAI_CHANNEL}" ]; then
409+
log "Using user-specified RHOAI channel: ${RHOAI_CHANNEL}"
410+
# Validate channel exists in catalog (catches typos in user-specified values)
411+
local validate_csv
412+
validate_csv=$(echo "${manifest_json}" | jq -r --arg ch "${RHOAI_CHANNEL}" '
413+
.status.channels[] | select(.name == $ch) | .currentCSV // empty') || true
414+
if [ -z "${validate_csv}" ]; then
415+
die "Channel '${RHOAI_CHANNEL}' not found in PackageManifest."
416+
fi
417+
else
418+
step "Auto-detecting RHOAI channel for version ${RHOAI_VERSION}..."
419+
local major="${RHOAI_VERSION%%.*}"
420+
local candidates=("stable-${RHOAI_VERSION}" "stable-${major}.x" "beta")
421+
for candidate in "${candidates[@]}"; do
422+
local csv
423+
csv=$(echo "${manifest_json}" | jq -r --arg ch "${candidate}" '
424+
.status.channels[] | select(.name == $ch) | .currentCSV // empty') || true
425+
if [ -n "${csv}" ] && [[ "${csv}" == rhods-operator.${RHOAI_VERSION}.* ]]; then
426+
RHOAI_CHANNEL="${candidate}"
427+
log "Channel '${candidate}' provides RHOAI ${RHOAI_VERSION} (CSV: ${csv})"
428+
break
429+
fi
430+
done
431+
if [ -z "${RHOAI_CHANNEL}" ]; then
432+
die "No channel provides RHOAI ${RHOAI_VERSION}. Checked: ${candidates[*]}"
433+
fi
434+
fi
435+
}
436+
340437
create_custom_catalogsource() {
341438
local name="$1"
342439
local namespace="$2"
@@ -388,42 +485,51 @@ install_rhoai_operator() {
388485
operator_name="rhods-operator"
389486
namespace="redhat-ods-operator"
390487
catalog="redhat-operators"
391-
channel="${RHOAI_CHANNEL}"
392488
;;
393489
odh)
394490
operator_name="opendatahub-operator"
395491
namespace="opendatahub"
396492
catalog="community-operators"
397-
channel="${ODH_CHANNEL}"
398493
;;
399494
*)
400495
die "Unknown OPERATOR_TYPE: ${OPERATOR_TYPE}. Use rhoai or odh."
401496
;;
402497
esac
403498

404-
# Custom catalog: create CatalogSource and override catalog source name
405-
if [ -n "${CUSTOM_CATALOG}" ]; then
406-
local custom_catalog_name="${OPERATOR_TYPE}-custom-catalog"
407-
log "Using custom catalog: ${CUSTOM_CATALOG}"
408-
create_custom_catalogsource "${custom_catalog_name}" "openshift-marketplace" "${CUSTOM_CATALOG}"
409-
catalog="${custom_catalog_name}"
410-
fi
411-
499+
# install operator
412500
if kubectl get subscription.operators.coreos.com "${operator_name}" \
413501
-n "${namespace}" &>/dev/null 2>&1; then
414502
log "${OPERATOR_TYPE} operator already installed. Skipping."
415503
else
416-
# Validate channel exists in catalog (skip for custom catalogs —
417-
# PackageManifest may not be synced yet after CatalogSource creation)
418-
if [ -z "${CUSTOM_CATALOG}" ]; then
419-
local available_channels
420-
available_channels=$(kubectl get packagemanifest "${operator_name}" \
421-
-n openshift-marketplace -o jsonpath='{.status.channels[*].name}' 2>/dev/null || echo "")
422-
if [ -z "${available_channels}" ]; then
423-
die "PackageManifest '${operator_name}' not found in catalog. Is the catalog source available?"
504+
# Custom catalog: create CatalogSource first so PackageManifest is
505+
# available for version/channel auto-detection
506+
if [ -n "${CUSTOM_CATALOG}" ]; then
507+
local custom_catalog_name="${OPERATOR_TYPE}-custom-catalog"
508+
log "Using custom catalog: ${CUSTOM_CATALOG}"
509+
create_custom_catalogsource "${custom_catalog_name}" "openshift-marketplace" "${CUSTOM_CATALOG}"
510+
catalog="${custom_catalog_name}"
511+
fi
512+
513+
# Resolve version and channel
514+
if [ "${OPERATOR_TYPE}" = "rhoai" ]; then
515+
resolve_rhoai_info
516+
channel="${RHOAI_CHANNEL}"
517+
else
518+
channel="${ODH_CHANNEL}"
519+
# Validate ODH channel exists before creating Subscription
520+
local pm_json
521+
pm_json=$(kubectl get packagemanifest "${operator_name}" \
522+
-n openshift-marketplace -o json 2>/dev/null) || true
523+
if [ -n "${CUSTOM_CATALOG}" ] && [ -n "${pm_json}" ]; then
524+
pm_json=$(echo "${pm_json}" | jq --arg cs "${custom_catalog_name}" \
525+
'select(.status.catalogSource == $cs)') || true
424526
fi
425-
if ! echo " ${available_channels} " | grep -q " ${channel} "; then
426-
die "Channel '${channel}' not found for '${operator_name}'. Available: ${available_channels}"
527+
if [ -n "${pm_json}" ]; then
528+
local available_channels
529+
available_channels=$(echo "${pm_json}" | jq -r '.status.channels[].name' | tr '\n' ' ') || true
530+
if [ -n "${available_channels}" ] && ! echo " ${available_channels} " | grep -q " ${channel} "; then
531+
die "Channel '${channel}' not found for '${operator_name}'. Available: ${available_channels}"
532+
fi
427533
fi
428534
fi
429535

@@ -453,8 +559,8 @@ EOF
453559
wait_for_subscription "${namespace}" "${operator_name}"
454560
fi
455561

456-
# Verify installed version matches expected version
457-
if [ "${OPERATOR_TYPE}" = "rhoai" ]; then
562+
# Verify installed version matches expected version (skipped when already installed and no version provided)
563+
if [ "${OPERATOR_TYPE}" = "rhoai" ] && [ -n "${RHOAI_VERSION}" ]; then
458564
local installed_csv
459565
installed_csv=$(kubectl get subscription.operators.coreos.com "${operator_name}" \
460566
-n "${namespace}" -o jsonpath='{.status.installedCSV}' 2>/dev/null || echo "")
@@ -466,24 +572,6 @@ EOF
466572
fi
467573
log "RHOAI installedCSV: ${installed_csv}"
468574
fi
469-
470-
# Verify operator was installed from the expected catalog source
471-
if [ -n "${CUSTOM_CATALOG}" ]; then
472-
local expected_catalog="${OPERATOR_TYPE}-custom-catalog"
473-
local install_plan
474-
install_plan=$(kubectl get subscription.operators.coreos.com "${operator_name}" \
475-
-n "${namespace}" -o jsonpath='{.status.installPlanRef.name}' 2>/dev/null || echo "")
476-
if [ -z "${install_plan}" ]; then
477-
die "No InstallPlan found for subscription '${operator_name}'."
478-
fi
479-
local actual_catalog
480-
actual_catalog=$(kubectl get installplan "${install_plan}" \
481-
-n "${namespace}" -o jsonpath='{.status.bundleLookups[0].catalogSourceRef.name}' 2>/dev/null || echo "")
482-
if [ "${actual_catalog}" != "${expected_catalog}" ]; then
483-
die "Operator installed from catalog '${actual_catalog}' instead of '${expected_catalog}'. Custom catalog was not used!"
484-
fi
485-
log "Verified: operator installed from custom catalog '${actual_catalog}'."
486-
fi
487575
}
488576

489577
apply_dsci_and_dsc() {
@@ -909,6 +997,9 @@ deploy_batch_gateway_rhoai() {
909997
--set "processor.config.modelGateways.${model_key}.initialBackoff=${GW_INITIAL_BACKOFF}"
910998
--set "processor.config.modelGateways.${model_key}.maxBackoff=${GW_MAX_BACKOFF}"
911999
--set "apiserver.config.batchAPI.passThroughHeaders={Authorization}"
1000+
# CI clusters have limited CPU; lower requests so the processor pod can be scheduled
1001+
--set "processor.resources.requests.cpu=100m"
1002+
--set "processor.resources.requests.memory=128Mi"
9121003
)
9131004

9141005
do_deploy_batch_gateway "${helm_args[@]}"
@@ -1182,8 +1273,8 @@ usage() {
11821273
echo "Environment Variables:"
11831274
echo " OPERATOR_TYPE rhoai or odh (default: rhoai)"
11841275
echo " CUSTOM_CATALOG Custom catalog image for operator (creates CatalogSource)"
1185-
echo " RHOAI_VERSION RHOAI version (default: 3.4)"
1186-
echo " RHOAI_CHANNEL OLM channel (default: stable-\${RHOAI_VERSION})"
1276+
echo " RHOAI_VERSION RHOAI version"
1277+
echo " RHOAI_CHANNEL RHOAI OLM channel"
11871278
echo " MODEL_NAME Model name for simulator (default: facebook/opt-125m)"
11881279
echo " MODEL_REPLICAS Number of replicas (default: 1)"
11891280
echo " SIM_IMAGE Simulator image (default: ghcr.io/llm-d/llm-d-inference-sim:v0.7.1)"

0 commit comments

Comments
 (0)