diff --git a/lib/vagrant/action/builtin/mixin_synced_folders.rb b/lib/vagrant/action/builtin/mixin_synced_folders.rb index 0faa6ecab..67692d61a 100644 --- a/lib/vagrant/action/builtin/mixin_synced_folders.rb +++ b/lib/vagrant/action/builtin/mixin_synced_folders.rb @@ -1,3 +1,5 @@ +require "json" + require 'vagrant/util/scoped_hash_override' module Vagrant @@ -54,12 +56,26 @@ module Vagrant @plugins ||= Vagrant.plugin("2").manager.synced_folders end + # This saves the synced folders data to the machine data directory. + # They can then be retrieved again with `synced_folders` by passing + # the `cached` option to it. + # + # @param [Machine] machine The machine that the folders belong to + # @param [Hash] folders The result from a {#synced_folders} call. + def save_synced_folders(machine, folders) + machine.data_dir.join("synced_folders").open("w") do |f| + f.write(JSON.dump(folders)) + end + end + # This returns the set of shared folders that should be done for # this machine. It returns the folders in a hash keyed by the # implementation class for the synced folders. # # @return [Hash>] - def synced_folders(machine, config=nil) + def synced_folders(machine, config=nil, **opts) + return cached_synced_folders(machine) if opts[:cached] + config ||= machine.config.vm folders = {} @@ -119,6 +135,26 @@ module Vagrant return folders end + + protected + + def cached_synced_folders(machine) + JSON.parse(machine.data_dir.join("synced_folders").read).tap do |r| + # We have to do all sorts of things to make the proper things + # symbols and + r.keys.each do |k| + r[k].each do |ik, v| + v.keys.each do |vk| + v[vk.to_sym] = v[vk] + v.delete(vk) + end + end + + r[k.to_sym] = r[k] + r.delete(k) + 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 7bd5ccbfa..802d6c01f 100644 --- a/test/unit/vagrant/action/builtin/mixin_synced_folders_test.rb +++ b/test/unit/vagrant/action/builtin/mixin_synced_folders_test.rb @@ -1,3 +1,5 @@ +require "tmpdir" + require File.expand_path("../../../../base", __FILE__) require "vagrant/action/builtin/mixin_synced_folders" @@ -12,8 +14,11 @@ describe Vagrant::Action::Builtin::MixinSyncedFolders do end let(:machine) do + data_dir = Pathname.new(Dir.mktmpdir) + double("machine").tap do |machine| allow(machine).to receive(:config).and_return(machine_config) + allow(machine).to receive(:data_dir).and_return(data_dir) end end @@ -130,5 +135,28 @@ describe Vagrant::Action::Builtin::MixinSyncedFolders do result = subject.synced_folders(machine) expect(result[:nfs]["root"][:foo]).to eql("bar") end + + it "should be able to save and retrieve cached versions" do + folders["root"] = {} + folders["another"] = { type: "" } + folders["foo"] = { type: "default" } + folders["nfs"] = { type: "nfs" } + + result = subject.synced_folders(machine) + subject.save_synced_folders(machine, result) + + # Clear the folders so we know its reading from cache + old_folders = folders.dup + folders.clear + + result = subject.synced_folders(machine, nil, cached: true) + expect(result.length).to eq(2) + expect(result[:default]).to eq({ + "another" => old_folders["another"], + "foo" => old_folders["foo"], + "root" => old_folders["root"], + }) + expect(result[:nfs]).to eq({ "nfs" => old_folders["nfs"] }) + end end end