From 8f9acd1cadf4a4e54af96441510813be2e48c16a Mon Sep 17 00:00:00 2001 From: Ignasi Barrera Date: Fri, 9 Jan 2015 13:07:20 +0100 Subject: [PATCH] Custom Chef version in the Omnibus installer --- apis/chef/pom.xml | 1 - .../chef/config/ChefBootstrapModule.java | 6 +- .../chef/InstallChefUsingOmnibus.java | 8 +- .../chef/InstallChefUsingOmnibusTest.java | 14 ++ ...tall_chef_version_omnibus_scriptbuilder.sh | 210 ++++++++++++++++++ 5 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 scriptbuilder/src/test/resources/test_install_chef_version_omnibus_scriptbuilder.sh diff --git a/apis/chef/pom.xml b/apis/chef/pom.xml index 178128f2a3..62f110048e 100644 --- a/apis/chef/pom.xml +++ b/apis/chef/pom.xml @@ -91,7 +91,6 @@ ch.qos.logback logback-classic - 1.0.9 test diff --git a/apis/chef/src/main/java/org/jclouds/chef/config/ChefBootstrapModule.java b/apis/chef/src/main/java/org/jclouds/chef/config/ChefBootstrapModule.java index a5fd231f0e..4c7bfcea62 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/config/ChefBootstrapModule.java +++ b/apis/chef/src/main/java/org/jclouds/chef/config/ChefBootstrapModule.java @@ -60,8 +60,10 @@ public class ChefBootstrapModule extends AbstractModule { @Provides @Named("installChefOmnibus") @Singleton - Statement installChefUsingOmnibus() { - return new InstallChefUsingOmnibus(); + Statement installChefUsingOmnibus(BootstrapProperties bootstrapProperties) { + return bootstrapProperties.chefVersion().isPresent() ? + new InstallChefUsingOmnibus(bootstrapProperties.chefVersion().get()) + : new InstallChefUsingOmnibus(); } @Provides diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibus.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibus.java index 859c91450e..76330868f8 100644 --- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibus.java +++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibus.java @@ -17,7 +17,9 @@ package org.jclouds.scriptbuilder.statements.chef; import static org.jclouds.scriptbuilder.domain.Statements.call; +import static org.jclouds.scriptbuilder.domain.Statements.exec; import static org.jclouds.scriptbuilder.domain.Statements.pipeHttpResponseToBash; +import static org.jclouds.scriptbuilder.domain.Statements.saveHttpResponseTo; import java.net.URI; @@ -37,7 +39,7 @@ import com.google.common.collect.ImmutableMultimap; * * * @see InstallChefGems - * @see InstallRuby + * @see org.jclouds.scriptbuilder.statements.ruby.InstallRuby */ public class InstallChefUsingOmnibus extends StatementList { @@ -49,4 +51,8 @@ public class InstallChefUsingOmnibus extends StatementList { ImmutableMultimap. of())); } + public InstallChefUsingOmnibus(String chefVersion) { + super(call("setupPublicCurl"), saveHttpResponseTo(URI.create(OMNIBUS_INSTALLER), "/tmp", "install-chef.sh"), + exec("sh /tmp/install-chef.sh -v " + chefVersion)); + } } diff --git a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibusTest.java b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibusTest.java index 3a919d13b8..cdfbab113d 100644 --- a/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibusTest.java +++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibusTest.java @@ -51,4 +51,18 @@ public class InstallChefUsingOmnibusTest { Resources.getResource("test_install_chef_omnibus_scriptbuilder." + ShellToken.SH.to(OsFamily.UNIX)), Charsets.UTF_8)); } + + public void installChefWithVersionUsingOmnibusInUnix() throws IOException { + assertEquals(new InstallChefUsingOmnibus("11.16.4").render(OsFamily.UNIX), "setupPublicCurl || return 1\n" + + "(mkdir -p /tmp && cd /tmp && [ ! -f install-chef.sh ] && " + + "curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -C - -X GET https://www.opscode.com/chef/install.sh >install-chef.sh)\n" + + "sh /tmp/install-chef.sh -v 11.16.4\n"); + } + + public void installChefWithVersionUsingOmnibusInUnixInScriptBuilder() throws IOException { + assertEquals(InitScript.builder().name("install_chef_omnibus").run(new InstallChefUsingOmnibus("11.16.4")).build() + .render(OsFamily.UNIX), Resources.toString( + Resources.getResource("test_install_chef_version_omnibus_scriptbuilder." + ShellToken.SH.to(OsFamily.UNIX)), + Charsets.UTF_8)); + } } diff --git a/scriptbuilder/src/test/resources/test_install_chef_version_omnibus_scriptbuilder.sh b/scriptbuilder/src/test/resources/test_install_chef_version_omnibus_scriptbuilder.sh new file mode 100644 index 0000000000..65807012ec --- /dev/null +++ b/scriptbuilder/src/test/resources/test_install_chef_version_omnibus_scriptbuilder.sh @@ -0,0 +1,210 @@ +#!/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_chef_omnibus" +export INSTANCE_HOME="/tmp/$INSTANCE_NAME" +export LOG_DIR="$INSTANCE_HOME" + return $? +} +function install_chef_omnibus { + 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_chef_omnibus || exit 1 + mkdir -p $INSTANCE_HOME + + # create runscript header + cat > $INSTANCE_HOME/install_chef_omnibus.sh <<-'END_OF_JCLOUDS_SCRIPT' + #!/bin/bash + set +u + shopt -s xpg_echo + shopt -s expand_aliases + + PROMPT_COMMAND='echo -ne \"\033]0;install_chef_omnibus\007\"' + export PATH=/usr/ucb/bin:/bin:/sbin:/usr/bin:/usr/sbin + + export INSTANCE_NAME='install_chef_omnibus' +END_OF_JCLOUDS_SCRIPT + cat >> $INSTANCE_HOME/install_chef_omnibus.sh <<-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_omnibus.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 +} + +END_OF_JCLOUDS_SCRIPT + + # add desired commands from the user + cat >> $INSTANCE_HOME/install_chef_omnibus.sh <<-'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 + + (mkdir -p /tmp && cd /tmp && [ ! -f install-chef.sh ] && curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -C - -X GET https://www.opscode.com/chef/install.sh >install-chef.sh) + + sh /tmp/install-chef.sh -v 11.16.4 + +END_OF_JCLOUDS_SCRIPT + + # add runscript footer + cat >> $INSTANCE_HOME/install_chef_omnibus.sh <<-'END_OF_JCLOUDS_SCRIPT' + exit $? + +END_OF_JCLOUDS_SCRIPT + + chmod u+x $INSTANCE_HOME/install_chef_omnibus.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 $?