use of io.fabric8.kubernetes.api.model.ContainerStateTerminated in project kubernetes-client by fabric8io.
the class PodStatusUtilTest method getContainersStatuses_should_return_all_containers.
@Test
public void getContainersStatuses_should_return_all_containers() {
// given
ContainerStatus waitingReady = containerStatus(true, containerState(null, containerStateWaiting(null), null));
ContainerStatus terminatedNonReady = containerStatus(false, containerState(containerStateTerminated(null, null), null, null));
Pod pod = pod("some pod").statusBuilder().containerStatuses(runningReady, waitingReady, terminatedNonReady).build().build();
// when
List<ContainerStatus> containers = PodStatusUtil.getContainerStatus(pod);
// then
assertThat(containers).containsExactlyInAnyOrder(runningReady, waitingReady, terminatedNonReady);
}
use of io.fabric8.kubernetes.api.model.ContainerStateTerminated in project styx by spotify.
the class KubernetesDockerRunnerTest method shouldNotDeletePodAfterNonDeletePeriodIfRunStateStillRunning.
@Parameters({ "NEW", "QUEUED", "PREPARE", "SUBMITTING", "SUBMITTED", "RUNNING" })
@Test
public void shouldNotDeletePodAfterNonDeletePeriodIfRunStateStillRunning(String stateName) {
final State state = State.valueOf(stateName);
createdPod.setStatus(podStatus);
when(podStatus.getContainerStatuses()).thenReturn(List.of(containerStatus, keepaliveContainerStatus));
when(containerStatus.getName()).thenReturn(MAIN_CONTAINER_NAME);
when(containerStatus.getState()).thenReturn(containerState);
when(containerState.getTerminated()).thenReturn(containerStateTerminated);
when(containerStateTerminated.getFinishedAt()).thenReturn(FIXED_INSTANT.minus(Duration.ofMinutes(5)).toString());
var runState = RunState.create(WORKFLOW_INSTANCE, state);
var shouldDelete = kdr.shouldDeletePodWithRunState(WORKFLOW_INSTANCE, createdPod, runState);
assertThat(shouldDelete, is(PodDeletionDecision.DO_NOT_DELETE));
}
use of io.fabric8.kubernetes.api.model.ContainerStateTerminated in project styx by spotify.
the class KubernetesDockerRunnerTest method shouldCleanupPodAfterNonDeletePeriodIfRunStateNotRunning.
@Parameters({ "TERMINATED", "FAILED", "ERROR", "DONE" })
@Test
public void shouldCleanupPodAfterNonDeletePeriodIfRunStateNotRunning(String stateName) {
final State state = State.valueOf(stateName);
// inject mock status in real instance
createdPod.setStatus(podStatus);
when(podStatus.getContainerStatuses()).thenReturn(List.of(keepaliveContainerStatus, containerStatus));
when(containerStatus.getName()).thenReturn(MAIN_CONTAINER_NAME);
when(containerStatus.getState()).thenReturn(containerState);
when(containerState.getTerminated()).thenReturn(containerStateTerminated);
when(containerStateTerminated.getFinishedAt()).thenReturn(FIXED_INSTANT.minus(Duration.ofMinutes(5)).toString());
var runState = RunState.create(WORKFLOW_INSTANCE, state);
var shouldDelete = kdr.shouldDeletePodWithRunState(WORKFLOW_INSTANCE, createdPod, runState);
assertThat(shouldDelete, is(PodDeletionDecision.DELETE));
}
use of io.fabric8.kubernetes.api.model.ContainerStateTerminated in project styx by spotify.
the class KubernetesDockerRunner method isTimeToDeletePossiblyForce.
private PodDeletionDecision isTimeToDeletePossiblyForce(ContainerStatus cs) {
final ContainerStateTerminated t = cs.getState().getTerminated();
if (t.getFinishedAt() == null) {
return PodDeletionDecision.FORCE_DELETE;
}
final Instant finishedAt;
try {
finishedAt = Instant.parse(t.getFinishedAt());
} catch (DateTimeParseException e) {
LOG.warn("Failed to parse container state terminated finishedAt: '{}'", t.getFinishedAt(), e);
return PodDeletionDecision.FORCE_DELETE;
}
final Instant deletionDeadline = time.get().minus(podDeletionDelay);
final Instant forceDeletionDeadline = deletionDeadline.minus(POD_FORCE_DELETION_TOLERATION);
return PodDeletionDecision.newBuilder().delete(finishedAt.isBefore(deletionDeadline)).force(finishedAt.isBefore(forceDeletionDeadline)).build();
}
use of io.fabric8.kubernetes.api.model.ContainerStateTerminated in project styx by spotify.
the class KubernetesPodEventTranslator method getExitCodeIfValid.
private static Optional<Integer> getExitCodeIfValid(String workflowInstance, Pod pod, ContainerStatus status, Stats stats) {
final ContainerStateTerminated terminated = status.getState().getTerminated();
// Check termination log exit code, if available
if (Optional.ofNullable(pod.getMetadata().getAnnotations()).map(annotations -> "true".equals(annotations.get(DOCKER_TERMINATION_LOGGING_ANNOTATION))).orElse(false)) {
if (terminated.getMessage() == null) {
LOG.warn("Missing termination log message for workflow instance {} container {}", workflowInstance, status.getContainerID());
stats.recordTerminationLogMissing();
} else {
try {
final TerminationLogMessage message = Json.deserialize(ByteString.encodeUtf8(terminated.getMessage()), TerminationLogMessage.class);
if (!Objects.equals(message.exitCode, terminated.getExitCode())) {
LOG.warn("Exit code mismatch for workflow instance {} container {}. Container exit code: {}. " + "Termination log exit code: {}", workflowInstance, status.getContainerID(), terminated.getExitCode(), message.exitCode);
stats.recordExitCodeMismatch();
}
if (terminated.getExitCode() != null && message.exitCode == 0) {
// code from docker, but there is not a lot we can do about that.
return Optional.of(terminated.getExitCode());
} else {
return Optional.of(message.exitCode);
}
} catch (IOException e) {
stats.recordTerminationLogInvalid();
LOG.warn("Unexpected termination log message for workflow instance {} container {}", workflowInstance, status.getContainerID(), e);
}
}
// TODO: consider separating execution status and debugging info in the "terminate" event.
if (terminated.getExitCode() != null && terminated.getExitCode() != 0) {
return Optional.of(terminated.getExitCode());
} else {
return Optional.empty();
}
}
// No termination log expected, use k8s exit code
if (terminated.getExitCode() == null) {
LOG.warn("Missing exit code for workflow instance {} container {}", workflowInstance, status.getContainerID());
return Optional.empty();
} else {
// there are cases k8s marks the pod failed but with exitCode 0
if ("Failed".equals(pod.getStatus().getPhase()) && terminated.getExitCode() == 0) {
return Optional.empty();
}
return Optional.of(terminated.getExitCode());
}
}
Aggregations