mirror of https://github.com/apache/jclouds.git
JCLOUDS-286: Add a statement to install Chef using Omnibus
This commit is contained in:
parent
389ba6c94a
commit
4304e6ab19
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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 $?
|
Loading…
Reference in New Issue