Shared folder task
This commit is contained in:
parent
05a01f5953
commit
73a3723608
|
@ -9,6 +9,7 @@ module Vagrant
|
|||
use VM::Import
|
||||
use VM::Customize
|
||||
use VM::ForwardPorts
|
||||
use VM::ShareFolders
|
||||
end
|
||||
|
||||
register :up, up
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
module Vagrant
|
||||
class Action
|
||||
module VM
|
||||
class ShareFolders
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@env = env
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@env = env
|
||||
|
||||
clear_shared_folders
|
||||
create_metadata
|
||||
|
||||
@app.call(env)
|
||||
|
||||
mount_shared_folders
|
||||
setup_unison
|
||||
end
|
||||
|
||||
# This method returns an actual list of VirtualBox shared
|
||||
# folders to create and their proper path.
|
||||
def shared_folders
|
||||
@env.env.config.vm.shared_folders.inject({}) do |acc, data|
|
||||
key, value = data
|
||||
|
||||
# This to prevent overwriting the actual shared folders data
|
||||
value = value.dup
|
||||
|
||||
if value[:sync]
|
||||
# Syncing this folder. Change the guestpath to reflect
|
||||
# what we're actually mounting.
|
||||
value[:original] = value.dup
|
||||
value[:guestpath] = "#{value[:guestpath]}#{@env.env.config.unison.folder_suffix}"
|
||||
end
|
||||
|
||||
acc[key] = value
|
||||
acc
|
||||
end
|
||||
end
|
||||
|
||||
# This method returns the list of shared folders which are to
|
||||
# be synced via unison.
|
||||
def unison_folders
|
||||
shared_folders.inject({}) do |acc, data|
|
||||
key, value = data
|
||||
acc[key] = value if !!value[:sync]
|
||||
acc
|
||||
end
|
||||
end
|
||||
|
||||
def clear_shared_folders
|
||||
if @env["vm"].vm.shared_folders.length > 0
|
||||
@env.logger.info "Clearing previously set shared folders..."
|
||||
|
||||
folders = @env["vm"].vm.shared_folders.dup
|
||||
folders.each do |shared_folder|
|
||||
shared_folder.destroy
|
||||
end
|
||||
|
||||
@env["vm"].reload!
|
||||
end
|
||||
end
|
||||
|
||||
def create_metadata
|
||||
@env.logger.info "Creating shared folders metadata..."
|
||||
|
||||
shared_folders.each do |name, data|
|
||||
folder = VirtualBox::SharedFolder.new
|
||||
folder.name = name
|
||||
folder.host_path = File.expand_path(data[:hostpath], @env.env.root_path)
|
||||
@env["vm"].vm.shared_folders << folder
|
||||
end
|
||||
|
||||
@env["vm"].vm.save
|
||||
end
|
||||
|
||||
def mount_shared_folders
|
||||
@env.logger.info "Mounting shared folders..."
|
||||
|
||||
@env["vm"].ssh.execute do |ssh|
|
||||
shared_folders.each do |name, data|
|
||||
@env.logger.info "-- #{name}: #{data[:guestpath]}"
|
||||
@env["vm"].system.mount_shared_folder(ssh, name, data[:guestpath])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setup_unison
|
||||
return if unison_folders.empty?
|
||||
|
||||
@env["vm"].ssh.execute do |ssh|
|
||||
@env["vm"].system.prepare_unison(ssh)
|
||||
|
||||
@env.logger.info "Creating unison crontab entries..."
|
||||
unison_folders.each do |name, data|
|
||||
@env["vm"].system.create_unison(ssh, data)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,217 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class ShareFoldersVMActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@klass = Vagrant::Action::VM::ShareFolders
|
||||
@app, @env = mock_action_data
|
||||
|
||||
@vm = mock("vm")
|
||||
@vm.stubs(:name).returns("foo")
|
||||
@vm.stubs(:ssh).returns(mock("ssh"))
|
||||
@vm.stubs(:system).returns(mock("system"))
|
||||
@env["vm"] = @vm
|
||||
|
||||
@internal_vm = mock("internal")
|
||||
@vm.stubs(:vm).returns(@internal_vm)
|
||||
|
||||
@instance = @klass.new(@app, @env)
|
||||
end
|
||||
|
||||
def stub_shared_folders
|
||||
env = mock_environment do |config|
|
||||
config.vm.shared_folders.clear
|
||||
|
||||
if block_given?
|
||||
yield config
|
||||
else
|
||||
folders = [%w{foo fooguest foohost}, %w{bar barguest barhost}]
|
||||
folders.each do |data|
|
||||
config.vm.share_folder(*data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@env.stubs(:env).returns(env)
|
||||
env.config.vm.shared_folders
|
||||
end
|
||||
|
||||
context "calling" do
|
||||
should "run the methods in the proper order" do
|
||||
before_seq = sequence("before")
|
||||
@instance.expects(:clear_shared_folders).once.in_sequence(before_seq)
|
||||
@instance.expects(:create_metadata).once.in_sequence(before_seq)
|
||||
@app.expects(:call).with(@env).in_sequence(before_seq)
|
||||
@instance.expects(:mount_shared_folders).once.in_sequence(before_seq)
|
||||
@instance.expects(:setup_unison).once.in_sequence(before_seq)
|
||||
|
||||
@instance.call(@env)
|
||||
end
|
||||
end
|
||||
|
||||
context "collecting shared folders" do
|
||||
setup do
|
||||
File.stubs(:expand_path).returns("baz")
|
||||
end
|
||||
|
||||
should "return a hash of the shared folders" do
|
||||
data = {
|
||||
"foo" => %W[bar baz],
|
||||
"bar" => %W[foo baz]
|
||||
}
|
||||
|
||||
stub_shared_folders do |config|
|
||||
data.each do |name, value|
|
||||
config.vm.share_folder(name, *value)
|
||||
end
|
||||
end
|
||||
|
||||
result = @instance.shared_folders
|
||||
assert_equal data.length, result.length
|
||||
data.each do |name, value|
|
||||
guest, host = value
|
||||
assert_equal guest, result[name][:guestpath]
|
||||
assert_equal host, result[name][:hostpath]
|
||||
end
|
||||
end
|
||||
|
||||
should "append sync suffix if sync enabled to a folder" do
|
||||
name = "foo"
|
||||
guest = "bar"
|
||||
host = "baz"
|
||||
|
||||
stub_shared_folders do |config|
|
||||
config.vm.share_folder(name, guest, host, :sync => true)
|
||||
end
|
||||
|
||||
result = @instance.shared_folders
|
||||
assert_equal "#{guest}#{@env.env.config.unison.folder_suffix}", result[name][:guestpath]
|
||||
assert_equal guest, result[name][:original][:guestpath]
|
||||
end
|
||||
|
||||
should "not destroy original hash" do
|
||||
@folders = stub_shared_folders do |config|
|
||||
config.vm.share_folder("foo", "bar", "baz", :sync => true)
|
||||
end
|
||||
|
||||
folder = @folders["foo"].dup
|
||||
|
||||
@instance.shared_folders
|
||||
assert_equal folder, @env.env.config.vm.shared_folders["foo"]
|
||||
end
|
||||
end
|
||||
|
||||
context "unison shared folders" do
|
||||
setup do
|
||||
@folders = stub_shared_folders do |config|
|
||||
config.vm.share_folder("foo", "bar", "baz", :sync => true)
|
||||
config.vm.share_folder("bar", "foo", "baz")
|
||||
end
|
||||
end
|
||||
|
||||
should "only return the folders marked for syncing" do
|
||||
result = @instance.unison_folders
|
||||
assert_equal 1, result.length
|
||||
assert result.has_key?("foo")
|
||||
assert !result.has_key?("bar")
|
||||
end
|
||||
end
|
||||
|
||||
context "clearing shared folders" do
|
||||
setup do
|
||||
@shared_folder = mock("shared_folder")
|
||||
@shared_folders = [@shared_folder]
|
||||
@internal_vm.stubs(:shared_folders).returns(@shared_folders)
|
||||
end
|
||||
|
||||
should "call destroy on each shared folder then reload" do
|
||||
destroy_seq = sequence("destroy")
|
||||
@shared_folders.each do |sf|
|
||||
sf.expects(:destroy).once.in_sequence(destroy_seq)
|
||||
end
|
||||
|
||||
@vm.expects(:reload!).once.in_sequence(destroy_seq)
|
||||
@instance.clear_shared_folders
|
||||
end
|
||||
|
||||
should "do nothing if no shared folders existed" do
|
||||
@shared_folders.clear
|
||||
@vm.expects(:reload!).never
|
||||
@instance.clear_shared_folders
|
||||
end
|
||||
end
|
||||
|
||||
context "setting up shared folder metadata" do
|
||||
setup do
|
||||
stub_shared_folders
|
||||
end
|
||||
|
||||
should "add all shared folders to the VM" do
|
||||
shared_folders = []
|
||||
data = %W[foo bar]
|
||||
shared_folders.expects(:<<).times(data.length).with() do |sf|
|
||||
hostpath = File.expand_path("#{sf.name}host", @env.env.root_path)
|
||||
assert data.include?(sf.name)
|
||||
assert_equal hostpath, sf.host_path
|
||||
true
|
||||
end
|
||||
|
||||
@internal_vm.stubs(:shared_folders).returns(shared_folders)
|
||||
@internal_vm.expects(:save).once
|
||||
|
||||
@instance.create_metadata
|
||||
end
|
||||
end
|
||||
|
||||
context "mounting the shared folders" do
|
||||
setup do
|
||||
@folders = stub_shared_folders
|
||||
@ssh = mock("ssh")
|
||||
@vm.ssh.stubs(:execute).yields(@ssh)
|
||||
@vm.system.stubs(:mount_shared_folder)
|
||||
end
|
||||
|
||||
should "mount all shared folders to the VM" do
|
||||
mount_seq = sequence("mount_seq")
|
||||
@folders.each do |name, data|
|
||||
@vm.system.expects(:mount_shared_folder).with(@ssh, name, data[:guestpath]).in_sequence(mount_seq)
|
||||
end
|
||||
|
||||
@instance.mount_shared_folders
|
||||
end
|
||||
end
|
||||
|
||||
context "setting up unison" do
|
||||
setup do
|
||||
@ssh = mock("ssh")
|
||||
@vm.ssh.stubs(:execute).yields(@ssh)
|
||||
|
||||
@folders = stub_shared_folders do |config|
|
||||
config.vm.share_folder("foo", "bar", "baz", :sync => true)
|
||||
config.vm.share_folder("bar", "foo", "baz")
|
||||
end
|
||||
end
|
||||
|
||||
should "do nothing if unison folders is empty" do
|
||||
@instance.stubs(:unison_folders).returns({})
|
||||
@vm.ssh.expects(:execute).never
|
||||
@instance.setup_unison
|
||||
end
|
||||
|
||||
should "prepare unison then create for each folder" do
|
||||
seq = sequence("unison seq")
|
||||
@vm.system.expects(:prepare_unison).with(@ssh).once.in_sequence(seq)
|
||||
@instance.unison_folders.each do |name, data|
|
||||
if data[:sync]
|
||||
@vm.system.expects(:create_unison).with do |ssh, opts|
|
||||
assert_equal @ssh, ssh
|
||||
assert_equal data, opts
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@instance.setup_unison
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue