Skip to content

Commit

Permalink
Merge pull request nesquena#6 from demandchain/zsp-refactor-chef-recipe
Browse files Browse the repository at this point in the history
major refactor to chef recipes
  • Loading branch information
Donovan Bray committed Oct 29, 2013
2 parents 3b150dd + 802e793 commit 8316589
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 53 deletions.
4 changes: 3 additions & 1 deletion lib/cap_recipes/tasks/chef_client/client.rb.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
log_level <%= chef_client_config_log_level %>
log_level :<%= chef_client_config_log_level.to_s %>
log_location <%= chef_client_config_log_location %>
chef_server_url "<%= chef_client_config_chef_server_url %>"
ssl_verify_mode <%= chef_client_config_ssl_verify_mode %>
validation_client_name "<%= chef_client_config_validation_client_name %>"
environment "<%= chef_client_config_environment %>"
file_backup_path "<%= chef_client_config_file_backup_path %>"
file_cache_path "<%= chef_client_config_file_cache_path %>"

Mixlib::Log::Formatter.show_time = true
19 changes: 12 additions & 7 deletions lib/cap_recipes/tasks/chef_client/hooks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@
Capistrano::Configuration.instance(true).load do

# DEPLOY
after "deploy:stop", "chef:client:stop"
after "deploy:start", "chef:client:start"
after "deploy:restart", "chef:client:restart"
after "deploy:provision", "chef:client:install"
after "deploy:update", "chef:client:update"
# after "deploy:stop", "chef:client:stop"
# after "deploy:start", "chef:client:start"
# after "deploy:restart", "chef:client:restart"
# after "deploy:provision", "chef:client:install"
# after "deploy:update", "chef:client:update"

# CHEF-CLIENT
after "chef:client:install", "chef:client:update"
# after "chef:client:update", "chef:client:logrotate"
# after "chef:client:install", "chef:client:configure"
# after "chef:client:configure", "chef:client:bootstrap"
# after "chef:client:bootstrap", "chef:client:status"

after "chef:client:stop", "chef:client:status"
after "chef:client:start", "chef:client:status"
after "chef:client:restart", "chef:client:status"

end
60 changes: 54 additions & 6 deletions lib/cap_recipes/tasks/chef_client/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,23 @@
set(:chef_client_dc3_machine_arch) { "x86_64" }

set(:chef_client_config_template) { File.join(File.dirname(__FILE__), 'client.rb.erb') }
set(:chef_client_config_log_level) { ":debug" }
set(:chef_client_config_log_level) { :info }
set(:chef_client_config_log_location) { "STDOUT" }
set(:chef_client_config_chef_server_url) { nil }
set(:chef_client_config_ssl_verify_mode) { ":verify_none" }
set(:chef_client_config_validation_client_name) { "chef-validator" }
set(:chef_client_config_environment) { rails_env.to_s }
set(:chef_client_config_environment) { nil }
set(:chef_client_config_file_backup_path) { "/var/chef/backup" }
set(:chef_client_config_file_cache_path) { "/var/chef/cache" }
set(:chef_client_install_method) { :ec2 }
set(:chef_server_validation_pem_path) { nil }
set(:chef_client_config_encrypted_data_bag_secret_path) { nil }

desc "install chef-client"
task :install, :roles => [:chef_client], :on_no_matching_servers => :continue do
logger.info("#" * 80)
logger.info("# CHEF-CLIENT INSTALL")
logger.info("#" * 80)
case chef_client_install_method.to_sym
when :ec2 then
run("curl -L http://www.opscode.com/chef/install.sh | #{sudo} bash")
Expand All @@ -46,14 +52,56 @@
sudo("dpkg -i /var/tmp/chef-client.deb")
sudo("ln -svf /opt/chef/bin/* /usr/bin/")
end
end

desc "configure chef-client"
task :configure, :roles => [:chef_client], :on_no_matching_servers => :continue do
logger.info("#" * 80)
logger.info("# CHEF-CLIENT CONFIGURE")
logger.info("#" * 80)

sudo("mkdir -p /etc/chef/")

chef_server_validation_pem = File.expand_path(File.join(chef_server_validation_pem_path, "chef-#{chef_client_install_method}-validation.pem"))
utilities.sudo_upload(chef_server_validation_pem, "/etc/chef/validation.pem", :owner => "root:root")
end
utilities.sudo_upload(chef_server_validation_pem, "/etc/chef/validation.pem", :owner => "root:root", :mode => "0400")

chef_client_config_encrypted_data_bag_secret = File.expand_path(File.join(chef_client_config_encrypted_data_bag_secret_path, "chef-#{chef_client_install_method}-data-bag-secret"))
utilities.sudo_upload(chef_client_config_encrypted_data_bag_secret, "/etc/chef/encrypted_data_bag_secret", :owner => "root:root", :mode => "0400")

desc "update chef-client"
task :update, :roles => [:chef_client], :on_no_matching_servers => :continue do
utilities.sudo_upload_template(chef_client_config_template, "/etc/chef/client.rb", :owner => "root:root")

sudo("chown -Rv root:root /etc/chef")
end

desc "chef-client bootstrap; purges the chef-client cache then runs chef-client once via command line"
task :bootstrap, :roles => [:chef_client], :on_no_matching_servers => :continue do
chef.client.stop
find_servers_for_task(current_task).each do |server|
logger.info("#" * 80)
logger.info("# CHEF-CLIENT BOOTSTRAP: #{server}")
logger.info("#" * 80)

sudo("rm -rfv /var/chef/cache/* /var/chef/backup/*", :hosts => server)
sudo("bash -c '([[ -f /opt/chef/bin/chef-client ]] && /opt/chef/bin/chef-client) || echo \"NOOP\"'", :hosts => server)
sudo("bash -c '([[ -f /etc/chef/client.pem ]] && chmod -v 0400 /etc/chef/client.pem) || echo \"NOOP\"'", :hosts => server)
sudo("chown -Rv root:root /etc/chef", :hosts => server)
end
chef.client.start
end

desc "chef-client boot; runs the chef-client once via command line"
task :boot, :roles => [:chef_client], :on_no_matching_servers => :continue do
chef.client.stop
find_servers_for_task(current_task).each do |server|
logger.info("#" * 80)
logger.info("# CHEF-CLIENT BOOT: #{server}")
logger.info("#" * 80)

sudo("bash -c '([[ -f /opt/chef/bin/chef-client ]] && /opt/chef/bin/chef-client) || echo \"NOOP\"'", :hosts => server)
sudo("bash -c '([[ -f /etc/chef/client.pem ]] && chmod -v 0400 /etc/chef/client.pem) || echo \"NOOP\"'", :hosts => server)
sudo("chown -Rv root:root /etc/chef", :hosts => server)
end
chef.client.start
end

end
Expand Down
134 changes: 101 additions & 33 deletions lib/cap_recipes/tasks/chef_client/manage.rb
Original file line number Diff line number Diff line change
@@ -1,65 +1,133 @@
###############################################################################
# CHEF-CLIENT MANAGE
################################################################################
require 'ostruct'

Capistrano::Configuration.instance(true).load do

namespace :chef do
namespace :client do

def with_report(servers, headers, &block)
raise "You must supply a block to 'with_report'!" if !block_given?

results = Array.new
max_lengths = OpenStruct.new
servers.each do |server|
results << block.call(server)
end

headers.each do |header|
maximum = [headers.collect{ |header| header.to_s }, results.collect{ |result| result.send(header.to_sym).to_s }].flatten.map(&:length).max
max_lengths.send("#{header}=", maximum)
end

puts("-" * (max_lengths.send(:table).values.reduce(:+) + (max_lengths.send(:table).keys.count * 2)))
headers.each do |header|
print(" %#{max_lengths.send(header)}s" % [header.to_s.upcase])
end
print("\n")
puts("-" * (max_lengths.send(:table).values.reduce(:+) + (max_lengths.send(:table).keys.count * 2)))

results.each do |result|
headers.each do |header|
print(" %#{max_lengths.send(header)}s" % [result.send(header)])
end
print("\n")
end
puts("-" * (max_lengths.send(:table).values.reduce(:+) + (max_lengths.send(:table).keys.count * 2)))
end

desc "start chef-client"
task :start, :roles => [:chef_client] do
logger.info("################################################################################")
logger.info("#" * 80)
logger.info("# CHEF-CLIENT START")
logger.info("################################################################################")
sudo("bash -c '([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client start) || ([[ -f /sbin/service ]] && /sbin/service chef-client start)'")
logger.info("#" * 80)
sudo("bash -c '([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client start) || echo \"NOT INSTALLED\"'")
end

desc "stop chef-client"
task :stop, :roles => [:chef_client] do
logger.info("################################################################################")
logger.info("#" * 80)
logger.info("# CHEF-CLIENT STOP")
logger.info("################################################################################")
sudo("bash -c '([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client stop) || ([[ -f /sbin/service ]] && /sbin/service chef-client stop)'")
logger.info("#" * 80)
sudo("bash -c '([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client stop) || echo \"NOT INSTALLED\"'")
end

desc "restart chef-client"
task :restart, :roles => [:chef_client] do
logger.info("################################################################################")
logger.info("#" * 80)
logger.info("# CHEF-CLIENT RESTART")
logger.info("################################################################################")
sudo("bash -c '([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client restart) || ([[ -f /sbin/service ]] && /sbin/service chef-client restart)'")
end

desc "reload chef-client"
task :reload, :roles => [:chef_client] do
logger.info("################################################################################")
logger.info("# CHEF-CLIENT RELOAD")
logger.info("################################################################################")
sudo("bash -c '([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client reload) || ([[ -f /sbin/service ]] && /sbin/service chef-client reload)'")
logger.info("#" * 80)
sudo("bash -c '([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client restart) || echo \"NOT INSTALLED\"'")
end

desc "chef-client status"
task :status, :roles => [:chef_client] do
logger.info("################################################################################")
logger.info("# CHEF-CLIENT STATUS")
logger.info("################################################################################")
sudo("bash -c '([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client status) || ([[ -f /sbin/service ]] && /sbin/service chef-client status)'")
results = Hash.new

run %Q{hostname -f} do |channel, stream, data|
break if data.strip.empty?
logger.info("#{channel.connection.host}: #{data.strip}")

result = (results[channel.connection.host] ||= OpenStruct.new)
result.hostname = data.strip
result.ip = channel.connection.host.strip
end

sudo %Q{bash -c '(([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client status) || echo "NOT INSTALLED")'} do |channel, stream, data|
break if data.strip.empty?
logger.info("#{channel.connection.host}: #{data.strip}")

result = (results[channel.connection.host] ||= OpenStruct.new)
data.strip!
!data.empty? and (result.chef_client_status = data)
end

sudo %Q{bash -c '(([[ -f /usr/bin/chef-client ]] && /usr/bin/chef-client -v) || echo "NOT INSTALLED")'} do |channel, stream, data|
break if data.strip.empty?
logger.info("#{channel.connection.host}: #{data.strip}")

result = (results[channel.connection.host] ||= OpenStruct.new)
data.strip!
!data.empty? and (result.chef_client_version = data)
end

with_report(results.values, [:hostname, :ip, :chef_client_version, :chef_client_status]) do |result|
result
end
end

desc "chef-client status"
task :version, :roles => [:chef_client] do
logger.info("################################################################################")
logger.info("# CHEF-CLIENT VERSION")
logger.info("################################################################################")
sudo("bash -c '([[ -f /usr/bin/chef-client ]] && /usr/bin/chef-client -v) || echo \"Failed to find the chef-client executable!\"'")
desc "watch chef-client logs"
task :tail, :roles => [:chef_client] do
logger.info("#" * 80)
logger.info("# CHEF-CLIENT TAIL")
logger.info("#" * 80)
stream("#{sudo} tail -f /var/log/chef/client.log")
end

desc "chef-client bootstrap; runs chef-client once via command line"
task :bootstrap, :roles => [:chef_client] do
logger.info("################################################################################")
logger.info("# CHEF-CLIENT BOOTSTRAP")
logger.info("################################################################################")
sudo("bash -c '([[ -f /usr/bin/chef-client ]] && /usr/bin/chef-client) || echo \"Failed to find the chef-client executable!\"'")
desc "chef-client key backup"
task :backup, :roles => [:chef_client] do
raise "You must specify a CHEF_ENV for this command!" if (ENV['CHEF_ENV'].nil? || ENV['CHEF_ENV'].blank?)
with_report(find_servers_for_task(current_task), [:hostname, :ip, :chef_client_version, :chef_client_status, :key_backup_result]) do |server|
logger.info("#" * 80)
logger.info("# CHEF-CLIENT KEY BACKUP: #{server}")
logger.info("#" * 80)

server_hostname = capture("hostname -f", :hosts => server).strip
chef_client_status = capture("#{sudo} bash -c '([[ -f /etc/init.d/chef-client ]] && /etc/init.d/chef-client status) || echo \"NOT INSTALLED\"'", :hosts => server).strip
chef_client_version = capture("#{sudo} bash -c '([[ -f /etc/init.d/chef-client ]] && /usr/bin/chef-client -v) || echo \"NOT INSTALLED\"'", :hosts => server).strip

to_filepath = File.expand_path(File.join(Dir.pwd, ".chef", "backup", current_ecosystem.to_s, "chef-#{ENV['CHEF_ENV'].downcase}-#{server_hostname}.pem"))
FileUtils.mkdir_p(File.dirname(to_filepath))
sudo("cp -v /etc/chef/client.pem /var/tmp/client.pem", :hosts => server)
sudo("chown -v dev:dev /var/tmp/client.pem", :hosts => server)
(top.download("/var/tmp/client.pem", to_filepath, :hosts => server) rescue nil)
sudo("rm -fv /var/tmp/client.pem", :hosts => server)
key_backup_result = ((File.exists?(to_filepath) && (File.mtime(to_filepath).utc > (Time.now.utc - 15.seconds))) ? "SUCCESS" : "X")

OpenStruct.new(:hostname => server_hostname, :ip => server.to_s, :chef_client_status => chef_client_status, :chef_client_version => chef_client_version, :key_backup_result => key_backup_result)
end
end

end
Expand Down
10 changes: 10 additions & 0 deletions lib/cap_recipes/tasks/chef_server/client.rb.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
log_level :<%= chef_server_config_log_level.to_s %>
log_location <%= chef_server_config_log_location %>
chef_server_url "<%= chef_server_config_chef_server_url %>"
ssl_verify_mode <%= chef_server_config_ssl_verify_mode %>
validation_client_name "<%= chef_server_config_validation_client_name %>"
environment "<%= chef_server_config_environment %>"
file_backup_path "<%= chef_server_config_file_backup_path %>"
file_cache_path "<%= chef_server_config_file_cache_path %>"

Mixlib::Log::Formatter.show_time = true
4 changes: 2 additions & 2 deletions lib/cap_recipes/tasks/chef_server/hooks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
Capistrano::Configuration.instance(true).load do

# DEPLOY
after "deploy:provision", "chef:server:install"
# after "deploy:provision", "chef:server:install"

# CHEF-SERVER
after "chef:server:install", "chef:server:update"
# after "chef:server:install", "chef:server:update"
# after "chef:server:update", "chef_server:logrotate"

end
Loading

0 comments on commit 8316589

Please sign in to comment.