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

io.fabric8.kubernetes.client.utils.internal.PodOperationUtil Maven / Gradle / Ivy

The newest version!
/*
 * 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.internal;

import io.fabric8.kubernetes.api.model.OwnerReference;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodList;
import io.fabric8.kubernetes.api.model.PodStatus;
import io.fabric8.kubernetes.client.KubernetesClientTimeoutException;
import io.fabric8.kubernetes.client.dsl.LogWatch;
import io.fabric8.kubernetes.client.dsl.Loggable;
import io.fabric8.kubernetes.client.dsl.PodResource;
import io.fabric8.kubernetes.client.dsl.internal.OperationContext;
import io.fabric8.kubernetes.client.dsl.internal.PodOperationContext;
import io.fabric8.kubernetes.client.dsl.internal.core.v1.PodOperationsImpl;
import io.fabric8.kubernetes.client.readiness.Readiness;
import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

public class PodOperationUtil {
  private static final Logger LOG = LoggerFactory.getLogger(PodOperationUtil.class);

  private PodOperationUtil() {
  }

  /**
   * Gets PodOperations for Pods specific to a controller
   *
   * @param podOperations {@link PodOperationsImpl} generic PodOperations class without any pod configured
   * @param controllerPodList List of pods based on a label that are related to a Controller
   * @param controllerUid UID of Controller
   * @return returns list of PodOperations with pods whose owner's UID is of the provided controller
   */
  public static List getFilteredPodsForLogs(PodOperationsImpl podOperations, PodList controllerPodList,
      String controllerUid) {
    List pods = new ArrayList<>();
    for (Pod pod : controllerPodList.getItems()) {
      OwnerReference ownerReference = KubernetesResourceUtil.getControllerUid(pod);
      if (ownerReference != null && ownerReference.getUid().equals(controllerUid)) {
        pods.add(podOperations.withName(pod.getMetadata().getName()));
      }
    }
    return pods;
  }

  public static PodOperationsImpl getGenericPodOperations(OperationContext context, PodOperationContext podOperationContext) {
    return new PodOperationsImpl(
        podOperationContext,
        context.withName(null).withApiGroupName(null).withApiGroupVersion("v1"));
  }

  public static List getPodOperationsForController(OperationContext context,
      PodOperationContext podOperationContext, String controllerUid, Map selectorLabels) {
    return getPodOperationsForController(
        PodOperationUtil.getGenericPodOperations(context, podOperationContext), controllerUid,
        selectorLabels);
  }

  public static LogWatch watchLog(List podResources, OutputStream out) {
    return findFirstPodResource(podResources).map(it -> it.watchLog(out)).orElse(null);
  }

  public static Reader getLogReader(List podResources) {
    return findFirstPodResource(podResources).map(Loggable::getLogReader).orElse(null);
  }

  public static InputStream getLogInputStream(List podResources) {
    return findFirstPodResource(podResources).map(Loggable::getLogInputStream).orElse(null);
  }

  private static Optional findFirstPodResource(List podResources) {
    if (!podResources.isEmpty()) {
      if (podResources.size() > 1) {
        LOG.debug("Found {} pods, Using first one to get log", podResources.size());
      }
      return Optional.ofNullable(podResources.get(0));
    }
    return Optional.empty();
  }

  public static String getLog(List podOperationList, Boolean isPretty) {
    StringBuilder stringBuilder = new StringBuilder();
    for (PodResource podOperation : podOperationList) {
      stringBuilder.append(podOperation.getLog(isPretty));
    }
    return stringBuilder.toString();
  }

  public static List getPodOperationsForController(PodOperationsImpl podOperations, String controllerUid,
      Map selectorLabels) {
    PodList controllerPodList = podOperations.withLabels(selectorLabels).list();

    return PodOperationUtil.getFilteredPodsForLogs(podOperations, controllerPodList, controllerUid);
  }

  public static Pod waitUntilReadyOrTerminal(PodResource podOperation, int logWaitTimeoutMs) {
    AtomicReference podRef = new AtomicReference<>();
    try {
      // Wait for Pod to become ready or succeeded
      podOperation.waitUntilCondition(p -> {
        podRef.set(p);
        return isReadyOrTerminal(p);
      },
          logWaitTimeoutMs,
          TimeUnit.MILLISECONDS);
    } catch (KubernetesClientTimeoutException timeout) {
      LOG.debug("Timed out waiting for Pod to become Ready: {}, will still proceed", timeout.getMessage());
    } catch (Exception otherException) {
      LOG.warn("Error while waiting for Pod to become Ready", otherException);
    }
    return podRef.get();
  }

  static boolean isReadyOrTerminal(Pod p) {
    // we'll treat missing as an exit condition - there's no expectation that we should wait for a pod that doesn't exist
    return p == null || Readiness.isPodReady(p) || Optional.ofNullable(p.getStatus()).map(PodStatus::getPhase)
        .filter(phase -> !Arrays.asList("Pending", "Unknown").contains(phase)).isPresent();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy