Search in sources :

Example 26 with SingularityDeploy

use of com.hubspot.singularity.SingularityDeploy in project Singularity by HubSpot.

the class DeployResource method deploy.

public SingularityRequestParent deploy(SingularityDeployRequest deployRequest, SingularityUser user) {
    validator.checkActionEnabled(SingularityAction.DEPLOY);
    SingularityDeploy deploy = deployRequest.getDeploy();
    checkNotNullBadRequest(deploy, "DeployRequest must have a deploy object");
    final Optional<String> deployUser = user.getEmail();
    final String requestId = checkNotNullBadRequest(deploy.getRequestId(), "DeployRequest must have a non-null requestId");
    SingularityRequestWithState requestWithState = fetchRequestWithState(requestId, user);
    authorizationHelper.checkForAuthorization(requestWithState.getRequest(), user, SingularityAuthorizationScope.WRITE);
    SingularityRequest request = requestWithState.getRequest();
    final Optional<SingularityRequest> updatedValidatedRequest;
    if (deployRequest.getUpdatedRequest().isPresent()) {
        authorizationHelper.checkForAuthorizedChanges(deployRequest.getUpdatedRequest().get(), requestWithState.getRequest(), user);
        updatedValidatedRequest = Optional.of(validator.checkSingularityRequest(deployRequest.getUpdatedRequest().get(), Optional.of(requestWithState.getRequest()), Optional.<SingularityDeploy>absent(), Optional.of(deploy)));
    } else {
        updatedValidatedRequest = Optional.absent();
    }
    if (updatedValidatedRequest.isPresent()) {
        request = updatedValidatedRequest.get();
    }
    validator.checkScale(request, Optional.of(taskManager.getActiveTaskIdsForRequest(request.getId()).size()));
    if (!deployRequest.isUnpauseOnSuccessfulDeploy() && !configuration.isAllowDeployOfPausedRequests()) {
        checkConflict(requestWithState.getState() != RequestState.PAUSED, "Request %s is paused. Unable to deploy (it must be manually unpaused first)", requestWithState.getRequest().getId());
    }
    deploy = validator.checkDeploy(request, deploy, taskManager.getActiveTaskIdsForRequest(requestId), taskManager.getPendingTaskIdsForRequest(requestId));
    final long now = System.currentTimeMillis();
    SingularityDeployMarker deployMarker = new SingularityDeployMarker(requestId, deploy.getId(), now, deployUser, deployRequest.getMessage());
    Optional<SingularityDeployProgress> deployProgress = Optional.absent();
    if (request.isLongRunning()) {
        deployProgress = Optional.of(new SingularityDeployProgress(Math.min(deploy.getDeployInstanceCountPerStep().or(request.getInstancesSafe()), request.getInstancesSafe()), 0, deploy.getDeployInstanceCountPerStep().or(request.getInstancesSafe()), deploy.getDeployStepWaitTimeMs().or(configuration.getDefaultDeployStepWaitTimeMs()), false, deploy.getAutoAdvanceDeploySteps().or(true), Collections.emptySet(), System.currentTimeMillis()));
    }
    SingularityPendingDeploy pendingDeployObj = new SingularityPendingDeploy(deployMarker, Optional.<SingularityLoadBalancerUpdate>absent(), DeployState.WAITING, deployProgress, updatedValidatedRequest);
    boolean deployToUnpause = false;
    if (requestWithState.getState() == RequestState.PAUSED && deployRequest.isUnpauseOnSuccessfulDeploy()) {
        deployToUnpause = true;
        requestManager.deployToUnpause(request, now, deployUser, deployRequest.getMessage());
    }
    boolean deployAlreadyInProgress = deployManager.createPendingDeploy(pendingDeployObj) == SingularityCreateResult.EXISTED;
    if (deployAlreadyInProgress && deployToUnpause) {
        requestManager.pause(request, now, deployUser, Optional.absent());
    }
    checkConflict(!deployAlreadyInProgress, "Pending deploy already in progress for %s - cancel it or wait for it to complete (%s)", requestId, deployManager.getPendingDeploy(requestId).orNull());
    deployManager.saveDeploy(request, deployMarker, deploy);
    if (request.isDeployable() && !(requestWithState.getState() == RequestState.PAUSED && configuration.isAllowDeployOfPausedRequests())) {
        requestManager.addToPendingQueue(new SingularityPendingRequest(requestId, deployMarker.getDeployId(), now, deployUser, PendingType.NEW_DEPLOY, deployRequest.getDeploy().getSkipHealthchecksOnDeploy(), deployRequest.getMessage()));
    }
    return fillEntireRequest(requestWithState, Optional.of(request));
}
Also used : SingularityPendingRequest(com.hubspot.singularity.SingularityPendingRequest) SingularityDeployMarker(com.hubspot.singularity.SingularityDeployMarker) SingularityRequest(com.hubspot.singularity.SingularityRequest) SingularityDeployProgress(com.hubspot.singularity.SingularityDeployProgress) SingularityDeploy(com.hubspot.singularity.SingularityDeploy) SingularityPendingDeploy(com.hubspot.singularity.SingularityPendingDeploy) SingularityRequestWithState(com.hubspot.singularity.SingularityRequestWithState)

Example 27 with SingularityDeploy

use of com.hubspot.singularity.SingularityDeploy in project Singularity by HubSpot.

the class SingularityUsagePoller method getClusterUtilization.

private SingularityClusterUtilization getClusterUtilization(Map<String, RequestUtilization> utilizationPerRequestId, long totalMemBytesUsed, long totalMemBytesAvailable, double totalCpuUsed, double totalCpuAvailable, long totalDiskBytesUsed, long totalDiskBytesAvailable, long now) {
    int numRequestsWithUnderUtilizedCpu = 0;
    int numRequestsWithOverUtilizedCpu = 0;
    int numRequestsWithUnderUtilizedMemBytes = 0;
    int numRequestsWithUnderUtilizedDiskBytes = 0;
    double totalUnderUtilizedCpu = 0;
    double totalOverUtilizedCpu = 0;
    long totalUnderUtilizedMemBytes = 0;
    long totalUnderUtilizedDiskBytes = 0;
    double maxUnderUtilizedCpu = 0;
    double maxOverUtilizedCpu = 0;
    long maxUnderUtilizedMemBytes = 0;
    long maxUnderUtilizedDiskBytes = 0;
    String maxUnderUtilizedCpuRequestId = null;
    String maxOverUtilizedCpuRequestId = null;
    String maxUnderUtilizedMemBytesRequestId = null;
    String maxUnderUtilizedDiskBytesRequestId = null;
    double minUnderUtilizedCpu = Double.MAX_VALUE;
    double minOverUtilizedCpu = Double.MAX_VALUE;
    long minUnderUtilizedMemBytes = Long.MAX_VALUE;
    long minUnderUtilizedDiskBytes = Long.MAX_VALUE;
    for (RequestUtilization utilization : utilizationPerRequestId.values()) {
        Optional<SingularityDeploy> maybeDeploy = deployManager.getDeploy(utilization.getRequestId(), utilization.getDeployId());
        if (maybeDeploy.isPresent() && maybeDeploy.get().getResources().isPresent()) {
            String requestId = utilization.getRequestId();
            long memoryBytesReserved = (long) (maybeDeploy.get().getResources().get().getMemoryMb() * SingularitySlaveUsage.BYTES_PER_MEGABYTE);
            double cpuReserved = maybeDeploy.get().getResources().get().getCpus();
            long diskBytesReserved = (long) maybeDeploy.get().getResources().get().getDiskMb() * SingularitySlaveUsage.BYTES_PER_MEGABYTE;
            double unusedCpu = cpuReserved - utilization.getAvgCpuUsed();
            long unusedMemBytes = (long) (memoryBytesReserved - utilization.getAvgMemBytesUsed());
            long unusedDiskBytes = (long) (diskBytesReserved - utilization.getAvgDiskBytesUsed());
            if (unusedCpu > 0) {
                numRequestsWithUnderUtilizedCpu++;
                totalUnderUtilizedCpu += unusedCpu;
                if (unusedCpu > maxUnderUtilizedCpu) {
                    maxUnderUtilizedCpu = unusedCpu;
                    maxUnderUtilizedCpuRequestId = requestId;
                }
                minUnderUtilizedCpu = Math.min(unusedCpu, minUnderUtilizedCpu);
            } else if (unusedCpu < 0) {
                double overusedCpu = Math.abs(unusedCpu);
                numRequestsWithOverUtilizedCpu++;
                totalOverUtilizedCpu += overusedCpu;
                if (overusedCpu > maxOverUtilizedCpu) {
                    maxOverUtilizedCpu = overusedCpu;
                    maxOverUtilizedCpuRequestId = requestId;
                }
                minOverUtilizedCpu = Math.min(overusedCpu, minOverUtilizedCpu);
            }
            if (unusedMemBytes > 0) {
                numRequestsWithUnderUtilizedMemBytes++;
                totalUnderUtilizedMemBytes += unusedMemBytes;
                if (unusedMemBytes > maxUnderUtilizedMemBytes) {
                    maxUnderUtilizedMemBytes = unusedMemBytes;
                    maxUnderUtilizedMemBytesRequestId = requestId;
                }
                minUnderUtilizedMemBytes = Math.min(unusedMemBytes, minUnderUtilizedMemBytes);
            }
            if (unusedDiskBytes > 0) {
                numRequestsWithUnderUtilizedDiskBytes++;
                totalUnderUtilizedDiskBytes += unusedDiskBytes;
                if (unusedDiskBytes > maxUnderUtilizedDiskBytes) {
                    maxUnderUtilizedDiskBytes = unusedDiskBytes;
                    maxUnderUtilizedDiskBytesRequestId = requestId;
                }
                minUnderUtilizedDiskBytes = Math.min(unusedDiskBytes, minUnderUtilizedMemBytes);
            }
        }
    }
    double avgUnderUtilizedCpu = numRequestsWithUnderUtilizedCpu != 0 ? totalUnderUtilizedCpu / numRequestsWithUnderUtilizedCpu : 0;
    double avgOverUtilizedCpu = numRequestsWithOverUtilizedCpu != 0 ? totalOverUtilizedCpu / numRequestsWithOverUtilizedCpu : 0;
    long avgUnderUtilizedMemBytes = numRequestsWithUnderUtilizedMemBytes != 0 ? totalUnderUtilizedMemBytes / numRequestsWithUnderUtilizedMemBytes : 0;
    long avgUnderUtilizedDiskBytes = numRequestsWithUnderUtilizedDiskBytes != 0 ? totalUnderUtilizedDiskBytes / numRequestsWithUnderUtilizedDiskBytes : 0;
    return new SingularityClusterUtilization(new ArrayList<>(utilizationPerRequestId.values()), numRequestsWithUnderUtilizedCpu, numRequestsWithOverUtilizedCpu, numRequestsWithUnderUtilizedMemBytes, numRequestsWithUnderUtilizedDiskBytes, totalUnderUtilizedCpu, totalOverUtilizedCpu, totalUnderUtilizedMemBytes, totalUnderUtilizedDiskBytes, avgUnderUtilizedCpu, avgOverUtilizedCpu, avgUnderUtilizedMemBytes, avgUnderUtilizedDiskBytes, maxUnderUtilizedCpu, maxOverUtilizedCpu, maxUnderUtilizedMemBytes, maxUnderUtilizedDiskBytes, maxUnderUtilizedCpuRequestId, maxOverUtilizedCpuRequestId, maxUnderUtilizedMemBytesRequestId, maxUnderUtilizedDiskBytesRequestId, getMin(minUnderUtilizedCpu), getMin(minOverUtilizedCpu), getMin(minUnderUtilizedMemBytes), getMin(minUnderUtilizedDiskBytes), totalMemBytesUsed, totalMemBytesAvailable, totalDiskBytesUsed, totalDiskBytesAvailable, totalCpuUsed, totalCpuAvailable, now);
}
Also used : RequestUtilization(com.hubspot.singularity.RequestUtilization) SingularityClusterUtilization(com.hubspot.singularity.SingularityClusterUtilization) SingularityDeploy(com.hubspot.singularity.SingularityDeploy)

Example 28 with SingularityDeploy

use of com.hubspot.singularity.SingularityDeploy in project Singularity by HubSpot.

the class SingularityCleaner method createLbCleanupRequest.

private void createLbCleanupRequest(String requestId, Iterable<SingularityTaskId> matchingActiveTaskIds) {
    Optional<String> maybeCurrentDeployId = deployManager.getInUseDeployId(requestId);
    Optional<SingularityDeploy> maybeDeploy = Optional.absent();
    if (maybeCurrentDeployId.isPresent()) {
        maybeDeploy = deployManager.getDeploy(requestId, maybeCurrentDeployId.get());
        if (maybeDeploy.isPresent()) {
            List<String> taskIds = new ArrayList<>();
            for (SingularityTaskId taskId : matchingActiveTaskIds) {
                taskIds.add(taskId.getId());
            }
            requestManager.saveLbCleanupRequest(new SingularityRequestLbCleanup(requestId, maybeDeploy.get().getLoadBalancerGroups().get(), maybeDeploy.get().getServiceBasePath().get(), taskIds, Optional.absent()));
            return;
        }
    }
    exceptionNotifier.notify("Insufficient data to create LB request cleanup", ImmutableMap.of("requestId", requestId, "deployId", maybeCurrentDeployId.toString(), "deploy", maybeDeploy.toString()));
}
Also used : ArrayList(java.util.ArrayList) SingularityDeploy(com.hubspot.singularity.SingularityDeploy) SingularityTaskId(com.hubspot.singularity.SingularityTaskId) SingularityRequestLbCleanup(com.hubspot.singularity.SingularityRequestLbCleanup)

Example 29 with SingularityDeploy

use of com.hubspot.singularity.SingularityDeploy in project Singularity by HubSpot.

the class SingularityCleaner method shouldKillTask.

private boolean shouldKillTask(SingularityTaskCleanup taskCleanup, List<SingularityTaskId> activeTaskIds, Set<SingularityTaskId> cleaningTasks, Multiset<SingularityDeployKey> incrementalCleaningTasks) {
    final Optional<SingularityRequestWithState> requestWithState = requestManager.getRequest(taskCleanup.getTaskId().getRequestId());
    if (!requestWithState.isPresent()) {
        LOG.debug("Killing a task {} immediately because the request was missing", taskCleanup);
        return true;
    }
    final SingularityRequest request = requestWithState.get().getRequest();
    if (taskCleanup.getRunBeforeKillId().isPresent()) {
        List<SingularityTaskShellCommandUpdate> shellCommandUpdates = taskManager.getTaskShellCommandUpdates(taskCleanup.getRunBeforeKillId().get());
        boolean finished = false;
        for (SingularityTaskShellCommandUpdate update : shellCommandUpdates) {
            if (update.getUpdateType().isFinished()) {
                finished = true;
                break;
            }
        }
        if (!finished) {
            LOG.debug("Waiting for pre-kill shell command {} to finish before killing task", taskCleanup.getRunBeforeKillId());
            return false;
        }
    }
    if (taskCleanup.getCleanupType().shouldKillTaskInstantly(request)) {
        LOG.debug("Killing a task {} immediately because of its cleanup type", taskCleanup);
        return true;
    }
    // If pausing, must be a long-running task to kill here
    if (requestWithState.get().getState() == RequestState.PAUSED && (!(taskCleanup.getCleanupType() == TaskCleanupType.PAUSING) || request.isLongRunning())) {
        LOG.debug("Killing a task {} immediately because the request was paused", taskCleanup);
        return true;
    }
    if (!request.isLongRunning()) {
        final long timeSinceCleanup = System.currentTimeMillis() - taskCleanup.getTimestamp();
        final long maxWaitTime = request.getKillOldNonLongRunningTasksAfterMillis().or(killNonLongRunningTasksInCleanupAfterMillis);
        final boolean tooOld = (maxWaitTime < 1) || (timeSinceCleanup > maxWaitTime);
        if (!tooOld) {
            LOG.trace("Not killing a non-longRunning task {}, running time since cleanup {} (max wait time is {})", taskCleanup, timeSinceCleanup, maxWaitTime);
        } else {
            LOG.debug("Killing a non-longRunning task {} - running time since cleanup {} exceeded max wait time {}", taskCleanup, timeSinceCleanup, maxWaitTime);
        }
        return tooOld;
    }
    final String requestId = request.getId();
    final Optional<SingularityRequestDeployState> deployState = deployManager.getRequestDeployState(requestId);
    if (taskCleanup.getCleanupType() == TaskCleanupType.DECOMISSIONING && deployState.get().getPendingDeploy().isPresent() && deployState.get().getPendingDeploy().get().getDeployId().equals(taskCleanup.getTaskId().getDeployId())) {
        final long timeSinceCleanup = System.currentTimeMillis() - taskCleanup.getTimestamp();
        final long maxWaitTime = configuration.getPendingDeployHoldTaskDuringDecommissionMillis();
        final boolean tooOld = (maxWaitTime < 1) || (timeSinceCleanup > maxWaitTime);
        if (!tooOld) {
            LOG.trace("Not killing {} - part of pending deploy - running time since cleanup {} (max wait time is {})", taskCleanup, timeSinceCleanup, maxWaitTime);
            return false;
        } else {
            LOG.debug("Killing {} - part of pending deploy but running time since cleanup {} exceeded max wait time {}", taskCleanup, timeSinceCleanup, maxWaitTime);
            return true;
        }
    }
    if (!deployState.isPresent() || !deployState.get().getActiveDeploy().isPresent()) {
        LOG.debug("Killing a task {} immediately because there is no active deploy state {}", taskCleanup, deployState);
        return true;
    }
    final String activeDeployId = deployState.get().getActiveDeploy().get().getDeployId();
    final String matchingTasksDeployId = taskCleanup.getCleanupType() == TaskCleanupType.INCREMENTAL_DEPLOY_CANCELLED || taskCleanup.getCleanupType() == TaskCleanupType.INCREMENTAL_DEPLOY_FAILED ? activeDeployId : taskCleanup.getTaskId().getDeployId();
    // check to see if there are enough active tasks out there that have been active for long enough that we can safely shut this task down.
    final List<SingularityTaskId> matchingTasks = new ArrayList<>();
    for (SingularityTaskId taskId : activeTaskIds) {
        if (!taskId.getRequestId().equals(requestId) || !taskId.getDeployId().equals(matchingTasksDeployId)) {
            continue;
        }
        if (cleaningTasks.contains(taskId)) {
            continue;
        }
        matchingTasks.add(taskId);
    }
    // For an incremental bounce or incremental deploy cleanup, shut down old tasks as new ones are started
    final SingularityDeployKey key = SingularityDeployKey.fromTaskId(taskCleanup.getTaskId());
    if (taskCleanup.getCleanupType() == TaskCleanupType.INCREMENTAL_BOUNCE) {
        return shouldKillIncrementalBounceTask(request, taskCleanup, matchingTasksDeployId, matchingTasks, key, incrementalCleaningTasks);
    } else if (isIncrementalDeployCleanup(taskCleanup)) {
        return shouldKillIncrementalDeployCleanupTask(request, taskCleanup, matchingTasksDeployId, matchingTasks, key, incrementalCleaningTasks);
    } else {
        if (matchingTasks.size() < request.getInstancesSafe()) {
            LOG.trace("Not killing a task {} yet, only {} matching out of a required {}", taskCleanup, matchingTasks.size(), request.getInstancesSafe());
            return false;
        }
    }
    final Optional<SingularityDeploy> deploy = deployManager.getDeploy(requestId, activeDeployId);
    final DeployHealth deployHealth = deployHealthHelper.getDeployHealth(requestWithState.get().getRequest(), deploy, matchingTasks, false);
    switch(deployHealth) {
        case HEALTHY:
            for (SingularityTaskId taskId : matchingTasks) {
                DeployHealth lbHealth = getLbHealth(request, taskId);
                if (lbHealth != DeployHealth.HEALTHY) {
                    LOG.trace("Not killing a task {}, waiting for new replacement tasks to be added to LB (current state: {})", taskCleanup, lbHealth);
                    return false;
                }
            }
            LOG.debug("Killing a task {}, all replacement tasks are healthy", taskCleanup);
            return true;
        case WAITING:
        case UNHEALTHY:
        default:
            LOG.trace("Not killing a task {}, waiting for new replacement tasks to be healthy (current state: {})", taskCleanup, deployHealth);
            return false;
    }
}
Also used : SingularityRequest(com.hubspot.singularity.SingularityRequest) ArrayList(java.util.ArrayList) SingularityRequestDeployState(com.hubspot.singularity.SingularityRequestDeployState) SingularityDeploy(com.hubspot.singularity.SingularityDeploy) SingularityDeployKey(com.hubspot.singularity.SingularityDeployKey) SingularityRequestWithState(com.hubspot.singularity.SingularityRequestWithState) SingularityTaskShellCommandUpdate(com.hubspot.singularity.SingularityTaskShellCommandUpdate) DeployHealth(com.hubspot.singularity.scheduler.SingularityDeployHealthHelper.DeployHealth) SingularityTaskId(com.hubspot.singularity.SingularityTaskId)

Example 30 with SingularityDeploy

use of com.hubspot.singularity.SingularityDeploy in project Singularity by HubSpot.

the class ValidatorTest method whenDeployHasRunNowSetItValidatesThatItIsLessThanACertaionLength.

@Test(expected = WebApplicationException.class)
public void whenDeployHasRunNowSetItValidatesThatItIsLessThanACertaionLength() {
    String requestId = "request";
    String deployID = "deploy";
    SingularityRequest request = new SingularityRequestBuilder(requestId, RequestType.ON_DEMAND).build();
    Optional<SingularityRunNowRequest> runNowRequest = Optional.of(runNowRequest(tooLongId()));
    SingularityDeploy deploy = SingularityDeploy.newBuilder(requestId, deployID).setCommand(Optional.of("printenv")).setRunImmediately(runNowRequest).build();
    validator.checkDeploy(request, deploy, Collections.emptyList(), Collections.emptyList());
}
Also used : SingularityRunNowRequest(com.hubspot.singularity.api.SingularityRunNowRequest) SingularityRequestBuilder(com.hubspot.singularity.SingularityRequestBuilder) SingularityRequest(com.hubspot.singularity.SingularityRequest) SingularityDeploy(com.hubspot.singularity.SingularityDeploy) Test(org.junit.Test)

Aggregations

SingularityDeploy (com.hubspot.singularity.SingularityDeploy)52 Test (org.junit.Test)38 SingularityRequest (com.hubspot.singularity.SingularityRequest)30 SingularityDeployBuilder (com.hubspot.singularity.SingularityDeployBuilder)27 SingularityRequestBuilder (com.hubspot.singularity.SingularityRequestBuilder)22 SingularityTask (com.hubspot.singularity.SingularityTask)12 SingularityTaskRequest (com.hubspot.singularity.SingularityTaskRequest)11 SingularityDeployRequest (com.hubspot.singularity.api.SingularityDeployRequest)10 HealthcheckOptions (com.hubspot.deploy.HealthcheckOptions)9 HealthcheckOptionsBuilder (com.hubspot.deploy.HealthcheckOptionsBuilder)9 SingularityTaskId (com.hubspot.singularity.SingularityTaskId)8 SingularityMesosTaskHolder (com.hubspot.singularity.helpers.SingularityMesosTaskHolder)8 SingularityTaskHealthcheckResult (com.hubspot.singularity.SingularityTaskHealthcheckResult)7 Resources (com.hubspot.mesos.Resources)6 SingularityRunNowRequest (com.hubspot.singularity.api.SingularityRunNowRequest)6 SingularityDeployMarker (com.hubspot.singularity.SingularityDeployMarker)5 SingularityPendingTaskId (com.hubspot.singularity.SingularityPendingTaskId)5 SingularityRequestWithState (com.hubspot.singularity.SingularityRequestWithState)5 ArrayList (java.util.ArrayList)5 SingularityContainerInfo (com.hubspot.mesos.SingularityContainerInfo)4