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. # implementation class for the synced folders.
# #
# @return [Hash<Symbol, Hash<String, Hash>>] # @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] return cached_synced_folders(machine) if opts[:cached]
config = opts[:config]
config ||= machine.config.vm config ||= machine.config.vm
folders = {} folders = {}

View File

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

View File

@ -47,6 +47,19 @@ module VagrantPlugins
proxy_ui.opts[:prefix_spaces] = true proxy_ui.opts[:prefix_spaces] = true
proxy_ui.opts[:target] = env[:machine].name.to_s 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. # Sync some folders so that our volumes work later.
new_config = VagrantPlugins::Kernel_V2::VMConfig.new new_config = VagrantPlugins::Kernel_V2::VMConfig.new
our_folders = synced_folders(env[:machine]) our_folders = synced_folders(env[:machine])
@ -59,53 +72,59 @@ module VagrantPlugins
data.delete(:type) data.delete(:type)
end 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 # Generate a new guestpath
data[:docker_guestpath] = data[:guestpath] data[:docker_guestpath] = data[:guestpath]
data[:docker_sfid] = id
data[:guestpath] = "/mnt/docker_#{Time.now.to_i}_#{rand(100000)}" data[:guestpath] = "/mnt/docker_#{Time.now.to_i}_#{rand(100000)}"
data[:id] = data[:id] = id[0...6] + rand(10000).to_s
Digest::MD5.hexdigest(Time.now.to_i.to_s)[0...6] +
rand(10000).to_s
# Add this synced folder onto the new config # Add this synced folder onto the new config if we haven't
new_config.synced_folder( # already shared it before.
data[:hostpath], if !existing_ids.has_key?(id)
data[:guestpath], new_config.synced_folder(
data) 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 # Remove from our machine
env[:machine].config.vm.synced_folders.delete(id) env[:machine].config.vm.synced_folders.delete(id)
end
end
# Sync the folders! # Add the "fixed" folder to our machine
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|
data = data.merge({ data = data.merge({
hostpath_exact: true, hostpath_exact: true,
type: :docker, type: :docker,
}) })
env[:machine].config.vm.synced_folder( env[:machine].config.vm.synced_folder(
data[:guestpath], data[:guestpath],
data[:docker_guestpath], data[:docker_guestpath],
data) data)
end end
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 end
end end

View File

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