Skip to content

Commit 348ec68

Browse files
Adding the Volume and volumeMount with code review comments. and rebased with the master.
Signed-off-by: lrangine <[email protected]> Signed-off-by: lrangine <[email protected]>
1 parent 7593bb3 commit 348ec68

File tree

5 files changed

+130
-5
lines changed

5 files changed

+130
-5
lines changed

infra/feast-operator/api/v1alpha1/featurestore_types.go

+25-2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ type FeatureStoreServices struct {
7878
DeploymentStrategy *appsv1.DeploymentStrategy `json:"deploymentStrategy,omitempty"`
7979
// Disable the 'feast repo initialization' initContainer
8080
DisableInitContainers bool `json:"disableInitContainers,omitempty"`
81+
// Volumes specifies the volumes to mount in the FeatureStore deployment. A corresponding `VolumeMount` should be added to whichever feast service(s) require access to said volume(s).
82+
Volumes []corev1.Volume `json:"volumes,omitempty"`
8183
}
8284

8385
// OfflineStore configures the deployed offline store service
@@ -89,6 +91,11 @@ type OfflineStore struct {
8991
// Allowed values: "debug", "info", "warning", "error", "critical".
9092
// +kubebuilder:validation:Enum=debug;info;warning;error;critical
9193
LogLevel string `json:"logLevel,omitempty"`
94+
// VolumeMounts defines the list of volumes that should be mounted into the feast container.
95+
// This allows attaching persistent storage, config files, secrets, or other resources
96+
// required by the Feast components. Ensure that each volume mount has a corresponding
97+
// volume definition in the Volumes field.
98+
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
9299
}
93100

94101
// OfflineStorePersistence configures the persistence settings for the offline store service
@@ -142,6 +149,12 @@ type OnlineStore struct {
142149
// Allowed values: "debug", "info", "warning", "error", "critical".
143150
// +kubebuilder:validation:Enum=debug;info;warning;error;critical
144151
LogLevel string `json:"logLevel,omitempty"`
152+
153+
// VolumeMounts defines the list of volumes that should be mounted into the feast container.
154+
// This allows attaching persistent storage, config files, secrets, or other resources
155+
// required by the Feast components. Ensure that each volume mount has a corresponding
156+
// volume definition in the Volumes field.
157+
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
145158
}
146159

147160
// OnlineStorePersistence configures the persistence settings for the online store service
@@ -151,7 +164,7 @@ type OnlineStorePersistence struct {
151164
DBPersistence *OnlineStoreDBStorePersistence `json:"store,omitempty"`
152165
}
153166

154-
// OnlineStoreFilePersistence configures the file-based persistence for the offline store service
167+
// OnlineStoreFilePersistence configures the file-based persistence for the online store service
155168
// +kubebuilder:validation:XValidation:rule="(!has(self.pvc) && has(self.path)) ? self.path.startsWith('/') : true",message="Ephemeral stores must have absolute paths."
156169
// +kubebuilder:validation:XValidation:rule="(has(self.pvc) && has(self.path)) ? !self.path.startsWith('/') : true",message="PVC path must be a file name only, with no slashes."
157170
// +kubebuilder:validation:XValidation:rule="has(self.path) ? !(self.path.startsWith('s3://') || self.path.startsWith('gs://')) : true",message="Online store does not support S3 or GS buckets."
@@ -160,7 +173,7 @@ type OnlineStoreFilePersistence struct {
160173
PvcConfig *PvcConfig `json:"pvc,omitempty"`
161174
}
162175

163-
// OnlineStoreDBStorePersistence configures the DB store persistence for the offline store service
176+
// OnlineStoreDBStorePersistence configures the DB store persistence for the online store service
164177
type OnlineStoreDBStorePersistence struct {
165178
// +kubebuilder:validation:Enum=snowflake.online;redis;ikv;datastore;dynamodb;bigtable;postgres;cassandra;mysql;hazelcast;singlestore;hbase;elasticsearch;qdrant;couchbase;milvus
166179
Type string `json:"type"`
@@ -198,6 +211,11 @@ type LocalRegistryConfig struct {
198211
// Allowed values: "debug", "info", "warning", "error", "critical".
199212
// +kubebuilder:validation:Enum=debug;info;warning;error;critical
200213
LogLevel string `json:"logLevel,omitempty"`
214+
// VolumeMounts defines the list of volumes that should be mounted into the feast container.
215+
// This allows attaching persistent storage, config files, secrets, or other resources
216+
// required by the Feast components. Ensure that each volume mount has a corresponding
217+
// volume definition in the Volumes field.
218+
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
201219
}
202220

203221
// RegistryPersistence configures the persistence settings for the registry service
@@ -290,6 +308,11 @@ type UIService struct {
290308
// Allowed values: "debug", "info", "warning", "error", "critical".
291309
// +kubebuilder:validation:Enum=debug;info;warning;error;critical
292310
LogLevel string `json:"logLevel,omitempty"`
311+
// VolumeMounts defines the list of volumes that should be mounted into the feast UI container.
312+
// This allows attaching persistent storage, config files, secrets, or other resources
313+
// required by the Feast components. Ensure that each volume mount has a corresponding
314+
// volume definition in the Volumes field.
315+
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
293316
}
294317

295318
// FeatureStoreRef defines which existing FeatureStore's registry should be used

infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go

+35
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infra/feast-operator/docs/api/markdown/ref.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ _Appears in:_
9595
| `ui` _[UIService](#uiservice)_ | |
9696
| `deploymentStrategy` _[DeploymentStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#deploymentstrategy-v1-apps)_ | |
9797
| `disableInitContainers` _boolean_ | Disable the 'feast repo initialization' initContainer |
98+
| `volumes` _[Volume](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#volume-v1-core) array_ | Volumes specifies the list of volumes to mount in the FeatureStore deployment. |
9899

99100

100101
#### FeatureStoreSpec
@@ -195,6 +196,7 @@ _Appears in:_
195196
| `tls` _[TlsConfigs](#tlsconfigs)_ | |
196197
| `logLevel` _string_ | LogLevel sets the logging level for the offline store service
197198
Allowed values: "debug", "info", "warning", "error", "critical". |
199+
| `volumeMounts` _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#volumemount-v1-core) array_ | |
198200

199201

200202
#### OfflineStoreDBStorePersistence
@@ -278,13 +280,14 @@ _Appears in:_
278280
| `tls` _[TlsConfigs](#tlsconfigs)_ | |
279281
| `logLevel` _string_ | LogLevel sets the logging level for the online store service
280282
Allowed values: "debug", "info", "warning", "error", "critical". |
283+
| `volumeMounts` _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#volumemount-v1-core) array_ | |
281284

282285

283286
#### OnlineStoreDBStorePersistence
284287

285288

286289

287-
OnlineStoreDBStorePersistence configures the DB store persistence for the offline store service
290+
OnlineStoreDBStorePersistence configures the DB store persistence for the online store service
288291

289292
_Appears in:_
290293
- [OnlineStorePersistence](#onlinestorepersistence)
@@ -300,7 +303,7 @@ _Appears in:_
300303

301304

302305

303-
OnlineStoreFilePersistence configures the file-based persistence for the offline store service
306+
OnlineStoreFilePersistence configures the file-based persistence for the online store service
304307

305308
_Appears in:_
306309
- [OnlineStorePersistence](#onlinestorepersistence)
@@ -375,6 +378,7 @@ _Appears in:_
375378
| --- | --- |
376379
| `local` _[LocalRegistryConfig](#localregistryconfig)_ | |
377380
| `remote` _[RemoteRegistryConfig](#remoteregistryconfig)_ | |
381+
| `volumeMounts` _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#volumemount-v1-core) array_ | |
378382

379383

380384
#### RegistryDBStorePersistence
@@ -537,5 +541,6 @@ _Appears in:_
537541
| `tls` _[TlsConfigs](#tlsconfigs)_ | |
538542
| `logLevel` _string_ | LogLevel sets the logging level for the UI service
539543
Allowed values: "debug", "info", "warning", "error", "critical". |
544+
| `volumeMounts` _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#volumemount-v1-core) array_ | |
540545

541546

infra/feast-operator/internal/controller/featurestore_controller_test_utils_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,38 @@ func createFeatureStoreResource(resourceName string, image string, pullPolicy co
104104
Spec: feastdevv1alpha1.FeatureStoreSpec{
105105
FeastProject: feastProject,
106106
Services: &feastdevv1alpha1.FeatureStoreServices{
107+
Volumes: []corev1.Volume{
108+
{
109+
Name: "config-volume",
110+
VolumeSource: corev1.VolumeSource{
111+
ConfigMap: &corev1.ConfigMapVolumeSource{
112+
LocalObjectReference: corev1.LocalObjectReference{
113+
Name: "my-config",
114+
},
115+
},
116+
},
117+
},
118+
},
107119
OfflineStore: &feastdevv1alpha1.OfflineStore{
120+
VolumeMounts: []corev1.VolumeMount{
121+
{
122+
Name: "config-volume",
123+
MountPath: "/etc/service-config",
124+
},
125+
},
108126
ServiceConfigs: feastdevv1alpha1.ServiceConfigs{
109127
OptionalConfigs: feastdevv1alpha1.OptionalConfigs{
110128
EnvFrom: envFromVar,
111129
},
112130
},
113131
},
114132
OnlineStore: &feastdevv1alpha1.OnlineStore{
133+
VolumeMounts: []corev1.VolumeMount{
134+
{
135+
Name: "config-volume",
136+
MountPath: "/etc/service-config",
137+
},
138+
},
115139
ServiceConfigs: feastdevv1alpha1.ServiceConfigs{
116140
DefaultConfigs: feastdevv1alpha1.DefaultConfigs{
117141
Image: &image,

infra/feast-operator/internal/controller/services/services.go

+39-1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,13 @@ func (feast *FeastServices) createPVC(pvcCreate *feastdevv1alpha1.PvcCreate, fea
325325
}
326326

327327
func (feast *FeastServices) setDeployment(deploy *appsv1.Deployment) error {
328+
var volumes []corev1.Volume
329+
if feast.Handler.FeatureStore.Spec.Services != nil {
330+
volumes = feast.Handler.FeatureStore.Spec.Services.Volumes
331+
}
332+
if volumes == nil {
333+
volumes = []corev1.Volume{} // Ensure it's an empty slice instead of nil
334+
}
328335
deploy.Labels = feast.getLabels()
329336
deploy.Spec = appsv1.DeploymentSpec{
330337
Replicas: &DefaultReplicas,
@@ -336,6 +343,7 @@ func (feast *FeastServices) setDeployment(deploy *appsv1.Deployment) error {
336343
},
337344
Spec: corev1.PodSpec{
338345
ServiceAccountName: feast.initFeastSA().Name,
346+
Volumes: volumes,
339347
},
340348
},
341349
}
@@ -379,7 +387,8 @@ func (feast *FeastServices) setContainers(podSpec *corev1.PodSpec) error {
379387
return nil
380388
}
381389

382-
func (feast *FeastServices) setContainer(containers *[]corev1.Container, feastType FeastServiceType, fsYamlB64 string) {
390+
func (feast *FeastServices) setContainer(containers *[]corev1.Container, feastType FeastServiceType,
391+
fsYamlB64 string) {
383392
tls := feast.getTlsConfigs(feastType)
384393
serviceConfigs := feast.getServiceConfigs(feastType)
385394
defaultServiceConfigs := serviceConfigs.DefaultConfigs
@@ -416,11 +425,40 @@ func (feast *FeastServices) setContainer(containers *[]corev1.Container, feastTy
416425
ProbeHandler: probeHandler,
417426
PeriodSeconds: 10,
418427
},
428+
VolumeMounts: feast.getVolumeMounts(feastType),
419429
}
420430
applyOptionalContainerConfigs(container, serviceConfigs.OptionalConfigs)
421431
*containers = append(*containers, *container)
422432
}
423433

434+
func (feast *FeastServices) getVolumeMounts(feastType FeastServiceType) (volumeMounts []corev1.VolumeMount) {
435+
appliedServices := feast.Handler.FeatureStore.Status.Applied.Services
436+
if appliedServices == nil {
437+
return []corev1.VolumeMount{} // Return an empty slice to avoid nil issues
438+
}
439+
440+
switch feastType {
441+
case OfflineFeastType:
442+
if feast.isOfflinStore() {
443+
return appliedServices.OfflineStore.VolumeMounts
444+
}
445+
case OnlineFeastType:
446+
if feast.isOnlinStore() {
447+
return appliedServices.OnlineStore.VolumeMounts
448+
}
449+
case RegistryFeastType:
450+
if feast.isLocalRegistry() {
451+
return appliedServices.Registry.Local.VolumeMounts
452+
}
453+
case UIFeastType:
454+
if feast.isUI() {
455+
return appliedServices.UI.VolumeMounts
456+
}
457+
}
458+
459+
return []corev1.VolumeMount{} // Default empty slice
460+
}
461+
424462
func (feast *FeastServices) setRoute(route *routev1.Route, feastType FeastServiceType) error {
425463

426464
svcName := feast.GetFeastServiceName(feastType)

0 commit comments

Comments
 (0)