Skip to content

Instantly share code, notes, and snippets.

@mitchellh
Created September 27, 2012 05:30
Show Gist options
  • Select an option

  • Save mitchellh/3792312 to your computer and use it in GitHub Desktop.

Select an option

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://foo@github.com/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
Copy Markdown

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