use of org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException in project devspaces-images by redhat-developer.
the class AsyncStoragePodInterceptor method deleteAsyncStoragePod.
private CompletableFuture<Void> deleteAsyncStoragePod(PodResource<Pod> podResource) throws InfrastructureException {
Watch toCloseOnException = null;
try {
final CompletableFuture<Void> deleteFuture = new CompletableFuture<>();
final Watch watch = podResource.watch(new DeleteWatcher<>(deleteFuture));
toCloseOnException = watch;
Boolean deleteSucceeded = podResource.withPropagationPolicy(BACKGROUND).delete();
if (deleteSucceeded == null || !deleteSucceeded) {
deleteFuture.complete(null);
}
return deleteFuture.whenComplete((v, e) -> {
if (e != null) {
LOG.warn("Failed to remove pod {} cause {}", ASYNC_STORAGE, e.getMessage());
}
watch.close();
});
} catch (KubernetesClientException e) {
if (toCloseOnException != null) {
toCloseOnException.close();
}
throw new KubernetesInfrastructureException(e);
} catch (Exception e) {
if (toCloseOnException != null) {
toCloseOnException.close();
}
throw e;
}
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException in project devspaces-images by redhat-developer.
the class KubernetesDeployments method watchEvents.
/**
* Registers a specified handler for handling events about changes in pods containers. Registering
* several handlers doesn't create multiple websocket connections, so it is efficient to call this
* method several times instead of using composite handler to combine other handlers.
*
* @param handler pod container events handler
* @throws InfrastructureException if any error occurs while watcher starting
*/
public void watchEvents(PodEventHandler handler) throws InfrastructureException {
if (containerWatch == null) {
final Watcher<Event> watcher = new Watcher<>() {
@Override
public void eventReceived(Action action, Event event) {
ObjectReference involvedObject = event.getInvolvedObject();
if (POD_OBJECT_KIND.equals(involvedObject.getKind()) || REPLICASET_OBJECT_KIND.equals(involvedObject.getKind()) || DEPLOYMENT_OBJECT_KIND.equals(involvedObject.getKind())) {
String podName = involvedObject.getName();
String lastTimestamp = event.getLastTimestamp();
if (lastTimestamp == null) {
String firstTimestamp = event.getFirstTimestamp();
if (firstTimestamp != null) {
// Done in the same way like it made in
// https://github.com/kubernetes/kubernetes/pull/86557
lastTimestamp = firstTimestamp;
} else {
LOG.debug("lastTimestamp and firstTimestamp are undefined. Event: {}. Fallback to the current time.", event);
lastTimestamp = PodEvents.convertDateToEventTimestamp(new Date());
}
}
PodEvent podEvent = new PodEvent(podName, getContainerName(involvedObject.getFieldPath()), event.getReason(), event.getMessage(), event.getMetadata().getCreationTimestamp(), lastTimestamp);
try {
if (happenedAfterWatcherInitialization(podEvent)) {
containerEventsHandlers.forEach(h -> h.handle(podEvent));
}
} catch (ParseException e) {
LOG.error("Failed to parse last timestamp of the event. Cause: {}. Event: {}", e.getMessage(), podEvent, e);
}
}
}
@Override
public void onClose(WatcherException ignored) {
}
/**
* Returns the container name if the event is related to container. When the event is
* related to container `fieldPath` field contain information in the following format:
* `spec.container{web}`, where `web` is container name
*/
private String getContainerName(String fieldPath) {
String containerName = null;
if (fieldPath != null) {
Matcher containerFieldMatcher = CONTAINER_FIELD_PATH_PATTERN.matcher(fieldPath);
if (containerFieldMatcher.matches()) {
containerName = containerFieldMatcher.group(CONTAINER_NAME_GROUP);
}
}
return containerName;
}
/**
* Returns true if 'lastTimestamp' of the event is *after* the time of the watcher
* initialization
*/
private boolean happenedAfterWatcherInitialization(PodEvent event) throws ParseException {
String eventLastTimestamp = event.getLastTimestamp();
Date eventLastTimestampDate = PodEvents.convertEventTimestampToDate(eventLastTimestamp);
return eventLastTimestampDate.after(watcherInitializationDate);
}
};
try {
watcherInitializationDate = new Date();
containerWatch = clientFactory.create(workspaceId).v1().events().inNamespace(namespace).watch(watcher);
} catch (KubernetesClientException ex) {
throw new KubernetesInfrastructureException(ex);
}
}
containerEventsHandlers.add(handler);
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException in project devspaces-images by redhat-developer.
the class KubernetesDeployments method delete.
/**
* Deletes all existing pods and the Deployments that control them.
*
* <p>Note that this method will mark Kubernetes pods as interrupted and then will wait until all
* pods will be killed.
*
* @throws InfrastructureException when {@link Thread} is interrupted while command executing
* @throws InfrastructureException when pods removal timeout is reached
* @throws InfrastructureException when any other exception occurs
*/
public void delete() throws InfrastructureException {
try {
final List<CompletableFuture<Void>> deleteFutures = new ArrayList<>();
// We first delete all deployments, then clean up any bare Pods.
List<Deployment> deployments = clientFactory.create(workspaceId).apps().deployments().inNamespace(namespace).withLabel(CHE_WORKSPACE_ID_LABEL, workspaceId).list().getItems();
for (Deployment deployment : deployments) {
deleteFutures.add(doDeleteDeployment(deployment.getMetadata().getName()));
}
// We have to be careful to not include pods that are controlled by a deployment
List<Pod> pods = clientFactory.create(workspaceId).pods().inNamespace(namespace).withLabel(CHE_WORKSPACE_ID_LABEL, workspaceId).withoutLabel(CHE_DEPLOYMENT_NAME_LABEL).list().getItems();
for (Pod pod : pods) {
List<OwnerReference> ownerReferences = pod.getMetadata().getOwnerReferences();
if (ownerReferences == null || ownerReferences.isEmpty()) {
deleteFutures.add(doDeletePod(pod.getMetadata().getName()));
}
}
final CompletableFuture<Void> removed = allOf(deleteFutures.toArray(new CompletableFuture[deleteFutures.size()]));
try {
removed.get(POD_REMOVAL_TIMEOUT_MIN, TimeUnit.MINUTES);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new InfrastructureException("Interrupted while waiting for pod removal. " + e.getMessage());
} catch (ExecutionException e) {
throw new InfrastructureException("Error occurred while waiting for pod removing. " + e.getMessage());
} catch (TimeoutException ex) {
throw new InfrastructureException("Pods removal timeout reached " + ex.getMessage());
}
} catch (KubernetesClientException e) {
throw new KubernetesInfrastructureException(e);
}
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException in project devspaces-images by redhat-developer.
the class KubernetesIngresses method wait.
public Ingress wait(String name, long timeout, TimeUnit timeoutUnit, Predicate<Ingress> predicate) throws InfrastructureException {
CompletableFuture<Ingress> future = new CompletableFuture<>();
Watch watch = null;
try {
Resource<Ingress> ingressResource = clientFactory.create(workspaceId).network().v1().ingresses().inNamespace(namespace).withName(name);
watch = ingressResource.watch(new Watcher<>() {
@Override
public void eventReceived(Action action, Ingress ingress) {
if (predicate.test(ingress)) {
future.complete(ingress);
}
}
@Override
public void onClose(WatcherException cause) {
future.completeExceptionally(new InfrastructureException("Waiting for ingress '" + name + "' was interrupted"));
}
});
Ingress actualIngress = ingressResource.get();
if (actualIngress == null) {
throw new InfrastructureException("Specified ingress " + name + " doesn't exist");
}
if (predicate.test(actualIngress)) {
return actualIngress;
}
try {
return future.get(timeout, timeoutUnit);
} catch (ExecutionException e) {
throw new InfrastructureException(e.getCause().getMessage(), e);
} catch (TimeoutException e) {
throw new InfrastructureException("Waiting for ingress '" + name + "' reached timeout");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new InfrastructureException("Waiting for ingress '" + name + "' was interrupted");
}
} catch (KubernetesClientException e) {
throw new KubernetesInfrastructureException(e);
} finally {
if (watch != null) {
watch.close();
}
}
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException in project devspaces-images by redhat-developer.
the class KubernetesNamespace method waitDefaultServiceAccount.
/**
* Waits few seconds until 'default' service account become available otherwise an infrastructure
* exception will be thrown.
*/
protected void waitDefaultServiceAccount(String namespaceName, KubernetesClient client) throws InfrastructureException {
final Predicate<ServiceAccount> predicate = Objects::nonNull;
final CompletableFuture<ServiceAccount> future = new CompletableFuture<>();
Watch watch = null;
try {
final Resource<ServiceAccount> saResource = client.serviceAccounts().inNamespace(namespaceName).withName(DEFAULT_SERVICE_ACCOUNT_NAME);
watch = saResource.watch(new Watcher<>() {
@Override
public void eventReceived(Action action, ServiceAccount serviceAccount) {
if (predicate.test(serviceAccount)) {
future.complete(serviceAccount);
}
}
@Override
public void onClose(WatcherException cause) {
future.completeExceptionally(new InfrastructureException("Waiting for service account '" + DEFAULT_SERVICE_ACCOUNT_NAME + "' was interrupted"));
}
});
if (predicate.test(saResource.get())) {
return;
}
try {
future.get(SERVICE_ACCOUNT_READINESS_TIMEOUT_SEC, TimeUnit.SECONDS);
} catch (ExecutionException ex) {
throw new InfrastructureException(ex.getCause().getMessage(), ex);
} catch (TimeoutException ex) {
throw new InfrastructureException("Waiting for service account '" + DEFAULT_SERVICE_ACCOUNT_NAME + "' reached timeout");
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new InfrastructureException("Waiting for service account '" + DEFAULT_SERVICE_ACCOUNT_NAME + "' was interrupted");
}
} catch (KubernetesClientException ex) {
throw new KubernetesInfrastructureException(ex);
} finally {
if (watch != null) {
watch.close();
}
}
}
Aggregations