Skip to content

Instantly share code, notes, and snippets.

@tmclaugh
Created May 19, 2014 16:43
Show Gist options
  • Save tmclaugh/9a0df4fe050a7b1cd6e1 to your computer and use it in GitHub Desktop.
Save tmclaugh/9a0df4fe050a7b1cd6e1 to your computer and use it in GitHub Desktop.
Vagrant Rakefile
# Rake wrapper around Vagrant.
#
# The intended usage is as follows
# $ rake vagrant:init[<branch_name>]
#
# This will create a vagrant instance named <branch_name>. It will also
# ensure that the puppet-deploy tree is on the same branch and that Puppet
# librarian has been run.
#
# TODO
# - daemon to check if puppet modules have changed branch and stop agent on
# the guest.
# - Convert over to named arguments possibly?
# - http://archives.ryandaigle.com/articles/2007/6/22/using-command-line-parameters-w-rake-and-capistrano
# - `vagrant up` has the ability to instantiate a host without running
# provisioners which may be useful to us.
#
VG_ROOT = File.dirname(__FILE__)
PUPPET_CLONE = VG_ROOT.split(File::SEPARATOR)[0..-2].join(File::SEPARATOR)
VAGRANTFILE = '%s/Vagrantfile' % VG_ROOT
INSTANCE_ROOT = '%s/instance' % VG_ROOT
DEFAULT_ROLE = 'role_basenode'
commands = {
:git => 'git',
:vagrant => 'vagrant',
:librarian_puppet => 'librarian-puppet'
}
namespace :vagrant do
def vagrant_cmd(instance, action, args='', env_args=nil, exit_true=false)
instance_dir = "#{INSTANCE_ROOT}/#{instance}"
if env_args
env_args.each do |arg|
k, v = arg.split('=')
ENV["#{k}"] = v
end
end
start_dir = Dir.pwd
Dir.chdir(instance_dir)
ENV['VG_PUPPET_CLONE'] = PUPPET_CLONE
if exit_true
exit_s = '; true'
else
exist_s = ''
end
sh %{vagrant #{action} #{args} #{exist_s}}
Dir.chdir(start_dir)
end
desc "switch to correct branch"
task :change_branch, :branch do |t, args|
branch = args[:branch]
if branch
sh %{git checkout #{branch}}
end
end
desc "run librarian-puppet"
task :run_librarian, [:branch] => ['change_branch'] do |t, args|
args.with_defaults(:branch => false)
branch = args[:branch]
if branch
if not File.exists?("#{PUPPET_CLONE}/Puppetfile.lock.#{branch}")
start_dir = Dir.pwd
Dir.chdir(PUPPET_CLONE)
FileUtils.rm Dir.glob("#{PUPPET_CLONE}/Puppetfile.lock.*")
sh %{#{commands[:librarian_puppet]} update --verbose}
FileUtils.ln_s "Puppetfile.lock", "#{PUPPET_CLONE}/Puppetfile.lock.#{branch}"
Dir.chdir(start_dir)
end
else
if not File.exists?("#{PUPPET_CLONE}/Puppetfile.lock")
# We can't guarentee that Puppetfile.lock won't change so we'll
# remove the Puppetfile.lock for a branch.
FileUtils.rm Dir.glob("#{PUPPET_CLONE}/Puppetfile.lock.*")
start_dir = Dir.pwd
Dir.chdir(PUPPET_CLONE)
sh %{#{commands[:librarian_puppet]} update --verbose}
Dir.chdir(start_dir)
end
end
end
desc "initialize instance"
task :init, :instance do |t, args|
instance = args[:instance]
instance_dir = "#{INSTANCE_ROOT}/#{instance}"
instance_vgfile = "#{instance_dir}/Vagrantfile"
# Process command line environment arguments
if ENV['role']
role = ENV['role']
elsif defined? ROLE
role = ROLE
else
role = DEFAULT_ROLE
end
if ENV['branch']
branch = ENV['branch']
elsif defined? BRANCH
branch = BRANCH
else
branch = nil
end
Rake::Task['vagrant:run_librarian'].invoke(branch)
if not File.exists?(instance_vgfile)
# Create home for all instances if it doesn't exist.
if not File.directory?(INSTANCE_ROOT)
Dir.mkdir(INSTANCE_ROOT)
end
# Create home for this instance if it doesn't exist.
if not File.directory?(instance_dir)
puts "Creating #{instance_dir}"
Dir.mkdir(instance_dir)
end
start_dir = Dir.pwd
Dir.chdir(instance_dir)
puts Dir.pwd
vagrant_cmd(args[:instance], 'init')
FileUtils.cp(VAGRANTFILE, instance_vgfile)
Dir.chdir(start_dir)
end
#Write our defaults. We only write this on first init.
if not File.exists?("#{instance_dir}/config.rb")
# write state information.
File.open("#{instance_dir}/config.rb", 'w') do |line|
if branch
line.write("BRANCH='#{branch}'\n")
else
line.write("BRANCH=false\n")
end
if role
line.write("ROLE='#{role}'\n")
else
line.write("ROLE=false\n")
end
end
end
end
desc "Bring up instance"
task :up, :instance do |t, args|
instance = args[:instance]
instance_dir = "#{INSTANCE_ROOT}/#{instance}"
# Let's get our state defaults if they exist
if File.exists?("#{instance_dir}/config.rb")
puts "checking defaults"
require "#{instance_dir}/config.rb"
end
# Process command line environment arguments
if ENV['role']
role = ENV['role']
elsif defined? ROLE
role = ROLE
else
role = DEFAULT_ROLE
end
role_full_list = []
role.split(',').each do |r|
role_full_list << "hubspot::roles::#{r}"
end
role_full = role_full_list.join(',')
if ENV['branch']
branch = ENV['branch']
elsif defined? BRANCH
branch = BRANCH
else
branch = nil
end
# Initialize setup
Rake::Task['vagrant:init'].invoke(instance, role, branch)
puts "Starting instance with:"
puts "role:\t#{role}"
puts "branch:\t#{branch}"
vagrant_cmd(args[:instance], 'up', '', env_args=["VG_ROLE=#{role_full}"])
end
desc "Bring up instance and then destroy it."
task :compile, :instance do |t, args|
instance = args[:instance]
instance_dir = "#{INSTANCE_ROOT}/#{instance}"
if defined? ENV['once']
once = true
end
# Initialize setup
Rake::Task['vagrant:up'].invoke(instance)
if once
Rake::Task['vagrant:remove'].invoke(instance)
else
Rake::Task['vagrant:destroy'].invoke(instance)
end
end
desc "Destroy instance"
task :destroy, :instance do |t, args|
vagrant_cmd(args[:instance], 'destroy', '-f')
end
desc "Halt instance"
task :halt, :instance do |t, args|
vagrant_cmd(args[:instance], 'halt')
end
desc "Run the provisioner again"
task :provision, :instance, :provisioner, :vmname do |t, args|
args.with_defaults(:provisioner => false)
provisioner = args[:provisioner]
vmname = args[:vmname]
if provisioner
prov_arg = "--provision-with #{provisioner}"
end
# Our default setup is a single VM so this isn't really useful.
if vmname
vmname_arg = vmname
end
vagrant_cmd(args[:instance], 'provision' "#{vmname_arg} #{prov_arg}")
end
desc "Reload instance"
task :reload, :instance do |t, args|
vagrant_cmd(args[:instance], 'reload')
end
desc "Resume instance"
task :resume, :instance do |t, args|
vagrant_cmd(args[:instance], 'resume')
end
desc "Remove instance entirely"
task :remove, [:instance] => ['destroy'] do |t, args|
instance = args[:instance]
instance_dir = "#{INSTANCE_ROOT}/#{instance}"
FileUtils.rm_r(instance_dir)
end
desc "SSH into instance"
task :ssh, :instance do |t, args|
vagrant_cmd(args[:instance], 'ssh', '', env_args=nil, exit_true=true)
end
desc "Check instance status"
task :status, :instance do |t, args|
vagrant_cmd(args[:instance], 'status')
end
desc "Suspend instance"
task :suspend, :instance do |t, args|
vagrant_cmd(args[:instance], 'suspend')
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment