Skip to content

Instantly share code, notes, and snippets.

@mitchellh
Created September 27, 2012 05:30
Show Gist options
  • Save mitchellh/3792312 to your computer and use it in GitHub Desktop.
Save mitchellh/3792312 to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# This is the script responsible for updating our Puppet master data,
# which includes modules, manifests, hiera data, etc. All of this data is
# managed in a git repository and upon "deploy" it is synced into the Puppet
# master.
#
# This script mirrors the remote git repository, looking for branches that
# match "env-*" (such as "env-production" or "env-test"). Each of these branches
# is setup as an environment into the Puppet master's data files. The
# `modulepath` of Puppet is expected to at least have this in it:
#
# /etc/puppet/environments/%{environment}/modules
#
# The manifests are also environment constrained, so you need to set the
# `manifest` config to the following:
#
# /etc/puppet/environments/%{environment}/manifests
#
# And finally, you must configure things like Hiera and so on to also
# read from the environments folder. Given the examples above, I will leave
# that up to you.
#
# When branches are deleted from the remote git repository, they will
# also be deleted from the Puppet data files.
set -e
# Export variables that subprocesses need
export GIT_SSH=/opt/puppet-updater/git_ssh
# Variables we use later
GIT_REPO_PATH=/tmp/puppet-repo
GIT_REPO_TEMP_PATH=/tmp/puppet-repo-temp
GIT_URL=git://[email protected]/bar.git
PUPPET_ENVIRONMENTS_ROOT=/etc/puppet/environments
PUPPET_FILE_USER=puppet-files
# Clone the repository if it doesn't exist. We clone it as a mirror
# since we don't need a working repository and this way it keeps the
# branches local.
if [ ! -d ${GIT_REPO_PATH} ]; then
git clone --mirror ${GIT_URL} ${GIT_REPO_PATH}
fi
# Update the repository. The "-p" flag will prune any branches that
# are deleted on the remote end.
pushd ${GIT_REPO_PATH}
git fetch -p -q
popd
# Go through each branch that represents environments on the Puppet master
# (that match "env-*") and copy it to the puppet master directory.
ENVIRONMENTS=$(
cd ${GIT_REPO_PATH} &&
git branch | sed -n -r -e 's/^\*?\s+env-(.*)/\1/p'
)
for name in $ENVIRONMENTS; do
# RSync the files to the proper location.
rm -rf ${GIT_REPO_TEMP_PATH}
git clone --branch env-${name} --depth 1 ${GIT_REPO_PATH} ${GIT_REPO_TEMP_PATH}
pushd ${GIT_REPO_TEMP_PATH}
rsync --archive --delete --exclude '.*' ./ ${PUPPET_ENVIRONMENTS_ROOT}/${name}
popd
done
# Delete the environments that don't exist anymore by comparing the
# directories we have in the Puppet environment root with the list
# of environments we got from git.
find ${PUPPET_ENVIRONMENTS_ROOT} -mindepth 1 -maxdepth 1 -type d -printf '%P\n' | while read name; do
found=0
for needle in $ENVIRONMENTS; do
if [[ $needle == $name ]]; then
found=1
break
fi
done
if [[ $found -eq 0 ]]; then
rm -r ${PUPPET_ENVIRONMENTS_ROOT}/${name}
fi
done
# Set proper permissions
chown -R ${PUPPET_FILE_USER}:${PUPPET_FILE_USER} ${PUPPET_ENVIRONMENTS_ROOT}
find ${PUPPET_ENVIRONMENTS_ROOT} -type d | xargs chmod 0755
find ${PUPPET_ENVIRONMENTS_ROOT} -type f | xargs chmod 0644
# Restart the puppet master. We do this because the puppet master is kind
# of flaky in picking up changes to the files.
/etc/init.d/puppetmaster restart
@cdenneen
Copy link

So this script resides on all puppetmasters and is run via fab file?

Do you have gists of your fab and rake files for unifying dev/qa/stage/prod across Vagrant, EC2, and whatever else?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment