Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per-server conf and add role + data bags paths to solo.rb file #33

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
120 changes: 62 additions & 58 deletions lib/roundsman/capistrano.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
def run_list(*recipes)
if recipes.any?
set :run_list, recipes
install_ruby if fetch(:run_roundsman_checks, true) && install_ruby?
install_ruby
run_chef
else
Array(fetch(:run_list))
Expand Down Expand Up @@ -48,11 +48,10 @@ def run(*args)
set_default(:roundsman_user) { fetch(:user) { capture('whoami').strip } }
set_default :debug_chef, false
set_default :package_manager, 'apt-get'
set_default :run_roundsman_checks, true

desc "Lists configuration"
task :configuration do
@_defaults.sort_by {|sym| sym.to_s}.each do |name|
@_defaults.sort.each do |name|
display_name = ":#{name},".ljust(30)
if variables[name].is_a?(Proc)
value = "<block>"
Expand All @@ -76,29 +75,10 @@ def run(*args)
end

def ensure_roundsman_working_dir
run "mkdir -p #{fetch(:roundsman_working_dir)}"
run "mkdir -p #{fetch(:roundsman_working_dir)}/cache"
sudo "chown -R #{fetch(:roundsman_user)} #{fetch(:roundsman_working_dir)}"
end

def install_ruby?
installed_version = capture("ruby --version || true").strip
if installed_version.include?("not found")
logger.info "No version of Ruby could be found."
return true
end
required_version = fetch(:ruby_version).gsub("-", "")
if fetch(:care_about_ruby_version)
if installed_version.include?(required_version)
logger.info "Ruby #{installed_version} matches the required version: #{required_version}."
return false
else
logger.info "Ruby version mismatch. Installed version: #{installed_version}, required is #{required_version}"
return true
end
else
logger.info "Already installed Ruby #{installed_version}, not #{required_version}. Set :care_about_ruby_version if you want to fix this."
return false
unless @ensured_roundsman_working_dir
run "mkdir -p #{fetch(:roundsman_working_dir)}/cache"
sudo "chown -R #{fetch(:roundsman_user)} #{fetch(:roundsman_working_dir)}"
@ensured_roundsman_working_dir = true
end
end

Expand Down Expand Up @@ -158,20 +138,43 @@ def distribution
end

def ensure_supported_distro
logger.info "Using Linux distribution #{distribution}"
abort "This distribution is not (yet) supported." unless distribution.include?("Ubuntu")
unless @ensured_supported_distro
logger.info "Using Linux distribution #{distribution}"
abort "This distribution is not (yet) supported." unless distribution.include?("Ubuntu")
@ensured_supported_distro = true
end
end

def install_ruby?
installed_version = capture("ruby --version || true").strip
if installed_version.include?("not found")
logger.info "No version of Ruby could be found."
return true
end
required_version = fetch(:ruby_version).gsub("-", "")
if installed_version.include?(required_version)
if fetch(:care_about_ruby_version)
logger.info "Ruby #{installed_version} matches the required version: #{required_version}."
return false
else
logger.info "Already installed Ruby #{installed_version}, not #{required_version}. Set :care_about_ruby_version if you want to fix this."
return false
end
else
logger.info "Ruby version mismatch. Installed version: #{installed_version}, required is #{required_version}"
return true
end
end

end

namespace :chef do

set_default :chef_version, "~> 10.18.2"
set_default :chef_version, "~> 0.10.8"
set_default :cookbooks_directory, ["config/cookbooks"]
set_default :databags_directory, "config/data_bags"
set_default :copyfile_disable, false
set_default :verbose_logging, true
set_default :filter_sensitive_settings, [ /password/, /filter_sensitive_settings/ ]
set_default :remove_settings_from_chef, [ ]

task :default, :except => { :no_release => true } do
ensure_cookbooks_exists
Expand All @@ -181,7 +184,7 @@ def ensure_supported_distro

desc "Generates the config and copies over the cookbooks to the server"
task :prepare_chef, :except => { :no_release => true } do
install if fetch(:run_roundsman_checks, true) && install_chef?
install if install_chef?
ensure_cookbooks_exists
generate_config
generate_attributes
Expand All @@ -190,27 +193,15 @@ def ensure_supported_distro

desc "Installs chef"
task :install, :except => { :no_release => true } do
if self[:rvm_type] == :user
run "gem uninstall -xaI chef || true"
run "gem install chef -v #{fetch(:chef_version).inspect} --quiet --no-ri --no-rdoc"
run "gem install ruby-shadow --quiet --no-ri --no-rdoc"
else
sudo "gem uninstall -xaI chef || true"
sudo "gem install chef -v #{fetch(:chef_version).inspect} --quiet --no-ri --no-rdoc"
sudo "gem install ruby-shadow --quiet --no-ri --no-rdoc"
end
sudo "gem uninstall -xaI chef || true"
sudo "gem install chef -v #{fetch(:chef_version).inspect} --quiet --no-ri --no-rdoc"
sudo "gem install ruby-shadow --quiet --no-ri --no-rdoc"
end

desc "Runs the existing chef configuration"
task :chef_solo, :except => { :no_release => true } do
logger.info "Now running #{fetch(:run_list).join(', ')}"
old_sudo = self[:sudo]
if self[:rvm_type] == :user
self[:sudo] = "rvmsudo_secure_path=1 #{File.join(rvm_bin_path, "rvmsudo")}"
end

sudo "chef-solo -c #{roundsman_working_dir("solo.rb")} -j #{roundsman_working_dir("solo.json")}#{' -l debug' if fetch(:debug_chef)}"
self[:sudo] = old_sudo
end

def ensure_cookbooks_exists
Expand All @@ -219,12 +210,15 @@ def ensure_cookbooks_exists
end

def cookbooks_paths
Array(fetch(:cookbooks_directory)).select { |path| File.exist?(path) }
Array(fetch(:cookbook_path)).select { |path| File.exist?(path) }
end

def roles_path
fetch(:role_path)
end

def databags_path
path = fetch(:databags_directory)
File.exist?(path) ? path : nil
def data_bags_path
fetch(:data_bag_path)
end

def install_chef?
Expand All @@ -235,28 +229,38 @@ def install_chef?

def generate_config
cookbook_string = cookbooks_paths.map { |c| "File.join(root, #{c.to_s.inspect})" }.join(', ')
role_string = "File.join(root, #{roles_path.to_s.inspect})" if roles_path
data_bag_string = "File.join(root, #{data_bags_path.to_s.inspect})" if data_bags_path
solo_rb = <<-RUBY
root = File.expand_path(File.dirname(__FILE__))
file_cache_path File.join(root, "cache")
cookbook_path [ #{cookbook_string} ]
verbose_logging #{fetch(:verbose_logging)}
data_bag_path File.join(root, #{fetch(:databags_directory).to_s.inspect})
RUBY

solo_rb << "role_path #{role_string}\n" if role_string
solo_rb << "data_bag_path #{data_bag_string}\n" if data_bag_string

put solo_rb, roundsman_working_dir("solo.rb"), :via => :scp
end

def generate_attributes
attrs = remove_procs_from_hash variables.dup
put attrs.to_json, roundsman_working_dir("solo.json"), :via => :scp
find_servers_for_task(current_task).each do |current_server|
merged_options = variables.merge(current_server.options)
server_conf = remove_procs_from_hash(merged_options)

put server_conf.to_json, roundsman_working_dir("solo.json"), :via => :scp, :hosts => current_server.host
end
end

# Recursively removes procs from hashes. Procs can exist because you specified them like this:
#
# set(:root_password) { Capistrano::CLI.password_prompt("Root password: ") }
def remove_procs_from_hash(hash)
filter_fields = Array(fetch(:filter_sensitive_settings)) + Array(fetch(:remove_settings_from_chef))

new_hash = {}
hash.each do |key, value|
next if fetch(:filter_sensitive_settings).find { |regex| regex.match(key.to_s) }
next if filter_fields.find { |matcher| matcher === key }
real_value = if value.respond_to?(:call)
begin
value.call
Expand All @@ -271,7 +275,7 @@ def remove_procs_from_hash(hash)
if real_value.is_a?(Hash)
real_value = remove_procs_from_hash(real_value)
end
if real_value != nil && !real_value.class.to_s.include?("Capistrano") # skip capistrano tasks
if real_value && !real_value.class.to_s.include?("Capistrano") # skip capistrano tasks
new_hash[key] = real_value
end
end
Expand All @@ -283,7 +287,7 @@ def copy_cookbooks
begin
tar_file.close
env_vars = fetch(:copyfile_disable) && RUBY_PLATFORM.downcase.include?('darwin') ? "COPYFILE_DISABLE=true" : ""
system "#{env_vars} tar -cjf #{tar_file.path} #{cookbooks_paths.join(' ')} #{databags_path.to_s}"
system "#{env_vars} tar -cjf #{tar_file.path} #{cookbooks_paths.join(' ')}"
upload tar_file.path, roundsman_working_dir("cookbooks.tar"), :via => :scp
run "cd #{roundsman_working_dir} && tar -xjf cookbooks.tar"
ensure
Expand Down