chef/cookbooks/provisioner/templates/default/crowbar_join.ubuntu.sh.erb
#!/bin/bash
# Copyright 2011, Dell
#
# Licensed 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.
#
case $1 in
stop) exit 0;;
status) bluepill chef-client status ; exit $? ;;
start|'') : ;;
*) echo "Unknown action to crowbar_join.sh."
exit 1;;
esac
if [[ $TERM != screen ]]; then
echo "Running $0 under screen. Attach with screen -r -S crowbar-join" >&2
exec screen -d -m -S crowbar-join "$0"
fi
if [[ ! -d /var/log/crowbar/crowbar_join ]] ; then
mkdir -p /var/log/crowbar/crowbar_join/
fi
exec 2>>/var/log/crowbar/crowbar_join/errlog
export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): '
export DEBIAN_FRONTEND=noninteractive
set -x
if [[ -f /etc/crowbar.install.key ]]; then
export CROWBAR_KEY="$(cat /etc/crowbar.install.key)"
fi
# Run a command and log its output.
log_to() {
# $1 = install log to log to
# $@ = rest of args
local __log="/var/log/crowbar/crowbar_join/$1"
local __timestamp="$(date '+%F %T %z')"
shift
printf "\n%s\n" "$__timestamp: Running $*" | \
tee -a "$__log.err" >> "$__log.log"
local _ret=0
if "$@" 2>> "$__log.err" >>"$__log.log"; then
_ret=0
else
_ret="$?"
echo "$__timestamp: $* failed."
echo "See $__log.log and $__log.err for more information."
fi
printf "\n$s\n--------\n" "$(date '+%F %T %z'): Done $*" | \
tee -a "$__log.err" >> "$__log.log"
return $_ret
}
post_state() {
local curlargs=(-o /dev/null --connect-timeout 60 -s \
-L -X POST --data-binary "{ \"name\": \"$1\", \"state\": \"$2\" }" \
-H "Accept: application/json" -H "Content-Type: application/json" \
--max-time 240 --insecure --location)
[[ $CROWBAR_KEY ]] && curlargs+=(-u "$CROWBAR_KEY" --digest --anyauth)
oldumask=`umask`
umask 077
curl "${curlargs[@]}" "http://<%=@admin_ip%>/crowbar/crowbar/1.0/transition/default"
umask $oldumask
}
# Spin while we wait for the interface to come up.
echo "Waiting on our network interface to come up..."
while ! ip addr | grep -v " lo" | grep -q "inet "
do
sleep 1
done
# Get our hostname
HOSTNAME=$(hostname -f)
sync_time() {
# stop ntpd before we run ntpdate, and start it again afterwards.
service ntp stop
killall ntpd
while ! /usr/sbin/ntpdate -b <%=@admin_ip%>; do
echo "Waiting for NTP server"
sleep 1
done
}
# Clean up install droppings
rm -f /update_system2.sh
rm -f /net-post-install.sh
echo "Synchronizing time (pass 1)"
sync_time
# Mark us as readying, and get our cert.
post_state $HOSTNAME "readying"
final_state="ready"
mkdir -p /etc/chef
wget -q "<%=@provisioner_web%>/validation.pem" -O- > /etc/chef/validation.pem
if [[ ! -x /etc/init.d/bluepill ]]; then
# Install Chef
echo "Installing Chef..."
echo "chef chef/chef_server_url string http://<%=@admin_ip%>:4000" >/tmp/debsel.conf
while ! log_to apt /usr/bin/apt-get update ; do
echo "Failed to apt-get update, wait and try again"
sleep 1
done
log_to apt /usr/bin/debconf-set-selections /tmp/debsel.conf
while ! log_to apt /usr/bin/apt-get --force-yes -y install \
chef libxml2-dev zlib1g-dev tcpdump; do
echo "Failed to apt-get install, wait and try again"
sleep 1
done
# Disable the chef-client service and make it not executable.
log_to chef service chef-client stop
log_to chef killall chef-client
log_to chef update-rc.d chef-client disable
log_to chef chmod ugo-x /etc/init.d/chef-client
mkdir -p /opt/dell/
( cd /opt/dell
wget -q "<%=@provisioner_web%>/patches.tar.gz"
tar xzvf patches.tar.gz
cd patches
./patch.sh
)
# Make rubygems do what we want.
cat >/etc/gemrc <<EOF
:sources:
- <%=@provisioner_web%>/gemsite/
gem: --no-ri --no-rdoc --bindir /usr/local/bin
EOF
gem install xml-simple
gem install libxml-ruby
gem install wsman
gem install cstruct
gem install bluepill
mkdir -p /etc/bluepill
curl -o /etc/bluepill/chef-client.pill <%=@provisioner_web%>/chef-client.pill
# Create an init script for bluepill
cat > /etc/init.d/bluepill <<EOF
#!/bin/bash
# chkconfig: 2345 99 01
# description: Bluepill Daemon runner
PATH=$PATH:/usr/local/bin:/usr/local/sbin
case \$1 in
start) for pill in /etc/bluepill/*.pill; do
[[ -f \$pill ]] || continue
bluepill load "\$pill"
done;;
stop) echo "Stop is not implemented, since bluepill processes are run independently.";;
status) if pidof bluepilld; then
echo "Bluepill is running."
exit 0
else
echo "Bluepill is not running."
exit 1
fi;;
*) echo "\$1: Not supported.";;
esac
EOF
chmod 755 /etc/init.d/bluepill
fi
# Run Chef
echo "Syncing time (pass 2)"
sync_time
# Until we arrange for the network to transisiton from using
# DHCP somewhere else, the first run of chef-client will always die due to
# the networking barclamp changing the IP address from dhcp to static.
# We will try to pick up and run with it.
echo "Running Chef Client (pass 1)"
log_to chef chef-client
# Make sure our interfaces are as up as we can get them
echo "Ensuring that our network interfaces are up."
log_to ifup ifup -a
# Only transition to problem state if the second run fails.
echo "Running Chef Client (pass 2)"
if ! log_to chef chef-client ; then
log_to ifup ifup -a
post_state $HOSTNAME "recovering"
echo "Error Path"
echo "Syncing Time (pass 3)"
sync_time
echo "Removing Chef Cache"
rm -rf /var/cache/chef/*
echo "Checking Install Integrity"
log_to apt /usr/bin/apt-get -q --force-yes -y install
echo "Running Chef Client (pass 3) - apt/cache cleanup"
if ! log_to chef chef-client ; then
log_to ifup ifup -a
echo "Error Path"
echo "Syncing Time (pass 4)"
sync_time
echo "Removing Chef Cache"
rm -rf /var/cache/chef/*
echo "Checking Install Integrity"
log_to apt /usr/bin/apt-get -q --force-yes -y install
echo "Checking Keys"
rm -f /etc/chef/client.pem
post_state $HOSTNAME "installed"
echo "Running Chef Client (pass 4) - password cleanup"
if ! log_to chef chef-client ; then
log_to ifup ifup -a
echo "chef-client run failed four times, giving up."
echo "Failed"
printf "Our IP address is: %s\n" "$(ip addr show)"
final_state="problem"
else
post_state "$HOSTNAME" "$final_state"
log_to chef chef-client
fi
fi
fi
# Make sure our code is up to date
log_to apt apt-get -q --force-yes -y upgrade
log_to time service ntp start
# Fire up bluepill, and let it keep chef-client up.
service bluepill start
# Transition to our final state
post_state $HOSTNAME "$final_state"
echo "Done"