replaceStatefulSet deletes an old StatefulSet and creates the new using spec in the PostgreSQL CRD.
(newStatefulSet *appsv1.StatefulSet)
| 212 | |
| 213 | // replaceStatefulSet deletes an old StatefulSet and creates the new using spec in the PostgreSQL CRD. |
| 214 | func (c *Cluster) replaceStatefulSet(newStatefulSet *appsv1.StatefulSet) error { |
| 215 | c.setProcessName("replacing statefulset") |
| 216 | if c.Statefulset == nil { |
| 217 | return fmt.Errorf("there is no statefulset in the cluster") |
| 218 | } |
| 219 | |
| 220 | statefulSetName := util.NameFromMeta(c.Statefulset.ObjectMeta) |
| 221 | c.logger.Debug("replacing statefulset") |
| 222 | |
| 223 | // Delete the current statefulset without deleting the pods |
| 224 | deletePropagationPolicy := metav1.DeletePropagationOrphan |
| 225 | oldStatefulset := c.Statefulset |
| 226 | |
| 227 | options := metav1.DeleteOptions{PropagationPolicy: &deletePropagationPolicy} |
| 228 | err := c.KubeClient.StatefulSets(oldStatefulset.Namespace).Delete(context.TODO(), oldStatefulset.Name, options) |
| 229 | if err != nil { |
| 230 | return fmt.Errorf("could not delete statefulset %q: %v", statefulSetName, err) |
| 231 | } |
| 232 | // make sure we clear the stored statefulset status if the subsequent create fails. |
| 233 | c.Statefulset = nil |
| 234 | // wait until the statefulset is truly deleted |
| 235 | c.logger.Debug("waiting for the statefulset to be deleted") |
| 236 | |
| 237 | err = retryutil.Retry(c.OpConfig.ResourceCheckInterval, c.OpConfig.ResourceCheckTimeout, |
| 238 | func() (bool, error) { |
| 239 | _, err2 := c.KubeClient.StatefulSets(oldStatefulset.Namespace).Get(context.TODO(), oldStatefulset.Name, metav1.GetOptions{}) |
| 240 | if err2 == nil { |
| 241 | return false, nil |
| 242 | } |
| 243 | if k8sutil.ResourceNotFound(err2) { |
| 244 | return true, nil |
| 245 | } |
| 246 | return false, err2 |
| 247 | }) |
| 248 | if err != nil { |
| 249 | return fmt.Errorf("could not delete statefulset: %v", err) |
| 250 | } |
| 251 | |
| 252 | // create the new statefulset with the desired spec. It would take over the remaining pods. |
| 253 | createdStatefulset, err := c.KubeClient.StatefulSets(newStatefulSet.Namespace).Create(context.TODO(), newStatefulSet, metav1.CreateOptions{}) |
| 254 | if err != nil { |
| 255 | return fmt.Errorf("could not create statefulset %q: %v", statefulSetName, err) |
| 256 | } |
| 257 | // check that all the previous replicas were picked up. |
| 258 | if newStatefulSet.Spec.Replicas == oldStatefulset.Spec.Replicas && |
| 259 | createdStatefulset.Status.Replicas != oldStatefulset.Status.Replicas { |
| 260 | c.logger.Warningf("number of pods for the old and updated Statefulsets is not identical") |
| 261 | } |
| 262 | |
| 263 | c.Statefulset = createdStatefulset |
| 264 | return nil |
| 265 | } |
| 266 | |
| 267 | func (c *Cluster) deleteStatefulSet() error { |
| 268 | c.setProcessName("deleting statefulset") |
no test coverage detected