From b9a20186350a0315ee7159f2df2b55a47e9f90a4 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 1 Apr 2013 00:04:54 -0700 Subject: remove supply_drop, add support for puppet_command. --- lib/leap_cli.rb | 1 + lib/leap_cli/commands/deploy.rb | 62 ++++---- lib/leap_cli/commands/node.rb | 1 - lib/leap_cli/constants.rb | 7 + lib/leap_cli/logger.rb | 1 + lib/leap_cli/remote/leap_plugin.rb | 67 +++++++++ lib/leap_cli/remote/plugin.rb | 93 ------------ lib/leap_cli/remote/puppet_plugin.rb | 66 ++++++++ lib/leap_cli/remote/rsync_plugin.rb | 35 +++++ lib/leap_cli/remote/tasks.rb | 22 +-- lib/leap_cli/util/remote_command.rb | 8 +- lib/leap_cli/version.rb | 2 +- vendor/supply_drop/lib/supply_drop.rb | 12 -- .../lib/supply_drop/async_enumerable.rb | 19 --- vendor/supply_drop/lib/supply_drop/plugin.rb | 111 -------------- vendor/supply_drop/lib/supply_drop/rsync.rb | 167 --------------------- .../supply_drop/lib/supply_drop/syntax_checker.rb | 21 --- vendor/supply_drop/lib/supply_drop/tasks.rb | 96 ------------ vendor/supply_drop/lib/supply_drop/thread_pool.rb | 39 ----- vendor/supply_drop/lib/supply_drop/util.rb | 23 --- .../supply_drop/lib/supply_drop/writer/batched.rb | 22 --- .../lib/supply_drop/writer/colorful_streaming.rb | 72 --------- vendor/supply_drop/lib/supply_drop/writer/file.rb | 23 --- .../lib/supply_drop/writer/streaming.rb | 16 -- vendor/supply_drop/supply_drop.gemspec | 13 -- 25 files changed, 224 insertions(+), 775 deletions(-) create mode 100644 lib/leap_cli/constants.rb create mode 100644 lib/leap_cli/remote/leap_plugin.rb delete mode 100644 lib/leap_cli/remote/plugin.rb create mode 100644 lib/leap_cli/remote/puppet_plugin.rb create mode 100644 lib/leap_cli/remote/rsync_plugin.rb delete mode 100644 vendor/supply_drop/lib/supply_drop.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/async_enumerable.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/plugin.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/rsync.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/syntax_checker.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/tasks.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/thread_pool.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/util.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/writer/batched.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/writer/colorful_streaming.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/writer/file.rb delete mode 100644 vendor/supply_drop/lib/supply_drop/writer/streaming.rb delete mode 100644 vendor/supply_drop/supply_drop.gemspec diff --git a/lib/leap_cli.rb b/lib/leap_cli.rb index 1921357..7b52ce4 100644 --- a/lib/leap_cli.rb +++ b/lib/leap_cli.rb @@ -1,6 +1,7 @@ module LeapCli; end require 'leap_cli/version.rb' +require 'leap_cli/constants.rb' require 'leap_cli/requirements.rb' require 'leap_cli/leapfile.rb' diff --git a/lib/leap_cli/commands/deploy.rb b/lib/leap_cli/commands/deploy.rb index 76df4fb..12e8294 100644 --- a/lib/leap_cli/commands/deploy.rb +++ b/lib/leap_cli/commands/deploy.rb @@ -2,8 +2,6 @@ module LeapCli module Commands - DEFAULT_TAGS = ['leap_base','leap_service'] - desc 'Apply recipes to a node or set of nodes.' long_desc 'The FILTER can be the name of a node, service, or tag.' arg_name 'FILTER' @@ -13,6 +11,9 @@ module LeapCli c.switch :fast, :desc => 'Makes the deploy command faster by skipping some slow steps. A "fast" deploy can be used safely if you recently completed a normal deploy.', :negatable => false + # --force + c.switch :force, :desc => 'Deploy even if there is a lockfile.', :negatable => false + # --tags c.flag :tags, :desc => 'Specify tags to pass through to puppet (overriding the default).', :default_value => DEFAULT_TAGS.join(','), :arg_name => 'TAG[,TAG]' @@ -34,37 +35,16 @@ module LeapCli ssh.leap.log :checking, 'node' do ssh.leap.assert_initialized end - ssh.leap.log :synching, "configuration files" do sync_hiera_config(ssh) sync_support_files(ssh) end - - # sync puppet manifests and apply them - ssh.set :puppet_source, [Path.platform, 'puppet'].join('/') - ssh.set :puppet_destination, '/srv/leap' - - # set tags - if options[:tags] - tags = options[:tags].split(',') - else - tags = DEFAULT_TAGS.dup + ssh.leap.log :synching, "puppet manifests" do + sync_puppet_files(ssh) end - tags << 'leap_slow' unless options[:fast] - - # set verbosity - verbosity = case LeapCli.log_level - when 3 then '--verbose' - when 4 then '--verbose --debug' - when 5 then '--verbose --debug --trace' - else '' + ssh.leap.log :applying, "puppet" do + ssh.puppet.apply(:verbosity => LeapCli.log_level, :tags => tags(options), :force => options[:force]) end - - ssh.set :puppet_command, "/usr/bin/puppet apply --color=false --tags=#{tags.join(',')} --detailed-exitcodes #{verbosity}" - ssh.set :puppet_lib, "puppet/modules" - ssh.set :puppet_parameters, '--libdir puppet/lib --confdir puppet puppet/manifests/site.pp' - ssh.set :puppet_stream_output, true - ssh.apply_puppet end end end @@ -73,7 +53,7 @@ module LeapCli def sync_hiera_config(ssh) dest_dir = provider.hiera_sync_destination - ssh.leap.rsync_update do |server| + ssh.rsync.update do |server| node = manager.node(server.host) hiera_file = Path.relative_path([:hiera, node.name]) ssh.leap.log hiera_file + ' -> ' + node.name + ':' + dest_dir + '/hiera.yaml' @@ -83,7 +63,7 @@ module LeapCli def sync_support_files(ssh) dest_dir = provider.hiera_sync_destination - ssh.leap.rsync_update do |server| + ssh.rsync.update do |server| node = manager.node(server.host) files_to_sync = node.file_paths.collect {|path| Path.relative_path(path, Path.provider) } if files_to_sync.any? @@ -102,6 +82,20 @@ module LeapCli end end + def sync_puppet_files(ssh) + ssh.rsync.update do |server| + ssh.leap.log(Path.platform + '/[bin,puppet] -> ' + server.host + ':' + LeapCli::PUPPET_DESTINATION) + { + :dest => LeapCli::PUPPET_DESTINATION, + :source => '.', + :chdir => Path.platform, + :excludes => '*', + :includes => ['/bin', '/bin/**', '/puppet', '/puppet/**'], + :flags => "--relative --dirs --delete --copy-links" + } + end + end + def init_submodules Dir.chdir Path.platform do assert_run! "git submodule sync" @@ -141,6 +135,16 @@ module LeapCli return includes end + def tags(options) + if options[:tags] + tags = options[:tags].split(',') + else + tags = LeapCli::DEFAULT_TAGS.dup + end + tags << 'leap_slow' unless options[:fast] + tags.join(',') + end + # # for safety, we allow production deploys to be turned off in the Leapfile. # diff --git a/lib/leap_cli/commands/node.rb b/lib/leap_cli/commands/node.rb index 8ebb5e8..379fba6 100644 --- a/lib/leap_cli/commands/node.rb +++ b/lib/leap_cli/commands/node.rb @@ -59,7 +59,6 @@ module LeapCli; module Commands save_public_host_key(node, global) update_compiled_ssh_configs ssh_connect(node, :bootstrap => true, :echo => options[:echo]) do |ssh| - ssh.set_hostname ssh.install_authorized_keys ssh.install_prerequisites end diff --git a/lib/leap_cli/constants.rb b/lib/leap_cli/constants.rb new file mode 100644 index 0000000..bf30df1 --- /dev/null +++ b/lib/leap_cli/constants.rb @@ -0,0 +1,7 @@ +module LeapCli + + PUPPET_DESTINATION = '/srv/leap' + INITIALIZED_FILE = "#{PUPPET_DESTINATION}/initialized" + DEFAULT_TAGS = ['leap_base','leap_service'] + +end \ No newline at end of file diff --git a/lib/leap_cli/logger.rb b/lib/leap_cli/logger.rb index 1aa7971..a496260 100644 --- a/lib/leap_cli/logger.rb +++ b/lib/leap_cli/logger.rb @@ -101,6 +101,7 @@ module LeapCli # IMPORTANT { :match => /^err ::/, :color => :red, :match_level => 0, :priority => -10 }, + { :match => /^ERROR:/, :color => :red, :match_level => 0, :priority => -10 }, { :match => /.*/, :color => :blue, :match_level => 0, :priority => -20 }, # CLEANUP diff --git a/lib/leap_cli/remote/leap_plugin.rb b/lib/leap_cli/remote/leap_plugin.rb new file mode 100644 index 0000000..2c427e9 --- /dev/null +++ b/lib/leap_cli/remote/leap_plugin.rb @@ -0,0 +1,67 @@ +# +# these methods are made available in capistrano tasks as 'leap.method_name' +# (see RemoteCommand::new_capistrano) +# + +module LeapCli; module Remote; module LeapPlugin + + def required_packages + "puppet ruby-hiera-puppet rsync lsb-release" + end + + def log(*args, &block) + LeapCli::Util::log(*args, &block) + end + + # + # creates directories that are owned by root and 700 permissions + # + def mkdirs(*dirs) + raise ArgumentError.new('illegal dir name') if dirs.grep(/[\' ]/).any? + run dirs.collect{|dir| "mkdir -m 700 -p #{dir}; "}.join + end + + def assert_initialized + begin + test_initialized_file = "test -f #{INITIALIZED_FILE}" + check_required_packages = "! dpkg-query -W --showformat='${Status}\n' #{required_packages} 2>&1 | grep -q -E '(deinstall|no packages)'" + run "#{test_initialized_file} && #{check_required_packages}" + rescue Capistrano::CommandError => exc + LeapCli::Util.bail! do + exc.hosts.each do |host| + LeapCli::Util.log :error, "running deploy: node not initialized. Run 'leap node init #{host}'", :host => host + end + end + end + end + + def mark_initialized + run "touch #{INITIALIZED_FILE}" + end + + #def mkdir(dir) + # run "mkdir -p #{dir}" + #end + + #def chown_root(dir) + # run "chown root -R #{dir} && chmod -R ag-rwx,u+rwX #{dir}" + #end + + #def logrun(cmd) + # @streamer ||= LeapCli::Remote::LogStreamer.new + # run cmd do |channel, stream, data| + # @streamer.collect_output(channel[:host], data) + # end + #end + +# return_code = nil +# run "something; echo return code: $?" do |channel, stream, data| +# if data =~ /return code: (\d+)/ +# return_code = $1.to_i +# else +# Capistrano::Configuration.default_io_proc.call(channel, stream, data) +# end +# end +# puts "finished with return code: #{return_code}" + +end; end; end \ No newline at end of file diff --git a/lib/leap_cli/remote/plugin.rb b/lib/leap_cli/remote/plugin.rb deleted file mode 100644 index 4824858..0000000 --- a/lib/leap_cli/remote/plugin.rb +++ /dev/null @@ -1,93 +0,0 @@ -# -# these methods are made available in capistrano tasks as 'leap.method_name' -# - -require 'rsync_command' - -module LeapCli; module Remote; module Plugin - - def required_packages - "puppet ruby-hiera-puppet rsync lsb-release" - end - - def log(*args, &block) - LeapCli::Util::log(*args, &block) - end - - # - # creates directories that are owned by root and 700 permissions - # - def mkdirs(*dirs) - raise ArgumentError.new('illegal dir name') if dirs.grep(/[\' ]/).any? - run dirs.collect{|dir| "mkdir -m 700 -p #{dir}; "}.join - end - - def assert_initialized - begin - test_initialized_file = "test -f /srv/leap/initialized" - check_required_packages = "! dpkg-query -W --showformat='${Status}\n' #{required_packages} 2>&1 | grep -q -E '(deinstall|no packages)'" - run "#{test_initialized_file} && #{check_required_packages}" - rescue Capistrano::CommandError => exc - LeapCli::Util.bail! do - exc.hosts.each do |host| - LeapCli::Util.log :error, "running deploy: node not initialized. Run 'leap node init #{host}'", :host => host - end - end - end - end - - def mark_initialized - run "touch /srv/leap/initialized" - end - - #def mkdir(dir) - # run "mkdir -p #{dir}" - #end - - #def chown_root(dir) - # run "chown root -R #{dir} && chmod -R ag-rwx,u+rwX #{dir}" - #end - - # - # takes a block, yielded a server, that should return a hash with various rsync options. - # supported options include: - # - # {:source => '', :dest => '', :flags => '', :includes => [], :excludes => []} - # - def rsync_update - rsync = RsyncCommand.new(:logger => logger, :flags => '-a') - rsync.asynchronously(find_servers) do |server| - options = yield server - next unless options - remote_user = server.user || fetch(:user, ENV['USER']) - src = options[:source] - dest = {:user => remote_user, :host => server.host, :path => options[:dest]} - options[:ssh] = ssh_options.merge(server.options[:ssh_options]||{}) - options[:chdir] ||= Path.provider - rsync.exec(src, dest, options) - end - if rsync.failed? - LeapCli::Util.bail! do - LeapCli::Util.log :failed, "to rsync to #{rsync.failures.map{|f|f[:dest][:host]}.join(' ')}" - end - end - end - - #def logrun(cmd) - # @streamer ||= LeapCli::Remote::LogStreamer.new - # run cmd do |channel, stream, data| - # @streamer.collect_output(channel[:host], data) - # end - #end - -# return_code = nil -# run "something; echo return code: $?" do |channel, stream, data| -# if data =~ /return code: (\d+)/ -# return_code = $1.to_i -# else -# Capistrano::Configuration.default_io_proc.call(channel, stream, data) -# end -# end -# puts "finished with return code: #{return_code}" - -end; end; end \ No newline at end of file diff --git a/lib/leap_cli/remote/puppet_plugin.rb b/lib/leap_cli/remote/puppet_plugin.rb new file mode 100644 index 0000000..9c41380 --- /dev/null +++ b/lib/leap_cli/remote/puppet_plugin.rb @@ -0,0 +1,66 @@ +# +# these methods are made available in capistrano tasks as 'puppet.method_name' +# (see RemoteCommand::new_capistrano) +# + +module LeapCli; module Remote; module PuppetPlugin + + def apply(options) + run "#{PUPPET_DESTINATION}/bin/puppet_command set_hostname apply #{flagize(options)}" + end + + private + + def flagize(hsh) + hsh.inject([]) {|str, item| + if item[1] === false + str + elsif item[1] === true + str << "--" + item[0].to_s + else + str << "--" + item[0].to_s + " " + item[1].to_s + end + }.join(' ') + end + +end; end; end + + + # def puppet(command = :noop) + # #puppet_cmd = "cd #{puppet_destination} && #{sudo_cmd} #{puppet_command} --modulepath=#{puppet_lib} #{puppet_parameters}" + # puppet_cmd = "cd #{puppet_destination} && #{sudo_cmd} #{puppet_command} #{puppet_parameters}" + # flag = command == :noop ? '--noop' : '' + + # writer = if puppet_stream_output + # SupplyDrop::Writer::Streaming.new(logger) + # else + # SupplyDrop::Writer::Batched.new(logger) + # end + + # writer = SupplyDrop::Writer::File.new(writer, puppet_write_to_file) unless puppet_write_to_file.nil? + + # begin + # exitcode = nil + # run "#{puppet_cmd} #{flag}; echo exitcode:$?" do |channel, stream, data| + # if data =~ /exitcode:(\d+)/ + # exitcode = $1 + # writer.collect_output(channel[:host], "Puppet #{command} complete (#{exitcode_description(exitcode)}).\n") + # else + # writer.collect_output(channel[:host], data) + # end + # end + # ensure + # writer.all_output_collected + # end + # end + + # def exitcode_description(code) + # case code + # when "0" then "no changes" + # when "2" then "changes made" + # when "4" then "failed" + # when "6" then "changes and failures" + # else code + # end + # end + diff --git a/lib/leap_cli/remote/rsync_plugin.rb b/lib/leap_cli/remote/rsync_plugin.rb new file mode 100644 index 0000000..2c89f26 --- /dev/null +++ b/lib/leap_cli/remote/rsync_plugin.rb @@ -0,0 +1,35 @@ +# +# these methods are made available in capistrano tasks as 'rsync.method_name' +# (see RemoteCommand::new_capistrano) +# + +require 'rsync_command' + +module LeapCli; module Remote; module RsyncPlugin + + # + # takes a block, yielded a server, that should return a hash with various rsync options. + # supported options include: + # + # {:source => '', :dest => '', :flags => '', :includes => [], :excludes => []} + # + def update + rsync = RsyncCommand.new(:logger => logger, :flags => '-a') + rsync.asynchronously(find_servers) do |server| + options = yield server + next unless options + remote_user = server.user || fetch(:user, ENV['USER']) + src = options[:source] + dest = {:user => remote_user, :host => server.host, :path => options[:dest]} + options[:ssh] = ssh_options.merge(server.options[:ssh_options]||{}) + options[:chdir] ||= Path.provider + rsync.exec(src, dest, options) + end + if rsync.failed? + LeapCli::Util.bail! do + LeapCli::Util.log :failed, "to rsync to #{rsync.failures.map{|f|f[:dest][:host]}.join(' ')}" + end + end + end + +end; end; end diff --git a/lib/leap_cli/remote/tasks.rb b/lib/leap_cli/remote/tasks.rb index 35349ad..b515650 100644 --- a/lib/leap_cli/remote/tasks.rb +++ b/lib/leap_cli/remote/tasks.rb @@ -3,8 +3,6 @@ # For DSL manual, see https://github.com/capistrano/capistrano/wiki # -require 'supply_drop' - MAX_HOSTS = 10 task :install_authorized_keys, :max_hosts => MAX_HOSTS do @@ -14,14 +12,8 @@ task :install_authorized_keys, :max_hosts => MAX_HOSTS do end end -task :set_hostname, :max_hosts => MAX_HOSTS do - leap.log :setting, "hostname" do - run "hostname $CAPISTRANO:HOST$" - end -end - task :install_prerequisites, :max_hosts => MAX_HOSTS do - leap.mkdirs puppet_destination + leap.mkdirs LeapCli::PUPPET_DESTINATION run "locale-gen" leap.log :updating, "package list" do run "apt-get update" @@ -33,9 +25,9 @@ task :install_prerequisites, :max_hosts => MAX_HOSTS do leap.mark_initialized end -task :apply_puppet, :max_hosts => MAX_HOSTS do - raise "now such directory #{puppet_source}" unless File.directory?(puppet_source) - leap.log :applying, "puppet" do - puppet.apply - end -end +#task :apply_puppet, :max_hosts => MAX_HOSTS do +# raise "now such directory #{puppet_source}" unless File.directory?(puppet_source) +# leap.log :applying, "puppet" do +# puppet.apply +# end +#end diff --git a/lib/leap_cli/util/remote_command.rb b/lib/leap_cli/util/remote_command.rb index aee4eff..57234eb 100644 --- a/lib/leap_cli/util/remote_command.rb +++ b/lib/leap_cli/util/remote_command.rb @@ -73,8 +73,12 @@ module LeapCli; module Util; module RemoteCommand @capistrano_enabled ||= begin require 'capistrano' require 'capistrano/cli' - require 'leap_cli/remote/plugin' - Capistrano.plugin :leap, LeapCli::Remote::Plugin + require 'leap_cli/remote/leap_plugin' + require 'leap_cli/remote/puppet_plugin' + require 'leap_cli/remote/rsync_plugin' + Capistrano.plugin :leap, LeapCli::Remote::LeapPlugin + Capistrano.plugin :puppet, LeapCli::Remote::PuppetPlugin + Capistrano.plugin :rsync, LeapCli::Remote::RsyncPlugin true end diff --git a/lib/leap_cli/version.rb b/lib/leap_cli/version.rb index 232eb45..7f0b4d5 100644 --- a/lib/leap_cli/version.rb +++ b/lib/leap_cli/version.rb @@ -3,6 +3,6 @@ module LeapCli VERSION = '0.2.0' SUMMARY = 'Command line interface to the LEAP platform' DESCRIPTION = 'The command "leap" can be used to manage a bevy of servers running the LEAP platform from the comfort of your own home.' - LOAD_PATHS = ['lib', 'vendor/supply_drop/lib', 'vendor/certificate_authority/lib', 'vendor/rsync_command/lib'] + LOAD_PATHS = ['lib', 'vendor/certificate_authority/lib', 'vendor/rsync_command/lib'] end end diff --git a/vendor/supply_drop/lib/supply_drop.rb b/vendor/supply_drop/lib/supply_drop.rb deleted file mode 100644 index 9c2c050..0000000 --- a/vendor/supply_drop/lib/supply_drop.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'supply_drop/rsync' -require 'supply_drop/async_enumerable' -require 'supply_drop/plugin' -require 'supply_drop/syntax_checker' -require 'supply_drop/thread_pool' -require 'supply_drop/util' -require 'supply_drop/writer/batched' -require 'supply_drop/writer/file' -require 'supply_drop/writer/streaming' -require 'supply_drop/tasks' - -Capistrano.plugin :supply_drop, SupplyDrop::Plugin diff --git a/vendor/supply_drop/lib/supply_drop/async_enumerable.rb b/vendor/supply_drop/lib/supply_drop/async_enumerable.rb deleted file mode 100644 index 1d5a116..0000000 --- a/vendor/supply_drop/lib/supply_drop/async_enumerable.rb +++ /dev/null @@ -1,19 +0,0 @@ -module SupplyDrop - module AsyncEnumerable - def each(&block) - pool = SupplyDrop::ThreadPool.new(SupplyDrop::Util.thread_pool_size) - super do |item| - pool.schedule(item, &block) - end - pool.shutdown - end - - def map(&block) - pool = SupplyDrop::ThreadPool.new(SupplyDrop::Util.thread_pool_size) - super do |item| - pool.schedule(item, &block) - end - pool.shutdown - end - end -end diff --git a/vendor/supply_drop/lib/supply_drop/plugin.rb b/vendor/supply_drop/lib/supply_drop/plugin.rb deleted file mode 100644 index 48198b4..0000000 --- a/vendor/supply_drop/lib/supply_drop/plugin.rb +++ /dev/null @@ -1,111 +0,0 @@ -module SupplyDrop - module Plugin - - def rsync - SupplyDrop::Util.thread_pool_size = puppet_parallel_rsync_pool_size - servers = SupplyDrop::Util.optionally_async(find_servers_for_task(current_task), puppet_parallel_rsync) - failed_servers = servers.map do |server| - rsync_cmd = SupplyDrop::Rsync.command( - puppet_source, - SupplyDrop::Rsync.remote_address(server.user || fetch(:user, ENV['USER']), server.host, puppet_destination), - :delete => true, - :excludes => puppet_excludes, - :ssh => ssh_options.merge(server.options[:ssh_options]||{}), - :flags => '--copy-links' - ) - logger.debug rsync_cmd - server.host unless system rsync_cmd - end.compact - - raise "rsync failed on #{failed_servers.join(',')}" if failed_servers.any? - end - - def prepare - #run "mkdir -p #{puppet_destination}" - #run "#{sudo} chown -R $USER: #{puppet_destination}" - end - - def noop - puppet(:noop) - end - - def apply - puppet(:apply) - end - - def lock - if should_lock? - cmd = <<-GETLOCK -if [ ! -f #{puppet_lock_file} ]; then - touch #{puppet_lock_file}; -else - stat -c "#{red_text("Puppet in progress, #{puppet_lock_file} owned by %U since %x")}" #{puppet_lock_file} >&2; - exit 1; -fi - GETLOCK - run cmd.gsub(/\s+/, ' ') - end - end - - def unlock - run "rm -f #{puppet_lock_file}; true" if should_lock? - end - - private - - def should_lock? - puppet_lock_file && !ENV['NO_PUPPET_LOCK'] - end - - def puppet(command = :noop) - #puppet_cmd = "cd #{puppet_destination} && #{sudo_cmd} #{puppet_command} --modulepath=#{puppet_lib} #{puppet_parameters}" - puppet_cmd = "cd #{puppet_destination} && #{sudo_cmd} #{puppet_command} #{puppet_parameters}" - flag = command == :noop ? '--noop' : '' - - writer = if puppet_stream_output - SupplyDrop::Writer::Streaming.new(logger) - else - SupplyDrop::Writer::Batched.new(logger) - end - - writer = SupplyDrop::Writer::File.new(writer, puppet_write_to_file) unless puppet_write_to_file.nil? - - begin - exitcode = nil - run "#{puppet_cmd} #{flag}; echo exitcode:$?" do |channel, stream, data| - if data =~ /exitcode:(\d+)/ - exitcode = $1 - writer.collect_output(channel[:host], "Puppet #{command} complete (#{exitcode_description(exitcode)}).\n") - else - writer.collect_output(channel[:host], data) - end - end - ensure - writer.all_output_collected - end - end - - def exitcode_description(code) - case code - when "0" then "no changes" - when "2" then "changes made" - when "4" then "failed" - when "6" then "changes and failures" - else code - end - end - - def red_text(text) - "\033[0;31m#{text}\033[0m" - end - - def sudo_cmd - if fetch(:use_sudo, true) - sudo(:as => puppet_runner) - else - logger.info "NOTICE: puppet_runner configuration invalid when use_sudo is false, ignoring..." unless puppet_runner.nil? - '' - end - end - end -end diff --git a/vendor/supply_drop/lib/supply_drop/rsync.rb b/vendor/supply_drop/lib/supply_drop/rsync.rb deleted file mode 100644 index a3d4898..0000000 --- a/vendor/supply_drop/lib/supply_drop/rsync.rb +++ /dev/null @@ -1,167 +0,0 @@ -module SupplyDrop - class Rsync - class << self - def command(from, to, options={}) - flags = ['-az'] - flags << '--delete' if options[:delete] - flags << includes(options[:includes]) if options.has_key?(:includes) - flags << excludes(options[:excludes]) if options.has_key?(:excludes) - flags << ssh_options(options[:ssh]) if options.has_key?(:ssh) - flags << options[:flags] if options.has_key?(:flags) - - "rsync #{flags.compact.join(' ')} #{from} #{to}" - end - - def remote_address(user, host, path) - user_with_host = [user, host].compact.join('@') - [user_with_host, path].join(':') - end - - def excludes(patterns) - [patterns].flatten.compact.map { |p| "--exclude='#{p}'" } - end - - def includes(patterns) - [patterns].flatten.compact.map { |p| "--include='#{p}'" } - end - - def ssh_options(options) - mapped_options = options.map do |key, value| - next unless value - - # - # Convert Net::SSH options into OpenSSH options. - # - # For a list of the options normally support by Net::SSH (and thus Capistrano), see - # http://net-ssh.github.com/net-ssh/classes/Net/SSH.html#method-c-start - # - # Also, to see how Net::SSH does the opposite of the conversion we are doing here, check out: - # https://github.com/net-ssh/net-ssh/blob/master/lib/net/ssh/config.rb - # - # API mismatch: - # - # * many OpenSSH options not supported - # * some options only make sense for Net::SSH - # * compression: for Net::SSH, this option is supposed to accept true, false, or algorithm. OpenSSH accepts 'yes' or 'no' - # - # - case key - when :auth_methods then opt_auth_methods(value) - when :bind_address then opt('BindAddress', value) - when :compression then opt('Compression', value ? 'yes' : 'no') - when :compression_level then opt('CompressionLevel', value.to_i) - when :config then "-F '#{value}'" - when :encryption then opt('Ciphers', [value].flatten.join(',')) - when :forward_agent then opt('ForwardAgent', value) - when :global_known_hosts_file then opt('GlobalKnownHostsFile', value) - when :hmac then opt('MACs', [value].flatten.join(',')) - when :host_key then opt('HostKeyAlgorithms', [value].flatten.join(',')) - when :host_key_alias then opt('HostKeyAlias', value) - when :host_name then opt('HostName', value) - when :kex then opt('KexAlgorithms', [value].flatten.join(',')) - when :key_data then nil # not supported - when :keys then [value].flatten.select { |k| File.exist?(k) }.map { |k| "-i #{k}" } - when :keys_only then opt('IdentitiesOnly', value ? 'yes' : 'no') - when :languages then nil # not applicable - when :logger then nil # not applicable - when :paranoid then opt('StrictHostKeyChecking', value ? 'yes' : 'no') - when :passphrase then nil # not supported - when :password then nil # not supported - when :port then "-p #{value.to_i}" - when :properties then nil # not applicable - when :proxy then nil # not applicable - when :rekey_blocks_limit then nil # not supported - when :rekey_limit then opt('RekeyLimit', reverse_interpret_size(value)) - when :rekey_packet_limit then nil # not supported - when :timeout then opt('ConnectTimeout', value.to_i) - when :user then "-l #{value}" - when :user_known_hosts_file then opt('UserKnownHostsFile', value) - when :verbose then opt('LogLevel', interpret_log_level(value)) - end - end.compact - - %[-e "ssh #{mapped_options.join(' ')}"] unless mapped_options.empty? - end - - private - - def opt(option_name, option_value) - "-o #{option_name}='#{option_value}'" - end - - # - # In OpenSSH, password and pubkey default to 'yes', hostbased defaults to 'no'. - # Regardless, if :auth_method is configured, then we explicitly set the auth method. - # - def opt_auth_methods(value) - value = [value].flatten - opts = [] - if value.any? - if value.include? 'password' - opts << opt('PasswordAuthentication', 'yes') - else - opts << opt('PasswordAuthentication', 'no') - end - if value.include? 'publickey' - opts << opt('PubkeyAuthentication', 'yes') - else - opts << opt('PubkeyAuthentication', 'no') - end - if value.include? 'hostbased' - opts << opt('HostbasedAuthentication', 'yes') - else - opts << opt('HostbasedAuthentication', 'no') - end - end - if opts.any? - return opts.join(' ') - else - nil - end - end - - # - # Converts the given integer size in bytes into a string with 'K', 'M', 'G' suffix, as appropriate. - # - # reverse of interpret_size in https://github.com/net-ssh/net-ssh/blob/master/lib/net/ssh/config.rb - # - def reverse_interpret_size(size) - size = size.to_i - if size < 1024 - "#{size}" - elsif size < 1024 * 1024 - "#{size/1024}K" - elsif size < 1024 * 1024 * 1024 - "#{size/(1024*1024)}M" - else - "#{size/(1024*1024*1024)}G" - end - end - - def interpret_log_level(level) - if level.is_a? Symbol - case level - when :debug then "DEBUG" - when :info then "INFO" - when :warn then "ERROR" - when :error then "ERROR" - when :fatal then "FATAL" - else "INFO" - end - elsif level.is_a? Integer - case level - when Logger::DEBUG then "DEBUG" - when Logger::INFO then "INFO" - when Logger::WARN then "ERROR" - when Logger::ERROR then "ERROR" - when Logger::FATAL then "FATAL" - else "INFO" - end - else - "INFO" - end - end - - end - end -end diff --git a/vendor/supply_drop/lib/supply_drop/syntax_checker.rb b/vendor/supply_drop/lib/supply_drop/syntax_checker.rb deleted file mode 100644 index fe9cda4..0000000 --- a/vendor/supply_drop/lib/supply_drop/syntax_checker.rb +++ /dev/null @@ -1,21 +0,0 @@ -module SupplyDrop - class SyntaxChecker - def initialize(path) - @path = path - end - - def validate_puppet_files - Dir.glob("#{@path}/**/*.pp").map do |puppet_file| - output = `puppet parser validate #{puppet_file}` - $?.to_i == 0 ? nil : [puppet_file, output] - end.compact - end - - def validate_templates - Dir.glob("#{@path}/**/*.erb").map do |template_file| - output = `erb -x -T '-' #{template_file} | ruby -c 2>&1` - $?.to_i == 0 ? nil : [template_file, output] - end.compact - end - end -end diff --git a/vendor/supply_drop/lib/supply_drop/tasks.rb b/vendor/supply_drop/lib/supply_drop/tasks.rb deleted file mode 100644 index e73b280..0000000 --- a/vendor/supply_drop/lib/supply_drop/tasks.rb +++ /dev/null @@ -1,96 +0,0 @@ -Capistrano::Configuration.instance.load do - namespace :puppet do - set :puppet_source, '.' - set :puppet_destination, '/tmp/supply_drop' - set :puppet_command, 'puppet apply' - set :puppet_lib, lambda { "#{puppet_destination}/modules" } - set :puppet_parameters, lambda { puppet_verbose ? '--debug --trace puppet.pp' : 'puppet.pp' } - set :puppet_verbose, false - set :puppet_excludes, %w(.git .svn) - set :puppet_stream_output, false - set :puppet_parallel_rsync, true - set :puppet_parallel_rsync_pool_size, 10 - set :puppet_syntax_check, false - set :puppet_write_to_file, nil - set :puppet_runner, nil - set :puppet_lock_file, '/tmp/puppet.lock' - - namespace :bootstrap do - desc "installs puppet via rubygems on an osx host" - task :osx do - if fetch(:use_sudo, true) - run "#{sudo} gem install puppet --no-ri --no-rdoc" - else - run "gem install puppet --no-ri --no-rdoc" - end - end - - desc "installs puppet via apt on an ubuntu host" - task :ubuntu do - run "mkdir -p #{puppet_destination}" - run "#{sudo} apt-get update" - run "#{sudo} apt-get install -y puppet rsync" - end - - desc "installs puppet via yum on a centos/red hat host" - task :redhat do - run "mkdir -p #{puppet_destination}" - run "#{sudo} yum -y install puppet rsync" - end - end - - desc "checks the syntax of all *.pp and *.erb files" - task :syntax_check do - checker = SupplyDrop::SyntaxChecker.new(puppet_source) - logger.info "Sytax Checking..." - errors = false - checker.validate_puppet_files.each do |file, error| - logger.important "Puppet error: #{file}" - logger.important error - errors = true - end - checker.validate_templates.each do |file, error| - logger.important "Template error: #{file}" - logger.important error - errors = true - end - raise "syntax errors" if errors - end - - desc "pushes the current puppet configuration to the server" - task :update_code, :except => { :nopuppet => true } do - syntax_check if puppet_syntax_check - supply_drop.rsync - end - - desc "runs puppet with --noop flag to show changes" - task :noop, :except => { :nopuppet => true } do - transaction do - on_rollback { supply_drop.unlock } - supply_drop.prepare - supply_drop.lock - update_code - supply_drop.noop - supply_drop.unlock - end - end - - desc "applies the current puppet config to the server" - task :apply, :except => { :nopuppet => true } do - transaction do - on_rollback { supply_drop.unlock } - supply_drop.prepare - supply_drop.lock - update_code - supply_drop.apply - supply_drop.unlock - end - end - - desc "clears the puppet lockfile on the server." - task :remove_lock, :except => { :nopuppet => true} do - supply_drop.lock - end - end -end - diff --git a/vendor/supply_drop/lib/supply_drop/thread_pool.rb b/vendor/supply_drop/lib/supply_drop/thread_pool.rb deleted file mode 100644 index 082cf4a..0000000 --- a/vendor/supply_drop/lib/supply_drop/thread_pool.rb +++ /dev/null @@ -1,39 +0,0 @@ -require 'thread' - -module SupplyDrop - class ThreadPool - def initialize(size) - @size = size - @jobs = Queue.new - @retvals = [] - - @pool = Array.new(@size) do |i| - Thread.new do - Thread.current[:id] = i - - catch(:exit) do - loop do - job, args = @jobs.pop - @retvals << job.call(*args) - end - end - end - end - end - - - def schedule(*args, &block) - @jobs << [block, args] - end - - - def shutdown - @size.times do - schedule { throw :exit } - end - - @pool.map(&:join) - @retvals - end - end -end diff --git a/vendor/supply_drop/lib/supply_drop/util.rb b/vendor/supply_drop/lib/supply_drop/util.rb deleted file mode 100644 index 5f4f9f4..0000000 --- a/vendor/supply_drop/lib/supply_drop/util.rb +++ /dev/null @@ -1,23 +0,0 @@ -module SupplyDrop - module Util - DEFAULT_THREAD_POOL_SIZE = 10 - - def self.thread_pool_size - @thread_pool_size ||= DEFAULT_THREAD_POOL_SIZE - end - - def self.thread_pool_size=(size) - @thread_pool_size = size - end - - def self.optionally_async(collection, async) - if async - async_collection = collection.clone - async_collection.extend SupplyDrop::AsyncEnumerable - async_collection - else - collection - end - end - end -end diff --git a/vendor/supply_drop/lib/supply_drop/writer/batched.rb b/vendor/supply_drop/lib/supply_drop/writer/batched.rb deleted file mode 100644 index e5fc826..0000000 --- a/vendor/supply_drop/lib/supply_drop/writer/batched.rb +++ /dev/null @@ -1,22 +0,0 @@ -module SupplyDrop - module Writer - class Batched - def initialize(logger) - @outputs = {} - @logger = logger - end - - def collect_output(host, data) - @outputs[host] ||= "" - @outputs[host] << data - end - - def all_output_collected - @outputs.keys.sort.each do |host| - @logger.info "Puppet output for #{host}" - @logger.debug @outputs[host], host - end - end - end - end -end diff --git a/vendor/supply_drop/lib/supply_drop/writer/colorful_streaming.rb b/vendor/supply_drop/lib/supply_drop/writer/colorful_streaming.rb deleted file mode 100644 index e88e552..0000000 --- a/vendor/supply_drop/lib/supply_drop/writer/colorful_streaming.rb +++ /dev/null @@ -1,72 +0,0 @@ -begin - require 'paint' -rescue -end - -module SupplyDrop - module Writer - class Streaming - def initialize(logger) - @mode = Capistrano::Logger::DEBUG - @logger = logger - end - - def collect_output(host, data) - if data =~ /^(notice|err|warning):/ - @mode = $1 - - # make deprecation warnings like notices - if data =~ /^warning: .*is deprecated.*$/ - @mode = 'notice' - end - - # make variable scope warnings like notices - if data =~ /^warning: Scope*$/ - @mode = 'notice' - end - - # force the printing of 'finished catalog run' if there have not been any errors - if @mode == 'notice' && !@error_encountered && data =~ /Finished catalog run/ - @mode = 'forced_notice' - elsif @mode == 'err' - @error_encountered = true - end - end - - # log each line, colorizing the hostname - data.lines.each do |line| - if line =~ /\w/ - @logger.log log_level, line.sub(/\n$/,''), colorize(host) - end - end - end - - def log_level - case @mode - when 'err' then Capistrano::Logger::IMPORTANT - when 'warning' then Capistrano::Logger::INFO - when 'notice' then Capistrano::Logger::DEBUG - else Capistrano::Logger::IMPORTANT - end - end - - def colorize(str) - if defined? Paint - color = case @mode - when 'err' then :red - when 'warning' then :yellow - when 'notice' then :cyan - when 'forced_notice' then :cyan - else :clear - end - Paint[str, color, :bold] - else - str - end - end - - def all_output_collected - end - end - end -end diff --git a/vendor/supply_drop/lib/supply_drop/writer/file.rb b/vendor/supply_drop/lib/supply_drop/writer/file.rb deleted file mode 100644 index 61454d8..0000000 --- a/vendor/supply_drop/lib/supply_drop/writer/file.rb +++ /dev/null @@ -1,23 +0,0 @@ -module SupplyDrop - module Writer - class File - def initialize(writer, file) - @wrapped_writer = writer - @logger = Capistrano::Logger.new(:output => file) - @logger.level = Capistrano::Logger::TRACE - @file_writer = Batched.new(@logger) - end - - def collect_output(host, data) - @wrapped_writer.collect_output(host, data) - @file_writer.collect_output(host, data) - end - - def all_output_collected - @wrapped_writer.all_output_collected - @file_writer.all_output_collected - @logger.close - end - end - end -end diff --git a/vendor/supply_drop/lib/supply_drop/writer/streaming.rb b/vendor/supply_drop/lib/supply_drop/writer/streaming.rb deleted file mode 100644 index e180ec8..0000000 --- a/vendor/supply_drop/lib/supply_drop/writer/streaming.rb +++ /dev/null @@ -1,16 +0,0 @@ -module SupplyDrop - module Writer - class Streaming - def initialize(logger) - @logger = logger - end - - def collect_output(host, data) - @logger.debug data, host - end - - def all_output_collected - end - end - end -end diff --git a/vendor/supply_drop/supply_drop.gemspec b/vendor/supply_drop/supply_drop.gemspec deleted file mode 100644 index 34c7e34..0000000 --- a/vendor/supply_drop/supply_drop.gemspec +++ /dev/null @@ -1,13 +0,0 @@ -require 'rake' - -Gem::Specification.new do |s| - s.name = "supply_drop" - s.summary = "Masterless puppet with capistrano" - s.description = "See http://github.com/pitluga/supply_drop" - s.version = "0.12.0" - s.authors = ["Tony Pitluga", "Paul Hinze"] - s.email = ["tony.pitluga@gmail.com", "paul.t.hinze@gmail.com"] - s.homepage = "http://github.com/pitluga/supply_drop" - s.files = FileList["README.md", "Rakefile", "lib/**/*.rb"] - s.add_dependency('capistrano', '>= 2.5.21') -end -- cgit v1.2.3