use of com.epam.pipeline.entity.pipeline.RunInstance in project cloud-pipeline by epam.
the class PipelineRunLoaderTest method shouldLoadPipelineRunTest.
@Test
void shouldLoadPipelineRunTest() throws EntityNotFoundException {
RunInstance instance = new RunInstance();
instance.setNodeType("type");
instance.setAwsRegionId(TEST_REGION);
instance.setSpot(true);
instance.setNodeDisk(NODE_DISK);
instance.setNodeId("id");
instance.setNodeImage(TEST_PATH);
instance.setNodeName(TEST_NAME);
RunStatus runStatus = new RunStatus();
runStatus.setRunId(1L);
runStatus.setStatus(TaskStatus.SUCCESS);
PipelineRunParameter parameter = new PipelineRunParameter();
parameter.setName(TEST_NAME);
parameter.setValue(TEST_VALUE);
PipelineRun expectedPipelineRun = new PipelineRun();
expectedPipelineRun.setId(1L);
expectedPipelineRun.setName(TEST_NAME);
expectedPipelineRun.setPipelineName(TEST_NAME);
expectedPipelineRun.setPipelineId(1L);
expectedPipelineRun.setInstance(instance);
expectedPipelineRun.setStatus(TaskStatus.SUCCESS);
expectedPipelineRun.setVersion(TEST_VERSION);
expectedPipelineRun.setRunStatuses(Collections.singletonList(runStatus));
expectedPipelineRun.setPricePerHour(PRICE);
expectedPipelineRun.setOwner(TEST_NAME);
expectedPipelineRun.setPipelineRunParameters(Collections.singletonList(parameter));
RunLog runLog = new RunLog();
runLog.setLogText(TEST_DESCRIPTION);
runLog.setStatus(TaskStatus.SUCCESS);
runLog.setTask(new PipelineTask(TEST_NAME));
List<RunLog> runLogs = Collections.singletonList(runLog);
PipelineRunWithLog expectedPipelineRunWithLog = new PipelineRunWithLog();
expectedPipelineRunWithLog.setPipelineRun(expectedPipelineRun);
expectedPipelineRunWithLog.setRunOwner(USER);
expectedPipelineRunWithLog.setRunLogs(runLogs);
PipelineRunLoader pipelineRunLoader = new PipelineRunLoader(apiClient);
when(apiClient.loadPipelineRunWithLogs(anyLong())).thenReturn(expectedPipelineRunWithLog);
when(apiClient.loadPipelineRun(anyLong())).thenReturn(expectedPipelineRun);
Optional<EntityContainer<PipelineRunWithLog>> container = pipelineRunLoader.loadEntity(1L);
EntityContainer<PipelineRunWithLog> pipelineRunEntityContainer = container.orElseThrow(AssertionError::new);
PipelineRunWithLog actualPipelineRunWithLog = pipelineRunEntityContainer.getEntity();
assertNotNull(actualPipelineRunWithLog);
PipelineRun actualPipelineRun = actualPipelineRunWithLog.getPipelineRun();
assertNotNull(actualPipelineRun);
List<RunLog> actualRunLogs = actualPipelineRunWithLog.getRunLogs();
assertNotNull(actualRunLogs);
verifyPipelineRun(expectedPipelineRun, actualPipelineRun);
verifyRunInstance(expectedPipelineRun.getInstance(), actualPipelineRun.getInstance());
verifyRunStatuses(expectedPipelineRun.getRunStatuses(), actualPipelineRun.getRunStatuses());
verifyRunParameters(expectedPipelineRun.getPipelineRunParameters(), actualPipelineRun.getPipelineRunParameters());
verifyRunLogs(runLogs, actualRunLogs);
verifyPipelineUser(pipelineRunEntityContainer.getOwner());
verifyPermissions(PERMISSIONS_CONTAINER_WITH_OWNER, pipelineRunEntityContainer.getPermissions());
}
use of com.epam.pipeline.entity.pipeline.RunInstance in project cloud-pipeline by epam.
the class AutoscaleManager method checkFreeNodes.
private void checkFreeNodes(Set<String> scheduledRuns, KubernetesClient client, Set<String> pods) {
NodeList nodeList = getAvailableNodes(client);
RunInstance defaultInstance = clusterManager.getDefaultInstance();
List<RunInstance> requiredInstances = getRequiredInstances(scheduledRuns, client);
nodeList.getItems().forEach(node -> {
String runId = node.getMetadata().getLabels().get(KubernetesConstants.RUN_ID_LABEL);
if (node.getMetadata().getLabels().get(KubernetesConstants.PAUSED_NODE_LABEL) != null) {
LOGGER.debug("Node {} is paused.", runId);
return;
}
RunInstance previousConfiguration = getPreviousRunInstance(runId);
if (!isNodeAvailable(node)) {
if (previousConfiguration != null) {
Long id = Long.parseLong(runId);
LOGGER.debug("Trying to set failure status for run {}.", runId);
pipelineRunManager.updatePipelineStatusIfNotFinal(id, TaskStatus.FAILURE, new Date());
updatePodStatus(node, id);
}
LOGGER.debug("Scaling down unavailable {} node.", runId);
clusterManager.scaleDown(runId);
return;
}
if (previousConfiguration == null) {
LOGGER.debug("Scaling down {} node for deleted pipeline.", runId);
clusterManager.scaleDown(runId);
return;
}
if (scheduledRuns.contains(runId) || pods.contains(runId)) {
LOGGER.debug("Node is already assigned to run {}.", runId);
return;
}
int currentClusterSize = getCurrentClusterSize(client);
Optional<RunInstance> matchingPipeline = requiredInstances.stream().filter(instance -> clusterManager.requirementsMatch(previousConfiguration, instance)).findFirst();
if (matchingPipeline.isPresent()) {
requiredInstances.remove(matchingPipeline.get());
LOGGER.debug("Leaving node {} free since it possibly matches a pending run.", runId);
} else {
Integer minClusterSize = preferenceManager.getPreference(SystemPreferences.CLUSTER_MIN_SIZE);
if (clusterManager.requirementsMatch(defaultInstance, previousConfiguration) && currentClusterSize <= minClusterSize) {
LOGGER.debug("Minimum cluster size achieved. Leaving {} nodes.", currentClusterSize);
} else {
if (clusterManager.isNodeExpired(runId)) {
LOGGER.debug("Scaling down expired node {}.", runId);
clusterManager.scaleDown(runId);
} else {
LOGGER.debug("Leaving node {} free.", runId);
}
}
}
});
Integer minClusterSize = preferenceManager.getPreference(SystemPreferences.CLUSTER_MIN_SIZE);
int currentClusterSize = getCurrentClusterSize(client);
if (minClusterSize > 0 && currentClusterSize < minClusterSize) {
createFreeNodes(nodeList);
}
}
use of com.epam.pipeline.entity.pipeline.RunInstance in project cloud-pipeline by epam.
the class AutoscaleManager method createNodeForRun.
private void createNodeForRun(List<CompletableFuture<Void>> tasks, String runId, RunInstance requiredInstance) {
long longId = Long.parseLong(runId);
addNodeUpTask(longId);
tasks.add(CompletableFuture.runAsync(() -> {
Instant start = Instant.now();
// save required instance
pipelineRunManager.updateRunInstance(longId, requiredInstance);
RunInstance instance = clusterManager.scaleUp(runId, requiredInstance);
// save instance ID and IP
pipelineRunManager.updateRunInstance(longId, instance);
Instant end = Instant.now();
removeNodeUpTask(longId);
LOGGER.debug("Time to create a node for run {} : {} s.", runId, Duration.between(start, end).getSeconds());
}, executorService.getExecutorService()).exceptionally(e -> {
LOGGER.error(e.getMessage(), e);
if (e.getCause() instanceof CmdExecutionException && Objects.equals(NODEUP_SPOT_FAILED_EXIT_CODE, ((CmdExecutionException) e.getCause()).getExitCode())) {
spotNodeUpAttempts.merge(longId, 1, (oldVal, newVal) -> oldVal + 1);
}
removeNodeUpTask(longId, false);
return null;
}));
}
use of com.epam.pipeline.entity.pipeline.RunInstance in project cloud-pipeline by epam.
the class AutoscaleManager method getNewRunInstance.
private RunInstance getNewRunInstance(String runId) throws GitClientException {
Long longRunId = Long.parseLong(runId);
PipelineRun run = pipelineRunManager.loadPipelineRun(longRunId);
RunInstance instance;
if (run.getInstance() == null || run.getInstance().isEmpty()) {
PipelineConfiguration configuration = pipelineRunManager.loadRunConfiguration(longRunId);
instance = clusterManager.configurationToInstance(configuration);
} else {
instance = clusterManager.fillInstance(run.getInstance());
}
if (instance.getSpot() != null && instance.getSpot() && spotNodeUpAttempts.getOrDefault(longRunId, 0) >= preferenceManager.getPreference(SystemPreferences.CLUSTER_SPOT_MAX_ATTEMPTS)) {
instance.setSpot(false);
pipelineRunManager.updateRunInstance(longRunId, instance);
}
return instance;
}
use of com.epam.pipeline.entity.pipeline.RunInstance in project cloud-pipeline by epam.
the class ClusterManagerImpl method getDefaultInstance.
@Override
public RunInstance getDefaultInstance() {
RunInstance instance = new RunInstance();
instance.setNodeDisk(preferenceManager.getPreference(SystemPreferences.CLUSTER_INSTANCE_HDD));
instance.setEffectiveNodeDisk(preferenceManager.getPreference(SystemPreferences.CLUSTER_INSTANCE_HDD));
instance.setNodeImage(preferenceManager.getPreference(SystemPreferences.CLUSTER_INSTANCE_IMAGE));
instance.setNodeType(preferenceManager.getPreference(SystemPreferences.CLUSTER_INSTANCE_TYPE));
instance.setAwsRegionId(awsRegionManager.loadDefaultRegion().getAwsRegionName());
return instance;
}
Aggregations