use of com.mesosphere.sdk.scheduler.plan.strategy.SerialStrategy 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.scheduler.plan.strategy.SerialStrategy in project dcos-commons by mesosphere.
the class SchedulerRunner method run.
/**
* Runs the scheduler. Don't forget to call this!
* This should never exit, instead the entire process will be terminated internally.
*/
@Override
public void run() {
SchedulerConfig schedulerConfig = schedulerBuilder.getSchedulerConfig();
ServiceSpec serviceSpec = schedulerBuilder.getServiceSpec();
Persister persister = schedulerBuilder.getPersister();
// Get a curator lock, then check the schema version:
CuratorLocker.lock(serviceSpec.getName(), serviceSpec.getZookeeperConnection());
// Check and/or initialize schema version before doing any other storage access:
new SchemaVersionStore(persister).check(SUPPORTED_SCHEMA_VERSION_SINGLE_SERVICE);
Metrics.configureStatsd(schedulerConfig);
AbstractScheduler scheduler = schedulerBuilder.build();
scheduler.start();
Optional<Scheduler> mesosScheduler = scheduler.getMesosScheduler();
if (mesosScheduler.isPresent()) {
ApiServer apiServer = new ApiServer(schedulerConfig, scheduler.getResources());
apiServer.start(new AbstractLifeCycle.AbstractLifeCycleListener() {
@Override
public void lifeCycleStarted(LifeCycle event) {
scheduler.markApiServerStarted();
}
});
runScheduler(new FrameworkRunner(FrameworkConfig.fromServiceSpec(serviceSpec), PodSpecsCannotUseUnsupportedFeatures.serviceRequestsGpuResources(serviceSpec), schedulerBuilder.isRegionAwarenessEnabled()).getFrameworkInfo(new FrameworkStore(schedulerBuilder.getPersister()).fetchFrameworkId()), mesosScheduler.get(), schedulerBuilder.getServiceSpec(), schedulerBuilder.getSchedulerConfig());
} else {
/**
* If no MesosScheduler is provided this scheduler has been deregistered and should report itself healthy
* and provide an empty COMPLETE deploy plan so it may complete its UNINSTALL.
*
* See {@link UninstallScheduler#getMesosScheduler()}.
*/
Plan emptyDeployPlan = new Plan() {
@Override
public List<Phase> getChildren() {
return Collections.emptyList();
}
@Override
public Strategy<Phase> getStrategy() {
return new SerialStrategy<>();
}
@Override
public UUID getId() {
return UUID.randomUUID();
}
@Override
public String getName() {
return Constants.DEPLOY_PLAN_NAME;
}
@Override
public List<String> getErrors() {
return Collections.emptyList();
}
};
try {
PersisterUtils.clearAllData(persister);
} catch (PersisterException e) {
// Best effort.
LOGGER.error("Failed to clear all data", e);
}
ApiServer apiServer = new ApiServer(schedulerConfig, Arrays.asList(new PlansResource(Collections.singletonList(DefaultPlanManager.createProceeding(emptyDeployPlan))), new HealthResource(Collections.emptyList())));
apiServer.start(new AbstractLifeCycle.AbstractLifeCycleListener() {
@Override
public void lifeCycleStarted(LifeCycle event) {
LOGGER.info("Started trivially healthy API server.");
}
});
}
}
use of com.mesosphere.sdk.scheduler.plan.strategy.SerialStrategy in project dcos-commons by mesosphere.
the class DefaultPhaseTest method testGetStatus.
@Test
public void testGetStatus() {
Step step1 = Mockito.mock(DeploymentStep.class);
Step step2 = Mockito.mock(DeploymentStep.class);
List<Step> steps = Arrays.asList(step1, step2);
final DefaultPhase serialPhase = new DefaultPhase("serial-phase", steps, new SerialStrategy<>(), Collections.emptyList());
when(step1.getPodInstanceRequirement()).thenReturn(Optional.empty());
when(step2.getPodInstanceRequirement()).thenReturn(Optional.empty());
when(step1.getStatus()).thenReturn(Status.PENDING);
when(step2.getStatus()).thenReturn(Status.WAITING);
Assert.assertEquals(Status.PENDING, serialPhase.getStatus());
when(step1.getStatus()).thenReturn(Status.WAITING);
when(step2.getStatus()).thenReturn(Status.WAITING);
final DefaultPhase canaryPhase = new DefaultPhase("canary-phase", steps, new CanaryStrategy(new SerialStrategy<>(), steps), Collections.emptyList());
Assert.assertEquals(Status.WAITING, canaryPhase.getStatus());
}
Aggregations