From 704ff9820079a8b7827cd5dc0e00d0be3d821f61 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 16 Apr 2014 14:07:18 -0700 Subject: [PATCH] providers/docker: only sync folders if they're not already there --- .../action/builtin/mixin_synced_folders.rb | 3 +- lib/vagrant/action/builtin/synced_folders.rb | 7 +- .../action/host_machine_sync_folders.rb | 77 ++++++++++++------- .../builtin/mixin_synced_folders_test.rb | 8 +- 4 files changed, 58 insertions(+), 37 deletions(-) diff --git a/lib/vagrant/action/builtin/mixin_synced_folders.rb b/lib/vagrant/action/builtin/mixin_synced_folders.rb index 949ec8444..d2dc76730 100644 --- a/lib/vagrant/action/builtin/mixin_synced_folders.rb +++ b/lib/vagrant/action/builtin/mixin_synced_folders.rb @@ -87,9 +87,10 @@ module Vagrant # implementation class for the synced folders. # # @return [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 = {} diff --git a/lib/vagrant/action/builtin/synced_folders.rb b/lib/vagrant/action/builtin/synced_folders.rb index 2980a3c25..6369195f0 100644 --- a/lib/vagrant/action/builtin/synced_folders.rb +++ b/lib/vagrant/action/builtin/synced_folders.rb @@ -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 diff --git a/plugins/providers/docker/action/host_machine_sync_folders.rb b/plugins/providers/docker/action/host_machine_sync_folders.rb index 07011f80c..14f5fb16b 100644 --- a/plugins/providers/docker/action/host_machine_sync_folders.rb +++ b/plugins/providers/docker/action/host_machine_sync_folders.rb @@ -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 diff --git a/test/unit/vagrant/action/builtin/mixin_synced_folders_test.rb b/test/unit/vagrant/action/builtin/mixin_synced_folders_test.rb index 769d2c385..d588879b9 100644 --- a/test/unit/vagrant/action/builtin/mixin_synced_folders_test.rb +++ b/test/unit/vagrant/action/builtin/mixin_synced_folders_test.rb @@ -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" },