Class: Vagrant::Communication::SSH

Inherits:
Base
  • Object
show all
Includes:
Util::ANSIEscapeCodeRemover, Util::Retryable
Defined in:
lib/vagrant/communication/ssh.rb

Overview

Provides communication with the VM via SSH.

Instance Method Summary collapse

Methods included from Util::Retryable

#retryable

Methods included from Util::ANSIEscapeCodeRemover

#remove_ansi_escape_codes

Methods inherited from Base

#test

Constructor Details

#initialize(vm) ⇒ SSH

Returns a new instance of SSH.



19
20
21
22
23
# File 'lib/vagrant/communication/ssh.rb', line 19

def initialize(vm)
  @vm     = vm
  @logger = Log4r::Logger.new("vagrant::communication::ssh")
  @connection = nil
end

Instance Method Details

#execute(command, opts = nil, &block) ⇒ Object



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
# File 'lib/vagrant/communication/ssh.rb', line 42

def execute(command, opts=nil, &block)
  opts = {
    :error_check => true,
    :error_class => Errors::VagrantError,
    :error_key   => :ssh_bad_exit_status,
    :command     => command,
    :sudo        => false
  }.merge(opts || {})

  # Connect via SSH and execute the command in the shell.
  exit_status = connect do |connection|
    shell_execute(connection, command, opts[:sudo], &block)
  end

  # Check for any errors
  if opts[:error_check] && exit_status != 0
    # The error classes expect the translation key to be _key,
    # but that makes for an ugly configuration parameter, so we
    # set it here from `error_key`
    error_opts = opts.merge(:_key => opts[:error_key])
    raise opts[:error_class], error_opts
  end

  # Return the exit status
  exit_status
end

#ready?Boolean

Returns:

  • (Boolean)


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/vagrant/communication/ssh.rb', line 25

def ready?
  @logger.debug("Checking whether SSH is ready...")

  Timeout.timeout(@vm.config.ssh.timeout) do
    connect
  end

  # If we reached this point then we successfully connected
  @logger.info("SSH is ready!")
  true
rescue Timeout::Error, Errors::SSHConnectionRefused, Net::SSH::Disconnect => e
  # The above errors represent various reasons that SSH may not be
  # ready yet. Return false.
  @logger.info("SSH not up: #{e.inspect}")
  return false
end

#sudo(command, opts = nil, &block) ⇒ Object



69
70
71
72
73
# File 'lib/vagrant/communication/ssh.rb', line 69

def sudo(command, opts=nil, &block)
  # Run `execute` but with the `sudo` option.
  opts = { :sudo => true }.merge(opts || {})
  execute(command, opts, &block)
end

#upload(from, to) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/vagrant/communication/ssh.rb', line 75

def upload(from, to)
  @logger.debug("Uploading: #{from} to #{to}")

  # Do an SCP-based upload...
  connect do |connection|
    scp = Net::SCP.new(connection)
    scp.upload!(from, to)
  end
rescue Net::SCP::Error => e
  # If we get the exit code of 127, then this means SCP is unavailable.
  raise Errors::SCPUnavailable if e.message =~ /\(127\)/

  # Otherwise, just raise the error up
  raise
end