You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2014/12/05 00:06:09 UTC

jclouds git commit: JCLOUDS-788 Added support for specifying a custom node name when generating the chef bootstrap node script

Repository: jclouds
Updated Branches:
  refs/heads/master a2a410d05 -> 06653f1dd


JCLOUDS-788 Added support for specifying a custom node name when generating the chef bootstrap node script


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/06653f1d
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/06653f1d
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/06653f1d

Branch: refs/heads/master
Commit: 06653f1dd2af12e66301b42734d6b9d8ada7a472
Parents: a2a410d
Author: William Chu <wi...@me.com>
Authored: Tue Dec 2 14:52:09 2014 -0800
Committer: Ignasi Barrera <na...@apache.org>
Committed: Thu Dec 4 23:47:20 2014 +0100

----------------------------------------------------------------------
 .../main/java/org/jclouds/chef/ChefService.java | 12 +++++
 .../chef/functions/GroupToBootScript.java       | 16 +++---
 .../jclouds/chef/internal/BaseChefService.java  |  8 ++-
 .../chef/functions/GroupToBootScriptTest.java   | 36 ++++++++++---
 .../src/test/resources/bootstrap-node-env.sh    | 56 ++++++++++++++++++++
 5 files changed, 113 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/06653f1d/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/ChefService.java b/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
index 040107a..6f136fa 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
@@ -25,6 +25,7 @@ import org.jclouds.chef.domain.Environment;
 import org.jclouds.chef.domain.Node;
 import org.jclouds.chef.internal.BaseChefService;
 import org.jclouds.domain.JsonBall;
+import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.rest.annotations.SinceApiVersion;
 import org.jclouds.scriptbuilder.domain.Statement;
 
@@ -79,6 +80,17 @@ public interface ChefService {
    Statement createBootstrapScriptForGroup(String group);
 
    /**
+    * Creates all steps necessary to bootstrap the node.
+    *
+    * @param group corresponds to a configured
+    *              {@link ChefProperties#CHEF_BOOTSTRAP_DATABAG} data bag where
+    *              run_list and other information are stored.
+    * @param nodeName The name of the node to create.
+    * @return The script used to bootstrap the node.
+    */
+   Statement createBootstrapScriptForGroup(String group, @Nullable String nodeName);
+
+   /**
     * Configures how the nodes of a certain group will be bootstrapped
     *
     * @param group           The group where the given bootstrap configuration will be

http://git-wip-us.apache.org/repos/asf/jclouds/blob/06653f1d/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java b/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java
index 516d9f9..6010353 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java
@@ -37,13 +37,13 @@ import org.jclouds.chef.config.InstallChef;
 import org.jclouds.chef.config.Validator;
 import org.jclouds.crypto.Pems;
 import org.jclouds.domain.JsonBall;
+import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.Json;
 import org.jclouds.location.Provider;
 import org.jclouds.scriptbuilder.ExitInsteadOfReturn;
 import org.jclouds.scriptbuilder.domain.Statement;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
 import com.google.common.base.Splitter;
@@ -58,7 +58,7 @@ import com.google.inject.TypeLiteral;
  * Generates a bootstrap script relevant for a particular group
  */
 @Singleton
-public class GroupToBootScript implements Function<String, Statement> {
+public class GroupToBootScript {
    private static final Pattern newLinePattern = Pattern.compile("(\\r\\n)|(\\n)");
    
    @VisibleForTesting
@@ -84,8 +84,7 @@ public class GroupToBootScript implements Function<String, Statement> {
       this.validatorCredential = checkNotNull(validatorCredential, validatorCredential);
    }
 
-   @Override
-   public Statement apply(String group) {
+   public Statement apply(String group, @Nullable String nodeName) {
       checkNotNull(group, "group");
       String validatorClientName = validatorName.get();
       PrivateKey validatorKey = validatorCredential.get();
@@ -103,9 +102,14 @@ public class GroupToBootScript implements Function<String, Statement> {
 
       String chefConfigDir = "{root}etc{fs}chef";
       Statement createChefConfigDir = exec("{md} " + chefConfigDir);
+      String createNodeName;
+      if (nodeName != null) {
+        createNodeName = String.format("node_name \"%s\"", nodeName);
+      } else {
+        createNodeName = String.format("node_name \"%s-\" + o[:ipaddress]", group);
+      }
       Statement createClientRb = appendFile(chefConfigDir + "{fs}client.rb", ImmutableList.of("require 'rubygems'",
-            "require 'ohai'", "o = Ohai::System.new", "o.all_plugins",
-            String.format("node_name \"%s-\" + o[:ipaddress]", group), "log_level :info", "log_location STDOUT",
+            "require 'ohai'", "o = Ohai::System.new", "o.all_plugins", createNodeName, "log_level :info", "log_location STDOUT",
             String.format("validation_client_name \"%s\"", validatorClientName),
             String.format("chef_server_url \"%s\"", endpoint.get())));
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/06653f1d/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java b/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
index 3e5769b..838fa4f 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
@@ -61,6 +61,7 @@ import org.jclouds.io.ByteStreams2;
 import org.jclouds.io.Payloads;
 import org.jclouds.io.payloads.RSADecryptingPayload;
 import org.jclouds.io.payloads.RSAEncryptingPayload;
+import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.Json;
 import org.jclouds.logging.Logger;
 import org.jclouds.scriptbuilder.domain.Statement;
@@ -171,8 +172,13 @@ public class BaseChefService implements ChefService {
    }
 
    @Override
+   public Statement createBootstrapScriptForGroup(String group, @Nullable String nodeName) {
+      return groupToBootScript.apply(group, nodeName);
+   }
+
+   @Override
    public Statement createBootstrapScriptForGroup(String group) {
-      return groupToBootScript.apply(group);
+      return groupToBootScript.apply(group, null);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/06653f1d/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java
index 8792025..89b6ec0 100644
--- a/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java
+++ b/apis/chef/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java
@@ -100,7 +100,7 @@ public class GroupToBootScriptTest {
       GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
             CacheLoader.from(Functions.forMap(ImmutableMap.<String, DatabagItem> of())), installChefGems,
             Optional.<String> absent(), validatorCredential);
-      fn.apply("foo");
+      fn.apply("foo", null);
    }
 
    @Test(expectedExceptions = IllegalStateException.class)
@@ -108,7 +108,7 @@ public class GroupToBootScriptTest {
       GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
             CacheLoader.from(Functions.forMap(ImmutableMap.<String, DatabagItem> of())), installChefGems,
             validatorName, Optional.<PrivateKey> absent());
-      fn.apply("foo");
+      fn.apply("foo", null);
    }
 
    @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Key 'foo' not present in map")
@@ -117,7 +117,7 @@ public class GroupToBootScriptTest {
       GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
             CacheLoader.from(Functions.forMap(ImmutableMap.<String, DatabagItem> of())), installChefGems,
             validatorName, validatorCredential);
-      fn.apply("foo");
+      fn.apply("foo", null);
    }
 
    @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "null value in entry: foo=null")
@@ -126,7 +126,7 @@ public class GroupToBootScriptTest {
       GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
             CacheLoader.from(Functions.forMap(ImmutableMap.<String, DatabagItem> of("foo", (DatabagItem) null))),
             installChefGems, validatorName, validatorCredential);
-      fn.apply("foo");
+      fn.apply("foo", null);
    }
 
    public void testOneRecipe() throws IOException {
@@ -141,7 +141,7 @@ public class GroupToBootScriptTest {
       replay(validatorKey);
 
       assertEquals(
-            fn.apply("foo").render(OsFamily.UNIX),
+            fn.apply("foo", null).render(OsFamily.UNIX),
             exitInsteadOfReturn(
                   OsFamily.UNIX,
                   Resources.toString(Resources.getResource("test_install_ruby." + ShellToken.SH.to(OsFamily.UNIX)),
@@ -168,7 +168,7 @@ public class GroupToBootScriptTest {
       replay(validatorKey);
 
       assertEquals(
-            fn.apply("foo").render(OsFamily.UNIX),
+            fn.apply("foo", null).render(OsFamily.UNIX),
             exitInsteadOfReturn(
                   OsFamily.UNIX,
                   Resources.toString(Resources.getResource("test_install_ruby." + ShellToken.SH.to(OsFamily.UNIX)),
@@ -194,7 +194,7 @@ public class GroupToBootScriptTest {
       replay(validatorKey);
 
       assertEquals(
-            fn.apply("foo").render(OsFamily.UNIX),
+            fn.apply("foo", null).render(OsFamily.UNIX),
             "setupPublicCurl || exit 1\ncurl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 "
                   + "-X GET  https://www.opscode.com/chef/install.sh |(bash)\n"
                   + Resources.toString(Resources.getResource("bootstrap.sh"), Charsets.UTF_8));
@@ -215,7 +215,7 @@ public class GroupToBootScriptTest {
       replay(validatorKey);
 
       assertEquals(
-            fn.apply("foo").render(OsFamily.UNIX),
+            fn.apply("foo", null).render(OsFamily.UNIX),
             "setupPublicCurl || exit 1\ncurl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 "
                   + "-X GET  https://www.opscode.com/chef/install.sh |(bash)\n"
                   + Resources.toString(Resources.getResource("bootstrap-env.sh"), Charsets.UTF_8));
@@ -227,4 +227,24 @@ public class GroupToBootScriptTest {
       return input.replaceAll(ShellToken.RETURN.to(family), ShellToken.EXIT.to(family));
    }
 
+  public void testCustomNodeName() throws IOException {
+    Optional<PrivateKey> validatorCredential = Optional.of(createMock(PrivateKey.class));
+    GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json,
+            CacheLoader.from(Functions.forMap(ImmutableMap.<String, JsonBall> of("foo", new JsonBall(
+                    "{\"tomcat6\":{\"ssl_port\":8433},\"environment\":\"env\","
+                            + "\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}")))), installChefOmnibus,
+            validatorName, validatorCredential);
+
+    PrivateKey validatorKey = validatorCredential.get();
+    expect(validatorKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes());
+    replay(validatorKey);
+
+    assertEquals(
+            fn.apply("foo", "bar").render(OsFamily.UNIX),
+            "setupPublicCurl || exit 1\ncurl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 "
+                    + "-X GET  https://www.opscode.com/chef/install.sh |(bash)\n"
+                    + Resources.toString(Resources.getResource("bootstrap-node-env.sh"), Charsets.UTF_8));
+
+    verify(validatorKey);
+  }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/06653f1d/apis/chef/src/test/resources/bootstrap-node-env.sh
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/resources/bootstrap-node-env.sh b/apis/chef/src/test/resources/bootstrap-node-env.sh
new file mode 100755
index 0000000..84713d6
--- /dev/null
+++ b/apis/chef/src/test/resources/bootstrap-node-env.sh
@@ -0,0 +1,56 @@
+mkdir -p /etc/chef
+cat >> /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
+	require 'rubygems'
+	require 'ohai'
+	o = Ohai::System.new
+	o.all_plugins
+	node_name "bar"
+	log_level :info
+	log_location STDOUT
+	validation_client_name "chef-validator"
+	chef_server_url "http://localhost:4000"
+END_OF_JCLOUDS_FILE
+cat >> /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
+	-----BEGIN PRIVATE KEY-----
+	LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVB
+	eWIyWkpKcUdtMEtLUis4bmZRSk5zU2QrRjl0WE5NVjdDZk9jVzZqc3FzOEVaZ2lW
+	ClIwOWhEMUlZT2o0WXFNMHFKT05sZ3lnNHhSV2V3ZFNHN1FUUGoxbEpwVkFpZGE5
+	c1h5MitrenlhZ1pBMUFtME8KWmNicWI1aG9lSURnY1grZURhNzlzMHUwRG9tamNm
+	TzlFS2h2SExCeit6TSszUXFQUmtQVjhuWVRiZnMrSGpWegp6T1U2RDFCMFhSMytJ
+	UFpabDJBbldzMmQwcWhuU3RIY0RVdm5SVlEwUDQ4Mll3TjlWZ2NlT1p0cFB6MERD
+	S0VKCjVUeDVTVHViOGswL3p0L1ZBTUhRYWZMU3VRTUxkMnM0Wkx1T1pwdE4vL3VB
+	c1RteGlyZXFkMzd6KzhaVGRCYkoKOExFcEoraUNYdVNmbTVhVWg3aXc2b3h2VG9Z
+	MkFMNTMraksyVVFJREFRQUJBb0lCQVFEQTg4QjNpL3hXbjB2WApCVnhGYW1DWW9l
+	Y3VOakd3WFhrU3laZXc2MTZBK0VPQ3U0N2JoNGFUdXJkRmJZTDBZRmFBdGFXdnps
+	YU4yZUhnCkRiK0hEdVRlZkUyOStXa2NHazZTc2hQbWl6NVQwWE9DQUlDV3c2d1NW
+	RGtIbUd3UzRqWnZiQUZtN1c4bndHazkKWWh4Z3hGaVJuZ3N3SlpGb3BPTG9GNVdY
+	czJ0ZDhndUlZTnNsTXBvN3R1NTBpRm5CSHdLTzJac1BBazh0OW5uUwp4bERhdkty
+	dXltRW1xSENyMytkdGlvNWVhZW5KY3AzZmpvWEJRT0tVazNpcElJMjlYUkI4TnFl
+	Q1ZWLzdLeHdxCmNrcU9CRWJSd0JjbGNreUliRCtSaUFnS3ZPZWxPUmpFaUU5UjQy
+	dnVxdnhSQTZrOWtkOW83dXRsWDBBVXRwRW4KM2daYzZMZXBBb0dCQVA5YWVsNVk3
+	NStzSzJKSlVOT09oTzhhZTQ1Y2RzaWxwMnlJMFgrVUJhU3VRczIrZHlQcAprcEVI
+	QXhkNHBtbVN2bi84YzlUbEVaaHIrcVliQUJYVlBsRG5jeHBJdXcyQWpiazdzL1M0
+	WGFTS3NScXBYTDU3CnpqL1FPcUxrUms4K09WVjlxNmxNZVFOcUx0RWoxdTZKUHZp
+	WDcwUm8rRlF0UnR0Tk9ZYmZkUC9mQW9HQkFNcEEKWGpSNXdvVjVzVWIrUkVnOXZF
+	dVlvOFJTeU9hcnhxS0ZDSVhWVU5zTE94KzIyK0FLNCtDUXBidWVXTjdqb3RybApZ
+	RDZ1VDZzdldpM0FBQzdraVkwVUkvZmpWUFJDVWk4dFZvUVVFMFRhVTVWTElUYVlP
+	QitXL2JCYURFNE05NTYwCjFOdURXTzkwYmFBNWRmVTQ0aXV6dmEwMnJHSlhLOStu
+	UzNvOG5rL1BBb0dCQUxPTDZkam5EZTRtd0FhRzZKY28KY2Q0eHI4amt5UHpDUlp1
+	eUJDU0Jid3BoSVVYTGM3aERwclBreTA2NG5jSkQxVURtd0lka1hkL2ZwTWtnMlFt
+	QQovQ1VrNkxFRmpNaXNxSG9qT2FDTDlnUVpKUGhMTjVRVU4yeDFQSldHanMxdlFo
+	OFRreDBpVVVDT2E4YlFQWE5SCiszNE9Uc1c2VFVuYTRDU1pBeWNMZmhmZkFvR0JB
+	SWdnVnNlZkJDdnVRa0YwTmVVaG1EQ1JaZmhuZDh5NTVSSFIKMUhDdnFLSWxwdity
+	aGNYL3pteUJMdXRlb3BZeVJKUnNPaUUyRlcwMGk4K3JJUFJ1NFozUTVueWJ4N3cz
+	UHpWOQpvSE41UjViYUU5T3lJNEtwWld6dHBZWWl0WkY2N05jbkF2VlVMSEhPdlZK
+	UUduS1lmTEhKWW1ySkY3R0Exb2pNCkF1TWRGYmpGQW9HQVB4VWh4d0Z5OGdhcUJh
+	aEtVRVpuNEY4MUhGUDVpaEdoa1Q0UUw2QUZQTzJlK0poSUdqdVIKMjcrODVoY0Zx
+	UStISFZ0RnNtODFiL2ErUjdQNFV1Q1JnYzhlQ2p4UU1vSjFYbDRuN1ZialBiSE1u
+	SU4wUnl2ZApPNFpwV0RXWW5DTzAyMUpUT1VVT0o0Si95MDQxNkJ2a3cwejU5eTdz
+	Tlg3d0RCQkhIYksvWENjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
+	-----END PRIVATE KEY-----
+	
+END_OF_JCLOUDS_FILE
+cat >> /etc/chef/first-boot.json <<-'END_OF_JCLOUDS_FILE'
+	{"tomcat6":{"ssl_port":8433},"environment":"env","run_list":["recipe[apache2]","role[webserver]"]}
+END_OF_JCLOUDS_FILE
+chef-client -j /etc/chef/first-boot.json -E "env"