use of org.jboss.pnc.spi.environment.RunningEnvironment in project pnc by project-ncl.
the class DefaultBuildExecutor method runTheBuild.
private CompletableFuture<CompletedBuild> runTheBuild(DefaultBuildExecutionSession buildExecutionSession) {
CompletableFuture<CompletedBuild> waitToCompleteFuture = new CompletableFuture<>();
if (buildExecutionSession.isCanceled()) {
waitToCompleteFuture.complete(null);
return waitToCompleteFuture;
}
ProcessStageUtils.logProcessStageBegin(BuildExecutionStatus.BUILD_SETTING_UP.toString(), "Running the build ...");
buildExecutionSession.setStatus(BuildExecutionStatus.BUILD_SETTING_UP);
RunningEnvironment runningEnvironment = buildExecutionSession.getRunningEnvironment();
try {
Consumer<CompletedBuild> onComplete = value -> {
ProcessStageUtils.logProcessStageEnd(BuildExecutionStatus.BUILD_SETTING_UP.toString(), "Build completed.");
waitToCompleteFuture.complete(value);
};
Consumer<Throwable> onError = (e) -> {
ProcessStageUtils.logProcessStageEnd(BuildExecutionStatus.BUILD_SETTING_UP.toString(), "Build failed.");
waitToCompleteFuture.completeExceptionally(new BuildProcessException(e, runningEnvironment));
};
String buildAgentUrl = runningEnvironment.getBuildAgentUrl();
String liveLogWebSocketUrl = "ws" + StringUtils.addEndingSlash(buildAgentUrl).replaceAll("http(s?):", ":") + "socket/text/ro";
log.debug("Setting live log websocket url: {}", liveLogWebSocketUrl);
buildExecutionSession.setLiveLogsUri(Optional.of(new URI(liveLogWebSocketUrl)));
BuildDriver buildDriver = buildDriverFactory.getBuildDriver();
RunningBuild runningBuild = buildDriver.startProjectBuild(buildExecutionSession, runningEnvironment, onComplete, onError);
buildExecutionSession.setCancelHook(runningBuild::cancel);
buildExecutionSession.setStatus(BuildExecutionStatus.BUILD_WAITING);
} catch (Throwable e) {
throw new BuildProcessException(e, runningEnvironment);
}
return waitToCompleteFuture;
}
use of org.jboss.pnc.spi.environment.RunningEnvironment in project pnc by project-ncl.
the class DefaultBuildExecutor method completeExecution.
private Void completeExecution(DefaultBuildExecutionSession buildExecutionSession, Throwable e) {
String buildExecutionId = buildExecutionSession.getId();
try {
// Ends when the result is stored by the Orchestrator
ProcessStageUtils.logProcessStageBegin("FINALIZING_BUILD", "Finalizing build ...");
if (e != null) {
log.debug("Finalizing FAILED execution. Exception: ", e);
} else {
log.debug("Finalizing SUCCESS execution.");
}
buildExecutionSession.setStatus(BuildExecutionStatus.FINALIZING_EXECUTION);
if (buildExecutionSession.getStartTime() == null) {
buildExecutionSession.setException(new ExecutorException("Missing start time."));
}
if (e != null) {
stopRunningEnvironment(e);
} else {
try {
destroyEnvironment(buildExecutionSession);
} catch (BuildProcessException destroyException) {
e = destroyException;
}
}
if (e != null) {
buildExecutionSession.setException(new ExecutorException(e));
}
if (buildExecutionSession.getEndTime() != null) {
buildExecutionSession.setException(new ExecutorException("End time already set."));
} else {
buildExecutionSession.setEndTime(new Date());
}
// check if any of previous statuses indicated "failed" state
if (buildExecutionSession.isCanceled()) {
buildExecutionSession.setStatus(BuildExecutionStatus.CANCELLED);
userLog.info("Build execution completed (canceled).");
} else if (buildExecutionSession.hasFailed()) {
buildExecutionSession.setStatus(BuildExecutionStatus.DONE_WITH_ERRORS);
userLog.warn("Build execution completed with errors.");
} else {
buildExecutionSession.setStatus(BuildExecutionStatus.DONE);
userLog.info("Build execution completed successfully.");
}
log.debug("Removing buildExecutionTask [" + buildExecutionId + "] from list of running tasks.");
runningExecutions.remove(buildExecutionId);
userLog.info("Build execution completed.");
} catch (Throwable t) {
userLog.error("Unable to complete execution!", t);
String executorException = "Unable to recover, see system log for the details.";
if (t.getMessage() != null) {
executorException += " " + t.getMessage();
}
buildExecutionSession.setException(new ExecutorException(executorException));
buildExecutionSession.setEndTime(new Date());
buildExecutionSession.setStatus(BuildExecutionStatus.SYSTEM_ERROR);
runningExecutions.remove(buildExecutionId);
} finally {
RunningEnvironment runningEnvironment = buildExecutionSession.getRunningEnvironment();
if (runningEnvironment == null) {
log.warn("Could not close Maven repository session [" + buildExecutionId + "]. Running environment was not set!");
} else {
RepositorySession repositorySession = runningEnvironment.getRepositorySession();
if (repositorySession == null) {
log.warn("Could not close Maven repository session [" + buildExecutionId + "]. Repository session was not set!");
} else {
log.debug("Closing Maven repository session [" + buildExecutionId + "].");
repositorySession.close();
}
}
}
return null;
}
use of org.jboss.pnc.spi.environment.RunningEnvironment in project pnc by project-ncl.
the class OpenshiftStartedEnvironment method monitorInitialization.
/**
* retries is decremented in retryPod in case of pod failing to start
*
* @param onComplete
* @param onError
* @param retries
*/
private void monitorInitialization(Consumer<RunningEnvironment> onComplete, Consumer<Exception> onError, int retries) {
cancelHook = () -> onComplete.accept(null);
CompletableFuture<Void> podFuture = creatingPod.thenComposeAsync(nul -> {
CancellableCompletableFuture<Void> monitor = pollingMonitor.monitor(this::isPodRunning, pollingMonitorCheckInterval, pollingMonitorTimeout, TimeUnit.SECONDS);
addFuture(monitor);
return monitor;
}, executor);
CompletableFuture<Void> serviceFuture = creatingService.thenComposeAsync(nul -> {
CancellableCompletableFuture<Void> monitor = pollingMonitor.monitor(this::isServiceRunning, pollingMonitorCheckInterval, pollingMonitorTimeout, TimeUnit.SECONDS);
addFuture(monitor);
return monitor;
}, executor);
CompletableFuture<Void> routeFuture;
if (creatingRoute.isPresent()) {
routeFuture = creatingRoute.get().thenComposeAsync(nul -> {
CancellableCompletableFuture<Void> monitor = pollingMonitor.monitor(this::isRouteRunning, pollingMonitorCheckInterval, pollingMonitorTimeout, TimeUnit.SECONDS);
addFuture(monitor);
return monitor;
}, executor);
} else {
routeFuture = CompletableFuture.completedFuture(null);
}
CompletableFuture<Void> openshiftDefinitionsError = new CompletableFuture<>();
openshiftDefinitions.exceptionally(t -> {
openshiftDefinitionsError.completeExceptionally(t);
return null;
});
CancellableCompletableFuture<Void> isBuildAgentUpFuture = pollingMonitor.monitor(this::isInternalServletAvailable, pollingMonitorCheckInterval, pollingMonitorTimeout, TimeUnit.SECONDS);
addFuture(isBuildAgentUpFuture);
CompletableFuture<RunningEnvironment> runningEnvironmentFuture = CompletableFutureUtils.allOfOrException(podFuture, serviceFuture, routeFuture).thenComposeAsync(nul -> isBuildAgentUpFuture, executor).thenApplyAsync(nul -> RunningEnvironment.createInstance(pod.getMetadata().getName(), Integer.parseInt(environmentConfiguration.getContainerPort()), route.getSpec().getHost(), getPublicEndpointUrl(), getInternalEndpointUrl(), repositorySession, Paths.get(environmentConfiguration.getWorkingDirectory()), this::destroyEnvironment, debugData), executor);
CompletableFuture.anyOf(runningEnvironmentFuture, openshiftDefinitionsError).handleAsync((runningEnvironment, throwable) -> {
if (throwable != null) {
logger.info("Error while trying to create an OpenShift environment... ", throwable);
cancelAndClearMonitors();
// no more retries, execute the onError consumer
if (retries == 0) {
logger.info("No more retries left, giving up!");
onError.accept(new Exception(getPrettierErrorMessageFromThrowable(throwable, true), throwable));
} else {
PodFailedStartException podFailedStartExc = null;
if (throwable instanceof PodFailedStartException) {
podFailedStartExc = (PodFailedStartException) throwable;
} else if (throwable.getCause() instanceof PodFailedStartException) {
podFailedStartExc = (PodFailedStartException) throwable.getCause();
}
if (podFailedStartExc != null && !Arrays.asList(POD_RETRYABLE_STATUSES).contains(podFailedStartExc.getPodStatus())) {
logger.info("The detected pod error status '{}' is not considered among the ones to be retried, giving up!", podFailedStartExc.getPodStatus());
// the status is not to be retried
onError.accept(new Exception(getPrettierErrorMessageFromThrowable(throwable, false), throwable));
} else {
if (!cancelRequested) {
logger.warn("Creating build environment failed with error '{}'! Retrying ({} retries left)...", throwable, retries);
retryEnvironment(onComplete, onError, retries);
} else {
logger.info("Build was cancelled, not retrying environment!");
}
}
}
} else {
logger.info("Environment successfully initialized. Pod [{}]; Service [{}].", pod.getMetadata().getName(), service.getMetadata().getName());
// openshiftDefinitionsError
onComplete.accept((RunningEnvironment) runningEnvironment);
// completes only with error
}
gaugeMetric.ifPresent(g -> g.incrementMetric(METRICS_POD_STARTED_SUCCESS_KEY));
return null;
}, executor);
}
use of org.jboss.pnc.spi.environment.RunningEnvironment in project pnc by project-ncl.
the class OpenshiftEnvironmentDriverRemoteTest method createAndDestroyEnvironment.
@Test
public void createAndDestroyEnvironment() throws EnvironmentDriverException, InterruptedException {
final Semaphore mutex = new Semaphore(0);
ObjectWrapper<Throwable> exceptionWrapper = new ObjectWrapper<>();
String dummyImageId = "abcd1234";
String dummyRepoUrl = "test.repo.url/repo";
// Create container
final StartedEnvironment startedEnv = environmentDriver.startEnvironment(dummyImageId, dummyRepoUrl, SystemImageType.DOCKER_IMAGE, DUMMY_REPOSITORY_CONFIGURATION, new DebugData(false), "put-access-token-here", false, Collections.emptyMap());
Consumer<RunningEnvironment> onEnvironmentStarted = (runningEnvironment) -> {
boolean containerDestroyed = false;
try {
assertThatContainerIsRunning(runningEnvironment);
// Destroy container
destroyEnvironment(runningEnvironment);
containerDestroyed = true;
assertThatContainerIsNotRunning(runningEnvironment);
mutex.release();
} catch (Throwable e) {
exceptionWrapper.set(e);
} finally {
if (!containerDestroyed) {
destroyEnvironmentWithReport(runningEnvironment);
}
}
mutex.release();
};
Consumer<Exception> onError = (e) -> {
try {
logger.info("Trying to destroy environment due to an error:", e);
startedEnv.destroyEnvironment();
mutex.release();
} catch (EnvironmentDriverException e1) {
logger.error("Environment LEAK! The running environment was not destroyed. ID: " + startedEnv.getId(), e1);
}
fail("Failed to init builder. " + e.getMessage());
};
startedEnv.monitorInitialization(onEnvironmentStarted, onError);
boolean completed = mutex.tryAcquire(TEST_EXECUTION_TIMEOUT, TimeUnit.SECONDS);
Throwable exception = exceptionWrapper.get();
if (exception != null) {
logger.error("", exception);
fail(exception.getMessage());
}
assertTrue("timeout reached, test has not complete.", completed);
}
use of org.jboss.pnc.spi.environment.RunningEnvironment in project pnc by project-ncl.
the class LivenessProbeTest method shouldFailTheBuildWhenAgentIsNotResponding.
@Test
public void shouldFailTheBuildWhenAgentIsNotResponding() throws InterruptedException, BuildDriverException {
TermdBuildDriverModuleConfig buildDriverModuleConfig = mock(TermdBuildDriverModuleConfig.class);
doReturn(200L).when(buildDriverModuleConfig).getLivenessProbeFrequencyMillis();
doReturn(500L).when(buildDriverModuleConfig).getLivenessFailTimeoutMillis();
ClientMockFactory buildAgentClientMockFactory = new ClientMockFactory();
TermdBuildDriver driver = new TermdBuildDriver(systemConfig, buildDriverModuleConfig, buildAgentClientMockFactory);
BuildExecutionSession buildExecution = mock(BuildExecutionSession.class);
BuildExecutionConfiguration buildExecutionConfiguration = mock(BuildExecutionConfiguration.class);
doReturn(buildExecutionConfiguration).when(buildExecution).getBuildExecutionConfiguration();
RunningEnvironment runningEnvironment = mock(RunningEnvironment.class);
doReturn(Paths.get("")).when(runningEnvironment).getWorkingDirectory();
doReturn(new DebugData(false)).when(runningEnvironment).getDebugData();
doReturn("http://localhost/").when(runningEnvironment).getInternalBuildAgentUrl();
doReturn(runningEnvironment).when(buildExecution).getRunningEnvironment();
BlockingQueue<Throwable> result = new ArrayBlockingQueue(1);
Consumer<CompletedBuild> onComplete = (completedBuild) -> Assert.fail("Build should complete with error.");
Consumer<Throwable> onError = (throwable) -> {
try {
result.put(throwable);
} catch (InterruptedException e) {
Assert.fail("Error in the test. Unable to add the result to queue.");
}
};
// when
RunningBuild runningBuild = driver.startProjectBuild(buildExecution, runningEnvironment, onComplete, onError);
// then
Throwable throwable = result.poll(1, TimeUnit.SECONDS);
Assert.assertNotNull("It should complete with an exception.", throwable);
Assert.assertEquals("Build Agent has gone away.", throwable.getMessage());
}
Aggregations