Search in sources :

Example 16 with Task

use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.

the class SingularitySchedulerTest method testRecoveredTaskIsRecoveredIfLoadBalancerRemoveIsStarted.

@Test
public void testRecoveredTaskIsRecoveredIfLoadBalancerRemoveIsStarted() {
    // set up the agent first
    sms.resourceOffers(Arrays.asList(createOffer(1, 129, 1025, "agent1", "host1", Optional.of("rack1")))).join();
    initLoadBalancedRequest();
    initLoadBalancedDeploy();
    SingularityTask task = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
    Assertions.assertEquals(1, taskManager.getNumActiveTasks());
    TaskStatus lost = TaskStatus.newBuilder().setTaskId(MesosProtosUtils.toTaskId(task.getMesosTask().getTaskId())).setAgentId(MesosProtosUtils.toAgentId(task.getAgentId())).setReason(Reason.REASON_AGENT_REMOVED).setMessage("health check timed out").setState(TaskState.TASK_LOST).build();
    sms.statusUpdate(lost).join();
    Assertions.assertEquals(0, taskManager.getNumActiveTasks());
    SingularityTaskId taskId = task.getTaskId();
    Assertions.assertTrue(taskManager.getTaskHistory(taskId).isPresent());
    taskManager.saveLoadBalancerState(taskId, LoadBalancerRequestType.REMOVE, new SingularityLoadBalancerUpdate(LoadBalancerRequestState.UNKNOWN, new LoadBalancerRequestId(taskId.getId(), LoadBalancerRequestType.REMOVE, Optional.<Integer>empty()), Optional.empty(), System.currentTimeMillis(), LoadBalancerMethod.DELETE, Optional.empty()));
    TaskStatus recovered = TaskStatus.newBuilder().setTaskId(MesosProtosUtils.toTaskId(task.getMesosTask().getTaskId())).setAgentId(MesosProtosUtils.toAgentId(task.getAgentId())).setReason(Reason.REASON_AGENT_REREGISTERED).setMessage("agent reregistered").setState(TaskState.TASK_RUNNING).build();
    sms.statusUpdate(recovered).join();
    newTaskChecker.getTaskCheckFutures().forEach(f -> {
        try {
            f.get(5, TimeUnit.SECONDS);
        } catch (TimeoutException te) {
        // Didn't see that....
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
    });
    Assertions.assertEquals(1, taskManager.getNumActiveTasks());
    Assertions.assertEquals(0, taskManager.getNumCleanupTasks());
    Assertions.assertEquals(1, requestManager.getSizeOfPendingQueue());
    Assertions.assertTrue(taskManager.getLoadBalancerState(taskId, LoadBalancerRequestType.ADD).isPresent());
}
Also used : SingularityLoadBalancerUpdate(com.hubspot.singularity.SingularityLoadBalancerUpdate) SingularityTask(com.hubspot.singularity.SingularityTask) LoadBalancerRequestId(com.hubspot.singularity.LoadBalancerRequestType.LoadBalancerRequestId) TaskStatus(org.apache.mesos.v1.Protos.TaskStatus) ExecutionException(java.util.concurrent.ExecutionException) SingularityTaskId(com.hubspot.singularity.SingularityTaskId) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.jupiter.api.Test)

Example 17 with Task

use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.

the class SingularitySchedulerTestBase method prepTask.

protected SingularityTask prepTask(SingularityRequest request, SingularityDeploy deploy, long launchTime, int instanceNo, boolean separateHosts, Optional<String> runId, Optional<String> agentAndRack) {
    SingularityPendingTask pendingTask = buildPendingTask(request, deploy, launchTime, instanceNo, runId);
    SingularityTaskRequest taskRequest = new SingularityTaskRequest(request, deploy, pendingTask);
    Offer offer;
    if (separateHosts || agentAndRack.isPresent()) {
        offer = createOffer(125, 1024, 2048, agentAndRack.orElse(String.format("agent%s", instanceNo)), agentAndRack.orElse(String.format("host%s", instanceNo)), agentAndRack);
    } else {
        offer = createOffer(125, 1024, 2048);
    }
    SingularityTaskId taskId = new SingularityTaskId(request.getId(), deploy.getId(), launchTime, instanceNo, offer.getHostname(), agentAndRack.orElse("rack1"));
    TaskID taskIdProto = TaskID.newBuilder().setValue(taskId.toString()).build();
    TaskInfo taskInfo = TaskInfo.newBuilder().setAgentId(offer.getAgentId()).setExecutor(ExecutorInfo.newBuilder().setExecutorId(ExecutorID.newBuilder().setValue("executorID"))).setTaskId(taskIdProto).setName("name").build();
    SingularityTask task = new SingularityTask(taskRequest, taskId, Collections.singletonList(mesosProtosUtils.offerFromProtos(offer)), mesosProtosUtils.taskFromProtos(taskInfo), Optional.of("rack1"));
    taskManager.savePendingTask(pendingTask);
    return task;
}
Also used : TaskInfo(org.apache.mesos.v1.Protos.TaskInfo) TaskID(org.apache.mesos.v1.Protos.TaskID) SingularityTask(com.hubspot.singularity.SingularityTask) Offer(org.apache.mesos.v1.Protos.Offer) SingularityPendingTask(com.hubspot.singularity.SingularityPendingTask) SingularityTaskRequest(com.hubspot.singularity.SingularityTaskRequest) SingularityTaskId(com.hubspot.singularity.SingularityTaskId)

Example 18 with Task

use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.

the class SingularityMesosTaskBuilder method prepareCustomExecutor.

/**
 * Prepares the Mesos TaskInfo object when using our custom SingularityExecutor.
 */
private void prepareCustomExecutor(final TaskInfo.Builder bldr, final SingularityTaskId taskId, final SingularityTaskRequest task, final SingularityOfferHolder offerHolder, final Optional<long[]> ports, final Resources desiredExecutorResources) {
    CommandInfo.Builder commandBuilder = CommandInfo.newBuilder().setValue(task.getDeploy().getCustomExecutorCmd().get());
    prepareEnvironment(task, taskId, commandBuilder, offerHolder, ports);
    if (task.getDeploy().getUser().isPresent()) {
        commandBuilder.setUser(task.getDeploy().getUser().get());
    }
    prepareMesosUriDownloads(task.getPendingTask().getExtraArtifacts(), commandBuilder);
    bldr.setExecutor(ExecutorInfo.newBuilder().setCommand(commandBuilder.build()).setExecutorId(ExecutorID.newBuilder().setValue(task.getDeploy().getCustomExecutorId().orElse(idGenerator.getNextExecutorId()))).setSource(// set source to taskId for use in statistics endpoint, TODO: remove
    task.getDeploy().getCustomExecutorSource().orElse(taskId.getId())).setLabels(Labels.newBuilder().addLabels(Label.newBuilder().setKey("taskId").setValue(taskId.getId()))).addAllResources(buildMesosResources(desiredExecutorResources, task.getRequest().getRequiredRole())).build());
    if (task.getDeploy().getExecutorData().isPresent()) {
        final ExecutorDataBuilder executorDataBldr = task.getDeploy().getExecutorData().get().toBuilder();
        String defaultS3Bucket = "";
        String s3UploaderKeyPattern = "";
        if (configuration.getS3ConfigurationOptional().isPresent()) {
            if (task.getRequest().getGroup().isPresent() && configuration.getS3ConfigurationOptional().get().getGroupOverrides().containsKey(task.getRequest().getGroup().get())) {
                defaultS3Bucket = configuration.getS3ConfigurationOptional().get().getGroupOverrides().get(task.getRequest().getGroup().get()).getS3Bucket();
                LOG.trace("Setting defaultS3Bucket to {} for task {} executorData", defaultS3Bucket, taskId.getId());
            } else {
                defaultS3Bucket = configuration.getS3ConfigurationOptional().get().getS3Bucket();
            }
            s3UploaderKeyPattern = configuration.getS3ConfigurationOptional().get().getS3KeyFormat();
        }
        if (task.getPendingTask().getCmdLineArgsList().isPresent() && !task.getPendingTask().getCmdLineArgsList().get().isEmpty()) {
            LOG.trace("Adding cmd line args {} to task {} executorData", task.getPendingTask().getCmdLineArgsList(), taskId.getId());
            final ImmutableList.Builder<String> extraCmdLineArgsBuilder = ImmutableList.builder();
            if (executorDataBldr.getExtraCmdLineArgs() != null && !executorDataBldr.getExtraCmdLineArgs().isEmpty()) {
                extraCmdLineArgsBuilder.addAll(executorDataBldr.getExtraCmdLineArgs());
            }
            extraCmdLineArgsBuilder.addAll(task.getPendingTask().getCmdLineArgsList().get());
            executorDataBldr.setExtraCmdLineArgs(extraCmdLineArgsBuilder.build());
        }
        List<SingularityS3UploaderFile> uploaderAdditionalFiles = new ArrayList<>();
        if (configuration.getS3ConfigurationOptional().isPresent()) {
            uploaderAdditionalFiles.addAll(configuration.getS3ConfigurationOptional().get().getS3UploaderAdditionalFiles());
        }
        uploaderAdditionalFiles.addAll(task.getPendingTask().getS3UploaderAdditionalFiles());
        uploaderAdditionalFiles.addAll(task.getDeploy().getS3UploaderAdditionalFiles());
        Optional<String> maybeS3StorageClass = configuration.getS3ConfigurationOptional().isPresent() ? configuration.getS3ConfigurationOptional().get().getS3StorageClass() : Optional.<String>empty();
        Optional<Long> maybeApplyAfterBytes = configuration.getS3ConfigurationOptional().isPresent() ? configuration.getS3ConfigurationOptional().get().getApplyS3StorageClassAfterBytes() : Optional.<Long>empty();
        if (task.getPendingTask().getRunAsUserOverride().isPresent()) {
            executorDataBldr.setUser(task.getPendingTask().getRunAsUserOverride());
        }
        Optional<HealthcheckOptions> healthcheckOptions = task.getRequest().getSkipHealthchecks().orElse(false) ? Optional.empty() : task.getDeploy().getHealthcheck();
        final SingularityTaskExecutorData executorData = new SingularityTaskExecutorData(executorDataBldr.build(), uploaderAdditionalFiles, defaultS3Bucket, s3UploaderKeyPattern, configuration.getCustomExecutorConfiguration().getServiceLog(), configuration.getCustomExecutorConfiguration().getServiceFinishedTailLog(), task.getRequest().getGroup(), maybeS3StorageClass, maybeApplyAfterBytes, getCpuHardLimit(task), healthcheckOptions);
        try {
            bldr.setData(ByteString.copyFromUtf8(objectMapper.writeValueAsString(executorData)));
        } catch (JsonProcessingException e) {
            LOG.warn("Unable to process executor data {} for task {} as json (trying as string)", executorData, taskId.getId(), e);
            bldr.setData(ByteString.copyFromUtf8(executorData.toString()));
        }
    } else if (task.getDeploy().getCommand().isPresent()) {
        bldr.setData(ByteString.copyFromUtf8(task.getDeploy().getCommand().get()));
    }
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) ByteString(com.google.protobuf.ByteString) ExecutorDataBuilder(com.hubspot.deploy.ExecutorDataBuilder) SingularityS3UploaderFile(com.hubspot.singularity.SingularityS3UploaderFile) SingularityTaskExecutorData(com.hubspot.singularity.SingularityTaskExecutorData) CommandInfo(org.apache.mesos.v1.Protos.CommandInfo) HealthcheckOptions(com.hubspot.deploy.HealthcheckOptions) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 19 with Task

use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.

the class SingularityOfferHolder method launchTasksAndGetUnusedOffers.

public List<Offer> launchTasksAndGetUnusedOffers(SingularityMesosSchedulerClient schedulerClient) {
    final List<TaskInfo> toLaunch = Lists.newArrayListWithCapacity(acceptedTasks.size());
    final List<SingularityTaskId> taskIds = Lists.newArrayListWithCapacity(acceptedTasks.size());
    for (SingularityMesosTaskHolder taskHolder : acceptedTasks) {
        taskIds.add(taskHolder.getTask().getTaskId());
        toLaunch.add(taskHolder.getMesosTask());
        LOG.debug("Launching {} with possible offers {}", taskHolder.getTask().getTaskId(), MesosUtils.formatOfferIdsForLog(offers));
        LOG.trace("Launching {} mesos task: {}", taskHolder.getTask().getTaskId(), MesosUtils.formatForLogging(taskHolder.getMesosTask()));
    }
    // At this point, `currentResources` contains a list of unused resources, because we subtracted out the required resources of every task we accepted.
    // Let's try and reclaim offers by trying to pull each offer's list of resources out of the combined pool of leftover resources.
    // n.b., This is currently not optimal. We just look through the offers in this instance and try to reclaim them with no particular priority or order.
    Map<Boolean, List<Offer>> partitionedOffers = offers.stream().collect(Collectors.partitioningBy(offer -> {
        List<Long> ports = MesosUtils.getAllPorts(offer.getResourcesList());
        boolean offerCanBeReclaimedFromUnusedResources = offer.getResourcesList().stream().collect(Collectors.groupingBy(Resource::getRole)).entrySet().stream().map(entry -> {
            // Now, for each set of offer Resources grouped by role...
            String role = entry.getKey();
            List<Resource> offerResources = entry.getValue();
            Optional<String> maybeRole = (!role.equals("") && !role.equals("*")) ? Optional.of(role) : Optional.empty();
            // ...Check if we can pull the Resources belonging to this offer out of the pool of `currentResources`.
            return MesosUtils.doesOfferMatchResources(maybeRole, MesosUtils.buildResourcesFromMesosResourceList(offerResources, maybeRole), currentResources, ports);
        }).reduce(true, (x, y) -> x && y);
        if (offerCanBeReclaimedFromUnusedResources) {
            // We can reclaim this offer in its entirety! Pull all of its resources out of the combined pool for this SingularityOfferHolder instance.
            LOG.trace("Able to reclaim offer {} from unused resources in OfferHolder from host {}. cpu: {}, mem: {}, disk: {}", offer.getId().getValue(), offer.getHostname(), MesosUtils.getNumCpus(offer), MesosUtils.getMemory(offer), MesosUtils.getDisk(offer));
            currentResources = MesosUtils.subtractResources(currentResources, offer.getResourcesList());
        }
        return offerCanBeReclaimedFromUnusedResources;
    }));
    List<Offer> leftoverOffers = partitionedOffers.get(true);
    List<Offer> neededOffers = partitionedOffers.get(false);
    schedulerClient.accept(neededOffers.stream().map(Offer::getId).collect(Collectors.toList()), Collections.singletonList(Operation.newBuilder().setType(Type.LAUNCH).setLaunch(Launch.newBuilder().addAllTaskInfos(toLaunch).build()).build()));
    LOG.debug("Launched tasks with offers {}, unused: {}", MesosUtils.formatOfferIdsForLog(neededOffers), MesosUtils.formatOfferIdsForLog(leftoverOffers));
    LOG.info("{} tasks ({}) launched", taskIds.size(), taskIds);
    return leftoverOffers;
}
Also used : Logger(org.slf4j.Logger) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) Offer(org.apache.mesos.v1.Protos.Offer) Protos(org.apache.mesos.v1.Protos) Collectors(java.util.stream.Collectors) SingularityMesosTaskHolder(com.hubspot.singularity.helpers.SingularityMesosTaskHolder) Objects(java.util.Objects) Resource(org.apache.mesos.v1.Protos.Resource) JavaUtils(com.hubspot.mesos.JavaUtils) List(java.util.List) Lists(com.google.common.collect.Lists) MesosUtils(com.hubspot.singularity.helpers.MesosUtils) Launch(org.apache.mesos.v1.Protos.Offer.Operation.Launch) Operation(org.apache.mesos.v1.Protos.Offer.Operation) Map(java.util.Map) TaskInfo(org.apache.mesos.v1.Protos.TaskInfo) Optional(java.util.Optional) Type(org.apache.mesos.v1.Protos.Offer.Operation.Type) Collections(java.util.Collections) SingularityTaskId(com.hubspot.singularity.SingularityTaskId) Resource(org.apache.mesos.v1.Protos.Resource) SingularityMesosTaskHolder(com.hubspot.singularity.helpers.SingularityMesosTaskHolder) TaskInfo(org.apache.mesos.v1.Protos.TaskInfo) Offer(org.apache.mesos.v1.Protos.Offer) List(java.util.List) SingularityTaskId(com.hubspot.singularity.SingularityTaskId)

Example 20 with Task

use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.

the class SingularityTaskSizeOptimizer method getSizeOptimizedTask.

SingularityTask getSizeOptimizedTask(SingularityMesosTaskHolder taskHolder) {
    if (configuration.isStoreAllMesosTaskInfoForDebugging()) {
        return taskHolder.getTask();
    }
    SingularityTask task = taskHolder.getTask();
    TaskInfo.Builder mesosTask = taskHolder.getMesosTask().toBuilder();
    mesosTask.clearData();
    List<MesosOfferObject> offers = task.getOffers().stream().map(MesosOfferObject::sizeOptimized).collect(Collectors.toList());
    SingularityTaskRequest taskRequest = task.getTaskRequest();
    if (task.getTaskRequest().getDeploy().getExecutorData().isPresent()) {
        SingularityDeployBuilder deploy = task.getTaskRequest().getDeploy().toBuilder();
        deploy.setExecutorData(Optional.empty());
        taskRequest = new SingularityTaskRequest(task.getTaskRequest().getRequest(), deploy.build(), task.getTaskRequest().getPendingTask());
    }
    return new SingularityTask(taskRequest, task.getTaskId(), offers, mesosProtosUtils.taskFromProtos(mesosTask.build()), task.getRackId());
}
Also used : TaskInfo(org.apache.mesos.v1.Protos.TaskInfo) MesosOfferObject(com.hubspot.mesos.protos.MesosOfferObject) SingularityTask(com.hubspot.singularity.SingularityTask) SingularityDeployBuilder(com.hubspot.singularity.SingularityDeployBuilder) SingularityTaskRequest(com.hubspot.singularity.SingularityTaskRequest)

Aggregations

SingularityTaskRequest (com.hubspot.singularity.SingularityTaskRequest)11 Test (org.junit.jupiter.api.Test)11 SingularityTask (com.hubspot.singularity.SingularityTask)9 Resources (com.hubspot.mesos.Resources)8 SingularityTaskId (com.hubspot.singularity.SingularityTaskId)8 SingularityMesosTaskHolder (com.hubspot.singularity.helpers.SingularityMesosTaskHolder)8 SingularityDeployBuilder (com.hubspot.singularity.SingularityDeployBuilder)7 SingularityRequest (com.hubspot.singularity.SingularityRequest)7 SingularityDeploy (com.hubspot.singularity.SingularityDeploy)6 SingularityRequestBuilder (com.hubspot.singularity.SingularityRequestBuilder)6 Protos (org.apache.mesos.v1.Protos)5 SingularityContainerInfo (com.hubspot.mesos.SingularityContainerInfo)4 SingularityDockerPortMapping (com.hubspot.mesos.SingularityDockerPortMapping)4 TaskInfo (org.apache.mesos.v1.Protos.TaskInfo)4 ImmutableList (com.google.common.collect.ImmutableList)3 Inject (com.google.inject.Inject)3 ByteString (com.google.protobuf.ByteString)3 JavaUtils (com.hubspot.mesos.JavaUtils)3 SingularityDockerInfo (com.hubspot.mesos.SingularityDockerInfo)3 SingularityPortMapping (com.hubspot.mesos.SingularityPortMapping)3