1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
module Oxidized
require 'net/ssh'
require 'oxidized/input/cli'
class SSH < Input
include CLI
class NoShell < StandardError; end
def connect node
@node = node
@output = ''
@node.model.cfg['ssh'].each { |cb| instance_exec &cb }
begin
@ssh = Net::SSH.start @node.ip, @node.auth[:username],
:password => @node.auth[:password], :timeout => CFG.timeout
rescue Timeout::Error, Net::SSH::Disconnect
return false
end
@ses = open_shell @ssh unless @exec
not @ssh.closed?
end
def cmd cmd, expect=@node.prompt
Log.debug "SSH: #{cmd} @ #{@node.name}"
if @exec
@ssh.exec! cmd
else
cmd_shell(cmd, expect).gsub(/\r\n/, "\n")
end
end
private
def disconnect
begin
@pre_logout.each { |command| cmd command }
@ssh.loop
@ssh.close if not @ssh.closed?
rescue Net::SSH::Disconnect
end
end
def open_shell ssh
ses = ssh.open_channel do |ch|
ch.on_data do |ch, data|
@output << data
end
ch.request_pty do |ch, success|
raise NoShell, "Can't get PTY" unless success
ch.send_channel_request 'shell' do |ch, success|
raise NoShell, "Can't get shell" unless success
end
end
end
expect @node.prompt
ses
end
def exec state=nil
state == nil ? @exec : (@exec=state)
end
def cmd_shell(cmd, expect_re)
@output = ''
@ses.send_data cmd + "\n"
@ses.process
expect expect_re if expect_re
@output
end
def expect regexp
@ssh.loop(0.1) do
sleep 0.1
not @output.match regexp
end
end
end
end
|