use of com.netflix.titus.api.model.ApplicationSLA in project titus-control-plane by Netflix.
the class CapacityManagementTest method addCriticalTierJobSla.
/**
* Add new critical tier SLA, which should be persisted in a storage, and should force a scale up of
* a server group.
*/
@Test(timeout = 30_000)
public void addCriticalTierJobSla() {
ApplicationSLA applicationSLA = ApplicationSlaSample.CriticalLarge.build();
String location = client.addApplicationSLA(asRepresentation(applicationSLA)).toBlocking().first();
assertThat(location).contains("/api/v2/management/applications/" + applicationSLA.getAppName());
}
use of com.netflix.titus.api.model.ApplicationSLA in project titus-control-plane by Netflix.
the class InMemoryApplicationSlaStore method remove.
@Override
public Observable<Void> remove(String applicationName) {
return Observable.create(subscriber -> {
synchronized (lock) {
ApplicationSLA result = applicationSLAs.remove(applicationName);
if (result == null) {
subscriber.onError(new NotFoundException(ApplicationSLA.class, applicationName));
} else {
applicationSLAsBySchedulerName.remove(result.getSchedulerName(), result);
subscriber.onCompleted();
}
}
});
}
use of com.netflix.titus.api.model.ApplicationSLA in project titus-control-plane by Netflix.
the class ApplicationSlaManagementResource method getApplicationSLA.
@GET
@Path("/{applicationName}")
@Override
public ApplicationSlaRepresentation getApplicationSLA(@PathParam("applicationName") String applicationName, @QueryParam("extended") boolean extended) {
ApplicationSLA applicationSLA = applicationSlaManagementService.getApplicationSLA(applicationName);
if (applicationSLA == null) {
throw new WebApplicationException(new IllegalArgumentException("SLA not defined for " + applicationName), Status.NOT_FOUND);
}
String cellId = extended ? configuration.getCellName() : null;
ReservationUsage reservationUsage = extended ? reservationUsageCalculator.buildCapacityGroupUsage(applicationName) : null;
return asRepresentation(applicationSLA, cellId, reservationUsage);
}
use of com.netflix.titus.api.model.ApplicationSLA in project titus-control-plane by Netflix.
the class ApplicationSlaManagementResource method removeApplicationSLA.
@DELETE
@Path("/{applicationName}")
@Override
public Response removeApplicationSLA(@PathParam("applicationName") String applicationName) {
if (DEFAULT_APPLICATION.equals(applicationName)) {
throw new WebApplicationException(new IllegalArgumentException("DEFAULT application SLA cannot be removed"), Status.BAD_REQUEST);
}
ApplicationSLA existing = applicationSlaManagementService.getApplicationSLA(applicationName);
if (existing == null) {
throw new WebApplicationException(new IllegalArgumentException("SLA not defined for " + applicationName), Status.NOT_FOUND);
}
applicationSlaManagementService.removeApplicationSLA(applicationName).timeout(1, TimeUnit.MINUTES).toBlocking().firstOrDefault(null);
return Response.status(Status.NO_CONTENT).location(URI.create(PATH_API_V2_MANAGEMENT_APPLICATIONS + '/' + applicationName)).build();
}
use of com.netflix.titus.api.model.ApplicationSLA in project titus-control-plane by Netflix.
the class V1SpecPodFactory method buildV1Pod.
@Override
public V1Pod buildV1Pod(Job<?> job, Task task) {
String taskId = task.getId();
Map<String, String> annotations = createV1SchemaPodAnnotations(job, task);
Pair<V1Affinity, Map<String, String>> affinityWithMetadata = podAffinityFactory.buildV1Affinity(job, task);
annotations.putAll(affinityWithMetadata.getRight());
Pair<List<String>, Map<String, String>> envVarsWithIndex = containerEnvFactory.buildContainerEnv(job, task);
List<V1EnvVar> envVarsList = toV1EnvVar(envVarsWithIndex.getRight());
annotations.put(POD_SYSTEM_ENV_VAR_NAMES, String.join(",", envVarsWithIndex.getLeft()));
Map<String, String> labels = new HashMap<>();
labels.put(KubeConstants.POD_LABEL_JOB_ID, job.getId());
labels.put(KubeConstants.POD_LABEL_TASK_ID, taskId);
JobManagerUtil.getRelocationBinpackMode(job).ifPresent(mode -> labels.put(KubeConstants.POD_LABEL_RELOCATION_BINPACK, mode));
// A V1Container has no room to store the original tag that the Image came from, so we store it as an
// annotation. Only saving the 'main' one for now.
annotations.put(POD_IMAGE_TAG_PREFIX + "main", job.getJobDescriptor().getContainer().getImage().getTag());
JobDescriptor<?> jobDescriptor = job.getJobDescriptor();
String capacityGroup = JobManagerUtil.getCapacityGroupDescriptorName(job.getJobDescriptor(), capacityGroupManagement).toLowerCase();
labels.put(KubeConstants.LABEL_CAPACITY_GROUP, capacityGroup);
V1ObjectMeta metadata = new V1ObjectMeta().name(taskId).namespace(DEFAULT_NAMESPACE).annotations(annotations).labels(labels);
V1Container container = new V1Container().name("main").image(KubePodUtil.buildImageString(configuration.getRegistryUrl(), jobDescriptor.getContainer().getImage())).env(envVarsList).resources(buildV1ResourceRequirements(job.getJobDescriptor().getContainer().getContainerResources())).imagePullPolicy(DEFAULT_IMAGE_PULL_POLICY).volumeMounts(KubePodUtil.buildV1VolumeMounts(job.getJobDescriptor().getContainer().getVolumeMounts()));
Container jobContainer = jobDescriptor.getContainer();
if (CollectionsExt.isNullOrEmpty(jobContainer.getCommand()) && !shouldSkipEntryPointJoin(jobDescriptor.getAttributes())) {
// use the old behavior where the agent needs to do shell splitting
String entrypointStr = StringExt.concatenate(jobContainer.getEntryPoint(), " ");
container.setCommand(Collections.singletonList(entrypointStr));
annotations.put(ENTRYPOINT_SHELL_SPLITTING_ENABLED, "true");
} else {
container.setCommand(jobContainer.getEntryPoint());
container.setArgs(jobContainer.getCommand());
}
List<V1Container> extraContainers = buildV1ExtraContainers(job.getJobDescriptor().getExtraContainers());
List<V1Container> allContainers = Stream.concat(Stream.of(container), extraContainers.stream()).collect(Collectors.toList());
List<V1Volume> volumes = buildV1Volumes(job.getJobDescriptor().getVolumes());
ApplicationSLA capacityGroupDescriptor = JobManagerUtil.getCapacityGroupDescriptor(job.getJobDescriptor(), capacityGroupManagement);
String schedulerName = selectScheduler(schedulerConfiguration, capacityGroupDescriptor, configuration);
V1PodSpec spec = new V1PodSpec().schedulerName(schedulerName).containers(allContainers).volumes(volumes).terminationGracePeriodSeconds(configuration.getPodTerminationGracePeriodSeconds()).restartPolicy(NEVER_RESTART_POLICY).dnsPolicy(DEFAULT_DNS_POLICY).affinity(affinityWithMetadata.getLeft()).tolerations(taintTolerationFactory.buildV1Toleration(job, task)).topologySpreadConstraints(topologyFactory.buildTopologySpreadConstraints(job));
// volumes need to be correctly added to pod spec
Optional<Pair<V1Volume, V1VolumeMount>> optionalEbsVolumeInfo = buildV1EBSObjects(job, task);
if (optionalEbsVolumeInfo.isPresent()) {
spec.addVolumesItem(optionalEbsVolumeInfo.get().getLeft());
container.addVolumeMountsItem(optionalEbsVolumeInfo.get().getRight());
}
appendEfsMounts(spec, container, job);
appendShmMount(spec, container, job);
return new V1Pod().metadata(metadata).spec(spec);
}
Aggregations