Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: PVC configuration and impl #4750

Merged
merged 12 commits into from
Nov 13, 2024
1 change: 1 addition & 0 deletions infra/feast-operator/config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ rules:
- ""
resources:
- configmaps
- persistentvolumeclaims
- services
verbs:
- create
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ spec:
file:
path: registry.db
pvc:
create: {}
create:
storageClassName: standard
resources:
requests:
storage: 1Gi
mountPath: /data/registry
dmartinol marked this conversation as resolved.
Show resolved Hide resolved
---
apiVersion: v1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type FeatureStoreReconciler struct {
//+kubebuilder:rbac:groups=feast.dev,resources=featurestores/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=feast.dev,resources=featurestores/finalizers,verbs=update
//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;create;update;watch;delete
//+kubebuilder:rbac:groups=core,resources=services;configmaps,verbs=get;list;create;update;watch;delete
//+kubebuilder:rbac:groups=core,resources=services;configmaps;persistentvolumeclaims,verbs=get;list;create;update;watch;delete

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
Expand Down Expand Up @@ -142,6 +142,7 @@ func (r *FeatureStoreReconciler) SetupWithManager(mgr ctrl.Manager) error {
Owns(&corev1.ConfigMap{}).
Owns(&appsv1.Deployment{}).
Owns(&corev1.Service{}).
Owns(&corev1.PersistentVolumeClaim{}).
Watches(&feastdevv1alpha1.FeatureStore{}, handler.EnqueueRequestsFromMapFunc(r.mapFeastRefsToFeastRequests)).
Complete(r)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
onlineStoreMountPath := "/online"
registryMountPath := "/registry"

storageClassName := "default"
dmartinol marked this conversation as resolved.
Show resolved Hide resolved

onlineStoreMountedPath := path.Join(onlineStoreMountPath, onlineStorePath)
registryMountedPath := path.Join(registryMountPath, registryPath)

Expand All @@ -80,7 +82,9 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
FilePersistence: &feastdevv1alpha1.OfflineStoreFilePersistence{
Type: offlineType,
PvcConfig: &feastdevv1alpha1.PvcConfig{
Create: &feastdevv1alpha1.PvcCreate{},
Create: &feastdevv1alpha1.PvcCreate{
StorageClassName: &storageClassName,
},
MountPath: offlineStoreMountPath,
},
},
Expand Down Expand Up @@ -153,7 +157,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Expect(resource.Status.Applied.Services.OfflineStore.Persistence.FilePersistence.Type).To(Equal(offlineType))
Expect(resource.Status.Applied.Services.OfflineStore.Persistence.FilePersistence.PvcConfig).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore.Persistence.FilePersistence.PvcConfig.Create).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore.Persistence.FilePersistence.PvcConfig.Create.StorageClassName).To(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore.Persistence.FilePersistence.PvcConfig.Create.StorageClassName).To(Equal(&storageClassName))
expectedResources := corev1.VolumeResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceStorage: apiresource.MustParse("20Gi"),
Expand Down Expand Up @@ -270,6 +274,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
pvc)
Expect(err).NotTo(HaveOccurred())
Expect(pvc.Name).To(Equal(deploy.Name))
Expect(pvc.Spec.StorageClassName).To(Equal(&storageClassName))
Expect(pvc.Spec.Resources.Requests.Storage().String()).To(Equal(services.DefaultOfflineStorageRequest))
Expect(pvc.DeletionTimestamp).To(BeNil())

Expand Down
81 changes: 43 additions & 38 deletions infra/feast-operator/internal/controller/services/repo_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,47 +54,52 @@ func getServiceRepoConfig(feastType FeastServiceType, featureStore *feastdevv1al
isLocalRegistry := isLocalRegistry(featureStore)
if appliedSpec.Services != nil {
services := appliedSpec.Services
// Offline server has an `offline_store` section and a remote `registry`
if feastType == OfflineFeastType && services.OfflineStore != nil {
fileType := string(OfflineDaskConfigType)
if services.OfflineStore.Persistence != nil &&
services.OfflineStore.Persistence.FilePersistence != nil &&
len(services.OfflineStore.Persistence.FilePersistence.Type) > 0 {
fileType = services.OfflineStore.Persistence.FilePersistence.Type
switch feastType {
case OfflineFeastType:
// Offline server has an `offline_store` section and a remote `registry`
if services.OfflineStore != nil {
fileType := string(OfflineDaskConfigType)
if services.OfflineStore.Persistence != nil &&
services.OfflineStore.Persistence.FilePersistence != nil &&
len(services.OfflineStore.Persistence.FilePersistence.Type) > 0 {
fileType = services.OfflineStore.Persistence.FilePersistence.Type
}

repoConfig.OfflineStore = OfflineStoreConfig{
Type: OfflineConfigType(fileType),
}
repoConfig.OnlineStore = OnlineStoreConfig{}
}

repoConfig.OfflineStore = OfflineStoreConfig{
Type: OfflineConfigType(fileType),
}
repoConfig.OnlineStore = OnlineStoreConfig{}
}
// Online server has an `online_store` section, a remote `registry` and a remote `offline_store`
if feastType == OnlineFeastType && services.OnlineStore != nil {
path := DefaultOnlineStoreEphemeralPath
if services.OnlineStore.Persistence != nil && services.OnlineStore.Persistence.FilePersistence != nil {
filePersistence := services.OnlineStore.Persistence.FilePersistence
path = getActualPath(filePersistence.Path, filePersistence.PvcConfig)
}

repoConfig.OnlineStore = OnlineStoreConfig{
Type: OnlineSqliteConfigType,
Path: path,
}
}
// Registry server only has a `registry` section
if feastType == RegistryFeastType && isLocalRegistry {
path := DefaultRegistryEphemeralPath
if services != nil && services.Registry != nil && services.Registry.Local != nil &&
services.Registry.Local.Persistence != nil && services.Registry.Local.Persistence.FilePersistence != nil {
filePersistence := services.Registry.Local.Persistence.FilePersistence
path = getActualPath(filePersistence.Path, filePersistence.PvcConfig)
case OnlineFeastType:
// Online server has an `online_store` section, a remote `registry` and a remote `offline_store`
if services.OnlineStore != nil {
path := DefaultOnlineStoreEphemeralPath
if services.OnlineStore.Persistence != nil && services.OnlineStore.Persistence.FilePersistence != nil {
filePersistence := services.OnlineStore.Persistence.FilePersistence
path = getActualPath(filePersistence.Path, filePersistence.PvcConfig)
}

repoConfig.OnlineStore = OnlineStoreConfig{
Type: OnlineSqliteConfigType,
Path: path,
}
}
repoConfig.Registry = RegistryConfig{
RegistryType: RegistryFileConfigType,
Path: path,
case RegistryFeastType:
// Registry server only has a `registry` section
if isLocalRegistry {
path := DefaultRegistryEphemeralPath
if services != nil && services.Registry != nil && services.Registry.Local != nil &&
services.Registry.Local.Persistence != nil && services.Registry.Local.Persistence.FilePersistence != nil {
filePersistence := services.Registry.Local.Persistence.FilePersistence
path = getActualPath(filePersistence.Path, filePersistence.PvcConfig)
}
repoConfig.Registry = RegistryConfig{
RegistryType: RegistryFileConfigType,
Path: path,
}
repoConfig.OfflineStore = OfflineStoreConfig{}
repoConfig.OnlineStore = OnlineStoreConfig{}
}
repoConfig.OfflineStore = OfflineStoreConfig{}
repoConfig.OnlineStore = OnlineStoreConfig{}
}
}

Expand Down
26 changes: 17 additions & 9 deletions infra/feast-operator/internal/controller/services/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,20 +259,28 @@ func (feast *FeastServices) createNewPVC(pvcCreate *feastdevv1alpha1.PvcCreate,
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteMany},
Resources: pvcCreate.Resources,
}
if pvcCreate.StorageClassName != nil {
pvc.Spec.StorageClassName = pvcCreate.StorageClassName
}
return pvc, controllerutil.SetControllerReference(feast.FeatureStore, pvc, feast.Scheme)
}

func (feast *FeastServices) getServiceConfigs(feastType FeastServiceType) feastdevv1alpha1.ServiceConfigs {
appliedSpec := feast.FeatureStore.Status.Applied
if feastType == OfflineFeastType && appliedSpec.Services.OfflineStore != nil {
return appliedSpec.Services.OfflineStore.ServiceConfigs
}
if feastType == OnlineFeastType && appliedSpec.Services.OnlineStore != nil {
return appliedSpec.Services.OnlineStore.ServiceConfigs
}
if feastType == RegistryFeastType && appliedSpec.Services.Registry != nil {
if appliedSpec.Services.Registry.Local != nil {
return appliedSpec.Services.Registry.Local.ServiceConfigs
switch feastType {
case OfflineFeastType:
if appliedSpec.Services.OfflineStore != nil {
return appliedSpec.Services.OfflineStore.ServiceConfigs
}
case OnlineFeastType:
if appliedSpec.Services.OnlineStore != nil {
return appliedSpec.Services.OnlineStore.ServiceConfigs
}
case RegistryFeastType:
if appliedSpec.Services.Registry != nil {
if appliedSpec.Services.Registry.Local != nil {
return appliedSpec.Services.Registry.Local.ServiceConfigs
}
}
}
return feastdevv1alpha1.ServiceConfigs{}
Expand Down
21 changes: 13 additions & 8 deletions infra/feast-operator/internal/controller/services/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@ func isLocalRegistry(featureStore *feastdevv1alpha1.FeatureStore) bool {
func hasPvcConfig(featureStore *feastdevv1alpha1.FeatureStore, feastType FeastServiceType) (*feastdevv1alpha1.PvcConfig, bool) {
services := featureStore.Status.Applied.Services
var pvcConfig *feastdevv1alpha1.PvcConfig = nil
if feastType == OnlineFeastType && services.OnlineStore != nil && services.OnlineStore.Persistence.FilePersistence != nil {
pvcConfig = services.OnlineStore.Persistence.FilePersistence.PvcConfig
}
if feastType == OfflineFeastType && services.OfflineStore != nil && services.OfflineStore.Persistence.FilePersistence != nil {
pvcConfig = services.OfflineStore.Persistence.FilePersistence.PvcConfig
}
if feastType == RegistryFeastType && isLocalRegistry(featureStore) && services.Registry.Local.Persistence.FilePersistence != nil {
pvcConfig = services.Registry.Local.Persistence.FilePersistence.PvcConfig
switch feastType {
case OnlineFeastType:
if services.OnlineStore != nil && services.OnlineStore.Persistence.FilePersistence != nil {
pvcConfig = services.OnlineStore.Persistence.FilePersistence.PvcConfig
}
case OfflineFeastType:
if services.OfflineStore != nil && services.OfflineStore.Persistence.FilePersistence != nil {
pvcConfig = services.OfflineStore.Persistence.FilePersistence.PvcConfig
}
case RegistryFeastType:
if isLocalRegistry(featureStore) && services.Registry.Local.Persistence.FilePersistence != nil {
pvcConfig = services.Registry.Local.Persistence.FilePersistence.PvcConfig
}
}
return pvcConfig, pvcConfig != nil
}
Expand Down
Loading