Class: Expect::SSH

Inherits:
Object
  • Object
show all
Includes:
Behavior
Defined in:
lib/expect/ssh.rb

Overview

An SSH Accessor with expect-like behaviors. See also Expect::Behavior.

Constant Summary

Constants included from Behavior

Behavior::EXP_SLEEP_INTERVAL_SEC_DEFAULT, Behavior::EXP_TIMEOUT_SEC_DEFAULT

Instance Attribute Summary collapse

Attributes included from Behavior

#exp_match, #exp_sleep_interval_sec, #exp_timeout_sec

Instance Method Summary collapse

Methods included from Behavior

#expect

Constructor Details

#initialize(hostname, username, port: 22, password: nil, ignore_known_hosts: false, key_file: nil, logout_command: "exit", wait_interval_sec: 0.1, log_level: Logger::WARN) ⇒ SSH

Returns a new instance of SSH.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/expect/ssh.rb', line 19

def initialize(hostname, username,
               # keyword args follow
               port: 22,
               password: nil, # password for login
               ignore_known_hosts: false, # ignore host key mismatches?
               key_file: nil, # path to private key file
               logout_command: "exit", # command to exit/logout SSH session on remote host
               wait_interval_sec: 0.1, # process interval
               log_level: Logger::WARN)
  @hostname = hostname
  @username = username
  @port = port
  @password = password
  @ignore_known_hosts = ignore_known_hosts
  @key_file = key_file
  @logout_command = logout_command
  @wait_interval_sec = wait_interval_sec
  @auth_methods = ['none', 'publickey', 'password']
  @ssh = nil
  @logger = Logger.new($stdout)
  @logger.level = log_level if log_level
  @receive_buffer = ''
end

Instance Attribute Details

#auth_methodsObject (readonly)

:Required methods to be created by the class mixing Expect::Behaviors :

#exp_process - should do one iteration of handle input and append buffer
#exp_buffer - provide the current buffer contents and empty it


17
18
19
# File 'lib/expect/ssh.rb', line 17

def auth_methods
  @auth_methods
end

Instance Method Details

#exp_bufferObject

exp_buffer - provide the current buffer contents and empty it



84
85
86
87
88
# File 'lib/expect/ssh.rb', line 84

def exp_buffer
  result = @receive_buffer
  @receive_buffer = ''
  result
end

#exp_processObject

exp_process - should do one iteration of handle input and append buffer



92
93
94
95
# File 'lib/expect/ssh.rb', line 92

def exp_process
  sleep(@wait_sec.to_f)
  @ssh.process(0)
end

#send_data(command) ⇒ Object

Transmit the contents of command using the SSH @channel



45
46
47
48
49
# File 'lib/expect/ssh.rb', line 45

def send_data(command)
  @logger.debug("[Expect::SSH##{__method__}] [@hostname=#{@hostname}] [command=#{command}]")
  command += "\n" unless command.end_with?("\n")
  @channel.send_data(command)
end

#startObject

Initiate SSH connection

Raises:

  • (RuntimeError)


53
54
55
56
57
58
59
60
# File 'lib/expect/ssh.rb', line 53

def start
  $stdout.puts(
      "[Expect::SSH##{__method__}] [@hostname=#{@hostname}] [@username=#{@username}] [options=#{options}]"
  )
  @ssh = Net::SSH.start(@hostname, @username, options)
  raise(RuntimeError, "[Expect::SSH##{__method__}]: SSH Start Failed") unless @ssh
  @channel = request_channel_pty_shell
end

#stopObject

Close SSH connection



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/expect/ssh.rb', line 64

def stop
  @logger.debug("[Expect::SSH##{__method__}]: Closing Channel")
  @channel.send_data(@logout_command + "\n")
  @channel.close
  begin
    # A net-ssh quirk is that if you send a graceful close but you don't send an exit, it'll hang forever
    # ...see also: http://stackoverflow.com/questions/25576454/ruby-net-ssh-script-not-closing
    # I send an exit but just in case, also force the shutdown if it doesn't happen in 1 second.  #NotPatient
    Timeout::timeout(1) do
      @logger.debug("[Expect::SSH##{__method__}]: Closing Session")
      @ssh.close
    end
  rescue Timeout::Error
    @logger.debug("[Expect::SSH##{__method__}]: FORCE Closing Session")
    @ssh.shutdown!
  end
end