Skip to content

Instantly share code, notes, and snippets.

@octplane
Created December 8, 2011 15:56
Show Gist options
  • Save octplane/1447412 to your computer and use it in GitHub Desktop.
Save octplane/1447412 to your computer and use it in GitHub Desktop.
Add chef search capability when using roles in capistrano Tasks
require 'rubygems'
require 'chef/client'
require 'chef/run_status'
require 'ohai'
require 'chef/mixin/language'
# Override the default role search in capistrano
# can be used to combine chef searches in capistrano land:
# task :master_update, :roles => 'recipes:chef\:\:server' do
# ...
# end
module Capistrano::Configuration::Servers
# Attempts to find all defined servers that match the given criteria.
# The options hash may include a :hosts option (which should specify
# an array of host names or ServerDefinition instances), a :roles
# option (specifying an array of roles), an :only option (specifying
# a hash of key/value pairs that any matching server must match),
# an :exception option (like :only, but the inverse), and a
# :skip_hostfilter option to ignore the HOSTFILTER environment variable
# described below.
#
# Additionally, if the HOSTS environment variable is set, it will take
# precedence over any other options. Similarly, the ROLES environment
# variable will take precedence over other options. If both HOSTS and
# ROLES are given, HOSTS wins.
#
# Yet additionally, if the HOSTFILTER environment variable is set, it
# will limit the result to hosts found in that (comma-separated) list.
#
# If the HOSTROLEFILTER environment variable is set, it will limit the
# result to hosts found in that (comma-separated) list of roles
#
# Usage:
#
# # return all known servers
# servers = find_servers
#
# # find all servers in the app role that are not exempted from
# # deployment
# servers = find_servers :roles => :app,
# :except => { :no_release => true }
#
# # returns the given hosts, translated to ServerDefinition objects
# servers = find_servers :hosts => "[email protected]"
def find_servers(options={})
return [] if options.key?(:hosts) && (options[:hosts].nil? || [] == options[:hosts])
return [] if options.key?(:roles) && (options[:roles].nil? || [] == options[:roles])
hosts = server_list_from(ENV['HOSTS'] || options[:hosts])
if hosts.any?
if options[:skip_hostfilter]
hosts.uniq
else
filter_server_list(hosts.uniq)
end
else
roles = role_list_from(ENV['ROLES'] || options[:roles] || self.roles.keys)
roles = roles & Array(options[:roles]) if preserve_roles && !options[:roles].nil?
only = options[:only] || {}
except = options[:except] || {}
# BOH
# Override role definition
@chef_search_facility ||= SearchHelper.new
# servers = roles.inject([]) { |list, role| list.concat(self.roles[role] || []) }
servers = roles.inject([]) { |list, role|
if ! self.roles.has_key?(role)
# If the role is missing create it on the fly and keep on working
role(role, *@chef_search_facility.search(:node, role).map {|n| n[:hostname]})
end
list.concat(self.roles[role] || [])
}
# EOH
servers = servers.select { |server| only.all? { |key,value| server.options[key] == value } }
servers = servers.reject { |server| except.any? { |key,value| server.options[key] == value } }
if options[:skip_hostfilter]
servers.uniq
else
filter_server_list(servers.uniq)
end
end
end
end
# Boot Chef system
Chef::Config.from_file("/etc/chef/client.rb")
Chef::Log.level :info
ohai = Ohai::System.new()
ohai.all_plugins
@node_name ||= ohai[:fqdn] ? ohai[:fqdn] : ohai[:hostname]
Chef::Config[:node_name] = @node_name
c = Chef::Client.new()
c.run_ohai
node = c.build_node
# the search helper can be used inside capistrano to allow the usage of the Chef mixin methods
# set :chef_searcher, SearchHelper.new
# ...
# chef_server.search(:node, "")
#
class SearchHelper
include Chef::Mixin::Language
end
@octplane
Copy link
Author

octplane commented Dec 8, 2011

require inside your capistrano file to activate. Use later as described in the source code. Share and have fun !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment