Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.hubspot.singularity.mesos.SingularityMesosTaskBuilder Maven / Gradle / Ivy
package com.hubspot.singularity.mesos;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Ints;
import com.google.inject.Inject;
import com.google.protobuf.ByteString;
import com.hubspot.deploy.ExecutorDataBuilder;
import com.hubspot.deploy.HealthcheckOptions;
import com.hubspot.mesos.Resources;
import com.hubspot.mesos.SingularityAppcImage;
import com.hubspot.mesos.SingularityContainerInfo;
import com.hubspot.mesos.SingularityDockerImage;
import com.hubspot.mesos.SingularityDockerInfo;
import com.hubspot.mesos.SingularityDockerNetworkType;
import com.hubspot.mesos.SingularityDockerParameter;
import com.hubspot.mesos.SingularityDockerPortMapping;
import com.hubspot.mesos.SingularityDockerVolume;
import com.hubspot.mesos.SingularityMesosArtifact;
import com.hubspot.mesos.SingularityMesosImage;
import com.hubspot.mesos.SingularityMesosInfo;
import com.hubspot.mesos.SingularityMesosTaskLabel;
import com.hubspot.mesos.SingularityNetworkInfo;
import com.hubspot.mesos.SingularityPortMapping;
import com.hubspot.mesos.SingularityVolume;
import com.hubspot.mesos.SingularityVolumeSource;
import com.hubspot.singularity.Singularity;
import com.hubspot.singularity.SingularityS3UploaderFile;
import com.hubspot.singularity.SingularityTask;
import com.hubspot.singularity.SingularityTaskExecutorData;
import com.hubspot.singularity.SingularityTaskId;
import com.hubspot.singularity.SingularityTaskRequest;
import com.hubspot.singularity.config.SingularityConfiguration;
import com.hubspot.singularity.data.ExecutorIdGenerator;
import com.hubspot.singularity.helpers.MesosProtosUtils;
import com.hubspot.singularity.helpers.MesosUtils;
import com.hubspot.singularity.helpers.SingularityMesosTaskHolder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.inject.Singleton;
import org.apache.mesos.v1.Protos.CommandInfo;
import org.apache.mesos.v1.Protos.CommandInfo.URI;
import org.apache.mesos.v1.Protos.ContainerInfo;
import org.apache.mesos.v1.Protos.ContainerInfo.DockerInfo;
import org.apache.mesos.v1.Protos.ContainerInfo.MesosInfo;
import org.apache.mesos.v1.Protos.Environment;
import org.apache.mesos.v1.Protos.Environment.Variable;
import org.apache.mesos.v1.Protos.ExecutorID;
import org.apache.mesos.v1.Protos.ExecutorInfo;
import org.apache.mesos.v1.Protos.Image;
import org.apache.mesos.v1.Protos.Label;
import org.apache.mesos.v1.Protos.Labels;
import org.apache.mesos.v1.Protos.Labels.Builder;
import org.apache.mesos.v1.Protos.NetworkInfo;
import org.apache.mesos.v1.Protos.Parameter;
import org.apache.mesos.v1.Protos.Parameters;
import org.apache.mesos.v1.Protos.Resource;
import org.apache.mesos.v1.Protos.TaskID;
import org.apache.mesos.v1.Protos.TaskInfo;
import org.apache.mesos.v1.Protos.Volume;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
class SingularityMesosTaskBuilder {
private static final Logger LOG = LoggerFactory.getLogger(
SingularityMesosTaskBuilder.class
);
private final ObjectMapper objectMapper;
private final ExecutorIdGenerator idGenerator;
private final SingularityConfiguration configuration;
private final MesosProtosUtils mesosProtosUtils;
@Inject
SingularityMesosTaskBuilder(
@Singularity ObjectMapper objectMapper,
ExecutorIdGenerator idGenerator,
SingularityConfiguration configuration,
MesosProtosUtils mesosProtosUtils
) {
this.objectMapper = objectMapper;
this.idGenerator = idGenerator;
this.configuration = configuration;
this.mesosProtosUtils = mesosProtosUtils;
}
public SingularityMesosTaskHolder buildTask(
SingularityOfferHolder offerHolder,
List availableResources,
SingularityTaskRequest taskRequest,
Resources desiredTaskResources,
Resources desiredExecutorResources
) {
final String sanitizedRackId = offerHolder.getSanitizedRackId();
final String sanitizedHost = offerHolder.getSanitizedHost();
final SingularityTaskId taskId = new SingularityTaskId(
taskRequest.getPendingTask().getPendingTaskId().getRequestId(),
taskRequest.getDeploy().getId(),
System.currentTimeMillis(),
taskRequest.getPendingTask().getPendingTaskId().getInstanceNo(),
sanitizedHost,
sanitizedRackId
);
final TaskInfo.Builder bldr = TaskInfo
.newBuilder()
.setTaskId(TaskID.newBuilder().setValue(taskId.toString()));
Optional ports = Optional.empty();
Optional portsResource = Optional.empty();
final Optional containerInfo = taskRequest
.getDeploy()
.getContainerInfo();
if (desiredTaskResources.getNumPorts() > 0 || hasLiteralPortMapping(containerInfo)) {
List requestedPorts = new ArrayList<>();
if (hasLiteralPortMapping(containerInfo)) {
requestedPorts.addAll(
containerInfo.get().getDocker().get().getLiteralHostPorts()
);
}
portsResource =
Optional.of(
MesosUtils.getPortsResource(
desiredTaskResources.getNumPorts(),
availableResources,
requestedPorts
)
);
ports =
Optional.of(
MesosUtils.getPorts(portsResource.get(), desiredTaskResources.getNumPorts())
);
}
if (containerInfo.isPresent()) {
prepareContainerInfo(offerHolder, taskId, bldr, containerInfo.get(), ports);
}
if (taskRequest.getDeploy().getCustomExecutorCmd().isPresent()) {
prepareCustomExecutor(
bldr,
taskId,
taskRequest,
offerHolder,
ports,
desiredExecutorResources
);
} else {
prepareCommand(bldr, taskId, taskRequest, offerHolder, ports);
}
if (portsResource.isPresent()) {
bldr.addResources(portsResource.get());
}
Optional requiredRole = taskRequest.getRequest().getRequiredRole();
bldr.addResources(
MesosUtils.getCpuResource(desiredTaskResources.getCpus(), requiredRole)
);
bldr.addResources(
MesosUtils.getMemoryResource(desiredTaskResources.getMemoryMb(), requiredRole)
);
bldr.addResources(
MesosUtils.getDiskResource(desiredTaskResources.getDiskMb(), requiredRole)
);
bldr.setAgentId(offerHolder.getOffers().get(0).getAgentId());
bldr.setName(taskRequest.getRequest().getId());
final Builder labelsBuilder = Labels.newBuilder();
// apply request-specific labels, if any
if (
taskRequest.getDeploy().getMesosLabels().isPresent() &&
!taskRequest.getDeploy().getMesosLabels().get().isEmpty()
) {
for (SingularityMesosTaskLabel label : taskRequest
.getDeploy()
.getMesosLabels()
.get()) {
org.apache.mesos.v1.Protos.Label.Builder labelBuilder = Label.newBuilder();
labelBuilder.setKey(label.getKey());
if ((label.getValue().isPresent())) {
labelBuilder.setValue(label.getValue().get());
}
labelsBuilder.addLabels(labelBuilder.build());
}
}
// apply task-specific labels, if any
final int taskInstanceNo = taskRequest
.getPendingTask()
.getPendingTaskId()
.getInstanceNo();
if (
taskRequest.getDeploy().getMesosTaskLabels().isPresent() &&
taskRequest.getDeploy().getMesosTaskLabels().get().containsKey(taskInstanceNo) &&
!taskRequest.getDeploy().getMesosTaskLabels().get().get(taskInstanceNo).isEmpty()
) {
for (SingularityMesosTaskLabel label : taskRequest
.getDeploy()
.getMesosTaskLabels()
.get()
.get(taskInstanceNo)) {
org.apache.mesos.v1.Protos.Label.Builder labelBuilder = Label.newBuilder();
labelBuilder.setKey(label.getKey());
if ((label.getValue().isPresent())) {
labelBuilder.setValue(label.getValue().get());
}
labelsBuilder.addLabels(labelBuilder.build());
}
}
bldr.setLabels(labelsBuilder);
TaskInfo task = bldr.build();
return new SingularityMesosTaskHolder(
new SingularityTask(
taskRequest,
taskId,
offerHolder
.getOffers()
.stream()
.map(o -> mesosProtosUtils.offerFromProtos(o))
.collect(Collectors.toList()),
mesosProtosUtils.taskFromProtos(task),
Optional.of(offerHolder.getRackId())
),
task
);
}
private boolean hasLiteralPortMapping(
Optional maybeContainerInfo
) {
return (
maybeContainerInfo.isPresent() &&
maybeContainerInfo.get().getDocker().isPresent() &&
!maybeContainerInfo.get().getDocker().get().getLiteralHostPorts().isEmpty()
);
}
private void setEnv(Environment.Builder envBldr, String key, Object value) {
if (value == null) {
return;
}
envBldr.addVariables(Variable.newBuilder().setName(key).setValue(value.toString()));
}
private void prepareEnvironment(
final SingularityTaskRequest task,
SingularityTaskId taskId,
CommandInfo.Builder commandBuilder,
final SingularityOfferHolder offerHolder,
final Optional ports
) {
Map envVars = new HashMap<>();
envVars.put("INSTANCE_NO", task.getPendingTask().getPendingTaskId().getInstanceNo());
envVars.put("TASK_HOST", offerHolder.getHostname());
envVars.put("TASK_RACK_ID", offerHolder.getRackId());
envVars.put("AVAILABILITY_ZONE", offerHolder.getRackId());
envVars.put(
"TASK_REQUEST_ID",
task.getPendingTask().getPendingTaskId().getRequestId()
);
envVars.put("TASK_DEPLOY_ID", taskId.getDeployId());
envVars.put("TASK_ID", taskId.getId());
envVars.put("ESTIMATED_INSTANCE_COUNT", task.getRequest().getInstancesSafe());
for (Entry envEntry : task
.getDeploy()
.getEnv()
.orElse(Collections.emptyMap())
.entrySet()) {
envVars.put(
envEntry.getKey(),
fillInTaskIdValues(envEntry.getValue(), offerHolder, taskId)
);
}
if (
task.getDeploy().getTaskEnv().isPresent() &&
task.getDeploy().getTaskEnv().get().containsKey(taskId.getInstanceNo()) &&
!task.getDeploy().getTaskEnv().get().get(taskId.getInstanceNo()).isEmpty()
) {
for (Entry envEntry : task
.getDeploy()
.getTaskEnv()
.get()
.get(taskId.getInstanceNo())
.entrySet()) {
envVars.put(
envEntry.getKey(),
fillInTaskIdValues(envEntry.getValue(), offerHolder, taskId)
);
}
}
if (ports.isPresent()) {
for (int portNum = 0; portNum < ports.get().length; portNum++) {
if (portNum == 0) {
envVars.put("PORT", ports.get()[portNum]);
}
envVars.put(String.format("PORT%s", portNum), ports.get()[portNum]);
}
}
if (task.getPendingTask().getResources().isPresent()) {
Resources override = task.getPendingTask().getResources().get();
if (override.getCpus() != 0) {
envVars.put("DEPLOY_CPUS", ((long) override.getCpus()));
}
if (override.getMemoryMb() != 0) {
envVars.put("DEPLOY_MEM", ((long) override.getMemoryMb()));
}
}
for (Entry entry : task.getPendingTask().getEnvOverrides().entrySet()) {
envVars.put(entry.getKey().toString(), entry.getValue());
}
// Set this last so it cannot be overridden by the user
if (task.getPendingTask().getUser().isPresent()) {
envVars.put("STARTED_BY_USER", task.getPendingTask().getUser().get());
}
Environment.Builder envBldr = Environment.newBuilder();
for (Entry entry : envVars.entrySet()) {
setEnv(envBldr, entry.getKey().toString(), entry.getValue());
}
commandBuilder.setEnvironment(envBldr.build());
}
private Optional buildPortMapping(
final SingularityDockerPortMapping singularityDockerPortMapping,
final Optional ports
) {
final int containerPort;
switch (singularityDockerPortMapping.getContainerPortType()) {
case LITERAL:
containerPort = singularityDockerPortMapping.getContainerPort();
break;
case FROM_OFFER:
containerPort =
Ints.checkedCast(ports.get()[singularityDockerPortMapping.getContainerPort()]);
break;
default:
return Optional.empty();
}
final int hostPort;
switch (singularityDockerPortMapping.getHostPortType()) {
case LITERAL:
hostPort = singularityDockerPortMapping.getHostPort();
break;
case FROM_OFFER:
hostPort =
Ints.checkedCast(ports.get()[singularityDockerPortMapping.getHostPort()]);
break;
default:
return Optional.empty();
}
return Optional.of(
DockerInfo
.PortMapping.newBuilder()
.setContainerPort(containerPort)
.setHostPort(hostPort)
.setProtocol(singularityDockerPortMapping.getProtocol())
.build()
);
}
private String fillInTaskIdValues(
String string,
SingularityOfferHolder offerHolder,
SingularityTaskId taskId
) {
if (!Strings.isNullOrEmpty(string)) {
string =
string
.replace("${TASK_REQUEST_ID}", taskId.getRequestId())
.replace("${TASK_DEPLOY_ID}", taskId.getDeployId())
.replace("${TASK_STARTED_AT}", Long.toString(taskId.getStartedAt()))
.replace("${TASK_INSTANCE_NO}", Integer.toString(taskId.getInstanceNo()))
.replace("${TASK_HOST}", offerHolder.getHostname())
.replace("${TASK_RACK_ID}", offerHolder.getRackId())
.replace("${TASK_ID}", taskId.getId());
}
return string;
}
private void prepareContainerInfo(
final SingularityOfferHolder offerHolder,
final SingularityTaskId taskId,
final TaskInfo.Builder bldr,
final SingularityContainerInfo containerInfo,
final Optional ports
) {
ContainerInfo.Builder containerBuilder = ContainerInfo.newBuilder();
containerBuilder.setType(
ContainerInfo.Type.valueOf(containerInfo.getType().toString())
);
final Optional dockerInfo = containerInfo.getDocker();
if (dockerInfo.isPresent()) {
final DockerInfo.Builder dockerInfoBuilder = DockerInfo.newBuilder();
dockerInfoBuilder.setImage(dockerInfo.get().getImage());
if (dockerInfo.get().getNetwork().isPresent()) {
dockerInfoBuilder.setNetwork(
DockerInfo.Network.valueOf(dockerInfo.get().getNetwork().get().toString())
);
}
final List portMappings = dockerInfo
.get()
.getPortMappings();
final boolean isBridged = SingularityDockerNetworkType.BRIDGE.equals(
dockerInfo.get().getNetwork().orElse(null)
);
if (
(dockerInfo.get().hasAllLiteralHostPortMappings() || ports.isPresent()) &&
!portMappings.isEmpty()
) {
for (SingularityDockerPortMapping singularityDockerPortMapping : portMappings) {
final Optional maybePortMapping = buildPortMapping(
singularityDockerPortMapping,
ports
);
if (maybePortMapping.isPresent()) {
dockerInfoBuilder.addPortMappings(maybePortMapping.get());
}
}
} else if (
configuration.getNetworkConfiguration().isDefaultPortMapping() &&
isBridged &&
portMappings.isEmpty() &&
ports.isPresent()
) {
for (long longPort : ports.get()) {
int port = Ints.checkedCast(longPort);
dockerInfoBuilder.addPortMappings(
DockerInfo
.PortMapping.newBuilder()
.setHostPort(port)
.setContainerPort(port)
.build()
);
}
}
if (!dockerInfo.get().getDockerParameters().isEmpty()) {
List parameters = new ArrayList<>();
for (SingularityDockerParameter parameter : dockerInfo
.get()
.getDockerParameters()) {
parameters.add(
Parameter
.newBuilder()
.setKey(parameter.getKey())
.setValue(parameter.getValue())
.build()
);
}
dockerInfoBuilder.addAllParameters(parameters);
}
dockerInfoBuilder.setPrivileged(dockerInfo.get().isPrivileged());
dockerInfoBuilder.setForcePullImage(dockerInfo.get().isForcePullImage());
containerBuilder.setDocker(dockerInfoBuilder);
}
for (SingularityVolume volumeInfo : containerInfo
.getVolumes()
.orElse(Collections.emptyList())) {
final Volume.Builder volumeBuilder = Volume.newBuilder();
volumeBuilder.setContainerPath(
fillInTaskIdValues(volumeInfo.getContainerPath(), offerHolder, taskId)
);
if (volumeInfo.getHostPath().isPresent()) {
volumeBuilder.setHostPath(
fillInTaskIdValues(volumeInfo.getHostPath().get(), offerHolder, taskId)
);
}
if (volumeInfo.getMode().isPresent()) {
volumeBuilder.setMode(Volume.Mode.valueOf(volumeInfo.getMode().get().toString()));
} else {
volumeBuilder.setMode(Volume.Mode.RO);
}
if (volumeInfo.getSource().isPresent()) {
final Volume.Source.Builder sourceBuilder = Volume.Source.newBuilder();
final SingularityVolumeSource source = volumeInfo.getSource().get();
sourceBuilder.setType(Volume.Source.Type.valueOf(source.getType().toString()));
if (source.getDockerVolume().isPresent()) {
final Volume.Source.DockerVolume.Builder dockerVolumeBuilder = Volume.Source.DockerVolume.newBuilder();
final SingularityDockerVolume dockerVolume = source.getDockerVolume().get();
if (dockerVolume.getDriver().isPresent()) {
dockerVolumeBuilder.setDriver(dockerVolume.getDriver().get());
}
if (dockerVolume.getName().isPresent()) {
dockerVolumeBuilder.setName(
dockerVolume
.getName()
.get()
.replace("%i", Integer.toString(taskId.getInstanceNo()))
);
}
if (!dockerVolume.getDriverOptions().isEmpty()) {
final Parameters.Builder parameters = Parameters.newBuilder();
for (Entry option : dockerVolume
.getDriverOptions()
.entrySet()) {
parameters.addParameter(
Parameter
.newBuilder()
.setKey(option.getKey())
.setValue(option.getValue())
.build()
);
}
dockerVolumeBuilder.setDriverOptions(parameters.build());
}
sourceBuilder.setDockerVolume(dockerVolumeBuilder.build());
}
volumeBuilder.setSource(sourceBuilder.build());
}
containerBuilder.addVolumes(volumeBuilder);
}
prepareMesosInfo(containerBuilder, containerInfo);
prepareNetworkInfos(containerBuilder, containerInfo, ports);
bldr.setContainer(containerBuilder);
}
private void prepareMesosInfo(
ContainerInfo.Builder containerBuilder,
final SingularityContainerInfo containerInfo
) {
if (!containerInfo.getMesos().isPresent()) {
return;
}
final MesosInfo.Builder builder = MesosInfo.newBuilder();
final SingularityMesosInfo mesos = containerInfo.getMesos().get();
if (mesos.getImage().isPresent()) {
final SingularityMesosImage image = mesos.getImage().get();
final Image.Builder imageBuilder = Image.newBuilder();
imageBuilder.setType(Image.Type.valueOf(image.getType().toString()));
if (image.getAppc().isPresent()) {
final SingularityAppcImage appc = image.getAppc().get();
final Image.Appc.Builder appcBuilder = Image.Appc.newBuilder();
appcBuilder.setName(appc.getName());
if (appc.getId().isPresent()) {
appcBuilder.setId(appc.getId().get());
}
imageBuilder.setAppc(appcBuilder.build());
}
if (image.getDocker().isPresent()) {
final SingularityDockerImage docker = image.getDocker().get();
final Image.Docker.Builder dockerBuilder = Image.Docker.newBuilder();
dockerBuilder.setName(docker.getName());
imageBuilder.setDocker(dockerBuilder.build());
}
builder.setImage(imageBuilder.build());
}
containerBuilder.setMesos(builder.build());
}
private void prepareNetworkInfos(
ContainerInfo.Builder containerBuilder,
final SingularityContainerInfo containerInfo,
final Optional ports
) {
for (SingularityNetworkInfo netInfo : containerInfo
.getNetworkInfos()
.orElse(Collections.emptyList())) {
final NetworkInfo.Builder netBuilder = NetworkInfo.newBuilder();
if (netInfo.getName().isPresent()) {
netBuilder.setName(netInfo.getName().get());
}
for (String group : netInfo.getGroups().orElse(Collections.emptyList())) {
netBuilder.addGroups(group);
}
for (SingularityPortMapping mapping : netInfo
.getPortMappings()
.orElseGet(defaultPortMappingFor(ports))) {
final NetworkInfo.PortMapping.Builder portBuilder = NetworkInfo.PortMapping.newBuilder();
final int hostPort = mapping.getHostPort();
final int containerPort = mapping.getContainerPort();
final long[] offerPorts = ports.orElse(new long[0]);
portBuilder.setHostPort(
hostPort < offerPorts.length ? (int) offerPorts[hostPort] : hostPort
);
portBuilder.setContainerPort(
containerPort < offerPorts.length
? (int) offerPorts[containerPort]
: containerPort
);
if (mapping.getProtocol().isPresent()) {
portBuilder.setProtocol(mapping.getProtocol().get());
}
netBuilder.addPortMappings(portBuilder.build());
}
containerBuilder.addNetworkInfos(netBuilder.build());
}
}
private Supplier> defaultPortMappingFor(
Optional ports
) {
return new Supplier>() {
@Override
public List get() {
final long[] portArray = ports.orElse(new long[0]);
final List mappings = new ArrayList<>(portArray.length);
for (long port : portArray) {
final int p = (int) port;
mappings.add(new SingularityPortMapping(p, p, Optional.of("tcp")));
mappings.add(new SingularityPortMapping(p, p, Optional.of("udp")));
}
return mappings;
}
};
}
private List buildMesosResources(
final Resources resources,
Optional role
) {
ImmutableList.Builder builder = ImmutableList.builder();
if (resources.getCpus() > 0) {
builder.add(MesosUtils.getCpuResource(resources.getCpus(), role));
}
if (resources.getMemoryMb() > 0) {
builder.add(MesosUtils.getMemoryResource(resources.getMemoryMb(), role));
}
if (resources.getDiskMb() > 0) {
builder.add(MesosUtils.getDiskResource(resources.getDiskMb(), role));
}
return builder.build();
}
/**
* 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 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(task.getDeploy().getCustomExecutorSource().orElse(taskId.getId())) // set source to taskId for use in statistics endpoint, TODO: remove
.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 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 uploaderAdditionalFiles = new ArrayList<>();
if (configuration.getS3ConfigurationOptional().isPresent()) {
uploaderAdditionalFiles.addAll(
configuration.getS3ConfigurationOptional().get().getS3UploaderAdditionalFiles()
);
}
uploaderAdditionalFiles.addAll(
task.getPendingTask().getS3UploaderAdditionalFiles()
);
uploaderAdditionalFiles.addAll(task.getDeploy().getS3UploaderAdditionalFiles());
Optional maybeS3StorageClass = configuration
.getS3ConfigurationOptional()
.isPresent()
? configuration.getS3ConfigurationOptional().get().getS3StorageClass()
: Optional.empty();
Optional maybeApplyAfterBytes = configuration
.getS3ConfigurationOptional()
.isPresent()
? configuration
.getS3ConfigurationOptional()
.get()
.getApplyS3StorageClassAfterBytes()
: Optional.empty();
if (task.getPendingTask().getRunAsUserOverride().isPresent()) {
executorDataBldr.setUser(task.getPendingTask().getRunAsUserOverride());
}
Optional 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()));
}
}
private Optional getCpuHardLimit(SingularityTaskRequest task) {
if (configuration.getCpuHardLimit().isPresent()) {
Optional maybeResources = task
.getPendingTask()
.getResources()
.isPresent()
? task.getPendingTask().getResources()
: task.getDeploy().getResources();
if (maybeResources.isPresent()) {
double requestedCpus = maybeResources.get().getCpus();
int scaledLimit = (int) Math.ceil(
requestedCpus * configuration.getCpuHardLimitScaleFactor()
);
return Optional.of(Math.max(scaledLimit, configuration.getCpuHardLimit().get()));
}
}
return Optional.empty();
}
/**
* Prepares the Mesos TaskInfo object when using the Mesos Default Executor.
*/
private void prepareCommand(
final TaskInfo.Builder bldr,
final SingularityTaskId taskId,
final SingularityTaskRequest task,
final SingularityOfferHolder offerHolder,
final Optional ports
) {
CommandInfo.Builder commandBldr = CommandInfo.newBuilder();
Optional specifiedUser = task
.getPendingTask()
.getRunAsUserOverride()
.isPresent()
? task.getPendingTask().getRunAsUserOverride()
: task.getDeploy().getUser();
if (specifiedUser.isPresent()) {
commandBldr.setUser(specifiedUser.get());
}
if (task.getDeploy().getCommand().isPresent()) {
commandBldr.setValue(task.getDeploy().getCommand().get());
}
if (task.getDeploy().getArguments().isPresent()) {
commandBldr.addAllArguments(task.getDeploy().getArguments().get());
}
if (task.getPendingTask().getCmdLineArgsList().isPresent()) {
commandBldr.addAllArguments(task.getPendingTask().getCmdLineArgsList().get());
}
if (task.getDeploy().getShell().isPresent()) {
commandBldr.setShell(task.getDeploy().getShell().get());
} else if (
(
task.getDeploy().getArguments().isPresent() &&
!task.getDeploy().getArguments().get().isEmpty()
) ||
// Hopefully temporary workaround for
// http://www.mail-archive.com/[email protected] /msg01449.html
task.getDeploy().getContainerInfo().isPresent() ||
(
task.getPendingTask().getCmdLineArgsList().isPresent() &&
!task.getPendingTask().getCmdLineArgsList().get().isEmpty()
)
) {
commandBldr.setShell(false);
}
List combinedArtifacts = new ArrayList<>();
combinedArtifacts.addAll(task.getDeploy().getUris().orElse(Collections.emptyList()));
combinedArtifacts.addAll(task.getPendingTask().getExtraArtifacts());
prepareMesosUriDownloads(combinedArtifacts, commandBldr);
prepareEnvironment(task, taskId, commandBldr, offerHolder, ports);
bldr.setCommand(commandBldr);
}
private void prepareMesosUriDownloads(
List extraArtifacts,
CommandInfo.Builder commandBldr
) {
for (SingularityMesosArtifact artifact : extraArtifacts) {
CommandInfo.URI.Builder uriBldr = URI
.newBuilder()
.setValue(artifact.getUri())
.setCache(artifact.isCache())
.setExecutable(artifact.isExecutable())
.setExtract(artifact.isExtract());
if (artifact.getOutputFile().isPresent()) {
uriBldr.setOutputFile(artifact.getOutputFile().get());
}
commandBldr.addUris(uriBldr.build());
}
}
}