github.com/metaprov/modela-operator@v0.0.0-20240118193048-f378be8b74d2/controllers/components/online_store.go (about) 1 package components 2 3 import ( 4 "context" 5 managementv1 "github.com/metaprov/modela-operator/api/v1alpha1" 6 "github.com/metaprov/modela-operator/pkg/helm" 7 "github.com/metaprov/modela-operator/pkg/kube" 8 k8serr "k8s.io/apimachinery/pkg/api/errors" 9 "sigs.k8s.io/controller-runtime/pkg/log" 10 "sigs.k8s.io/kustomize/kyaml/kio" 11 ) 12 13 // Modela system represent the model core system 14 type OnlineStore struct { 15 Namespace string 16 Version string 17 ReleaseName string 18 Name string 19 PodNamePrefix string 20 ManifestPath string 21 Dryrun bool 22 } 23 24 func NewOnlineStore() *OnlineStore { 25 return &OnlineStore{ 26 Namespace: "modela-system", 27 ManifestPath: "online-store", 28 PodNamePrefix: "modela-online-store", 29 ReleaseName: "modela-redis", 30 Name: "redis", 31 } 32 } 33 34 func (os OnlineStore) GetInstallPhase() managementv1.ModelaPhase { 35 return managementv1.ModelaPhaseInstallingOnlineStore 36 } 37 38 func (os OnlineStore) IsEnabled(modela managementv1.Modela) bool { 39 return modela.Spec.OnlineStore.Install 40 } 41 42 // Check if the database installed 43 func (os OnlineStore) Installed(ctx context.Context) (bool, error) { 44 if created, err := kube.IsNamespaceCreated("modela-system"); !created || err != nil { 45 return created, err 46 } 47 if _, missing, err := kube.LoadResources(os.ManifestPath, nil, false); missing > 0 { 48 log.FromContext(ctx).Info("Resources detected as missing from the modela-system namespace", "count", missing) 49 return false, managementv1.ComponentMissingResourcesError 50 } else if err != nil { 51 return false, err 52 } 53 54 if installed, err := helm.IsChartInstalled(ctx, os.Name, os.Namespace, os.ReleaseName); !installed { 55 return false, err 56 } 57 58 return true, nil 59 } 60 61 func (os OnlineStore) Install(ctx context.Context, modela *managementv1.Modela) error { 62 logger := log.FromContext(ctx) 63 64 if err := kube.CreateNamespace(os.Namespace, modela.Name); err != nil && !k8serr.IsAlreadyExists(err) { 65 logger.Error(err, "failed to create namespace") 66 return err 67 } 68 69 logger.Info("Applying Helm Chart", "version", os.Version) 70 if installed, err := helm.IsChartInstalled(ctx, os.Name, os.Namespace, os.ReleaseName); !installed { 71 if err = helm.InstallChart(ctx, os.Name, os.Namespace, os.ReleaseName, modela.Spec.OnlineStore.Values.Object); err != nil { 72 return err 73 } 74 } 75 76 var password string 77 if values, err := kube.GetSecretValuesAsString("modela-system", "redis"); err == nil { 78 password, _ = values["redis-password"] 79 } 80 81 yaml, _, err := kube.LoadResources(os.ManifestPath, []kio.Filter{ 82 kube.LabelFilter{Labels: map[string]string{"management.modela.ai/operator": modela.Name}}, 83 kube.NamespaceFilter{Namespace: os.Namespace}, 84 kube.RedisSecretFilter{Password: password}, 85 kube.ContainerVersionFilter{Version: modela.Spec.Distribution}, 86 kube.OwnerReferenceFilter{Owner: modela.GetName(), OwnerNamespace: modela.GetNamespace(), UID: string(modela.GetUID())}, 87 }, false) 88 if err != nil { 89 return err 90 } 91 92 logger.Info("Applying online store resources", "length", len(yaml)) 93 if err := kube.ApplyYaml(string(yaml)); err != nil { 94 return err 95 } 96 97 return nil 98 } 99 100 func (os OnlineStore) InstallNewVersion(ctx context.Context, modela *managementv1.Modela) error { 101 logger := log.FromContext(ctx) 102 103 var password string 104 if values, err := kube.GetSecretValuesAsString("modela-system", "redis"); err == nil { 105 password, _ = values["redis-password"] 106 } 107 108 yaml, _, err := kube.LoadResources(os.ManifestPath, []kio.Filter{ 109 kube.LabelFilter{Labels: map[string]string{"management.modela.ai/operator": modela.Name}}, 110 kube.NamespaceFilter{Namespace: os.Namespace}, 111 kube.RedisSecretFilter{Password: password}, 112 kube.ContainerVersionFilter{Version: modela.Spec.Distribution}, 113 kube.OwnerReferenceFilter{Owner: modela.GetName(), OwnerNamespace: modela.GetNamespace(), UID: string(modela.GetUID())}, 114 }, false) 115 if err != nil { 116 return err 117 } 118 119 logger.Info("Applying online store resources", "length", len(yaml), "ns", os.Namespace) 120 if err := kube.ApplyYaml(string(yaml)); err != nil { 121 return err 122 } 123 124 return nil 125 } 126 127 func (os OnlineStore) Installing(ctx context.Context) (bool, error) { 128 installed, err := os.Installed(ctx) 129 if !installed { 130 return installed, err 131 } 132 133 running, err := kube.IsPodRunning(os.Namespace, os.PodNamePrefix) 134 if err != nil { 135 return false, err 136 } 137 return !running, nil 138 } 139 140 func (os OnlineStore) Ready(ctx context.Context) (bool, error) { 141 installing, err := os.Installing(ctx) 142 if err != nil && err != managementv1.ComponentNotInstalledByModelaError { 143 return false, err 144 } 145 return !installing, nil 146 } 147 148 func (os OnlineStore) Uninstall(ctx context.Context, modela *managementv1.Modela) error { 149 return helm.UninstallChart(ctx, os.Name, os.Namespace, os.ReleaseName, map[string]interface{}{}) 150 }