Last active
November 14, 2017 20:20
-
-
Save jfryman/14e5134ad0a2cc982f554b6811080573 to your computer and use it in GitHub Desktop.
Puppet Env Magic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$stdout.sync = true | |
namespace :environments do | |
desc "Update one or more branches " | |
task :update, :branch do |_, args| | |
branch = args[:branch] || 'all' | |
log "Pruning origin" | |
git(:remote, :prune, :origin) | |
repo_dir = ENV['ROOT_DIR'] || '/opt/puppet' | |
envs_dir = ENV['PUPPET_ENV_DIR'] || "#{ROOT_DIR}/environments" | |
log "Loading list of branches" | |
all_branches = git(:branch, '-a').split(/\W*\n\W*/) | |
branches = all_branches.map {|r| remote_branch_name(r) }.compact | |
# Unless specified, only deploy the requested branch | |
branch.eql?('all') ? deploy = branches : deploy = branch | |
Rake::Task['environments:cleanup'].invoke(envs_dir, branches) | |
Rake::Task['environments:setup'].invoke(envs_dir, repo_dir, deploy) | |
Rake::Task['environments:symlink'].invoke(envs_dir) | |
end | |
desc "Clean up old branches from upstream" | |
task :cleanup, :dir, :branches do |_, args| | |
dir, branches = args[:dir], args[:branches] | |
log "Cleaning up deleted branches from #{Dir.pwd}" | |
Dir.chdir(dir) do | |
current_envs = Dir['*'] | |
current_envs.each do |env| | |
next if env == 'current_working_directory' | |
next if branches.include? env | |
next if branches.any?{ |branch| branch.gsub(/\W/,'_') == env } | |
puts "Removing environment #{env}" | |
FileUtils.rm_rf env | |
end | |
end | |
end | |
desc "Deploy a branch" | |
task :setup, :env_dir, :repo_dir, :branches do |_, args| | |
environments_dir, repo_dir, branches = args[:env_dir], args[:repo_dir], args[:branches] | |
Array(branches).each do |branch| | |
log "Setting up branch #{branch} from #{Dir.pwd}" | |
env_checkout = "#{environments_dir}/#{branch.gsub(/\W/,'_')}" | |
Dir.chdir(repo_dir) do | |
log "Updating git root from #{Dir.pwd}" | |
git(:fetch, '--all') | |
log "Running gc on git root." | |
git(:gc, '--auto') | |
end | |
log "Cloning initial branch environment #{branch}" | |
git(:clone, '--mirror', repo_dir, "#{env_checkout}.tmp/.git") | |
Dir.chdir("#{env_checkout}.tmp") do | |
log "Turning bare mirror into regular repository" | |
git(:config, '--bool', 'core.bare', 'false') | |
log "Resetting branch environment to origin/#{branch}" | |
git(:reset, '--hard', "origin/#{branch}") | |
local_branch_sha = git('show', '-s', '--pretty=format:%H', 'HEAD').strip | |
log "Environment #{branch} is currently on #{local_branch_sha}" | |
end | |
log "Deploying new branch environment #{branch}" | |
FileUtils.mv env_checkout, "#{env_checkout}.old" if File.directory? env_checkout | |
FileUtils.mv "#{env_checkout}.tmp", env_checkout | |
FileUtils.rm_rf "#{env_checkout}.old" if File.directory? "#{env_checkout}.old" | |
end | |
end | |
task :symlink, :environments_dir do |_, args| | |
environments_dir = args[:environments_dir] | |
unless Dir.exists?("#{environments_dir}/production") do | |
log "Creating production symlinks" | |
Dir.chdir(environments_dir) do | |
ln_nfs 'master', 'production' | |
end | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def git(command, *args) | |
arguments = args.map {|a| a.to_s }.join(' ') | |
output = `git #{command} #{arguments} 2>&1` | |
log output | |
output | |
end | |
def remote_branch_name(full_branch_name) | |
full_branch_name[%r{remotes/origin/([\w\-\/]*)$}, 1] | |
end | |
def librarian(dir) | |
Dir.chdir(dir) | |
puts `bundle exec librarian-puppet install` | |
end | |
def ln_nfs(source, dest) | |
if File.exists?(dest) || | |
(File.symlink?(dest) && File.readlink(dest) != source) | |
File.unlink dest | |
end | |
File.symlink source, dest | |
end | |
def log(message) | |
timestr = Time.now.strftime("%H:%M:%S") | |
puts "[#{timestr}] #{message}" | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env sh | |
set -e | |
if [ $(id -u) -ne 0 ]; then | |
echo "Please run with root privileges" | |
exit 1 | |
fi | |
DIR=$( dirname "$(readlink -f "$0")" ) | |
. $DIR/shared-functions | |
cd $PROJECT_ROOT | |
echo "Configuring system..." | |
if [ -n "$DEBUG" ]; then | |
echo "Enabling Debug..." | |
PUPPET_GRAPH_ARGS="--graph --graphdir $PROJECT_ROOT/graphs/$NODE" | |
PUPPET_DEBUG_ARGS="--debug --verbose $PUPPET_GRAPH_ARGS" | |
LIBRARIAN_DEBUG_AGRS="--verbose" | |
GIT_DEBUG_ARGS="--verbose" | |
RSYNC_DEBUG_ARGS="-v" | |
## Make graph directory for output and debug | |
if [ ! -d $PROJECT_ROOT/graphs/${NODE} ]; then | |
mkdir -p $PROJECT_ROOT/graphs/${NODE} | |
fi | |
fi | |
# Disable color output from different tools | |
if [ -n "$NOCOLOR" ]; then | |
PUPPET_COLOR_ARGS="--color=false" | |
fi | |
# Do not attempt to upload from upstream git | |
if [ -z "$DISABLE_GIT" ]; then | |
git pull origin -q $GIT_DEBUG_ARGS | |
fi | |
## Run any pre-flight commands | |
$PROJECT_ROOT/script/preflight-os | |
# Set the environment. This should be done *after* librarian-puppet | |
## has done its thing to determine if it is needed to switch back | |
## to production if the branch has been deleted. | |
## | |
## `puppet_environment` is set in Class[puppet::masterless] | |
CURRENT_ENV=`$PROJECT_ROOT/bin/facter puppet_environment` | |
PUPPET_ENV="" | |
if [ -z "$ENV" ]; then | |
if [ -n "$CURRENT_ENV" ]; then | |
PUPPET_ENV=$CURRENT_ENV | |
else | |
PUPPET_ENV='production' | |
fi | |
else | |
PUPPET_ENV=$ENV | |
fi | |
# Setup Puppet environments | |
mkdir -p $PROJECT_ROOT/environments | |
if [ "$PUPPET_ENV" = "current_working_directory" ]; then | |
# Make sure the current working directory is an environment too! | |
# This is sort of a hack to support environments while developing | |
# on the currently active branch in Vagrant or other environments | |
echo "Setting up 'current_working_directory'..." | |
## Install Puppet libs | |
librarian-puppet install >> $LOG_FILE 2>&1 | |
## Setup an environment for this project | |
rsync $RSYNC_DEBUG_ARGS -arh --delete --exclude "environments" \ | |
--exclude "vendor" --exclude "artifacts" --exclude "graphs" \ | |
--exclude "packer" --exclude "script" --exclude ".git" \ | |
$PROJECT_ROOT/ $PROJECT_ROOT/environments/current_working_directory/ | |
else | |
echo "Setting up Puppet environments..." | |
rake environments:update[$PUPPET_ENV] >> $LOG_FILE 2>&1 | |
fi | |
## Attempt to detect if the environment even exists... if not, | |
## roll back to the production environment. | |
### Make sure our environment conforms to Puppet environment naming | |
PUPPET_ENV=$(echo $PUPPET_ENV | sed 's/[-\/.]/_/g') | |
if [ ! -d $PROJECT_ROOT/environments/$PUPPET_ENV ]; then | |
echo "The environment $PUPPET_ENV does not exist... falling back to production" | |
PUPPET_ENV='production' | |
fi | |
## Run Puppet | |
puppet apply $PUPPET_DEBUG_ARGS --environment $PUPPET_ENV \ | |
--config $PROJECT_ROOT/puppet.conf $PUPPET_COLOR_ARGS \ | |
$PROJECT_ROOT/environments/$PUPPET_ENV/manifests $@ 2>&1 \ | |
| tee -a $LOG_FILE |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment