synced_folders/rsync: Install `rsync` on guest if needed

Add new `rsync_installed` and `rsync_install` guest capabilities
to detect and install `rsync`.

Also copy `rsync_pre` capability to all Unix guests.
This commit is contained in:
Teemu Matilainen 2014-01-31 00:26:43 -03:00
parent 8cc7d00314
commit ee2ae94c25
22 changed files with 309 additions and 1 deletions

View File

@ -432,6 +432,10 @@ module Vagrant
error_key(:rsync_not_found) error_key(:rsync_not_found)
end end
class RSyncNotInstalledInGuest < VagrantError
error_key(:rsync_not_installed_in_guest)
end
class SCPPermissionDenied < VagrantError class SCPPermissionDenied < VagrantError
error_key(:scp_permission_denied) error_key(:scp_permission_denied)
end end

View File

@ -0,0 +1,20 @@
module VagrantPlugins
module GuestDarwin
module Cap
class RSync
def self.rsync_installed(machine)
machine.communicate.test("which rsync")
end
def self.rsync_pre(machine, folder_opts)
username = machine.ssh_info[:username]
machine.communicate.tap do |comm|
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
end
end
end
end
end
end

View File

@ -36,6 +36,16 @@ module VagrantPlugins
Cap::MountVmwareSharedFolder Cap::MountVmwareSharedFolder
end end
guest_capability("darwin", "rsync_installed") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("darwin", "rsync_pre") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("darwin", "shell_expand_guest_path") do guest_capability("darwin", "shell_expand_guest_path") do
require_relative "cap/shell_expand_guest_path" require_relative "cap/shell_expand_guest_path"
Cap::ShellExpandGuestPath Cap::ShellExpandGuestPath

View File

@ -0,0 +1,14 @@
module VagrantPlugins
module GuestDebian
module Cap
class RSync
def self.rsync_install(machine)
machine.communicate.tap do |comm|
comm.sudo("apt-get -y update")
comm.sudo("apt-get -y install rsync")
end
end
end
end
end
end

View File

@ -25,6 +25,11 @@ module VagrantPlugins
require_relative "cap/nfs_client" require_relative "cap/nfs_client"
Cap::NFSClient Cap::NFSClient
end end
guest_capability("debian", "rsync_install") do
require_relative "cap/rsync"
Cap::RSync
end
end end
end end
end end

View File

@ -0,0 +1,26 @@
module VagrantPlugins
module GuestFreeBSD
module Cap
class RSync
def self.rsync_install(machine)
machine.communicate.tap do |comm|
comm.sudo("pkg_add -r rsync")
end
end
def self.rsync_installed(machine)
machine.communicate.test("which rsync")
end
def self.rsync_pre(machine, folder_opts)
username = machine.ssh_info[:username]
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
end
end
end
end
end

View File

@ -30,6 +30,21 @@ module VagrantPlugins
require_relative "cap/mount_nfs_folder" require_relative "cap/mount_nfs_folder"
Cap::MountNFSFolder Cap::MountNFSFolder
end end
guest_capability("freebsd", "rsync_install") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("freebsd", "rsync_installed") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("freebsd", "rsync_pre") do
require_relative "cap/rsync"
Cap::RSync
end
end end
end end
end end

View File

@ -2,6 +2,10 @@ module VagrantPlugins
module GuestLinux module GuestLinux
module Cap module Cap
class RSync class RSync
def self.rsync_installed(machine)
machine.communicate.test("which rsync")
end
def self.rsync_pre(machine, folder_opts) def self.rsync_pre(machine, folder_opts)
username = machine.ssh_info[:username] username = machine.ssh_info[:username]

View File

@ -46,7 +46,11 @@ module VagrantPlugins
Cap::ReadIPAddress Cap::ReadIPAddress
end end
# RSync synced folders guest_capability("linux", "rsync_installed") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("linux", "rsync_pre") do guest_capability("linux", "rsync_pre") do
require_relative "cap/rsync" require_relative "cap/rsync"
Cap::RSync Cap::RSync

View File

@ -0,0 +1,27 @@
module VagrantPlugins
module GuestNetBSD
module Cap
class RSync
def self.rsync_installed(machine)
machine.communicate.test("which rsync")
end
def self.rsync_install(machine)
machine.communicate.sudo(
'export PKG_PATH="http://ftp.NetBSD.org/pub/pkgsrc/packages/NetBSD/' \
'`uname -m`/`uname -r | cut -d. -f1-2`/All"; ' \
'pkg_add rsync')
end
def self.rsync_pre(machine, folder_opts)
username = machine.ssh_info[:username]
machine.communicate.tap do |comm|
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
end
end
end
end
end
end

View File

@ -30,6 +30,21 @@ module VagrantPlugins
require_relative "cap/mount_nfs_folder" require_relative "cap/mount_nfs_folder"
Cap::MountNFSFolder Cap::MountNFSFolder
end end
guest_capability("netbsd", "rsync_install") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("netbsd", "rsync_installed") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("netbsd", "rsync_pre") do
require_relative "cap/rsync"
Cap::RSync
end
end end
end end
end end

View File

@ -0,0 +1,26 @@
module VagrantPlugins
module GuestOpenBSD
module Cap
class RSync
def self.rsync_install(machine)
machine.communicate.tap do |comm|
comm.sudo("pkg_add -I rsync--")
end
end
def self.rsync_installed(machine)
machine.communicate.test("which rsync")
end
def self.rsync_pre(machine, folder_opts)
username = machine.ssh_info[:username]
machine.communicate.tap do |comm|
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
end
end
end
end
end
end

View File

@ -30,6 +30,21 @@ module VagrantPlugins
require_relative "cap/mount_nfs_folder" require_relative "cap/mount_nfs_folder"
Cap::MountNFSFolder Cap::MountNFSFolder
end end
guest_capability("openbsd", "rsync_install") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("openbsd", "rsync_installed") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("openbsd", "rsync_pre") do
require_relative "cap/rsync"
Cap::RSync
end
end end
end end
end end

View File

@ -0,0 +1,13 @@
module VagrantPlugins
module GuestRedHat
module Cap
class RSync
def self.rsync_install(machine)
machine.communicate.tap do |comm|
comm.sudo("yum -y install rsync")
end
end
end
end
end
end

View File

@ -30,6 +30,11 @@ module VagrantPlugins
require_relative "cap/nfs_client" require_relative "cap/nfs_client"
Cap::NFSClient Cap::NFSClient
end end
guest_capability("redhat", "rsync_install") do
require_relative "cap/rsync"
Cap::RSync
end
end end
end end
end end

View File

@ -0,0 +1,20 @@
module VagrantPlugins
module GuestSolaris
module Cap
class RSync
def self.rsync_installed(machine)
machine.communicate.test("which rsync")
end
def self.rsync_pre(machine, folder_opts)
username = machine.ssh_info[:username]
machine.communicate.tap do |comm|
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
end
end
end
end
end
end

View File

@ -35,6 +35,16 @@ module VagrantPlugins
require_relative "cap/mount_virtualbox_shared_folder" require_relative "cap/mount_virtualbox_shared_folder"
Cap::MountVirtualBoxSharedFolder Cap::MountVirtualBoxSharedFolder
end end
guest_capability("solaris", "rsync_installed") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("solaris", "rsync_pre") do
require_relative "cap/rsync"
Cap::RSync
end
end end
end end
end end

View File

@ -0,0 +1,20 @@
module VagrantPlugins
module GuestSolaris11
module Cap
class RSync
def self.rsync_installed(machine)
machine.communicate.test("which rsync")
end
def self.rsync_pre(machine, folder_opts)
username = machine.ssh_info[:username]
machine.communicate.tap do |comm|
comm.sudo("mkdir -p '#{folder_opts[:guestpath]}'")
comm.sudo("chown -R #{username} '#{folder_opts[:guestpath]}'")
end
end
end
end
end
end

View File

@ -39,6 +39,16 @@ module VagrantPlugins
require_relative "cap/mount_virtualbox_shared_folder" require_relative "cap/mount_virtualbox_shared_folder"
Cap::MountVirtualBoxSharedFolder Cap::MountVirtualBoxSharedFolder
end end
guest_capability("solaris11", "rsync_installed") do
require_relative "cap/rsync"
Cap::RSync
end
guest_capability("solaris11", "rsync_pre") do
require_relative "cap/rsync"
Cap::RSync
end
end end
end end
end end

View File

@ -28,6 +28,16 @@ module VagrantPlugins
end end
def enable(machine, folders, opts) def enable(machine, folders, opts)
if machine.guest.capability?(:rsync_installed)
installed = machine.guest.capability(:rsync_installed)
if !installed
can_install = machine.guest.capability?(:rsync_install)
raise Vagrant::Errors::RSyncNotInstalledInGuest if !can_install
machine.ui.info I18n.t("vagrant.rsync_installing")
machine.guest.capability(:rsync_install)
end
end
ssh_info = machine.ssh_info ssh_info = machine.ssh_info
if ssh_info[:private_key_path].empty? && ssh_info[:password] if ssh_info[:private_key_path].empty? && ssh_info[:password]

View File

@ -99,6 +99,7 @@ en:
rsync_folder: |- rsync_folder: |-
Rsyncing folder: %{hostpath} => %{guestpath} Rsyncing folder: %{hostpath} => %{guestpath}
rsync_folder_excludes: " - Exclude: %{excludes}" rsync_folder_excludes: " - Exclude: %{excludes}"
rsync_installing: "Installing rsync to the VM..."
rsync_ssh_password: |- rsync_ssh_password: |-
The machine you're rsyncing folders to is configured to use The machine you're rsyncing folders to is configured to use
password-based authentication. Vagrant can't script rsync to automatically password-based authentication. Vagrant can't script rsync to automatically
@ -574,6 +575,11 @@ en:
rsync_not_found: |- rsync_not_found: |-
"rsync" could not be found on your PATH. Make sure that rsync "rsync" could not be found on your PATH. Make sure that rsync
is properly installed on your system and available on the PATH. is properly installed on your system and available on the PATH.
rsync_not_installed_in_guest: |-
"rsync" was not detected as installed in your guest machine. This
is required for rsync synced folders to work. In addition to this,
Vagrant doesn't know how to automatically install rsync for your
machine, so you must do this manually.
scp_permission_denied: |- scp_permission_denied: |-
Failed to upload a file to the guest VM via SCP due to a permissions Failed to upload a file to the guest VM via SCP due to a permissions
error. This is normally because the user running Vagrant doesn't have error. This is normally because the user running Vagrant doesn't have

View File

@ -48,6 +48,7 @@ describe VagrantPlugins::SyncedFolderRSync::SyncedFolder do
before do before do
machine.stub(ssh_info: ssh_info) machine.stub(ssh_info: ssh_info)
guest.stub(:capability?).with(:rsync_installed)
end end
it "rsyncs each folder" do it "rsyncs each folder" do
@ -64,5 +65,33 @@ describe VagrantPlugins::SyncedFolderRSync::SyncedFolder do
subject.enable(machine, folders, {}) subject.enable(machine, folders, {})
end end
it "installs rsync if capable" do
folders = [ [:foo, {}] ]
helper_class.stub(:rsync_single)
guest.stub(:capability?).with(:rsync_installed).and_return(true)
guest.stub(:capability?).with(:rsync_install).and_return(true)
expect(guest).to receive(:capability).with(:rsync_installed).and_return(false)
expect(guest).to receive(:capability).with(:rsync_install)
subject.enable(machine, folders, {})
end
it "errors if rsync not installable" do
folders = [ [:foo, {}] ]
helper_class.stub(:rsync_single)
guest.stub(:capability?).with(:rsync_installed).and_return(true)
guest.stub(:capability?).with(:rsync_install).and_return(false)
expect(guest).to receive(:capability).with(:rsync_installed).and_return(false)
expect { subject.enable(machine, folders, {}) }.
to raise_error(Vagrant::Errors::RSyncNotInstalledInGuest)
end
end end
end end