| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- /*
- 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"
- "github.com/LocoStack/loco-operator/pkg/templates/downloader"
- corev1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/resource"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
- )
- type ArtifactReconciler struct {
- *JobReconciler
- client client.Client
- scheme *runtime.Scheme
- stack *v1alpha1.Stack
- owner metav1.Object
- artifactsSpec *v1alpha1.ArtifactSpec
- }
- func NewArtifactReconciler(client client.Client, scheme *runtime.Scheme, stack *v1alpha1.Stack, component string, owner metav1.Object, artifactsSpec *v1alpha1.ArtifactSpec) *ArtifactReconciler {
- return &ArtifactReconciler{
- JobReconciler: NewJobReconciler(
- client, scheme, stack, "Artifact", owner.GetName(), owner,
- ),
- client: client,
- scheme: scheme,
- stack: stack,
- owner: owner,
- artifactsSpec: artifactsSpec,
- }
- }
- func (r *ArtifactReconciler) ReconcileArtifact(ctx context.Context) (*corev1.PersistentVolumeClaim, bool, bool, error) {
- var pvcName string
- if r.artifactsSpec.PVC != nil {
- pvcName = r.artifactsSpec.PVC.ClaimName
- } else {
- pvcName = fmt.Sprintf("%s-artifacts", r.owner.GetName())
- }
- pvc, err := r.reconcilePVC(ctx, pvcName)
- if err != nil {
- return nil, false, true, err
- }
- if r.artifactsSpec.HuggingFace != nil || r.artifactsSpec.URL != nil {
- variables := map[string]string{
- "spec.pvcName": pvcName,
- }
- var tmpl *v1alpha1.Template
- if r.artifactsSpec.HuggingFace != nil {
- hf := r.artifactsSpec.HuggingFace
- tmpl = downloader.HFDownloaderTemplate.DeepCopy()
- variables["spec.hfRepo"] = hf.Repo
- variables["spec.hfFilename"] = hf.FileName
- if hf.Revision == "" {
- variables["spec.hfRevision"] = "main"
- } else {
- variables["spec.hfRevision"] = hf.Revision
- }
- if hf.Endpoint != "" {
- variables["spec.hfEndpoint"] = hf.Endpoint
- } else {
- variables["spec.hfEndpoint"] = "https://huggingface.co"
- }
- if hf.TokenSecretRef != nil {
- variables["spec.hfToken.name"] = hf.TokenSecretRef.Name
- variables["spec.hfToken.key"] = hf.TokenSecretRef.Key
- } else {
- variables["spec.hfToken.name"] = "not-set"
- variables["spec.hfToken.key"] = "not-set"
- }
- } else if r.artifactsSpec.URL != nil {
- tmpl = downloader.URLDownloaderTemplate.DeepCopy()
- variables["spec.download"] = r.artifactsSpec.URL.URL
- variables["spec.fileName"] = r.artifactsSpec.URL.FileName
- }
- completed, failed, err := r.JobReconciler.ReconcileJob(ctx, tmpl, variables)
- if err != nil {
- return nil, false, true, err
- }
- return pvc, completed, failed, nil
- }
- return pvc, true, false, nil
- }
- func (r *ArtifactReconciler) reconcilePVC(ctx context.Context, pvcName string) (*corev1.PersistentVolumeClaim, error) {
- pvc := &corev1.PersistentVolumeClaim{ObjectMeta: metav1.ObjectMeta{
- Name: pvcName,
- Namespace: r.owner.GetNamespace(),
- }}
- pvcNotFound := false
- if err := r.client.Get(ctx, client.ObjectKeyFromObject(pvc), pvc); err != nil {
- if client.IgnoreNotFound(err) != nil {
- return nil, fmt.Errorf("Failed to get PVC: %w", err)
- }
- pvcNotFound = true
- }
- if pvcNotFound {
- _, err := controllerutil.CreateOrUpdate(ctx, r.client, pvc, func() error {
- if pvc.CreationTimestamp.IsZero() {
- pvc.Labels = ResourceLabels(r.stack.Name, "Artifact", pvcName, "")
- pvc.Spec = corev1.PersistentVolumeClaimSpec{
- AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce},
- Resources: corev1.VolumeResourceRequirements{
- Requests: corev1.ResourceList{
- corev1.ResourceStorage: resource.MustParse("30Gi"),
- },
- },
- }
- }
- return controllerutil.SetControllerReference(r.owner, pvc, r.scheme)
- })
- if err != nil {
- return nil, fmt.Errorf("Failed to create or update PVC: %w", err)
- }
- }
- return pvc, nil
- }
|