Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion opensearch-operator/pkg/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,11 @@ func ReplicaHostName(currentSts appsv1.StatefulSet, repNum int32) string {
}

func WorkingPodForRollingRestart(k8sClient k8s.K8sClient, sts *appsv1.StatefulSet) (string, error) {
// If revisions match (no spec change), indicate no work without requeue-triggering error
if sts.Status.UpdateRevision != "" && sts.Status.CurrentRevision == sts.Status.UpdateRevision {
return "", nil
}

// If there are potentially mixed revisions we need to check each pod
podWithOlderRevision, err := GetPodWithOlderRevision(k8sClient, sts)
if err != nil {
Expand All @@ -490,7 +495,9 @@ func WorkingPodForRollingRestart(k8sClient k8s.K8sClient, sts *appsv1.StatefulSe
if podWithOlderRevision != nil {
return podWithOlderRevision.Name, nil
}
return "", errors.New("unable to calculate the working pod for rolling restart")

// No pod requires restart at the moment; return empty name with nil error
return "", nil
}

// DeleteStuckPodWithOlderRevision deletes the crashed pod only if there is any update in StatefulSet.
Expand Down
21 changes: 21 additions & 0 deletions opensearch-operator/pkg/reconcilers/rollingRestart.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ func (r *RollingRestartReconciler) Reconcile() (ctrl.Result, error) {
if err != nil {
return ctrl.Result{}, err
}

// Skip rolling restart if revisions are the same (no actual spec changes)
// This prevents unnecessary rolling restarts during node draining/pod recreation
if sts.Status.UpdateRevision != "" && sts.Status.CurrentRevision == sts.Status.UpdateRevision {
// All pods are up to date, no rolling restart needed
lg.V(1).Info(fmt.Sprintf("StatefulSet %s has matching current and update revisions, skipping rolling restart", sts.Name))
continue
}

if sts.Status.UpdateRevision != "" &&
sts.Status.UpdatedReplicas != ptr.Deref(sts.Spec.Replicas, int32(1)) {
pendingUpdate = true
Expand Down Expand Up @@ -147,6 +156,14 @@ func (r *RollingRestartReconciler) Reconcile() (ctrl.Result, error) {
if err != nil {
return ctrl.Result{}, err
}

// Skip rolling restart if revisions are the same (no actual spec changes)
// This prevents unnecessary rolling restarts during node draining/pod recreation
if sts.Status.UpdateRevision != "" && sts.Status.CurrentRevision == sts.Status.UpdateRevision {
lg.V(1).Info(fmt.Sprintf("StatefulSet %s has matching current and update revisions, skipping rolling restart", sts.Name))
continue
}

if sts.Status.UpdateRevision != "" &&
sts.Status.UpdatedReplicas != ptr.Deref(sts.Spec.Replicas, 1) {
// Only restart pods if not all pods are updated and the sts is healthy with no pods terminating
Expand Down Expand Up @@ -190,6 +207,10 @@ func (r *RollingRestartReconciler) restartStatefulSetPod(sts *appsv1.StatefulSet
if err != nil {
return ctrl.Result{}, err
}
if workingPod == "" {
// Nothing to restart right now; do not requeue due to this condition
return ctrl.Result{}, nil
}

lg.Info(fmt.Sprintf("Preparing to restart pod %s", workingPod))
ready, err = services.PreparePodForDelete(r.osClient, lg, workingPod, r.instance.Spec.General.DrainDataNodes, dataCount)
Expand Down
5 changes: 5 additions & 0 deletions opensearch-operator/pkg/reconcilers/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,11 @@ func (r *UpgradeReconciler) doNodePoolUpgrade(pool opsterv1.NodePool) error {
r.setComponentConditions(conditions, pool.Component)
return err
}
if workingPod == "" {
// No pod to restart right now; this is a non-error state
r.setComponentConditions(conditions, pool.Component)
return nil
}

ready, err = services.PreparePodForDelete(r.osClient, r.logger, workingPod, r.instance.Spec.General.DrainDataNodes, dataCount)
if err != nil {
Expand Down