#!/bin/bash
if [ -n “${CHEF_ENVIRONMENTS}” ]; then
environments=( ${CHEF_ENVIRONMENTS} )
elif [ -f “${PWD%/}/.travis-envs” ]; then
environments=( $(<"${PWD%/}/.travis-envs") )
fi
decrypt() {
if [ -n "${SECRET}" ]; then openssl aes-256-cbc -pass 'env:SECRET' -in "${1}" -out "${2}" -d -a return $? else return 1 fi
}
load_ssh_key() {
decrypt "${PWD%/}/.travis-key" ~/.ssh/id_rsa_travis || return $? chmod 0600 ~/.ssh/id_rsa_travis || return $? ssh-add -D || return $? ssh-add ~/.ssh/id_rsa_travis || return $? return 0
}
update_nodes() {
knife exec -E "def get_value(node, attribute); attribute.split('.').inject(node) { |hash, key| hash[key] }; end; def update_node(node, attribute, value); begin; puts \"Updating #{node.name}[#{attribute}] to #{value}\"; attribute.split('.').inject(node.normal) { |hash, key| hash[key].is_a?(String) ? hash[key] = value : hash[key]; }; saved_node = node.save; loaded_node = Chef::Node.load(node.name); unless get_value(saved_node, attribute) == value puts \"Warning: saved node value does not match #{value}\"; return false; end; unless get_value(loaded_node, attribute) == value puts \"Warning: loaded node value does not match #{value}\"; return false; end; return true; rescue; end; return false; end; nodes.find('${1}') { |node| succeeded = false (1..5).each { |try| puts \"Attempt #{try} for #{node.name}:\"; succeeded = update_node(node, '${2}', '${3}'); break if succeeded; }; if succeeded; puts \"Updated #{node.name}\"; else; fail(StandardError, \"Failed to update #{node.name}\"); end; }" return $?
}
setup_chef() {
if [ -n "${CHEF_ENVIRONMENTS}" ]; then setup_chef_from_env else setup_chef_from_files fi
}
setup_chef_from_files() {
# Load ssh key for knife load_ssh_key || exit $? if [ -n "${CHEF_VALIDATOR}" ]; then CHEF_VALIDATOR="${PWD%/}/.travis-${CHEF_VALIDATOR}" else CHEF_VALIDATOR="$(echo ${PWD%/}/.travis-*-validator.pem)" fi # Determine Chef organization name from validator pem CHEF_ORG="${CHEF_VALIDATOR##*/.travis-}" CHEF_ORG="${CHEF_ORG%% }" CHEF_ORG="${CHEF_ORG%%-validator*}" # Set CHEF_SERVER from CHEF_ORG unless provided from environment CHEF_SERVER="${CHEF_SERVER:-https://api.opscode.com/organizations/${CHEF_ORG}}" if [ -n "${CHEF_CLIENT}" ]; then CHEF_CLIENT="${PWD%/}/.travis-${CHEF_CLIENT}" else # Determine Chef node name from client pem CHEF_CLIENT="$(echo ${PWD%/}/.travis-*.pem)" CHEF_CLIENT="${CHEF_CLIENT/${CHEF_VALIDATOR}/}" fi # Determine Chef user name from client pem CHEF_USER="${CHEF_CLIENT##*/.travis-}" CHEF_USER="${CHEF_USER%% }" CHEF_USER="${CHEF_USER%%.*}" # Configure knife and decrypt keys [ -d "${PWD%/}/.chef" ] && rm -rf "${PWD%/}/.chef" mkdir "${PWD%/}/.chef" || exit $? cat >"${PWD%/}/.chef/knife.rb" <<EOF
current_dir = File.dirname(__FILE__)
log_level :info log_location STDOUT
node_name '${CHEF_USER}' client_key “#{current_dir}/${CHEF_USER}.pem” validation_client_name '${CHEF_ORG}-validator' validation_key “#{current_dir}/${CHEF_ORG}-validator.pem” chef_server_url '${CHEF_SERVER}'
knife = '${CHEF_USER}' knife = '~/.ssh/id_rsa_travis' EOF
decrypt ${CHEF_CLIENT} "${PWD%/}/.chef/${CHEF_USER}.pem" || exit $? decrypt ${CHEF_VALIDATOR} "${PWD%/}/.chef/${CHEF_ORG}-validator.pem" || exit $?
}
setup_chef_from_env() {
# Install chef gem to get knife gem install chef -v '~> 11.0' --no-rdoc --no-ri || exit $? # Redefine CHEF_SERVER if possible using environment if [ -n "${environment}" ]; then chef_server_variable_name="CHEF_SERVER_${environment^^}" if [ -n "${!chef_server_variable_name}" ]; then CHEF_SERVER="${!chef_server_variable_name}" fi fi # Determine Chef organization name from CHEF_SERVER CHEF_ORG="${CHEF_SERVER##*/}" # Redefine CHEF_USER if possible using environment if [ -n "${environment}" ]; then chef_user_variable_name="CHEF_USER_${environment^^}" if [ -n "${!chef_user_variable_name}" ]; then CHEF_USER="${!chef_user_variable_name}" fi fi # Redefine CHEF_CLIENT if possible using environment if [ -n "${environment}" ]; then chef_client_variable_name="CHEF_CLIENT_${environment^^}" if [ -n "${!chef_client_variable_name}" ]; then CHEF_CLIENT="${!chef_client_variable_name}" fi fi # Configure knife and write client key [ -d "${PWD%/}/.chef" ] && rm -rf "${PWD%/}/.chef" mkdir "${PWD%/}/.chef" || exit $? if [ -n "${CHEF_CLIENT}" ]; then echo -e "${CHEF_CLIENT}" >"${PWD%/}/.chef/${CHEF_USER}.pem" fi cat >"${PWD%/}/.chef/knife.rb" <<EOF
current_dir = File.dirname(__FILE__)
log_level :info log_location STDOUT
node_name '${CHEF_USER}' client_key “#{current_dir}/${CHEF_USER}.pem” chef_server_url '${CHEF_SERVER}'
knife = '${CHEF_USER}' EOF }
if [ -n “${1}” -a “${1}” = “prepare” ]; then
load_ssh_key exit $?
fi
if [ -n “${1}” -a “${1}” = “setup” ]; then
setup_chef exit $?
fi
if [ -n “${TRAVIS_BRANCH}” ]; then
if [ "${TRAVIS_BRANCH%%/*}" = "environment" ]; then # Only run once on matrix builds if [ -n "${TEST_GROUP}" -a "${TEST_GROUP}" != "1" ]; then exit 0 fi # Deploy if we support the environment environment="${TRAVIS_BRANCH##environment/}" if [[ "${environments[@]}" != "${environments[@]//${environment}/}" ]]; then setup_chef # Run the app-specific deploy code source "${PWD%/}/.travis-deploy" fi else # Not a deploy so just run the tests source "${PWD%/}/.travis-test" fi
else
environment="${1}" if [[ "${environments[@]}" == "${environments[@]//${environment}/}" ]]; then set +x echo "Usage: $(basename "${0}") ENVIRONMENT" echo echo " Valid environments:" for e in ${environments[@]}; do echo " ${e}" done echo echo "Report bugs to <mattk@granicus.com>." exit 0 fi
fi
exit 0