use of org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException in project devspaces-images by redhat-developer.
the class KubernetesDeployments method doDeletePod.
protected CompletableFuture<Void> doDeletePod(String podName) throws InfrastructureException {
Watch toCloseOnException = null;
try {
PodResource<Pod> podResource = clientFactory.create(workspaceId).pods().inNamespace(namespace).withName(podName);
if (podResource.get() == null) {
throw new InfrastructureException(format("No pod found to delete for name %s", podName));
}
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 {}", podName, 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 createDeployment.
private Pod createDeployment(Deployment deployment, String workspaceId) throws InfrastructureException {
addPullSecretsOfSA(deployment);
final String deploymentName = deployment.getMetadata().getName();
final CompletableFuture<Pod> createFuture = new CompletableFuture<>();
final Watch createWatch = clientFactory.create(workspaceId).pods().inNamespace(namespace).withLabels(Map.of(CHE_WORKSPACE_ID_LABEL, workspaceId, CHE_DEPLOYMENT_NAME_LABEL, deploymentName)).watch(new CreateWatcher(createFuture, workspaceId, deploymentName));
try {
clientFactory.create(workspaceId).apps().deployments().inNamespace(namespace).create(deployment);
return createFuture.get(POD_CREATION_TIMEOUT_MIN, TimeUnit.MINUTES);
} catch (KubernetesClientException e) {
throw new KubernetesInfrastructureException(e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new InfrastructureException(format("Interrupted while waiting for Pod creation. -id: %s -message: %s", deploymentName, e.getMessage()));
} catch (ExecutionException e) {
throw new InfrastructureException(format("Error occured while waiting for Pod creation. -id: %s -message: %s", deploymentName, e.getCause().getMessage()));
} catch (TimeoutException e) {
throw new InfrastructureException(format("Pod creation timeout exceeded. -id: %s -message: %s", deploymentName, e.getMessage()));
} finally {
createWatch.close();
}
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException in project devspaces-images by redhat-developer.
the class KubernetesDeployments method exec.
/**
* Executes command in specified container.
*
* @param name pod name (or name of deployment containing pod) where command will be executed
* @param containerName container name where command will be executed
* @param timeoutMin timeout to wait until process will be done
* @param command command to execute
* @param outputConsumer command output biconsumer, that is accepts stream type and message
* @throws InfrastructureException when specified timeout is reached
* @throws InfrastructureException when {@link Thread} is interrupted while command executing
* @throws InfrastructureException when command error stream is not empty
* @throws InfrastructureException when any other exception occurs
*/
public void exec(String name, String containerName, int timeoutMin, String[] command, BiConsumer<String, String> outputConsumer) throws InfrastructureException {
final String podName = getPodName(name);
final ExecWatchdog watchdog = new ExecWatchdog();
final ByteArrayOutputStream errStream = new ByteArrayOutputStream(ERROR_BUFF_INITIAL_CAP);
try (ExecWatch watch = clientFactory.create(workspaceId).pods().inNamespace(namespace).withName(podName).inContainer(containerName).writingError(errStream).usingListener(watchdog).exec(encode(command))) {
try {
watchdog.wait(timeoutMin, TimeUnit.MINUTES);
final byte[] error = errStream.toByteArray();
if (error.length > 0) {
final String cmd = Arrays.stream(command).collect(Collectors.joining(" ", "", "\n"));
final String err = new String(error, UTF_8);
outputConsumer.accept(STDOUT, cmd);
outputConsumer.accept(STDERR, err);
throw new InfrastructureException(err);
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new InfrastructureException(ex.getMessage(), ex);
}
} catch (KubernetesClientException ex) {
throw new KubernetesInfrastructureException(ex);
}
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException in project devspaces-images by redhat-developer.
the class KubernetesNamespace method create.
private Namespace create(String namespaceName, KubernetesClient client) throws InfrastructureException {
try {
Namespace namespace = client.namespaces().create(new NamespaceBuilder().withNewMetadata().withName(namespaceName).endMetadata().build());
waitDefaultServiceAccount(namespaceName, client);
return namespace;
} catch (KubernetesClientException e) {
if (e.getCode() == 403) {
LOG.error("Unable to create new Kubernetes project due to lack of permissions." + "When using workspace namespace placeholders, service account with lenient permissions (cluster-admin) must be used.");
}
throw new KubernetesInfrastructureException(e);
}
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException in project devspaces-images by redhat-developer.
the class KubernetesPersistentVolumeClaims method waitBound.
/**
* Waits until persistent volume claim state is bound. If used k8s Storage Class has
* 'volumeBindingMode: WaitForFirstConsumer', we don't wait to avoid deadlock.
*
* @param name name of persistent volume claim that should be watched
* @param timeoutMillis waiting timeout in milliseconds
* @return persistent volume claim that is bound or in waiting for consumer state
* @throws InfrastructureException when specified timeout is reached
* @throws InfrastructureException when {@link Thread} is interrupted while waiting
* @throws InfrastructureException when any other exception occurs
*/
public PersistentVolumeClaim waitBound(String name, long timeoutMillis) throws InfrastructureException {
try {
Resource<PersistentVolumeClaim> pvcResource = clientFactory.create(workspaceId).persistentVolumeClaims().inNamespace(namespace).withName(name);
PersistentVolumeClaim actualPvc = pvcResource.get();
if (actualPvc.getStatus().getPhase().equals(PVC_BOUND_PHASE)) {
return actualPvc;
}
CompletableFuture<PersistentVolumeClaim> future = new CompletableFuture<>();
// any of these watchers can finish the operation resolving the future
try (Watch boundWatcher = pvcIsBoundWatcher(future, pvcResource);
Watch waitingWatcher = pvcIsWaitingForConsumerWatcher(future, actualPvc)) {
return future.get(timeoutMillis, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
// should take a look.
throw new InternalInfrastructureException(e.getCause().getMessage(), e);
} catch (TimeoutException e) {
// issues that admin should take a look.
throw new InternalInfrastructureException("Waiting for persistent volume claim '" + name + "' reached timeout");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new InfrastructureException("Waiting for persistent volume claim '" + name + "' was interrupted");
}
} catch (KubernetesClientException e) {
throw new KubernetesInfrastructureException(e);
}
}
Aggregations