feat(lightspeed): replace RAG init container with OKP deployment - #3370
feat(lightspeed): replace RAG init container with OKP deployment #3370maysunfaisal wants to merge 3 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3370 +/- ##
==========================================
+ Coverage 63.97% 65.74% +1.76%
==========================================
Files 38 43 +5
Lines 2365 2633 +268
==========================================
+ Hits 1513 1731 +218
- Misses 702 747 +45
- Partials 150 155 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
51db81c to
3bbec01
Compare
| selectorLabels := okpSelectorLabels(backstage.Name) | ||
|
|
||
| // OKP Deployment | ||
| deployment := &appsv1.Deployment{ |
There was a problem hiding this comment.
@maysunfaisal Though I'll mostly let the @redhat-developer/rhdh-install team comment on the operator source changes I'll make one comment on this part.
It makes sense to have controller parsing for OpenShift only parts, I wondering if it would be better to have the OKP deployment specification either in a OKP flavour or a separate OKP deployment specification within the lightspeed (intelligent-assistant) flavour that this controller source parses?
I'm considering the different non-lightspeed flavours users and customers may use as well as any automated patching that may be used here (i.e. patching the OKP image).
fyi @gazarenkov @rm3l
There was a problem hiding this comment.
Valid concern @michael-valdron
Midstream digest-pinning scans YAML manifests, not Go source, so it would miss the OKP image ref in okp.go. A couple of things worth noting:
- OKP is already lightspeed-only at runtime — applyOkpResources gates on IsFlavourEnabled("lightspeed") && IsOpenshift(), so non-lightspeed users get zero OKP resources today. That said, having it described declaratively in the flavour is cleaner.
- The move is non-trivial:
- the operator's config kinds (deployment, service, route) are singletons tied to the main RHDH app, so OKP would need new registered kinds + factories. The existing .ocp/.k8s suffix mechanism also doesn't handle "create-or-skip-entirely" gating, so some Go code will still be needed for the
OpenShift-only conditional logic.
- the operator's config kinds (deployment, service, route) are singletons tied to the main RHDH app, so OKP would need new registered kinds + factories. The existing .ocp/.k8s suffix mechanism also doesn't handle "create-or-skip-entirely" gating, so some Go code will still be needed for the
I'm going to explore options on how best to approach this. Would appreciate any suggestions or guidance from @gazarenkov / @rm3l on the preferred pattern for flavour-owned sidecar resources.
There was a problem hiding this comment.
The OKP Deployment/Service/Route are now defined in the lightspeed flavour YAML (config/profile/rhdh/default-config/flavours/lightspeed/okp-*.yaml) and applied via the normal model path, rather than constructed imperatively in okp.go.
Each is a separately registered key, still gated to OpenShift. The only bit kept in Go is injecting OKP_SERVICE_URL into the lightspeed-core sidecar, since that value is computed at runtime (CR name/namespace + ingress domain) and can't be a static YAML env. This also means the OKP image string now rides in the bundle ConfigMap, so midstream image pinning can see it.
|
Corresponding rhdh-chart PR redhat-developer/rhdh-chart#500 |
Move the OKP (Offline Knowledge Portal) Deployment, Service, and Route out of imperative Go construction in internal/controller/okp.go and into the lightspeed flavour as YAML manifests, so OKP is described like every other flavour resource and its image string rides in the bundle ConfigMap (visible to midstream image pinning). Addresses PR redhat-developer#3370 review comment: "should OKP be in the flavour YAML rather than Go?". Each OKP object is a separately registered model key (OkpDeploymentKey, OkpServiceKey, OkpRouteKey) with its own MergeFunc, and stays gated to OpenShift in addToModel. Flavour gating is implicit (files live only in flavours/lightspeed/). The runtime behavior is unchanged: same objects, same OpenShift-only gating, same OKP_SERVICE_URL injection into the lightspeed-core sidecar before apply (no dual ReplicaSet). Remove applyOkpResources; OKP now flows through the normal applyObjects(GetRuntimeObjects()) SSA path. Keep prepareOkpEnvVar and prepareOkpConfig as controller wiring. Regenerate bundle manifests and dist/rhdh/install.yaml. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the OKP (Offline Knowledge Portal) Deployment, Service, and Route out of imperative Go construction in internal/controller/okp.go and into the lightspeed flavour as YAML manifests, so OKP is described like every other flavour resource and its image string rides in the bundle ConfigMap (visible to midstream image pinning). Addresses PR redhat-developer#3370 review comment: "should OKP be in the flavour YAML rather than Go?". Each OKP object is a separately registered model key (OkpDeploymentKey, OkpServiceKey, OkpRouteKey) with its own MergeFunc, and stays gated to OpenShift in addToModel. Flavour gating is implicit (files live only in flavours/lightspeed/). The runtime behavior is unchanged: same objects, same OpenShift-only gating, same OKP_SERVICE_URL injection into the lightspeed-core sidecar before apply (no dual ReplicaSet). Remove applyOkpResources; OKP now flows through the normal applyObjects(GetRuntimeObjects()) SSA path. Keep prepareOkpEnvVar and prepareOkpConfig as controller wiring. Regenerate bundle manifests and dist/rhdh/install.yaml. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
15302a5 to
ecd3199
Compare
|
/build-images |
|
❌ Image build failed See workflow run for details: https://github.com/redhat-developer/rhdh-operator/actions/runs/32705736214 Triggered by @rm3l |
|
/build-images |
|
❌ Image build failed See workflow run for details: https://github.com/redhat-developer/rhdh-operator/actions/runs/32705962118 Triggered by @rm3l |
…DP-16103] Remove the init-rag-data init container and FAISS vector store from the lightspeed flavour. Add OKP (Offline Knowledge Portal) as a Deployment, Service, and Route managed by the operator, gated on OpenShift; vanilla K8s swaps in the lightspeed-stack-no-okp.yaml config to avoid LCORE crashing without an OKP backend. Inject OKP_SERVICE_URL into the lightspeed-core sidecar before applying objects to avoid a dual ReplicaSet rollout. Align the LCORE sidecar with the OGX image and pin the OKP image. Sync vendored Lightspeed configs from lightspeed-configs@main. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the OKP (Offline Knowledge Portal) Deployment, Service, and Route out of imperative Go construction in internal/controller/okp.go and into the lightspeed flavour as YAML manifests, so OKP is described like every other flavour resource and its image string rides in the bundle ConfigMap (visible to midstream image pinning). Addresses PR redhat-developer#3370 review comment: "should OKP be in the flavour YAML rather than Go?". Each OKP object is a separately registered model key (OkpDeploymentKey, OkpServiceKey, OkpRouteKey) with its own MergeFunc, and stays gated to OpenShift in addToModel. Flavour gating is implicit (files live only in flavours/lightspeed/). The runtime behavior is unchanged: same objects, same OpenShift-only gating, same OKP_SERVICE_URL injection into the lightspeed-core sidecar before apply (no dual ReplicaSet). Remove applyOkpResources; OKP now flows through the normal applyObjects(GetRuntimeObjects()) SSA path. Keep prepareOkpEnvVar and prepareOkpConfig as controller wiring. Regenerate bundle manifests and dist/rhdh/install.yaml. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
71c206f to
9726670
Compare
|
/build-images |
|
✅ PR images built successfully! Images are available for testing:
Also available with PR number tag:
Triggered by @maysunfaisal |
Jdubrick
left a comment
There was a problem hiding this comment.
Just a general question as well: will OKP get cleaned up if someone disables the lightspeed flavour?
| # Lightspeed Plugins | ||
| - package: oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-lightspeed:{{inherit}} | ||
| # Intelligent Assistant Plugins | ||
| - package: oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant:{{inherit}} |
There was a problem hiding this comment.
Question more for @rm3l instead of us: since the next tag of the plugin catalog has the plugins listed as quay.io we have to change the reference here. Do we need to swap them back to registry.access.redhat.com eventually?
There was a problem hiding this comment.
I haven't tested it yet, but can you adopt the new ref:// pattern going forward (see redhat-developer/rhdh#5204)? This way, it won't be affected by registry changes in the DPDY. Can you try this?
There was a problem hiding this comment.
ok switched to ref:// in the new commit and plugins install successfully
======= No plugin path specified for oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant@sha256:88cccf46912392c8be10aa9a454c5f5fd2257968bee1007ab8430a22cdc3d65c, auto-detecting from OCI manifest
======= Auto-resolving OCI package oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant@sha256:88cccf46912392c8be10aa9a454c5f5fd2257968bee1007ab8430a22cdc3d65c to use plugin path: red-hat-developer-hub-backstage-plugin-intelligent-assistant
======= Adding new dynamic plugin configuration for version `sha256:88cccf46912392c8be10aa9a454c5f5fd2257968bee1007ab8430a22cdc3d65c` of oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant:!red-hat-developer-hub-backstage-plugin-intelligent-assis
======= No plugin path specified for oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend@sha256:76c597cd1e44b6fff262ad9fa8bacf0123f55bb97139138dbde8fa401dc4dc84, auto-detecting from OCI manifest
======= Auto-resolving OCI package oci://quay.io/rhdh/red-hat-developer-hub-backstage-pluginkend@sha256:76c597cd1e44b6fff262ad9fa8bacf0123f55bb97139138dbde8fa401dc4dc84 to use pluginpath: red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend
======= Adding new dynamic plugin configuration for version `sha256:76c597cd1e44b6fff262ad9fa8bacf0123f55bb97139138dbde8fa401dc4dc84` of oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend:!redge-plugin-intelligent-assistant-backend
======= No plugin path specified for oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant@sha256:88cccf46912392c8be10aa9a454c5f5fd2257968bee1007ab8430a22cdc3d65c, auto-detecting from OCI manifest
======= Auto-resolving OCI package oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant@sha256:88cccf46912392c8be10aa9a454c5f5fd2257968bee1007ab8430a22cdc3d65c to use plugin path: red-hat-developer-hub-backstage-plugin-intelligent-assistant
======= Overriding dynamic plugin configuration oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant:!red-hat-developer-hub-backstage-plugin-intelligent-assistant
======= No plugin path specified for oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend@sha256:76c597cd1e44b6fff262ad9fa8bacf0123f55bb97139138dbde8fa401dc4dc84, auto-detecting from OCI manifest
======= Auto-resolving OCI package oci://quay.io/rhdh/red-hat-developer-hub-backstage-pluginkend@sha256:76c597cd1e44b6fff262ad9fa8bacf0123f55bb97139138dbde8fa401dc4dc84 to use pluginpath: red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend
======= Overriding dynamic plugin configuration oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend:!red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend
======= Installing OCI plugin oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant@sha256:88cccf46912392c8be10aa9a454c5f5fd2257968bee1007ab8430a22cdc3d65c!red-hat-developer-hub-backsta
ge-plugin-intelligent-assistant
==> Downloading oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant@sha256:88cccf46912392c8be10aa9a454c5f5fd2257968bee1007ab8430a22cdc3d65c
======= Installing OCI plugin oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intesha256:76c597cd1e44b6fff262ad9fa8bacf0123f55bb97139138dbde8fa401dc4dc84!red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend
==> Downloading oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-6c597cd1e44b6fff262ad9fa8bacf0123f55bb97139138dbde8fa401dc4dc84
==> Installed oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant@sha256:88cccf46912392c8be10aa9a454c5f5fd2257968bee1007ab8430a22cdc3d65c!red-hat-developer-hub-backstage-plugin-igent-assistant
==> Installed oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend@sha256:76c597cd1e44b6fff262ad9fa8bacf0123f55bb97139138dbde8fa401dc4dc84!red-hat-developer-hub-backstagen-intelligent-assistant-backend
======= All plugins installed successfully
| > [!NOTE] | ||
| > The `{{inherit}}` tag resolves the plugin version from the RHDH catalog index that ships with the operator's RHDH image, so the assistant stays aligned with the platform. The `quay.io/rhdh` registry is significant — it matches the operator's `CATALOG_INDEX_IMAGE`, allowing the reference to resolve at the container level. |
There was a problem hiding this comment.
Do we need this blurb? Since inherit is an RHDH specific thing that multiple plugins use, maybe it should be top-level/already covered?
There was a problem hiding this comment.
Yeah i can update to remove it
| The assistant uses **OKP (Offline Knowledge Portal)** for document retrieval (RAG), replacing the previous RAG init container and FAISS vector store. | ||
|
|
||
| - **OpenShift:** the operator deploys OKP as a `Deployment`, `Service`, and `Route` (Solr on `8983`, httpd on `8080`), and injects `OKP_SERVICE_URL` into the `lightspeed-core` sidecar so the assistant queries it for grounded answers. | ||
| - **Vanilla Kubernetes:** OKP is **not** deployed (the operator has no Ingress support). The Lightspeed Core config falls back to `lightspeed-stack-no-okp.yaml` (the `rag`/`okp` sections stripped out) so the service starts cleanly without an OKP backend. General chat and Notebooks still work; OKP-backed retrieval is unavailable. |
There was a problem hiding this comment.
We should mention that responses related to RHDH/Lightspeed (Intelligent Assistant)/etc may not be as accurate without a knowledge base to draw on
|
/cc @gazarenkov |
…ext, docs [RHIDP-16103] Switch IA plugin references from oci://...inherit to ref:// pattern (per rm3l review, rhdh#5204). Add OTEL_SDK_DISABLED=true to LCORE env to prevent crash when OTEL collector unreachable. Add securityContext to LCORE and OKP containers matching the operator RHDH deployment precedent. Update docs: remove inherit note, add accuracy caveat for vanilla K8s without OKP knowledge base. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
/build-images |
|
✅ PR images built successfully! Images are available for testing:
Also available with PR number tag:
Triggered by @maysunfaisal |
gazarenkov
left a comment
There was a problem hiding this comment.
To add the additional resources needed for your plugin please use Plugin dependencies feature instead.
You can see how it implemented in orchestrator flavour as well (it uses sonataflow dependencies).
Thanks @gazarenkov, looked into plugin-deps for OKP. Our manifests are already declarative YAML, not imperative Go: The Go wrappers (
Orchestrator's sonataflow deps are standalone resources, no cross-container wiring or platform gating needed. OKP needs both. Open to discussion if there's a path to extend plugin-deps for these cases! |
|
PR needs rebase. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |



Description
Replace the Lightspeed RAG init container / FAISS vector store with an OKP (Offline Knowledge Portal) backend and swap the Lightspeed dynamic plugins to the Intelligent Assistant plugins.
OKP deployment
Deployment,Service, andRoute(Solr8983+ httpd8080) — newinternal/controller/okp.go, wired inbackstage_controller.go.lightspeed-stack-no-okp.yamlso LCORE does not crash without an OKP backend (operator has no Ingress support — RHDHPLAN-423/RHIDP-2176).OKP_SERVICE_URLinto thelightspeed-coresidecar before applying objects, avoiding a dual-ReplicaSet rollout.Plugin swap (Intelligent Assistant)
oci://quay.io/rhdh/red-hat-developer-hub-backstage-plugin-intelligent-assistant(-backend):{{inherit}},enabled: true; FE carries the fullpluginConfig(dynamicRoutes/mountPoints).quay.io/rhdh(notregistry.access.redhat.com) to match the operator'sCATALOG_INDEX_IMAGE+ RHDH image, so{{inherit}}resolves at the container level (install-dynamic-plugins).Config & images
HF_HOME+--synthesized-config-outputfor read-only rootfs, and pin the OKP image toregistry.redhat.io/offline-knowledge-portal/rhokp-rhel9:1.2.10-1786628394.lightspeed-configs@main(hack/sync-lightspeed-configs.sh).dist/rhdh/install.yaml+bundle/rhdh/manifests/rhdh-flavour-lightspeed-config_v1_configmap.yaml.Which issue(s) does this PR fix or relate to
https://redhat.atlassian.net/browse/RHIDP-16103
PR acceptance criteria
How to test changes / Special notes to the reviewer
On OpenShift:
make deploy IMG=<operator-image> PROFILE=rhdhOPENAI_API_KEY) — seeexamples/lightspeed.yaml.BackstageCR with thelightspeedflavour enabled and the secret wired into thelightspeed-corecontainer.developer-hubpod 2/2 Running; OKPDeployment/Service/Route1/1 Running.OKP_SERVICE_URL+HF_HOMEinjected into thelightspeed-coresidecar; LCOREGET /v1/modelsreturns 200.{{inherit}}(digests match the RHDH image's catalog).On vanilla K8s: OKP is skipped,
lightspeed-stack-no-okp.yamlis used, and LCORE starts without crashing.Building Container Images for Testing
Need to test container images from this PR?
For Maintainers: To trigger a test image build, review the code and comment
/build-images.This always builds the HEAD of the PR branch.
For Contributors: Ask a maintainer to run
/build-images.Images will be built and pushed to Quay with links posted in comments.