diff --git a/plugins/provisioners/chef/config/base.rb b/plugins/provisioners/chef/config/base.rb index 4adb0d148..370736fd6 100644 --- a/plugins/provisioners/chef/config/base.rb +++ b/plugins/provisioners/chef/config/base.rb @@ -1,11 +1,7 @@ -require "vagrant/util/counter" - module VagrantPlugins module Chef module Config class Base < Vagrant.plugin("2", :config) - extend Vagrant::Util::Counter - # The path to Chef's bin/ directory. # @return [String] attr_accessor :binary_path @@ -48,11 +44,11 @@ module VagrantPlugins # @return [String] attr_accessor :version - # The path where the Chef installer will be downloaded to. Only valid if + # The path where the Chef installer will be downloaded to. Only valid if # install is true or "force". It defaults to nil, which means that the - # omnibus installer will choose the destination and you have no control - # over it. - # + # omnibus installer will choose the destination and you have no control + # over it. + # # @return [String] attr_accessor :installer_download_path diff --git a/plugins/provisioners/chef/config/base_runner.rb b/plugins/provisioners/chef/config/base_runner.rb index 334c9b739..12ac0aabd 100644 --- a/plugins/provisioners/chef/config/base_runner.rb +++ b/plugins/provisioners/chef/config/base_runner.rb @@ -81,7 +81,7 @@ module VagrantPlugins @https_proxy_pass = nil if @https_proxy_pass == UNSET_VALUE @no_proxy = nil if @no_proxy == UNSET_VALUE @node_name = nil if @node_name == UNSET_VALUE - @provisioning_path = nil if @provisioning_path == UNSET_VALUE + @provisioning_path = "/tmp/vagrant-chef" if @provisioning_path == UNSET_VALUE @file_backup_path = "/var/chef/backup" if @file_backup_path == UNSET_VALUE @file_cache_path = "/var/chef/cache" if @file_cache_path == UNSET_VALUE @verbose_logging = false if @verbose_logging == UNSET_VALUE @@ -89,12 +89,6 @@ module VagrantPlugins if @encrypted_data_bag_secret_key_path == UNSET_VALUE @encrypted_data_bag_secret_key_path = nil end - - # Set the default provisioning path to be a unique path in /tmp - if !@provisioning_path - counter = self.class.get_and_update_counter(:chef_config) - @provisioning_path = "/tmp/vagrant-chef-#{counter}" - end end def merge(other) diff --git a/plugins/provisioners/chef/provisioner/chef_solo.rb b/plugins/provisioners/chef/provisioner/chef_solo.rb index af9314bd9..18bdc9e1d 100644 --- a/plugins/provisioners/chef/provisioner/chef_solo.rb +++ b/plugins/provisioners/chef/provisioner/chef_solo.rb @@ -1,3 +1,7 @@ +require "digest/md5" +require "securerandom" +require "set" + require "log4r" require "vagrant/util/counter" @@ -11,6 +15,8 @@ module VagrantPlugins class ChefSolo < Base extend Vagrant::Util::Counter include Vagrant::Util::Counter + include Vagrant::Action::Builtin::MixinSyncedFolders + attr_reader :environments_folders attr_reader :cookbook_folders attr_reader :role_folders @@ -28,10 +34,11 @@ module VagrantPlugins @data_bags_folders = expanded_folders(@config.data_bags_path, "data_bags") @environments_folders = expanded_folders(@config.environments_path, "environments") - share_folders(root_config, "csc", @cookbook_folders) - share_folders(root_config, "csr", @role_folders) - share_folders(root_config, "csdb", @data_bags_folders) - share_folders(root_config, "cse", @environments_folders) + existing = synced_folders(@machine, cached: true) + share_folders(root_config, "csc", @cookbook_folders, existing) + share_folders(root_config, "csr", @role_folders, existing) + share_folders(root_config, "csdb", @data_bags_folders, existing) + share_folders(root_config, "cse", @environments_folders, existing) end def provision(mode = :solo) @@ -72,8 +79,10 @@ module VagrantPlugins local_path = File.expand_path(path, @machine.env.root_path) if File.exist?(local_path) - # Path exists on the host, setup the remote path - remote_path = "#{@config.provisioning_path}/chef-solo-#{get_and_update_counter(:cookbooks_path)}" + # Path exists on the host, setup the remote path. We use + # the MD5 of the local path so that it is predictable. + key = Digest::MD5.hexdigest(local_path) + remote_path = "#{@config.provisioning_path}/#{key}" else @machine.ui.warn(I18n.t("vagrant.provisioners.chef.cookbook_folder_not_found_warning", path: local_path.to_s)) @@ -103,16 +112,31 @@ module VagrantPlugins # Shares the given folders with the given prefix. The folders should # be of the structure resulting from the `expanded_folders` function. - def share_folders(root_config, prefix, folders) - folders.each do |type, local_path, remote_path| - if type == :host - opts = {} - opts[:id] = "v-#{prefix}-#{self.class.get_and_update_counter(:shared_folder)}" - opts[:type] = @config.synced_folder_type if @config.synced_folder_type - - root_config.vm.synced_folder(local_path, remote_path, opts) + def share_folders(root_config, prefix, folders, existing=nil) + existing_set = Set.new + (existing || []).each do |_, fs| + fs.each do |id, data| + existing_set.add(data[:guestpath]) end end + + folders.each do |type, local_path, remote_path| + next if type != :host + + # If this folder already exists, then we don't share it, it means + # it was already put down on disk. + if existing_set.include?(remote_path) + @logger.debug("Not sharing #{local_path}, exists as #{remote_path}") + next + end + + opts = {} + opts[:id] = "v-#{prefix}-#{self.class.get_and_update_counter(:shared_folder)}" + opts[:type] = @config.synced_folder_type if @config.synced_folder_type + + root_config.vm.synced_folder(local_path, remote_path, opts) + end + @shared_folders += folders end