patch config only once
This commit is contained in:
		
							parent
							
								
									8d5df0c758
								
							
						
					
					
						commit
						f5067e302c
					
				| 
						 | 
					@ -263,7 +263,11 @@ func (c *Cluster) syncPodDisruptionBudget(isUpdate bool) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Cluster) syncStatefulSet() error {
 | 
					func (c *Cluster) syncStatefulSet() error {
 | 
				
			||||||
	var masterPod *v1.Pod
 | 
						var (
 | 
				
			||||||
 | 
							masterPod               *v1.Pod
 | 
				
			||||||
 | 
							postgresConfig          map[string]interface{}
 | 
				
			||||||
 | 
							instanceRestartRequired bool
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	podsToRecreate := make([]v1.Pod, 0)
 | 
						podsToRecreate := make([]v1.Pod, 0)
 | 
				
			||||||
	switchoverCandidates := make([]spec.NamespacedName, 0)
 | 
						switchoverCandidates := make([]spec.NamespacedName, 0)
 | 
				
			||||||
| 
						 | 
					@ -388,17 +392,42 @@ func (c *Cluster) syncStatefulSet() error {
 | 
				
			||||||
		c.logger.Warnf("could not get list of pods to apply special PostgreSQL parameters only to be set via Patroni API: %v", err)
 | 
							c.logger.Warnf("could not get list of pods to apply special PostgreSQL parameters only to be set via Patroni API: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// get Postgres config, compare with manifest and update via Patroni PATCH endpoint if it differs
 | 
				
			||||||
 | 
						// Patroni's config endpoint is just a "proxy" to DCS. It is enough to patch it only once and it doesn't matter which pod is used.
 | 
				
			||||||
	for i, pod := range pods {
 | 
						for i, pod := range pods {
 | 
				
			||||||
		role := PostgresRole(pod.Labels[c.OpConfig.PodRoleLabel])
 | 
							podName := util.NameFromMeta(pods[i].ObjectMeta)
 | 
				
			||||||
		if role == Master {
 | 
							config, err := c.patroni.GetConfig(&pod)
 | 
				
			||||||
			masterPod = &pods[i]
 | 
							if err != nil {
 | 
				
			||||||
 | 
								c.logger.Warningf("could not get Postgres config from pod %s: %v", podName, err)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		c.syncPostgreSQLConfiguration(&pod)
 | 
							instanceRestartRequired, err = c.checkAndSetGlobalPostgreSQLConfiguration(&pod, config)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								c.logger.Warningf("could not set PostgreSQL configuration options for pod %s: %v", podName, err)
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if masterPod != nil {
 | 
						// if the config update requires a restart, call Patroni restart for replicas first, then master
 | 
				
			||||||
		c.syncPostgreSQLConfiguration(masterPod)
 | 
						if instanceRestartRequired {
 | 
				
			||||||
 | 
							c.logger.Info("restarting Postgres server within pods")
 | 
				
			||||||
 | 
							ttl, ok := postgresConfig["ttl"].(int32)
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								ttl = 30
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for i, pod := range pods {
 | 
				
			||||||
 | 
								role := PostgresRole(pod.Labels[c.OpConfig.PodRoleLabel])
 | 
				
			||||||
 | 
								if role == Master {
 | 
				
			||||||
 | 
									masterPod = &pods[i]
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								c.restartInstance(&pod, ttl)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if masterPod != nil {
 | 
				
			||||||
 | 
								c.restartInstance(masterPod, ttl)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// if we get here we also need to re-create the pods (either leftovers from the old
 | 
						// if we get here we also need to re-create the pods (either leftovers from the old
 | 
				
			||||||
| 
						 | 
					@ -414,36 +443,20 @@ func (c *Cluster) syncStatefulSet() error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Cluster) syncPostgreSQLConfiguration(pod *v1.Pod) {
 | 
					func (c *Cluster) restartInstance(pod *v1.Pod, ttl int32) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	podName := util.NameFromMeta(pod.ObjectMeta)
 | 
						podName := util.NameFromMeta(pod.ObjectMeta)
 | 
				
			||||||
	role := PostgresRole(pod.Labels[c.OpConfig.PodRoleLabel])
 | 
						role := PostgresRole(pod.Labels[c.OpConfig.PodRoleLabel])
 | 
				
			||||||
	config, err := c.patroni.GetConfig(pod)
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						c.eventRecorder.Event(c.GetReference(), v1.EventTypeNormal, "Update", fmt.Sprintf("restarting Postgres server within %s pod %s", role, pod.Name))
 | 
				
			||||||
		c.logger.Warningf("could not get config for %s pod %s: %v", role, podName, err)
 | 
					
 | 
				
			||||||
 | 
						if err := c.patroni.Restart(pod); err != nil {
 | 
				
			||||||
 | 
							c.logger.Warningf("could not restart Postgres server within %s pod %s: %v", role, podName, err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	instanceRestartRequired, err := c.checkAndSetPostgreSQLConfiguration(pod, config)
 | 
						time.Sleep(time.Duration(ttl) * time.Second)
 | 
				
			||||||
	if err != nil {
 | 
						c.logger.Debugf("Postgres server successfuly restarted in %s pod %s", role, podName)
 | 
				
			||||||
		c.logger.Warningf("could not set PostgreSQL configuration options for %s pod %s: %v", role, podName, err)
 | 
						c.eventRecorder.Event(c.GetReference(), v1.EventTypeNormal, "Update", fmt.Sprintf("Postgres server restart done for pod %s pod %s", role, pod.Name))
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if instanceRestartRequired {
 | 
					 | 
				
			||||||
		c.logger.Debugf("restarting Postgres server within %s pod %s", role, podName)
 | 
					 | 
				
			||||||
		ttl, ok := config["ttl"].(int32)
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			ttl = 30
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		c.eventRecorder.Event(c.GetReference(), v1.EventTypeNormal, "Update", fmt.Sprintf("restarting Postgres server within %s pod %s", role, pod.Name))
 | 
					 | 
				
			||||||
		if err := c.patroni.Restart(pod); err != nil {
 | 
					 | 
				
			||||||
			c.logger.Warningf("could not restart Postgres server within %s pod %s: %v", role, podName, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		time.Sleep(time.Duration(ttl) * time.Second)
 | 
					 | 
				
			||||||
		c.logger.Infof("Postgres server successfuly restarted in %s pod %s", role, podName)
 | 
					 | 
				
			||||||
		c.eventRecorder.Event(c.GetReference(), v1.EventTypeNormal, "Update", fmt.Sprintf("Postgres server restart done for pod %s pod %s", role, pod.Name))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AnnotationsToPropagate get the annotations to update if required
 | 
					// AnnotationsToPropagate get the annotations to update if required
 | 
				
			||||||
| 
						 | 
					@ -478,15 +491,9 @@ func (c *Cluster) AnnotationsToPropagate(annotations map[string]string) map[stri
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// checkAndSetPostgreSQLConfiguration checks whether cluster-wide API parameters
 | 
					// checkAndSetGlobalPostgreSQLConfiguration checks whether cluster-wide API parameters
 | 
				
			||||||
// (like max_connections) have changed and if necessary sets it via the Patroni API
 | 
					// (like max_connections) have changed and if necessary sets it via the Patroni API
 | 
				
			||||||
func (c *Cluster) checkAndSetPostgreSQLConfiguration(pod *v1.Pod, patroniConfig map[string]interface{}) (bool, error) {
 | 
					func (c *Cluster) checkAndSetGlobalPostgreSQLConfiguration(pod *v1.Pod, patroniConfig map[string]interface{}) (bool, error) {
 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		err             error
 | 
					 | 
				
			||||||
		pods            []v1.Pod
 | 
					 | 
				
			||||||
		restartRequired bool
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	configToSet := make(map[string]interface{})
 | 
						configToSet := make(map[string]interface{})
 | 
				
			||||||
	parametersToSet := make(map[string]string)
 | 
						parametersToSet := make(map[string]string)
 | 
				
			||||||
	effectivePgParameters := make(map[string]interface{})
 | 
						effectivePgParameters := make(map[string]interface{})
 | 
				
			||||||
| 
						 | 
					@ -538,7 +545,7 @@ func (c *Cluster) checkAndSetPostgreSQLConfiguration(pod *v1.Pod, patroniConfig
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(configToSet) == 0 {
 | 
						if len(configToSet) == 0 {
 | 
				
			||||||
		return restartRequired, nil
 | 
							return false, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	configToSetJson, err := json.Marshal(configToSet)
 | 
						configToSetJson, err := json.Marshal(configToSet)
 | 
				
			||||||
| 
						 | 
					@ -551,14 +558,11 @@ func (c *Cluster) checkAndSetPostgreSQLConfiguration(pod *v1.Pod, patroniConfig
 | 
				
			||||||
	podName := util.NameFromMeta(pod.ObjectMeta)
 | 
						podName := util.NameFromMeta(pod.ObjectMeta)
 | 
				
			||||||
	c.logger.Debugf("calling Patroni API on a pod %s to set the following Postgres options: %s",
 | 
						c.logger.Debugf("calling Patroni API on a pod %s to set the following Postgres options: %s",
 | 
				
			||||||
		podName, configToSetJson)
 | 
							podName, configToSetJson)
 | 
				
			||||||
	if err = c.patroni.SetConfig(pod, configToSet); err == nil {
 | 
						if err = c.patroni.SetConfig(pod, configToSet); err != nil {
 | 
				
			||||||
		restartRequired = true
 | 
							return true, fmt.Errorf("could not patch postgres parameters with a pod %s: %v", podName, err)
 | 
				
			||||||
		return restartRequired, nil
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	c.logger.Warningf("could not patch postgres parameters with a pod %s: %v", podName, err)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return restartRequired, fmt.Errorf("could not reach Patroni API to set Postgres options: failed on every pod (%d total)",
 | 
						return true, nil
 | 
				
			||||||
		len(pods))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Cluster) syncSecrets() error {
 | 
					func (c *Cluster) syncSecrets() error {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue