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 2011/03/17 18:00:24 UTC
svn commit: r1082594 - in /incubator/whirr/trunk: ./
core/src/main/java/org/apache/whirr/cluster/actions/
core/src/main/java/org/apache/whirr/service/ core/src/main/resources/
core/src/test/java/org/apache/whirr/service/
services/hadoop/src/main/java/o...
Author: asavu
Date: Thu Mar 17 17:00:24 2011
New Revision: 1082594
URL: http://svn.apache.org/viewvc?rev=1082594&view=rev
Log:
WHIRR-158. Allow users to log into clusters as themselves
Modified:
incubator/whirr/trunk/CHANGES.txt
incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/BootstrapClusterAction.java
incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/ConfigureClusterAction.java
incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java
incubator/whirr/trunk/core/src/main/resources/whirr-default.properties
incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java
incubator/whirr/trunk/services/hadoop/src/main/java/org/apache/whirr/service/hadoop/HadoopProxy.java
Modified: incubator/whirr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/CHANGES.txt?rev=1082594&r1=1082593&r2=1082594&view=diff
==============================================================================
--- incubator/whirr/trunk/CHANGES.txt (original)
+++ incubator/whirr/trunk/CHANGES.txt Thu Mar 17 17:00:24 2011
@@ -15,6 +15,9 @@ Release 0.4.0 - 2011-03-15
WHIRR-198. Support user-defined images (Adrian Cole via asavu)
+ WHIRR-158. Allow users to log into clusters as themselves
+ (Adrian Cole and asavu)
+
IMPROVEMENTS
WHIRR-139. upgrade to version 1 of the "enforcer" plugin (Jakob Homan
Modified: incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/BootstrapClusterAction.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/BootstrapClusterAction.java?rev=1082594&r1=1082593&r2=1082594&view=diff
==============================================================================
--- incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/BootstrapClusterAction.java (original)
+++ incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/BootstrapClusterAction.java Thu Mar 17 17:00:24 2011
@@ -19,9 +19,16 @@
package org.apache.whirr.cluster.actions;
import static org.jclouds.compute.options.TemplateOptions.Builder.runScript;
+import static org.jclouds.scriptbuilder.domain.Statements.appendFile;
+import static org.jclouds.scriptbuilder.domain.Statements.interpret;
+import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
import com.google.common.base.Function;
+import com.google.common.base.Splitter;
import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -56,11 +63,9 @@ import org.jclouds.compute.RunNodesExcep
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey;
-import org.jclouds.scriptbuilder.domain.InstallRSAPrivateKey;
+import org.jclouds.scriptbuilder.InitBuilder;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.domain.Statement;
-import org.jclouds.scriptbuilder.domain.StatementList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -151,17 +156,50 @@ public class BootstrapClusterAction exte
LOG.info("Configuring template");
if (LOG.isDebugEnabled())
LOG.debug("Running script:\n{}", statementBuilder.render(OsFamily.UNIX));
- Statement runScript = new StatementList(
- new AuthorizeRSAPublicKey(clusterSpec.getPublicKey()),
- statementBuilder,
- new InstallRSAPrivateKey(clusterSpec.getPrivateKey()));
+ Statement runScript = addUserAndAuthorizeSudo(
+ clusterSpec.getClusterUser(),
+ clusterSpec.getPublicKey(),
+ clusterSpec.getPrivateKey(),
+ statementBuilder);
TemplateBuilder templateBuilder = computeService.templateBuilder()
.options(runScript(runScript));
strategy.configureTemplateBuilder(clusterSpec, templateBuilder);
return templateBuilder.build();
}
+
+ private static Statement addUserAndAuthorizeSudo(String user,
+ String publicKey, String privateKey, Statement statement) {
+ return new InitBuilder("setup-" + user,// name of the script
+ "/tmp",// working directory
+ "/tmp/logs",// location of stdout.log and stderr.log
+ ImmutableMap.of("newUser", user, "defaultHome", "/home/users"), // variables
+ ImmutableList.<Statement> of(
+ createUserWithPublicAndPrivateKey(user, publicKey, privateKey),
+ makeSudoersOnlyPermitting(user),
+ statement));
+ }
+
+ // must be used inside InitBuilder, as this sets the shell variables used in this statement
+ static Statement createUserWithPublicAndPrivateKey(String username,
+ String publicKey, String privateKey) {
+ // note directory must be created first
+ return newStatementList(interpret("mkdir -p $DEFAULT_HOME/$NEW_USER/.ssh",
+ "useradd --shell /bin/bash -d $DEFAULT_HOME/$NEW_USER $NEW_USER\n"), appendFile(
+ "$DEFAULT_HOME/$NEW_USER/.ssh/authorized_keys", Splitter.on('\n').split(publicKey)),
+ appendFile(
+ "$DEFAULT_HOME/$NEW_USER/.ssh/id_rsa", Splitter.on('\n').split(privateKey)),
+ interpret("chmod 400 $DEFAULT_HOME/$NEW_USER/.ssh/*",
+ "chown -R $NEW_USER $DEFAULT_HOME/$NEW_USER\n"));
+ }
+ // must be used inside InitBuilder, as this sets the shell variables used in this statement
+ static Statement makeSudoersOnlyPermitting(String username) {
+ return newStatementList(interpret("rm /etc/sudoers", "touch /etc/sudoers", "chmod 0440 /etc/sudoers",
+ "chown root /etc/sudoers\n"), appendFile("/etc/sudoers", ImmutableSet.of("root ALL = (ALL) ALL",
+ "%adm ALL = (ALL) ALL", username + " ALL = (ALL) NOPASSWD: ALL")));
+ }
+
private Set<Instance> getInstances(final Set<String> roles,
Set<? extends NodeMetadata> nodes) {
return Sets.newLinkedHashSet(Collections2.transform(Sets.newLinkedHashSet(nodes),
Modified: incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/ConfigureClusterAction.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/ConfigureClusterAction.java?rev=1082594&r1=1082593&r2=1082594&view=diff
==============================================================================
--- incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/ConfigureClusterAction.java (original)
+++ incubator/whirr/trunk/core/src/main/java/org/apache/whirr/cluster/actions/ConfigureClusterAction.java Thu Mar 17 17:00:24 2011
@@ -19,7 +19,6 @@
package org.apache.whirr.cluster.actions;
import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import java.io.IOException;
@@ -78,7 +77,7 @@ public class ConfigureClusterAction exte
ComputeServiceContextBuilder.build(getComputeServiceContextFactory(), clusterSpec);
ComputeService computeService = computeServiceContext.getComputeService();
Credentials credentials = new Credentials(
- Iterables.get(cluster.getInstances(), 0).getLoginCredentials().identity,
+ clusterSpec.getClusterUser(),
clusterSpec.getPrivateKey());
try {
LOG.info("Running configuration script");
Modified: incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java?rev=1082594&r1=1082593&r2=1082594&view=diff
==============================================================================
--- incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java (original)
+++ incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java Thu Mar 17 17:00:24 2011
@@ -135,7 +135,11 @@ public class ClusterSpec {
"urls from. Change this to host your own set of launch scripts."),
LOGIN_USER(String.class, false, "Override the default login user "+
- "used to bootstrap whirr. E.g. ubuntu or myuser:mypass.");
+ "used to bootstrap whirr. E.g. ubuntu or myuser:mypass."),
+
+ CLUSTER_USER(String.class, false, "The name of the user that Whirr " +
+ "will create on all the cluster instances. You have to use " +
+ "this user to login to nodes.");
private Class<?> type;
private boolean multipleArguments;
@@ -370,6 +374,7 @@ public class ClusterSpec {
private List<String> clientCidrs;
private String version;
private String runUrlBase;
+ private String clusterUser;
private Configuration config;
@@ -454,6 +459,7 @@ public class ClusterSpec {
// patch until jclouds 1.0-beta-10
System.setProperty("whirr.login-user", loginUser);
}
+ clusterUser = c.getString(Property.CLUSTER_USER.getConfigName());
this.config = c;
}
@@ -516,9 +522,15 @@ public class ClusterSpec {
public String getVersion() {
return version;
}
+ @Deprecated
public String getRunUrlBase() {
return runUrlBase;
}
+
+ public String getClusterUser() {
+ return clusterUser;
+ }
+
public void setInstanceTemplates(List<InstanceTemplate> instanceTemplates) {
this.instanceTemplates = instanceTemplates;
@@ -629,12 +641,15 @@ public class ClusterSpec {
this.version = version;
}
+ @Deprecated
public void setRunUrlBase(String runUrlBase) {
this.runUrlBase = runUrlBase;
}
-
- //
-
+
+ public void setClusterUser(String user) {
+ this.clusterUser = user;
+ }
+
public Configuration getConfiguration() {
return config;
}
@@ -675,7 +690,6 @@ public class ClusterSpec {
&& Objects.equal(locationId, that.locationId)
&& Objects.equal(clientCidrs, that.clientCidrs)
&& Objects.equal(version, that.version)
- && Objects.equal(runUrlBase, that.runUrlBase)
;
}
return false;
@@ -704,7 +718,6 @@ public class ClusterSpec {
.add("locationId", locationId)
.add("clientCidrs", clientCidrs)
.add("version", version)
- .add("runUrlBase", runUrlBase)
.toString();
}
Modified: incubator/whirr/trunk/core/src/main/resources/whirr-default.properties
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/src/main/resources/whirr-default.properties?rev=1082594&r1=1082593&r2=1082594&view=diff
==============================================================================
--- incubator/whirr/trunk/core/src/main/resources/whirr-default.properties (original)
+++ incubator/whirr/trunk/core/src/main/resources/whirr-default.properties Thu Mar 17 17:00:24 2011
@@ -18,3 +18,5 @@ whirr.private-key-file=${sys:user.home}/
whirr.version=${version}
whirr.max-startup-retries=1
+
+whirr.cluster-user=${sys:user.name}
Modified: incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java?rev=1082594&r1=1082593&r2=1082594&view=diff
==============================================================================
--- incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java (original)
+++ incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java Thu Mar 17 17:00:24 2011
@@ -295,5 +295,12 @@ public class ClusterSpecTest {
assertThat(t1.getMinNumberOfInstances(), is(1));
t2 = templates.get(1);
assertThat(t2.getMinNumberOfInstances(), is(3));
- }
+ }
+
+ @Test
+ public void testClusterUserShouldBeCurrentUser() throws Exception {
+ ClusterSpec spec = ClusterSpec.withTemporaryKeys();
+ assertThat(spec.getClusterUser(), is(System.getProperty("user.name")));
+ }
+
}
Modified: incubator/whirr/trunk/services/hadoop/src/main/java/org/apache/whirr/service/hadoop/HadoopProxy.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/services/hadoop/src/main/java/org/apache/whirr/service/hadoop/HadoopProxy.java?rev=1082594&r1=1082593&r2=1082594&view=diff
==============================================================================
--- incubator/whirr/trunk/services/hadoop/src/main/java/org/apache/whirr/service/hadoop/HadoopProxy.java (original)
+++ incubator/whirr/trunk/services/hadoop/src/main/java/org/apache/whirr/service/hadoop/HadoopProxy.java Thu Mar 17 17:00:24 2011
@@ -56,7 +56,7 @@ public class HadoopProxy {
Files.write(clusterSpec.getPrivateKey(), identity, Charsets.UTF_8);
}
KeyPair.setPermissionsTo600(identity);
- String user = Iterables.get(cluster.getInstances(), 0).getLoginCredentials().identity;
+ String user = clusterSpec.getClusterUser();
InetAddress namenode = HadoopCluster.getNamenodePublicAddress(cluster);
String server = DnsUtil.resolveAddress(namenode.getHostAddress());
return new String[] { "ssh",