synced_folders/rsync: only chown when necessary [GH-3525]
Run remote rsync as root to guarantee that rsync can write to guestpath. This obviates the need to chown the guestpath to the SSH user prior to sync. This brings a substantial speedup (2x on a moderately-sized shared folder) and properly triggers filesystem notifications on only the files changed by a given sync.
This commit is contained in:
parent
75ee7425f5
commit
2df36892dd
|
@ -6,13 +6,14 @@ module VagrantPlugins
|
|||
machine.communicate.test("which rsync")
|
||||
end
|
||||
|
||||
def self.rsync_pre(machine, folder_opts)
|
||||
username = machine.ssh_info[:username]
|
||||
def self.rsync_command(machine)
|
||||
"sudo rsync"
|
||||
end
|
||||
|
||||
machine.communicate.tap do |comm|
|
||||
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
|
||||
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
|
||||
end
|
||||
def self.rsync_post(machine, opts)
|
||||
machine.communicate.sudo(
|
||||
"find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
|
||||
"xargs -0 -r chown -v #{opts[:owner]}:#{opts[:group]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,7 +41,12 @@ module VagrantPlugins
|
|||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("darwin", "rsync_pre") do
|
||||
guest_capability("darwin", "rsync_command") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("darwin", "rsync_post") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
|
|
@ -12,13 +12,14 @@ module VagrantPlugins
|
|||
machine.communicate.test("which rsync")
|
||||
end
|
||||
|
||||
def self.rsync_pre(machine, folder_opts)
|
||||
username = machine.ssh_info[:username]
|
||||
def self.rsync_command(machine)
|
||||
"sudo rsync"
|
||||
end
|
||||
|
||||
machine.communicate.tap do |comm|
|
||||
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'", shell: "sh")
|
||||
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'", shell: "sh")
|
||||
end
|
||||
def self.rsync_post(machine, opts)
|
||||
machine.communicate.sudo(
|
||||
"find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
|
||||
"xargs -0 -r chown -v #{opts[:owner]}:#{opts[:group]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,7 +46,12 @@ module VagrantPlugins
|
|||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("freebsd", "rsync_pre") do
|
||||
guest_capability("freebsd", "rsync_command") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("freebsd", "rsync_post") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
|
|
@ -6,21 +6,14 @@ module VagrantPlugins
|
|||
machine.communicate.test("which rsync")
|
||||
end
|
||||
|
||||
def self.rsync_pre(machine, opts)
|
||||
username = machine.ssh_info[:username]
|
||||
|
||||
machine.communicate.tap do |comm|
|
||||
comm.sudo("mkdir -p '#{opts[:guestpath]}'")
|
||||
comm.sudo("find '#{opts[:guestpath]}' ! -user #{username} -print0 | " +
|
||||
"xargs -0 -r chown -v #{username}:")
|
||||
end
|
||||
def self.rsync_command(machine)
|
||||
"sudo rsync"
|
||||
end
|
||||
|
||||
def self.rsync_post(machine, opts)
|
||||
machine.communicate.tap do |comm|
|
||||
comm.sudo("find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
|
||||
"xargs -0 -r chown -v #{opts[:owner]}:#{opts[:group]}")
|
||||
end
|
||||
machine.communicate.sudo(
|
||||
"find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
|
||||
"xargs -0 -r chown -v #{opts[:owner]}:#{opts[:group]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -67,12 +67,12 @@ module VagrantPlugins
|
|||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("linux", "rsync_post") do
|
||||
guest_capability("linux", "rsync_command") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("linux", "rsync_pre") do
|
||||
guest_capability("linux", "rsync_post") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
|
|
@ -13,13 +13,14 @@ module VagrantPlugins
|
|||
'pkg_add rsync')
|
||||
end
|
||||
|
||||
def self.rsync_pre(machine, folder_opts)
|
||||
username = machine.ssh_info[:username]
|
||||
def self.rsync_command(machine)
|
||||
"sudo rsync"
|
||||
end
|
||||
|
||||
machine.communicate.tap do |comm|
|
||||
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
|
||||
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
|
||||
end
|
||||
def self.rsync_post(machine, opts)
|
||||
machine.communicate.sudo(
|
||||
"find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
|
||||
"xargs -0 -r chown -v #{opts[:owner]}:#{opts[:group]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,7 +46,12 @@ module VagrantPlugins
|
|||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("netbsd", "rsync_pre") do
|
||||
guest_capability("netbsd", "rsync_command") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("netbsd", "rsync_post") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
|
|
@ -13,13 +13,14 @@ module VagrantPlugins
|
|||
machine.communicate.test("which rsync")
|
||||
end
|
||||
|
||||
def self.rsync_pre(machine, folder_opts)
|
||||
username = machine.ssh_info[:username]
|
||||
def self.rsync_command(machine)
|
||||
"sudo rsync"
|
||||
end
|
||||
|
||||
machine.communicate.tap do |comm|
|
||||
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
|
||||
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
|
||||
end
|
||||
def self.rsync_post(machine, opts)
|
||||
machine.communicate.sudo(
|
||||
"find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
|
||||
"xargs -0 -r chown -v #{opts[:owner]}:#{opts[:group]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,7 +46,12 @@ module VagrantPlugins
|
|||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("openbsd", "rsync_pre") do
|
||||
guest_capability("openbsd", "rsync_command") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("openbsd", "rsync_post") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
|
|
@ -6,14 +6,13 @@ module VagrantPlugins
|
|||
machine.communicate.test("which rsync")
|
||||
end
|
||||
|
||||
def self.rsync_pre(machine, folder_opts)
|
||||
username = machine.ssh_info[:username]
|
||||
sudo = machine.config.smartos.suexec_cmd
|
||||
def self.rsync_command(machine)
|
||||
"#{machine.config.smartos.suexec_cmd} rsync"
|
||||
end
|
||||
|
||||
machine.communicate.tap do |comm|
|
||||
comm.execute("#{sudo} mkdir -p '#{folder_opts[:guestpath]}'")
|
||||
comm.execute("#{sudo} chown -R #{username} '#{folder_opts[:guestpath]}'")
|
||||
end
|
||||
def self.rsync_post(machine, opts)
|
||||
machine.communicate.sudo("find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
|
||||
"xargs -0 -r chown -v #{opts[:owner]}:#{opts[:group]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,7 +41,12 @@ module VagrantPlugins
|
|||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("smartos", "rsync_pre") do
|
||||
guest_capability("smartos", "rsync_command") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("smartos", "rsync_post") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
|
|
@ -6,13 +6,15 @@ module VagrantPlugins
|
|||
machine.communicate.test("which rsync")
|
||||
end
|
||||
|
||||
def self.rsync_pre(machine, folder_opts)
|
||||
username = machine.ssh_info[:username]
|
||||
def self.rsync_command(machine)
|
||||
"#{machine.config.solaris.suexec_cmd} rsync"
|
||||
end
|
||||
|
||||
machine.communicate.tap do |comm|
|
||||
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
|
||||
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
|
||||
end
|
||||
def self.rsync_post(machine, opts)
|
||||
su_cmd = machine.config.solaris.su_cmd
|
||||
machine.communicate.execute(
|
||||
"#{su_cmd} find '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
|
||||
"xargs -0 -r chown -v #{opts[:owner]}:#{opts[:group]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,7 +41,12 @@ module VagrantPlugins
|
|||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("solaris", "rsync_pre") do
|
||||
guest_capability("solaris", "rsync_command") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
||||
guest_capability("solaris", "rsync_post") do
|
||||
require_relative "cap/rsync"
|
||||
Cap::RSync
|
||||
end
|
||||
|
|
|
@ -6,13 +6,15 @@ module VagrantPlugins
|
|||
machine.communicate.test("which rsync")
|
||||
end
|
||||
|
||||
def self.rsync_pre(machine, folder_opts)
|
||||
username = machine.ssh_info[:username]
|
||||
def self.rsync_command(machine)
|
||||
"#{machine.config.solaris11.suexec_cmd} rsync"
|
||||
end
|
||||
|
||||
machine.communicate.tap do |comm|
|
||||
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
|
||||
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
|
||||
end
|
||||
def self.rsync_post(machine, opts)
|
||||
su_cmd = machine.config.solaris11.su_cmd
|
||||
machine.communicate.execute(
|
||||
"#{su_cmd} '#{opts[:guestpath]}' '(' ! -user #{opts[:owner]} -or ! -group #{opts[:group]} ')' -print0 | " +
|
||||
"xargs -0 -r chown -v #{opts[:owner]}:#{opts[:group]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -84,6 +84,17 @@ module VagrantPlugins
|
|||
args << "--no-perms" if args.include?("--archive") || args.include?("-a")
|
||||
end
|
||||
|
||||
# Disable rsync's owner/group preservation (implied by --archive) unless
|
||||
# specifically requested, since we adjust owner/group to match shared
|
||||
# folder setting ourselves.
|
||||
args << "--no-owner" unless args.include?("--owner") || args.include?("-o")
|
||||
args << "--no-group" unless args.include?("--group") || args.include?("-g")
|
||||
|
||||
# Tell local rsync how to invoke remote rsync with sudo
|
||||
if machine.guest.capability?(:rsync_command)
|
||||
args << "--rsync-path"<< machine.guest.capability(:rsync_command)
|
||||
end
|
||||
|
||||
# Build up the actual command to execute
|
||||
command = [
|
||||
"rsync",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require File.expand_path("../../../../../base", __FILE__)
|
||||
|
||||
describe "VagrantPlugins::VagrantPlugins::Cap::Rsync" do
|
||||
let(:plugin) { VagrantPlugins::GuestSmartos::Plugin.components.guest_capabilities[:smartos].get(:rsync_pre) }
|
||||
let(:plugin) { VagrantPlugins::GuestSmartos::Plugin.components.guest_capabilities[:smartos].get(:rsync_installed) }
|
||||
let(:machine) { double("machine") }
|
||||
let(:config) { double("config", smartos: VagrantPlugins::GuestSmartos::Config.new) }
|
||||
let(:communicator) { VagrantTests::DummyCommunicator::Communicator.new(machine) }
|
||||
|
@ -30,23 +30,5 @@ describe "VagrantPlugins::VagrantPlugins::Cap::Rsync" do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".rsync_pre" do
|
||||
let(:username) { "some_user" }
|
||||
|
||||
before do
|
||||
machine.stub(:ssh_info).and_return({username: username})
|
||||
end
|
||||
|
||||
it "creates a local directory" do
|
||||
communicator.expect_command(%Q(pfexec mkdir -p '/mountpoint'))
|
||||
plugin.rsync_pre(machine, {guestpath: '/mountpoint'})
|
||||
end
|
||||
|
||||
it "chowns local directory to ssh user" do
|
||||
communicator.expect_command(%Q(pfexec chown -R #{username} '/mountpoint'))
|
||||
plugin.rsync_pre(machine, {guestpath: '/mountpoint'})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue