lib/capistrano-chef-solo.rb in yyuu-capistrano-chef-solo-0.1.5 vs lib/capistrano-chef-solo.rb in yyuu-capistrano-chef-solo-0.1.6
- old
+ new
@@ -33,20 +33,31 @@
desc("Show chef-solo attributes. (an alias of chef_solo:attributes)")
task(:attributes, :except => { :no_release => true }) {
find_and_execute_task("chef_solo:attributes")
}
+
+ desc("Show chef-solo attributes for role. (an alias of chef_solo:role_attributes)")
+ task(:role_attributes, :except => { :no_release => true }) {
+ find_and_execute_task("chef_solo:role_attributes")
+ }
+
+ desc("Show chef-solo attributes for host. (an alias of chef_solo:host_attributes)")
+ task(:host_attributes, :except => { :no_release => true }) {
+ find_and_execute_task("chef_solo:host_attributes")
+ }
}
namespace(:chef_solo) {
_cset(:chef_solo_use_bundler, true)
_cset(:chef_solo_version, "11.4.0")
_cset(:chef_solo_path) { capture("echo $HOME/chef").strip }
_cset(:chef_solo_cache_path) { File.join(chef_solo_path, "cache") }
_cset(:chef_solo_config_path) { File.join(chef_solo_path, "config") }
_cset(:chef_solo_cookbooks_path) { File.join(chef_solo_path, "cookbooks") }
_cset(:chef_solo_data_bags_path) { File.join(chef_solo_path, "data_bags") }
+ _cset(:chef_solo_roles_path) { File.join(chef_solo_path, "roles") }
_cset(:chef_solo_config_file) { File.join(chef_solo_config_path, "solo.rb") }
_cset(:chef_solo_attributes_file) { File.join(chef_solo_config_path, "solo.json") }
_cset(:chef_solo_bootstrap_user) {
if variables.key?(:chef_solo_user)
@@ -173,15 +184,17 @@
end
}
# Acts like `default`, but will apply specified recipes only.
def run_list(*recipes)
+ options = { :update => true }.merge(Hash === recipes.last ? recipes.pop : {})
+ update_p = options.delete(:update)
connect_with_settings do
setup
transaction do
- update
- invoke(:run_list => recipes)
+ update(options) if update_p
+ invoke(options.merge(:run_list => recipes))
end
end
end
_cset(:chef_solo_cmd, "chef-solo")
@@ -193,17 +206,40 @@
end
}
desc("Show chef-solo attributes.")
task(:attributes, :except => { :no_release => true }) {
- hosts = ENV.fetch("HOST", "").split(/\s*,\s*/)
- roles = ENV.fetch("ROLE", "").split(/\s*,\s*/).map { |role| role.to_sym }
- roles += hosts.map { |host| role_names_for_host(ServerDefinition.new(host)) }
- attributes = _generate_attributes(:hosts => hosts, :roles => roles)
- STDOUT.puts(_json_attributes(attributes))
+ find_and_execute_task("chef_solo:host_attributes")
+ find_and_execute_task("chef_solo:role_attributes")
}
+ desc("Show chef-solo attributes for host.")
+ task(:host_attributes, :except => { :no_release => true }) {
+ if ENV.key?("HOST")
+ hosts = ENV.fetch("HOST", "").split(/\s*,\s*/)
+ else
+ hosts = find_servers_for_task(current_task).map { |server| server.host }
+ end
+ hosts.each do |host|
+ logger.debug("generating chef-solo attributes for host `#{host}'.")
+ STDOUT.puts(_json_attributes(_generate_host_attributes(host, :roles => role_names_for_host(ServerDefinition.new(host)))))
+ end
+ }
+
+ desc("Show chef-solo attributes for role.")
+ task(:role_attributes, :except => { :no_release => true }) {
+ if ENV.key?("ROLE")
+ roles = ENV.fetch("ROLE", "").split(/\s*,\s*/).map { |role| role.to_sym }
+ else
+ roles = find_servers_for_task(current_task).map { |server| role_names_for_host(server) }.flatten.uniq
+ end
+ roles.each do |role|
+ logger.debug("generating chef-solo attributes for role `#{role}'.")
+ STDOUT.puts(_json_attributes(_generate_role_attributes(role)))
+ end
+ }
+
_cset(:chef_solo_gem_dependencies) {{
fetch(:chef_solo_gem, "chef") => chef_solo_version,
}}
_cset(:chef_solo_gemfile) {
gemfile = []
@@ -224,13 +260,13 @@
version = execute("--version", :via => :capture)
installed = Regexp.new(Regexp.escape(chef_solo_version)) =~ version
rescue
installed = false
end
+ dirs = [ chef_solo_path, chef_solo_cache_path, chef_solo_config_path, chef_solo_roles_path ].uniq
+ run("mkdir -p #{dirs.map { |x| x.dump }.join(" ")}")
unless installed
- dirs = [ chef_solo_path, chef_solo_cache_path, chef_solo_config_path ].uniq
- run("mkdir -p #{dirs.map { |x| x.dump }.join(" ")}")
if chef_solo_use_bundler
top.put(chef_solo_gemfile, File.join(chef_solo_path, "Gemfile"))
args = fetch(:chef_solo_bundle_options, [])
args << "--path=#{File.join(chef_solo_path, "bundle").dump}"
args << "--quiet"
@@ -421,10 +457,11 @@
_cset(:chef_solo_config) {
(<<-EOS).gsub(/^\s*/, "")
file_cache_path #{chef_solo_cache_path.dump}
cookbook_path #{chef_solo_cookbooks_path.dump}
data_bag_path #{chef_solo_data_bags_path.dump}
+ role_path #{chef_solo_roles_path.dump}
EOS
}
def update_config(options={})
top.put(chef_solo_config, chef_solo_config_file, options)
end
@@ -467,53 +504,56 @@
:application, :deploy_to, :rails_env, :latest_release,
:releases_path, :shared_path, :current_path, :release_path,
])
_cset(:chef_solo_capistrano_attributes_exclude, [:logger, /password/, :source, :strategy])
_cset(:chef_solo_attributes, {})
- _cset(:chef_solo_host_attributes, {})
- _cset(:chef_solo_role_attributes, {})
_cset(:chef_solo_run_list, [])
+ _cset(:chef_solo_host_attributes, {})
_cset(:chef_solo_host_run_list, {})
- _cset(:chef_solo_role_run_list, {})
-
- def _generate_attributes(options={})
- hosts = [ options.delete(:hosts) ].flatten.compact.uniq
+ def _generate_host_attributes(host, options={})
roles = [ options.delete(:roles) ].flatten.compact.uniq
#
# By default, the Chef attributes will be generated by following order.
#
# 1. Use _non-lazy_ variables of Capistrano.
# 2. Use attributes defined in `:chef_solo_attributes`.
- # 3. Use attributes defined in `:chef_solo_role_attributes` for target role.
- # 4. Use attributes defined in `:chef_solo_host_attributes` for target host.
+ # 3. Use attributes defined in `:chef_solo_host_attributes` for target host.
#
attributes = chef_solo_capistrano_attributes.dup
_merge_attributes!(attributes, chef_solo_attributes)
- roles.each do |role|
- _merge_attributes!(attributes, chef_solo_role_attributes.fetch(role, {}))
- end
- hosts.each do |host|
- _merge_attributes!(attributes, chef_solo_host_attributes.fetch(host, {}))
- end
+ _merge_attributes!(attributes, chef_solo_host_attributes.fetch(host, {}))
#
- # The Chef `run_list` will be generated from `:chef_solo_role_run_list` and
- # `:chef_solo_host_run_list`.
+ # The Chef `run_list` will be generated from `:chef_solo_run_list` and `:chef_solo_host_run_list`.
#
_merge_attributes!(attributes, {"run_list" => chef_solo_run_list})
- roles.each do |role|
- _merge_attributes!(attributes, {"run_list" => chef_solo_role_run_list.fetch(role, [])})
- end
- hosts.each do |host|
- _merge_attributes!(attributes, {"run_list" => chef_solo_host_run_list.fetch(host, [])})
- end
+ _merge_attributes!(attributes, {"run_list" => roles.map { |role| "role[#{role}]" } }) unless roles.empty?
+ _merge_attributes!(attributes, {"run_list" => chef_solo_host_run_list.fetch(host, [])})
attributes
end
+ _cset(:chef_solo_role_attributes, {})
+ _cset(:chef_solo_role_run_list, {})
+ def _generate_role_attributes(role, options={})
+ attributes = {
+ "name" => role,
+ "chef_type" => "role",
+ "json_class" => "Chef::Role",
+ }
+ _merge_attributes!(attributes, {"default_attributes" => chef_solo_role_attributes.fetch(role, {})})
+ _merge_attributes!(attributes, {"run_list" => chef_solo_role_run_list.fetch(role, [])})
+ attributes
+ end
+
def update_attributes(options={})
+ roles.each_key.each do |role|
+ logger.debug("updating chef-solo role attributes for #{role}.")
+ attributes = _generate_role_attributes(role)
+ top.put(_json_attributes(attributes), File.join(chef_solo_roles_path, "#{role}.json"), options)
+ end
servers = find_servers_for_task(current_task)
servers.each do |server|
- logger.debug("updating chef-solo attributes for #{server.host}.")
- attributes = _generate_attributes(:hosts => server.host, :roles => role_names_for_host(server))
+ logger.debug("updating chef-solo host attributes for #{server.host}.")
+ attributes = _generate_host_attributes(server.host, :roles => role_names_for_host(server))
top.put(_json_attributes(attributes), chef_solo_attributes_file, options.merge(:hosts => server.host))
end
end
def invoke(options={})