Repository: incubator-slider Updated Branches: refs/heads/develop 49bf0f1cd -> 5fea3dfc1
SLIDER-657 Introduce --force switch for slider destroy command (Sherry Guo via gourksaha) Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/5fea3dfc Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/5fea3dfc Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/5fea3dfc Branch: refs/heads/develop Commit: 5fea3dfc12076bb9f83875e0edec0a9d537decf1 Parents: 49bf0f1 Author: Gour Saha <[email protected]> Authored: Thu Oct 29 17:06:13 2015 -0700 Committer: Gour Saha <[email protected]> Committed: Thu Oct 29 17:06:13 2015 -0700 ---------------------------------------------------------------------- .../org/apache/slider/client/SliderClient.java | 23 ++++++++++++++- .../apache/slider/client/SliderClientAPI.java | 4 +++ .../slider/common/params/ActionDestroyArgs.java | 7 ++++- .../agent/freezethaw/TestFreezeCommands.groovy | 4 +-- .../standalone/TestStandaloneAMDestroy.groovy | 31 ++++++++++++++++---- .../standalone/TestStandaloneAgentAM.groovy | 5 +++- 6 files changed, 63 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/5fea3dfc/slider-core/src/main/java/org/apache/slider/client/SliderClient.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java index 9a77c67..6a7a65b 100644 --- a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java +++ b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java @@ -21,6 +21,7 @@ package org.apache.slider.client; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.io.Files; + import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.ArrayUtils; @@ -83,6 +84,7 @@ import org.apache.slider.common.params.ActionAMSuicideArgs; import org.apache.slider.common.params.ActionClientArgs; import org.apache.slider.common.params.ActionCreateArgs; import org.apache.slider.common.params.ActionDependencyArgs; +import org.apache.slider.common.params.ActionDestroyArgs; import org.apache.slider.common.params.ActionDiagnosticArgs; import org.apache.slider.common.params.ActionEchoArgs; import org.apache.slider.common.params.ActionExistsArgs; @@ -392,7 +394,7 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe break; case ACTION_DESTROY: - exitCode = actionDestroy(clusterName); + exitCode = actionDestroy(clusterName, serviceArgs.getActionDestroyArgs()); break; case ACTION_DIAGNOSTICS: @@ -609,14 +611,28 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe return client; } + /** + * Keep this signature for backward compatibility with + * force=true by default. + */ @Override public int actionDestroy(String clustername) throws YarnException, IOException { + ActionDestroyArgs destroyArgs = new ActionDestroyArgs(); + destroyArgs.force = true; + return actionDestroy(clustername, destroyArgs); + } + + @Override + public int actionDestroy(String clustername, + ActionDestroyArgs destroyArgs) throws YarnException, IOException { // verify that a live cluster isn't there SliderUtils.validateClusterName(clustername); //no=op, it is now mandatory. verifyBindingsDefined(); verifyNoLiveClusters(clustername, "Destroy"); + boolean forceDestroy = destroyArgs.force; + log.debug("actionDestroy({}, force={})", clustername, forceDestroy); // create the directory path Path clusterDirectory = sliderFileSystem.buildClusterDirPath(clustername); @@ -625,6 +641,11 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe boolean exists = fs.exists(clusterDirectory); if (exists) { log.debug("Application Instance {} found at {}: destroying", clustername, clusterDirectory); + if (!forceDestroy) { + // fail the command if --force is not explicitly specified + throw new UsageException("Destroy will permanently delete directories and registries. " + + "Reissue this command with the --force option if you want to proceed."); + } boolean deleted = fs.delete(clusterDirectory, true); if (!deleted) { http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/5fea3dfc/slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java b/slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java index bab451f..ca5c338 100644 --- a/slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java +++ b/slider-core/src/main/java/org/apache/slider/client/SliderClientAPI.java @@ -28,6 +28,7 @@ import org.apache.slider.common.params.AbstractClusterBuildingActionArgs; import org.apache.slider.common.params.ActionAMSuicideArgs; import org.apache.slider.common.params.ActionClientArgs; import org.apache.slider.common.params.ActionDependencyArgs; +import org.apache.slider.common.params.ActionDestroyArgs; import org.apache.slider.common.params.ActionDiagnosticArgs; import org.apache.slider.common.params.ActionEchoArgs; import org.apache.slider.common.params.ActionFlexArgs; @@ -62,6 +63,9 @@ public interface SliderClientAPI extends Service { * #1 the cluster is started between verifying that there are no live * clusters of that name. */ + int actionDestroy(String clustername, ActionDestroyArgs destroyArgs) + throws YarnException, IOException; + int actionDestroy(String clustername) throws YarnException, IOException; http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/5fea3dfc/slider-core/src/main/java/org/apache/slider/common/params/ActionDestroyArgs.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionDestroyArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionDestroyArgs.java index 1203d28..4a129ab 100644 --- a/slider-core/src/main/java/org/apache/slider/common/params/ActionDestroyArgs.java +++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionDestroyArgs.java @@ -18,15 +18,20 @@ package org.apache.slider.common.params; +import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @Parameters(commandNames = {SliderActions.ACTION_DESTROY}, commandDescription = SliderActions.DESCRIBE_ACTION_DESTROY) public class ActionDestroyArgs extends AbstractActionArgs { - + @Override public String getActionName() { return SliderActions.ACTION_DESTROY; } + + @Parameter(names = {ARG_FORCE}, + description = "force the operation") + public boolean force; } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/5fea3dfc/slider-core/src/test/groovy/org/apache/slider/agent/freezethaw/TestFreezeCommands.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/freezethaw/TestFreezeCommands.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/freezethaw/TestFreezeCommands.groovy index 0473e02..b2fcf8e 100644 --- a/slider-core/src/test/groovy/org/apache/slider/agent/freezethaw/TestFreezeCommands.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/agent/freezethaw/TestFreezeCommands.groovy @@ -144,7 +144,7 @@ class TestFreezeCommands extends AgentMiniClusterTestBase { ServiceLauncher<SliderClient> destroy1 = execSliderCommand(conf, [ SliderActions.ACTION_DESTROY, clustername, - Arguments.ARG_FILESYSTEM, fsDefaultName + Arguments.ARG_FILESYSTEM, fsDefaultName, Arguments.ARG_FORCE ]); fail( "expected a failure from the destroy, got error code ${destroy1.serviceExitCode}"); @@ -168,7 +168,7 @@ class TestFreezeCommands extends AgentMiniClusterTestBase { ServiceLauncher<SliderClient> destroy2 = execSliderCommand(conf, [ SliderActions.ACTION_DESTROY, clustername, - Arguments.ARG_FILESYSTEM, fsDefaultName, + Arguments.ARG_FILESYSTEM, fsDefaultName, Arguments.ARG_FORCE ]); assertSucceeded(destroy2) http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/5fea3dfc/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy index 164f609..e3eb229 100644 --- a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy @@ -25,12 +25,15 @@ import org.apache.slider.agent.AgentMiniClusterTestBase import org.apache.slider.client.SliderClient import org.apache.slider.common.SliderExitCodes import org.apache.slider.common.params.ActionEchoArgs +import org.apache.slider.common.params.ActionDestroyArgs import org.apache.slider.common.params.Arguments import org.apache.slider.common.params.SliderActions import org.apache.slider.common.tools.SliderFileSystem import org.apache.slider.core.exceptions.ErrorStrings import org.apache.slider.core.exceptions.SliderException import org.apache.slider.core.exceptions.UnknownApplicationInstanceException +import org.apache.slider.core.exceptions.UsageException +import org.apache.slider.core.main.LauncherExitCodes import org.apache.slider.core.main.ServiceLauncher import org.junit.Test @@ -113,13 +116,29 @@ class TestStandaloneAMDestroy extends AgentMiniClusterTestBase { describe "END EXPECTED WARNINGS" describe "destroying $clustername" - //now: destroy it - - int exitCode = sliderClient.actionDestroy(clustername); + //now: destroy it without the --force option and + //expect it to fail + + def destroyEx = launchExpectingException(SliderClient, + configuration, + "", + [ + SliderActions.ACTION_DESTROY, + clustername, + Arguments.ARG_FILESYSTEM, fsDefaultName, + Arguments.ARG_MANAGER, RMAddr, + ]) + assert destroyEx instanceof UsageException + + // destroy again but with --force option + describe "destroying $clustername --force" + ActionDestroyArgs destroyArgs = new ActionDestroyArgs() + destroyArgs.force = true + int exitCode = sliderClient.actionDestroy(clustername, destroyArgs); assert 0 == exitCode sleep(1000) // twice, not expecting an error the second time - exitCode = sliderClient.actionDestroy(clustername); + exitCode = sliderClient.actionDestroy(clustername, destroyArgs); assert 0 == exitCode describe "post destroy checks" @@ -171,14 +190,14 @@ class TestStandaloneAMDestroy extends AgentMiniClusterTestBase { "Successful echo of a text document ${echoed.size()} characters long") //try to destroy it while live try { - int ec = cluster2.actionDestroy(clustername) + int ec = cluster2.actionDestroy(clustername, destroyArgs) fail("expected a failure from the destroy, got error code $ec") } catch (SliderException e) { assertFailureClusterInUse(e); } //and try to destroy a completely different cluster just for the fun of it - assert 0 == sliderClient.actionDestroy("no-cluster-of-this-name") + assert 0 == sliderClient.actionDestroy("no-cluster-of-this-name", destroyArgs) maybeStopCluster(cluster2, "", "Teardown at end of test case", false); } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/5fea3dfc/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy index 3707b85..eaf4386 100644 --- a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy @@ -30,6 +30,7 @@ import org.apache.slider.api.ClusterNode import org.apache.slider.client.SliderClient import org.apache.slider.common.SliderKeys import org.apache.slider.common.params.ActionRegistryArgs +import org.apache.slider.common.params.ActionDestroyArgs import org.apache.slider.common.tools.Duration import org.apache.slider.core.build.InstanceBuilder import org.apache.slider.core.conf.AggregateConf @@ -192,7 +193,9 @@ class TestStandaloneAgentAM extends AgentMiniClusterTestBase { assert instance3.yarnApplicationState >= YarnApplicationState.FINISHED // destroy it - client.actionDestroy(newcluster) + ActionDestroyArgs args = new ActionDestroyArgs() + args.force = true; + client.actionDestroy(newcluster, args) }
