Skip to content

Commit a557bf2

Browse files
committed
Update watchPods() behavior for Patroni role change
Add an additional check to the existing watchPods function to queue an event when an instance Pod is first given the 'master' role. Issue: PGO-190
1 parent b5a09a1 commit a557bf2

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

internal/controller/postgrescluster/watches.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ func (*Reconciler) watchPods() handler.Funcs {
5757
}})
5858
return
5959
}
60+
61+
// Queue an event to start applying changes if the PostgreSQL instance
62+
// now has the "master" role.
63+
if len(cluster) != 0 &&
64+
!patroni.PodIsPrimary(e.ObjectOld) &&
65+
patroni.PodIsPrimary(e.ObjectNew) {
66+
q.Add(reconcile.Request{NamespacedName: client.ObjectKey{
67+
Namespace: e.ObjectNew.GetNamespace(),
68+
Name: cluster,
69+
}})
70+
return
71+
}
6072
},
6173
}
6274
}

internal/patroni/reconcile.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,24 @@ func instanceProbes(cluster *v1beta1.PostgresCluster, container *corev1.Containe
181181
}
182182
}
183183

184+
// PodIsPrimary returns whether or not pod is currently acting as the leader with
185+
// the "master" role. This role will be called "primary" in the future, see:
186+
// - https://github.com/zalando/patroni/blob/master/docs/releases.rst?plain=1#L213
187+
func PodIsPrimary(pod metav1.Object) bool {
188+
if pod == nil {
189+
return false
190+
}
191+
192+
// TODO(cbandy): This works only when using Kubernetes for DCS.
193+
194+
// - https://github.com/zalando/patroni/blob/v3.1.1/patroni/ha.py#L296
195+
// - https://github.com/zalando/patroni/blob/v3.1.1/patroni/ha.py#L583
196+
// - https://github.com/zalando/patroni/blob/v3.1.1/patroni/ha.py#L782
197+
// - https://github.com/zalando/patroni/blob/v3.1.1/patroni/ha.py#L1574
198+
status := pod.GetAnnotations()["status"]
199+
return strings.Contains(status, `"role":"master"`)
200+
}
201+
184202
// PodIsStandbyLeader returns whether or not pod is currently acting as a "standby_leader".
185203
func PodIsStandbyLeader(pod metav1.Object) bool {
186204
if pod == nil {

internal/patroni/reconcile_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,31 @@ volumes:
231231
`))
232232
}
233233

234+
func TestPodIsPrimary(t *testing.T) {
235+
// No object
236+
assert.Assert(t, !PodIsPrimary(nil))
237+
238+
// No annotations
239+
pod := &corev1.Pod{}
240+
assert.Assert(t, !PodIsPrimary(pod))
241+
242+
// No role
243+
pod.Annotations = map[string]string{"status": `{}`}
244+
assert.Assert(t, !PodIsPrimary(pod))
245+
246+
// Replica
247+
pod.Annotations["status"] = `{"role":"replica"}`
248+
assert.Assert(t, !PodIsPrimary(pod))
249+
250+
// Standby leader
251+
pod.Annotations["status"] = `{"role":"standby_leader"}`
252+
assert.Assert(t, !PodIsPrimary(pod))
253+
254+
// Primary
255+
pod.Annotations["status"] = `{"role":"master"}`
256+
assert.Assert(t, PodIsPrimary(pod))
257+
}
258+
234259
func TestPodIsStandbyLeader(t *testing.T) {
235260
// No object
236261
assert.Assert(t, !PodIsStandbyLeader(nil))

0 commit comments

Comments
 (0)