From 50360e37032781d77852cb6e3c5d495e2c3e89ea Mon Sep 17 00:00:00 2001 From: Mark Vulfson Date: Mon, 10 Jun 2019 08:53:55 -0700 Subject: [PATCH] fix(RRB): Add dedicated pin stage (#2968) For RRB we start by pinning the source SG so that it doesn't scale down during deploy (and end with unpinning it). However, if for whatever reason some of the instances are taken out of discovery/targetgroup we will timeout waiting for capacity match on this operation. Since this pin/unpin operations are purely "cautionary" and don't require us to actually match the capacity, don't wait for capacity match so we don't fail for this non-critical reason --- .../aws/AwsDeployStagePreProcessor.groovy | 8 +-- .../servergroup/PinServerGroupStage.groovy | 51 +++++++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/pipeline/servergroup/PinServerGroupStage.groovy diff --git a/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/pipeline/providers/aws/AwsDeployStagePreProcessor.groovy b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/pipeline/providers/aws/AwsDeployStagePreProcessor.groovy index 16b8890bbf..2d2bb164ab 100644 --- a/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/pipeline/providers/aws/AwsDeployStagePreProcessor.groovy +++ b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/pipeline/providers/aws/AwsDeployStagePreProcessor.groovy @@ -17,7 +17,7 @@ package com.netflix.spinnaker.orca.clouddriver.pipeline.providers.aws -import com.netflix.spinnaker.orca.clouddriver.pipeline.servergroup.ResizeServerGroupStage +import com.netflix.spinnaker.orca.clouddriver.pipeline.servergroup.PinServerGroupStage import com.netflix.spinnaker.orca.clouddriver.pipeline.servergroup.strategies.AbstractDeployStrategyStage import com.netflix.spinnaker.orca.clouddriver.pipeline.servergroup.strategies.DeployStagePreProcessor import com.netflix.spinnaker.orca.clouddriver.pipeline.servergroup.support.TargetServerGroup @@ -39,7 +39,7 @@ class AwsDeployStagePreProcessor implements DeployStagePreProcessor { ApplySourceServerGroupCapacityStage applySourceServerGroupSnapshotStage @Autowired - ResizeServerGroupStage resizeServerGroupStage + PinServerGroupStage pinServerGroupStage @Autowired TargetServerGroupResolver targetServerGroupResolver @@ -101,7 +101,7 @@ class AwsDeployStagePreProcessor implements DeployStagePreProcessor { stageDefinitions << new StageDefinition( name: "Pin ${resizeContext.serverGroupName}", - stageDefinitionBuilder: resizeServerGroupStage, + stageDefinitionBuilder: pinServerGroupStage, context: resizeContext ) } @@ -213,7 +213,7 @@ class AwsDeployStagePreProcessor implements DeployStagePreProcessor { return new StageDefinition( name: "Unpin ${resizeContext.serverGroupName} (deployFailed=${deployFailed})".toString(), - stageDefinitionBuilder: resizeServerGroupStage, + stageDefinitionBuilder: pinServerGroupStage, context: resizeContext ) } diff --git a/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/pipeline/servergroup/PinServerGroupStage.groovy b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/pipeline/servergroup/PinServerGroupStage.groovy new file mode 100644 index 0000000000..3755304876 --- /dev/null +++ b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/pipeline/servergroup/PinServerGroupStage.groovy @@ -0,0 +1,51 @@ +/* + * Copyright 2019 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.netflix.spinnaker.orca.clouddriver.pipeline.servergroup + +import com.netflix.spinnaker.orca.clouddriver.pipeline.servergroup.support.TargetServerGroupLinearStageSupport +import com.netflix.spinnaker.orca.clouddriver.tasks.DetermineHealthProvidersTask +import com.netflix.spinnaker.orca.clouddriver.tasks.MonitorKatoTask +import com.netflix.spinnaker.orca.clouddriver.tasks.servergroup.ResizeServerGroupTask +import com.netflix.spinnaker.orca.clouddriver.tasks.servergroup.ServerGroupCacheForceRefreshTask +import com.netflix.spinnaker.orca.pipeline.TaskNode +import com.netflix.spinnaker.orca.pipeline.model.Stage +import groovy.util.logging.Slf4j +import org.springframework.stereotype.Component + +/** + * PinServerGroupStage updates the capacity (min/max/desired) on a server group but does not wait for capacity match, + * unlike ResizeServerGroup. + * Furthermore, it doesn't enabled/disable scaling processes. It simply sets the min/max/desired sizes on an ASG. + * + * The intent of the stage is to pin to prevent the ASG from scaling down, or, less usefully, up. As such, + * the expectation is that the right number of instances are already up and no need to wait for the capacity to match. + * That's why we can also ignore reenabling/disabling the scaling processes during this operation. + * This stage is used with rolling red black. + */ +@Component +@Slf4j +class PinServerGroupStage extends TargetServerGroupLinearStageSupport { + public static final String TYPE = getType(PinServerGroupStage) + + @Override + protected void taskGraphInternal(Stage stage, TaskNode.Builder builder) { + builder + .withTask("resizeServerGroup", ResizeServerGroupTask) + .withTask("monitorServerGroup", MonitorKatoTask) + .withTask("forceCacheRefresh", ServerGroupCacheForceRefreshTask) + } +}