@@ -5,10 +5,12 @@ import (
55 "encoding/json"
66 "fmt"
77 "strings"
8+ "time"
89
910 "github.com/Masterminds/semver"
1011 "github.com/zalando/postgres-operator/pkg/spec"
1112 "github.com/zalando/postgres-operator/pkg/util"
13+ "github.com/zalando/postgres-operator/pkg/util/retryutil"
1214 v1 "k8s.io/api/core/v1"
1315 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1416 "k8s.io/apimachinery/pkg/types"
@@ -106,6 +108,74 @@ func (c *Cluster) removeFailuresAnnotation() error {
106108 return nil
107109}
108110
111+ func (c * Cluster ) labelCriticalOperation (pods []v1.Pod ) error {
112+ for _ , pod := range pods {
113+ var meta metav1.ObjectMeta
114+ meta .Labels = map [string ]string {"critical-operaton" : "true" }
115+ patchData , err := json .Marshal (struct {
116+ ObjMeta interface {} `json:"metadata"`
117+ }{& meta })
118+ if err != nil {
119+ return fmt .Errorf ("could not form patch for critical operation label: %v" , err )
120+ }
121+
122+ err = retryutil .Retry (1 * time .Second , 5 * time .Second ,
123+ func () (bool , error ) {
124+ _ , err2 := c .KubeClient .Pods (pod .Namespace ).Patch (
125+ context .TODO (),
126+ pod .Name ,
127+ types .MergePatchType ,
128+ []byte (patchData ),
129+ metav1.PatchOptions {},
130+ "" )
131+ if err2 != nil {
132+ return false , err2
133+ }
134+ return true , nil
135+ })
136+ if err != nil {
137+ return fmt .Errorf ("could not patch pod critical operation label: %v" , err )
138+ }
139+ }
140+ c .logger .Info ("pods are patched with critical operation label" )
141+ return nil
142+ }
143+
144+ func (c * Cluster ) removeCriticalOperationLabel (pods []v1.Pod ) error {
145+ for _ , pod := range pods {
146+ annotationToRemove := []map [string ]string {
147+ {
148+ "op" : "remove" ,
149+ "path" : fmt .Sprintf ("/metadata/labels/%s" , "critical-operaton" ),
150+ },
151+ }
152+ removePatch , err := json .Marshal (annotationToRemove )
153+ if err != nil {
154+ c .logger .Errorf ("could not form patch for critical operation label: %v" , err )
155+ return err
156+ }
157+ err = retryutil .Retry (1 * time .Second , 5 * time .Second ,
158+ func () (bool , error ) {
159+ _ , err2 := c .KubeClient .Pods (pod .Namespace ).Patch (
160+ context .TODO (),
161+ pod .Name ,
162+ types .JSONPatchType ,
163+ []byte (removePatch ),
164+ metav1.PatchOptions {},
165+ "" )
166+ if err2 != nil {
167+ return false , err2
168+ }
169+ return true , nil
170+ })
171+ if err != nil {
172+ return fmt .Errorf ("failed to remove pod critical operation label: %v" , err )
173+ }
174+ }
175+ c .logger .Info ("critical operation label is removed from all pods" )
176+ return nil
177+ }
178+
109179/*
110180Execute upgrade when mode is set to manual or full or when the owning team is allowed for upgrade (and mode is "off").
111181
@@ -219,6 +289,16 @@ func (c *Cluster) majorVersionUpgrade() error {
219289 if allRunning && masterPod != nil {
220290 c .logger .Infof ("healthy cluster ready to upgrade, current: %d desired: %d" , c .currentMajorVersion , desiredVersion )
221291 if c .currentMajorVersion < desiredVersion {
292+ defer func () error {
293+ if err = c .removeCriticalOperationLabel (pods ); err != nil {
294+ return fmt .Errorf ("failed to remove critical-operation label: %s" , err )
295+ }
296+ return nil
297+ }()
298+ if err = c .labelCriticalOperation (pods ); err != nil {
299+ return fmt .Errorf ("failed to assign critical-operation label: %s" , err )
300+ }
301+
222302 podName := & spec.NamespacedName {Namespace : masterPod .Namespace , Name : masterPod .Name }
223303 c .logger .Infof ("triggering major version upgrade on pod %s of %d pods" , masterPod .Name , numberOfPods )
224304 c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeNormal , "Major Version Upgrade" , "starting major version upgrade on pod %s of %d pods" , masterPod .Name , numberOfPods )
0 commit comments