lib/core/util/ssh.rb in nucleon-0.2.0 vs lib/core/util/ssh.rb in nucleon-0.2.1

- old
+ new

@@ -138,10 +138,12 @@ # SSH Execution interface @@sessions = {} @@auth = {} + @@session_lock = Mutex.new + #--- def self.session_id(hostname, user) "#{hostname}-#{user}" end @@ -150,41 +152,44 @@ def self.session(hostname, user, port = 22, private_key = nil, reset = false, options = {}) require 'net/ssh' session_id = session_id(hostname, user) - config = Config.ensure(options) - ssh_options = Config.new({ - :user_known_hosts_file => [ File.join(key_path, 'known_hosts'), File.join(key_path, 'known_hosts2') ], - :auth_methods => [ 'publickey' ], - :paranoid => :very - }).import(Util::Data.subset(config, config.keys - [ :keypair, :key_dir, :key_name ])) + @@session_lock.synchronize do + config = Config.ensure(options) - if private_key - auth_id = [ session_id, private_key ].join('_') + ssh_options = Config.new({ + :user_known_hosts_file => [ File.join(key_path, 'known_hosts'), File.join(key_path, 'known_hosts2') ], + :auth_methods => [ 'publickey' ], + :paranoid => :very + }).import(Util::Data.subset(config, config.keys - [ :keypair, :key_dir, :key_name ])) + + if private_key + auth_id = [ session_id, private_key ].join('_') - if ! @@auth[auth_id] && keypair = unlock_private_key(private_key, config) - @@auth[auth_id] = keypair - end - config[:keypair] = @@auth[auth_id] # Reset so caller can access updated keypair + if ! @@auth[auth_id] && keypair = unlock_private_key(private_key, config) + @@auth[auth_id] = keypair + end + config[:keypair] = @@auth[auth_id] # Reset so caller can access updated keypair - if @@auth[auth_id].is_a?(String) - ssh_options[:keys_only] = false - ssh_options[:keys] = [ @@auth[auth_id] ] - else - ssh_options[:keys_only] = true - ssh_options[:key_data] = [ @@auth[auth_id].private_key ] + if @@auth[auth_id].is_a?(String) + ssh_options[:keys_only] = false + ssh_options[:keys] = [ @@auth[auth_id] ] + else + ssh_options[:keys_only] = true + ssh_options[:key_data] = [ @@auth[auth_id].private_key ] + end end - end - ssh_options[:port] = port + ssh_options[:port] = port - if reset || ! @@sessions.has_key?(session_id) - @@sessions[session_id] = Net::SSH.start(hostname, user, ssh_options.export) + if reset || ! @@sessions.has_key?(session_id) + @@sessions[session_id] = Net::SSH.start(hostname, user, ssh_options.export) + end end - yield(@@sessions[session_id]) if block_given? && @@sessions[session_id] + yield(@@sessions[session_id]) if block_given? && @@sessions[session_id] @@sessions[session_id] end def self.init_session(hostname, user, port = 22, private_key = nil, options = {}) session(hostname, user, port, private_key, true, options) @@ -242,11 +247,10 @@ result = Shell::Result.new(command) logger.info(">> running SSH: #{command}") ssh.open_channel do |ssh_channel| - ssh_channel.request_pty ssh_channel.exec(command) do |channel, success| unless success raise "Could not execute command: #{command.inspect}" end @@ -254,10 +258,9 @@ result.append_output(data) yield(:output, command, data) if block_given? end channel.on_extended_data do |ch, type, data| - next unless type == 1 result.append_errors(data) yield(:error, command, data) if block_given? end channel.on_request('exit-status') do |ch, data|