Mounting a folder now waits for the mount to succeed before continuing. Fixed a race condition between SSH daemon starting and the VBox kernel extensions loading...

This commit is contained in:
Mitchell Hashimoto 2010-03-05 19:16:57 -08:00
parent 41b25e68ec
commit 49c98ad8af
2 changed files with 75 additions and 2 deletions

View File

@ -38,11 +38,31 @@ module Vagrant
shared_folders.each do |name, hostpath, guestpath|
logger.info "-- #{name}: #{guestpath}"
ssh.exec!("sudo mkdir -p #{guestpath}")
ssh.exec!("sudo mount -t vboxsf #{name} #{guestpath}")
mount_folder(ssh, name, guestpath)
ssh.exec!("sudo chown #{Vagrant.config.ssh.username} #{guestpath}")
end
end
end
def mount_folder(ssh, name, guestpath, sleeptime=5)
# Note: This method seems pretty OS-specific and could also use
# some configuration options. For now its duct tape and "works"
# but should be looked at in the future.
attempts = 0
while true
result = ssh.exec!("sudo mount -t vboxsf #{name} #{guestpath}") do |ch, type, data|
# net/ssh returns the value in ch[:result] (based on looking at source)
ch[:result] = !!(type == :stderr && data =~ /No such device/i)
end
break unless result
attempts += 1
raise ActionException.new("Failed to mount shared folders. vboxsf was not available.") if attempts >= 10
sleep sleeptime
end
end
end
end
end

View File

@ -53,7 +53,7 @@ class SharedFoldersActionTest < Test::Unit::TestCase
ssh = mock("ssh")
@folders.each do |name, hostpath, guestpath|
ssh.expects(:exec!).with("sudo mkdir -p #{guestpath}").in_sequence(mount_seq)
ssh.expects(:exec!).with("sudo mount -t vboxsf #{name} #{guestpath}").in_sequence(mount_seq)
@action.expects(:mount_folder).with(ssh, name, guestpath).in_sequence(mount_seq)
ssh.expects(:exec!).with("sudo chown #{Vagrant.config.ssh.username} #{guestpath}").in_sequence(mount_seq)
end
Vagrant::SSH.expects(:execute).yields(ssh)
@ -61,4 +61,57 @@ class SharedFoldersActionTest < Test::Unit::TestCase
@action.after_boot
end
end
context "mounting the main folder" do
setup do
@ssh = mock("ssh")
@name = "foo"
@guestpath = "bar"
@sleeptime = 0
@limit = 10
@success_return = false
end
def mount_folder
@action.mount_folder(@ssh, @name, @guestpath, @sleeptime)
end
should "execute the proper mount command" do
@ssh.expects(:exec!).with("sudo mount -t vboxsf #{@name} #{@guestpath}").returns(@success_return)
mount_folder
end
should "test type of text and text string to detect error" do
data = mock("data")
data.expects(:[]=).with(:result, !@success_return)
@ssh.expects(:exec!).yields(data, :stderr, "No such device").returns(@success_return)
mount_folder
end
should "test type of text and test string to detect success" do
data = mock("data")
data.expects(:[]=).with(:result, @success_return)
@ssh.expects(:exec!).yields(data, :stdout, "Nothing such device").returns(@success_return)
mount_folder
end
should "raise an ActionException if the command fails constantly" do
@ssh.expects(:exec!).times(@limit).returns(!@success_return)
assert_raises(Vagrant::Actions::ActionException) {
mount_folder
}
end
should "not raise any exception if the command succeeded" do
@ssh.expects(:exec!).once.returns(@success_return)
assert_nothing_raised {
mount_folder
}
end
end
end