diff --git a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/StopNodeInUniverse.java b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/StopNodeInUniverse.java index 20fd1755100d..c69f6b6ee35a 100644 --- a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/StopNodeInUniverse.java +++ b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/StopNodeInUniverse.java @@ -17,7 +17,6 @@ import com.yugabyte.yw.common.DnsManager; import com.yugabyte.yw.common.config.GlobalConfKeys; import com.yugabyte.yw.common.config.RuntimeConfGetter; -import com.yugabyte.yw.common.config.UniverseConfKeys; import com.yugabyte.yw.forms.NodeActionFormData; import com.yugabyte.yw.models.Universe; import com.yugabyte.yw.models.helpers.NodeDetails; @@ -33,8 +32,6 @@ @Retryable public class StopNodeInUniverse extends UniverseDefinitionTaskBase { - protected boolean isBlacklistLeaders; - protected int leaderBacklistWaitTimeMs; @Inject private RuntimeConfGetter confGetter; @Inject @@ -56,125 +53,119 @@ protected NodeDetails findNewMasterIfApplicable(Universe universe, NodeDetails c } @Override - public void run() { + public void validateParams(boolean isFirstTry) { + super.validateParams(isFirstTry); + Universe universe = getUniverse(); + NodeDetails currentNode = universe.getNode(taskParams().nodeName); + if (currentNode == null) { + String msg = "No node " + taskParams().nodeName + " found in universe " + universe.getName(); + log.error(msg); + throw new RuntimeException(msg); + } + } - try { - checkUniverseVersion(); - - // Set the 'updateInProgress' flag to prevent other updates from happening. - Universe universe = - lockUniverseForUpdate( - taskParams().expectedUniverseVersion, - u -> { - if (isFirstTry()) { - NodeDetails node = u.getNode(taskParams().nodeName); - if (node == null) { - String msg = - "No node " + taskParams().nodeName + " found in universe " + u.getName(); - log.error(msg); - throw new RuntimeException(msg); - } - if (node.isMaster) { - NodeDetails newMasterNode = findNewMasterIfApplicable(u, node); - if (newMasterNode != null && newMasterNode.masterState == null) { - newMasterNode.masterState = MasterState.ToStart; - } - node.masterState = MasterState.ToStop; - } - } - }); - - log.info( - "Stop Node with name {} from universe {} ({})", - taskParams().nodeName, - taskParams().getUniverseUUID(), - universe.getName()); - - isBlacklistLeaders = - confGetter.getConfForScope(universe, UniverseConfKeys.ybUpgradeBlacklistLeaders); - leaderBacklistWaitTimeMs = - confGetter.getConfForScope(universe, UniverseConfKeys.ybUpgradeBlacklistLeaderWaitTimeMs); - - NodeDetails currentNode = universe.getNode(taskParams().nodeName); - if (currentNode == null) { - String msg = - "No node " + taskParams().nodeName + " found in universe " + universe.getName(); - log.error(msg); - throw new RuntimeException(msg); - } - preTaskActions(); - List nodeList = Collections.singletonList(currentNode); + @Override + protected void createPrecheckTasks(Universe universe) { + NodeDetails currentNode = universe.getNode(taskParams().nodeName); + if (currentNode.isTserver) { + createNodePrecheckTasks( + currentNode, + EnumSet.of(ServerType.TSERVER), + SubTaskGroupType.StoppingNodeProcesses, + null); + } + } - if (currentNode.isTserver) { - clearLeaderBlacklistIfAvailable(SubTaskGroupType.StoppingNodeProcesses); + @Override + protected void freezeUniverseInTxn(Universe universe) { + NodeDetails node = universe.getNode(taskParams().nodeName); + if (node == null) { + String msg = "No node " + taskParams().nodeName + " found in universe " + universe.getName(); + log.error(msg); + throw new RuntimeException(msg); + } + if (node.isMaster) { + NodeDetails newMasterNode = findNewMasterIfApplicable(universe, node); + if (newMasterNode != null && newMasterNode.masterState == null) { + newMasterNode.masterState = MasterState.ToStart; } + node.masterState = MasterState.ToStop; + } + } - // Update Node State to Stopping - createSetNodeStateTask(currentNode, NodeState.Stopping) - .setSubTaskGroupType(SubTaskGroupType.StoppingNodeProcesses); + @Override + public void run() { + super.runUpdateTasks(this::runTask); + } + + private void runTask() { + log.info( + "Stop Node with name {} from universe uuid={}", + taskParams().nodeName, + taskParams().getUniverseUUID()); + + Universe universe = getUniverse(); + NodeDetails currentNode = universe.getNode(taskParams().nodeName); + + preTaskActions(); + List nodeList = Collections.singletonList(currentNode); + + if (currentNode.isTserver) { + clearLeaderBlacklistIfAvailable(SubTaskGroupType.StoppingNodeProcesses); + } + + // Update Node State to Stopping + createSetNodeStateTask(currentNode, NodeState.Stopping) + .setSubTaskGroupType(SubTaskGroupType.StoppingNodeProcesses); + taskParams().azUuid = currentNode.azUuid; + taskParams().placementUuid = currentNode.placementUuid; + boolean instanceExists = instanceExists(taskParams()); + if (instanceExists) { if (currentNode.isTserver) { - createNodePrecheckTasks( + stopProcessesOnNode( currentNode, EnumSet.of(ServerType.TSERVER), - SubTaskGroupType.StoppingNodeProcesses, - null); + true, + false, + SubTaskGroupType.StoppingNodeProcesses); + // Remove leader blacklist. + removeFromLeaderBlackListIfAvailable(nodeList, SubTaskGroupType.StoppingNodeProcesses); } - taskParams().azUuid = currentNode.azUuid; - taskParams().placementUuid = currentNode.placementUuid; - boolean instanceExists = instanceExists(taskParams()); - if (instanceExists) { - if (currentNode.isTserver) { - stopProcessesOnNode( - currentNode, - EnumSet.of(ServerType.TSERVER), - true, - false, - SubTaskGroupType.StoppingNodeProcesses); - // Remove leader blacklist. - removeFromLeaderBlackListIfAvailable(nodeList, SubTaskGroupType.StoppingNodeProcesses); - } - - // Stop Yb-controller on this node. - if (universe.isYbcEnabled()) { - createStopYbControllerTasks(nodeList) - .setSubTaskGroupType(SubTaskGroupType.StoppingNodeProcesses); - } - } - if (currentNode.isTserver) { - // Update the per process state in YW DB. - createUpdateNodeProcessTask(taskParams().nodeName, ServerType.TSERVER, false) + // Stop Yb-controller on this node. + if (universe.isYbcEnabled()) { + createStopYbControllerTasks(nodeList) .setSubTaskGroupType(SubTaskGroupType.StoppingNodeProcesses); } + } + if (currentNode.isTserver) { + // Update the per process state in YW DB. + createUpdateNodeProcessTask(taskParams().nodeName, ServerType.TSERVER, false) + .setSubTaskGroupType(SubTaskGroupType.StoppingNodeProcesses); + } - createMasterReplacementTasks( - universe, - currentNode, - () -> findNewMasterIfApplicable(universe, currentNode), - instanceExists); + createMasterReplacementTasks( + universe, + currentNode, + () -> findNewMasterIfApplicable(universe, currentNode), + instanceExists); - // Update Node State to Stopped - createSetNodeStateTask(currentNode, NodeState.Stopped) - .setSubTaskGroupType(SubTaskGroupType.StoppingNode); + // Update Node State to Stopped + createSetNodeStateTask(currentNode, NodeState.Stopped) + .setSubTaskGroupType(SubTaskGroupType.StoppingNode); - // Update the swamper target file. - createSwamperTargetUpdateTask(false /* removeFile */); + // Update the swamper target file. + createSwamperTargetUpdateTask(false /* removeFile */); - // Update the DNS entry for this universe. - createDnsManipulationTask(DnsManager.DnsCommandType.Edit, false, universe) - .setSubTaskGroupType(SubTaskGroupType.StoppingNode); + // Update the DNS entry for this universe. + createDnsManipulationTask(DnsManager.DnsCommandType.Edit, false, universe) + .setSubTaskGroupType(SubTaskGroupType.StoppingNode); - // Mark universe task state to success - createMarkUniverseUpdateSuccessTasks().setSubTaskGroupType(SubTaskGroupType.StoppingNode); + // Mark universe task state to success + createMarkUniverseUpdateSuccessTasks().setSubTaskGroupType(SubTaskGroupType.StoppingNode); - getRunnableTask().runSubTasks(); - } catch (Throwable t) { - log.error("Error executing task {}, error='{}'", getName(), t.getMessage(), t); - throw t; - } finally { - unlockUniverseForUpdate(); - } + getRunnableTask().runSubTasks(); log.info("Finished {} task.", getName()); } diff --git a/managed/src/test/java/com/yugabyte/yw/commissioner/tasks/StopNodeInUniverseTest.java b/managed/src/test/java/com/yugabyte/yw/commissioner/tasks/StopNodeInUniverseTest.java index 0e58ecf8dd42..0fdc76fe7f04 100644 --- a/managed/src/test/java/com/yugabyte/yw/commissioner/tasks/StopNodeInUniverseTest.java +++ b/managed/src/test/java/com/yugabyte/yw/commissioner/tasks/StopNodeInUniverseTest.java @@ -4,11 +4,11 @@ import static com.yugabyte.yw.common.AssertHelper.assertJsonEqual; import static com.yugabyte.yw.common.ModelFactory.createUniverse; -import static com.yugabyte.yw.models.TaskInfo.State.Failure; import static com.yugabyte.yw.models.TaskInfo.State.Success; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -28,6 +28,7 @@ import com.yugabyte.yw.common.ModelFactory; import com.yugabyte.yw.common.NodeManager; import com.yugabyte.yw.common.PlacementInfoUtil; +import com.yugabyte.yw.common.PlatformServiceException; import com.yugabyte.yw.common.ShellResponse; import com.yugabyte.yw.controllers.UniverseControllerRequestBinder; import com.yugabyte.yw.forms.UniverseDefinitionTaskParams; @@ -154,9 +155,10 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_TASK_SEQUENCE = ImmutableList.of( + TaskType.CheckUnderReplicatedTablets, + TaskType.FreezeUniverse, TaskType.ModifyBlackList, TaskType.SetNodeState, - TaskType.CheckUnderReplicatedTablets, TaskType.ModifyBlackList, TaskType.WaitForLeaderBlacklistCompletion, TaskType.AnsibleClusterServerCtl, @@ -169,9 +171,10 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_TASK_EXPECTED_RESULTS = ImmutableList.of( Json.toJson(ImmutableMap.of()), - Json.toJson(ImmutableMap.of("state", "Stopping")), Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of()), + Json.toJson(ImmutableMap.of("state", "Stopping")), + Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of("process", "tserver", "command", "stop")), Json.toJson(ImmutableMap.of()), @@ -182,9 +185,10 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_WITH_YBC_TASK_SEQUENCE = ImmutableList.of( + TaskType.CheckUnderReplicatedTablets, + TaskType.FreezeUniverse, TaskType.ModifyBlackList, TaskType.SetNodeState, - TaskType.CheckUnderReplicatedTablets, TaskType.ModifyBlackList, TaskType.WaitForLeaderBlacklistCompletion, TaskType.AnsibleClusterServerCtl, @@ -198,9 +202,10 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_WITH_YBC_TASK_EXPECTED_RESULTS = ImmutableList.of( Json.toJson(ImmutableMap.of()), - Json.toJson(ImmutableMap.of("state", "Stopping")), Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of()), + Json.toJson(ImmutableMap.of("state", "Stopping")), + Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of("process", "tserver", "command", "stop")), Json.toJson(ImmutableMap.of()), @@ -212,9 +217,10 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_TASK_SEQUENCE_MASTER = ImmutableList.of( + TaskType.CheckUnderReplicatedTablets, + TaskType.FreezeUniverse, TaskType.ModifyBlackList, TaskType.SetNodeState, - TaskType.CheckUnderReplicatedTablets, TaskType.ModifyBlackList, TaskType.WaitForLeaderBlacklistCompletion, TaskType.AnsibleClusterServerCtl, @@ -236,9 +242,10 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_TASK_SEQUENCE_MASTER_RESULTS = ImmutableList.of( Json.toJson(ImmutableMap.of()), - Json.toJson(ImmutableMap.of("state", "Stopping")), Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of()), + Json.toJson(ImmutableMap.of("state", "Stopping")), + Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of("process", "tserver", "command", "stop")), Json.toJson(ImmutableMap.of()), @@ -258,9 +265,10 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_WITH_YBC_TASK_SEQUENCE_MASTER = ImmutableList.of( + TaskType.CheckUnderReplicatedTablets, + TaskType.FreezeUniverse, TaskType.ModifyBlackList, TaskType.SetNodeState, - TaskType.CheckUnderReplicatedTablets, TaskType.ModifyBlackList, TaskType.WaitForLeaderBlacklistCompletion, TaskType.AnsibleClusterServerCtl, @@ -283,9 +291,10 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_WITH_YBC_TASK_SEQUENCE_MASTER_RESULTS = ImmutableList.of( Json.toJson(ImmutableMap.of()), - Json.toJson(ImmutableMap.of("state", "Stopping")), Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of()), + Json.toJson(ImmutableMap.of("state", "Stopping")), + Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of("process", "tserver", "command", "stop")), Json.toJson(ImmutableMap.of()), @@ -306,6 +315,7 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_TASK_SEQUENCE_DEDICATED_MASTER = ImmutableList.of( + TaskType.FreezeUniverse, TaskType.SetNodeState, TaskType.ChangeMasterConfig, TaskType.AnsibleClusterServerCtl, @@ -322,6 +332,7 @@ private TaskInfo submitTask(NodeTaskParams taskParams, String nodeName) { private static final List STOP_NODE_DEDICATED_MASTER_EXPECTED_RESULTS = ImmutableList.of( + Json.toJson(ImmutableMap.of()), Json.toJson(ImmutableMap.of("state", "Stopping")), Json.toJson(ImmutableMap.of("opType", "RemoveMaster")), Json.toJson(ImmutableMap.of("process", "master", "command", "stop")), @@ -557,9 +568,8 @@ public void testStopUnknownNode() { UniverseControllerRequestBinder.deepCopy( defaultUniverse.getUniverseDetails(), NodeTaskParams.class); taskParams.setUniverseUUID(defaultUniverse.getUniverseUUID()); - TaskInfo taskInfo = submitTask(taskParams, "host-n9"); - verify(mockNodeManager, times(0)).nodeCommand(any(), any()); - assertEquals(Failure, taskInfo.getTaskState()); + // Throws at validateParams check. + assertThrows(PlatformServiceException.class, () -> submitTask(taskParams, "host-n9")); } @Test