Class: Kitchen::SSH

Inherits:
Object
  • Object
show all
Defined in:
lib/kitchen/ssh.rb

Overview

Class to help establish SSH connections, issue remote commands, and transfer files between a local system and remote node.

Author:

Instance Method Summary collapse

Constructor Details

#initialize(hostname, username, options = {}) ⇒ SSH

Returns a new instance of SSH.



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/kitchen/ssh.rb', line 40

def initialize(hostname, username, options = {})
  @hostname = hostname
  @username = username
  @options = options.dup
  @logger = @options.delete(:logger) || ::Logger.new(STDOUT)

  if block_given?
    yield self
    shutdown
  end
end

Instance Method Details

#exec(cmd) ⇒ Object



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

def exec(cmd)
  logger.debug("[SSH] #{self} (#{cmd})")
  exit_code = exec_with_exit(cmd)

  if exit_code != 0
    raise SSHFailed, "SSH exited (#{exit_code}) for command: [#{cmd}]"
  end
end

#login_commandObject



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/kitchen/ssh.rb', line 92

def 
  args  = %W{ -o UserKnownHostsFile=/dev/null }
  args += %W{ -o StrictHostKeyChecking=no }
  args += %W{ -o LogLevel=#{logger.debug? ? "VERBOSE" : "ERROR"} }
  args += %W{ -o ForwardAgent=#{options[:forward_agent] ? "yes" : "no"} } if options.key? :forward_agent
  Array(options[:keys]).each { |ssh_key| args += %W{ -i #{ssh_key}} }
  args += %W{ -p #{port}}
  args += %W{ #{username}@#{hostname}}

  LoginCommand.new(["ssh", *args])
end

#shutdownObject



79
80
81
82
83
84
85
86
# File 'lib/kitchen/ssh.rb', line 79

def shutdown
  return if @session.nil?

  logger.debug("[SSH] closing connection to #{self}")
  session.shutdown!
ensure
  @session = nil
end

#upload!(local, remote, options = {}, &progress) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/kitchen/ssh.rb', line 61

def upload!(local, remote, options = {}, &progress)
  if progress.nil?
    progress = lambda { |ch, name, sent, total|
      if sent == total
        logger.debug("Uploaded #{name} (#{total} bytes)")
      end
    }
  end

  session.scp.upload!(local, remote, options, &progress)
end

#upload_path!(local, remote, options = {}, &progress) ⇒ Object



73
74
75
76
77
# File 'lib/kitchen/ssh.rb', line 73

def upload_path!(local, remote, options = {}, &progress)
  options = { :recursive => true }.merge(options)

  upload!(local, remote, options, &progress)
end

#waitObject



88
89
90
# File 'lib/kitchen/ssh.rb', line 88

def wait
  logger.info("Waiting for #{hostname}:#{port}...") until test_ssh
end