use of org.eclipse.che.workspace.infrastructure.kubernetes.model.KubernetesMachineImpl in project che-server by eclipse-che.
the class KubernetesInternalRuntime method watchLogsIfDebugEnabled.
private void watchLogsIfDebugEnabled(Map<String, String> startOptions) throws InfrastructureException {
if (LogWatcher.shouldWatchLogs(startOptions)) {
LOG.info("Debug workspace startup. Will watch the logs of '{}'", getContext().getIdentity().getWorkspaceId());
// get all the pods we care about
Set<String> podNames = machines.getMachines(getContext().getIdentity()).values().stream().filter(Objects::nonNull).map(KubernetesMachineImpl::getPodName).filter(Objects::nonNull).collect(Collectors.toSet());
LOG.debug("Watch '{}' pods in workspace '{}'", podNames, getContext().getIdentity().getWorkspaceId());
namespace.deployments().watchLogs(new PodLogToEventPublisher(this.eventPublisher, this.getContext().getIdentity()), this.eventPublisher, LogWatchTimeouts.DEFAULT, podNames, LogWatcher.getLogLimitBytes(startOptions));
}
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.model.KubernetesMachineImpl in project che-server by eclipse-che.
the class KubernetesInternalRuntime method checkServers.
/**
* Returns a function, the result of which the completable stage that performs servers checks and
* start of servers probes.
*/
private Function<Void, CompletionStage<Void>> checkServers(List<CompletableFuture<?>> toCancelFutures, KubernetesMachineImpl machine) {
// Need to get active span here to allow use in returned function;
final Span activeSpan = tracer.activeSpan();
return ignored -> {
// Span must be created within this lambda block, otherwise the span begins as soon as
// this function is called (i.e. before the previous steps in the machine boot chain
// are complete
final Span tracingSpan = tracer.buildSpan(CHECK_SERVERS).asChildOf(activeSpan).start();
TracingTags.WORKSPACE_ID.set(tracingSpan, getContext().getIdentity().getWorkspaceId());
TracingTags.MACHINE_NAME.set(tracingSpan, machine.getName());
// This completable future is used to unity the servers checks and start of probes
final CompletableFuture<Void> serversAndProbesFuture = new CompletableFuture<>();
final String machineName = machine.getName();
final RuntimeIdentity runtimeId = getContext().getIdentity();
final ServersChecker serverCheck = serverCheckerFactory.create(runtimeId, machineName, machine.getServers());
final CompletableFuture<?> serversReadyFuture;
LOG.debug("Performing servers check for machine '{}' in workspace '{}'", machineName, runtimeId.getWorkspaceId());
try {
serversReadyFuture = serverCheck.startAsync(new ServerReadinessHandler(machineName));
toCancelFutures.add(serversReadyFuture);
serversAndProbesFuture.whenComplete((ok, ex) -> {
LOG.debug("Servers checks done for machine '{}' in workspace '{}'", machineName, runtimeId.getWorkspaceId());
serversReadyFuture.cancel(true);
});
} catch (InfrastructureException ex) {
serversAndProbesFuture.completeExceptionally(ex);
TracingTags.setErrorStatus(tracingSpan, ex);
tracingSpan.finish();
return serversAndProbesFuture;
}
serversReadyFuture.whenComplete((BiConsumer<Object, Throwable>) (ok, ex) -> {
if (ex != null) {
serversAndProbesFuture.completeExceptionally(ex);
TracingTags.setErrorStatus(tracingSpan, ex);
tracingSpan.finish();
return;
}
try {
probeScheduler.schedule(probesFactory.getProbes(runtimeId, machineName, machine.getServers()), new ServerLivenessHandler());
} catch (InfrastructureException iex) {
serversAndProbesFuture.completeExceptionally(iex);
}
serversAndProbesFuture.complete(null);
tracingSpan.finish();
});
return serversAndProbesFuture;
};
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.model.KubernetesMachineImpl in project che-server by eclipse-che.
the class KubernetesInternalRuntime method storeStartingMachine.
/**
* Puts createdPod in the {@code machines} map and sends the starting event for this machine
*/
private void storeStartingMachine(Pod createdPod, ObjectMeta toCreateMeta, Map<String, InternalMachineConfig> machineConfigs, ServerResolver serverResolver) throws InfrastructureException {
final String workspaceId = getContext().getIdentity().getWorkspaceId();
for (Container container : createdPod.getSpec().getContainers()) {
String machineName = Names.machineName(toCreateMeta, container);
LOG.debug("Creating machine '{}' in workspace '{}'", machineName, workspaceId);
// Sometimes we facing NPE trying to retrieve machine config. Possible names mismatch. Need to
// get more info on that cases.
InternalMachineConfig machineConfig = Optional.ofNullable(machineConfigs.get(machineName)).orElseThrow(() -> {
LOG.error("Workspace '{}' start failed. Machine with name '{}' requested but not found in configs map. Present machines are: {}.", workspaceId, machineName, String.join(",", machineConfigs.keySet()));
return new InfrastructureException(format("Unable to start the workspace '%s' due to an internal inconsistency while composing the workspace runtime." + "Please report a bug. If possible, include the details from Che devfile and server log in bug report (your admin can help with that)", workspaceId));
});
machines.put(getContext().getIdentity(), new KubernetesMachineImpl(workspaceId, machineName, createdPod.getMetadata().getName(), container.getName(), MachineStatus.STARTING, machineConfig.getAttributes(), serverResolver.resolve(machineName)));
eventPublisher.sendStartingEvent(machineName, getContext().getIdentity());
}
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.model.KubernetesMachineImpl in project che-server by eclipse-che.
the class JpaKubernetesMachineCache method doUpdateMachineStatus.
@Transactional
protected void doUpdateMachineStatus(String workspaceId, String machineName, MachineStatus status) throws InfrastructureException {
EntityManager entityManager = managerProvider.get();
KubernetesMachineImpl machine = entityManager.find(KubernetesMachineImpl.class, new MachineId(workspaceId, machineName));
if (machine == null) {
throw new InfrastructureException(format("Machine '%s:%s' was not found", workspaceId, machineName));
}
machine.setStatus(status);
entityManager.flush();
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.model.KubernetesMachineImpl in project devspaces-images by redhat-developer.
the class KubernetesInternalRuntime method internalStart.
@Override
protected void internalStart(Map<String, String> startOptions) throws InfrastructureException {
KubernetesRuntimeContext<E> context = getContext();
String workspaceId = context.getIdentity().getWorkspaceId();
try {
startSynchronizer.setStartThread();
startSynchronizer.start();
runtimeCleaner.cleanUp(namespace, workspaceId);
provisionWorkspace(startOptions, context, workspaceId);
volumesStrategy.prepare(context.getEnvironment(), context.getIdentity(), startSynchronizer.getStartTimeoutMillis(), startOptions);
startSynchronizer.checkFailure();
startMachines();
watchLogsIfDebugEnabled(startOptions);
previewUrlCommandProvisioner.provision(context.getEnvironment(), namespace);
runtimeStates.updateCommands(context.getIdentity(), context.getEnvironment().getCommands());
startSynchronizer.checkFailure();
final Map<String, CompletableFuture<Void>> machinesFutures = new LinkedHashMap<>();
// futures that must be cancelled explicitly
final List<CompletableFuture<?>> toCancelFutures = new CopyOnWriteArrayList<>();
final EnvironmentContext currentContext = EnvironmentContext.getCurrent();
CompletableFuture<Void> startFailure = startSynchronizer.getStartFailure();
Span waitRunningAsyncSpan = tracer.buildSpan(WAIT_MACHINES_START).start();
try (Scope waitRunningAsyncScope = tracer.scopeManager().activate(waitRunningAsyncSpan)) {
TracingTags.WORKSPACE_ID.set(waitRunningAsyncSpan, workspaceId);
for (KubernetesMachineImpl machine : machines.getMachines(context.getIdentity()).values()) {
String machineName = machine.getName();
final CompletableFuture<Void> machineBootChain = waitRunningAsync(toCancelFutures, machine).thenComposeAsync(checkFailure(startFailure), executor).thenRun(publishRunningStatus(machineName)).thenCompose(checkFailure(startFailure)).thenCompose(setContext(currentContext, checkServers(toCancelFutures, machine))).exceptionally(publishFailedStatus(startFailure, machineName));
machinesFutures.put(machineName, machineBootChain);
}
waitMachines(machinesFutures, toCancelFutures, startFailure);
} finally {
waitRunningAsyncSpan.finish();
}
startSynchronizer.complete();
} catch (InfrastructureException | RuntimeException e) {
Exception startFailureCause = startSynchronizer.getStartFailureNow();
if (startFailureCause == null) {
startFailureCause = e;
}
startSynchronizer.completeExceptionally(startFailureCause);
LOG.warn("Failed to start Kubernetes runtime of workspace {}.", workspaceId, startFailureCause);
boolean interrupted = Thread.interrupted() || startFailureCause instanceof RuntimeStartInterruptedException;
// Cancels workspace servers probes if any
probeScheduler.cancel(workspaceId);
// stop watching before namespace cleaning up
namespace.deployments().stopWatch(true);
try {
runtimeCleaner.cleanUp(namespace, workspaceId);
} catch (InfrastructureException cleanUppingEx) {
LOG.warn("Failed to clean up namespace after workspace '{}' start failing.", context.getIdentity().getWorkspaceId(), cleanUppingEx);
}
if (interrupted) {
throw new RuntimeStartInterruptedException(getContext().getIdentity());
}
wrapAndRethrow(startFailureCause);
} finally {
namespace.deployments().stopWatch();
}
}
Aggregations