You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whirr.apache.org by as...@apache.org on 2012/01/25 14:22:36 UTC
svn commit: r1235735 [1/2] - in /whirr/trunk: ./
cli/src/main/java/org/apache/whirr/cli/
cli/src/main/java/org/apache/whirr/cli/command/
cli/src/main/resources/META-INF/services/
cli/src/test/java/org/apache/whirr/cli/ cli/src/test/java/org/apache/whir...
Author: asavu
Date: Wed Jan 25 13:22:35 2012
New Revision: 1235735
URL: http://svn.apache.org/viewvc?rev=1235735&view=rev
Log:
WHIRR-479. ScriptBasedClusterAction should allow filtering by role and instance-id (asavu)
Added:
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/HelpCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RoleLifecycleCommand.java
whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/BaseCommandTest.java
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureServicesAction.java
whirr/trunk/core/src/main/java/org/apache/whirr/actions/StartServicesAction.java
whirr/trunk/core/src/main/java/org/apache/whirr/actions/StopServicesAction.java
whirr/trunk/core/src/test/java/org/apache/whirr/actions/CleanupClusterActionTest.java
whirr/trunk/core/src/test/java/org/apache/whirr/actions/ConfigureServicesActionTest.java
whirr/trunk/core/src/test/java/org/apache/whirr/actions/ScriptBasedClusterActionTest.java
whirr/trunk/core/src/test/java/org/apache/whirr/actions/StartServicesActionTest.java
whirr/trunk/core/src/test/java/org/apache/whirr/actions/StopServicesActionTest.java
Removed:
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureClusterAction.java
whirr/trunk/core/src/main/java/org/apache/whirr/actions/StartClusterAction.java
whirr/trunk/core/src/main/java/org/apache/whirr/actions/StopClusterAction.java
Modified:
whirr/trunk/CHANGES.txt
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/Main.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/CleanupClusterCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ConfigureServicesCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyInstanceCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListClusterCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListProvidersCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RunScriptCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StartServicesCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StopServicesCommand.java
whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/VersionCommand.java
whirr/trunk/cli/src/main/resources/META-INF/services/org.apache.whirr.command.Command
whirr/trunk/cli/src/test/java/org/apache/whirr/cli/MainTest.java
whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyClusterCommandTest.java
whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyInstanceCommandTest.java
whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/LaunchClusterCommandTest.java
whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/ListClusterCommandTest.java
whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/RunScriptCommandTest.java
whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/VersionCommandTest.java
whirr/trunk/core/src/main/java/org/apache/whirr/ClusterController.java
whirr/trunk/core/src/main/java/org/apache/whirr/actions/CleanupClusterAction.java
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java
whirr/trunk/core/src/main/java/org/apache/whirr/command/AbstractClusterCommand.java
whirr/trunk/core/src/main/java/org/apache/whirr/command/Command.java
whirr/trunk/core/src/main/java/org/apache/whirr/service/DryRunModule.java
whirr/trunk/core/src/test/java/org/apache/whirr/service/DryRunModuleTest.java
whirr/trunk/core/src/test/resources/META-INF/services/org.apache.whirr.service.ClusterActionHandler
Modified: whirr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/whirr/trunk/CHANGES.txt?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/CHANGES.txt (original)
+++ whirr/trunk/CHANGES.txt Wed Jan 25 13:22:35 2012
@@ -27,6 +27,9 @@ Trunk (unreleased changes)
WHIRR-483. Upgrade to jclouds 1.3.1 (asavu)
+ WHIRR-479. ScriptBasedClusterAction should allow filtering by
+ role and instance-id (asavu)
+
BUG FIXES
WHIRR-367. Wrong groupId for zookeeper (Joe Crobak via asavu)
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/Main.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/Main.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/Main.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/Main.java Wed Jan 25 13:22:35 2012
@@ -18,7 +18,6 @@
package org.apache.whirr.cli;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.whirr.command.Command;
@@ -33,6 +32,8 @@ import java.util.Map;
import java.util.ServiceLoader;
import java.util.SortedSet;
+import static com.google.common.collect.Lists.newArrayList;
+
/**
* The entry point for the Whirr CLI.
*/
@@ -42,6 +43,10 @@ public class Main {
private int maxLen = 0;
Main(Command... commands) throws IOException {
+ this(newArrayList(commands));
+ }
+
+ Main(Iterable<Command> commands) throws IOException {
for (Command command : commands) {
commandMap.put(command.getName(), command);
maxLen = Math.max(maxLen, command.getName().length());
@@ -92,7 +97,7 @@ public class Main {
public static void main(String... args) throws Exception {
ServiceLoader<Command> loader = ServiceLoader.load(Command.class);
- Main main = new Main(Lists.newArrayList(loader).toArray(new Command[0]));
+ Main main = new Main(loader);
int rc = main.run(System.in, System.out, System.err, Arrays.asList(args));
System.exit(rc);
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/CleanupClusterCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/CleanupClusterCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/CleanupClusterCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/CleanupClusterCommand.java Wed Jan 25 13:22:35 2012
@@ -18,7 +18,6 @@
package org.apache.whirr.cli.command;
-import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.apache.whirr.ClusterController;
import org.apache.whirr.ClusterControllerFactory;
@@ -54,11 +53,11 @@ public class CleanupClusterCommand exten
List<String> args) throws Exception {
OptionSet optionSet = parser.parse(args.toArray(new String[0]));
-
if (!optionSet.nonOptionArguments().isEmpty()) {
- printUsage(parser, err);
+ printUsage(err);
return -1;
}
+
try {
ClusterSpec clusterSpec = getClusterSpec(optionSet);
ClusterController controller = createClusterController(clusterSpec.getServiceName());
@@ -66,13 +65,13 @@ public class CleanupClusterCommand exten
return 0;
} catch (IllegalArgumentException e) {
- err.println(e.getMessage());
- printUsage(parser, err);
+ printErrorAndHelpHint(err, e);
return -1;
}
}
- private void printUsage(OptionParser parser, PrintStream stream) throws IOException {
+ @Override
+ public void printUsage(PrintStream stream) throws IOException {
stream.println("Usage: whirr cleanup-cluster [OPTIONS]");
stream.println();
parser.printHelpOn(stream);
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ConfigureServicesCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ConfigureServicesCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ConfigureServicesCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ConfigureServicesCommand.java Wed Jan 25 13:22:35 2012
@@ -18,23 +18,18 @@
package org.apache.whirr.cli.command;
-import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.apache.whirr.ClusterController;
import org.apache.whirr.ClusterControllerFactory;
import org.apache.whirr.ClusterSpec;
-import org.apache.whirr.command.AbstractClusterCommand;
import org.apache.whirr.state.ClusterStateStoreFactory;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.List;
/**
* A command to configure the cluster services
*/
-public class ConfigureServicesCommand extends AbstractClusterCommand {
+public class ConfigureServicesCommand extends RoleLifecycleCommand {
public ConfigureServicesCommand() throws IOException {
this(new ClusterControllerFactory());
@@ -48,33 +43,16 @@ public class ConfigureServicesCommand ex
ClusterStateStoreFactory stateStoreFactory) {
super("configure-services", "Configure the cluster services.", factory, stateStoreFactory);
}
-
- @Override
- public int run(InputStream in, PrintStream out, PrintStream err,
- List<String> args) throws Exception {
-
- OptionSet optionSet = parser.parse(args.toArray(new String[0]));
-
- if (!optionSet.nonOptionArguments().isEmpty()) {
- printUsage(parser, err);
- return -1;
- }
- try {
- ClusterSpec clusterSpec = getClusterSpec(optionSet);
- ClusterController controller = createClusterController(clusterSpec.getServiceName());
- controller.configureServices(clusterSpec);
- return 0;
-
- } catch (IllegalArgumentException e) {
- err.println(e.getMessage());
- printUsage(parser, err);
- return -1;
- }
- }
- private void printUsage(OptionParser parser, PrintStream stream) throws IOException {
- stream.println("Usage: whirr configure-services [OPTIONS]");
- stream.println();
- parser.printHelpOn(stream);
+ @Override
+ public int runLifecycleStep(ClusterSpec clusterSpec, ClusterController controller, OptionSet optionSet)
+ throws IOException, InterruptedException {
+ controller.configureServices(
+ clusterSpec,
+ getCluster(clusterSpec, controller),
+ getTargetRolesOrEmpty(optionSet),
+ getTargetInstanceIdsOrEmpty(optionSet)
+ );
+ return 0;
}
}
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyClusterCommand.java Wed Jan 25 13:22:35 2012
@@ -23,7 +23,6 @@ import java.io.InputStream;
import java.io.PrintStream;
import java.util.List;
-import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.apache.whirr.ClusterController;
@@ -51,7 +50,7 @@ public class DestroyClusterCommand exten
OptionSet optionSet = parser.parse(args.toArray(new String[0]));
if (!optionSet.nonOptionArguments().isEmpty()) {
- printUsage(parser, err);
+ printUsage(err);
return -1;
}
try {
@@ -61,15 +60,9 @@ public class DestroyClusterCommand exten
controller.destroyCluster(clusterSpec);
return 0;
} catch (IllegalArgumentException e) {
- err.println(e.getMessage());
- printUsage(parser, err);
+ printErrorAndHelpHint(err, e);
return -1;
}
}
- private void printUsage(OptionParser parser, PrintStream stream) throws IOException {
- stream.println("Usage: whirr destroy-cluster [OPTIONS]");
- stream.println();
- parser.printHelpOn(stream);
- }
}
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyInstanceCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyInstanceCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyInstanceCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/DestroyInstanceCommand.java Wed Jan 25 13:22:35 2012
@@ -23,7 +23,6 @@ import java.io.InputStream;
import java.io.PrintStream;
import java.util.List;
-import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
@@ -57,12 +56,12 @@ public class DestroyInstanceCommand exte
OptionSet optionSet = parser.parse(args.toArray(new String[0]));
if (!optionSet.nonOptionArguments().isEmpty()) {
- printUsage(parser, err);
+ printUsage(err);
return -1;
}
try {
if (!optionSet.hasArgument(instanceOption)) {
- throw new IllegalArgumentException("You need to specify an instance ID.");
+ throw new IllegalArgumentException("--instance-id is a mandatory argument");
}
ClusterSpec clusterSpec = getClusterSpec(optionSet);
ClusterController controller = createClusterController(clusterSpec.getServiceName());
@@ -73,13 +72,13 @@ public class DestroyInstanceCommand exte
return 0;
} catch(IllegalArgumentException e) {
- err.println(e.getMessage());
- printUsage(parser, err);
+ printErrorAndHelpHint(err, e);
return -1;
}
}
- private void printUsage(OptionParser parser, PrintStream stream) throws IOException {
+ @Override
+ public void printUsage(PrintStream stream) throws IOException {
stream.println("Usage: whirr destroy-instance --instance-id <region/ID> [OPTIONS]");
stream.println();
parser.printHelpOn(stream);
Added: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/HelpCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/HelpCommand.java?rev=1235735&view=auto
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/HelpCommand.java (added)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/HelpCommand.java Wed Jan 25 13:22:35 2012
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.whirr.cli.command;
+
+import org.apache.whirr.command.Command;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.List;
+import java.util.ServiceLoader;
+
+public class HelpCommand extends Command {
+
+ public HelpCommand() {
+ super("help", "Show help about an action");
+ }
+
+ @Override
+ public int run(InputStream in, PrintStream out, PrintStream err, List<String> args) throws Exception {
+ if (args.size() == 0) {
+ printUsage(out);
+ return -1;
+ }
+
+ String helpForCommand = args.get(0);
+ ServiceLoader<Command> loader = ServiceLoader.load(Command.class);
+ for(Command command : loader) {
+ if (command.getName().equals(helpForCommand)) {
+ command.printUsage(out);
+ return 0;
+ }
+ }
+
+ err.println("No command found with that name: " + helpForCommand);
+ return -2;
+ }
+
+ @Override
+ public void printUsage(PrintStream stream) throws IOException {
+ stream.println("Usage: whirr help <command>");
+ }
+}
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/LaunchClusterCommand.java Wed Jan 25 13:22:35 2012
@@ -23,7 +23,6 @@ import java.io.InputStream;
import java.io.PrintStream;
import java.util.List;
-import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.apache.whirr.Cluster;
@@ -50,10 +49,10 @@ public class LaunchClusterCommand extend
public int run(InputStream in, PrintStream out, PrintStream err,
List<String> args) throws Exception {
- OptionSet optionSet = parser.parse(args.toArray(new String[0]));
+ OptionSet optionSet = parser.parse(args.toArray(new String[args.size()]));
if (!optionSet.nonOptionArguments().isEmpty()) {
- printUsage(parser, err);
+ printUsage(err);
return -1;
}
@@ -71,15 +70,8 @@ public class LaunchClusterCommand extend
return 0;
} catch (IllegalArgumentException e) {
- err.println(e.getMessage());
- printUsage(parser, err);
+ printErrorAndHelpHint(err, e);
return -1;
}
}
-
- private void printUsage(OptionParser parser, PrintStream stream) throws IOException {
- stream.println("Usage: whirr launch-cluster [OPTIONS]");
- stream.println();
- parser.printHelpOn(stream);
- }
}
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListClusterCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListClusterCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListClusterCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListClusterCommand.java Wed Jan 25 13:22:35 2012
@@ -25,7 +25,6 @@ import java.io.InputStream;
import java.io.PrintStream;
import java.util.List;
-import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.apache.whirr.Cluster;
@@ -58,10 +57,10 @@ public class ListClusterCommand extends
public int run(InputStream in, PrintStream out, PrintStream err,
List<String> args) throws Exception {
- OptionSet optionSet = parser.parse(args.toArray(new String[0]));
+ OptionSet optionSet = parser.parse(args.toArray(new String[args.size()]));
if (!optionSet.nonOptionArguments().isEmpty()) {
- printUsage(parser, err);
+ printUsage(err);
return -1;
}
try {
@@ -83,15 +82,8 @@ public class ListClusterCommand extends
}
return 0;
} catch (IllegalArgumentException e) {
- err.println(e.getMessage());
- printUsage(parser, err);
+ printErrorAndHelpHint(err, e);
return -1;
}
}
-
- private void printUsage(OptionParser parser, PrintStream stream) throws IOException {
- stream.println("Usage: whirr list-cluster [OPTIONS]");
- stream.println();
- parser.printHelpOn(stream);
- }
}
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListProvidersCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListProvidersCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListProvidersCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/ListProvidersCommand.java Wed Jan 25 13:22:35 2012
@@ -59,8 +59,9 @@ public class ListProvidersCommand extend
return 0;
}
- private void printUsage(PrintStream out) {
- out.println("whirr list-providers <compute OR blobstore>");
+ @Override
+ public void printUsage(PrintStream out) {
+ out.println("Usage: whirr list-providers <compute OR blobstore>");
}
private void listBlobstoreProviders(PrintStream out) {
Added: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RoleLifecycleCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RoleLifecycleCommand.java?rev=1235735&view=auto
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RoleLifecycleCommand.java (added)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RoleLifecycleCommand.java Wed Jan 25 13:22:35 2012
@@ -0,0 +1,114 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.whirr.cli.command;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import joptsimple.OptionSet;
+import joptsimple.OptionSpec;
+import org.apache.whirr.ClusterController;
+import org.apache.whirr.ClusterControllerFactory;
+import org.apache.whirr.ClusterSpec;
+import org.apache.whirr.command.AbstractClusterCommand;
+import org.apache.whirr.state.ClusterStateStoreFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.collect.Sets.newHashSet;
+
+public abstract class RoleLifecycleCommand extends AbstractClusterCommand {
+
+ private final static ImmutableSet<String> EMPTYSET = ImmutableSet.of();
+
+ private OptionSpec<String> rolesOption = parser
+ .accepts("roles", "Cluster roles to target")
+ .withRequiredArg().ofType(String.class);
+
+ private OptionSpec<String> instanceIdsOption = parser
+ .accepts("instance-ids", "Cluster instance IDs to target")
+ .withRequiredArg().ofType(String.class);
+
+ public RoleLifecycleCommand(String name, String description,
+ ClusterControllerFactory factory, ClusterStateStoreFactory stateStoreFactory) {
+ super(name, description, factory, stateStoreFactory);
+ }
+
+ /**
+ * Implement this method to trigger the relevant role lifecycle action
+ */
+ public abstract int runLifecycleStep(ClusterSpec clusterSpec, ClusterController controller, OptionSet optionSet)
+ throws IOException, InterruptedException;
+
+ @Override
+ public int run(InputStream in, PrintStream out, PrintStream err, List<String> args) throws Exception {
+ OptionSet optionSet = parser.parse(args.toArray(new String[args.size()]));
+ if (!optionSet.nonOptionArguments().isEmpty()) {
+ printUsage(err);
+ return -1;
+ }
+
+ try {
+ ClusterSpec clusterSpec = getClusterSpec(optionSet);
+ return runLifecycleStep(
+ clusterSpec,
+ createClusterController(clusterSpec.getServiceName()),
+ optionSet
+ );
+
+ } catch (IllegalArgumentException e) {
+ printErrorAndHelpHint(err, e);
+ return -1;
+ }
+ }
+
+ /**
+ * Get the list of targeted roles for this command or an empty set
+ */
+ protected Set<String> getTargetRolesOrEmpty(OptionSet optionSet) {
+ if (optionSet.hasArgument(rolesOption)) {
+ return newHashSet(Splitter.on(",").split(optionSet.valueOf(rolesOption)));
+ }
+ return EMPTYSET;
+ }
+
+ /**
+ * Get the list of targeted instance IDs for this command or an empty set
+ */
+ protected Set<String> getTargetInstanceIdsOrEmpty(OptionSet optionSet) {
+ if (optionSet.hasArgument(instanceIdsOption)) {
+ return newHashSet(Splitter.on(",").split(optionSet.valueOf(instanceIdsOption)));
+ }
+ return EMPTYSET;
+ }
+
+ /**
+ * Print a generic usage indication for this class of commands
+ */
+ @Override
+ public void printUsage(PrintStream stream) throws IOException {
+ stream.println("Usage: whirr " + getName() + " [OPTIONS] [--roles role1,role2] [--instance-ids id1,id2]");
+ stream.println();
+ parser.printHelpOn(stream);
+ }
+
+}
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RunScriptCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RunScriptCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RunScriptCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/RunScriptCommand.java Wed Jan 25 13:22:35 2012
@@ -24,7 +24,6 @@ import com.google.common.collect.Iterabl
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
-import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.apache.commons.lang.StringUtils;
@@ -89,13 +88,13 @@ public class RunScriptCommand extends Ab
OptionSet optionSet = parser.parse(args.toArray(new String[0]));
if (!optionSet.has(scriptOption)) {
err.println("Please specify a script file to be executed.");
- printUsage(parser, err);
+ err.println("Get more help: whirr help " + getName());
return -1;
}
if (!(new File(optionSet.valueOf(scriptOption))).exists()) {
err.printf("Script file '%s' not found.", optionSet.valueOf(scriptOption));
- printUsage(parser, err);
+ err.println("Get more help: whirr help " + getName());
return -2;
}
@@ -109,8 +108,7 @@ public class RunScriptCommand extends Ab
spec, condition, execFile(optionSet.valueOf(scriptOption))));
} catch(IllegalArgumentException e) {
- err.println(e.getMessage());
- printUsage(parser, err);
+ printErrorAndHelpHint(err, e);
return -3;
}
}
@@ -168,8 +166,8 @@ public class RunScriptCommand extends Ab
"\n");
}
- private void printUsage(OptionParser parser,
- PrintStream stream) throws IOException {
+ @Override
+ public void printUsage(PrintStream stream) throws IOException {
stream.println("Usage: whirr run-script [OPTIONS] --script <script> " +
"[--instances id1,id2] [--roles role1,role2]");
stream.println();
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StartServicesCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StartServicesCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StartServicesCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StartServicesCommand.java Wed Jan 25 13:22:35 2012
@@ -18,23 +18,18 @@
package org.apache.whirr.cli.command;
-import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.apache.whirr.ClusterController;
import org.apache.whirr.ClusterControllerFactory;
import org.apache.whirr.ClusterSpec;
-import org.apache.whirr.command.AbstractClusterCommand;
import org.apache.whirr.state.ClusterStateStoreFactory;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.List;
/**
* A command to start the cluster services
*/
-public class StartServicesCommand extends AbstractClusterCommand {
+public class StartServicesCommand extends RoleLifecycleCommand {
public StartServicesCommand() throws IOException {
this(new ClusterControllerFactory());
@@ -48,33 +43,16 @@ public class StartServicesCommand extend
ClusterStateStoreFactory stateStoreFactory) {
super("start-services", "Start the cluster services.", factory, stateStoreFactory);
}
-
- @Override
- public int run(InputStream in, PrintStream out, PrintStream err,
- List<String> args) throws Exception {
-
- OptionSet optionSet = parser.parse(args.toArray(new String[0]));
-
- if (!optionSet.nonOptionArguments().isEmpty()) {
- printUsage(parser, err);
- return -1;
- }
- try {
- ClusterSpec clusterSpec = getClusterSpec(optionSet);
- ClusterController controller = createClusterController(clusterSpec.getServiceName());
- controller.startServices(clusterSpec);
- return 0;
-
- } catch (IllegalArgumentException e) {
- err.println(e.getMessage());
- printUsage(parser, err);
- return -1;
- }
- }
- private void printUsage(OptionParser parser, PrintStream stream) throws IOException {
- stream.println("Usage: whirr start-services [OPTIONS]");
- stream.println();
- parser.printHelpOn(stream);
+ @Override
+ public int runLifecycleStep(ClusterSpec clusterSpec, ClusterController controller, OptionSet optionSet)
+ throws IOException, InterruptedException {
+ controller.startServices(
+ clusterSpec,
+ getCluster(clusterSpec, controller),
+ getTargetRolesOrEmpty(optionSet),
+ getTargetInstanceIdsOrEmpty(optionSet)
+ );
+ return 0;
}
}
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StopServicesCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StopServicesCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StopServicesCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/StopServicesCommand.java Wed Jan 25 13:22:35 2012
@@ -18,23 +18,18 @@
package org.apache.whirr.cli.command;
-import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.apache.whirr.ClusterController;
import org.apache.whirr.ClusterControllerFactory;
import org.apache.whirr.ClusterSpec;
-import org.apache.whirr.command.AbstractClusterCommand;
import org.apache.whirr.state.ClusterStateStoreFactory;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.List;
/**
* A command to stop the cluster services
*/
-public class StopServicesCommand extends AbstractClusterCommand {
+public class StopServicesCommand extends RoleLifecycleCommand {
public StopServicesCommand() throws IOException {
this(new ClusterControllerFactory());
@@ -48,33 +43,16 @@ public class StopServicesCommand extends
ClusterStateStoreFactory stateStoreFactory) {
super("stop-services", "Stop the cluster services.", factory, stateStoreFactory);
}
-
- @Override
- public int run(InputStream in, PrintStream out, PrintStream err,
- List<String> args) throws Exception {
-
- OptionSet optionSet = parser.parse(args.toArray(new String[0]));
-
- if (!optionSet.nonOptionArguments().isEmpty()) {
- printUsage(parser, err);
- return -1;
- }
- try {
- ClusterSpec clusterSpec = getClusterSpec(optionSet);
- ClusterController controller = createClusterController(clusterSpec.getServiceName());
- controller.stopServices(clusterSpec);
- return 0;
-
- } catch (IllegalArgumentException e) {
- err.println(e.getMessage());
- printUsage(parser, err);
- return -1;
- }
- }
- private void printUsage(OptionParser parser, PrintStream stream) throws IOException {
- stream.println("Usage: whirr stop-services [OPTIONS]");
- stream.println();
- parser.printHelpOn(stream);
+ @Override
+ public int runLifecycleStep(ClusterSpec clusterSpec, ClusterController controller, OptionSet optionSet)
+ throws IOException, InterruptedException {
+ controller.stopServices(
+ clusterSpec,
+ getCluster(clusterSpec, controller),
+ getTargetRolesOrEmpty(optionSet),
+ getTargetInstanceIdsOrEmpty(optionSet)
+ );
+ return 0;
}
}
Modified: whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/VersionCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/VersionCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/VersionCommand.java (original)
+++ whirr/trunk/cli/src/main/java/org/apache/whirr/cli/command/VersionCommand.java Wed Jan 25 13:22:35 2012
@@ -18,6 +18,7 @@
package org.apache.whirr.cli.command;
+import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.List;
@@ -45,4 +46,8 @@ public class VersionCommand extends Comm
return 0;
}
+ @Override
+ public void printUsage(PrintStream stream) throws IOException {
+ }
+
}
Modified: whirr/trunk/cli/src/main/resources/META-INF/services/org.apache.whirr.command.Command
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/main/resources/META-INF/services/org.apache.whirr.command.Command?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/main/resources/META-INF/services/org.apache.whirr.command.Command (original)
+++ whirr/trunk/cli/src/main/resources/META-INF/services/org.apache.whirr.command.Command Wed Jan 25 13:22:35 2012
@@ -20,3 +20,4 @@ org.apache.whirr.cli.command.ListCluster
org.apache.whirr.cli.command.ListProvidersCommand
org.apache.whirr.cli.command.RunScriptCommand
org.apache.whirr.cli.command.VersionCommand
+org.apache.whirr.cli.command.HelpCommand
Modified: whirr/trunk/cli/src/test/java/org/apache/whirr/cli/MainTest.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/MainTest.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/test/java/org/apache/whirr/cli/MainTest.java (original)
+++ whirr/trunk/cli/src/test/java/org/apache/whirr/cli/MainTest.java Wed Jan 25 13:22:35 2012
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.Lists;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Collections;
@@ -48,6 +49,10 @@ public class MainTest {
List<String> args) throws Exception {
return 0;
}
+
+ @Override
+ public void printUsage(PrintStream stream) throws IOException {
+ }
}
@Test
Added: whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/BaseCommandTest.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/BaseCommandTest.java?rev=1235735&view=auto
==============================================================================
--- whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/BaseCommandTest.java (added)
+++ whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/BaseCommandTest.java Wed Jan 25 13:22:35 2012
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.whirr.cli.command;
+
+import com.google.common.collect.ListMultimap;
+import org.apache.whirr.service.DryRunModule;
+import org.jclouds.compute.callables.RunScriptOnNode;
+import org.jclouds.compute.callables.RunScriptOnNodeAsInitScriptUsingSsh;
+import org.jclouds.compute.callables.SudoAwareInitManager;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.scriptbuilder.InitBuilder;
+import org.junit.Before;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.util.Map;
+
+import static junit.framework.Assert.fail;
+
+public class BaseCommandTest {
+
+ protected ByteArrayOutputStream outBytes;
+ protected PrintStream out;
+
+ protected ByteArrayOutputStream errBytes;
+ protected PrintStream err;
+
+ @Before
+ public void setUp() {
+ outBytes = new ByteArrayOutputStream();
+ out = new PrintStream(outBytes);
+
+ errBytes = new ByteArrayOutputStream();
+ err = new PrintStream(errBytes);
+ }
+
+ protected void assertNoEntryForPhases(DryRunModule.DryRun dryRun, String... phases) throws Exception {
+ for (String phaseName : phases) {
+ try {
+ fail("Found entry: " + getEntryForPhase(dryRun.getExecutions(), phaseName) + " for phase: " + phaseName);
+ } catch (IllegalStateException e) {
+ // No entry found - OK
+ }
+ }
+ }
+
+ protected void assertExecutedPhases(DryRunModule.DryRun dryRun, String... phases) throws Exception {
+ for (String phaseName : phases) {
+ try {
+ getEntryForPhase(dryRun.getExecutions(), phaseName);
+ } catch (IllegalStateException e) {
+ fail("No entry found for phase: " + phaseName);
+ }
+ }
+ }
+
+ private Map.Entry<NodeMetadata, RunScriptOnNode> getEntryForPhase(
+ ListMultimap<NodeMetadata, RunScriptOnNode> executions, String phaseName)
+ throws Exception {
+ for (Map.Entry<NodeMetadata, RunScriptOnNode> entry : executions.entries()) {
+ if (getScriptName(entry.getValue()).startsWith(phaseName)) {
+ return entry;
+ }
+ }
+ throw new IllegalStateException("phase not found: " + phaseName);
+ }
+
+ private String getScriptName(RunScriptOnNode script) throws Exception {
+ if (script instanceof RunScriptOnNodeAsInitScriptUsingSsh) {
+ Field initField = SudoAwareInitManager.class
+ .getDeclaredField("init");
+ initField.setAccessible(true);
+ return ((InitBuilder) initField
+ .get(script))
+ .getInstanceName();
+ }
+ throw new IllegalArgumentException();
+ }
+}
Modified: whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyClusterCommandTest.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyClusterCommandTest.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyClusterCommandTest.java (original)
+++ whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyClusterCommandTest.java Wed Jan 25 13:22:35 2012
@@ -18,57 +18,35 @@
package org.apache.whirr.cli.command;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import com.google.common.collect.Lists;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.PrintStream;
-import java.util.Collections;
-import java.util.Map;
-
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.whirr.ClusterController;
import org.apache.whirr.ClusterControllerFactory;
import org.apache.whirr.ClusterSpec;
import org.apache.whirr.util.KeyPair;
-import org.hamcrest.Matcher;
-import org.junit.Before;
import org.junit.Test;
-import org.junit.internal.matchers.StringContains;
-public class DestroyClusterCommandTest {
+import java.io.File;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class DestroyClusterCommandTest extends BaseCommandTest {
- private ByteArrayOutputStream outBytes;
- private PrintStream out;
- private ByteArrayOutputStream errBytes;
- private PrintStream err;
-
- @Before
- public void setUp() {
- outBytes = new ByteArrayOutputStream();
- out = new PrintStream(outBytes);
- errBytes = new ByteArrayOutputStream();
- err = new PrintStream(errBytes);
- }
-
@Test
public void testInsufficientOptions() throws Exception {
DestroyClusterCommand command = new DestroyClusterCommand();
int rc = command.run(null, null, err, Collections.<String>emptyList());
assertThat(rc, is(-1));
- assertThat(errBytes.toString(), containsUsageString());
- }
-
- private Matcher<String> containsUsageString() {
- return StringContains.containsString("Usage: whirr destroy-cluster [OPTIONS]");
+ assertThat(errBytes.toString(), containsString("Option 'cluster-name' not set"));
}
@Test
Modified: whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyInstanceCommandTest.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyInstanceCommandTest.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyInstanceCommandTest.java (original)
+++ whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/DestroyInstanceCommandTest.java Wed Jan 25 13:22:35 2012
@@ -18,46 +18,27 @@
package org.apache.whirr.cli.command;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import com.google.common.collect.Lists;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.PrintStream;
-import java.util.Collections;
-import java.util.Map;
-
import org.apache.whirr.ClusterController;
import org.apache.whirr.ClusterControllerFactory;
import org.apache.whirr.ClusterSpec;
import org.apache.whirr.util.KeyPair;
-import org.junit.Before;
import org.junit.Test;
-public class DestroyInstanceCommandTest {
-
- private ByteArrayOutputStream outBytes;
- private PrintStream out;
-
- private ByteArrayOutputStream errBytes;
- private PrintStream err;
+import java.io.File;
+import java.util.Collections;
+import java.util.Map;
- @Before
- public void setUp() {
- outBytes = new ByteArrayOutputStream();
- out = new PrintStream(outBytes);
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
- errBytes = new ByteArrayOutputStream();
- err = new PrintStream(errBytes);
- }
+public class DestroyInstanceCommandTest extends BaseCommandTest {
@Test
public void testInstanceIdMandatory() throws Exception {
@@ -66,10 +47,7 @@ public class DestroyInstanceCommandTest
assertThat(rc, is(-1));
String errOutput = errBytes.toString();
- assertThat(errOutput, containsString("You need to specify " +
- "an instance ID."));
- assertThat(errOutput, containsString("Usage: whirr destroy-instance" +
- " --instance-id <region/ID> [OPTIONS]"));
+ assertThat(errOutput, containsString("--instance-id is a mandatory argument"));
}
@Test
Modified: whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/LaunchClusterCommandTest.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/LaunchClusterCommandTest.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/LaunchClusterCommandTest.java (original)
+++ whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/LaunchClusterCommandTest.java Wed Jan 25 13:22:35 2012
@@ -18,22 +18,8 @@
package org.apache.whirr.cli.command;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.PrintStream;
-import java.util.Collections;
-import java.util.Map;
-
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.whirr.Cluster;
@@ -41,37 +27,31 @@ import org.apache.whirr.ClusterControlle
import org.apache.whirr.ClusterControllerFactory;
import org.apache.whirr.ClusterSpec;
import org.apache.whirr.InstanceTemplate;
+import org.apache.whirr.service.DryRunModule;
import org.apache.whirr.util.KeyPair;
-import org.hamcrest.Matcher;
-import org.junit.Before;
+import org.hamcrest.MatcherAssert;
import org.junit.Test;
-import org.junit.internal.matchers.StringContains;
-public class LaunchClusterCommandTest {
+import java.io.File;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
- private ByteArrayOutputStream outBytes;
- private PrintStream out;
- private ByteArrayOutputStream errBytes;
- private PrintStream err;
-
- @Before
- public void setUp() {
- outBytes = new ByteArrayOutputStream();
- out = new PrintStream(outBytes);
+public class LaunchClusterCommandTest extends BaseCommandTest{
- errBytes = new ByteArrayOutputStream();
- err = new PrintStream(errBytes);
- }
@Test
public void testInsufficientArgs() throws Exception {
LaunchClusterCommand command = new LaunchClusterCommand();
int rc = command.run(null, null, err, Collections.<String>emptyList());
assertThat(rc, is(-1));
- assertThat(errBytes.toString(), containsUsageString());
- }
-
- private Matcher<String> containsUsageString() {
- return StringContains.containsString("Usage: whirr launch-cluster [OPTIONS]");
+ assertThat(errBytes.toString(), containsString("Option 'cluster-name' not set."));
}
@Test
@@ -139,7 +119,7 @@ public class LaunchClusterCommandTest {
"--cluster-name", "test-cluster",
"--instance-templates", "1 hadoop-namenode+hadoop-jobtracker,3 hadoop-datanode+hadoop-tasktracker",
"--instance-templates-max-percent-failures", "60 hadoop-datanode+hadoop-tasktracker",
- "--provider", "ec2",
+ "--provider", "aws-ec2",
"--identity", "myusername", "--credential", "mypassword",
"--private-key-file", keys.get("private").getAbsolutePath(),
"--version", "version-string"
@@ -159,7 +139,7 @@ public class LaunchClusterCommandTest {
.roles("hadoop-datanode", "hadoop-tasktracker").build()
));
expectedClusterSpec.setServiceName("hadoop");
- expectedClusterSpec.setProvider("ec2");
+ expectedClusterSpec.setProvider("aws-ec2");
expectedClusterSpec.setIdentity("myusername");
expectedClusterSpec.setCredential("mypassword");
expectedClusterSpec.setClusterName("test-cluster");
@@ -172,4 +152,23 @@ public class LaunchClusterCommandTest {
assertThat(outBytes.toString(), containsString("Started cluster of 0 instances"));
}
+
+ @Test
+ public void testLaunchClusterUsingDryRun() throws Exception {
+ DryRunModule.resetDryRun();
+
+ ClusterControllerFactory factory = new ClusterControllerFactory();
+ LaunchClusterCommand launchCluster = new LaunchClusterCommand(factory);
+
+ int rc = launchCluster.run(null, out, err, ImmutableList.of(
+ "--cluster-name", "test-cluster-launch",
+ "--state-store", "none",
+ "--instance-templates", "1 zookeeper+cassandra, 1 zookeeper+elasticsearch",
+ "--provider", "stub",
+ "--identity", "dummy"
+ ));
+
+ MatcherAssert.assertThat(rc, is(0));
+ assertExecutedPhases(DryRunModule.DryRun.INSTANCE, "setup", "configure", "start");
+ }
}
Modified: whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/ListClusterCommandTest.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/ListClusterCommandTest.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/ListClusterCommandTest.java (original)
+++ whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/ListClusterCommandTest.java Wed Jan 25 13:22:35 2012
@@ -19,6 +19,7 @@
package org.apache.whirr.cli.command;
import static com.google.common.base.Preconditions.checkArgument;
+import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
@@ -29,9 +30,7 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.PrintStream;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@@ -44,42 +43,22 @@ import org.apache.whirr.state.ClusterSta
import org.apache.whirr.state.ClusterStateStoreFactory;
import org.apache.whirr.state.MemoryClusterStateStore;
import org.apache.whirr.util.KeyPair;
-import org.hamcrest.Matcher;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
-import org.junit.Before;
import org.junit.Test;
-import org.junit.internal.matchers.StringContains;
-public class ListClusterCommandTest {
-
- private ByteArrayOutputStream outBytes;
- private PrintStream out;
- private ByteArrayOutputStream errBytes;
- private PrintStream err;
-
- @Before
- public void setUp() {
- outBytes = new ByteArrayOutputStream();
- out = new PrintStream(outBytes);
- errBytes = new ByteArrayOutputStream();
- err = new PrintStream(errBytes);
- }
+public class ListClusterCommandTest extends BaseCommandTest {
@Test
public void testInsufficientOptions() throws Exception {
ListClusterCommand command = new ListClusterCommand();
int rc = command.run(null, null, err, Collections.<String>emptyList());
assertThat(rc, is(-1));
- assertThat(errBytes.toString(), containsUsageString());
- }
-
- private Matcher<String> containsUsageString() {
- return StringContains.containsString("Usage: whirr list-cluster [OPTIONS]");
+ assertThat(errBytes.toString(), containsString("Option 'cluster-name' not set."));
}
@Test
Modified: whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/RunScriptCommandTest.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/RunScriptCommandTest.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/RunScriptCommandTest.java (original)
+++ whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/RunScriptCommandTest.java Wed Jan 25 13:22:35 2012
@@ -33,13 +33,10 @@ import org.apache.whirr.util.KeyPair;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.domain.Credentials;
import org.jclouds.scriptbuilder.domain.Statement;
-import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.PrintStream;
import java.util.Map;
import java.util.Set;
@@ -53,22 +50,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-public class RunScriptCommandTest {
-
- private ByteArrayOutputStream outBytes;
- private PrintStream out;
-
- private ByteArrayOutputStream errBytes;
- private PrintStream err;
-
- @Before
- public void setUp() {
- outBytes = new ByteArrayOutputStream();
- out = new PrintStream(outBytes);
-
- errBytes = new ByteArrayOutputStream();
- err = new PrintStream(errBytes);
- }
+public class RunScriptCommandTest extends BaseCommandTest {
@Test
public void testScriptPathIsMandatory() throws Exception {
Modified: whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/VersionCommandTest.java
URL: http://svn.apache.org/viewvc/whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/VersionCommandTest.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/VersionCommandTest.java (original)
+++ whirr/trunk/cli/src/test/java/org/apache/whirr/cli/command/VersionCommandTest.java Wed Jan 25 13:22:35 2012
@@ -18,27 +18,16 @@
package org.apache.whirr.cli.command;
+import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
import java.util.Collections;
-import org.junit.Before;
import org.junit.Test;
-public class VersionCommandTest {
-
- private ByteArrayOutputStream outBytes;
- private PrintStream out;
-
- @Before
- public void setUp() {
- outBytes = new ByteArrayOutputStream();
- out = new PrintStream(outBytes);
- }
+public class VersionCommandTest extends BaseCommandTest{
@Test
public void testOverrides() throws Exception {
@@ -46,6 +35,7 @@ public class VersionCommandTest {
int rc = command.run(null, out, null, Collections.<String>emptyList());
assertThat(rc, is(0));
assertThat(outBytes.toString(), startsWith("Apache Whirr "));
+ assertThat(outBytes.toString(), containsString("jclouds"));
}
}
Modified: whirr/trunk/core/src/main/java/org/apache/whirr/ClusterController.java
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/ClusterController.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/ClusterController.java (original)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/ClusterController.java Wed Jan 25 13:22:35 2012
@@ -21,14 +21,15 @@ package org.apache.whirr;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import org.apache.whirr.actions.BootstrapClusterAction;
import org.apache.whirr.actions.CleanupClusterAction;
-import org.apache.whirr.actions.ConfigureClusterAction;
+import org.apache.whirr.actions.ConfigureServicesAction;
import org.apache.whirr.actions.DestroyClusterAction;
-import org.apache.whirr.actions.StartClusterAction;
-import org.apache.whirr.actions.StopClusterAction;
+import org.apache.whirr.actions.StartServicesAction;
+import org.apache.whirr.actions.StopServicesAction;
import org.apache.whirr.service.ClusterActionHandler;
import org.apache.whirr.state.ClusterStateStore;
import org.apache.whirr.state.ClusterStateStoreFactory;
@@ -62,6 +63,7 @@ public class ClusterController {
private static final Logger LOG = LoggerFactory.getLogger(ClusterController.class);
private static final Map<String, ClusterActionHandler> HANDLERS = HandlerMapFactory.create();
+ private static final ImmutableSet<String> EMPTYSET = ImmutableSet.of();
private final Function<ClusterSpec, ComputeServiceContext> getCompute;
private final ClusterStateStoreFactory stateStoreFactory;
@@ -144,7 +146,13 @@ public class ClusterController {
public Cluster configureServices(ClusterSpec clusterSpec, Cluster cluster)
throws IOException, InterruptedException {
- ConfigureClusterAction configurer = new ConfigureClusterAction(getCompute(), HANDLERS);
+ return configureServices(clusterSpec, cluster, EMPTYSET, EMPTYSET);
+ }
+
+ public Cluster configureServices(ClusterSpec clusterSpec, Cluster cluster, Set<String> targetRoles,
+ Set<String> targetInstanceIds) throws IOException, InterruptedException {
+ ConfigureServicesAction configurer = new ConfigureServicesAction(getCompute(), HANDLERS,
+ targetRoles, targetInstanceIds);
return configurer.execute(clusterSpec, cluster);
}
@@ -157,7 +165,12 @@ public class ClusterController {
public Cluster startServices(ClusterSpec clusterSpec, Cluster cluster)
throws IOException, InterruptedException {
- StartClusterAction starter = new StartClusterAction(getCompute(), HANDLERS);
+ return startServices(clusterSpec, cluster, EMPTYSET, EMPTYSET);
+ }
+
+ public Cluster startServices(ClusterSpec clusterSpec, Cluster cluster,
+ Set<String> targetRoles, Set<String> targetInstanceIds) throws IOException, InterruptedException {
+ StartServicesAction starter = new StartServicesAction(getCompute(), HANDLERS, targetRoles, targetInstanceIds);
return starter.execute(clusterSpec, cluster);
}
@@ -170,7 +183,13 @@ public class ClusterController {
public Cluster stopServices(ClusterSpec clusterSpec, Cluster cluster)
throws IOException, InterruptedException {
- StopClusterAction stopper = new StopClusterAction(getCompute(), HANDLERS);
+ return stopServices(clusterSpec, cluster, EMPTYSET, EMPTYSET);
+
+ }
+
+ public Cluster stopServices(ClusterSpec clusterSpec, Cluster cluster, Set<String> targetRoles,
+ Set<String> targetInstanceIds) throws IOException, InterruptedException {
+ StopServicesAction stopper = new StopServicesAction(getCompute(), HANDLERS, targetRoles, targetInstanceIds);
return stopper.execute(clusterSpec, cluster);
}
@@ -186,7 +205,7 @@ public class ClusterController {
CleanupClusterAction cleanner = new CleanupClusterAction(getCompute(), HANDLERS);
return cleanner.execute(clusterSpec, cluster);
}
-
+
/**
* Stop the cluster and destroy all resources associated with it.
*
Modified: whirr/trunk/core/src/main/java/org/apache/whirr/actions/CleanupClusterAction.java
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/actions/CleanupClusterAction.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/actions/CleanupClusterAction.java (original)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/actions/CleanupClusterAction.java Wed Jan 25 13:22:35 2012
@@ -26,6 +26,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
+import java.util.Set;
/**
* A {@link ClusterAction} for cleaning-up the cluster services
@@ -35,11 +36,21 @@ public class CleanupClusterAction extend
private static final Logger LOG = LoggerFactory.getLogger(CleanupClusterAction.class);
public CleanupClusterAction(
- final Function<ClusterSpec, ComputeServiceContext> getCompute,
- final Map<String, ClusterActionHandler> handlerMap) {
+ Function<ClusterSpec, ComputeServiceContext> getCompute,
+ Map<String, ClusterActionHandler> handlerMap
+ ) {
super(getCompute, handlerMap);
}
+ public CleanupClusterAction(
+ Function<ClusterSpec, ComputeServiceContext> getCompute,
+ Map<String, ClusterActionHandler> handlerMap,
+ Set<String> targetRoles,
+ Set<String> targetInstanceIds
+ ) {
+ super(getCompute, handlerMap, targetRoles, targetInstanceIds);
+ }
+
@Override
protected String getAction() {
return ClusterActionHandler.CLEANUP_ACTION;
Added: whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureServicesAction.java
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureServicesAction.java?rev=1235735&view=auto
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureServicesAction.java (added)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureServicesAction.java Wed Jan 25 13:22:35 2012
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.whirr.actions;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.primitives.Ints;
+import org.apache.whirr.ClusterSpec;
+import org.apache.whirr.InstanceTemplate;
+import org.apache.whirr.RolePredicates;
+import org.apache.whirr.service.ClusterActionEvent;
+import org.apache.whirr.service.ClusterActionHandler;
+import org.apache.whirr.service.FirewallManager.Rule;
+import org.jclouds.compute.ComputeServiceContext;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+
+/**
+ * A {@link org.apache.whirr.ClusterAction} for running a configuration script on instances
+ * in the cluster after it has been bootstrapped.
+ */
+public class ConfigureServicesAction extends ScriptBasedClusterAction {
+
+ public ConfigureServicesAction(
+ Function<ClusterSpec, ComputeServiceContext> getCompute,
+ Map<String, ClusterActionHandler> handlerMap
+ ) {
+ super(getCompute, handlerMap);
+ }
+
+ public ConfigureServicesAction(
+ Function<ClusterSpec, ComputeServiceContext> getCompute,
+ Map<String, ClusterActionHandler> handlerMap,
+ Set<String> targetRoles,
+ Set<String> targetInstanceIds
+ ) {
+ super(getCompute, handlerMap, targetRoles, targetInstanceIds);
+ }
+
+ @Override
+ protected String getAction() {
+ return ClusterActionHandler.CONFIGURE_ACTION;
+ }
+
+ /**
+ * Apply the firewall rules specified via configuration.
+ */
+ protected void eventSpecificActions(Entry<InstanceTemplate, ClusterActionEvent> entry)
+ throws IOException {
+ ClusterActionEvent event = entry.getValue();
+ ClusterSpec clusterSpec = event.getClusterSpec();
+
+ Map<String, List<String>> firewallRules = clusterSpec.getFirewallRules();
+ for (String role: firewallRules.keySet()) {
+ if (!roleIsInTarget(role)) {
+ continue; // skip execution for this role
+ }
+ Rule rule = Rule.create();
+
+ if (role == null) {
+ rule.destination(event.getCluster().getInstances());
+ } else {
+ rule.destination(RolePredicates.role(role));
+ }
+
+ List<String> ports = firewallRules.get(role);
+ rule.ports(Ints.toArray(Collections2.transform(ports, new Function<String,Integer>() {
+ @Override
+ public Integer apply(String input) {
+ return Integer.valueOf(input);
+ }
+ })));
+
+ event.getFirewallManager().addRule(rule);
+ }
+ }
+
+}
Modified: whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java (original)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java Wed Jan 25 13:22:35 2012
@@ -18,23 +18,14 @@
package org.apache.whirr.actions;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.apache.whirr.RolePredicates.onlyRolesIn;
-import static org.jclouds.compute.options.RunScriptOptions.Builder.overrideCredentialsWith;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import javax.annotation.Nullable;
-
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ComputationException;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import org.apache.whirr.Cluster;
import org.apache.whirr.Cluster.Instance;
import org.apache.whirr.ClusterAction;
@@ -53,12 +44,21 @@ import org.jclouds.scriptbuilder.domain.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ComputationException;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import javax.annotation.Nullable;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.whirr.RolePredicates.onlyRolesIn;
+import static org.jclouds.compute.options.RunScriptOptions.Builder.overrideCredentialsWith;
/**
* A {@link ClusterAction} that provides the base functionality for running
@@ -70,12 +70,26 @@ public abstract class ScriptBasedCluster
.getLogger(ScriptBasedClusterAction.class);
private final Map<String, ClusterActionHandler> handlerMap;
+ private final ImmutableSet<String> targetRoles;
+ private final ImmutableSet<String> targetInstanceIds;
+
+ protected ScriptBasedClusterAction(
+ Function<ClusterSpec, ComputeServiceContext> getCompute,
+ Map<String, ClusterActionHandler> handlerMap
+ ) {
+ this(getCompute, handlerMap, ImmutableSet.<String>of(), ImmutableSet.<String>of());
+ }
protected ScriptBasedClusterAction(
Function<ClusterSpec, ComputeServiceContext> getCompute,
- final Map<String, ClusterActionHandler> handlerMap) {
+ Map<String, ClusterActionHandler> handlerMap,
+ Set<String> targetRoles,
+ Set<String> targetInstanceIds
+ ) {
super(getCompute);
this.handlerMap = checkNotNull(handlerMap, "handlerMap");
+ this.targetRoles = ImmutableSet.copyOf(checkNotNull(targetRoles, "targetRoles"));
+ this.targetInstanceIds = ImmutableSet.copyOf(checkNotNull(targetInstanceIds, "targetInstanceIds"));
}
public Cluster execute(ClusterSpec clusterSpec, Cluster cluster)
@@ -84,20 +98,23 @@ public abstract class ScriptBasedCluster
Map<InstanceTemplate, ClusterActionEvent> eventMap = Maps.newHashMap();
Cluster newCluster = cluster;
for (InstanceTemplate instanceTemplate : clusterSpec.getInstanceTemplates()) {
+ if (shouldIgnoreInstanceTemplate(instanceTemplate)) {
+ continue; // skip execution if this group of instances is not in target
+ }
StatementBuilder statementBuilder = new StatementBuilder();
- ComputeServiceContext computeServiceContext = getCompute().apply(
- clusterSpec);
+ ComputeServiceContext computeServiceContext = getCompute().apply(clusterSpec);
FirewallManager firewallManager = new FirewallManager(
computeServiceContext, clusterSpec, newCluster);
- ClusterActionEvent event = new ClusterActionEvent(getAction(),
- clusterSpec, instanceTemplate, newCluster, statementBuilder,
- getCompute(), firewallManager);
+ ClusterActionEvent event = new ClusterActionEvent(getAction(), clusterSpec,
+ instanceTemplate, newCluster, statementBuilder, getCompute(), firewallManager);
eventMap.put(instanceTemplate, event);
for (String role : instanceTemplate.getRoles()) {
- safeGetActionHandler(role).beforeAction(event);
+ if (roleIsInTarget(role)) {
+ safeGetActionHandler(role).beforeAction(event);
+ }
}
// cluster may have been updated by handler
@@ -110,13 +127,18 @@ public abstract class ScriptBasedCluster
newCluster = Iterables.get(eventMap.values(), 0).getCluster();
for (InstanceTemplate instanceTemplate : clusterSpec.getInstanceTemplates()) {
+ if (shouldIgnoreInstanceTemplate(instanceTemplate)) {
+ continue;
+ }
ClusterActionEvent event = eventMap.get(instanceTemplate);
for (String role : instanceTemplate.getRoles()) {
- event.setCluster(newCluster);
- safeGetActionHandler(role).afterAction(event);
+ if (roleIsInTarget(role)) {
+ event.setCluster(newCluster);
+ safeGetActionHandler(role).afterAction(event);
- // cluster may have been updated by handler
- newCluster = event.getCluster();
+ // cluster may have been updated by handler
+ newCluster = event.getCluster();
+ }
}
}
@@ -136,56 +158,44 @@ public abstract class ScriptBasedCluster
final ExecutorService executorService = Executors.newCachedThreadPool();
final Collection<Future<ExecResponse>> futures = Sets.newHashSet();
- ClusterSpec clusterSpec = eventMap.values().iterator().next()
- .getClusterSpec();
-
- ComputeServiceContext computeServiceContext = getCompute().apply(
- clusterSpec);
- final ComputeService computeService = computeServiceContext
- .getComputeService();
+ final ClusterSpec clusterSpec = eventMap.values().iterator().next().getClusterSpec();
+ final ComputeServiceContext computeServiceContext = getCompute().apply(clusterSpec);
+ final ComputeService computeService = computeServiceContext.getComputeService();
final Credentials credentials = new Credentials(
clusterSpec.getClusterUser(), clusterSpec.getPrivateKey());
- for (Entry<InstanceTemplate, ClusterActionEvent> entry : eventMap
- .entrySet()) {
+ for (Entry<InstanceTemplate, ClusterActionEvent> entry : eventMap.entrySet()) {
+ if (shouldIgnoreInstanceTemplate(entry.getKey())) {
+ continue; // skip if not in the target
+ }
eventSpecificActions(entry);
Cluster cluster = entry.getValue().getCluster();
-
- StatementBuilder statementBuilder = entry.getValue()
- .getStatementBuilder();
+ StatementBuilder statementBuilder = entry.getValue().getStatementBuilder();
if (statementBuilder.isEmpty()) {
continue; // skip execution if we have an empty list
}
- Set<Instance> instances = cluster.getInstancesMatching(onlyRolesIn(entry
- .getKey().getRoles()));
-
- String instanceIds = Joiner.on(", ").join(
- Iterables.transform(instances, new Function<Instance, String>() {
- @Override
- public String apply(@Nullable Instance instance) {
- return instance == null ? "<null>" : instance.getId();
- }
- }));
-
- LOG.info("Starting to run scripts on cluster for phase {}"
- + "instances: {}", phaseName, instanceIds);
+ Set<Instance> instances = cluster.getInstancesMatching(onlyRolesIn(entry.getKey().getRoles()));
+ LOG.info("Starting to run scripts on cluster for phase {} "
+ + "on instances: {}", phaseName, asString(instances));
for (final Instance instance : instances) {
+ if (instanceIsNotInTarget(instance)) {
+ continue; // skip the script execution
+ }
final Statement statement = statementBuilder.build(clusterSpec, instance);
futures.add(executorService.submit(new Callable<ExecResponse>() {
@Override
public ExecResponse call() {
- LOG.info("Running {} phase script on: {}", phaseName,
- instance.getId());
+ LOG.info("Running {} phase script on: {}", phaseName, instance.getId());
if (LOG.isDebugEnabled()) {
- LOG.debug("{} phase script on: {}\n{}", new Object[] { phaseName,
- instance.getId(), statement.render(OsFamily.UNIX) });
+ LOG.debug("{} phase script on: {}\n{}", new Object[]{phaseName,
+ instance.getId(), statement.render(OsFamily.UNIX)});
}
try {
@@ -223,6 +233,43 @@ public abstract class ScriptBasedCluster
phaseName);
}
+ private String asString(Set<Instance> instances) {
+ return Joiner.on(", ").join(
+ Iterables.transform(instances, new Function<Instance, String>() {
+ @Override
+ public String apply(@Nullable Instance instance) {
+ return instance == null ? "<null>" : instance.getId();
+ }
+ }));
+ }
+
+ protected boolean shouldIgnoreInstanceTemplate(InstanceTemplate template) {
+ return targetRoles.size() != 0 && containsNoneOf(template.getRoles(), targetRoles);
+ }
+
+ protected boolean roleIsInTarget(String role) {
+ return targetRoles.size() == 0 || targetRoles.contains(role);
+ }
+
+ protected boolean instanceIsNotInTarget(Instance instance) {
+ if (targetInstanceIds.size() != 0) {
+ return ! targetInstanceIds.contains(instance.getId());
+ }
+ if (targetRoles.size() != 0) {
+ return containsNoneOf(instance.getRoles(), targetRoles);
+ }
+ return false;
+ }
+
+ private boolean containsNoneOf(Set<String> querySet, final Set<String> target) {
+ return !Iterables.any(querySet, new Predicate<String>() {
+ @Override
+ public boolean apply(@Nullable String role) {
+ return target.contains(role);
+ }
+ });
+ }
+
protected void eventSpecificActions(
Entry<InstanceTemplate, ClusterActionEvent> entry) throws IOException {
}
Added: whirr/trunk/core/src/main/java/org/apache/whirr/actions/StartServicesAction.java
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/actions/StartServicesAction.java?rev=1235735&view=auto
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/actions/StartServicesAction.java (added)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/actions/StartServicesAction.java Wed Jan 25 13:22:35 2012
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.whirr.actions;
+
+import com.google.common.base.Function;
+import org.apache.whirr.ClusterSpec;
+import org.apache.whirr.service.ClusterActionHandler;
+import org.jclouds.compute.ComputeServiceContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A {@link ClusterAction} for starting the cluster services
+ */
+public class StartServicesAction extends ScriptBasedClusterAction {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StartServicesAction.class);
+
+ public StartServicesAction(
+ Function<ClusterSpec, ComputeServiceContext> getCompute,
+ Map<String, ClusterActionHandler> handlerMap
+ ) {
+ super(getCompute, handlerMap);
+ }
+
+ public StartServicesAction(
+ Function<ClusterSpec, ComputeServiceContext> getCompute,
+ Map<String, ClusterActionHandler> handlerMap,
+ Set<String> targetRoles,
+ Set<String> targetInstanceIds
+ ) {
+ super(getCompute, handlerMap, targetRoles, targetInstanceIds);
+ }
+
+ @Override
+ protected String getAction() {
+ return ClusterActionHandler.START_ACTION;
+ }
+}
Added: whirr/trunk/core/src/main/java/org/apache/whirr/actions/StopServicesAction.java
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/actions/StopServicesAction.java?rev=1235735&view=auto
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/actions/StopServicesAction.java (added)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/actions/StopServicesAction.java Wed Jan 25 13:22:35 2012
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.whirr.actions;
+
+import com.google.common.base.Function;
+import org.apache.whirr.ClusterSpec;
+import org.apache.whirr.service.ClusterActionHandler;
+import org.jclouds.compute.ComputeServiceContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A {@link ClusterAction} for stopping the cluster services
+ */
+public class StopServicesAction extends ScriptBasedClusterAction {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StopServicesAction.class);
+
+ public StopServicesAction(
+ Function<ClusterSpec, ComputeServiceContext> getCompute,
+ Map<String, ClusterActionHandler> handlerMap
+ ) {
+ super(getCompute, handlerMap);
+ }
+
+ public StopServicesAction(
+ Function<ClusterSpec, ComputeServiceContext> getCompute,
+ Map<String, ClusterActionHandler> handlerMap,
+ Set<String> targetRoles,
+ Set<String> targetInstanceIds
+ ) {
+ super(getCompute, handlerMap, targetRoles, targetInstanceIds);
+ }
+
+ @Override
+ protected String getAction() {
+ return ClusterActionHandler.STOP_ACTION;
+ }
+}
Modified: whirr/trunk/core/src/main/java/org/apache/whirr/command/AbstractClusterCommand.java
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/command/AbstractClusterCommand.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/command/AbstractClusterCommand.java (original)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/command/AbstractClusterCommand.java Wed Jan 25 13:22:35 2012
@@ -24,6 +24,8 @@ import static org.apache.whirr.ClusterSp
import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.io.PrintStream;
import java.util.EnumSet;
import java.util.Map;
@@ -36,6 +38,7 @@ import org.apache.commons.configuration.
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.whirr.Cluster;
import org.apache.whirr.ClusterController;
import org.apache.whirr.ClusterControllerFactory;
import org.apache.whirr.ClusterSpec;
@@ -65,14 +68,12 @@ public abstract class AbstractClusterCom
.describedAs("config.properties")
.ofType(String.class);
- public AbstractClusterCommand(String name, String description,
- ClusterControllerFactory factory) {
+ public AbstractClusterCommand(String name, String description, ClusterControllerFactory factory) {
this(name, description, factory, new ClusterStateStoreFactory());
}
- public AbstractClusterCommand(String name, String description,
- ClusterControllerFactory factory,
- ClusterStateStoreFactory stateStoreFactory) {
+ public AbstractClusterCommand(String name, String description, ClusterControllerFactory factory,
+ ClusterStateStoreFactory stateStoreFactory) {
super(name, description);
this.factory = factory;
@@ -91,6 +92,9 @@ public abstract class AbstractClusterCom
}
}
+ /**
+ * Load the cluster spec by parsing the command line option set
+ */
protected ClusterSpec getClusterSpec(OptionSet optionSet) throws ConfigurationException {
Configuration optionsConfig = new PropertiesConfiguration();
for (Map.Entry<Property, OptionSpec<?>> entry : optionSpecs.entrySet()) {
@@ -121,6 +125,15 @@ public abstract class AbstractClusterCom
}
/**
+ * Get the cluster instance together with NodeMetadata (through API calls)
+ */
+ protected Cluster getCluster(ClusterSpec clusterSpec, ClusterController controller)
+ throws IOException, InterruptedException {
+ return new Cluster(controller.getInstances(
+ clusterSpec, createClusterStateStore(clusterSpec)));
+ }
+
+ /**
* Create the specified service
*/
protected ClusterController createClusterController(String serviceName) {
@@ -132,8 +145,28 @@ public abstract class AbstractClusterCom
return controller;
}
+ /**
+ * Create the cluster state store object
+ */
protected ClusterStateStore createClusterStateStore(ClusterSpec spec) {
return stateStoreFactory.create(spec);
}
+ /**
+ * Print command execution error and a hint to help the user get more help
+ */
+ protected void printErrorAndHelpHint(PrintStream stream, Throwable e) {
+ stream.println(e.getMessage());
+ stream.println("Help: whirr help " + getName());
+ }
+
+ /**
+ * Print a generic usage indication for commands
+ */
+ @Override
+ public void printUsage(PrintStream stream) throws IOException {
+ stream.println("Usage: whirr " + getName() + " [OPTIONS]");
+ stream.println();
+ parser.printHelpOn(stream);
+ }
}
Modified: whirr/trunk/core/src/main/java/org/apache/whirr/command/Command.java
URL: http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/command/Command.java?rev=1235735&r1=1235734&r2=1235735&view=diff
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/command/Command.java (original)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/command/Command.java Wed Jan 25 13:22:35 2012
@@ -18,6 +18,7 @@
package org.apache.whirr.command;
+import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.List;
@@ -46,4 +47,5 @@ public abstract class Command {
public abstract int run(InputStream in, PrintStream out, PrintStream err,
List<String> args) throws Exception;
+ public abstract void printUsage(PrintStream stream) throws IOException;
}