mirror of https://github.com/apache/jclouds.git
Improved RubyGems installation.
Enable users to configure the version of RubyGems that will be installed and also if the system and existing gems have to be upgraded after the installation. Also modifies the InstallChefGems statement to allow users to specify the desired version of the Chef gem to install.
This commit is contained in:
parent
c31145e42e
commit
fb70b3fd22
|
@ -22,6 +22,8 @@ import org.jclouds.scriptbuilder.domain.OsFamily;
|
|||
|
||||
public class FunctionNotFoundException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public FunctionNotFoundException(String functionName, OsFamily family) {
|
||||
super("function: " + functionName + " not found for family: " + family);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ public class ChefSolo implements Statement {
|
|||
private List<Role> roles = Lists.newArrayList();
|
||||
private List<DataBag> databags = Lists.newArrayList();
|
||||
private RunList runlist;
|
||||
private String chefVersion;
|
||||
|
||||
/**
|
||||
* Directory where Chef Solo will store files.
|
||||
|
@ -232,13 +233,22 @@ public class ChefSolo implements Statement {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The version of the Chef gem to install.
|
||||
*/
|
||||
public Builder chefVersion(String chefVersion) {
|
||||
this.chefVersion = checkNotNull(chefVersion, "chefVersion");
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChefSolo build() {
|
||||
return new ChefSolo(Optional.of(fileCachePath), Optional.fromNullable(rolePath),
|
||||
Optional.fromNullable(databagPath), Optional.of(cookbookPath.build()),
|
||||
Optional.fromNullable(cookbooksArchiveLocation), Optional.fromNullable(jsonAttributes),
|
||||
Optional.fromNullable(group), Optional.fromNullable(interval), Optional.fromNullable(logLevel),
|
||||
Optional.fromNullable(logFile), Optional.fromNullable(nodeName), Optional.fromNullable(splay),
|
||||
Optional.fromNullable(user), Optional.of(roles), Optional.of(databags), Optional.fromNullable(runlist));
|
||||
Optional.fromNullable(user), Optional.of(roles), Optional.of(databags), Optional.fromNullable(runlist),
|
||||
Optional.fromNullable(chefVersion));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -259,13 +269,14 @@ public class ChefSolo implements Statement {
|
|||
private Optional<List<Role>> roles;
|
||||
private Optional<List<DataBag>> databags;
|
||||
private RunList runlist;
|
||||
private final InstallChefGems installChefGems = new InstallChefGems();
|
||||
private final InstallChefGems installChefGems;
|
||||
|
||||
public ChefSolo(Optional<String> fileCachePath, Optional<String> rolePath, Optional<String> databagPath,
|
||||
Optional<ImmutableList<String>> cookbookPath, Optional<String> cookbooksArchiveLocation,
|
||||
Optional<String> jsonAttributes, Optional<String> group, Optional<Integer> interval,
|
||||
Optional<String> logLevel, Optional<String> logFile, Optional<String> nodeName, Optional<Integer> splay,
|
||||
Optional<String> user, Optional<List<Role>> roles, Optional<List<DataBag>> databags, Optional<RunList> runlist) {
|
||||
Optional<String> user, Optional<List<Role>> roles, Optional<List<DataBag>> databags,
|
||||
Optional<RunList> runlist, Optional<String> chefVersion) {
|
||||
this.fileCachePath = checkNotNull(fileCachePath, "fileCachePath must be set").or(DEFAULT_SOLO_PATH);
|
||||
this.rolePath = checkNotNull(rolePath, "rolePath must be set").or(this.fileCachePath + "/roles");
|
||||
this.databagPath = checkNotNull(databagPath, "databagPath must be set").or(this.fileCachePath + "/data_bags");
|
||||
|
@ -281,11 +292,13 @@ public class ChefSolo implements Statement {
|
|||
this.roles = checkNotNull(roles, "roles must be set");
|
||||
this.databags = checkNotNull(databags, "databags must be set");
|
||||
this.runlist = checkNotNull(runlist, "runlist must be set").or(RunList.builder().build());
|
||||
this.user = checkNotNull(user, "chefVersion must be set");
|
||||
if (!checkNotNull(cookbookPath, "cookbookPath must be set").isPresent() || cookbookPath.get().isEmpty()) {
|
||||
this.cookbookPath = ImmutableList.<String> of(this.fileCachePath + "/cookbooks");
|
||||
} else {
|
||||
this.cookbookPath = ImmutableList.<String> copyOf(cookbookPath.get());
|
||||
}
|
||||
this.installChefGems = InstallChefGems.builder().version(chefVersion.orNull()).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,21 +20,46 @@ package org.jclouds.scriptbuilder.statements.chef;
|
|||
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||
import org.jclouds.scriptbuilder.statements.ruby.InstallRuby;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Installs Chef gems onto a host.
|
||||
*
|
||||
* @author Ignasi Barrera
|
||||
*/
|
||||
public class InstallChefGems extends StatementList {
|
||||
public class InstallChefGems implements Statement {
|
||||
|
||||
public InstallChefGems() {
|
||||
// Chef versions prior to 10.16.4 install an incompatible moneta gem.
|
||||
// See: http://tickets.opscode.com/browse/CHEF-3721
|
||||
super(new InstallRuby(), exec("gem install chef --no-rdoc --no-ri"));
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private Optional<String> version = Optional.absent();
|
||||
|
||||
/**
|
||||
* The version of the Chef gem to install.
|
||||
* <p>
|
||||
* Can be something like '>= 0.10.8'.
|
||||
*/
|
||||
public Builder version(@Nullable String version) {
|
||||
this.version = Optional.fromNullable(version);
|
||||
return this;
|
||||
}
|
||||
|
||||
public InstallChefGems build() {
|
||||
return new InstallChefGems(version);
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<String> version;
|
||||
|
||||
public InstallChefGems(Optional<String> version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,7 +67,16 @@ public class InstallChefGems extends StatementList {
|
|||
if (family == OsFamily.WINDOWS) {
|
||||
throw new UnsupportedOperationException("windows not yet implemented");
|
||||
}
|
||||
return super.render(family);
|
||||
|
||||
Statement statement = version.isPresent() ? exec(String.format("gem install chef -v '%s' --no-rdoc --no-ri",
|
||||
version.get())) : exec("gem install chef --no-rdoc --no-ri");
|
||||
|
||||
return statement.render(family);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> functionDependencies(OsFamily family) {
|
||||
return ImmutableSet.<String> of();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,41 +19,19 @@
|
|||
package org.jclouds.scriptbuilder.statements.ruby;
|
||||
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.call;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.extractTargzAndFlattenIntoDirectory;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||
|
||||
/**
|
||||
* Installs Ruby and Rubygems gems onto a host.
|
||||
* Installs Ruby onto a host.
|
||||
*
|
||||
* @author Ignasi Barrera
|
||||
*/
|
||||
public class InstallRuby extends StatementList {
|
||||
|
||||
private static final URI RUBYGEMS_URI = URI.create("http://production.cf.rubygems.org/rubygems/rubygems-1.8.10.tgz");
|
||||
|
||||
public static Statement installRubyGems() {
|
||||
return new StatementList(//
|
||||
exec("if ! hash gem 2>/dev/null; then"), //
|
||||
exec("("), //
|
||||
extractTargzAndFlattenIntoDirectory(RUBYGEMS_URI, "/tmp/rubygems"), //
|
||||
exec("{cd} /tmp/rubygems"), //
|
||||
exec("ruby setup.rb --no-format-executable"), //
|
||||
exec("{rm} -fr /tmp/rubygems"), //
|
||||
exec(")"), //
|
||||
exec("fi"), //
|
||||
// Make sure RubyGems is up to date
|
||||
exec("gem update --system"), //
|
||||
exec("gem update --no-rdoc --no-ri"));
|
||||
}
|
||||
|
||||
public InstallRuby() {
|
||||
super(call("setupPublicCurl"), call("installRuby"), installRubyGems());
|
||||
super(call("setupPublicCurl"), call("installRuby"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/**
|
||||
* 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.scriptbuilder.statements.ruby;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.extractTargzAndFlattenIntoDirectory;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Installs RubyGems onto a host.
|
||||
*
|
||||
* @author Ignasi Barrera
|
||||
*/
|
||||
public class InstallRubyGems implements Statement {
|
||||
|
||||
public static final String DEFAULT_RUBYGEMS_VERSION = "1.8.10";
|
||||
private static final String RUBYGEMS_URI_TEMPLATE = "http://production.cf.rubygems.org/rubygems/rubygems-%s.tgz";
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private Optional<String> version = Optional.absent();
|
||||
private boolean updateSystem = false;
|
||||
private Optional<String> updateSystemVersion = Optional.absent();
|
||||
private boolean updateExistingGems = false;
|
||||
|
||||
/**
|
||||
* The version of RubyGems to install.
|
||||
*/
|
||||
public Builder version(@Nullable String version) {
|
||||
this.version = Optional.fromNullable(version);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the gem system after installing RubyGems.
|
||||
*/
|
||||
public Builder updateSystem(boolean updateSystem) {
|
||||
this.updateSystem = updateSystem;
|
||||
this.updateSystemVersion = Optional.absent();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the gem system after installing RubyGems, forcing the update to
|
||||
* a concrete version.
|
||||
*/
|
||||
public Builder updateSystem(boolean updateSystem, @Nullable String updateSystemVersion) {
|
||||
this.updateSystem = updateSystem;
|
||||
this.updateSystemVersion = Optional.fromNullable(updateSystemVersion);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the existing gems after installing RubyGems.
|
||||
*/
|
||||
public Builder updateExistingGems(boolean updateExistingGems) {
|
||||
this.updateExistingGems = updateExistingGems;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InstallRubyGems build() {
|
||||
return new InstallRubyGems(version, updateSystem, updateSystemVersion, updateExistingGems);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Optional<String> version;
|
||||
private boolean updateSystem;
|
||||
private Optional<String> updateSystemVersion;
|
||||
private boolean updateExistingGems;
|
||||
|
||||
public InstallRubyGems(Optional<String> version, boolean updateSystem, Optional<String> updateSystemVersion,
|
||||
boolean updateExistingGems) {
|
||||
this.version = checkNotNull(version, "version must be set");
|
||||
this.updateSystem = updateSystem;
|
||||
this.updateSystemVersion = checkNotNull(updateSystemVersion, "updateSystemVersion must be set");
|
||||
this.updateExistingGems = updateExistingGems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(OsFamily family) {
|
||||
if (family == OsFamily.WINDOWS) {
|
||||
throw new UnsupportedOperationException("windows not yet implemented");
|
||||
}
|
||||
|
||||
URI rubygemsUri = URI.create(String.format(RUBYGEMS_URI_TEMPLATE, version.or(DEFAULT_RUBYGEMS_VERSION)));
|
||||
|
||||
ImmutableList.Builder<Statement> statements = ImmutableList.builder();
|
||||
statements.add(exec("if ! hash gem 2>/dev/null; then"));
|
||||
statements.add(exec("("));
|
||||
statements.add(extractTargzAndFlattenIntoDirectory(rubygemsUri, "/tmp/rubygems"));
|
||||
statements.add(exec("{cd} /tmp/rubygems"));
|
||||
statements.add(exec("ruby setup.rb --no-format-executable"));
|
||||
statements.add(exec("{rm} -fr /tmp/rubygems"));
|
||||
statements.add(exec(")"));
|
||||
statements.add(exec("fi"));
|
||||
|
||||
if (updateSystem) {
|
||||
statements.add(updateSystemVersion.isPresent() ? exec("gem update --system " + updateSystemVersion.get())
|
||||
: exec("gem update --system"));
|
||||
}
|
||||
if (updateExistingGems) {
|
||||
statements.add(exec("gem update --no-rdoc --no-ri"));
|
||||
}
|
||||
|
||||
return new StatementList(statements.build()).render(family);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> functionDependencies(OsFamily family) {
|
||||
return ImmutableSet.<String> of();
|
||||
}
|
||||
|
||||
}
|
|
@ -26,7 +26,6 @@ import static org.jclouds.scriptbuilder.domain.Statements.kill;
|
|||
import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.switchArg;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
|
|
|
@ -23,8 +23,6 @@ import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
|||
import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
|
|
@ -26,17 +26,14 @@ import static org.testng.Assert.assertTrue;
|
|||
import java.io.IOException;
|
||||
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.ShellToken;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.scriptbuilder.domain.chef.DataBag;
|
||||
import org.jclouds.scriptbuilder.domain.chef.Role;
|
||||
import org.jclouds.scriptbuilder.domain.chef.RunList;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link ChefSoloTest} statement.
|
||||
|
@ -380,9 +377,18 @@ public class ChefSoloTest {
|
|||
+ "chef-solo -c /var/chef/solo.rb -j /var/chef/node.json -N `hostname` -u foo\n");
|
||||
}
|
||||
|
||||
public void testChefSoloWithChefGemVersion() throws IOException {
|
||||
String script = ChefSolo.builder().chefVersion(">= 0.10.8").build().render(OsFamily.UNIX);
|
||||
assertEquals(script, installChefGems(">= 0.10.8") + createConfigFile() + createNodeFile()
|
||||
+ "chef-solo -c /var/chef/solo.rb -j /var/chef/node.json -N `hostname`\n");
|
||||
}
|
||||
|
||||
private static String installChefGems() throws IOException {
|
||||
return Resources.toString(Resources.getResource("test_install_ruby." + ShellToken.SH.to(OsFamily.UNIX)),
|
||||
Charsets.UTF_8) + "gem install chef --no-rdoc --no-ri\n";
|
||||
return "gem install chef --no-rdoc --no-ri\n";
|
||||
}
|
||||
|
||||
private static String installChefGems(String version) throws IOException {
|
||||
return "gem install chef -v '" + version + "' --no-rdoc --no-ri\n";
|
||||
}
|
||||
|
||||
private static String createConfigFile() {
|
||||
|
|
|
@ -40,21 +40,22 @@ public class InstallChefGemsTest {
|
|||
|
||||
@Test(expectedExceptions = UnsupportedOperationException.class, expectedExceptionsMessageRegExp = "windows not yet implemented")
|
||||
public void installChefGemsInWindows() {
|
||||
new InstallChefGems().render(OsFamily.WINDOWS);
|
||||
InstallChefGems.builder().build().render(OsFamily.WINDOWS);
|
||||
}
|
||||
|
||||
public void installChefGemsUnix() throws IOException {
|
||||
assertEquals(
|
||||
new InstallChefGems().render(OsFamily.UNIX),
|
||||
Resources.toString(Resources.getResource("test_install_ruby." + ShellToken.SH.to(OsFamily.UNIX)),
|
||||
Charsets.UTF_8) + "gem install chef --no-rdoc --no-ri\n");
|
||||
assertEquals(InstallChefGems.builder().build().render(OsFamily.UNIX), "gem install chef --no-rdoc --no-ri\n");
|
||||
}
|
||||
|
||||
public void installChefGemsUnixInScriptBuilderSourcesSetupPublicCurl() throws IOException {
|
||||
assertEquals(
|
||||
InitScript.builder().name("install_chef_gems").run(new InstallChefGems()).build().render(OsFamily.UNIX),
|
||||
Resources.toString(
|
||||
Resources.getResource("test_install_chef_gems_scriptbuilder." + ShellToken.SH.to(OsFamily.UNIX)),
|
||||
Charsets.UTF_8));
|
||||
public void installChefGemsUnixWithCustomVersion() throws IOException {
|
||||
assertEquals(InstallChefGems.builder().version(">= 0.10.8").build().render(OsFamily.UNIX),
|
||||
"gem install chef -v '>= 0.10.8' --no-rdoc --no-ri\n");
|
||||
}
|
||||
|
||||
public void installChefGemsUnixInScriptBuilder() throws IOException {
|
||||
assertEquals(InitScript.builder().name("install_chef_gems").run(InstallChefGems.builder().build()).build()
|
||||
.render(OsFamily.UNIX), Resources.toString(
|
||||
Resources.getResource("test_install_chef_gems_scriptbuilder." + ShellToken.SH.to(OsFamily.UNIX)),
|
||||
Charsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
* 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.scriptbuilder.statements.ruby;
|
||||
|
||||
import static org.jclouds.scriptbuilder.statements.ruby.InstallRubyGems.DEFAULT_RUBYGEMS_VERSION;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jclouds.scriptbuilder.InitScript;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.ShellToken;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link InstallRubyGemsTest} statement.
|
||||
*
|
||||
* @author Ignasi Barrera
|
||||
*/
|
||||
@Test(groups = "unit", testName = "InstallRubyGemsTest")
|
||||
public class InstallRubyGemsTest {
|
||||
|
||||
@Test(expectedExceptions = UnsupportedOperationException.class, expectedExceptionsMessageRegExp = "windows not yet implemented")
|
||||
public void installRubyGemsInWindows() {
|
||||
new InstallRuby().render(OsFamily.WINDOWS);
|
||||
}
|
||||
|
||||
public void installRubyGemsDefaultsUnix() throws IOException {
|
||||
assertEquals(InstallRubyGems.builder().build().render(OsFamily.UNIX), installRubyGems(DEFAULT_RUBYGEMS_VERSION));
|
||||
}
|
||||
|
||||
public void installRubyGemsForcingVersion() throws IOException {
|
||||
assertEquals(InstallRubyGems.builder().version("1.8.25").build().render(OsFamily.UNIX), installRubyGems("1.8.25"));
|
||||
}
|
||||
|
||||
public void installRubyGemsAndUpdateSystem() throws IOException {
|
||||
assertEquals(InstallRubyGems.builder().updateSystem(true).build().render(OsFamily.UNIX),
|
||||
installRubyGems(DEFAULT_RUBYGEMS_VERSION) + updateSystem(null));
|
||||
}
|
||||
|
||||
public void installRubyGemsAndUpdateSystemForcingUpdateVersion() throws IOException {
|
||||
assertEquals(InstallRubyGems.builder().updateSystem(true, "1.8.25").build().render(OsFamily.UNIX),
|
||||
installRubyGems(DEFAULT_RUBYGEMS_VERSION) + updateSystem("1.8.25"));
|
||||
}
|
||||
|
||||
public void installRubyGemsAndUpdateGems() throws IOException {
|
||||
assertEquals(InstallRubyGems.builder().updateExistingGems(true).build().render(OsFamily.UNIX),
|
||||
installRubyGems(DEFAULT_RUBYGEMS_VERSION) + updateGems());
|
||||
}
|
||||
|
||||
public void installRubyGemsUpdatingSystemAndGems() throws IOException {
|
||||
assertEquals(InstallRubyGems.builder().version("1.2.3").updateSystem(true, "1.2.4").updateExistingGems(true)
|
||||
.build().render(OsFamily.UNIX), installRubyGems("1.2.3") + updateSystem("1.2.4") + updateGems());
|
||||
}
|
||||
|
||||
public void installRubyGemsDefaultsWithUpgrade() throws IOException {
|
||||
assertEquals(InstallRubyGems.builder().updateSystem(true).updateExistingGems(true).build().render(OsFamily.UNIX),
|
||||
Resources.toString(Resources.getResource("test_install_rubygems." + ShellToken.SH.to(OsFamily.UNIX)),
|
||||
Charsets.UTF_8));
|
||||
}
|
||||
|
||||
public void installRubyGemsUnixDefaultsInScriptBuilder() throws IOException {
|
||||
assertEquals(
|
||||
InitScript.builder().name("install_rubygems").run(InstallRubyGems.builder().build()).build()
|
||||
.render(OsFamily.UNIX), Resources.toString(
|
||||
Resources.getResource("test_install_rubygems_scriptbuilder." + ShellToken.SH.to(OsFamily.UNIX)),
|
||||
Charsets.UTF_8));
|
||||
}
|
||||
|
||||
private static String installRubyGems(String version) {
|
||||
String script = "if ! hash gem 2>/dev/null; then\n"
|
||||
+ "(\n"
|
||||
+ "mkdir /tmp/$$\n"
|
||||
+ "curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://production.cf.rubygems.org/rubygems/rubygems-"
|
||||
+ version + ".tgz |(mkdir -p /tmp/$$ &&cd /tmp/$$ &&tar -xpzf -)\n" + "mkdir -p /tmp/rubygems\n"
|
||||
+ "mv /tmp/$$/*/* /tmp/rubygems\n" + "rm -rf /tmp/$$\n" + "cd /tmp/rubygems\n"
|
||||
+ "ruby setup.rb --no-format-executable\n" //
|
||||
+ "rm -fr /tmp/rubygems\n" + //
|
||||
")\n" + //
|
||||
"fi\n";
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
private static String updateSystem(String version) {
|
||||
return version == null ? "gem update --system\n" : "gem update --system " + version + "\n";
|
||||
}
|
||||
|
||||
private static String updateGems() {
|
||||
return "gem update --no-rdoc --no-ri\n";
|
||||
}
|
||||
|
||||
}
|
|
@ -77,89 +77,6 @@ END_OF_JCLOUDS_SCRIPT
|
|||
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||
export LOG_DIR='$LOG_DIR'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/install_chef_gems.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
function abort {
|
||||
echo "aborting: $@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
alias apt-get-update="apt-get update -qq"
|
||||
alias apt-get-install="apt-get install -f -y -qq --force-yes"
|
||||
alias yum-install="yum --quiet --nogpgcheck -y install"
|
||||
|
||||
function ensure_cmd_or_install_package_apt(){
|
||||
local cmd=$1
|
||||
shift
|
||||
local pkg=$*
|
||||
|
||||
hash $cmd 2>/dev/null || ( apt-get-update && apt-get-install $pkg )
|
||||
}
|
||||
|
||||
function ensure_cmd_or_install_package_yum(){
|
||||
local cmd=$1
|
||||
shift
|
||||
local pkg=$*
|
||||
hash $cmd 2>/dev/null || yum-install $pkg
|
||||
}
|
||||
|
||||
function ensure_netutils_apt() {
|
||||
ensure_cmd_or_install_package_apt nslookup dnsutils
|
||||
ensure_cmd_or_install_package_apt curl curl
|
||||
}
|
||||
|
||||
function ensure_netutils_yum() {
|
||||
ensure_cmd_or_install_package_yum nslookup bind-utils
|
||||
ensure_cmd_or_install_package_yum curl curl
|
||||
}
|
||||
|
||||
# most network services require that the hostname is in
|
||||
# the /etc/hosts file, or they won't operate
|
||||
function ensure_hostname_in_hosts() {
|
||||
[ -n "$SSH_CONNECTION" ] && {
|
||||
local ipaddr=`echo $SSH_CONNECTION | awk '{print $3}'`
|
||||
} || {
|
||||
local ipaddr=`hostname -i`
|
||||
}
|
||||
# NOTE: we blindly trust existing hostname settings in /etc/hosts
|
||||
egrep -q `hostname` /etc/hosts || echo "$ipaddr `hostname`" >> /etc/hosts
|
||||
}
|
||||
|
||||
# download locations for many services are at public dns
|
||||
function ensure_can_resolve_public_dns() {
|
||||
nslookup yahoo.com | grep yahoo.com > /dev/null || echo nameserver 208.67.222.222 >> /etc/resolv.conf
|
||||
}
|
||||
|
||||
function setupPublicCurl() {
|
||||
ensure_hostname_in_hosts
|
||||
if which dpkg &> /dev/null; then
|
||||
ensure_netutils_apt
|
||||
elif which rpm &> /dev/null; then
|
||||
ensure_netutils_yum
|
||||
else
|
||||
abort "we only support apt-get and yum right now... please contribute!"
|
||||
return 1
|
||||
fi
|
||||
ensure_can_resolve_public_dns
|
||||
return 0
|
||||
}
|
||||
function installRuby() {
|
||||
if ! hash ruby 2>/dev/null; then
|
||||
if which dpkg &> /dev/null; then
|
||||
apt-get-update
|
||||
apt-get install -y ruby ruby-dev build-essential
|
||||
elif which rpm &> /dev/null; then
|
||||
# Disable chef from the base repo (http://tickets.opscode.com/browse/CHEF-2906)
|
||||
sed -i "s/\[base\]/\0\n\exclude=ruby*/g" /etc/yum.repos.d/CentOS-Base.repo
|
||||
# Make sure to install an appropriate ruby version
|
||||
yum erase -y ruby ruby-libs
|
||||
rpm -Uvh http://rbel.co/rbel5
|
||||
yum install -y ruby ruby-devel make gcc gcc-c++ automake autoconf
|
||||
else
|
||||
abort "we only support apt-get and yum right now... please contribute"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add desired commands from the user
|
||||
|
@ -167,23 +84,6 @@ END_OF_JCLOUDS_SCRIPT
|
|||
cd $INSTANCE_HOME
|
||||
rm -f $INSTANCE_HOME/rc
|
||||
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||
setupPublicCurl || exit 1
|
||||
installRuby || exit 1
|
||||
if ! hash gem 2>/dev/null; then
|
||||
(
|
||||
mkdir /tmp/$$
|
||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://production.cf.rubygems.org/rubygems/rubygems-1.8.10.tgz |(mkdir -p /tmp/$$ &&cd /tmp/$$ &&tar -xpzf -)
|
||||
mkdir -p /tmp/rubygems
|
||||
mv /tmp/$$/*/* /tmp/rubygems
|
||||
rm -rf /tmp/$$
|
||||
cd /tmp/rubygems
|
||||
ruby setup.rb --no-format-executable
|
||||
rm -fr /tmp/rubygems
|
||||
)
|
||||
fi
|
||||
gem update --system
|
||||
gem update --no-rdoc --no-ri
|
||||
|
||||
gem install chef --no-rdoc --no-ri
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
|
|
@ -1,16 +1,2 @@
|
|||
setupPublicCurl || return 1
|
||||
installRuby || return 1
|
||||
if ! hash gem 2>/dev/null; then
|
||||
(
|
||||
mkdir /tmp/$$
|
||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://production.cf.rubygems.org/rubygems/rubygems-1.8.10.tgz |(mkdir -p /tmp/$$ &&cd /tmp/$$ &&tar -xpzf -)
|
||||
mkdir -p /tmp/rubygems
|
||||
mv /tmp/$$/*/* /tmp/rubygems
|
||||
rm -rf /tmp/$$
|
||||
cd /tmp/rubygems
|
||||
ruby setup.rb --no-format-executable
|
||||
rm -fr /tmp/rubygems
|
||||
)
|
||||
fi
|
||||
gem update --system
|
||||
gem update --no-rdoc --no-ri
|
||||
|
|
|
@ -171,21 +171,6 @@ END_OF_JCLOUDS_SCRIPT
|
|||
|
||||
installRuby || exit 1
|
||||
|
||||
if ! hash gem 2>/dev/null; then
|
||||
(
|
||||
mkdir /tmp/$$
|
||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://production.cf.rubygems.org/rubygems/rubygems-1.8.10.tgz |(mkdir -p /tmp/$$ &&cd /tmp/$$ &&tar -xpzf -)
|
||||
mkdir -p /tmp/rubygems
|
||||
mv /tmp/$$/*/* /tmp/rubygems
|
||||
rm -rf /tmp/$$
|
||||
cd /tmp/rubygems
|
||||
ruby setup.rb --no-format-executable
|
||||
rm -fr /tmp/rubygems
|
||||
)
|
||||
fi
|
||||
gem update --system
|
||||
gem update --no-rdoc --no-ri
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
if ! hash gem 2>/dev/null; then
|
||||
(
|
||||
mkdir /tmp/$$
|
||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://production.cf.rubygems.org/rubygems/rubygems-1.8.10.tgz |(mkdir -p /tmp/$$ &&cd /tmp/$$ &&tar -xpzf -)
|
||||
mkdir -p /tmp/rubygems
|
||||
mv /tmp/$$/*/* /tmp/rubygems
|
||||
rm -rf /tmp/$$
|
||||
cd /tmp/rubygems
|
||||
ruby setup.rb --no-format-executable
|
||||
rm -fr /tmp/rubygems
|
||||
)
|
||||
fi
|
||||
gem update --system
|
||||
gem update --no-rdoc --no-ri
|
|
@ -0,0 +1,151 @@
|
|||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
shopt -s expand_aliases
|
||||
unset PATH JAVA_HOME LD_LIBRARY_PATH
|
||||
function abort {
|
||||
echo "aborting: $@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
function default {
|
||||
export INSTANCE_NAME="install_rubygems"
|
||||
export INSTANCE_HOME="/tmp/$INSTANCE_NAME"
|
||||
export LOG_DIR="$INSTANCE_HOME"
|
||||
return $?
|
||||
}
|
||||
function install_rubygems {
|
||||
return $?
|
||||
}
|
||||
function findPid {
|
||||
unset FOUND_PID;
|
||||
[ $# -eq 1 ] || {
|
||||
abort "findPid requires a parameter of pattern to match"
|
||||
return 1
|
||||
}
|
||||
local PATTERN="$1"; shift
|
||||
local _FOUND=`ps auxwww|grep "$PATTERN"|grep -v " $0"|grep -v grep|grep -v $$|awk '{print $2}'`
|
||||
[ -n "$_FOUND" ] && {
|
||||
export FOUND_PID=$_FOUND
|
||||
return 0
|
||||
} || {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
function forget {
|
||||
unset FOUND_PID;
|
||||
[ $# -eq 3 ] || {
|
||||
abort "forget requires parameters INSTANCE_NAME SCRIPT LOG_DIR"
|
||||
return 1
|
||||
}
|
||||
local INSTANCE_NAME="$1"; shift
|
||||
local SCRIPT="$1"; shift
|
||||
local LOG_DIR="$1"; shift
|
||||
mkdir -p $LOG_DIR
|
||||
findPid $INSTANCE_NAME
|
||||
[ -n "$FOUND_PID" -a -f $LOG_DIR/stdout.log ] && {
|
||||
echo $INSTANCE_NAME already running pid $FOUND_PID
|
||||
return 1;
|
||||
} || {
|
||||
nohup $SCRIPT >$LOG_DIR/stdout.log 2>$LOG_DIR/stderr.log &
|
||||
RETURN=$?
|
||||
# this is generally followed by findPid, so we shouldn't exit
|
||||
# immediately as the proc may not have registered in ps, yet
|
||||
test $RETURN && sleep 1
|
||||
return $RETURN;
|
||||
}
|
||||
}
|
||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||
case $1 in
|
||||
init)
|
||||
default || exit 1
|
||||
install_rubygems || exit 1
|
||||
mkdir -p $INSTANCE_HOME
|
||||
|
||||
# create runscript header
|
||||
cat > $INSTANCE_HOME/install_rubygems.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
#!/bin/bash
|
||||
set +u
|
||||
shopt -s xpg_echo
|
||||
shopt -s expand_aliases
|
||||
|
||||
PROMPT_COMMAND='echo -ne \"\033]0;install_rubygems\007\"'
|
||||
export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin
|
||||
|
||||
export INSTANCE_NAME='install_rubygems'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
cat >> $INSTANCE_HOME/install_rubygems.sh <<-END_OF_JCLOUDS_SCRIPT
|
||||
export INSTANCE_NAME='$INSTANCE_NAME'
|
||||
export INSTANCE_HOME='$INSTANCE_HOME'
|
||||
export LOG_DIR='$LOG_DIR'
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add desired commands from the user
|
||||
cat >> $INSTANCE_HOME/install_rubygems.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
cd $INSTANCE_HOME
|
||||
rm -f $INSTANCE_HOME/rc
|
||||
trap 'echo $?>$INSTANCE_HOME/rc' 0 1 2 3 15
|
||||
if ! hash gem 2>/dev/null; then
|
||||
(
|
||||
mkdir /tmp/$$
|
||||
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET http://production.cf.rubygems.org/rubygems/rubygems-1.8.10.tgz |(mkdir -p /tmp/$$ &&cd /tmp/$$ &&tar -xpzf -)
|
||||
mkdir -p /tmp/rubygems
|
||||
mv /tmp/$$/*/* /tmp/rubygems
|
||||
rm -rf /tmp/$$
|
||||
cd /tmp/rubygems
|
||||
ruby setup.rb --no-format-executable
|
||||
rm -fr /tmp/rubygems
|
||||
)
|
||||
fi
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
# add runscript footer
|
||||
cat >> $INSTANCE_HOME/install_rubygems.sh <<-'END_OF_JCLOUDS_SCRIPT'
|
||||
exit $?
|
||||
|
||||
END_OF_JCLOUDS_SCRIPT
|
||||
|
||||
chmod u+x $INSTANCE_HOME/install_rubygems.sh
|
||||
;;
|
||||
status)
|
||||
default || exit 1
|
||||
findPid $INSTANCE_NAME || exit 1
|
||||
echo $FOUND_PID
|
||||
;;
|
||||
stop)
|
||||
default || exit 1
|
||||
findPid $INSTANCE_NAME || exit 1
|
||||
[ -n "$FOUND_PID" ] && {
|
||||
echo stopping $FOUND_PID
|
||||
kill -9 $FOUND_PID
|
||||
}
|
||||
;;
|
||||
start)
|
||||
default || exit 1
|
||||
forget $INSTANCE_NAME $INSTANCE_HOME/$INSTANCE_NAME.sh $LOG_DIR || exit 1
|
||||
;;
|
||||
stdout)
|
||||
default || exit 1
|
||||
cat $LOG_DIR/stdout.log
|
||||
;;
|
||||
stderr)
|
||||
default || exit 1
|
||||
cat $LOG_DIR/stderr.log
|
||||
;;
|
||||
exitstatus)
|
||||
default || exit 1
|
||||
[ -f $LOG_DIR/rc ] && cat $LOG_DIR/rc;;
|
||||
tail)
|
||||
default || exit 1
|
||||
tail $LOG_DIR/stdout.log
|
||||
;;
|
||||
tailerr)
|
||||
default || exit 1
|
||||
tail $LOG_DIR/stderr.log
|
||||
;;
|
||||
run)
|
||||
default || exit 1
|
||||
$INSTANCE_HOME/$INSTANCE_NAME.sh
|
||||
;;
|
||||
esac
|
||||
exit $?
|
Loading…
Reference in New Issue