lib/remote/session.rb in remote-session-0.0.1 vs lib/remote/session.rb in remote-session-0.0.2
- old
+ new
@@ -1,6 +1,7 @@
require 'remote/session/version'
+require 'net/sftp'
require 'net/ssh'
module Remote
class Session
SUDO_PROMPT = 'sudo_prompt'
@@ -11,66 +12,99 @@
block.call rs
rs.close
end
- attr_accessor :host, :user, :password, :options
+ attr_accessor :host
+ attr_accessor :username
+ attr_accessor :password
+ attr_accessor :port
+ attr_accessor :private_key
+ attr_accessor :prompts
+ attr_accessor :session
def initialize( host, options = {} )
- @host = host
- @options = options.clone
- @user = @options.delete( :user ) || ENV[ 'USER' ]
- @password = @options.delete( :password )
+ @session = nil
+ @host = host
+ @username = options[ :username ] || ENV[ 'USER' ]
+ @password = options[ :password ]
+ @port = options[ :port ]
+ @private_key = options[ :private_key ]
+ @prompts = options[ :prompts ] || {}
+ @sudo_password = options[ :sudo_password ]
+
connect
end
def run( command )
raise "Session is closed" if @session.nil?
puts "@#{ @host }: #{ command }"
puts @session.exec!( command )
end
- def sudo( command, prompts = {} )
+ def sudo( command )
raise "Session is closed" if @session.nil?
puts "@#{ @host }: sudo #{ command }"
@session.open_channel do |ch|
ch.request_pty do |ch, success|
raise "Could not obtain pty" if ! success
- channel_exec ch, command, prompts
+ channel_exec ch, command
end
end
@session.loop
end
def close
@session.close
@session = nil
end
+ def sudo_put( remote_path, &block )
+ temp_path = "/tmp/remote-session.#{ Time.now.to_f }"
+ run "mkdir #{ temp_path }"
+ run "chmod 0700 #{ temp_path }"
+
+ temp_file = File.join( temp_path, File.basename( remote_path ) )
+ put temp_file, &block
+
+ sudo "cp -f #{ temp_file } #{ remote_path }"
+ run "rm -rf #{ temp_path }"
+ end
+
+ def put( remote_path, &block )
+ sftp = Net::SFTP::Session.new( @session ).connect!
+ sftp.file.open( remote_path, 'w' ) do |f|
+ f.puts block.call
+ end
+ sftp.close_channel
+ end
+
private
def ssh_options
s = {}
- s[ :password ] = @password if @password
+ s[ :password ] = @password if @password
+ s[ :keys ] = [ @private_key ] if @private_key
+ s[ :port ] = @port if @port
s
end
def connect
- @session = Net::SSH.start( @host, @user, ssh_options )
+ @session = Net::SSH.start( @host, @username, ssh_options )
end
- def channel_exec( ch, command, prompts )
+ def channel_exec( ch, command )
ch.exec "sudo -p '#{ SUDO_PROMPT }' #{ command }" do |ch, success|
raise "Could not execute sudo command: #{ command }" if ! success
ch.on_data do | ch, data |
if data =~ Regexp.new( SUDO_PROMPT )
- ch.send_data "#{ @options[ :sudo_password ] }\n"
+ ch.send_data "#{ @sudo_password }\n"
else
prompt_matched = false
- prompts.each_pair do | prompt, send |
+ @prompts.each_pair do | prompt, send |
if data =~ Regexp.new( prompt )
ch.send_data "#{ send }\n"
prompt_matched = true
end
end