All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.fabric8.kubernetes.client.utils.PodStatusUtil Maven / Gradle / Ivy

/**
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.fabric8.kubernetes.client.utils;

import io.fabric8.kubernetes.api.model.ContainerState;
import io.fabric8.kubernetes.api.model.ContainerStatus;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodStatus;
import io.fabric8.kubernetes.client.internal.readiness.Readiness;

import java.util.Collections;
import java.util.List;

public class PodStatusUtil {

    private static final String POD_RUNNING = "Running";
    private static final String POD_INITIALIZING = "PodInitializing";
    private static final String CONTAINER_COMPLETED = "Completed";

    private PodStatusUtil() {}

    /**
     * Returns {@code true} if the given pod is running. Returns {@code false} otherwise.
     *
     * The definition when a pod is considered running can be found at
     * k8s.io/api/core/v1/types.go#L3564
     * It states:
     * "PodRunning means the pod has been bound to a node and all of the containers have been started.
     * At least one container is still running or is in the process of being restarted."
     *
     * The logic is taken from (kubernetes/printers.go) printPod()
     * and (openshift-web-console/resources.js) podStatus()
     *
     * @param pod the pod to return the running status for
     * @return returns true if the pod is running
     */
    public static boolean isRunning(Pod pod) {
        if (isInStatus(POD_RUNNING, pod)) {
            return true;
        }
        if (hasDeletionTimestamp(pod)
                || isInitializing(pod)) {
            return false;
        }
        if (hasRunningContainer(pod)) {
            return !hasCompletedContainer(pod)
                    || Readiness.isPodReady(pod);
        }
        return false;
    }

    private static boolean isInStatus(String expected, Pod pod) {
        if (pod == null
                || pod.getStatus() == null
                || expected == null) {
            return false;
        }

        return expected.equals(pod.getStatus().getPhase())
                || expected.equals(pod.getStatus().getReason());
    }

    private static boolean hasDeletionTimestamp(Pod pod) {
        if (pod == null) {
            return false;
        }
        return pod.getMetadata() != null
                && pod.getMetadata().getDeletionTimestamp() != null;
    }

    /**
     * Returns {@code true} if the given pod has at least 1 container that's initializing.
     *
     * @param pod the pod to return the initializing status for
     * @return returns true if the pod is initializing
     */
    public static boolean isInitializing(Pod pod) {
        if (pod == null) {
            return false;
        }
        return pod.getStatus().getInitContainerStatuses().stream()
                .anyMatch(PodStatusUtil::isInitializing);
    }

    /**
     * Returns {@code true} if the given container status is terminated with an non-0 exit code or is waiting.
     * Returns {@code false} otherwise.
     */
    private static boolean isInitializing(ContainerStatus status) {
        if (status == null) {
            return true;
        }

        ContainerState state = status.getState();
        if (state == null) {
            return true;
        }
        if (isTerminated(state)) {
            return hasNonNullExitCode(state);
        } else if (isWaiting(state)) {
            return !isWaitingInitializing(state);
        } else {
            return true;
        }
    }

    private static boolean isTerminated(ContainerState state) {
        return state == null
            || state.getTerminated() != null;
    }

    private static boolean hasNonNullExitCode(ContainerState state) {
        return state.getTerminated() != null
                && state.getTerminated().getExitCode() != 0;
    }

    private static boolean isWaiting(ContainerState state) {
        return state == null
                || state.getWaiting() != null;
    }

    private static boolean isWaitingInitializing(ContainerState state) {
        return state != null
                && state.getWaiting() != null
                && POD_INITIALIZING.equals(state.getWaiting().getReason());
    }

    private static boolean hasRunningContainer(Pod pod) {
        return getContainerStatus(pod).stream()
                .anyMatch(PodStatusUtil::isRunning);
    }

    private static boolean isRunning(ContainerStatus status) {
        return status.getReady() != null
                && status.getState() != null
                && status.getState().getRunning() != null;
    }

    private static boolean hasCompletedContainer(Pod pod) {
        return getContainerStatus(pod).stream()
                .anyMatch(PodStatusUtil::isCompleted);
    }

    private static boolean isCompleted(ContainerStatus status) {
        return status.getState() != null
                && status.getState().getTerminated() != null
                && CONTAINER_COMPLETED.equals(status.getState().getTerminated().getReason());
    }

    /**
     * Returns the container status for all containers of the given pod. Returns an empty list
     * if the pod has no status
     *
     * @param pod the pod to return the container status for
     * @return list of container status
     *
     * @see Pod#getStatus()
     * @see PodStatus#getContainerStatuses()
     */
    public static List getContainerStatus(Pod pod) {
        if (pod == null
                || pod.getStatus() == null) {
            return Collections.emptyList();
        }
        return pod.getStatus().getContainerStatuses();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy