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 2013/09/18 23:49:44 UTC

git commit: JCLOUDS-286: Add a statement to install Chef using Omnibus

Updated Branches:
  refs/heads/master 389ba6c94 -> 4304e6ab1


JCLOUDS-286: Add a statement to install Chef using Omnibus


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

Branch: refs/heads/master
Commit: 4304e6ab198a7565e8b320120e742e71cb99a175
Parents: 389ba6c
Author: Ignasi Barrera <na...@apache.org>
Authored: Tue Sep 17 10:00:25 2013 +0200
Committer: Ignasi Barrera <na...@apache.org>
Committed: Wed Sep 18 23:35:09 2013 +0200

----------------------------------------------------------------------
 .../scriptbuilder/statements/chef/ChefSolo.java |   6 +
 .../statements/chef/InstallChefGems.java        |  10 +
 .../chef/InstallChefUsingOmnibus.java           |  54 +++++
 .../chef/InstallChefUsingOmnibusTest.java       |  56 +++++
 .../test_install_chef_omnibus_scriptbuilder.sh  | 208 +++++++++++++++++++
 5 files changed, 334 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/4304e6ab/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/ChefSolo.java
----------------------------------------------------------------------
diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/ChefSolo.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/ChefSolo.java
index 8f0d6d5..c7a0931 100644
--- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/ChefSolo.java
+++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/ChefSolo.java
@@ -31,6 +31,8 @@ import org.jclouds.scriptbuilder.domain.Statements;
 import org.jclouds.scriptbuilder.domain.chef.DataBag;
 import org.jclouds.scriptbuilder.domain.chef.Role;
 import org.jclouds.scriptbuilder.domain.chef.RunList;
+import org.jclouds.scriptbuilder.statements.ruby.InstallRuby;
+import org.jclouds.scriptbuilder.statements.ruby.InstallRubyGems;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
@@ -45,6 +47,10 @@ import com.google.common.collect.Lists;
  * Bootstraps a node using Chef Solo.
  * 
  * @author Ignasi Barrera
+ * 
+ * @see InstallChefGems
+ * @see InstallRuby
+ * @see InstallRubyGems
  */
 public class ChefSolo implements Statement {
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/4304e6ab/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefGems.java
----------------------------------------------------------------------
diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefGems.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefGems.java
index f30c8e4..5fc5a34 100644
--- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefGems.java
+++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefGems.java
@@ -21,14 +21,24 @@ 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.Statement;
+import org.jclouds.scriptbuilder.statements.ruby.InstallRuby;
+import org.jclouds.scriptbuilder.statements.ruby.InstallRubyGems;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
 
 /**
  * Installs Chef gems onto a host.
+ * <p>
+ * If you only want to install the Chef client and don't care about the version
+ * of Ruby and Rubygems, use the {@link InstallChefUsingOmnibus} statement
+ * instead.
  * 
  * @author Ignasi Barrera
+ * 
+ * @see InstallChefUsingOmnibus
+ * @see InstallRuby
+ * @see InstallRubyGems
  */
 public class InstallChefGems implements Statement {
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/4304e6ab/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibus.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..c16b220
--- /dev/null
+++ b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibus.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.chef;
+
+import static org.jclouds.scriptbuilder.domain.Statements.call;
+import static org.jclouds.scriptbuilder.domain.Statements.pipeHttpResponseToBash;
+
+import java.net.URI;
+
+import org.jclouds.scriptbuilder.domain.StatementList;
+import org.jclouds.scriptbuilder.statements.ruby.InstallRuby;
+
+import com.google.common.collect.ImmutableMultimap;
+
+/**
+ * Installs the Chef client using the Omnibus installer.
+ * <p>
+ * This will install an entire ruby distribution with all required gems in a
+ * concrete directory so there is no need to manually download or configure any
+ * Ruby version or gem.
+ * <p>
+ * If you want more control on the Ruby version or the gems being installed, use
+ * the {@link InstallChefGems} statement instead.
+ * 
+ * @author Ignasi Barrera
+ * 
+ * @see InstallChefGems
+ * @see InstallRuby
+ */
+public class InstallChefUsingOmnibus extends StatementList {
+
+   /** The URL for the Omnibus installer */
+   public static final String OMNIBUS_INSTALLER = "https://www.opscode.com/chef/install.sh";
+
+   public InstallChefUsingOmnibus() {
+      super(call("setupPublicCurl"), pipeHttpResponseToBash("GET", URI.create(OMNIBUS_INSTALLER),
+            ImmutableMultimap.<String, String> of()));
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/4304e6ab/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibusTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..0dc6fc2
--- /dev/null
+++ b/scriptbuilder/src/test/java/org/jclouds/scriptbuilder/statements/chef/InstallChefUsingOmnibusTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.chef;
+
+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 InstallChefUsingOmnibus} statement.
+ * 
+ * @author Ignasi Barrera
+ */
+@Test(groups = "unit", testName = "InstallChefClientUsingOmnibusTest")
+public class InstallChefUsingOmnibusTest {
+
+   @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "windows not supported")
+   public void installChefUsingOmnibusInWindows() {
+      new InstallChefUsingOmnibus().render(OsFamily.WINDOWS);
+   }
+
+   public void installChefUsingOmnibusInUnix() throws IOException {
+      assertEquals(new InstallChefUsingOmnibus().render(OsFamily.UNIX), "setupPublicCurl || return 1\n"
+            + "curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 "
+            + "-X GET  https://www.opscode.com/chef/install.sh |(bash)\n");
+   }
+
+   public void installChefUsingOmnibusInUnixInScriptBuilder() throws IOException {
+      assertEquals(InitScript.builder().name("install_chef_omnibus").run(new InstallChefUsingOmnibus()).build()
+            .render(OsFamily.UNIX), Resources.toString(
+            Resources.getResource("test_install_chef_omnibus_scriptbuilder." + ShellToken.SH.to(OsFamily.UNIX)),
+            Charsets.UTF_8));
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/4304e6ab/scriptbuilder/src/test/resources/test_install_chef_omnibus_scriptbuilder.sh
----------------------------------------------------------------------
diff --git a/scriptbuilder/src/test/resources/test_install_chef_omnibus_scriptbuilder.sh b/scriptbuilder/src/test/resources/test_install_chef_omnibus_scriptbuilder.sh
new file mode 100644
index 0000000..e295c33
--- /dev/null
+++ b/scriptbuilder/src/test/resources/test_install_chef_omnibus_scriptbuilder.sh
@@ -0,0 +1,208 @@
+#!/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
+	
+	curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET  https://www.opscode.com/chef/install.sh |(bash)
+	
+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 $?