use of com.mesosphere.sdk.specification.PortSpec in project dcos-commons by mesosphere.
the class PortEvaluationStage method evaluate.
@Override
public EvaluationOutcome evaluate(MesosResourcePool mesosResourcePool, PodInfoBuilder podInfoBuilder) {
long requestedPort = portSpec.getValue().getRanges().getRange(0).getBegin();
long assignedPort = requestedPort;
if (requestedPort == 0) {
// If this is from an existing pod with the dynamic port already assigned and reserved, just keep it.
Optional<Long> priorTaskPort = podInfoBuilder.getPriorPortForTask(getTaskName().get(), portSpec);
if (priorTaskPort.isPresent()) {
// Reuse the prior port value.
assignedPort = priorTaskPort.get();
logger.info("Using previously reserved dynamic port: {}", assignedPort);
} else {
// Choose a new port value.
Optional<Integer> dynamicPort = useHostPorts ? selectDynamicPort(mesosResourcePool, podInfoBuilder) : selectOverlayPort(podInfoBuilder);
if (!dynamicPort.isPresent()) {
return EvaluationOutcome.fail(this, "No ports were available for dynamic claim in offer," + " and no matching port %s was present in prior %s: %s %s", portSpec.getPortName(), getTaskName().isPresent() ? "task " + getTaskName().get() : "executor", TextFormat.shortDebugString(mesosResourcePool.getOffer()), podInfoBuilder.toString()).build();
}
assignedPort = dynamicPort.get();
logger.info("Claiming new dynamic port: {}", assignedPort);
}
}
// Update portSpec to reflect the assigned port value (for example, to reflect a dynamic port allocation):
Protos.Value.Builder valueBuilder = Protos.Value.newBuilder().setType(Protos.Value.Type.RANGES);
valueBuilder.getRangesBuilder().addRangeBuilder().setBegin(assignedPort).setEnd(assignedPort);
PortSpec updatedPortSpec = PortSpec.withValue(portSpec, valueBuilder.build());
if (useHostPorts) {
OfferEvaluationUtils.ReserveEvaluationOutcome reserveEvaluationOutcome = OfferEvaluationUtils.evaluateSimpleResource(this, updatedPortSpec, resourceId, resourceNamespace, mesosResourcePool);
EvaluationOutcome evaluationOutcome = reserveEvaluationOutcome.getEvaluationOutcome();
if (!evaluationOutcome.isPassing()) {
return evaluationOutcome;
}
Optional<String> resourceIdResult = reserveEvaluationOutcome.getResourceId();
setProtos(podInfoBuilder, ResourceBuilder.fromSpec(updatedPortSpec, resourceIdResult, resourceNamespace).build());
return EvaluationOutcome.pass(this, evaluationOutcome.getOfferRecommendations(), "Offer contains required %sport: '%s' with resourceId: '%s'", resourceId.isPresent() ? "previously reserved " : "", assignedPort, resourceId).mesosResource(evaluationOutcome.getMesosResource().get()).build();
} else {
setProtos(podInfoBuilder, ResourceBuilder.fromSpec(updatedPortSpec, resourceId, resourceNamespace).build());
return EvaluationOutcome.pass(this, "Port %s doesn't require resource reservation, ignoring resource requirements and using port %d", portSpec.getPortName(), assignedPort).build();
}
}
use of com.mesosphere.sdk.specification.PortSpec in project dcos-commons by mesosphere.
the class PortEvaluationStage method selectDynamicPort.
private static Optional<Integer> selectDynamicPort(MesosResourcePool mesosResourcePool, PodInfoBuilder podInfoBuilder) {
Set<Integer> consumedPorts = new HashSet<>();
// compile a list of those to check against the offered ports.
for (TaskSpec task : podInfoBuilder.getPodInstance().getPod().getTasks()) {
for (ResourceSpec resourceSpec : task.getResourceSet().getResources()) {
if (resourceSpec instanceof PortSpec) {
PortSpec portSpec = (PortSpec) resourceSpec;
if (portSpec.getPort() != 0) {
consumedPorts.add((int) portSpec.getPort());
}
}
}
}
// Also check other dynamically allocated ports which had been taken by earlier stages of this evaluation round.
for (Protos.Resource.Builder resourceBuilder : podInfoBuilder.getTaskResourceBuilders()) {
consumedPorts.addAll(getPortsInResource(resourceBuilder.build()));
}
for (Protos.Resource.Builder resourceBuilder : podInfoBuilder.getExecutorResourceBuilders()) {
consumedPorts.addAll(getPortsInResource(resourceBuilder.build()));
}
Protos.Value availablePorts = mesosResourcePool.getUnreservedMergedPool().get(Constants.PORTS_RESOURCE_TYPE);
Optional<Integer> dynamicPort = Optional.empty();
if (availablePorts != null) {
dynamicPort = availablePorts.getRanges().getRangeList().stream().flatMap(r -> IntStream.rangeClosed((int) r.getBegin(), (int) r.getEnd()).boxed()).filter(p -> !consumedPorts.contains(p)).findFirst();
}
return dynamicPort;
}
Aggregations