lib/capistrano-chef-solo.rb in yyuu-capistrano-chef-solo-0.0.8 vs lib/capistrano-chef-solo.rb in yyuu-capistrano-chef-solo-0.0.9

- old
+ new

@@ -1,23 +1,21 @@ -require 'capistrano-chef-solo/version' -require 'capistrano-rbenv' -require 'capistrano/configuration' -require 'capistrano/recipes/deploy/scm' -require 'capistrano/transfer' -require 'json' -require 'tmpdir' -require 'uri' +require "capistrano-chef-solo/version" +require "capistrano-rbenv" +require "capistrano/configuration" +require "capistrano/recipes/deploy/scm" +require "json" +require "uri" module Capistrano module ChefSolo def self.extended(configuration) configuration.load { namespace(:"chef-solo") { _cset(:chef_solo_home) { capture('echo $HOME').strip } - _cset(:chef_solo_version, '10.16.4') + _cset(:chef_solo_version, "10.16.4") _cset(:chef_solo_path) { File.join(chef_solo_home, 'chef') } _cset(:chef_solo_path_children, %w(bundle cache config cookbooks)) def connect_with_settings() # preserve original :user and :ssh_options @@ -36,10 +34,19 @@ set(:ssh_options, _chef_solo_ssh_options) set(:rbenv_ruby_version, _chef_solo_rbenv_ruby_version) end end + desc("Setup chef-solo.") + task(:setup) { + connect_with_settings { + transaction { + bootstrap + } + } + } + desc("Run chef-solo.") task(:default) { connect_with_settings { transaction { bootstrap @@ -84,12 +91,12 @@ update_attributes invoke } task(:update_cookbooks) { - tmpdir = Dir.mktmpdir() - remote_tmpdir = capture("mktemp -d").chomp + tmpdir = `mktemp -d /tmp/capistrano-chef-solo.XXXXXXXXXX`.chomp + remote_tmpdir = capture("mktemp -d /tmp/capistrano-chef-solo.XXXXXXXXXX").chomp destination = File.join(tmpdir, 'cookbooks') remote_destination = File.join(chef_solo_path, 'cookbooks') filename = File.join(tmpdir, 'cookbooks.tar.gz') remote_filename = File.join(remote_tmpdir, 'cookbooks.tar.gz') begin @@ -182,34 +189,54 @@ task(:update_config) { put(chef_solo_config, File.join(chef_solo_path, 'config', 'solo.rb')) } # merge nested hashes - def _deep_merge(a, b) + def deep_merge(a, b) f = lambda { |key, val1, val2| Hash === val1 && Hash === val2 ? val1.merge(val2, &f) : val2 } a.merge(b, &f) end - def _json(x) + def json(x) if fetch(:chef_solo_pretty_json, true) JSON.pretty_generate(x) else JSON.generate(x) end end + _cset(:chef_solo_capistrano_attributes) { + # reject lazy variables since they might have side-effects. + Hash[variables.reject { |key, value| value.respond_to?(:call) }] + } _cset(:chef_solo_attributes, {}) _cset(:chef_solo_host_attributes, {}) + _cset(:chef_solo_run_list, []) + _cset(:chef_solo_host_run_list, {}) + + def generate_attributes(options={}) + attributes = deep_merge(chef_solo_capistrano_attributes, chef_solo_attributes) + attributes = deep_merge(attributes, {"run_list" => chef_solo_run_list}) + if options.has_key?(:host) + attributes = deep_merge(attributes, chef_solo_host_attributes.fetch(options[:host], {})) + attributes = deep_merge(attributes, {"run_list" => chef_solo_host_run_list.fetch(options[:host], [])}) + end + attributes + end + + desc("Show chef-solo attributes.") + task(:show_attributes) { + STDOUT.puts(json(generate_attributes)) + } + task(:update_attributes) { - attributes = _deep_merge(chef_solo_attributes, {'run_list' => fetch(:chef_solo_run_list, [])}) - to = File.join(chef_solo_path, 'config', 'solo.json') - if chef_solo_host_attributes.empty? - put(_json(attributes), to) + to = File.join(chef_solo_path, "config", "solo.json") + if chef_solo_host_attributes.empty? and chef_solo_host_run_list.empty? + put(json(generate_attributes), to) else execute_on_servers { |servers| servers.each { |server| - host_attributes = _deep_merge(attributes, chef_solo_host_attributes.fetch(server.host, {})) - Capistrano::Transfer.process(:up, StringIO.new(_json(host_attributes)), to, [sessions[server]], :logger => logger) + put(json(generate_attributes(:host => server.host), to, :hosts => server.host)) } } end }