Skip to content

Commit 611400f

Browse files
committed
Fix nodePlugin affinity not propagating from OperatorConfig to DaemonSet
Rook creates Driver CRs with a non-nil but empty Affinity struct. The merge logic only checked if Affinity == nil, so the affinity from OperatorConfig.driverSpecDefaults was never applied. Add isAffinityEmpty() helper to check for nil or effectively empty affinity structs, allowing the merge to properly fill in defaults. Signed-off-by: ksc98 <kylechang96@gmail.com>
1 parent 7c71102 commit 611400f

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

internal/controller/driver_controller.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,7 +1731,7 @@ func mergeDriverSpecs(dest, src *csiv1.DriverSpec) {
17311731
if dest.Annotations == nil {
17321732
dest.Annotations = src.Annotations
17331733
}
1734-
if dest.Affinity == nil {
1734+
if isAffinityEmpty(dest.Affinity) {
17351735
dest.Affinity = src.Affinity
17361736
}
17371737
if dest.Tolerations == nil {
@@ -1786,7 +1786,7 @@ func mergeDriverSpecs(dest, src *csiv1.DriverSpec) {
17861786
if dest.Annotations == nil {
17871787
dest.Annotations = src.Annotations
17881788
}
1789-
if dest.Affinity == nil {
1789+
if isAffinityEmpty(dest.Affinity) {
17901790
dest.Affinity = src.Affinity
17911791
}
17921792
if dest.Tolerations == nil {
@@ -1855,3 +1855,14 @@ func mergeDriverSpecs(dest, src *csiv1.DriverSpec) {
18551855
dest.CephFsClientType = src.CephFsClientType
18561856
}
18571857
}
1858+
1859+
// isAffinityEmpty checks if an Affinity is nil or has no meaningful content.
1860+
// This handles the case where an Affinity struct is non-nil but contains only
1861+
// empty nested structs (e.g., &Affinity{NodeAffinity: &NodeAffinity{}}).
1862+
func isAffinityEmpty(affinity *corev1.Affinity) bool {
1863+
if affinity == nil {
1864+
return true
1865+
}
1866+
return reflect.DeepEqual(affinity, &corev1.Affinity{}) ||
1867+
reflect.DeepEqual(affinity, &corev1.Affinity{NodeAffinity: &corev1.NodeAffinity{}})
1868+
}

internal/controller/driver_controller_test.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ import (
2121

2222
. "github.com/onsi/ginkgo/v2"
2323
. "github.com/onsi/gomega"
24+
corev1 "k8s.io/api/core/v1"
2425
"k8s.io/apimachinery/pkg/api/errors"
26+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2527
"k8s.io/apimachinery/pkg/types"
2628
"sigs.k8s.io/controller-runtime/pkg/reconcile"
2729

28-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29-
3030
csiv1 "github.com/ceph/ceph-csi-operator/api/v1"
3131
)
3232

@@ -82,3 +82,41 @@ var _ = Describe("Driver Controller", func() {
8282
})
8383
})
8484
})
85+
86+
var _ = Describe("isAffinityEmpty", func() {
87+
It("should return true for nil affinity", func() {
88+
Expect(isAffinityEmpty(nil)).To(BeTrue())
89+
})
90+
91+
It("should return true for empty affinity struct", func() {
92+
Expect(isAffinityEmpty(&corev1.Affinity{})).To(BeTrue())
93+
})
94+
95+
It("should return true for affinity with empty NodeAffinity", func() {
96+
affinity := &corev1.Affinity{
97+
NodeAffinity: &corev1.NodeAffinity{},
98+
}
99+
Expect(isAffinityEmpty(affinity)).To(BeTrue())
100+
})
101+
102+
It("should return false for affinity with NodeAffinity content", func() {
103+
affinity := &corev1.Affinity{
104+
NodeAffinity: &corev1.NodeAffinity{
105+
RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
106+
NodeSelectorTerms: []corev1.NodeSelectorTerm{
107+
{
108+
MatchExpressions: []corev1.NodeSelectorRequirement{
109+
{
110+
Key: "kubernetes.io/hostname",
111+
Operator: corev1.NodeSelectorOpNotIn,
112+
Values: []string{"node1"},
113+
},
114+
},
115+
},
116+
},
117+
},
118+
},
119+
}
120+
Expect(isAffinityEmpty(affinity)).To(BeFalse())
121+
})
122+
})

0 commit comments

Comments
 (0)