From b1548a2eb68ad89daf397a0b59e79c2561802b0e Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Wed, 5 Jul 2017 16:22:59 -0700 Subject: [PATCH] (#5160) Only rsync-auto current working dir with docker provider Prior to this commit, when users invoked the `rsync-auto` command using the docker provider with boot2docker, vagrant would rsync all known containers using the boot2docker vm rather than the current working dir. This commit updates that behavior to ensure that only the current working dirs vagrant machines will be rsynced. --- .../rsync/command/rsync_auto.rb | 18 +++++ templates/locales/en.yml | 2 + .../rsync/command/rsync_auto_test.rb | 78 +++++++++++++++---- 3 files changed, 82 insertions(+), 16 deletions(-) diff --git a/plugins/synced_folders/rsync/command/rsync_auto.rb b/plugins/synced_folders/rsync/command/rsync_auto.rb index 407b7f368..8b84f8ed3 100644 --- a/plugins/synced_folders/rsync/command/rsync_auto.rb +++ b/plugins/synced_folders/rsync/command/rsync_auto.rb @@ -48,6 +48,9 @@ module VagrantPlugins paths = {} ignores = [] with_target_vms(argv) do |machine| + next if machine.state.id == :not_created + cwd = machine.env.cwd.to_s + if machine.provider.capability?(:proxy_machine) proxy = machine.provider.capability(:proxy_machine) if proxy @@ -70,6 +73,21 @@ module VagrantPlugins folders = cached[:rsync] next if !folders || folders.empty? + # NOTE: This check is required with boot2docker since all containers + # share the same virtual machine. This prevents rsync-auto from + # syncing all known containers with rsync to the boot2docker vm + # and only syncs the current working dirs folders. + sync_folders = {} + folders.each do |id, folder_opts| + if cwd != folder_opts[:hostpath] + machine.ui.info(I18n.t("vagrant.rsync_auto_remove_folder", + folder: folder_opts[:hostpath])) + else + sync_folders[id] = folder_opts + end + end + folders = sync_folders + # Get the SSH info for this machine so we can do an initial # sync to the VM. ssh_info = machine.ssh_info diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 26d756564..deae43256 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -218,6 +218,8 @@ en: have specified `rsync_auto` to be false. rsync_auto_path: |- Watching: %{path} + rsync_auto_remove_folder: |- + Not syncing %{folder} as it is not part of the current working directory. rsync_auto_rsync_error: |- There was an error while executing rsync. The error is shown below. This may not be critical since rsync sometimes fails, but if this message diff --git a/test/unit/plugins/synced_folders/rsync/command/rsync_auto_test.rb b/test/unit/plugins/synced_folders/rsync/command/rsync_auto_test.rb index b1e1a7451..a6aafaa4b 100644 --- a/test/unit/plugins/synced_folders/rsync/command/rsync_auto_test.rb +++ b/test/unit/plugins/synced_folders/rsync/command/rsync_auto_test.rb @@ -13,31 +13,77 @@ describe VagrantPlugins::SyncedFolderRSync::Command::RsyncAuto do env.create_vagrant_env end - let(:synced_folders) { {} } + let(:synced_folders_empty) { {} } + let(:synced_folders_dupe) { {"1234": + {type: "rsync", + exclude: false, + hostpath: "/Users/brian/code/vagrant-sandbox"}, + "5678": + {type: "rsync", + exclude: false, + hostpath: "/Not/The/Same/Path"}} } let(:helper_class) { VagrantPlugins::SyncedFolderRSync::RsyncHelper } + let(:paths) { {} } + let(:ssh_info) {{}} + + def machine_stub(name) + double(name).tap do |m| + m.stub(id: "foo") + m.stub(reload: nil) + m.stub(ssh_info: ssh_info) + m.stub(ui: iso_env.ui) + m.stub(provider: double("provider")) + m.stub(state: double("state", id: :not_created)) + m.stub(env: iso_env) + + m.ui.stub(error: nil) + end + end + + subject do + described_class.new(argv, iso_env).tap + end + + + describe "#execute" do + let (:machine) { machine_stub("m") } + let (:cached_folders) { { rsync: synced_folders_dupe } } + + before do + allow(subject).to receive(:with_target_vms) { |&block| block.call machine } + end + + it "does not sync folders outside of the cwd" do + allow(machine.ui).to receive(:info) + allow(machine.state).to receive(:id).and_return(:created) + allow(machine.env).to receive(:cwd). + and_return("/Users/brian/code/vagrant-sandbox") + allow(machine.provider).to receive(:capability?).and_return(false) + + allow(subject).to receive(:synced_folders). + with(machine, cached: true).and_return(cached_folders) + allow(helper_class).to receive(:rsync_single).and_return(true) + allow(Vagrant::Util::Busy).to receive(:busy).and_return(true) + allow(Listen).to receive(:to).and_return(true) + + + expect(machine.ui).to receive(:info). + with("Not syncing /Not/The/Same/Path as it is not part of the current working directory.") + expect(helper_class).to receive(:rsync_single) + + subject.execute() + end + end + subject do described_class.new(argv, iso_env).tap do |s| - s.stub(synced_folders: synced_folders) + s.stub(synced_folders: synced_folders_empty) end end describe "#callback" do - let(:paths) { {} } - let(:ssh_info) {{}} - - def machine_stub(name) - double(name).tap do |m| - m.stub(id: "foo") - m.stub(reload: nil) - m.stub(ssh_info: ssh_info) - m.stub(ui: double("ui")) - - m.ui.stub(error: nil) - end - end - it "syncs modified folders to the proper path" do paths["/foo"] = [ { machine: machine_stub("m1"), opts: double("opts_m1") },