Search in sources :

Example 11 with InfrastructureException

use of org.eclipse.che.api.workspace.server.spi.InfrastructureException in project che-server by eclipse-che.

the class KubernetesDeployments method handleStartingPodStatus.

private void handleStartingPodStatus(CompletableFuture<Void> podRunningFuture, Pod pod) {
    PodStatus status = pod.getStatus();
    String podPhase = status.getPhase();
    if (POD_STATUS_PHASE_RUNNING.equals(podPhase)) {
        // check that all the containers are ready...
        Map<String, String> terminatedContainers = new HashMap<>();
        List<String> restartingContainers = new ArrayList<>();
        for (ContainerStatus cs : status.getContainerStatuses()) {
            ContainerStateTerminated terminated = cs.getState().getTerminated();
            if (terminated == null) {
                ContainerStateWaiting waiting = cs.getState().getWaiting();
                // we've caught the container waiting for a restart after a failure
                if (waiting != null) {
                    terminated = cs.getLastState().getTerminated();
                }
            }
            if (terminated != null) {
                terminatedContainers.put(cs.getName(), format("reason = '%s', exit code = %d, message = '%s'", terminated.getReason(), terminated.getExitCode(), terminated.getMessage()));
            }
            if (cs.getRestartCount() != null && cs.getRestartCount() > 0) {
                restartingContainers.add(cs.getName());
            }
        }
        if (terminatedContainers.isEmpty() && restartingContainers.isEmpty()) {
            podRunningFuture.complete(null);
        } else {
            StringBuilder errorMessage = new StringBuilder();
            if (!restartingContainers.isEmpty()) {
                errorMessage.append("The following containers have restarted during the startup:\n");
                errorMessage.append(String.join(", ", restartingContainers));
            }
            if (!terminatedContainers.isEmpty()) {
                if (errorMessage.length() > 0) {
                    errorMessage.append("\n");
                }
                errorMessage.append("The following containers have terminated:\n");
                errorMessage.append(terminatedContainers.entrySet().stream().map(e -> e.getKey() + ": " + e.getValue()).collect(Collectors.joining("" + "\n")));
            }
            podRunningFuture.completeExceptionally(new InfrastructureException(errorMessage.toString()));
        }
        return;
    }
    if (POD_STATUS_PHASE_SUCCEEDED.equals(podPhase)) {
        podRunningFuture.completeExceptionally(new InfrastructureException("Pod container has been terminated. Container must be configured to use a non-terminating command."));
        return;
    }
    if (POD_STATUS_PHASE_FAILED.equals(podPhase)) {
        String exceptionMessage = "Pod '" + pod.getMetadata().getName() + "' failed to start.";
        String reason = pod.getStatus().getReason();
        if (Strings.isNullOrEmpty(reason)) {
            try {
                String podLog = clientFactory.create(workspaceId).pods().inNamespace(namespace).withName(pod.getMetadata().getName()).getLog();
                exceptionMessage = exceptionMessage.concat(" Pod logs: ").concat(podLog);
            } catch (InfrastructureException | KubernetesClientException e) {
                exceptionMessage = exceptionMessage.concat(" Error occurred while fetching pod logs: " + e.getMessage());
            }
        } else {
            exceptionMessage = exceptionMessage.concat(" Reason: ").concat(reason);
        }
        podRunningFuture.completeExceptionally(new InfrastructureException(exceptionMessage));
        LOG.warn(exceptionMessage);
    }
}
Also used : ContainerStateWaiting(io.fabric8.kubernetes.api.model.ContainerStateWaiting) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ContainerStateTerminated(io.fabric8.kubernetes.api.model.ContainerStateTerminated) PodStatus(io.fabric8.kubernetes.api.model.PodStatus) ContainerStatus(io.fabric8.kubernetes.api.model.ContainerStatus) KubernetesInfrastructureException(org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException) InfrastructureException(org.eclipse.che.api.workspace.server.spi.InfrastructureException) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException)

Example 12 with InfrastructureException

use of org.eclipse.che.api.workspace.server.spi.InfrastructureException in project che-server by eclipse-che.

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);
    }
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) Watch(io.fabric8.kubernetes.client.Watch) PersistentVolumeClaim(io.fabric8.kubernetes.api.model.PersistentVolumeClaim) ExecutionException(java.util.concurrent.ExecutionException) KubernetesInfrastructureException(org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException) InternalInfrastructureException(org.eclipse.che.api.workspace.server.spi.InternalInfrastructureException) InfrastructureException(org.eclipse.che.api.workspace.server.spi.InfrastructureException) KubernetesInfrastructureException(org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException) InternalInfrastructureException(org.eclipse.che.api.workspace.server.spi.InternalInfrastructureException) TimeoutException(java.util.concurrent.TimeoutException) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException)

Example 13 with InfrastructureException

use of org.eclipse.che.api.workspace.server.spi.InfrastructureException in project che-server by eclipse-che.

the class KubernetesRecipeParser method parse.

/**
 * Parses Kubernetes objects from recipe content.
 *
 * @param recipeContent recipe content that should be parsed
 * @return parsed objects
 * @throws IllegalArgumentException if recipe content is null
 * @throws ValidationException if recipe content has broken format
 * @throws ValidationException if recipe content has unrecognized objects
 * @throws InfrastructureException when exception occurred during kubernetes client creation
 */
public List<HasMetadata> parse(String recipeContent) throws ValidationException, InfrastructureException {
    checkNotNull(recipeContent, "Recipe content type must not be null");
    try {
        // Behavior:
        // - If `content` is a single object like Deployment, load().get() will get the object in that
        // list
        // - If `content` is a Kubernetes List, load().get() will get the objects in that list
        // - If `content` is an OpenShift template, load().get() will get the objects in the template
        // with parameters substituted (e.g. with default values).
        List<HasMetadata> parsed = clientFactory.create().load(new ByteArrayInputStream(recipeContent.getBytes())).get();
        // needed because Che master namespace is set by K8s API during list loading
        parsed.stream().filter(o -> o.getMetadata() != null).forEach(o -> o.getMetadata().setNamespace(null));
        return parsed;
    } catch (KubernetesClientException e) {
        // KubernetesClient wraps the error when a JsonMappingException occurs so we need the cause
        String message = e.getCause() == null ? e.getMessage() : e.getCause().getMessage();
        if (message.contains("\n")) {
            // Clean up message if it comes from JsonMappingException. Format is e.g.
            // `No resource type found for:v1#Route1\n at [...]`
            message = message.split("\\n", 2)[0];
        }
        throw new ValidationException(format("Could not parse Kubernetes recipe: %s", message));
    }
}
Also used : KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) ImmutableSet(com.google.common.collect.ImmutableSet) KubernetesClientFactory(org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Set(java.util.Set) HasMetadata(io.fabric8.kubernetes.api.model.HasMetadata) String.format(java.lang.String.format) ValidationException(org.eclipse.che.api.core.ValidationException) Inject(javax.inject.Inject) InfrastructureException(org.eclipse.che.api.workspace.server.spi.InfrastructureException) List(java.util.List) InternalRecipe(org.eclipse.che.api.workspace.server.spi.environment.InternalRecipe) ByteArrayInputStream(java.io.ByteArrayInputStream) HasMetadata(io.fabric8.kubernetes.api.model.HasMetadata) ValidationException(org.eclipse.che.api.core.ValidationException) ByteArrayInputStream(java.io.ByteArrayInputStream) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException)

Example 14 with InfrastructureException

use of org.eclipse.che.api.workspace.server.spi.InfrastructureException in project che-server by eclipse-che.

the class UserProfileConfigurator method prepareProfileSecret.

private Secret prepareProfileSecret(NamespaceResolutionContext namespaceResolutionContext) throws InfrastructureException {
    User user;
    try {
        user = userManager.getById(namespaceResolutionContext.getUserId());
    } catch (NotFoundException | ServerException e) {
        throw new InfrastructureException(String.format("Could not find current user with id:%s.", namespaceResolutionContext.getUserId()), e);
    }
    Base64.Encoder enc = Base64.getEncoder();
    final Map<String, String> userProfileData = new HashMap<>();
    userProfileData.put("id", enc.encodeToString(user.getId().getBytes()));
    userProfileData.put("name", enc.encodeToString(user.getName().getBytes()));
    userProfileData.put("email", enc.encodeToString(user.getEmail().getBytes()));
    return new SecretBuilder().addToData(userProfileData).withNewMetadata().withName(USER_PROFILE_SECRET_NAME).addToLabels(DEV_WORKSPACE_MOUNT_LABEL, "true").addToLabels(DEV_WORKSPACE_WATCH_SECRET_LABEL, "true").addToAnnotations(DEV_WORKSPACE_MOUNT_AS_ANNOTATION, "file").addToAnnotations(DEV_WORKSPACE_MOUNT_PATH_ANNOTATION, USER_PROFILE_SECRET_MOUNT_PATH).endMetadata().build();
}
Also used : SecretBuilder(io.fabric8.kubernetes.api.model.SecretBuilder) User(org.eclipse.che.api.core.model.user.User) ServerException(org.eclipse.che.api.core.ServerException) Base64(java.util.Base64) HashMap(java.util.HashMap) NotFoundException(org.eclipse.che.api.core.NotFoundException) InfrastructureException(org.eclipse.che.api.workspace.server.spi.InfrastructureException)

Example 15 with InfrastructureException

use of org.eclipse.che.api.workspace.server.spi.InfrastructureException in project che-server by eclipse-che.

the class KubernetesServerExposer method exposeSecureServers.

private void exposeSecureServers(Map<String, ServerConfig> securedServers, Map<String, ServicePort> securedPorts) throws InfrastructureException {
    if (securedPorts.isEmpty()) {
        return;
    }
    Optional<Service> secureService = secureServerExposer.createService(securedPorts.values(), pod, machineName, securedServers);
    String secureServiceName = secureService.map(s -> {
        String n = s.getMetadata().getName();
        k8sEnv.getServices().put(n, s);
        return n;
    }).orElse(null);
    for (ServicePort servicePort : securedPorts.values()) {
        // expose service port related secure servers if exist
        Map<String, ServerConfig> matchedSecureServers = match(securedServers, servicePort);
        if (!matchedSecureServers.isEmpty()) {
            onEachExposableServerSet(matchedSecureServers, (serverId, srvrs) -> {
                secureServerExposer.expose(k8sEnv, pod, machineName, secureServiceName, serverId, servicePort, srvrs);
            });
        }
    }
}
Also used : NameGenerator.generate(org.eclipse.che.commons.lang.NameGenerator.generate) Container(io.fabric8.kubernetes.api.model.Container) ConfigurationProvisioner(org.eclipse.che.workspace.infrastructure.kubernetes.provision.ConfigurationProvisioner) ExternalServerExposer(org.eclipse.che.workspace.infrastructure.kubernetes.server.external.ExternalServerExposer) LoggerFactory(org.slf4j.LoggerFactory) ServicePort(io.fabric8.kubernetes.api.model.ServicePort) KubernetesEnvironment(org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment) ServicePortBuilder(io.fabric8.kubernetes.api.model.ServicePortBuilder) HashMap(java.util.HashMap) SERVER_NAME_ATTRIBUTE(org.eclipse.che.api.core.model.workspace.config.ServerConfig.SERVER_NAME_ATTRIBUTE) ArrayList(java.util.ArrayList) Collectors.toMap(java.util.stream.Collectors.toMap) Map(java.util.Map) Service(io.fabric8.kubernetes.api.model.Service) UniqueNamesProvisioner(org.eclipse.che.workspace.infrastructure.kubernetes.provision.UniqueNamesProvisioner) Constants(org.eclipse.che.workspace.infrastructure.kubernetes.Constants) Logger(org.slf4j.Logger) ImmutableMap(com.google.common.collect.ImmutableMap) SecureServerExposer(org.eclipse.che.workspace.infrastructure.kubernetes.server.secure.SecureServerExposer) Integer.parseInt(java.lang.Integer.parseInt) ServerConfig(org.eclipse.che.api.core.model.workspace.config.ServerConfig) Annotations(org.eclipse.che.workspace.infrastructure.kubernetes.Annotations) ContainerPort(io.fabric8.kubernetes.api.model.ContainerPort) InfrastructureException(org.eclipse.che.api.workspace.server.spi.InfrastructureException) CHE_ORIGINAL_NAME_LABEL(org.eclipse.che.workspace.infrastructure.kubernetes.Constants.CHE_ORIGINAL_NAME_LABEL) Ingress(io.fabric8.kubernetes.api.model.networking.v1.Ingress) RuntimeIdentity(org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity) PodData(org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment.PodData) Optional(java.util.Optional) ContainerPortBuilder(io.fabric8.kubernetes.api.model.ContainerPortBuilder) Collections(java.util.Collections) ServicePort(io.fabric8.kubernetes.api.model.ServicePort) ServerConfig(org.eclipse.che.api.core.model.workspace.config.ServerConfig) Service(io.fabric8.kubernetes.api.model.Service)

Aggregations

InfrastructureException (org.eclipse.che.api.workspace.server.spi.InfrastructureException)242 InternalInfrastructureException (org.eclipse.che.api.workspace.server.spi.InternalInfrastructureException)64 Test (org.testng.annotations.Test)56 KubernetesInfrastructureException (org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException)44 RuntimeIdentity (org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity)42 KubernetesClientException (io.fabric8.kubernetes.client.KubernetesClientException)38 CompletableFuture (java.util.concurrent.CompletableFuture)36 ExecutionException (java.util.concurrent.ExecutionException)36 TimeoutException (java.util.concurrent.TimeoutException)32 ServerException (org.eclipse.che.api.core.ServerException)32 Pod (io.fabric8.kubernetes.api.model.Pod)30 Map (java.util.Map)26 ValidationException (org.eclipse.che.api.core.ValidationException)22 Traced (org.eclipse.che.commons.annotation.Traced)20 Container (io.fabric8.kubernetes.api.model.Container)18 List (java.util.List)18 Set (java.util.Set)18 Inject (javax.inject.Inject)18 RuntimeStartInterruptedException (org.eclipse.che.api.workspace.server.spi.RuntimeStartInterruptedException)18 KubernetesEnvironment (org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment)18