@@ -384,10 +384,13 @@ func (feast *FeastServices) createPVC(pvcCreate *feastdevv1.PvcCreate, feastType
384384 }
385385
386386 // PVCs are immutable, so we only create... we don't update an existing one.
387+ // Treat AlreadyExists as success: a pre-existing PVC without the managed-by label
388+ // won't appear in the filtered cache (Client.Get returns NotFound), but Create
389+ // will hit AlreadyExists on the API server — both cases mean the PVC is present.
387390 err = feast .Handler .Client .Get (feast .Handler .Context , client .ObjectKeyFromObject (pvc ), pvc )
388391 if err != nil && apierrors .IsNotFound (err ) {
389392 err = feast .Handler .Client .Create (feast .Handler .Context , pvc )
390- if err != nil {
393+ if err != nil && ! apierrors . IsAlreadyExists ( err ) {
391394 return err
392395 }
393396 logger .Info ("Successfully created" , "PersistentVolumeClaim" , pvc .Name )
@@ -408,9 +411,10 @@ func (feast *FeastServices) setDeployment(deploy *appsv1.Deployment) error {
408411 }
409412
410413 deploy .Labels = feast .getLabels ()
414+ selectorLabels := feast .getSelectorLabels ()
411415 deploy .Spec = appsv1.DeploymentSpec {
412416 Replicas : replicas ,
413- Selector : metav1 .SetAsLabelSelector (deploy . GetLabels () ),
417+ Selector : metav1 .SetAsLabelSelector (selectorLabels ),
414418 Strategy : feast .getDeploymentStrategy (),
415419 Template : corev1.PodTemplateSpec {
416420 ObjectMeta : metav1.ObjectMeta {
@@ -818,7 +822,7 @@ func (feast *FeastServices) setService(svc *corev1.Service, feastType FeastServi
818822 }
819823
820824 svc .Spec = corev1.ServiceSpec {
821- Selector : feast .getLabels (),
825+ Selector : feast .getSelectorLabels (),
822826 Type : corev1 .ServiceTypeClusterIP ,
823827 Ports : []corev1.ServicePort {
824828 {
@@ -868,6 +872,7 @@ func (feast *FeastServices) setServiceAccount(sa *corev1.ServiceAccount) error {
868872
869873func (feast * FeastServices ) createNewPVC (pvcCreate * feastdevv1.PvcCreate , feastType FeastServiceType ) (* corev1.PersistentVolumeClaim , error ) {
870874 pvc := feast .initPVC (feastType )
875+ pvc .Labels = feast .getFeastTypeLabels (feastType )
871876
872877 pvc .Spec = corev1.PersistentVolumeClaimSpec {
873878 AccessModes : pvcCreate .AccessModes ,
@@ -976,7 +981,7 @@ func (feast *FeastServices) applyTopologySpread(podSpec *corev1.PodSpec) {
976981 MaxSkew : 1 ,
977982 TopologyKey : "topology.kubernetes.io/zone" ,
978983 WhenUnsatisfiable : corev1 .ScheduleAnyway ,
979- LabelSelector : metav1 .SetAsLabelSelector (feast .getLabels ()),
984+ LabelSelector : metav1 .SetAsLabelSelector (feast .getSelectorLabels ()),
980985 }}
981986}
982987
@@ -999,7 +1004,7 @@ func (feast *FeastServices) applyAffinity(podSpec *corev1.PodSpec) {
9991004 Weight : 100 ,
10001005 PodAffinityTerm : corev1.PodAffinityTerm {
10011006 TopologyKey : "kubernetes.io/hostname" ,
1002- LabelSelector : metav1 .SetAsLabelSelector (feast .getLabels ()),
1007+ LabelSelector : metav1 .SetAsLabelSelector (feast .getSelectorLabels ()),
10031008 },
10041009 }},
10051010 },
@@ -1060,12 +1065,24 @@ func (feast *FeastServices) getFeastTypeLabels(feastType FeastServiceType) map[s
10601065 return labels
10611066}
10621067
1063- func (feast * FeastServices ) getLabels () map [string ]string {
1068+ // getSelectorLabels returns the minimal label set used for immutable selectors
1069+ // (Deployment spec.selector, Service spec.selector, TopologySpreadConstraints, PodAffinity).
1070+ // This must NOT change after initial resource creation.
1071+ func (feast * FeastServices ) getSelectorLabels () map [string ]string {
10641072 return map [string ]string {
10651073 NameLabelKey : feast .Handler .FeatureStore .Name ,
10661074 }
10671075}
10681076
1077+ // getLabels returns the full label set for mutable metadata (ObjectMeta.Labels).
1078+ // Includes the managed-by label used by the informer cache filter.
1079+ func (feast * FeastServices ) getLabels () map [string ]string {
1080+ return map [string ]string {
1081+ NameLabelKey : feast .Handler .FeatureStore .Name ,
1082+ ManagedByLabelKey : ManagedByLabelValue ,
1083+ }
1084+ }
1085+
10691086func (feast * FeastServices ) setServiceHostnames () error {
10701087 feast .Handler .FeatureStore .Status .ServiceHostnames = feastdevv1.ServiceHostnames {}
10711088 domain := svcDomain + ":"
@@ -1438,10 +1455,10 @@ func IsDeploymentAvailable(conditions []appsv1.DeploymentCondition) bool {
14381455// container that is in a failing state. Returns empty string if no failure found.
14391456func (feast * FeastServices ) GetPodContainerFailureMessage (deploy appsv1.Deployment ) string {
14401457 podList := corev1.PodList {}
1441- labels := feast .getLabels ()
1458+ selectorLabels := feast .getSelectorLabels ()
14421459 if err := feast .Handler .Client .List (feast .Handler .Context , & podList ,
14431460 client .InNamespace (deploy .Namespace ),
1444- client .MatchingLabels (labels ),
1461+ client .MatchingLabels (selectorLabels ),
14451462 ); err != nil {
14461463 return ""
14471464 }
0 commit comments