lib/vagrant/ssh.rb in vagrant-0.7.0.beta vs lib/vagrant/ssh.rb in vagrant-0.7.0.beta2
- old
+ new
@@ -1,10 +1,12 @@
require 'timeout'
require 'net/ssh'
require 'net/scp'
require 'mario'
+require 'vagrant/ssh/session'
+
module Vagrant
# Manages SSH access to a specific environment. Allows an environment to
# replace the process with SSH itself, run a specific set of commands,
# upload files, or even check if a host is up.
class SSH
@@ -40,10 +42,11 @@
# Command line options
command_options = ["-p #{options[:port]}", "-o UserKnownHostsFile=/dev/null",
"-o StrictHostKeyChecking=no", "-o IdentitiesOnly=yes",
"-i #{options[:private_key_path]}"]
command_options << "-o ForwardAgent=yes" if env.config.ssh.forward_agent
+ command_options << "-o ForwardX11=yes" if env.config.ssh.forward_x11
# Some hackery going on here. On Mac OS X Leopard (10.5), exec fails
# (GH-51). As a workaround, we fork and wait. On all other platforms,
# we simply exec.
pid = nil
@@ -158,80 +161,8 @@
return pnum.hostport if pnum
# Fall back to the default
return env.config.ssh.port
- end
- end
-
- class SSH
- # A helper class which wraps around `Net::SSH::Connection::Session`
- # in order to provide basic command error checking while still
- # providing access to the actual session object.
- class Session
- include Util::Retryable
-
- attr_reader :session
-
- def initialize(session)
- @session = session
- end
-
- # Executes a given command on the SSH session and blocks until
- # the command completes. This is an almost line for line copy of
- # the actual `exec!` implementation, except that this
- # implementation also reports `:exit_status` to the block if given.
- def exec!(command, options=nil, &block)
- options = {
- :error_check => true
- }.merge(options || {})
-
- block ||= Proc.new do |ch, type, data|
- check_exit_status(data, command, options) if type == :exit_status && options[:error_check]
-
- ch[:result] ||= ""
- ch[:result] << data if [:stdout, :stderr].include?(type)
- end
-
- retryable(:tries => 5, :on => IOError, :sleep => 0.5) do
- metach = session.open_channel do |channel|
- channel.exec(command) do |ch, success|
- raise "could not execute command: #{command.inspect}" unless success
-
- # Output stdout data to the block
- channel.on_data do |ch2, data|
- block.call(ch2, :stdout, data)
- end
-
- # Output stderr data to the block
- channel.on_extended_data do |ch2, type, data|
- block.call(ch2, :stderr, data)
- end
-
- # Output exit status information to the block
- channel.on_request("exit-status") do |ch2, data|
- block.call(ch2, :exit_status, data.read_long)
- end
- end
- end
-
- metach.wait
- metach[:result]
- end
- end
-
- # Checks for an erroroneous exit status and raises an exception
- # if so.
- def check_exit_status(exit_status, command, options=nil)
- if exit_status != 0
- options = {
- :_error_class => Errors::VagrantError,
- :_key => :ssh_bad_exit_status,
- :command => command
- }.merge(options || {})
-
- raise options[:_error_class], options
- end
- end
end
end
end