class Vagrant::Action::Builtin::SSHRun

This class will run a single command on the remote machine and will mirror the output to the UI. The resulting exit status of the command will exist in the `:ssh_run_exit_status` key in the environment.

Public Class Methods

new(app, env) click to toggle source
# File lib/vagrant/action/builtin/ssh_run.rb, line 17
def initialize(app, env)
  @app    = app
  @logger = Log4r::Logger.new("vagrant::action::builtin::ssh_run")
end

Public Instance Methods

call(env) click to toggle source
# File lib/vagrant/action/builtin/ssh_run.rb, line 22
def call(env)
  # Grab the SSH info from the machine
  info = env[:machine].ssh_info

  # If the result is nil, then the machine is telling us that it is
  # not yet ready for SSH, so we raise this exception.
  raise Errors::SSHNotReady if info.nil?

  info[:private_key_path] ||= []

  # Check SSH key permissions
  info[:private_key_path].each do |path|
    SSH.check_key_permissions(Pathname.new(path))
  end

  if info[:private_key_path].empty?
    raise Errors::SSHRunRequiresKeys
  end

  # Get the command and wrap it in a login shell
  command = ShellQuote.escape(env[:ssh_run_command], "'")
  command = "#{env[:machine].config.ssh.shell} -c '#{command}'"

  # Execute!
  opts = env[:ssh_opts] || {}
  opts[:extra_args] ||= []

  # Allow the user to specify a tty or non-tty manually, but if they
  # don't then we default to a TTY
  if !opts[:extra_args].include?("-t") && !opts[:extra_args].include?("-T")
    opts[:extra_args] << "-t"
  end

  opts[:extra_args] << command
  opts[:subprocess] = true
  env[:ssh_run_exit_status] = Util::SSH.exec(info, opts)

  # Call the next middleware
  @app.call(env)
end