Avoid passing the role into the recreatePod.

Conceptually, the operator's task is just to change the pod. As it
has no influence over the role the pod will take (either the master
or a replica), it shouldn't wait for the specific role.

This fixes at least one issue, where the pod running in a single-pod
cluster has been waited for forever by the operator expecting it to
have a wrong role (since Patroni callback assiging it the original
replica role has been killed after a quick promote by the next
callback.)
This commit is contained in:
Oleksii Kliukin 2017-04-10 11:50:26 +02:00 committed by Murat Kabilov
parent 8e658174e8
commit 176c6e8b19
3 changed files with 11 additions and 9 deletions

View File

@ -112,7 +112,7 @@ func (c *Cluster) registerPodSubscriber(podName spec.PodName) chan spec.PodEvent
return ch return ch
} }
func (c *Cluster) recreatePod(pod v1.Pod, spiloRole string) error { func (c *Cluster) recreatePod(pod v1.Pod) error {
podName := spec.PodName{ podName := spec.PodName{
Namespace: pod.Namespace, Namespace: pod.Namespace,
Name: pod.Name, Name: pod.Name,
@ -133,7 +133,7 @@ func (c *Cluster) recreatePod(pod v1.Pod, spiloRole string) error {
if err := c.waitForPodDeletion(ch); err != nil { if err := c.waitForPodDeletion(ch); err != nil {
return err return err
} }
if err := c.waitForPodLabel(ch, spiloRole); err != nil { if err := c.waitForPodLabel(ch); err != nil {
return err return err
} }
c.logger.Infof("Pod '%s' is ready", podName) c.logger.Infof("Pod '%s' is ready", podName)
@ -184,7 +184,7 @@ func (c *Cluster) recreatePods() error {
continue continue
} }
err = c.recreatePod(pod, "replica") err = c.recreatePod(pod)
if err != nil { if err != nil {
return fmt.Errorf("Can't recreate replica Pod '%s': %s", util.NameFromMeta(pod.ObjectMeta), err) return fmt.Errorf("Can't recreate replica Pod '%s': %s", util.NameFromMeta(pod.ObjectMeta), err)
} }
@ -197,7 +197,7 @@ func (c *Cluster) recreatePods() error {
//TODO: specify master, leave new master empty //TODO: specify master, leave new master empty
c.logger.Infof("Recreating master Pod '%s'", util.NameFromMeta(masterPod.ObjectMeta)) c.logger.Infof("Recreating master Pod '%s'", util.NameFromMeta(masterPod.ObjectMeta))
if err := c.recreatePod(masterPod, "replica"); err != nil { if err := c.recreatePod(masterPod); err != nil {
return fmt.Errorf("Can't recreate master Pod '%s': %s", util.NameFromMeta(masterPod.ObjectMeta), err) return fmt.Errorf("Can't recreate master Pod '%s': %s", util.NameFromMeta(masterPod.ObjectMeta), err)
} }

View File

@ -152,7 +152,6 @@ func (c *Cluster) syncPods() error {
//First check if we have left overs from the previous rolling update //First check if we have left overs from the previous rolling update
for _, pod := range pods.Items { for _, pod := range pods.Items {
podRole := util.PodSpiloRole(&pod)
podName := spec.PodName{ podName := spec.PodName{
Namespace: pod.Namespace, Namespace: pod.Namespace,
Name: pod.Name, Name: pod.Name,
@ -161,7 +160,7 @@ func (c *Cluster) syncPods() error {
if match && pod.Status.Phase == v1.PodPending { if match && pod.Status.Phase == v1.PodPending {
c.logger.Infof("Waiting for left over Pod '%s'", podName) c.logger.Infof("Waiting for left over Pod '%s'", podName)
ch := c.registerPodSubscriber(podName) ch := c.registerPodSubscriber(podName)
c.waitForPodLabel(ch, podRole) c.waitForPodLabel(ch)
c.unregisterPodSubscriber(podName) c.unregisterPodSubscriber(podName)
} }
} }
@ -177,7 +176,7 @@ func (c *Cluster) syncPods() error {
if util.PodSpiloRole(&pod) == "master" { if util.PodSpiloRole(&pod) == "master" {
//TODO: do manual failover first //TODO: do manual failover first
} }
err = c.recreatePod(pod, "replica") // newly created pods are always "replica"s err = c.recreatePod(pod)
c.logger.Infof("Pod '%s' has been successfully recreated", util.NameFromMeta(pod.ObjectMeta)) c.logger.Infof("Pod '%s' has been successfully recreated", util.NameFromMeta(pod.ObjectMeta))
} }

View File

@ -146,12 +146,15 @@ func (c *Cluster) getTeamMembers() ([]string, error) {
return teamInfo.Members, nil return teamInfo.Members, nil
} }
func (c *Cluster) waitForPodLabel(podEvents chan spec.PodEvent, spiloRole string) error { func (c *Cluster) waitForPodLabel(podEvents chan spec.PodEvent) error {
for { for {
select { select {
case podEvent := <-podEvents: case podEvent := <-podEvents:
role := util.PodSpiloRole(podEvent.CurPod) role := util.PodSpiloRole(podEvent.CurPod)
if role == spiloRole { // TODO: newly-created Pods are always replicas => check against empty string only // We cannot assume any role of the newly created pod. Normally, for a multi-pod cluster
// we should observe the 'replica' value, but it could be that some pods are not allowed
// to promote, therefore, the new pod could be a master as well.
if role == "master" || role == "replica" {
return nil return nil
} }
case <-time.After(c.OpConfig.PodLabelWaitTimeout): case <-time.After(c.OpConfig.PodLabelWaitTimeout):