lib/ztk/ssh.rb in ztk-0.2.5 vs lib/ztk/ssh.rb in ztk-0.2.6

- old
+ new

@@ -83,10 +83,40 @@ # end # # @author Zachary Patten <zachary@jovelabs.net> class SSH < ZTK::Base + EXIT_SIGNALS = { + 1 => "SIGHUP", + 2 => "SIGINT", + 3 => "SIGQUIT", + 4 => "SIGILL", + 5 => "SIGTRAP", + 6 => "SIGABRT", + 7 => "SIGBUS", + 8 => "SIGFPE", + 9 => "SIGKILL", + 10 => "SIGUSR1", + 11 => "SIGSEGV", + 12 => "SIGUSR2", + 13 => "SIGPIPE", + 14 => "SIGALRM", + 15 => "SIGTERM", + # 16 unused? + 17 => "SIGCHLD", + 18 => "SIGCONT", + 19 => "SIGSTOP", + 20 => "SIGTSTP", + 21 => "SIGTTIN", + 22 => "SIGTTOU", + 23 => "SIGURG", + 24 => "SIGXCPU", + 25 => "SIGXFSZ", + 26 => "SIGVTALRM", + 27 => "SIGPROF" + } + # @param [Hash] config Configuration options hash. # @option config [String] :host_name Server hostname to connect to. # @option config [String] :user Username to use for authentication. # @option config [String, Array<String>] :keys A single or series of # identity files to use for authentication. @@ -104,13 +134,14 @@ def initialize(configuration={}) super({ :forward_agent => true, :compression => false, :user_known_hosts_file => '/dev/null', - :timeout => 60 + :timeout => 60, + :ignore_exit_status => false }.merge(configuration)) - config.logger.debug { "config(#{config.inspect})" } + config.logger.debug { "config=#{config.send(:table).inspect}" } end def inspect tags = Array.new @@ -158,11 +189,11 @@ # config.user = ENV["USER"] # config.host_name = "127.0.0.1" # end # ssh.console def console - config.logger.debug { "config(#{config.inspect})" } + config.logger.debug { "config=#{config.send(:table).inspect}" } config.logger.info { "console(#{console_command.inspect})" } Kernel.exec(console_command) end @@ -196,16 +227,16 @@ "#{header}\n" end options = OpenStruct.new({ :exit_code => 0, :silence => false }.merge(options)) - config.logger.debug { "config(#{config.inspect})" } - config.logger.debug { "options(#{options.inspect})" } - config.logger.info { "exec(#{command.inspect}, #{options.inspect})" } + config.logger.debug { "config=#{config.send(:table).inspect}" } + config.logger.debug { "options=#{options.send(:table).inspect}" } + config.logger.info { "exec(#{command.inspect})" } output = "" - exit_code = nil + exit_code = -1 exit_signal = nil stdout_header = false stderr_header = false begin @@ -271,14 +302,19 @@ rescue Timeout::Error => e direct_log(:debug) { log_header("TIMEOUT") } log_and_raise(SSHError, "Session timed out after #{config.timeout} seconds!") end - config.logger.debug { "exit_code(#{exit_code}), exit_signal(#{exit_signal})" } + message = [ + "exit_code=#{exit_code}", + (exit_signal.nil? ? nil : "exit_signal=#{exit_signal} (#{EXIT_SIGNALS[exit_signal]})") + ].compact.join(", ") - if (exit_code != options.exit_code) - log_and_raise(SSHError, "exec(#{command.inspect}, #{options.inspect}) failed! [#{exit_code}, #{exit_signal}]") + config.logger.debug { message } + + if !config.ignore_exit_status && (exit_code != options.exit_code) + log_and_raise(SSHError, message) end OpenStruct.new(:output => output, :exit_code => exit_code, :exit_signal => exit_signal) end # Uploads a local file to a remote host. @@ -295,11 +331,11 @@ # end # local = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa.pub")) # remote = File.expand_path(File.join("/tmp", "id_rsa.pub")) # ssh.upload(local, remote) def upload(local, remote) - config.logger.debug { "config(#{config.inspect})" } + config.logger.debug { "config=#{config.send(:table).inspect}" } config.logger.info { "upload(#{local.inspect}, #{remote.inspect})" } ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do @sftp = Net::SFTP.start(config.host_name, config.user, ssh_options) sftp.upload!(local.to_s, remote.to_s) do |event, uploader, *args| @@ -335,10 +371,10 @@ # end # local = File.expand_path(File.join("/tmp", "id_rsa.pub")) # remote = File.expand_path(File.join(ENV["HOME"], ".ssh", "id_rsa.pub")) # ssh.download(remote, local) def download(remote, local) - config.logger.debug { "config(#{config.inspect})" } + config.logger.debug { "config=#{config.send(:table).inspect}" } config.logger.info { "download(#{remote.inspect}, #{local.inspect})" } ZTK::RescueRetry.try(:tries => 3, :on => EOFError) do @sftp = Net::SFTP.start(config.host_name, config.user, ssh_options) sftp.download!(remote.to_s, local.to_s) do |event, downloader, *args|