lib/chef/knife/winrm_knife_base.rb in knife-windows-1.8.0 vs lib/chef/knife/winrm_knife_base.rb in knife-windows-1.9.0

- old
+ new

@@ -110,46 +110,53 @@ ( !data.kind_of?(Array) && data.respond_to?(:to_hash) ) ? data.to_hash : data end def run_command(command = '') relay_winrm_command(command) - check_for_errors! - - # Knife seems to ignore the return value of this method, - # so we exit to force the process exit code for this - # subcommand if returns is set - exit @exit_code if @exit_code && @exit_code != 0 - 0 + @exit_code end def relay_winrm_command(command) Chef::Log.debug(command) - session_results = [] - @winrm_sessions.each do |s| - begin - session_results << s.relay_command(command) - rescue WinRM::WinRMHTTPTransportError, WinRM::WinRMAuthorizationError => e - if authorization_error?(e) - if ! config[:suppress_auth_failure] - # Display errors if the caller hasn't opted to retry - ui.error "Failed to authenticate to #{s.host} as #{locate_config_value(:winrm_user)}" - ui.info "Response: #{e.message}" - ui.info get_failed_authentication_hint - raise e - end - @exit_code = 401 - else - raise e + @session_results = [] + + queue = Queue.new + @winrm_sessions.each { |s| queue << s } + # These nils will kill the Threads once no more sessions are left + locate_config_value(:concurrency).times { queue << nil } + + threads = [] + locate_config_value(:concurrency).times do + threads << Thread.new do + while session = queue.pop + run_command_in_thread(session, command) end end end - session_results + threads.map(&:join) + @session_results end private + def run_command_in_thread(s, command) + @session_results << s.relay_command(command) + rescue WinRM::WinRMHTTPTransportError, WinRM::WinRMAuthorizationError => e + if authorization_error?(e) + if ! config[:suppress_auth_failure] + # Display errors if the caller hasn't opted to retry + ui.error "Failed to authenticate to #{s.host} as #{locate_config_value(:winrm_user)}" + ui.info "Response: #{e.message}" + ui.info get_failed_authentication_hint + raise e + end + else + raise e + end + end + def get_failed_authentication_hint if @session_opts[:basic_auth_only] FAILED_BASIC_HINT else FAILED_NOT_BASIC_HINT @@ -160,13 +167,14 @@ exception.is_a?(WinRM::WinRMAuthorizationError) || exception.message =~ /401/ end def check_for_errors! + @exit_code ||= 0 @winrm_sessions.each do |session| session_exit_code = session.exit_code unless success_return_codes.include? session_exit_code.to_i - @exit_code = session_exit_code.to_i + @exit_code = [@exit_code, session_exit_code.to_i].max ui.error "Failed to execute command on #{session.host} return code #{session_exit_code}" end end end