in pkg/controller/elasticsearch/driver/suspend.go [33:86]
func reconcileSuspendedPods(ctx context.Context, c k8s.Client, es esv1.Elasticsearch, e *expectations.Expectations) error {
// let's make sure we observe any deletions in the cache to avoid redundant deletion
pendingPodDeletions, err := e.PendingPodDeletions()
if err != nil {
return err
}
deletionsSatisfied := len(pendingPodDeletions) == 0
// suspendedPodNames as indicated by the user on the Elasticsearch resource via an annotation
// the corresponding configMap has already been reconciled prior to that function
suspendedPodNames := es.SuspendedPodNames()
// all known Pods, this is mostly to fine tune the reconciliation to the current state of the Pods, see below
statefulSets, err := sset.RetrieveActualStatefulSets(c, k8s.ExtractNamespacedName(&es))
if err != nil {
return err
}
knownPods, err := statefulSets.GetActualPods(c)
if err != nil {
return err
}
for i, pod := range knownPods {
pod := pod
// Pod should be suspended
if suspendedPodNames.Has(pod.Name) {
for _, s := range pod.Status.ContainerStatuses {
// delete the Pod without grace period if the main Elasticsearch container is running
// and we have seen all expected deletions in the cache
if deletionsSatisfied && s.Name == esv1.ElasticsearchContainerName && s.State.Running != nil {
ulog.FromContext(ctx).Info("Deleting suspended pod", "pod_name", pod.Name, "pod_uid", pod.UID,
"namespace", es.Namespace, "es_name", es.Name)
// the precondition serves as an additional barrier in addition to the expectation mechanism to
// not accidentally deleting Pods we do not intent to delete (because our view of the world is out of sync)
preconditions := client.Preconditions{
UID: &pod.UID,
ResourceVersion: &pod.ResourceVersion,
}
if err := c.Delete(ctx, &knownPods[i], preconditions, client.GracePeriodSeconds(0)); err != nil {
return err
}
// record the expected deletion
e.ExpectDeletion(pod)
}
}
} else if isSuspended(pod) {
// Pod is suspended. But it should not be. Try to speed up propagation of config map entries so that it can
// start up again. Without this it can take minutes until the config map file in the Pod's filesystem is
// updated with the current state.
annotation.MarkPodAsUpdated(ctx, c, pod)
}
}
return nil
}