104 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
| package cluster
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 
 | |
| 	"github.com/zalando/postgres-operator/pkg/spec"
 | |
| 	v1 "k8s.io/api/core/v1"
 | |
| )
 | |
| 
 | |
| // VersionMap Map of version numbers
 | |
| var VersionMap = map[string]int{
 | |
| 	"9.5": 90500,
 | |
| 	"9.6": 90600,
 | |
| 	"10":  100000,
 | |
| 	"11":  110000,
 | |
| 	"12":  120000,
 | |
| 	"13":  130000,
 | |
| }
 | |
| 
 | |
| // IsBiggerPostgresVersion Compare two Postgres version numbers
 | |
| func IsBiggerPostgresVersion(old string, new string) bool {
 | |
| 	oldN, _ := VersionMap[old]
 | |
| 	newN, _ := VersionMap[new]
 | |
| 	return newN > oldN
 | |
| }
 | |
| 
 | |
| // GetDesiredMajorVersionAsInt Convert string to comparable integer of PG version
 | |
| func (c *Cluster) GetDesiredMajorVersionAsInt() int {
 | |
| 	return VersionMap[c.GetDesiredMajorVersion()]
 | |
| }
 | |
| 
 | |
| // GetDesiredMajorVersion returns major version to use, incl. potential auto upgrade
 | |
| func (c *Cluster) GetDesiredMajorVersion() string {
 | |
| 
 | |
| 	if c.Config.OpConfig.MajorVersionUpgradeMode == "full" {
 | |
| 		// current is 9.5, minimal is 11 allowing 11 to 13 clusters, everything below is upgraded
 | |
| 		if IsBiggerPostgresVersion(c.Spec.PgVersion, c.Config.OpConfig.MinimalMajorVersion) {
 | |
| 			c.logger.Infof("overwriting configured major version %s to %s", c.Spec.PgVersion, c.Config.OpConfig.TargetMajorVersion)
 | |
| 			return c.Config.OpConfig.TargetMajorVersion
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return c.Spec.PgVersion
 | |
| }
 | |
| 
 | |
| func (c *Cluster) majorVersionUpgrade() error {
 | |
| 
 | |
| 	if c.OpConfig.MajorVersionUpgradeMode == "off" {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	desiredVersion := c.GetDesiredMajorVersionAsInt()
 | |
| 
 | |
| 	if c.currentMajorVersion >= desiredVersion {
 | |
| 		c.logger.Infof("cluster version up to date. current: %d, min desired: %d", c.currentMajorVersion, desiredVersion)
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	pods, err := c.listPods()
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	allRunning := true
 | |
| 
 | |
| 	var masterPod *v1.Pod
 | |
| 
 | |
| 	for _, pod := range pods {
 | |
| 		ps, _ := c.patroni.GetMemberData(&pod)
 | |
| 
 | |
| 		if ps.State != "running" {
 | |
| 			allRunning = false
 | |
| 			c.logger.Infof("identified non running pod, potentially skipping major version upgrade")
 | |
| 		}
 | |
| 
 | |
| 		if ps.Role == "master" {
 | |
| 			masterPod = &pod
 | |
| 			c.currentMajorVersion = ps.ServerVersion
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	numberOfPods := len(pods)
 | |
| 	if allRunning && masterPod != nil {
 | |
| 		c.logger.Infof("healthy cluster ready to upgrade, current: %d desired: %d", c.currentMajorVersion, desiredVersion)
 | |
| 		if c.currentMajorVersion < desiredVersion {
 | |
| 			podName := &spec.NamespacedName{Namespace: masterPod.Namespace, Name: masterPod.Name}
 | |
| 			c.logger.Infof("triggering major version upgrade on pod %s of %d pods", masterPod.Name, numberOfPods)
 | |
| 			c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeNormal, "Major Version Upgrade", "Starting major version upgrade on pod %s of %d pods", masterPod.Name, numberOfPods)
 | |
| 			upgradeCommand := fmt.Sprintf("/usr/bin/python3 /scripts/inplace_upgrade.py %d 2>&1 | tee last_upgrade.log", numberOfPods)
 | |
| 
 | |
| 			result, err := c.ExecCommand(podName, "/bin/su", "postgres", "-c", upgradeCommand)
 | |
| 			if err != nil {
 | |
| 				c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeNormal, "Major Version Upgrade", "Upgrade from %d to %d FAILED: %v", c.currentMajorVersion, desiredVersion, err)
 | |
| 				return err
 | |
| 			}
 | |
| 
 | |
| 			c.logger.Infof("upgrade action triggered and command completed: %s", result[:50])
 | |
| 			c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeNormal, "Major Version Upgrade", "Upgrade from %d to %d finished", c.currentMajorVersion, desiredVersion)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 |