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|