Method: Vagrant::Util::SSH.exec

Defined in:
lib/vagrant/util/ssh.rb

.exec(ssh_info, opts = {}) ⇒ Object

Halts the running of this process and replaces it with a full-fledged SSH shell into a remote machine.

Note: This method NEVER returns. The process ends after this.

Parameters:

  • ssh_info (Hash)

    This is the SSH information. For the keys required please see the documentation of Machine#ssh_info.

  • opts (Hash) (defaults to: {})

    These are additional options that are supported by exec.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/vagrant/util/ssh.rb', line 55

def self.exec(ssh_info, opts={})
  # Ensure the platform supports ssh. On Windows there are several programs which
  # include ssh, notably git, mingw and cygwin, but make sure ssh is in the path!
  if !Which.which("ssh")
    if Platform.windows?
      raise Errors::SSHUnavailableWindows,
        :host => ssh_info[:host],
        :port => ssh_info[:port],
        :username => ssh_info[:username],
        :key_path => ssh_info[:private_key_path]
    end

    raise Errors::SSHUnavailable
  end

  # If plain mode is enabled then we don't do any authentication (we don't
  # set a user or an identity file)
  plain_mode = opts[:plain_mode]

  options = {}
  options[:host] = ssh_info[:host]
  options[:port] = ssh_info[:port]
  options[:username] = ssh_info[:username]
  options[:private_key_path] = ssh_info[:private_key_path]

  # Command line options
  command_options = [
    "-p", options[:port].to_s,
    "-o", "LogLevel=FATAL",
    "-o", "StrictHostKeyChecking=no",
    "-o", "UserKnownHostsFile=/dev/null"]

  # Solaris/OpenSolaris/Illumos uses SunSSH which doesn't support the
  # IdentitiesOnly option. Also, we don't enable it in plain mode so
  # that SSH properly searches our identities and tries to do it itself.
  if !Platform.solaris? && !plain_mode
    command_options += ["-o", "IdentitiesOnly=yes"]
  end

  # If we're not in plain mode, attach the private key path.
  command_options += ["-i", options[:private_key_path].to_s] if !plain_mode

  if ssh_info[:forward_x11]
    # Both are required so that no warnings are shown regarding X11
    command_options += [
      "-o", "ForwardX11=yes",
      "-o", "ForwardX11Trusted=yes"]
  end

  # Configurables -- extra_args should always be last due to the way the
  # ssh args parser works. e.g. if the user wants to use the -t option,
  # any shell command(s) she'd like to run on the remote server would
  # have to be the last part of the 'ssh' command:
  #
  #   $ ssh localhost -t -p 2222 "cd mydirectory; bash"
  #
  # Without having extra_args be last, the user loses this ability
  command_options += ["-o", "ForwardAgent=yes"] if ssh_info[:forward_agent]
  command_options.concat(opts[:extra_args]) if opts[:extra_args]

  # Build up the host string for connecting
  host_string = options[:host]
  host_string = "#{options[:username]}@#{host_string}" if !plain_mode
  command_options.unshift(host_string)

  # Invoke SSH with all our options
  LOGGER.info("Invoking SSH: #{command_options.inspect}")
  SafeExec.exec("ssh", *command_options)
end