Skip to content

Commit cbfe201

Browse files
Polina BunginaSchmaetz
authored andcommitted
take over several changes
1 parent 04087eb commit cbfe201

File tree

3 files changed

+104
-12
lines changed

3 files changed

+104
-12
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ require (
3333
)
3434

3535
require (
36+
github.com/Masterminds/semver v1.5.0 // indirect
3637
github.com/davecgh/go-spew v1.1.1 // indirect
3738
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
3839
github.com/evanphx/json-patch v4.12.0+incompatible // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
22
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
33
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
4+
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
5+
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
46
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
57
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
68
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=

pkg/cluster/majorversionupgrade.go

Lines changed: 101 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"strings"
88

9+
"github.com/Masterminds/semver"
910
"github.com/cybertec-postgresql/cybertec-pg-operator/pkg/spec"
1011
"github.com/cybertec-postgresql/cybertec-pg-operator/pkg/util"
1112
v1 "k8s.io/api/core/v1"
@@ -44,7 +45,7 @@ func (c *Cluster) GetDesiredMajorVersionAsInt() int {
4445
func (c *Cluster) GetDesiredMajorVersion() string {
4546

4647
if c.Config.OpConfig.MajorVersionUpgradeMode == "full" {
47-
// e.g. current is 10, minimal is 11 allowing 11 to 15 clusters, everything below is upgraded
48+
// e.g. current is 13, minimal is 13 allowing 13 to 17 clusters, everything below is upgraded
4849
if IsBiggerPostgresVersion(c.Spec.PgVersion, c.Config.OpConfig.MinimalMajorVersion) {
4950
c.logger.Infof("overwriting configured major version %s to %s", c.Spec.PgVersion, c.Config.OpConfig.TargetMajorVersion)
5051
return c.Config.OpConfig.TargetMajorVersion
@@ -136,22 +137,33 @@ func (c *Cluster) majorVersionUpgrade() error {
136137
desiredVersion := c.GetDesiredMajorVersionAsInt()
137138

138139
if c.currentMajorVersion >= desiredVersion {
140+
if _, exists := c.ObjectMeta.Annotations[majorVersionUpgradeFailureAnnotation]; exists { // if failure annotation exists, remove it
141+
c.removeFailuresAnnotation()
142+
c.logger.Infof("removing failure annotation as the cluster is already up to date")
143+
}
139144
c.logger.Infof("cluster version up to date. current: %d, min desired: %d", c.currentMajorVersion, desiredVersion)
140145
return nil
141146
}
142147

143-
pods, err := c.listPodsOfType(TYPE_POSTGRESQL)
148+
pods, err := c.listPods()
144149
if err != nil {
145150
return err
146151
}
147152

148153
allRunning := true
154+
isStandbyCluster := false
149155

150156
var masterPod *v1.Pod
151157

152158
for i, pod := range pods {
153159
ps, _ := c.patroni.GetMemberData(&pod)
154160

161+
if ps.Role == "standby_leader" {
162+
isStandbyCluster = true
163+
c.currentMajorVersion = ps.ServerVersion
164+
break
165+
}
166+
155167
if ps.State != "running" {
156168
allRunning = false
157169
c.logger.Infof("identified non running pod, potentially skipping major version upgrade")
@@ -163,37 +175,114 @@ func (c *Cluster) majorVersionUpgrade() error {
163175
}
164176
}
165177

178+
if masterPod == nil {
179+
c.logger.Infof("no master in the cluster, skipping major version upgrade")
180+
return nil
181+
}
182+
183+
// Recheck version with newest data from Patroni
184+
if c.currentMajorVersion >= desiredVersion {
185+
if _, exists := c.ObjectMeta.Annotations[majorVersionUpgradeFailureAnnotation]; exists { // if failure annotation exists, remove it
186+
c.removeFailuresAnnotation()
187+
c.logger.Infof("removing failure annotation as the cluster is already up to date")
188+
}
189+
c.logger.Infof("recheck cluster version is already up to date. current: %d, min desired: %d", c.currentMajorVersion, desiredVersion)
190+
return nil
191+
} else if isStandbyCluster {
192+
c.logger.Warnf("skipping major version upgrade for %s/%s standby cluster. Re-deploy standby cluster with the required Postgres version specified", c.Namespace, c.Name)
193+
return nil
194+
}
195+
196+
if _, exists := c.ObjectMeta.Annotations[majorVersionUpgradeFailureAnnotation]; exists {
197+
c.logger.Infof("last major upgrade failed, skipping upgrade")
198+
return nil
199+
}
200+
201+
if !isInMaintenanceWindow(c.Spec.MaintenanceWindows) {
202+
c.logger.Infof("skipping major version upgrade, not in maintenance window")
203+
return nil
204+
}
205+
206+
members, err := c.patroni.GetClusterMembers(masterPod)
207+
if err != nil {
208+
c.logger.Error("could not get cluster members data from Patroni API, skipping major version upgrade")
209+
return err
210+
}
211+
patroniData, err := c.patroni.GetMemberData(masterPod)
212+
if err != nil {
213+
c.logger.Error("could not get members data from Patroni API, skipping major version upgrade")
214+
return err
215+
}
216+
patroniVer, err := semver.NewVersion(patroniData.Patroni.Version)
217+
if err != nil {
218+
c.logger.Error("error parsing Patroni version")
219+
patroniVer, _ = semver.NewVersion("3.0.4")
220+
}
221+
verConstraint, _ := semver.NewConstraint(">= 3.0.4")
222+
checkStreaming, _ := verConstraint.Validate(patroniVer)
223+
224+
for _, member := range members {
225+
if PostgresRole(member.Role) == Leader {
226+
continue
227+
}
228+
if checkStreaming && member.State != "streaming" {
229+
c.logger.Infof("skipping major version upgrade, replica %s is not streaming from primary", member.Name)
230+
return nil
231+
}
232+
if member.Lag > 16*1024*1024 {
233+
c.logger.Infof("skipping major version upgrade, replication lag on member %s is too high", member.Name)
234+
return nil
235+
}
236+
}
237+
238+
isUpgradeSuccess := true
166239
numberOfPods := len(pods)
167240
if allRunning && masterPod != nil {
168241
c.logger.Infof("healthy cluster ready to upgrade, current: %d desired: %d", c.currentMajorVersion, desiredVersion)
169242
if c.currentMajorVersion < desiredVersion {
243+
defer func() error {
244+
if err = c.criticalOperationLabel(pods, nil); err != nil {
245+
return fmt.Errorf("failed to remove critical-operation label: %s", err)
246+
}
247+
return nil
248+
}()
249+
val := "true"
250+
if err = c.criticalOperationLabel(pods, &val); err != nil {
251+
return fmt.Errorf("failed to assign critical-operation label: %s", err)
252+
}
253+
170254
podName := &spec.NamespacedName{Namespace: masterPod.Namespace, Name: masterPod.Name}
171255
c.logger.Infof("triggering major version upgrade on pod %s of %d pods", masterPod.Name, numberOfPods)
172-
c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeNormal, "Major Version Upgrade", "Starting major version upgrade on pod %s of %d pods", masterPod.Name, numberOfPods)
256+
c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeNormal, "Major Version Upgrade", "starting major version upgrade on pod %s of %d pods", masterPod.Name, numberOfPods)
173257
upgradeCommand := fmt.Sprintf("set -o pipefail && /usr/bin/python3 /scripts/inplace_upgrade.py %d 2>&1 | tee last_upgrade.log", numberOfPods)
174258

175-
c.logger.Debugf("checking if the spilo image runs with root or non-root (check for user id=0)")
259+
c.logger.Debug("checking if the spilo image runs with root or non-root (check for user id=0)")
176260
resultIdCheck, errIdCheck := c.ExecCommand(podName, "/bin/bash", "-c", "/usr/bin/id -u")
177261
if errIdCheck != nil {
178-
c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeWarning, "Major Version Upgrade", "Checking user id to run upgrade from %d to %d FAILED: %v", c.currentMajorVersion, desiredVersion, errIdCheck)
262+
c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeWarning, "Major Version Upgrade", "checking user id to run upgrade from %d to %d FAILED: %v", c.currentMajorVersion, desiredVersion, errIdCheck)
179263
}
180264

181265
resultIdCheck = strings.TrimSuffix(resultIdCheck, "\n")
182-
var result string
266+
var result, scriptErrMsg string
183267
if resultIdCheck != "0" {
184-
c.logger.Infof("User id was identified as: %s, hence default user is non-root already", resultIdCheck)
268+
c.logger.Infof("user id was identified as: %s, hence default user is non-root already", resultIdCheck)
185269
result, err = c.ExecCommand(podName, "/bin/bash", "-c", upgradeCommand)
270+
scriptErrMsg, _ = c.ExecCommand(podName, "/bin/bash", "-c", "tail -n 1 last_upgrade.log")
186271
} else {
187-
c.logger.Infof("User id was identified as: %s, using su to reach the postgres user", resultIdCheck)
272+
c.logger.Infof("user id was identified as: %s, using su to reach the postgres user", resultIdCheck)
188273
result, err = c.ExecCommand(podName, "/bin/su", "postgres", "-c", upgradeCommand)
274+
scriptErrMsg, _ = c.ExecCommand(podName, "/bin/bash", "-c", "tail -n 1 last_upgrade.log")
189275
}
190276
if err != nil {
191-
c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeWarning, "Major Version Upgrade", "Upgrade from %d to %d FAILED: %v", c.currentMajorVersion, desiredVersion, err)
192-
return err
277+
isUpgradeSuccess = false
278+
c.annotatePostgresResource(isUpgradeSuccess)
279+
c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeWarning, "Major Version Upgrade", "upgrade from %d to %d FAILED: %v", c.currentMajorVersion, desiredVersion, scriptErrMsg)
280+
return fmt.Errorf("%s", scriptErrMsg)
193281
}
194-
c.logger.Infof("upgrade action triggered and command completed: %s", result[:100])
195282

196-
c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeNormal, "Major Version Upgrade", "Upgrade from %d to %d finished", c.currentMajorVersion, desiredVersion)
283+
c.annotatePostgresResource(isUpgradeSuccess)
284+
c.logger.Infof("upgrade action triggered and command completed: %s", result[:100])
285+
c.eventRecorder.Eventf(c.GetReference(), v1.EventTypeNormal, "Major Version Upgrade", "upgrade from %d to %d finished", c.currentMajorVersion, desiredVersion)
197286
}
198287
}
199288

0 commit comments

Comments
 (0)