diff --git a/SingularityBase/src/main/java/com/hubspot/singularity/SingularityRequestCleanup.java b/SingularityBase/src/main/java/com/hubspot/singularity/SingularityRequestCleanup.java index 6ad1fbad9b..6155b2299e 100644 --- a/SingularityBase/src/main/java/com/hubspot/singularity/SingularityRequestCleanup.java +++ b/SingularityBase/src/main/java/com/hubspot/singularity/SingularityRequestCleanup.java @@ -9,6 +9,7 @@ public class SingularityRequestCleanup { private final Optional user; private final RequestCleanupType cleanupType; private final Optional killTasks; + private final Optional removeFromLoadBalancer; private final Optional skipHealthchecks; private final Optional deployId; private final long timestamp; @@ -18,16 +19,24 @@ public class SingularityRequestCleanup { private final Optional runShellCommandBeforeKill; @JsonCreator - public SingularityRequestCleanup(@JsonProperty("user") Optional user, @JsonProperty("cleanupType") RequestCleanupType cleanupType, @JsonProperty("timestamp") long timestamp, - @JsonProperty("killTasks") Optional killTasks, @JsonProperty("requestId") String requestId, @JsonProperty("deployId") Optional deployId, - @JsonProperty("skipHealthchecks") Optional skipHealthchecks, @JsonProperty("message") Optional message, @JsonProperty("actionId") Optional actionId, - @JsonProperty("runShellCommandBeforeKill") Optional runShellCommandBeforeKill) { + public SingularityRequestCleanup(@JsonProperty("user") Optional user, + @JsonProperty("cleanupType") RequestCleanupType cleanupType, + @JsonProperty("timestamp") long timestamp, + @JsonProperty("killTasks") Optional killTasks, + @JsonProperty("removeFromLoadBalancer") Optional removeFromLoadBalancer, + @JsonProperty("requestId") String requestId, + @JsonProperty("deployId") Optional deployId, + @JsonProperty("skipHealthchecks") Optional skipHealthchecks, + @JsonProperty("message") Optional message, + @JsonProperty("actionId") Optional actionId, + @JsonProperty("runShellCommandBeforeKill") Optional runShellCommandBeforeKill) { this.user = user; this.cleanupType = cleanupType; this.timestamp = timestamp; this.requestId = requestId; this.deployId = deployId; this.killTasks = killTasks; + this.removeFromLoadBalancer = removeFromLoadBalancer; this.skipHealthchecks = skipHealthchecks; this.actionId = actionId; this.message = message; @@ -42,6 +51,10 @@ public Optional getKillTasks() { return killTasks; } + public Optional getRemoveFromLoadBalancer() { + return removeFromLoadBalancer; + } + public String getRequestId() { return requestId; } @@ -80,6 +93,7 @@ public String toString() { "user=" + user + ", cleanupType=" + cleanupType + ", killTasks=" + killTasks + + ", removeFromLoadBalancer=" + removeFromLoadBalancer + ", skipHealthchecks=" + skipHealthchecks + ", deployId=" + deployId + ", timestamp=" + timestamp + diff --git a/SingularityBase/src/main/java/com/hubspot/singularity/SingularityTaskCleanup.java b/SingularityBase/src/main/java/com/hubspot/singularity/SingularityTaskCleanup.java index 2b6c8724b4..012f035e82 100644 --- a/SingularityBase/src/main/java/com/hubspot/singularity/SingularityTaskCleanup.java +++ b/SingularityBase/src/main/java/com/hubspot/singularity/SingularityTaskCleanup.java @@ -13,11 +13,14 @@ public class SingularityTaskCleanup { private final Optional message; private final Optional actionId; private final Optional runBeforeKillId; + private final Optional removeFromLoadBalancer; @JsonCreator public SingularityTaskCleanup(@JsonProperty("user") Optional user, @JsonProperty("cleanupType") TaskCleanupType cleanupType, @JsonProperty("timestamp") long timestamp, @JsonProperty("taskId") SingularityTaskId taskId, @JsonProperty("message") Optional message, @JsonProperty("actionId") Optional actionId, - @JsonProperty("runBeforeKillId") Optional runBeforeKillId) { + @JsonProperty("runBeforeKillId") Optional runBeforeKillId, + @JsonProperty("removeFromLoadBalancer") Optional removeFromLoadBalancer + ) { this.user = user; this.cleanupType = cleanupType; this.timestamp = timestamp; @@ -25,6 +28,17 @@ public SingularityTaskCleanup(@JsonProperty("user") Optional user, @Json this.message = message; this.actionId = actionId; this.runBeforeKillId = runBeforeKillId; + this.removeFromLoadBalancer = removeFromLoadBalancer; + } + + public SingularityTaskCleanup(Optional user, + TaskCleanupType cleanupType, + long timestamp, + SingularityTaskId taskId, + Optional message, + Optional actionId, + Optional runBeforeKillId) { + this(user, cleanupType, timestamp, taskId, message, actionId, runBeforeKillId, Optional.absent()); } public Optional getActionId() { @@ -55,6 +69,10 @@ public Optional getRunBeforeKillId() { return runBeforeKillId; } + public Optional getRemoveFromLoadBalancer() { + return removeFromLoadBalancer; + } + @Override public String toString() { return "SingularityTaskCleanup{" + diff --git a/SingularityBase/src/main/java/com/hubspot/singularity/api/SingularityDeleteRequestRequest.java b/SingularityBase/src/main/java/com/hubspot/singularity/api/SingularityDeleteRequestRequest.java index 0fba9bcb21..3d8c426768 100644 --- a/SingularityBase/src/main/java/com/hubspot/singularity/api/SingularityDeleteRequestRequest.java +++ b/SingularityBase/src/main/java/com/hubspot/singularity/api/SingularityDeleteRequestRequest.java @@ -9,12 +9,15 @@ public class SingularityDeleteRequestRequest { private final Optional message; private final Optional actionId; + private final Optional deleteFromLoadBalancer; @JsonCreator public SingularityDeleteRequestRequest(@JsonProperty("message") Optional message, - @JsonProperty("actionId") Optional actionId) { + @JsonProperty("actionId") Optional actionId, + @JsonProperty("deleteFromLoadBalancer") Optional deleteFromLoadBalancer) { this.message = message; this.actionId = actionId; + this.deleteFromLoadBalancer = deleteFromLoadBalancer; } @ApiModelProperty(required=false, value="A message to show to users about why this action was taken") @@ -27,11 +30,17 @@ public Optional getActionId() { return actionId; } + @ApiModelProperty(required = false, value = "Should the service associated with the request be removed from the load balancer") + public Optional getDeleteFromLoadBalancer() { + return deleteFromLoadBalancer; + } + @Override public String toString() { return "SingularityDeleteRequestRequest{" + "message=" + message + ", actionId=" + actionId + + ", deleteFromLoadBalancer=" + deleteFromLoadBalancer + '}'; } } diff --git a/SingularityService/src/main/java/com/hubspot/singularity/data/RequestManager.java b/SingularityService/src/main/java/com/hubspot/singularity/data/RequestManager.java index 04618e3333..2e191f6b2a 100644 --- a/SingularityService/src/main/java/com/hubspot/singularity/data/RequestManager.java +++ b/SingularityService/src/main/java/com/hubspot/singularity/data/RequestManager.java @@ -398,11 +398,11 @@ public Optional getRequest(String requestId, boolea return getData(getRequestPath(requestId), requestTranscoder); } - public void startDeletingRequest(SingularityRequest request, Optional user, Optional actionId, Optional message) { + public void startDeletingRequest(SingularityRequest request, Optional removeFromLoadBalancer, Optional user, Optional actionId, Optional message) { final long now = System.currentTimeMillis(); // delete it no matter if the delete request already exists. - createCleanupRequest(new SingularityRequestCleanup(user, RequestCleanupType.DELETING, now, Optional.of(Boolean.TRUE), request.getId(), Optional. absent(), + createCleanupRequest(new SingularityRequestCleanup(user, RequestCleanupType.DELETING, now, Optional.of(Boolean.TRUE), removeFromLoadBalancer, request.getId(), Optional. absent(), Optional. absent(), message, actionId, Optional.absent())); markDeleting(request, System.currentTimeMillis(), user, message); diff --git a/SingularityService/src/main/java/com/hubspot/singularity/helpers/RequestHelper.java b/SingularityService/src/main/java/com/hubspot/singularity/helpers/RequestHelper.java index 57b08f5bdb..b4429747fd 100644 --- a/SingularityService/src/main/java/com/hubspot/singularity/helpers/RequestHelper.java +++ b/SingularityService/src/main/java/com/hubspot/singularity/helpers/RequestHelper.java @@ -97,9 +97,10 @@ private void checkReschedule(SingularityRequest newRequest, Optional actionId = maybeBounceRequest.get().getActionId().or(Optional.of(UUID.randomUUID().toString())); + Optional removeFromLoadBalancer = Optional.absent(); SingularityCreateResult createResult = requestManager.createCleanupRequest( new SingularityRequestCleanup(user, maybeBounceRequest.get().getIncremental().or(true) ? RequestCleanupType.INCREMENTAL_BOUNCE : RequestCleanupType.BOUNCE, - System.currentTimeMillis(), Optional. absent(), newRequest.getId(), Optional.of(maybeDeployId.get()), skipHealthchecks, message, actionId, maybeBounceRequest.get().getRunShellCommandBeforeKill())); + System.currentTimeMillis(), Optional. absent(), removeFromLoadBalancer, newRequest.getId(), Optional.of(maybeDeployId.get()), skipHealthchecks, message, actionId, maybeBounceRequest.get().getRunShellCommandBeforeKill())); if (createResult != SingularityCreateResult.EXISTED) { requestManager.bounce(newRequest, System.currentTimeMillis(), user, Optional.of("Bouncing due to bounce after scale")); diff --git a/SingularityService/src/main/java/com/hubspot/singularity/resources/RequestResource.java b/SingularityService/src/main/java/com/hubspot/singularity/resources/RequestResource.java index c1199f7a46..2755c1f51a 100644 --- a/SingularityService/src/main/java/com/hubspot/singularity/resources/RequestResource.java +++ b/SingularityService/src/main/java/com/hubspot/singularity/resources/RequestResource.java @@ -238,7 +238,7 @@ public SingularityRequestParent bounce(String requestId, Optional absent(), requestId, Optional.of(deployId), skipHealthchecks, message, actionId, runBeforeKill)); + System.currentTimeMillis(), Optional. absent(), Optional.absent(), requestId, Optional.of(deployId), skipHealthchecks, message, actionId, runBeforeKill)); requestManager.bounce(requestWithState.getRequest(), System.currentTimeMillis(), JavaUtils.getUserEmail(user), message); @@ -378,9 +378,10 @@ public SingularityRequestParent pause(String requestId, Optional removeFromLoadBalancer = Optional.absent(); SingularityCreateResult result = requestManager.createCleanupRequest(new SingularityRequestCleanup(JavaUtils.getUserEmail(user), - RequestCleanupType.PAUSING, now, killTasks, requestId, Optional. absent(), Optional. absent(), message, actionId, runBeforeKill)); + RequestCleanupType.PAUSING, now, killTasks, removeFromLoadBalancer, requestId, Optional. absent(), Optional. absent(), message, actionId, runBeforeKill)); checkConflict(result == SingularityCreateResult.CREATED, "%s is already pausing - try again soon", requestId, result); @@ -617,13 +618,15 @@ public SingularityRequest deleteRequest(String requestId, Optional message = Optional.absent(); Optional actionId = Optional.absent(); + Optional deleteFromLoadBalancer = Optional.absent(); if (deleteRequest.isPresent()) { actionId = deleteRequest.get().getActionId(); message = deleteRequest.get().getMessage(); + deleteFromLoadBalancer = deleteRequest.get().getDeleteFromLoadBalancer(); } - requestManager.startDeletingRequest(request, JavaUtils.getUserEmail(user), actionId, message); + requestManager.startDeletingRequest(request, deleteFromLoadBalancer, JavaUtils.getUserEmail(user), actionId, message); mailer.sendRequestRemovedMail(request, JavaUtils.getUserEmail(user), message); diff --git a/SingularityService/src/main/java/com/hubspot/singularity/scheduler/SingularityCleaner.java b/SingularityService/src/main/java/com/hubspot/singularity/scheduler/SingularityCleaner.java index 4853fac9ec..038859de41 100644 --- a/SingularityService/src/main/java/com/hubspot/singularity/scheduler/SingularityCleaner.java +++ b/SingularityService/src/main/java/com/hubspot/singularity/scheduler/SingularityCleaner.java @@ -365,7 +365,9 @@ private void drainRequestCleanupQueue() { } else { Optional maybeHistory = requestHistoryHelper.getLastHistory(requestId); if (maybeHistory.isPresent()) { - if (maybeHistory.get().getRequest().isLoadBalanced() && configuration.isDeleteRemovedRequestsFromLoadBalancer()) { + if (maybeHistory.get().getRequest().isLoadBalanced() + && configuration.isDeleteRemovedRequestsFromLoadBalancer() + && requestCleanup.getRemoveFromLoadBalancer().or(true)) { createLbCleanupRequest(requestId, matchingActiveTaskIds); } requestManager.markDeleted(maybeHistory.get().getRequest(), start, requestCleanup.getUser(), requestCleanup.getMessage()); @@ -494,7 +496,7 @@ private void delete(SingularityRequestCleanup requestCleanup, Iterable absent(), Optional. absent(), Optional. absent(), Optional.of(msg), Optional.absent(), Optional.absent())); - requestResource.deleteRequest(requestId, Optional.of(new SingularityDeleteRequestRequest(Optional.of("a msg"), Optional. absent()))); + requestResource.deleteRequest(requestId, Optional.of(new SingularityDeleteRequestRequest(Optional.of("a msg"), Optional. absent(), Optional.absent()))); cleaner.drainCleanupQueue(); diff --git a/SingularityService/src/test/java/com/hubspot/singularity/scheduler/HistoryPersisterTest.java b/SingularityService/src/test/java/com/hubspot/singularity/scheduler/HistoryPersisterTest.java index 2b8b91b24e..5d8c2c0245 100644 --- a/SingularityService/src/test/java/com/hubspot/singularity/scheduler/HistoryPersisterTest.java +++ b/SingularityService/src/test/java/com/hubspot/singularity/scheduler/HistoryPersisterTest.java @@ -48,7 +48,7 @@ public void testRequestAgePurging() { Assert.assertTrue(!requestManager.getRequestHistory(requestId).isEmpty()); - requestManager.startDeletingRequest(request, user, Optional. absent(), Optional. absent()); + requestManager.startDeletingRequest(request, Optional.absent(), user, Optional. absent(), Optional. absent()); requestManager.deleteHistoryParent(requestId); @@ -79,17 +79,17 @@ public void testRequestCountPurging() { configuration.setMaxRequestsWithHistoryInZkWhenNoDatabase(Optional.of(2)); configuration.setDeleteStaleRequestsFromZkWhenNoDatabaseAfterHours(7); - requestManager.startDeletingRequest(requestOne, user, Optional.absent(), Optional.absent()); + requestManager.startDeletingRequest(requestOne, Optional.absent(), user, Optional.absent(), Optional.absent()); requestManager.deleteHistoryParent(requestOne.getId()); requestManager.activate(requestOne, RequestHistoryType.CREATED, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(4), Optional. absent(), Optional. absent()); requestManager.cooldown(requestOne, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(3)); - requestManager.startDeletingRequest(requestTwo, user, Optional.absent(), Optional.absent()); + requestManager.startDeletingRequest(requestTwo, Optional.absent(), user, Optional.absent(), Optional.absent()); requestManager.deleteHistoryParent(requestTwo.getId()); requestManager.activate(requestTwo, RequestHistoryType.CREATED, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(4), Optional. absent(), Optional. absent()); requestManager.cooldown(requestTwo, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(3)); - requestManager.startDeletingRequest(requestThree, user, Optional.absent(), Optional.absent()); + requestManager.startDeletingRequest(requestThree, Optional.absent(), user, Optional.absent(), Optional.absent()); requestManager.deleteHistoryParent(requestThree.getId()); requestManager.activate(requestThree, RequestHistoryType.CREATED, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(4), Optional. absent(), Optional. absent()); requestManager.cooldown(requestThree, System.currentTimeMillis() - TimeUnit.HOURS.toMillis(3)); @@ -198,7 +198,7 @@ public void testPurgingDoesntApplyIfDatabasePresent() { initRequest(); initFirstDeploy(); - requestManager.startDeletingRequest(request, user, Optional. absent(), Optional. absent()); + requestManager.startDeletingRequest(request, Optional.absent(), user, Optional. absent(), Optional. absent()); requestManager.deleteHistoryParent(requestId); diff --git a/SingularityService/src/test/java/com/hubspot/singularity/scheduler/SingularitySchedulerTest.java b/SingularityService/src/test/java/com/hubspot/singularity/scheduler/SingularitySchedulerTest.java index 2754ae436c..8cd2fe1457 100644 --- a/SingularityService/src/test/java/com/hubspot/singularity/scheduler/SingularitySchedulerTest.java +++ b/SingularityService/src/test/java/com/hubspot/singularity/scheduler/SingularitySchedulerTest.java @@ -878,6 +878,51 @@ public void testLbCleanupDoesNotRemoveBeforeAdd() { Assert.assertTrue(taskManager.getCleanupTaskIds().contains(taskOne.getTaskId())); } + @Test + public void testLbCleanupSkippedOnSkipRemoveFlag() { + configuration.setDeleteRemovedRequestsFromLoadBalancer(true); + initLoadBalancedRequest(); + initLoadBalancedDeploy(); + startTask(firstDeploy); + + boolean removeFromLoadBalancer = false; + SingularityDeleteRequestRequest deleteRequest = new SingularityDeleteRequestRequest(Optional.absent(), Optional.absent(), Optional.of(removeFromLoadBalancer)); + + requestResource.deleteRequest(requestId, Optional.of(deleteRequest)); + + testingLbClient.setNextBaragonRequestState(BaragonRequestState.WAITING); + + Assert.assertFalse("Tasks should get cleaned up", requestManager.getCleanupRequests().isEmpty()); + cleaner.drainCleanupQueue(); + killKilledTasks(); + + Assert.assertFalse("The request should get cleaned up", requestManager.getCleanupRequests().isEmpty()); + cleaner.drainCleanupQueue(); + + Assert.assertTrue("The request should not be removed from the load balancer", requestManager.getLbCleanupRequestIds().isEmpty()); + } + + @Test + public void testLbCleanupOccursOnRequestDelete() { + configuration.setDeleteRemovedRequestsFromLoadBalancer(true); + initLoadBalancedRequest(); + initLoadBalancedDeploy(); + startTask(firstDeploy); + + requestResource.deleteRequest(requestId, Optional.absent()); + + testingLbClient.setNextBaragonRequestState(BaragonRequestState.WAITING); + + Assert.assertFalse("Tasks should get cleaned up", requestManager.getCleanupRequests().isEmpty()); + cleaner.drainCleanupQueue(); + killKilledTasks(); + + Assert.assertFalse("The request should get cleaned up", requestManager.getCleanupRequests().isEmpty()); + cleaner.drainCleanupQueue(); + + Assert.assertFalse("The request should get removed from the load balancer", requestManager.getLbCleanupRequestIds().isEmpty()); + } + @Test public void testReconciliation() { Assert.assertTrue(!taskReconciliation.isReconciliationRunning()); @@ -960,7 +1005,7 @@ public void badPauseExpires() { initRequest(); requestManager.createCleanupRequest(new SingularityRequestCleanup(Optional.absent(), RequestCleanupType.PAUSING, System.currentTimeMillis(), - Optional.absent(), requestId, Optional.absent(), Optional. absent(), Optional.absent(), Optional.absent(), Optional.absent())); + Optional.absent(), Optional.absent(), requestId, Optional.absent(), Optional. absent(), Optional.absent(), Optional.absent(), Optional.absent())); cleaner.drainCleanupQueue(); @@ -1142,7 +1187,7 @@ public void testIncrementalBounce() { SingularityTask taskTwo = startSeparatePlacementTask(firstDeploy, 2); requestManager.createCleanupRequest(new SingularityRequestCleanup(user, RequestCleanupType.INCREMENTAL_BOUNCE, System.currentTimeMillis(), - Optional.absent(), requestId, Optional.of(firstDeployId), Optional. absent(), Optional.absent(), Optional.absent(), Optional.absent())); + Optional.absent(), Optional.absent(), requestId, Optional.of(firstDeployId), Optional. absent(), Optional.absent(), Optional.absent(), Optional.absent())); Assert.assertTrue(requestManager.cleanupRequestExists(requestId)); @@ -1426,7 +1471,7 @@ public void testRemovedRequestData() { deployChecker.checkDeploys(); Assert.assertEquals(DeployState.WAITING, deployManager.getPendingDeploys().get(0).getCurrentDeployState()); - requestManager.startDeletingRequest(request, Optional.absent(), Optional.absent(), Optional.absent()); + requestManager.startDeletingRequest(request, Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent()); requestManager.markDeleted(request, now, Optional.absent(), Optional.absent()); deployChecker.checkDeploys(); SingularityDeployResult deployResult = deployManager.getDeployResult(requestId, firstDeployId).get(); @@ -1440,7 +1485,7 @@ public void itCorrectlyUpdatesRequestDeletingStateHistory() { Assert.assertEquals(RequestState.ACTIVE, requestManager.getRequest(requestId).get().getState()); Assert.assertEquals(1, requestManager.getRequestHistory(requestId).size()); - requestManager.startDeletingRequest(request, Optional.absent(), Optional.absent(), Optional.of("the cake is a lie")); + requestManager.startDeletingRequest(request, Optional.absent(), Optional.absent(), Optional.absent(), Optional.of("the cake is a lie")); Assert.assertEquals(RequestState.DELETING, requestManager.getRequest(requestId).get().getState()); Assert.assertEquals(2, requestManager.getRequestHistory(requestId).size()); @@ -1471,7 +1516,7 @@ public void itSetsRequestStateToDeletedAfterAllTasksAreCleanedUp() { Assert.assertEquals(requestId, requestManager.getActiveRequests().iterator().next().getRequest().getId()); Assert.assertEquals(2, taskManager.getActiveTaskIds().size()); - requestManager.startDeletingRequest(request, Optional.absent(), Optional.absent(), Optional.absent()); + requestManager.startDeletingRequest(request, Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent()); Assert.assertEquals(requestId, requestManager.getCleanupRequests().get(0).getRequestId()); Assert.assertEquals(RequestState.DELETING, requestManager.getRequest(requestId).get().getState()); @@ -1497,7 +1542,7 @@ public void itSetsRequestStateToDeletedIfTaskCleanupFails() { Assert.assertEquals(requestId, requestManager.getActiveRequests().iterator().next().getRequest().getId()); Assert.assertEquals(2, taskManager.getActiveTaskIds().size()); - requestManager.startDeletingRequest(request, Optional.absent(), Optional.absent(), Optional.absent()); + requestManager.startDeletingRequest(request, Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent()); Assert.assertEquals(requestId, requestManager.getCleanupRequests().get(0).getRequestId()); Assert.assertEquals(RequestState.DELETING, requestManager.getRequest(requestId).get().getState()); @@ -1902,6 +1947,7 @@ public void testScaleWithBounceDoesNotLaunchExtraInstances() { Assert.assertEquals(5, taskManager.getPendingTaskIds().size()); } + @Test public void testAcceptOffersWithRoleForRequestWithRole() { SingularityRequestBuilder bldr = new SingularityRequestBuilder(requestId, RequestType.ON_DEMAND); bldr.setRequiredRole(Optional.of("test-role")); diff --git a/SingularityService/src/test/java/com/hubspot/singularity/scheduler/SingularitySchedulerTestBase.java b/SingularityService/src/test/java/com/hubspot/singularity/scheduler/SingularitySchedulerTestBase.java index d47bbf02bd..1928d67a31 100644 --- a/SingularityService/src/test/java/com/hubspot/singularity/scheduler/SingularitySchedulerTestBase.java +++ b/SingularityService/src/test/java/com/hubspot/singularity/scheduler/SingularitySchedulerTestBase.java @@ -528,6 +528,14 @@ protected void initHCDeploy() { firstDeploy = initAndFinishDeploy(request, new SingularityDeployBuilder(request.getId(), firstDeployId).setCommand(Optional.of("sleep 100")).setHealthcheck(Optional.of(new HealthcheckOptionsBuilder("http://uri").build()))); } + protected void initLoadBalancedDeploy() { + SingularityDeployBuilder builder = new SingularityDeployBuilder(requestId, firstDeployId) + .setCommand(Optional.of("sleep 100")) + .setServiceBasePath(Optional.of("/basepath")) + .setLoadBalancerGroups(Optional.of(Collections.singleton("test"))); + firstDeploy = initAndFinishDeploy(request, builder); + } + protected SingularityDeploy initAndFinishDeploy(SingularityRequest request, String deployId) { return initAndFinishDeploy(request, new SingularityDeployBuilder(request.getId(), deployId).setCommand(Optional.of("sleep 100"))); } diff --git a/SingularityUI/app/actions/api/requests.es6 b/SingularityUI/app/actions/api/requests.es6 index dbf6bed74a..3514c7a59a 100644 --- a/SingularityUI/app/actions/api/requests.es6 +++ b/SingularityUI/app/actions/api/requests.es6 @@ -39,9 +39,9 @@ export const SaveRequest = buildJsonApiAction( export const RemoveRequest = buildJsonApiAction( 'REMOVE_REQUEST', 'DELETE', - (requestId, { message }) => ({ + (requestId, { message, deleteFromLoadBalancer }) => ({ url: `/requests/request/${requestId}`, - body: { message } + body: { message, deleteFromLoadBalancer } }) ); diff --git a/SingularityUI/app/components/common/modalButtons/RemoveButton.jsx b/SingularityUI/app/components/common/modalButtons/RemoveButton.jsx index c9c524422e..bc3d70079f 100644 --- a/SingularityUI/app/components/common/modalButtons/RemoveButton.jsx +++ b/SingularityUI/app/components/common/modalButtons/RemoveButton.jsx @@ -17,6 +17,7 @@ const removeTooltip = ( export default class RemoveButton extends Component { static propTypes = { requestId: PropTypes.string.isRequired, + loadBalanced: PropTypes.bool, loadBalancerData: PropTypes.object, children: PropTypes.node, then: PropTypes.func @@ -36,7 +37,13 @@ export default class RemoveButton extends Component { return ( {getClickComponent(this)} - + ); } diff --git a/SingularityUI/app/components/common/modalButtons/RemoveModal.jsx b/SingularityUI/app/components/common/modalButtons/RemoveModal.jsx index 234d8923df..fb7ce9cf51 100644 --- a/SingularityUI/app/components/common/modalButtons/RemoveModal.jsx +++ b/SingularityUI/app/components/common/modalButtons/RemoveModal.jsx @@ -5,9 +5,29 @@ import { RemoveRequest } from '../../../actions/api/requests'; import FormModal from '../modal/FormModal'; +const controls = (loadBalanced) => { + const formElements = []; + formElements.push({ + name: 'message', + type: FormModal.INPUT_TYPES.STRING, + label: 'Message (optional)' + }); + if (loadBalanced) { + formElements.push({ + name: 'deleteFromLoadBalancer', + type: FormModal.INPUT_TYPES.BOOLEAN, + label: 'Remove from load balancer', + defaultValue: true + }); + } + + return formElements; +}; + class RemoveModal extends Component { static propTypes = { requestId: PropTypes.string.isRequired, + loadBalanced: PropTypes.bool, loadBalancerData: PropTypes.object, removeRequest: PropTypes.func.isRequired }; @@ -19,7 +39,7 @@ class RemoveModal extends Component { render() { const loadBalancerWarning = (
-

Removing this request will also remove the following settings from the load balancer

+

If you remove this request from the load balancer, the following settings will also be removed:

{JSON.stringify(this.props.loadBalancerData, null, 2)}
); @@ -31,13 +51,7 @@ class RemoveModal extends Component { action="Remove Request" onConfirm={this.props.removeRequest} buttonStyle="danger" - formElements={[ - { - name: 'message', - type: FormModal.INPUT_TYPES.STRING, - label: 'Message (optional)' - } - ]}> + formElements={controls(this.props.loadBalanced)}>

Are you sure you want to remove this request?

{this.props.requestId}

If not paused, removing this request will kill all active and scheduled tasks and tasks for it will not run again unless it is reposted to Singularity.

diff --git a/SingularityUI/app/components/requestDetail/header/RequestActionButtons.jsx b/SingularityUI/app/components/requestDetail/header/RequestActionButtons.jsx index f8d6be3fdb..7b34d90bad 100644 --- a/SingularityUI/app/components/requestDetail/header/RequestActionButtons.jsx +++ b/SingularityUI/app/components/requestDetail/header/RequestActionButtons.jsx @@ -8,7 +8,7 @@ import { Link } from 'react-router'; import JSONButton from '../../common/JSONButton'; import { FetchRequest } from '../../../actions/api/requests'; -import { +import { FetchActiveTasksForRequest, FetchRequestHistory } from '../../../actions/api/history'; @@ -161,8 +161,9 @@ const RequestActionButtons = ({requestParent, fetchRequest, fetchRequestHistory, } const removeButton = ( -