providers/docker: only sync folders if they're not already there

This commit is contained in:
Mitchell Hashimoto 2014-04-16 14:07:18 -07:00
parent 6883109d27
commit 704ff98200
4 changed files with 58 additions and 37 deletions

View File

@ -87,9 +87,10 @@ module Vagrant
# implementation class for the synced folders.
#
# @return [Hash<Symbol, Hash<String, Hash>>]
def synced_folders(machine, config=nil, **opts)
def synced_folders(machine, **opts)
return cached_synced_folders(machine) if opts[:cached]
config = opts[:config]
config ||= machine.config.vm
folders = {}

View File

@ -20,10 +20,11 @@ module Vagrant
def call(env)
opts = {
cached: !!env[:synced_folders_cached],
config: env[:synced_folders_config],
}
folders = synced_folders(
env[:machine], env[:synced_folders_config], **opts)
folders = synced_folders(env[:machine], **opts)
original_folders = folders
folders.each do |impl_name, fs|
@logger.info("Synced Folder Implementation: #{impl_name}")
@ -89,7 +90,7 @@ module Vagrant
end
# Save the synced folders
save_synced_folders(env[:machine], folders, merge: true)
save_synced_folders(env[:machine], original_folders, merge: true)
end
end
end

View File

@ -47,6 +47,19 @@ module VagrantPlugins
proxy_ui.opts[:prefix_spaces] = true
proxy_ui.opts[:target] = env[:machine].name.to_s
# Read the existing folders that are setup
existing_folders = synced_folders(host_machine, cached: true)
existing_ids = {}
if existing_folders
existing_folders.each do |impl, fs|
fs.each do |_name, data|
if data[:docker_sfid]
existing_ids[data[:docker_sfid]] = data
end
end
end
end
# Sync some folders so that our volumes work later.
new_config = VagrantPlugins::Kernel_V2::VMConfig.new
our_folders = synced_folders(env[:machine])
@ -59,53 +72,59 @@ module VagrantPlugins
data.delete(:type)
end
# Generate an ID that is deterministic based on our machine
# and Vagrantfile path...
id = Digest::MD5.hexdigest(
"#{env[:machine].env.root_path}#{env[:machine].name}")
# Generate a new guestpath
data[:docker_guestpath] = data[:guestpath]
data[:docker_sfid] = id
data[:guestpath] = "/mnt/docker_#{Time.now.to_i}_#{rand(100000)}"
data[:id] =
Digest::MD5.hexdigest(Time.now.to_i.to_s)[0...6] +
rand(10000).to_s
data[:id] = id[0...6] + rand(10000).to_s
# Add this synced folder onto the new config
new_config.synced_folder(
data[:hostpath],
data[:guestpath],
data)
# Add this synced folder onto the new config if we haven't
# already shared it before.
if !existing_ids.has_key?(id)
new_config.synced_folder(
data[:hostpath],
data[:guestpath],
data)
else
# We already have the folder, so just load its data
data = existing_ids[id]
end
# Remove from our machine
env[:machine].config.vm.synced_folders.delete(id)
end
end
# Sync the folders!
env[:machine].ui.output(I18n.t(
"docker_provider.host_machine_syncing_folders"))
host_machine.with_ui(proxy_ui) do
action_env = { synced_folders_config: new_config }
begin
host_machine.action(:sync_folders, action_env)
rescue Vagrant::Errors::UnimplementedProviderAction
callable = Vagrant::Action::Builder.new
callable.use Vagrant::Action::Builtin::SyncedFolders
host_machine.action_raw(:sync_folders, callable, action_env)
end
end
# Re-add to our machine the "fixed" synced folders
new_folders = synced_folders(host_machine, new_config)
new_folders.each do |_type, folders|
folders.each do |id, data|
# Add the "fixed" folder to our machine
data = data.merge({
hostpath_exact: true,
type: :docker,
})
env[:machine].config.vm.synced_folder(
data[:guestpath],
data[:docker_guestpath],
data)
end
end
if !new_config.synced_folders.empty?
# Sync the folders!
env[:machine].ui.output(I18n.t(
"docker_provider.host_machine_syncing_folders"))
host_machine.with_ui(proxy_ui) do
action_env = { synced_folders_config: new_config }
begin
host_machine.action(:sync_folders, action_env)
rescue Vagrant::Errors::UnimplementedProviderAction
callable = Vagrant::Action::Builder.new
callable.use Vagrant::Action::Builtin::SyncedFolders
host_machine.action_raw(:sync_folders, callable, action_env)
end
end
end
end
end
end

View File

@ -101,7 +101,7 @@ describe Vagrant::Action::Builtin::MixinSyncedFolders do
other = double("config")
other.stub(synced_folders: other_folders)
result = subject.synced_folders(machine, other)
result = subject.synced_folders(machine, config: other)
expect(result.length).to eq(1)
expect(result[:default]).to eq({
"bar" => other_folders["bar"],
@ -137,7 +137,7 @@ describe Vagrant::Action::Builtin::MixinSyncedFolders do
end
it "returns nil if cached read with no cache" do
result = subject.synced_folders(machine, nil, cached: true)
result = subject.synced_folders(machine, cached: true)
expect(result).to be_nil
end
@ -154,7 +154,7 @@ describe Vagrant::Action::Builtin::MixinSyncedFolders do
old_folders = folders.dup
folders.clear
result = subject.synced_folders(machine, nil, cached: true)
result = subject.synced_folders(machine, cached: true)
expect(result.length).to eq(2)
expect(result[:default]).to eq({
"another" => old_folders["another"],
@ -180,7 +180,7 @@ describe Vagrant::Action::Builtin::MixinSyncedFolders do
folders.clear
# Read them all back
result = subject.synced_folders(machine, nil, cached: true)
result = subject.synced_folders(machine, cached: true)
expect(result.length).to eq(2)
expect(result[:default]).to eq({
"foo" => { type: "default" },