diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 627238415..e059759dd 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -340,6 +340,20 @@ func (c *Cluster) compareStatefulSetWith(statefulSet *v1beta1.StatefulSet) *comp needsRollUpdate = true reasons = append(reasons, "new statefulset's metadata labels doesn't match the current one") } + if (c.Statefulset.Spec.Selector != nil) && (statefulSet.Spec.Selector != nil) { + if !reflect.DeepEqual(c.Statefulset.Spec.Selector.MatchLabels, statefulSet.Spec.Selector.MatchLabels) { + // forbid introducing new labels in the selector on the new statefulset, as it would cripple replacements + // due to the fact that the new statefulset won't be able to pick up old pods with non-matching labels. + if !util.MapContains(c.Statefulset.Spec.Selector.MatchLabels, statefulSet.Spec.Selector.MatchLabels) { + c.logger.Warningf("new statefulset introduces extra labels in the label selector, cannot continue") + return &compareStatefulsetResult{} + } + } + needsReplace = true + needsRollUpdate = true + reasons = append(reasons, "new statefulset's selector doesn't match the current one") + } + if !reflect.DeepEqual(c.Statefulset.Spec.Template.Annotations, statefulSet.Spec.Template.Annotations) { needsRollUpdate = true needsReplace = true diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 843578293..cf16bb39a 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -564,6 +564,7 @@ func (c *Cluster) generateStatefulSet(spec *spec.PostgresSpec) (*v1beta1.Statefu }, Spec: v1beta1.StatefulSetSpec{ Replicas: &numberOfInstances, + Selector: c.labelsSelector(), ServiceName: c.serviceName(Master), Template: *podTemplate, VolumeClaimTemplates: []v1.PersistentVolumeClaim{*volumeClaimTemplate}, diff --git a/pkg/cluster/util.go b/pkg/cluster/util.go index dd996ccd1..4a4f4e04a 100644 --- a/pkg/cluster/util.go +++ b/pkg/cluster/util.go @@ -355,6 +355,10 @@ func (c *Cluster) labelsSet(shouldAddExtraLabels bool) labels.Set { return labels.Set(lbls) } +func (c *Cluster) labelsSelector() *metav1.LabelSelector { + return &metav1.LabelSelector{c.labelsSet(false), nil} +} + func (c *Cluster) roleLabelsSet(role PostgresRole) labels.Set { lbls := c.labelsSet(false) lbls[c.OpConfig.PodRoleLabel] = string(role)