2014-01-11 01:40:29 +00:00
|
|
|
require "log4r"
|
|
|
|
|
|
|
|
require "vagrant/util/subprocess"
|
|
|
|
require "vagrant/util/which"
|
|
|
|
|
|
|
|
module VagrantPlugins
|
|
|
|
module SyncedFolderRSync
|
|
|
|
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
|
|
|
include Vagrant::Util
|
|
|
|
|
|
|
|
def initialize(*args)
|
|
|
|
super
|
|
|
|
|
|
|
|
@logger = Log4r::Logger.new("vagrant::synced_folders::rsync")
|
|
|
|
end
|
|
|
|
|
|
|
|
def usable?(machine, raise_error=false)
|
|
|
|
rsync_path = Which.which("rsync")
|
|
|
|
return true if rsync_path
|
|
|
|
return false if !raise_error
|
|
|
|
raise Vagrant::Errors::RSyncNotFound
|
|
|
|
end
|
|
|
|
|
|
|
|
def prepare(machine, folders, opts)
|
|
|
|
# Nothing is necessary to do before VM boot.
|
|
|
|
end
|
|
|
|
|
|
|
|
def enable(machine, folders, opts)
|
|
|
|
ssh_info = machine.ssh_info
|
|
|
|
|
2014-01-11 04:37:11 +00:00
|
|
|
if ssh_info[:private_key_path].empty? && ssh_info[:password]
|
|
|
|
machine.ui.warn(I18n.t("vagrant.rsync_ssh_password"))
|
|
|
|
end
|
|
|
|
|
2014-01-11 01:40:29 +00:00
|
|
|
folders.each do |id, folder_opts|
|
2014-01-11 01:51:44 +00:00
|
|
|
rsync_single(machine, ssh_info, folder_opts)
|
2014-01-11 01:40:29 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# rsync_single rsync's a single folder with the given options.
|
2014-01-11 01:51:44 +00:00
|
|
|
def rsync_single(machine, ssh_info, opts)
|
2014-01-11 01:40:29 +00:00
|
|
|
# Folder info
|
|
|
|
guestpath = opts[:guestpath]
|
|
|
|
hostpath = opts[:hostpath]
|
|
|
|
|
|
|
|
# Connection information
|
|
|
|
username = ssh_info[:username]
|
|
|
|
host = ssh_info[:host]
|
|
|
|
rsh = [
|
|
|
|
"ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no",
|
|
|
|
ssh_info[:private_key_path].map { |p| "-i '#{p}'" },
|
|
|
|
].flatten.join(" ")
|
|
|
|
|
|
|
|
# Exclude some files by default, and any that might be configured
|
|
|
|
# by the user.
|
|
|
|
excludes = ['.vagrant/']
|
2014-01-11 02:06:16 +00:00
|
|
|
excludes += Array(opts[:exclude]).map(&:to_s) if opts[:exclude]
|
2014-01-11 02:01:38 +00:00
|
|
|
excludes.uniq!
|
2014-01-11 01:40:29 +00:00
|
|
|
|
|
|
|
# Build up the actual command to execute
|
|
|
|
command = [
|
|
|
|
"rsync",
|
|
|
|
"--verbose",
|
|
|
|
"--archive",
|
|
|
|
"-z",
|
|
|
|
excludes.map { |e| ["--exclude", e] },
|
|
|
|
"-e", rsh,
|
|
|
|
hostpath,
|
|
|
|
"#{username}@#{host}:#{guestpath}"
|
|
|
|
].flatten
|
|
|
|
command_opts = {}
|
|
|
|
|
|
|
|
# The working directory should be the root path
|
2014-01-11 01:51:44 +00:00
|
|
|
command_opts[:workdir] = machine.env.root_path.to_s
|
2014-01-11 01:40:29 +00:00
|
|
|
|
2014-01-11 01:51:44 +00:00
|
|
|
machine.ui.info(I18n.t(
|
2014-01-11 01:40:29 +00:00
|
|
|
"vagrant.rsync_folder", guestpath: guestpath, hostpath: hostpath))
|
2014-01-11 02:06:16 +00:00
|
|
|
if excludes.length > 1
|
|
|
|
machine.ui.info(I18n.t(
|
|
|
|
"vagrant.rsync_folder_excludes", excludes: excludes.inspect))
|
|
|
|
end
|
2014-01-11 01:51:44 +00:00
|
|
|
|
|
|
|
# If we have tasks to do before rsyncing, do those.
|
|
|
|
if machine.guest.capability?(:rsync_pre)
|
|
|
|
machine.guest.capability(:rsync_pre, opts)
|
|
|
|
end
|
|
|
|
|
2014-01-11 01:40:29 +00:00
|
|
|
r = Vagrant::Util::Subprocess.execute(*(command + [command_opts]))
|
|
|
|
if r.exit_code != 0
|
|
|
|
raise Vagrant::Errors::RSyncError,
|
|
|
|
command: command.join(" "),
|
|
|
|
guestpath: guestpath,
|
|
|
|
hostpath: hostpath,
|
|
|
|
stderr: r.stderr
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|