From 38f4065e617521fdefff263bac35223260775cd3 Mon Sep 17 00:00:00 2001 From: Ignasi Barrera Date: Tue, 14 May 2013 08:28:56 +0200 Subject: [PATCH] JCLOUDS-3: Bootstrap nodes in a custom environment Added the environment where the nodes in a group must be created in the bootstrap data bag. This way the configuration is persisted and can be used between runs, such as the node run list. To accomodate the new bootstrap parameter, the method in the ChefService used to create the data bag has been refactored and a the new BootstrapConfig object has been created. This way, we'll be able to extend the information in the bootstrap databag in the future without changing the ChefService interface. --- .../main/java/org/jclouds/chef/ChefService.java | 32 ++++--- .../org/jclouds/chef/domain/BootstrapConfig.java | 99 ++++++++++++++++++++++ .../jclouds/chef/functions/GroupToBootScript.java | 16 +++- .../org/jclouds/chef/internal/BaseChefService.java | 59 +++++++------ .../chef/functions/GroupToBootScriptTest.java | 60 ++++++++++--- .../jclouds/chef/internal/BaseChefServiceTest.java | 38 +++++---- core/src/test/resources/bootstrap-env.sh | 56 ++++++++++++ 7 files changed, 288 insertions(+), 72 deletions(-) create mode 100644 core/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java create mode 100755 core/src/test/resources/bootstrap-env.sh diff --git a/core/src/main/java/org/jclouds/chef/ChefService.java b/core/src/main/java/org/jclouds/chef/ChefService.java index a3a434f..c78899a 100644 --- a/core/src/main/java/org/jclouds/chef/ChefService.java +++ b/core/src/main/java/org/jclouds/chef/ChefService.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; +import org.jclouds.chef.domain.BootstrapConfig; import org.jclouds.chef.domain.Client; import org.jclouds.chef.domain.CookbookVersion; import org.jclouds.chef.domain.Environment; @@ -74,22 +75,15 @@ public interface ChefService { Statement createBootstrapScriptForGroup(String group); /** - * assigns a run list to all nodes bootstrapped with a certain group - * - * @param runList - * list of recipes or roles to assign. syntax is - * {@code recipe[name]} and {@code role[name]} + * Configures how the nodes of a certain group will be bootstrapped * * @param group - * corresponds to a configured - * {@link org.jclouds.chef.config.ChefProperties#CHEF_BOOTSTRAP_DATABAG - * databag} where run_list and other information are stored - * @deprecated use - * {@link ChefService#updateBootstrapConfigForGroup(Iterable, String) - + * The group where the given bootstrap configuration will be + * applied. + * @param bootstrapConfig + * The configuration to be applied to the nodes in the group. */ - @Deprecated - void updateRunListForGroup(Iterable runList, String group); + void updateBootstrapConfigForGroup(String group, BootstrapConfig bootstrapConfig); /** * assigns a run list to all nodes bootstrapped with a certain group @@ -102,9 +96,11 @@ public interface ChefService { * corresponds to a configured * {@link org.jclouds.chef.config.ChefProperties#CHEF_BOOTSTRAP_DATABAG * databag} where run_list and other information are stored - * @see #makeChefApiBootstrapScriptForTag + * @deprecated Use {link + * {@link #updateBootstrapConfigForGroup(String, BootstrapConfig)} */ - public void updateBootstrapConfigForGroup(Iterable runList, String group); + @Deprecated + void updateBootstrapConfigForGroup(Iterable runList, String group); /** * assigns a run list to all nodes bootstrapped with a certain group, and @@ -123,9 +119,11 @@ public interface ChefService { * corresponds to a configured * {@link org.jclouds.chef.config.ChefProperties#CHEF_BOOTSTRAP_DATABAG * databag} where run_list and other information are stored - * @see #makeChefApiBootstrapScriptForTag + * @deprecated Use {link + * {@link #updateBootstrapConfigForGroup(String, BootstrapConfig)} */ - public void updateBootstrapConfigForGroup(Iterable runList, JsonBall jsonAttributes, String group); + @Deprecated + void updateBootstrapConfigForGroup(Iterable runList, JsonBall jsonAttributes, String group); /** * @param group diff --git a/core/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java b/core/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java new file mode 100644 index 0000000..6d00ff2 --- /dev/null +++ b/core/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java @@ -0,0 +1,99 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.chef.domain; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.addAll; + +import java.util.List; + +import org.jclouds.domain.JsonBall; + +import com.google.common.base.Optional; +import com.google.common.collect.Lists; + +/** + * Configures how the nodes in a group will bootstrap. + * + * @author Ignasi Barrera + * @since 1.7 + */ +public class BootstrapConfig { + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private List runList = Lists.newArrayList(); + private String environment; + private JsonBall attribtues; + + /** + * Sets the run list that will be executed in the nodes of the group. + */ + public Builder runList(Iterable runList) { + addAll(this.runList, checkNotNull(runList, "runList")); + return this; + } + + /** + * Sets the environment where the nodes in the group will be deployed. + */ + public Builder environment(String environment) { + this.environment = checkNotNull(environment, "environment"); + return this; + } + + /** + * Sets the attributes that will be populated to the deployed nodes. + */ + public Builder attributes(JsonBall attributes) { + this.attribtues = checkNotNull(attributes, "attributes"); + return this; + } + + public BootstrapConfig build() { + return new BootstrapConfig(runList, Optional.fromNullable(environment), Optional.fromNullable(attribtues)); + } + } + + private List runList = Lists.newArrayList(); + private Optional environment; + private Optional attribtues; + + protected BootstrapConfig(List runList, Optional environment, Optional attribtues) { + this.runList = checkNotNull(runList, "runList"); + this.environment = checkNotNull(environment, "environment"); + this.attribtues = checkNotNull(attribtues, "attributes"); + } + + public List getRunList() { + return runList; + } + + public Optional getEnvironment() { + return environment; + } + + public Optional getAttribtues() { + return attribtues; + } + +} diff --git a/core/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java b/core/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java index 37baea8..e619799 100644 --- a/core/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java +++ b/core/src/main/java/org/jclouds/chef/functions/GroupToBootScript.java @@ -44,11 +44,13 @@ 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; import com.google.common.base.Supplier; import com.google.common.cache.CacheLoader; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.inject.TypeLiteral; /** @@ -82,6 +84,7 @@ public class GroupToBootScript implements Function { this.validatorCredential = checkNotNull(validatorCredential, validatorCredential); } + @Override public Statement apply(String group) { checkNotNull(group, "group"); String validatorClientName = validatorName.get(); @@ -94,6 +97,10 @@ public class GroupToBootScript implements Function { throw propagate(e); } + Map config = json.fromJson(bootstrapConfig.toString(), + BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE); + Optional environment = Optional.fromNullable(config.get("environment")); + String chefConfigDir = "{root}etc{fs}chef"; Statement createChefConfigDir = exec("{md} " + chefConfigDir); Statement createClientRb = appendFile(chefConfigDir + "{fs}client.rb", ImmutableList.of("require 'rubygems'", @@ -106,10 +113,15 @@ public class GroupToBootScript implements Function { Splitter.on('\n').split(Pems.pem(validatorKey))); String chefBootFile = chefConfigDir + "{fs}first-boot.json"; - Statement createFirstBoot = appendFile(chefBootFile, Collections.singleton(json.toJson(bootstrapConfig))); - Statement runChef = exec("chef-client -j " + chefBootFile); + ImmutableMap.Builder options = ImmutableMap.builder(); + options.put("-j", chefBootFile); + if (environment.isPresent()) { + options.put("-E", environment.get().toString()); + } + String strOptions = Joiner.on(' ').withKeyValueSeparator(" ").join(options.build()); + Statement runChef = exec("chef-client " + strOptions); return newStatementList(installChefGems, createChefConfigDir, createClientRb, createValidationPem, createFirstBoot, runChef); diff --git a/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java b/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java index b1532a4..3e4611c 100644 --- a/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java +++ b/core/src/main/java/org/jclouds/chef/internal/BaseChefService.java @@ -36,6 +36,7 @@ import org.jclouds.chef.ChefApi; import org.jclouds.chef.ChefContext; import org.jclouds.chef.ChefService; import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.BootstrapConfig; import org.jclouds.chef.domain.Client; import org.jclouds.chef.domain.CookbookVersion; import org.jclouds.chef.domain.DatabagItem; @@ -63,10 +64,8 @@ import org.jclouds.logging.Logger; import org.jclouds.scriptbuilder.domain.Statement; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.io.ByteStreams; import com.google.common.io.InputSupplier; @@ -210,26 +209,15 @@ public class BaseChefService implements ChefService { } @Override - @Deprecated - public void updateRunListForGroup(Iterable runList, String group) { - updateBootstrapConfigForGroup(runList, group); - } - - @Override - public void updateBootstrapConfigForGroup(Iterable runList, String group) { - updateBootstrapConfigForGroup(runList, null, group); - } - - @Override - public void updateBootstrapConfigForGroup(Iterable runList, @Nullable JsonBall jsonAttributes, String group) { + public void updateBootstrapConfigForGroup(String group, BootstrapConfig bootstrapConfig) { try { api.createDatabag(databag); } catch (IllegalStateException e) { } - String bootstrapConfig = buildBootstrapConfiguration(runList, Optional.fromNullable(jsonAttributes)); - DatabagItem runlist = new DatabagItem(group, bootstrapConfig); + String jsonConfig = buildBootstrapConfiguration(bootstrapConfig); + DatabagItem runlist = new DatabagItem(group, jsonConfig); if (api.getDatabagItem(databag, group) == null) { api.createDatabagItem(databag, runlist); @@ -239,6 +227,19 @@ public class BaseChefService implements ChefService { } @Override + @Deprecated + public void updateBootstrapConfigForGroup(Iterable runList, String group) { + updateBootstrapConfigForGroup(runList, null, group); + } + + @Override + @Deprecated + public void updateBootstrapConfigForGroup(Iterable runList, @Nullable JsonBall jsonAttributes, String group) { + updateBootstrapConfigForGroup(group, BootstrapConfig.builder().runList(runList).attributes(jsonAttributes) + .build()); + } + + @Override public List getRunListForGroup(String group) { return runListForGroup.apply(group); } @@ -261,18 +262,23 @@ public class BaseChefService implements ChefService { } @VisibleForTesting - String buildBootstrapConfiguration(Iterable runList, Optional jsonAttributes) { - checkNotNull(runList, "runList must not be null"); - checkNotNull(jsonAttributes, "jsonAttributes must not be null"); - - Map bootstrapConfig = Maps.newHashMap(); - bootstrapConfig.put("run_list", Lists.newArrayList(runList)); - if (jsonAttributes.isPresent()) { - Map attributes = json.fromJson(jsonAttributes.get().toString(), + String buildBootstrapConfiguration(BootstrapConfig bootstrapConfig) { + checkNotNull(bootstrapConfig, "bootstrapConfig must not be null"); + + Map configMap = Maps.newHashMap(); + configMap.put("run_list", bootstrapConfig.getRunList()); + + if (bootstrapConfig.getEnvironment().isPresent()) { + configMap.put("environment", bootstrapConfig.getEnvironment().get()); + } + + if (bootstrapConfig.getAttribtues().isPresent()) { + Map attributes = json.fromJson(bootstrapConfig.getAttribtues().get().toString(), BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE); - bootstrapConfig.putAll(attributes); + configMap.putAll(attributes); } - return json.toJson(bootstrapConfig); + + return json.toJson(configMap); } @Override @@ -289,4 +295,5 @@ public class BaseChefService implements ChefService { public Iterable listEnvironmentsNamed(Iterable names) { return listEnvironments.execute(names); } + } diff --git a/core/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java b/core/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java index fbaee25..482fde8 100644 --- a/core/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java +++ b/core/src/test/java/org/jclouds/chef/functions/GroupToBootScriptTest.java @@ -42,6 +42,7 @@ import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.ShellToken; import org.jclouds.scriptbuilder.domain.Statement; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.google.common.base.Charsets; @@ -63,22 +64,29 @@ import com.google.inject.name.Names; @Test(groups = "unit", testName = "GroupToBootScriptTest") public class GroupToBootScriptTest { - Injector injector = Guice.createInjector(new AbstractModule() { - @Override - protected void configure() { - bind(String.class).annotatedWith(ApiVersion.class).toInstance(ChefApi.VERSION); - bind(String.class).annotatedWith(Names.named(CHEF_UPDATE_GEM_SYSTEM)).toInstance("true"); - bind(String.class).annotatedWith(Names.named(CHEF_UPDATE_GEMS)).toInstance("true"); - } - }, new ChefParserModule(), new GsonModule(), new ChefBootstrapModule()); + private Json json; + private Statement installChefGems; + private Optional validatorName; - Json json = injector.getInstance(Json.class); - Statement installChefGems = injector.getInstance(Key.get(Statement.class, Names.named("installChefGems"))); - Optional validatorName = Optional. of("chef-validator"); - Optional validatorCredential = Optional. of(createMock(PrivateKey.class)); + @BeforeClass + public void setup() { + Injector injector = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + bind(String.class).annotatedWith(ApiVersion.class).toInstance(ChefApi.VERSION); + bind(String.class).annotatedWith(Names.named(CHEF_UPDATE_GEM_SYSTEM)).toInstance("true"); + bind(String.class).annotatedWith(Names.named(CHEF_UPDATE_GEMS)).toInstance("true"); + } + }, new ChefParserModule(), new GsonModule(), new ChefBootstrapModule()); + + json = injector.getInstance(Json.class); + installChefGems = injector.getInstance(Key.get(Statement.class, Names.named("installChefGems"))); + validatorName = Optional. of("chef-validator"); + } @Test(expectedExceptions = IllegalStateException.class) public void testMustHaveValidatorName() { + Optional validatorCredential = Optional.of(createMock(PrivateKey.class)); GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json, CacheLoader.from(Functions.forMap(ImmutableMap. of())), installChefGems, Optional. absent(), validatorCredential); @@ -95,6 +103,7 @@ public class GroupToBootScriptTest { @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Key 'foo' not present in map") public void testMustHaveRunScriptsName() { + Optional validatorCredential = Optional.of(createMock(PrivateKey.class)); GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json, CacheLoader.from(Functions.forMap(ImmutableMap. of())), installChefGems, validatorName, validatorCredential); @@ -103,6 +112,7 @@ public class GroupToBootScriptTest { @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "null value in entry: foo=null") public void testMustHaveRunScriptsValue() { + Optional validatorCredential = Optional.of(createMock(PrivateKey.class)); GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json, CacheLoader.from(Functions.forMap(ImmutableMap. of("foo", (DatabagItem) null))), installChefGems, validatorName, validatorCredential); @@ -110,6 +120,7 @@ public class GroupToBootScriptTest { } public void testOneRecipe() throws IOException { + Optional validatorCredential = Optional.of(createMock(PrivateKey.class)); GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json, CacheLoader.from(Functions.forMap(ImmutableMap. of("foo", new JsonBall( "{\"tomcat6\":{\"ssl_port\":8433},\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}")))), @@ -131,4 +142,29 @@ public class GroupToBootScriptTest { verify(validatorKey); } + + public void testOneRecipeAndEnvironment() throws IOException { + Optional validatorCredential = Optional.of(createMock(PrivateKey.class)); + GroupToBootScript fn = new GroupToBootScript(Suppliers.ofInstance(URI.create("http://localhost:4000")), json, + CacheLoader.from(Functions.forMap(ImmutableMap. of("foo", new JsonBall( + "{\"tomcat6\":{\"ssl_port\":8433},\"environment\":\"env\"," + + "\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}")))), installChefGems, + validatorName, validatorCredential); + + PrivateKey validatorKey = validatorCredential.get(); + expect(validatorKey.getEncoded()).andReturn(PemsTest.PRIVATE_KEY.getBytes()); + replay(validatorKey); + + assertEquals( + fn.apply("foo").render(OsFamily.UNIX), + Resources.toString(Resources.getResource("test_install_ruby." + ShellToken.SH.to(OsFamily.UNIX)), + Charsets.UTF_8) + + Resources.toString( + Resources.getResource("test_install_rubygems." + ShellToken.SH.to(OsFamily.UNIX)), + Charsets.UTF_8) + + "gem install chef --no-rdoc --no-ri\n" + + Resources.toString(Resources.getResource("bootstrap-env.sh"), Charsets.UTF_8)); + + verify(validatorKey); + } } diff --git a/core/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java b/core/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java index 65fb31d..46a3f8d 100644 --- a/core/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java +++ b/core/src/test/java/org/jclouds/chef/internal/BaseChefServiceTest.java @@ -24,6 +24,7 @@ import java.util.List; import org.jclouds.ContextBuilder; import org.jclouds.chef.ChefApiMetadata; +import org.jclouds.chef.domain.BootstrapConfig; import org.jclouds.chef.filters.SignedHeaderAuthTest; import org.jclouds.chef.util.RunListBuilder; import org.jclouds.domain.JsonBall; @@ -32,7 +33,6 @@ import org.jclouds.rest.internal.BaseRestApiTest.MockModule; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.inject.Injector; @@ -57,39 +57,47 @@ public class BaseChefServiceTest { chefService = injector.getInstance(BaseChefService.class); } - @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "runList must not be null") - public void testBuildBootstrapConfigurationWithNullRunlist() { - chefService.buildBootstrapConfiguration(null, null); - } - - @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "jsonAttributes must not be null") - public void testBuildBootstrapConfigurationWithNullJsonAttributes() { - chefService.buildBootstrapConfiguration(ImmutableList. of(), null); + @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "bootstrapConfig must not be null") + public void testBuildBootstrapConfigurationWithNullConfig() { + chefService.buildBootstrapConfiguration(null); } public void testBuildBootstrapConfigurationWithEmptyRunlist() { - String config = chefService - .buildBootstrapConfiguration(ImmutableList. of(), Optional. absent()); + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(ImmutableList. of()).build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); assertEquals(config, "{\"run_list\":[]}"); } public void testBuildBootstrapConfigurationWithRunlist() { List runlist = new RunListBuilder().addRecipe("apache2").addRole("webserver").build(); - String config = chefService.buildBootstrapConfiguration(runlist, Optional. absent()); + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist).build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); assertEquals(config, "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}"); } public void testBuildBootstrapConfigurationWithRunlistAndEmptyAttributes() { List runlist = new RunListBuilder().addRecipe("apache2").addRole("webserver").build(); - String config = chefService.buildBootstrapConfiguration(runlist, Optional.of(new JsonBall("{}"))); + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist).attributes(new JsonBall("{}")) + .build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); assertEquals(config, "{\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}"); } public void testBuildBootstrapConfigurationWithRunlistAndAttributes() { List runlist = new RunListBuilder().addRecipe("apache2").addRole("webserver").build(); - String config = chefService.buildBootstrapConfiguration(runlist, - Optional.of(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}"))); + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist) + .attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}")).build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); assertEquals(config, "{\"tomcat6\":{\"ssl_port\":8433},\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}"); } + public void testBuildBootstrapConfigurationWithRunlistAndAttributesAndEnvironment() { + List runlist = new RunListBuilder().addRecipe("apache2").addRole("webserver").build(); + BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runlist) + .attributes(new JsonBall("{\"tomcat6\":{\"ssl_port\":8433}}")).environment("env").build(); + String config = chefService.buildBootstrapConfiguration(bootstrapConfig); + assertEquals(config, + "{\"tomcat6\":{\"ssl_port\":8433},\"environment\":\"env\",\"run_list\":[\"recipe[apache2]\",\"role[webserver]\"]}"); + } + } diff --git a/core/src/test/resources/bootstrap-env.sh b/core/src/test/resources/bootstrap-env.sh new file mode 100755 index 0000000..315e248 --- /dev/null +++ b/core/src/test/resources/bootstrap-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 "foo-" + o[:ipaddress] + 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" -- 1.7.12.4 (Apple Git-37)