From 172e576344bc526b36dfe2594c2cf84b628a3292 Mon Sep 17 00:00:00 2001 From: Sergey Yedrikov Date: Mon, 22 Dec 2025 20:55:17 -0500 Subject: [PATCH] OLS-2106: Operator connects Openshift RAG by default to LSC backend --- cmd/main.go | 1 + internal/controller/appserver/deployment.go | 6 +- internal/controller/appserver/rag.go | 47 -------------- internal/controller/lcore/assets_test.go | 45 ++++--------- internal/controller/lcore/config.go | 65 ++++++++++++------- internal/controller/lcore/deployment.go | 19 +++++- internal/controller/lcore/deployment_test.go | 65 ++++++++++++++++++- internal/controller/olsconfig_helpers.go | 4 ++ internal/controller/reconciler/interface.go | 3 + internal/controller/utils/rag.go | 50 ++++++++++++++ .../{appserver => utils}/rag_test.go | 9 ++- internal/controller/utils/testing.go | 6 ++ internal/controller/utils/types.go | 1 + 13 files changed, 208 insertions(+), 113 deletions(-) delete mode 100644 internal/controller/appserver/rag.go create mode 100644 internal/controller/utils/rag.go rename internal/controller/{appserver => utils}/rag_test.go (89%) diff --git a/cmd/main.go b/cmd/main.go index d8c20d6f5..8ad2b3a56 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -429,6 +429,7 @@ func main() { OpenShiftMCPServerImage: imagesMap["openshift-mcp-server-image"], DataverseExporterImage: imagesMap["dataverse-exporter-image"], LightspeedCoreImage: imagesMap["lightspeed-core"], + OcpRagImage: imagesMap["ocp-rag-image"], UseLCore: useLCore, Namespace: namespace, PrometheusAvailable: prometheusAvailable, diff --git a/internal/controller/appserver/deployment.go b/internal/controller/appserver/deployment.go index e65e99458..8efe1d915 100644 --- a/internal/controller/appserver/deployment.go +++ b/internal/controller/appserver/deployment.go @@ -296,7 +296,7 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) ( // RAG volume if len(cr.Spec.OLSConfig.RAG) > 0 { - ragVolume := generateRAGVolume() + ragVolume := utils.GenerateRAGVolume() volumes = append(volumes, ragVolume) } @@ -313,7 +313,7 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) ( ) if len(cr.Spec.OLSConfig.RAG) > 0 { - ragVolumeMounts := generateRAGVolumeMount() + ragVolumeMounts := utils.GenerateRAGVolumeMount() volumeMounts = append(volumeMounts, ragVolumeMounts) } @@ -348,7 +348,7 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) ( initContainers := []corev1.Container{} if len(cr.Spec.OLSConfig.RAG) > 0 { - ragInitContainers := GenerateRAGInitContainers(cr) + ragInitContainers := utils.GenerateRAGInitContainers(cr) initContainers = append(initContainers, ragInitContainers...) } diff --git a/internal/controller/appserver/rag.go b/internal/controller/appserver/rag.go deleted file mode 100644 index 444fc3237..000000000 --- a/internal/controller/appserver/rag.go +++ /dev/null @@ -1,47 +0,0 @@ -package appserver - -import ( - "fmt" - "path" - - corev1 "k8s.io/api/core/v1" - - olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1" - "github.com/openshift/lightspeed-operator/internal/controller/utils" -) - -func generateRAGVolume() corev1.Volume { - return corev1.Volume{ - Name: utils.RAGVolumeName, - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - } -} - -func GenerateRAGInitContainers(cr *olsv1alpha1.OLSConfig) []corev1.Container { - var initContainers []corev1.Container - for idx, rag := range cr.Spec.OLSConfig.RAG { - ragName := fmt.Sprintf("rag-%d", idx) - initContainers = append(initContainers, corev1.Container{ - Name: ragName, - Image: rag.Image, - ImagePullPolicy: corev1.PullAlways, - Command: []string{"sh", "-c", fmt.Sprintf("mkdir -p %s && cp -a %s/. %s", path.Join(utils.RAGVolumeMountPath, ragName), rag.IndexPath, path.Join(utils.RAGVolumeMountPath, ragName))}, - VolumeMounts: []corev1.VolumeMount{ - { - Name: utils.RAGVolumeName, - MountPath: utils.RAGVolumeMountPath, - }, - }, - }) - } - return initContainers -} - -func generateRAGVolumeMount() corev1.VolumeMount { - return corev1.VolumeMount{ - Name: utils.RAGVolumeName, - MountPath: utils.RAGVolumeMountPath, - } -} diff --git a/internal/controller/lcore/assets_test.go b/internal/controller/lcore/assets_test.go index d416d8678..d2b938789 100644 --- a/internal/controller/lcore/assets_test.go +++ b/internal/controller/lcore/assets_test.go @@ -35,8 +35,7 @@ func TestBuildLlamaStackYAML_SupportedProvider(t *testing.T) { } // Build the YAML - ctx := context.Background() - yamlOutput, err := buildLlamaStackYAML(nil, ctx, cr) + yamlOutput, err := buildLlamaStackYAML(createTestReconciler(), context.Background(), cr) if err != nil { t.Fatalf("buildLlamaStackYAML returned error for supported provider: %v", err) } @@ -89,8 +88,7 @@ func TestBuildLlamaStackYAML_UnsupportedProvider(t *testing.T) { } // Build the YAML - should return error - ctx := context.Background() - yamlOutput, err := buildLlamaStackYAML(nil, ctx, cr) + yamlOutput, err := buildLlamaStackYAML(createTestReconciler(), context.Background(), cr) // Verify error is returned if err == nil { @@ -104,10 +102,10 @@ func TestBuildLlamaStackYAML_UnsupportedProvider(t *testing.T) { } if err.Error() != "" && len(err.Error()) > 0 { // Check if error message contains expected text - if !contains(err.Error(), expectedErrMsg) { + if !strings.Contains(err.Error(), expectedErrMsg) { t.Errorf("Error message '%s' doesn't contain expected text '%s'", err.Error(), expectedErrMsg) } - if !contains(err.Error(), providerType) { + if !strings.Contains(err.Error(), providerType) { t.Errorf("Error message '%s' doesn't mention provider type '%s'", err.Error(), providerType) } } @@ -142,8 +140,7 @@ func TestBuildLlamaStackYAML_OpenAICompatibleProviders(t *testing.T) { } // Build the YAML - should succeed - ctx := context.Background() - yamlOutput, err := buildLlamaStackYAML(nil, ctx, cr) + yamlOutput, err := buildLlamaStackYAML(createTestReconciler(), context.Background(), cr) // Verify no error is returned if err != nil { @@ -262,8 +259,7 @@ func TestBuildLlamaStackYAML_AzureProvider(t *testing.T) { } // Build the YAML - ctx := context.Background() - yamlOutput, err := buildLlamaStackYAML(testReconciler, ctx, cr) + yamlOutput, err := buildLlamaStackYAML(testReconciler, context.Background(), cr) if err != nil { t.Fatalf("buildLlamaStackYAML returned error for Azure provider: %v", err) } @@ -344,24 +340,7 @@ func TestBuildLlamaStackYAML_AzureProvider(t *testing.T) { t.Logf("Successfully validated Llama Stack YAML with Azure provider (%d bytes)", len(yamlOutput)) } -// Helper function to check if a string contains a substring -func contains(s, substr string) bool { - return len(s) >= len(substr) && (s == substr || len(s) > len(substr) && findSubstring(s, substr)) -} - -func findSubstring(s, substr string) bool { - for i := 0; i <= len(s)-len(substr); i++ { - if s[i:i+len(substr)] == substr { - return true - } - } - return false -} - -func TestBuildLCoreConfigYAML(t *testing.T) { - // Use a proper CR from test fixtures instead of nil - cr := utils.GetDefaultOLSConfigCR() - +func createTestReconciler() *utils.TestReconciler { // Create a fake client and reconciler for the test scheme := runtime.NewScheme() _ = olsv1alpha1.AddToScheme(scheme) @@ -370,15 +349,19 @@ func TestBuildLCoreConfigYAML(t *testing.T) { WithScheme(scheme). Build() logger := zap.New(zap.UseDevMode(true)) - testReconciler := utils.NewTestReconciler( + return utils.NewTestReconciler( fakeClient, logger, scheme, "test-namespace", ) +} + +func TestBuildLCoreConfigYAML(t *testing.T) { + // Use a proper CR from test fixtures instead of nil + cr := utils.GetDefaultOLSConfigCR() - ctx := context.Background() - yamlOutput, err := buildLCoreConfigYAML(testReconciler, ctx, cr) + yamlOutput, err := buildLCoreConfigYAML(createTestReconciler(), context.Background(), cr) if err != nil { t.Fatalf("buildLCoreConfigYAML returned error: %v", err) } diff --git a/internal/controller/lcore/config.go b/internal/controller/lcore/config.go index f5a6526fe..7f41a4404 100644 --- a/internal/controller/lcore/config.go +++ b/internal/controller/lcore/config.go @@ -374,23 +374,47 @@ func buildLlamaStackToolRuntime(_ reconciler.Reconciler, _ *olsv1alpha1.OLSConfi } } -func buildLlamaStackVectorDB(_ reconciler.Reconciler, _ *olsv1alpha1.OLSConfig) []interface{} { - return []interface{}{ - map[string]interface{}{ - "provider_id": "faiss", +func buildLlamaStackVectorIO(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) []interface{} { + vectorIOs := []interface{}{} + // Use RAG configuration from OLSConfig if available + if len(cr.Spec.OLSConfig.RAG) > 0 { + for _, rag := range cr.Spec.OLSConfig.RAG { + id := "byok_rag_" + sanitizeID(rag.Image) + vectorIOs = append(vectorIOs, map[string]interface{}{ + "provider_id": id, + "provider_type": "inline::faiss", + "config": map[string]interface{}{ + "kvstore": map[string]interface{}{ + "db_path": "/rag-data/" + id + "/faiss_store.db", + "type": "kv_sqlight", + }, + "persistence": map[string]interface{}{ + "backend": "kv_default", + "namespace": "vector_io::faiss", + }, + }, + }) + } + } + if !cr.Spec.OLSConfig.ByokRAGOnly { + // OCP RAG database + vectorIOs = append(vectorIOs, map[string]interface{}{ + "provider_id": "ocp-rag", "provider_type": "inline::faiss", "config": map[string]interface{}{ "kvstore": map[string]interface{}{ - "backend": "sql_default", - "table_name": "vector_store", + "db_path": "/rag-data/ocp/vector_db/ocp_product_docs/" + r.GetOpenShiftMajor() + "." + r.GetOpenshiftMinor() + "/faiss_store.db", + "type": "kv_sqlight", }, "persistence": map[string]interface{}{ "backend": "kv_default", - "namespace": "vector_persistence", + "namespace": "vector_io::faiss", }, }, - }, + }) } + + return vectorIOs } func buildLlamaStackServerConfig(_ reconciler.Reconciler, _ *olsv1alpha1.OLSConfig) map[string]interface{} { @@ -428,26 +452,19 @@ func buildLlamaStackVectorDBs(_ reconciler.Reconciler, cr *olsv1alpha1.OLSConfig vectorDB := map[string]interface{}{ "embedding_model": "sentence-transformers/all-mpnet-base-v2", "embedding_dimension": 768, - "provider_id": "faiss", + "provider_id": "byok_rag_" + sanitizeID(rag.Image), + "vector_db_id": "byok_rag_" + sanitizeID(rag.Image), } - - // Use IndexID if specified, otherwise generate a default - if rag.IndexID != "" { - vectorDB["vector_db_id"] = rag.IndexID - } else { - // Generate a simple ID from the image name - vectorDB["vector_db_id"] = "rag_" + sanitizeID(rag.Image) - } - vectorDBs = append(vectorDBs, vectorDB) } - } else { - // Default fallback if no RAG configured + } + if !cr.Spec.OLSConfig.ByokRAGOnly { + // OCP RAG database vectorDBs = append(vectorDBs, map[string]interface{}{ - "vector_db_id": "my_knowledge_base", + "vector_db_id": "ocp-rag", "embedding_model": "sentence-transformers/all-mpnet-base-v2", "embedding_dimension": 768, - "provider_id": "faiss", + "provider_id": "ocp-rag", }) } @@ -478,7 +495,7 @@ func buildLlamaStackModels(_ reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) [ "model_id": "sentence-transformers/all-mpnet-base-v2", "model_type": "embedding", "provider_id": "sentence-transformers", - "provider_model_id": "sentence-transformers/all-mpnet-base-v2", + "provider_model_id": "/rag-data/ocp/embeddings_model", "metadata": map[string]interface{}{ "embedding_dimension": 768, }, @@ -595,7 +612,7 @@ func buildLlamaStackYAML(r reconciler.Reconciler, ctx context.Context, cr *olsv1 "safety": buildLlamaStackSafety(r, cr), // Required by agents provider // "telemetry": buildLlamaStackTelemetry(r, cr), // Telemetry and tracing "tool_runtime": buildLlamaStackToolRuntime(r, cr), // Required for RAG - "vector_io": buildLlamaStackVectorDB(r, cr), // Required for RAG + "vector_io": buildLlamaStackVectorIO(r, cr), // Required for RAG } // Add top-level fields diff --git a/internal/controller/lcore/deployment.go b/internal/controller/lcore/deployment.go index e51f5b791..262ba6ef6 100644 --- a/internal/controller/lcore/deployment.go +++ b/internal/controller/lcore/deployment.go @@ -273,6 +273,9 @@ func GenerateLCoreDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) // PostgreSQL CA ConfigMap volume (for TLS certificate verification) volumes = append(volumes, utils.GetPostgresCAConfigVolume()) + // RAG volume + volumes = append(volumes, utils.GenerateRAGVolume()) + // Add external TLS secret if provided by user var tlsVolumeMounts []corev1.VolumeMount if cr.Spec.OLSConfig.TLSConfig != nil && cr.Spec.OLSConfig.TLSConfig.KeyCertSecretRef.Name != "" { @@ -318,6 +321,9 @@ func GenerateLCoreDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) utils.GetPostgresCAVolumeMount("/etc/certs/postgres-ca"), } + // RAG volume mount + llamaStackVolumeMounts = append(llamaStackVolumeMounts, utils.GenerateRAGVolumeMount()) + // User provided CA certificates - create both volumes and volume mounts in single pass _ = utils.ForEachExternalConfigMap(cr, func(name, source string) error { var volumeName, llamaStackMountPath string @@ -526,6 +532,16 @@ func GenerateLCoreDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) } lightspeedStackContainer.Resources = *lightspeedStackResources + initContainers := []corev1.Container{} + ocpRagDirName := "ocp" + ocpRagDir := path.Join(utils.RAGVolumeMountPath, ocpRagDirName) + initContainers = append(initContainers, utils.GenerateRAGInitContainer(ocpRagDirName, r.GetOcpRagImage(), ocpRagDir, cr)) + + if len(cr.Spec.OLSConfig.RAG) > 0 { + ragInitContainers := utils.GenerateRAGInitContainers(cr) + initContainers = append(initContainers, ragInitContainers...) + } + deployment := appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: "lightspeed-stack-deployment", @@ -552,7 +568,8 @@ func GenerateLCoreDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) llamaStackContainer, lightspeedStackContainer, }, - Volumes: volumes, + Volumes: volumes, + InitContainers: initContainers, }, }, RevisionHistoryLimit: &revisionHistoryLimit, diff --git a/internal/controller/lcore/deployment_test.go b/internal/controller/lcore/deployment_test.go index 1dbdf03d0..bad964db8 100644 --- a/internal/controller/lcore/deployment_test.go +++ b/internal/controller/lcore/deployment_test.go @@ -57,6 +57,13 @@ func (m *mockReconciler) GetLCoreImage() string { return m.image } +func (m *mockReconciler) GetOcpRagImage() string { + if m.image == "" { + return utils.OcpRagImageDefault + } + return m.image +} + func (m *mockReconciler) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { // Return NotFound error for all Get calls in tests // This simulates the ConfigMaps not existing yet during deployment generation @@ -203,6 +210,16 @@ func TestGenerateLCoreDeployment(t *testing.T) { t.Error("lightspeed-stack container missing readiness probe") } + // Verify init containers + initContainers := deployment.Spec.Template.Spec.InitContainers + if len(initContainers) != 1 { + t.Fatalf("Expected 1 initContainer, got %d", len(initContainers)) + } + ragInitContainer := initContainers[0] + if ragInitContainer.Name != "ocp" { + t.Errorf("Expected RAG initContainer name '%s', got '%s'", "ocp", ragInitContainer.Name) + } + // Verify volumes volumes := deployment.Spec.Template.Spec.Volumes expectedVolumes := map[string]bool{ @@ -210,6 +227,7 @@ func TestGenerateLCoreDeployment(t *testing.T) { utils.LCoreConfigCmName: false, utils.LlamaCacheVolumeName: false, "secret-lightspeed-tls": false, + utils.RAGVolumeName: false, } for _, vol := range volumes { if _, expected := expectedVolumes[vol.Name]; expected { @@ -224,8 +242,8 @@ func TestGenerateLCoreDeployment(t *testing.T) { // Verify volume mounts in llama-stack container llamaStackMounts := llamaStackContainer.VolumeMounts - if len(llamaStackMounts) < 3 { - t.Errorf("Expected at least 3 volume mounts in llama-stack container (config, cache, CA), got %d", len(llamaStackMounts)) + if len(llamaStackMounts) < 4 { + t.Errorf("Expected at least 3 volume mounts in llama-stack container (config, cache, CA, RAG), got %d", len(llamaStackMounts)) } llamaStackMountNames := make(map[string]bool) for _, mount := range llamaStackMounts { @@ -240,6 +258,9 @@ func TestGenerateLCoreDeployment(t *testing.T) { if !llamaStackMountNames[utils.OpenShiftCAVolumeName] { t.Errorf("Missing '%s' volume mount in llama-stack container", utils.OpenShiftCAVolumeName) } + if !llamaStackMountNames[utils.RAGVolumeName] { + t.Errorf("Missing '%s' volume mount in llama-stack container", utils.RAGVolumeName) + } // Verify volume mounts in lightspeed-stack container lightspeedStackMounts := lightspeedStackContainer.VolumeMounts @@ -397,3 +418,43 @@ func TestGenerateLCoreDeploymentWithAdditionalCA(t *testing.T) { t.Logf("Successfully validated LCore Deployment with Additional CA") } + +/* +func TestGenerateLCoreDeploymentWithRag(t *testing.T) { + // Create an OLSConfig CR with additionalCAConfigMapRef + cr := &olsv1alpha1.OLSConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster", + }, + Spec: olsv1alpha1.OLSConfigSpec{ + LLMConfig: olsv1alpha1.LLMSpec{ + Providers: []olsv1alpha1.ProviderSpec{ + { + Name: "test-provider", + CredentialsSecretRef: corev1.LocalObjectReference{ + Name: "test-secret", + }, + }, + }, + }, + OLSConfig: olsv1alpha1.OLSSpec{ + RAG: , + }, + }, + } + + // Create a mock reconciler + r := &mockReconciler{} + + // Generate the deployment + deployment, err := GenerateLCoreDeployment(r, cr) + if err != nil { + t.Fatalf("GenerateLCoreDeployment returned error: %v", err) + } + + // Verify deployment is not nil + if deployment == nil { + t.Fatal("GenerateLCoreDeployment returned nil deployment") + } +} +*/ diff --git a/internal/controller/olsconfig_helpers.go b/internal/controller/olsconfig_helpers.go index 1eaf3025b..fc3028b8c 100644 --- a/internal/controller/olsconfig_helpers.go +++ b/internal/controller/olsconfig_helpers.go @@ -73,6 +73,10 @@ func (r *OLSConfigReconciler) GetLCoreImage() string { return r.Options.LightspeedCoreImage } +func (r *OLSConfigReconciler) GetOcpRagImage() string { + return r.Options.OcpRagImage +} + func (r *OLSConfigReconciler) IsPrometheusAvailable() bool { return r.Options.PrometheusAvailable } diff --git a/internal/controller/reconciler/interface.go b/internal/controller/reconciler/interface.go index 4c492e997..981041da3 100644 --- a/internal/controller/reconciler/interface.go +++ b/internal/controller/reconciler/interface.go @@ -63,6 +63,9 @@ type Reconciler interface { // GetLCoreImage returns the LCore image to use GetLCoreImage() string + // GetLCoreImage returns the LCore image to use + GetOcpRagImage() string + // IsPrometheusAvailable returns whether Prometheus Operator CRDs are available IsPrometheusAvailable() bool diff --git a/internal/controller/utils/rag.go b/internal/controller/utils/rag.go new file mode 100644 index 000000000..79b218743 --- /dev/null +++ b/internal/controller/utils/rag.go @@ -0,0 +1,50 @@ +package utils + +import ( + "fmt" + "path" + + corev1 "k8s.io/api/core/v1" + + olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1" +) + +func GenerateRAGVolume() corev1.Volume { + return corev1.Volume{ + Name: RAGVolumeName, + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + } +} + +func GenerateRAGInitContainer(name, image, indexPath string, cr *olsv1alpha1.OLSConfig) corev1.Container { + return corev1.Container{ + Name: name, + Image: image, + ImagePullPolicy: corev1.PullAlways, + Command: []string{"sh", "-c", fmt.Sprintf("mkdir -p %s && cp -a %s/. %s", path.Join(RAGVolumeMountPath, name), indexPath, path.Join(RAGVolumeMountPath, name))}, + VolumeMounts: []corev1.VolumeMount{ + { + Name: RAGVolumeName, + MountPath: RAGVolumeMountPath, + }, + }, + } +} + +func GenerateRAGInitContainers(cr *olsv1alpha1.OLSConfig) []corev1.Container { + var initContainers []corev1.Container + for idx, rag := range cr.Spec.OLSConfig.RAG { + ragName := fmt.Sprintf("rag-%d", idx) + initContainers = append(initContainers, GenerateRAGInitContainer(ragName, rag.Image, rag.IndexPath, cr)) + } + return initContainers +} + +func GenerateRAGVolumeMount() corev1.VolumeMount { + return corev1.VolumeMount{ + Name: RAGVolumeName, + MountPath: RAGVolumeMountPath, + } +} diff --git a/internal/controller/appserver/rag_test.go b/internal/controller/utils/rag_test.go similarity index 89% rename from internal/controller/appserver/rag_test.go rename to internal/controller/utils/rag_test.go index c0750a1d0..f91171516 100644 --- a/internal/controller/appserver/rag_test.go +++ b/internal/controller/utils/rag_test.go @@ -1,4 +1,4 @@ -package appserver +package utils import ( . "github.com/onsi/ginkgo/v2" @@ -8,7 +8,6 @@ import ( corev1 "k8s.io/api/core/v1" olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1" - "github.com/openshift/lightspeed-operator/internal/controller/utils" ) var _ = Describe("App server assets", func() { @@ -16,7 +15,7 @@ var _ = Describe("App server assets", func() { Context("complete custom resource", func() { BeforeEach(func() { - cr = utils.GetDefaultOLSConfigCR() + cr = GetDefaultOLSConfigCR() cr.Spec.OLSConfig.RAG = []olsv1alpha1.RAGSpec{ { Image: "rag-image-1", @@ -43,7 +42,7 @@ var _ = Describe("App server assets", func() { "ImagePullPolicy": Equal(corev1.PullAlways), "Command": Equal([]string{"sh", "-c", "mkdir -p /rag-data/rag-0 && cp -a /path/to/index-1/. /rag-data/rag-0"}), "VolumeMounts": ConsistOf(corev1.VolumeMount{ - Name: utils.RAGVolumeName, + Name: RAGVolumeName, MountPath: "/rag-data", }), })) @@ -53,7 +52,7 @@ var _ = Describe("App server assets", func() { "ImagePullPolicy": Equal(corev1.PullAlways), "Command": Equal([]string{"sh", "-c", "mkdir -p /rag-data/rag-1 && cp -a /path/to/index-2/. /rag-data/rag-1"}), "VolumeMounts": ConsistOf(corev1.VolumeMount{ - Name: utils.RAGVolumeName, + Name: RAGVolumeName, MountPath: "/rag-data", }), })) diff --git a/internal/controller/utils/testing.go b/internal/controller/utils/testing.go index 7e4377f6c..82e434583 100644 --- a/internal/controller/utils/testing.go +++ b/internal/controller/utils/testing.go @@ -22,6 +22,7 @@ type TestReconciler struct { McpServerImage string DataverseExporter string LCoreImage string + OcpRagImage string openShiftMajor string openShiftMinor string PrometheusAvailable bool @@ -73,6 +74,10 @@ func (r *TestReconciler) GetLCoreImage() string { return r.LCoreImage } +func (r *TestReconciler) GetOcpRagImage() string { + return r.OcpRagImage +} + func (r *TestReconciler) IsPrometheusAvailable() bool { return r.PrometheusAvailable } @@ -110,6 +115,7 @@ func NewTestReconciler( AppServerImage: OLSAppServerImageDefault, McpServerImage: OLSAppServerImageDefault, LCoreImage: LlamaStackImageDefault, + OcpRagImage: OcpRagImageDefault, DataverseExporter: DataverseExporterImageDefault, openShiftMajor: "123", openShiftMinor: "456", diff --git a/internal/controller/utils/types.go b/internal/controller/utils/types.go index d134377a7..59a99ada2 100644 --- a/internal/controller/utils/types.go +++ b/internal/controller/utils/types.go @@ -24,6 +24,7 @@ type OLSConfigReconcilerOptions struct { DataverseExporterImage string OpenShiftMCPServerImage string LightspeedCoreImage string + OcpRagImage string UseLCore bool Namespace string PrometheusAvailable bool