First capability for linux

This commit is contained in:
Mitchell Hashimoto 2013-04-03 23:01:43 -07:00
parent 819ef46fca
commit 28d3f274d8
7 changed files with 88 additions and 34 deletions

View File

@ -127,7 +127,7 @@ module Vagrant
:guest => @chain[0][0].to_s
end
cap_method.call(*args)
cap_method.call(@machine, *args)
end
# This returns whether the guest is ready to work. If this returns

View File

@ -0,0 +1,41 @@
module VagrantPlugins
module GuestLinux
module Cap
class MountVirtualBoxSharedFolder
def self.mount_virtualbox_shared_folder(machine, name, guestpath, options)
expanded_guest_path = machine.guest.capability(
:shell_expand_guest_path, guestpath)
# Determine the permission string to attach to the mount command
mount_options = "-o uid=`id -u #{options[:owner]}`,gid=`id -g #{options[:group]}`"
mount_options += ",#{options[:extra]}" if options[:extra]
mount_command = "mount -t vboxsf #{mount_options} #{name} #{expanded_guest_path}"
# Create the guest path if it doesn't exist
machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
# Attempt to mount the folder. We retry here a few times because
# it can fail early on.
attempts = 0
while true
success = true
machine.communicate.sudo(mount_command) do |type, data|
success = false if type == :stderr && data =~ /No such device/i
end
break if success
attempts += 1
# TODO: Nicer exception
raise "Mount failed"
sleep 2
end
# Chown the directory to the proper user
machine.communicate.sudo(
"chown `id -u #{options[:owner]}`:`id -g #{options[:group]}` #{expanded_guest_path}")
end
end
end
end
end

View File

@ -0,0 +1,27 @@
module VagrantPlugins
module GuestLinux
module Cap
class ShellExpandGuestPath
def self.shell_expand_guest_path(machine, path)
real_path = nil
machine.communicate.execute("printf #{guestpath}") do |type, data|
if type == :stdout
real_path ||= ""
real_path += data
end
end
if !real_path
# If no real guest path was detected, this is really strange
# and we raise an exception because this is a bug.
# TODO: Nice exception
raise "No expanded guest path detected."
end
# Chomp the string so that any trailing newlines are killed
return real_path.chomp
end
end
end
end
end

View File

@ -52,15 +52,6 @@ module VagrantPlugins
end
end
def mount_shared_folder(name, guestpath, options)
real_guestpath = expanded_guest_path(guestpath)
@logger.debug("Shell expanded guest path: #{real_guestpath}")
@vm.communicate.sudo("mkdir -p #{real_guestpath}")
mount_folder(name, real_guestpath, options)
@vm.communicate.sudo("chown `id -u #{options[:owner]}`:`id -g #{options[:group]}` #{real_guestpath}")
end
def mount_nfs(ip, folders)
# TODO: Maybe check for nfs support on the guest, since its often
# not installed by default
@ -105,26 +96,6 @@ module VagrantPlugins
# Chomp the string so that any trailing newlines are killed
return real_guestpath.chomp
end
def mount_folder(name, guestpath, options)
# Determine the permission string to attach to the mount command
mount_options = "-o uid=`id -u #{options[:owner]}`,gid=`id -g #{options[:group]}`"
mount_options += ",#{options[:extra]}" if options[:extra]
attempts = 0
while true
success = true
@vm.communicate.sudo("mount -t vboxsf #{mount_options} #{name} #{guestpath}") do |type, data|
success = false if type == :stderr && data =~ /No such device/i
end
break if success
attempts += 1
raise LinuxError, :mount_fail if attempts >= 10
sleep 5
end
end
end
end
end

View File

@ -15,6 +15,16 @@ module VagrantPlugins
require File.expand_path("../guest", __FILE__)
Guest
end
guest_capability("linux", "shell_expand_guest_path") do
require_relative "cap/shell_expand_guest_path"
Cap::ShellExpandGuestPath
end
guest_capability("linux", "mount_virtualbox_shared_folder") do
require_relative "cap/mount_virtualbox_shared_folder"
Cap::MountVirtualBoxSharedFolder
end
end
end
end

View File

@ -108,7 +108,8 @@ module VagrantPlugins
data[:group] ||= @env[:machine].config.ssh.username
# Mount the actual folder
@env[:machine].guest.mount_shared_folder(id, data[:guestpath], data)
@env[:machine].guest.capability(
:mount_virtualbox_shared_folder, id, data[:guestpath], data)
else
# If no guest path is specified, then automounting is disabled
@env[:ui].info(I18n.t("vagrant.actions.vm.share_folders.nomount_entry",

View File

@ -7,7 +7,11 @@ describe Vagrant::Guest do
let(:capabilities) { {} }
let(:guests) { {} }
let(:machine) { double("machine") }
let(:machine) do
double("machine").tap do |m|
m.stub(:inspect => "machine")
end
end
subject { described_class.new(machine, guests, capabilities) }
@ -58,14 +62,14 @@ describe Vagrant::Guest do
register_capability(:bar, :test)
expect { subject.capability(:test) }.
to raise_error(RuntimeError, "cap: test []")
to raise_error(RuntimeError, "cap: test [machine]")
end
it "executes the capability with arguments" do
register_capability(:bar, :test)
expect { subject.capability(:test, 1) }.
to raise_error(RuntimeError, "cap: test [1]")
to raise_error(RuntimeError, "cap: test [machine, 1]")
end
it "raises an exception if the capability doesn't exist" do