Remove leopard/tiger checking and just retry exec using safe_exec

This commit is contained in:
Mitchell Hashimoto 2011-07-09 16:37:12 -07:00
parent 7deeac42dc
commit 1aed9f0f38
4 changed files with 35 additions and 27 deletions

View File

@ -12,6 +12,7 @@ module Vagrant
autoload :Session, 'vagrant/ssh/session'
include Util::Retryable
include Util::SafeExec
# Reference back up to the environment which this SSH object belongs
# to
@ -56,10 +57,8 @@ module Vagrant
# 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
pid = fork if Util::Platform.leopard? || Util::Platform.tiger?
Kernel.exec "ssh #{command_options.join(" ")} #{options[:username]}@#{options[:host]}".strip if pid.nil?
Process.wait(pid) if pid
command = "ssh #{command_options.join(" ")} #{options[:username]}@#{options[:host]}".strip
safe_exec(command)
end
# Opens an SSH connection to this environment's virtual machine and yields

View File

@ -8,6 +8,7 @@ module Vagrant
autoload :Platform, 'vagrant/util/platform'
autoload :ResourceLogger, 'vagrant/util/resource_logger'
autoload :Retryable, 'vagrant/util/retryable'
autoload :SafeExec, 'vagrant/util/safe_exec'
autoload :StackedProcRunner, 'vagrant/util/stacked_proc_runner'
autoload :TemplateRenderer, 'vagrant/util/template_renderer'
end

View File

@ -0,0 +1,28 @@
module Vagrant
module Util
# This module provies a `safe_exec` method which is a drop-in
# replacement for `Kernel.exec` which addresses a specific issue
# which manifests on OS X 10.5 and perhaps other operating systems.
# This issue causes `exec` to fail if there is more than one system
# thread. In that case, `safe_exec` automatically falls back to
# forking.
module SafeExec
def safe_exec(command)
fork_instead = false
begin
pid = nil
pid = fork if fork_instead
Kernel.exec(command) if pid.nil?
Process.wait(pid) if pid
rescue Errno::E045
# We retried already, raise the issue and be done
raise if fork_instead
# The error manifested itself, retry with a fork.
fork_instead = true
retry
end
end
end
end
end

View File

@ -20,10 +20,8 @@ class SshTest < Test::Unit::TestCase
mock_ssh
@ssh.stubs(:check_key_permissions)
@ssh.stubs(:port).returns(2222)
Kernel.stubs(:exec)
@ssh.stubs(:safe_exec)
Kernel.stubs(:system).returns(true)
Vagrant::Util::Platform.stubs(:leopard?).returns(false)
end
should "raise an exception if SSH is not found" do
@ -41,7 +39,7 @@ class SshTest < Test::Unit::TestCase
should "check key permissions prior to exec" do
exec_seq = sequence("exec_seq")
@ssh.expects(:check_key_permissions).with(@env.config.ssh.private_key_path).once.in_sequence(exec_seq)
Kernel.expects(:exec).in_sequence(exec_seq)
@ssh.expects(:safe_exec).in_sequence(exec_seq)
@ssh.connect
end
@ -81,24 +79,6 @@ class SshTest < Test::Unit::TestCase
@ssh.connect
end
context "on leopard" do
setup do
Vagrant::Util::Platform.stubs(:leopard?).returns(true)
end
teardown do
Vagrant::Util::Platform.stubs(:leopard?).returns(false)
end
should "fork, exec, and wait" do
pid = mock("pid")
@ssh.expects(:fork).once.returns(pid)
Process.expects(:wait).with(pid)
@ssh.connect
end
end
context "checking windows" do
teardown do
Mario::Platform.forced = Mario::Platform::Linux
@ -116,7 +96,7 @@ class SshTest < Test::Unit::TestCase
end
def ssh_exec_expect(port, key_path, uname, host)
Kernel.expects(:exec).with() do |arg|
@ssh.expects(:safe_exec).with() do |arg|
assert arg =~ /^ssh/, "ssh command expected"
assert arg =~ /-p #{port}/, "-p #{port} expected"
assert arg =~ /-i #{key_path}/, "-i #{key_path} expected"