func DeterminePodsSafeToUpdate()

in controllers/util/solr_update_util.go [108:152]


func DeterminePodsSafeToUpdate(ctx context.Context, cloud *solr.SolrCloud, totalPods int, outOfDatePods OutOfDatePodSegmentation, hasReadyPod bool, availableUpdatedPodCount int, logger logr.Logger) (podsToUpdate []corev1.Pod, podsHaveReplicas map[string]bool, retryLater bool, err error) {
	// Before fetching the cluster state, be sure that there is room to update at least 1 pod
	maxPodsUnavailable, unavailableUpdatedPodCount, maxPodsToUpdate := calculateMaxPodsToUpdate(cloud, totalPods, len(outOfDatePods.Running), len(outOfDatePods.NotStarted)+len(outOfDatePods.ScheduledForDeletion), availableUpdatedPodCount)
	if maxPodsToUpdate <= 0 {
		logger.Info("Pod update selection canceled. The number of updated pods unavailable equals or exceeds the calculated maxPodsUnavailable.",
			"unavailableUpdatedPods", unavailableUpdatedPodCount, "outOfDatePodsNotStarted", len(outOfDatePods.NotStarted), "alreadyScheduledForDeletion", len(outOfDatePods.ScheduledForDeletion), "maxPodsUnavailable", maxPodsUnavailable)
	} else {
		clusterResp := &solr_api.SolrClusterStatusResponse{}
		overseerResp := &solr_api.SolrOverseerStatusResponse{}

		if hasReadyPod {
			queryParams := url.Values{}
			queryParams.Add("action", "CLUSTERSTATUS")
			err = solr_api.CallCollectionsApi(ctx, cloud, queryParams, clusterResp)
			if err == nil {
				queryParams.Set("action", "OVERSEERSTATUS")
				err = solr_api.CallCollectionsApi(ctx, cloud, queryParams, overseerResp)
				if _, apiErr := solr_api.CheckForCollectionsApiError("OVERSEERSTATUS", overseerResp.ResponseHeader, overseerResp.Error); apiErr != nil {
					err = apiErr
				}
			}
			if err != nil {
				logger.Error(err, "Error retrieving cluster status, delaying pod update selection")
			}
		}
		// If the update logic already wants to retry later, then do not pick any pods
		if !retryLater {
			logger.Info("Pod update selection started.",
				"outOfDatePods", len(outOfDatePods.Running),
				"maxPodsUnavailable", maxPodsUnavailable,
				"unavailableUpdatedPods", unavailableUpdatedPodCount,
				"outOfDatePodsNotStarted", len(outOfDatePods.NotStarted),
				"alreadyScheduledForDeletion", len(outOfDatePods.ScheduledForDeletion),
				"maxPodsToUpdate", maxPodsToUpdate)
			podsToUpdate, podsHaveReplicas = pickPodsToUpdate(cloud, outOfDatePods, clusterResp.ClusterStatus, overseerResp.Leader, maxPodsToUpdate, logger)

			// If there are no pods to upgrade, even though the maxPodsToUpdate is >0, then retry later because the issue stems from cluster state
			// and clusterState changes will not call the reconciler.
			if len(podsToUpdate) == 0 && len(outOfDatePods.Running) > 0 {
				retryLater = true
			}
		}
	}
	return podsToUpdate, podsHaveReplicas, retryLater, err
}