Sfoglia il codice sorgente

feat(template): add Qdrant template

Thomas Zhang 3 mesi fa
parent
commit
6c2a1ec787

+ 2 - 0
internal/controller/component_controller.go

@@ -161,6 +161,8 @@ func (r *ComponentReconciler) getComponentReconciler(comp *v1alpha1.Component, s
 	switch comp.Spec.Template.Name {
 	switch comp.Spec.Template.Name {
 	case "litellm":
 	case "litellm":
 		return reconciler.NewLiteLLMReconciler(r.Client, r.Scheme, stack, comp)
 		return reconciler.NewLiteLLMReconciler(r.Client, r.Scheme, stack, comp)
+	case "qdrant":
+		return reconciler.NewQdrantReconciler(r.Client, r.Scheme, stack, comp)
 	default:
 	default:
 		return reconciler.NewDefaultComponentReconciler(r.Client, r.Scheme, stack, comp)
 		return reconciler.NewDefaultComponentReconciler(r.Client, r.Scheme, stack, comp)
 	}
 	}

+ 58 - 0
internal/reconciler/qdrant.go

@@ -0,0 +1,58 @@
+/*
+Copyright 2026 LocoStack.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package reconciler
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/LocoStack/loco-operator/api/v1alpha1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+const (
+	QDRANT_DEFAULT_STORAGE_SIZE = "1Gi"
+)
+
+type QdrantReconciler struct {
+	*DefaultComponentReconciler
+	client    client.Client
+	scheme    *runtime.Scheme
+	stack     *v1alpha1.Stack
+	component *v1alpha1.Component
+}
+
+func NewQdrantReconciler(client client.Client, scheme *runtime.Scheme, stack *v1alpha1.Stack, component *v1alpha1.Component) *QdrantReconciler {
+	return &QdrantReconciler{
+		DefaultComponentReconciler: NewDefaultComponentReconciler(client, scheme, stack, component),
+		client:                     client,
+		scheme:                     scheme,
+		stack:                      stack,
+		component:                  component,
+	}
+}
+
+func (r *QdrantReconciler) ReconcileComponent(ctx context.Context, tmpl *v1alpha1.Template, variables map[string]string) ([]client.Object, error) {
+	if err := r.ReconcileStorage(ctx, "qdrant", QDRANT_DEFAULT_STORAGE_SIZE); err != nil {
+		return nil, fmt.Errorf("reconciling qdrant persistent volume: %w", err)
+	}
+	if _, err := r.DefaultComponentReconciler.ReconcileComponent(ctx, tmpl, variables); err != nil {
+		return nil, err
+	}
+	return nil, nil
+}

+ 54 - 0
pkg/templates/qdrant/template.go

@@ -0,0 +1,54 @@
+/*
+Copyright 2026 LocoStack.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package qdrant
+
+import (
+	"github.com/LocoStack/loco-operator/api/v1alpha1"
+	corev1 "k8s.io/api/core/v1"
+)
+
+const (
+	QDRANT_DATA_PATH = "/data/qdrant"
+)
+
+var QdrantTemplate = v1alpha1.Template{
+	Name: "qdrant",
+	Spec: v1alpha1.TemplateSpec{
+		Runtime: v1alpha1.RuntimeSpec{
+			Name:  "qdrant",
+			Image: "qdrant/qdrant:v1.18.0",
+			Env: []corev1.EnvVar{
+				{Name: "QDRANT__SERVICE__HTTP_PORT", Value: "$(spec.runtime.port)"},
+				{Name: "QDRANT__STORAGE__STORAGE_PATH", Value: QDRANT_DATA_PATH},
+			},
+			VolumeMounts: []corev1.VolumeMount{
+				{Name: "data", MountPath: QDRANT_DATA_PATH},
+			},
+			Port: 6333,
+		},
+		Volumes: []corev1.Volume{
+			{
+				Name: "data",
+				VolumeSource: corev1.VolumeSource{
+					PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
+						ClaimName: "$(metadata.name)-qdrant",
+					},
+				},
+			},
+		},
+	},
+}

+ 3 - 0
pkg/templates/templates.go

@@ -23,6 +23,7 @@ import (
 
 
 	"github.com/LocoStack/loco-operator/api/v1alpha1"
 	"github.com/LocoStack/loco-operator/api/v1alpha1"
 	"github.com/LocoStack/loco-operator/pkg/templates/litellm"
 	"github.com/LocoStack/loco-operator/pkg/templates/litellm"
+	"github.com/LocoStack/loco-operator/pkg/templates/qdrant"
 	corev1 "k8s.io/api/core/v1"
 	corev1 "k8s.io/api/core/v1"
 )
 )
 
 
@@ -240,4 +241,6 @@ var Manager = NewTemplateManager()
 func init() {
 func init() {
 	Manager.RegisterTemplate(litellm.LiteLLMTemplate)
 	Manager.RegisterTemplate(litellm.LiteLLMTemplate)
 	Manager.RegisterRuntime(litellm.LiteLLMTemplate.Spec.Runtime)
 	Manager.RegisterRuntime(litellm.LiteLLMTemplate.Spec.Runtime)
+	Manager.RegisterTemplate(qdrant.QdrantTemplate)
+	Manager.RegisterRuntime(qdrant.QdrantTemplate.Spec.Runtime)
 }
 }