use of com.mesosphere.sdk.specification.PodInstance in project dcos-commons by mesosphere.
the class OfferEvaluatorPlacementTest method testColocateAgents.
@Test
public void testColocateAgents() throws Exception {
Protos.Resource offeredCpu = ResourceTestUtils.getUnreservedCpus(2.0);
// Don't launch
PlacementRule placementRule = PlacementUtils.getAgentPlacementRule(Collections.emptyList(), Arrays.asList("some-random-agent")).get();
PodSpec podSpec = PodInstanceRequirementTestUtils.getCpuRequirement(1.0).getPodInstance().getPod();
podSpec = DefaultPodSpec.newBuilder(podSpec).placementRule(placementRule).build();
PodInstance podInstance = new DefaultPodInstance(podSpec, 0);
PodInstanceRequirement podInstanceRequirement = PodInstanceRequirement.newBuilder(podInstance, Arrays.asList(TestConstants.TASK_NAME)).build();
List<OfferRecommendation> recommendations = evaluator.evaluate(podInstanceRequirement, Arrays.asList(OfferTestUtils.getCompleteOffer(offeredCpu)));
Assert.assertEquals(0, recommendations.size());
// Launch
placementRule = PlacementUtils.getAgentPlacementRule(Collections.emptyList(), Arrays.asList(TestConstants.AGENT_ID.getValue())).get();
podSpec = DefaultPodSpec.newBuilder(podSpec).placementRule(placementRule).build();
podInstance = new DefaultPodInstance(podSpec, 0);
podInstanceRequirement = PodInstanceRequirement.newBuilder(podInstance, Arrays.asList(TestConstants.TASK_NAME)).build();
recommendations = evaluator.evaluate(podInstanceRequirement, Arrays.asList(OfferTestUtils.getCompleteOffer(offeredCpu)));
Assert.assertEquals(5, recommendations.size());
}
use of com.mesosphere.sdk.specification.PodInstance in project dcos-commons by mesosphere.
the class OfferEvaluatorPlacementTest method testAvoidAgents.
@Test
public void testAvoidAgents() throws Exception {
Protos.Resource offeredCpu = ResourceTestUtils.getUnreservedCpus(2.0);
// Don't launch
PlacementRule placementRule = PlacementUtils.getAgentPlacementRule(Arrays.asList(TestConstants.AGENT_ID.getValue()), Collections.emptyList()).get();
PodSpec podSpec = PodInstanceRequirementTestUtils.getCpuRequirement(1.0).getPodInstance().getPod();
podSpec = DefaultPodSpec.newBuilder(podSpec).placementRule(placementRule).build();
PodInstance podInstance = new DefaultPodInstance(podSpec, 0);
PodInstanceRequirement podInstanceRequirement = PodInstanceRequirement.newBuilder(podInstance, Arrays.asList(TestConstants.TASK_NAME)).build();
List<OfferRecommendation> recommendations = evaluator.evaluate(podInstanceRequirement, Arrays.asList(OfferTestUtils.getCompleteOffer(offeredCpu)));
Assert.assertEquals(0, recommendations.size());
// Launch
placementRule = PlacementUtils.getAgentPlacementRule(Arrays.asList("some-random-agent"), Collections.emptyList()).get();
podSpec = DefaultPodSpec.newBuilder(podSpec).placementRule(placementRule).build();
podInstance = new DefaultPodInstance(podSpec, 0);
podInstanceRequirement = PodInstanceRequirement.newBuilder(podInstance, Arrays.asList(TestConstants.TASK_NAME)).build();
recommendations = evaluator.evaluate(podInstanceRequirement, Arrays.asList(OfferTestUtils.getCompleteOffer(offeredCpu)));
Assert.assertEquals(5, recommendations.size());
}
use of com.mesosphere.sdk.specification.PodInstance in project dcos-commons by mesosphere.
the class CassandraRecoveryPlanOverrider method getNodeRecoveryPhase.
private Phase getNodeRecoveryPhase(Plan inputPlan, int index) {
Phase inputPhase = inputPlan.getChildren().get(0);
Step inputLaunchStep = inputPhase.getChildren().get(index);
// Dig all the way down into the command, so we can append the replace_address option to it.
PodInstance podInstance = inputLaunchStep.start().get().getPodInstance();
PodSpec podSpec = podInstance.getPod();
TaskSpec taskSpec = podSpec.getTasks().stream().filter(t -> t.getName().equals("server")).findFirst().get();
CommandSpec command = taskSpec.getCommand().get();
// Get IP address for the pre-existing node.
Optional<Protos.TaskStatus> status = StateStoreUtils.getTaskStatusFromProperty(stateStore, TaskSpec.getInstanceName(podInstance, taskSpec));
if (!status.isPresent()) {
logger.error("No previously stored TaskStatus to pull IP address from in Cassandra recovery");
return null;
}
String replaceIp = status.get().getContainerStatus().getNetworkInfos(0).getIpAddresses(0).getIpAddress();
DefaultCommandSpec.Builder builder = DefaultCommandSpec.newBuilder(command);
builder.value(String.format("%s -Dcassandra.replace_address=%s -Dcassandra.consistent.rangemovement=false%n", command.getValue().trim(), replaceIp));
// Rebuild a new PodSpec with the modified command, and add it to the phase we return.
TaskSpec newTaskSpec = DefaultTaskSpec.newBuilder(taskSpec).commandSpec(builder.build()).build();
List<TaskSpec> tasks = podSpec.getTasks().stream().map(t -> {
if (t.getName().equals(newTaskSpec.getName())) {
return newTaskSpec;
}
return t;
}).collect(Collectors.toList());
PodSpec newPodSpec = DefaultPodSpec.newBuilder(podSpec).tasks(tasks).build();
PodInstance newPodInstance = new DefaultPodInstance(newPodSpec, index);
PodInstanceRequirement replacePodInstanceRequirement = PodInstanceRequirement.newBuilder(newPodInstance, inputLaunchStep.getPodInstanceRequirement().get().getTasksToLaunch()).recoveryType(RecoveryType.PERMANENT).build();
Step replaceStep = new RecoveryStep(inputLaunchStep.getName(), replacePodInstanceRequirement, new UnconstrainedLaunchConstrainer(), stateStore);
List<Step> steps = new ArrayList<>();
steps.add(replaceStep);
// Restart all other nodes if replacing a seed node to refresh IP resolution
int replaceIndex = replaceStep.getPodInstanceRequirement().get().getPodInstance().getIndex();
if (CassandraSeedUtils.isSeedNode(replaceIndex)) {
logger.info("Scheduling restart of all nodes other than 'node-{}' to refresh seed node address.", replaceIndex);
List<Step> restartSteps = inputPhase.getChildren().stream().filter(step -> step.getPodInstanceRequirement().get().getPodInstance().getIndex() != replaceIndex).map(step -> {
PodInstanceRequirement restartPodInstanceRequirement = PodInstanceRequirement.newBuilder(step.getPodInstanceRequirement().get().getPodInstance(), step.getPodInstanceRequirement().get().getTasksToLaunch()).recoveryType(RecoveryType.TRANSIENT).build();
return new RecoveryStep(step.getName(), restartPodInstanceRequirement, new UnconstrainedLaunchConstrainer(), stateStore);
}).collect(Collectors.toList());
steps.addAll(restartSteps);
}
return new DefaultPhase(RECOVERY_PHASE_NAME, steps, new SerialStrategy<>(), Collections.emptyList());
}
use of com.mesosphere.sdk.specification.PodInstance in project dcos-commons by mesosphere.
the class RoundRobinByAttributeRuleTest method testRolloutWithAgentCount.
@Test
public void testRolloutWithAgentCount() throws TaskException, InvalidRequirementException {
PlacementRule rule = new RoundRobinByAttributeRule(ATTRIB_NAME, Optional.of(3), MATCHER);
// throw in some preexisting tasks to be ignored by our matcher:
List<TaskInfo> tasks = new ArrayList<>();
tasks.add(getTaskInfo("ignored1", "value1"));
tasks.add(getTaskInfo("ignored2", "value2"));
tasks.add(getTaskInfo("ignored3", "value3"));
tasks.add(getTaskInfo("ignored4", "value4"));
tasks.add(getTaskInfo("ignored5", "value5"));
tasks.add(getTaskInfo("ignored6", "foo", "value6"));
tasks.add(getTaskInfo("ignored7", "bar", "value7"));
tasks.add(getTaskInfo("ignored8", "baz", "value8"));
// 1st task fits on value1:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
TaskInfo taskInfo1 = getTaskInfo("1", "value1");
PodInstance req1 = getPodInstance(taskInfo1);
// value1:1
tasks.add(taskInfo1);
// 2nd task doesn't fit on value1 which already has something, but does fit on value2/value3:
EvaluationOutcome outcome = rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks);
assertFalse(outcome.toString(), outcome.isPassing());
assertTrue(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
TaskInfo taskInfo2 = getTaskInfo("2", "value3");
PodInstance req2 = getPodInstance(taskInfo2);
// value1:1, value3:1
tasks.add(taskInfo2);
// duplicates of preexisting tasks 1/3 fit on their previous values:
assertTrue(rule.filter(offerWithAttribute("value1"), req1, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), req2, tasks).isPassing());
// 3rd task doesnt fit on value1/value3, does fit on value2:
assertFalse(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertFalse(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:1, value3:1
tasks.add(getTaskInfo("3", "value2"));
// 4th task fits on any value as the three values now have the same size:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:2, value3:1
tasks.add(getTaskInfo("4", "value2"));
// 5th task doesn't fit on value2 but does fit on value1/value3:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
assertFalse(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:2, value3:2
tasks.add(getTaskInfo("5", "value3"));
// 6th task is launched on erroneous value4 (host4 shouldn't exist: we were told there were only 3 values!)
assertTrue(rule.filter(offerWithAttribute("value4"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:2, value3:2, value4:1
tasks.add(getTaskInfo("6", "value4"));
// 7th task is launched on value4 as well:
assertTrue(rule.filter(offerWithAttribute("value4"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:2, value3:2, value4:2
tasks.add(getTaskInfo("7", "value4"));
// 8th task fails to launch on values2-4 as they now all have more occupancy than value1:
assertFalse(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertFalse(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
assertFalse(rule.filter(offerWithAttribute("value4"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
// value1:2, value2:2, value3:2, value4:2
tasks.add(getTaskInfo("8", "value1"));
// now all values1-4 have equal occupancy = 2. adding a task to any of them should work:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value4"), POD_INSTANCE, tasks).isPassing());
}
use of com.mesosphere.sdk.specification.PodInstance in project dcos-commons by mesosphere.
the class RoundRobinByAttributeRuleTest method testRolloutWithoutAgentCount.
@Test
public void testRolloutWithoutAgentCount() throws TaskException, InvalidRequirementException {
PlacementRule rule = new RoundRobinByAttributeRule(ATTRIB_NAME, Optional.empty(), MATCHER);
// throw in some preexisting tasks to be ignored by our matcher:
List<TaskInfo> tasks = new ArrayList<>();
tasks.add(getTaskInfo("ignored1", "value1"));
tasks.add(getTaskInfo("ignored2", "value2"));
tasks.add(getTaskInfo("ignored3", "value3"));
tasks.add(getTaskInfo("ignored4", "value4"));
tasks.add(getTaskInfo("ignored5", "value5"));
tasks.add(getTaskInfo("ignored6", "foo", "value6"));
tasks.add(getTaskInfo("ignored7", "bar", "value7"));
tasks.add(getTaskInfo("ignored8", "baz", "value8"));
// 1st task fits on value1:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
TaskInfo taskInfo1 = getTaskInfo("1", "value1");
PodInstance req1 = getPodInstance(taskInfo1);
// value1:1
tasks.add(taskInfo1);
// 2nd task fits on any of value1/value2/value3, as we don't yet know of other valid values:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
TaskInfo taskInfo2 = getTaskInfo("2", "value3");
PodInstance req2 = getPodInstance(taskInfo2);
// value1:1, value3:1
tasks.add(taskInfo2);
// duplicates of preexisting tasks 1/3 fit on their previous values:
assertTrue(rule.filter(offerWithAttribute("value1"), req1, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), req2, tasks).isPassing());
// 3rd task fits on any of value1/value2/value3, as all known values have the same amount:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:1, value3:1
tasks.add(getTaskInfo("3", "value2"));
// 4th task fits on any of value1/value2/value3, as all known values have the same amount:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:2, value3:1
tasks.add(getTaskInfo("4", "value2"));
// 5th task doesn't fit on value2 but does fit on value1/value3:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
assertFalse(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:2, value3:2
tasks.add(getTaskInfo("5", "value3"));
// 6th task is launched on new value4:
assertTrue(rule.filter(offerWithAttribute("value4"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:2, value3:2, value4:1
tasks.add(getTaskInfo("6", "value4"));
// 7th task is launched on new value4 as well:
assertTrue(rule.filter(offerWithAttribute("value4"), POD_INSTANCE, tasks).isPassing());
// value1:1, value2:2, value3:2, value4:2
tasks.add(getTaskInfo("7", "value4"));
// 8th task fails to launch on values2-4 as they now all have more occupancy than value1:
assertFalse(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertFalse(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
assertFalse(rule.filter(offerWithAttribute("value4"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
// value1:2, value2:2, value3:2, value4:2
tasks.add(getTaskInfo("8", "value1"));
// now all values1-4 have equal occupancy = 2. adding a task to any of them should work:
assertTrue(rule.filter(offerWithAttribute("value1"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value2"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value3"), POD_INSTANCE, tasks).isPassing());
assertTrue(rule.filter(offerWithAttribute("value4"), POD_INSTANCE, tasks).isPassing());
}
Aggregations