synced_folders/rsync: move rsync logic out to helper
This commit is contained in:
parent
9b383740ba
commit
59218ded68
|
@ -324,7 +324,7 @@ module Vagrant
|
|||
# Returns the state of this machine. The state is queried from the
|
||||
# backing provider, so it can be any arbitrary symbol.
|
||||
#
|
||||
# @return [Symbol]
|
||||
# @return [MachineState]
|
||||
def state
|
||||
result = @provider.state
|
||||
raise Errors::MachineStateInvalid if !result.is_a?(MachineState)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
require 'optparse'
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
module VagrantPlugins
|
||||
module SyncedFolderRSync
|
||||
module Command
|
||||
class Rsync < Vagrant.plugin("2", :command)
|
||||
def self.synopsis
|
||||
"syncs rsync synced folders to remote machine"
|
||||
end
|
||||
|
||||
def execute
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant rsync [vm-name]"
|
||||
o.separator ""
|
||||
end
|
||||
|
||||
# Parse the options and return if we don't have any target.
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
|
||||
# Go through each machine and perform the rsync
|
||||
error = false
|
||||
with_target_vms(argv) do |machine|
|
||||
if !machine.communicate.ready?
|
||||
machine.ui.error(I18n.t("vagrant.rsync_communicator_not_ready"))
|
||||
error = true
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
return error ? 1 : 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,66 @@
|
|||
require "vagrant/util/subprocess"
|
||||
|
||||
module VagrantPlugins
|
||||
module SyncedFolderRSync
|
||||
# This is a helper that abstracts out the functionality of rsyncing
|
||||
# folders so that it can be called from anywhere.
|
||||
class RsyncHelper
|
||||
def self.rsync_single(machine, ssh_info, opts)
|
||||
# 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/']
|
||||
excludes += Array(opts[:exclude]).map(&:to_s) if opts[:exclude]
|
||||
excludes.uniq!
|
||||
|
||||
# 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
|
||||
command_opts[:workdir] = machine.env.root_path.to_s
|
||||
|
||||
machine.ui.info(I18n.t(
|
||||
"vagrant.rsync_folder", guestpath: guestpath, hostpath: hostpath))
|
||||
if excludes.length > 1
|
||||
machine.ui.info(I18n.t(
|
||||
"vagrant.rsync_folder_excludes", excludes: excludes.inspect))
|
||||
end
|
||||
|
||||
# If we have tasks to do before rsyncing, do those.
|
||||
if machine.guest.capability?(:rsync_pre)
|
||||
machine.guest.capability(:rsync_pre, opts)
|
||||
end
|
||||
|
||||
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
|
|
@ -9,6 +9,11 @@ module VagrantPlugins
|
|||
The Rsync synced folder plugin will sync folders via rsync.
|
||||
EOF
|
||||
|
||||
command("rsync", primary: false) do
|
||||
require_relative "command/rsync"
|
||||
Command::Rsync
|
||||
end
|
||||
|
||||
synced_folder("rsync", 5) do
|
||||
require_relative "synced_folder"
|
||||
SyncedFolder
|
||||
|
|
|
@ -3,6 +3,8 @@ require "log4r"
|
|||
require "vagrant/util/subprocess"
|
||||
require "vagrant/util/which"
|
||||
|
||||
require_relative "helper"
|
||||
|
||||
module VagrantPlugins
|
||||
module SyncedFolderRSync
|
||||
class SyncedFolder < Vagrant.plugin("2", :synced_folder)
|
||||
|
@ -33,65 +35,7 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
folders.each do |id, folder_opts|
|
||||
rsync_single(machine, ssh_info, folder_opts)
|
||||
end
|
||||
end
|
||||
|
||||
# rsync_single rsync's a single folder with the given options.
|
||||
def rsync_single(machine, ssh_info, opts)
|
||||
# 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/']
|
||||
excludes += Array(opts[:exclude]).map(&:to_s) if opts[:exclude]
|
||||
excludes.uniq!
|
||||
|
||||
# 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
|
||||
command_opts[:workdir] = machine.env.root_path.to_s
|
||||
|
||||
machine.ui.info(I18n.t(
|
||||
"vagrant.rsync_folder", guestpath: guestpath, hostpath: hostpath))
|
||||
if excludes.length > 1
|
||||
machine.ui.info(I18n.t(
|
||||
"vagrant.rsync_folder_excludes", excludes: excludes.inspect))
|
||||
end
|
||||
|
||||
# If we have tasks to do before rsyncing, do those.
|
||||
if machine.guest.capability?(:rsync_pre)
|
||||
machine.guest.capability(:rsync_pre, opts)
|
||||
end
|
||||
|
||||
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
|
||||
RsyncHelper.rsync_single(machine, ssh_info, folder_opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -85,6 +85,9 @@ en:
|
|||
%{names}
|
||||
provisioner_cleanup: |-
|
||||
Running cleanup tasks for '%{name}' provisioner...
|
||||
rsync_communicator_not_ready: |-
|
||||
The machine is reporting that it is not ready for rsync to
|
||||
communiate with it. Verify that this machine is properly running.
|
||||
rsync_folder: |-
|
||||
Rsyncing folder: %{hostpath} => %{guestpath}
|
||||
rsync_folder_excludes: " - Exclude: %{excludes}"
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
require_relative "../../../base"
|
||||
|
||||
require Vagrant.source_root.join("plugins/synced_folders/rsync/helper")
|
||||
|
||||
describe VagrantPlugins::SyncedFolderRSync::RsyncHelper do
|
||||
include_context "unit"
|
||||
|
||||
let(:iso_env) do
|
||||
# We have to create a Vagrantfile so there is a root path
|
||||
env = isolated_environment
|
||||
env.vagrantfile("")
|
||||
env.create_vagrant_env
|
||||
end
|
||||
|
||||
let(:guest) { double("guest") }
|
||||
let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) }
|
||||
|
||||
subject { described_class }
|
||||
|
||||
before do
|
||||
machine.stub(guest: guest)
|
||||
end
|
||||
|
||||
describe "#rsync_single" do
|
||||
let(:result) { Vagrant::Util::Subprocess::Result.new(0, "", "") }
|
||||
|
||||
let(:ssh_info) {{
|
||||
private_key_path: [],
|
||||
}}
|
||||
let(:opts) { {} }
|
||||
let(:ui) { machine.ui }
|
||||
|
||||
before do
|
||||
Vagrant::Util::Subprocess.stub(execute: result)
|
||||
|
||||
guest.stub(capability?: false)
|
||||
end
|
||||
|
||||
it "doesn't raise an error if it succeeds" do
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
|
||||
it "raises an error if the exit code is non-zero" do
|
||||
Vagrant::Util::Subprocess.stub(
|
||||
execute: Vagrant::Util::Subprocess::Result.new(1, "", ""))
|
||||
|
||||
expect {subject.rsync_single(machine, ssh_info, opts) }.
|
||||
to raise_error(Vagrant::Errors::RSyncError)
|
||||
end
|
||||
|
||||
it "executes within the root path" do
|
||||
Vagrant::Util::Subprocess.should_receive(:execute).with do |*args|
|
||||
expect(args.last).to be_kind_of(Hash)
|
||||
|
||||
opts = args.last
|
||||
expect(opts[:workdir]).to eql(machine.env.root_path.to_s)
|
||||
end
|
||||
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
|
||||
it "executes the rsync_pre capability first if it exists" do
|
||||
guest.should_receive(:capability?).with(:rsync_pre).and_return(true)
|
||||
guest.should_receive(:capability).with(:rsync_pre, opts).ordered
|
||||
Vagrant::Util::Subprocess.should_receive(:execute).ordered.and_return(result)
|
||||
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
|
||||
context "excluding files" do
|
||||
it "excludes files if given as a string" do
|
||||
opts[:exclude] = "foo"
|
||||
|
||||
Vagrant::Util::Subprocess.should_receive(:execute).with do |*args|
|
||||
index = args.find_index("foo")
|
||||
expect(index).to be > 0
|
||||
expect(args[index-1]).to eql("--exclude")
|
||||
end
|
||||
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
|
||||
it "excludes multiple files" do
|
||||
opts[:exclude] = ["foo", "bar"]
|
||||
|
||||
Vagrant::Util::Subprocess.should_receive(:execute).with do |*args|
|
||||
index = args.find_index("foo")
|
||||
expect(index).to be > 0
|
||||
expect(args[index-1]).to eql("--exclude")
|
||||
|
||||
index = args.find_index("bar")
|
||||
expect(index).to be > 0
|
||||
expect(args[index-1]).to eql("--exclude")
|
||||
end
|
||||
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,6 +16,8 @@ describe VagrantPlugins::SyncedFolderRSync::SyncedFolder do
|
|||
let(:host) { double("host") }
|
||||
let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) }
|
||||
|
||||
let(:helper_class) { VagrantPlugins::SyncedFolderRSync::RsyncHelper }
|
||||
|
||||
before do
|
||||
machine.env.stub(host: host)
|
||||
machine.stub(guest: guest)
|
||||
|
@ -55,7 +57,7 @@ describe VagrantPlugins::SyncedFolderRSync::SyncedFolder do
|
|||
]
|
||||
|
||||
folders.each do |_, opts|
|
||||
subject.should_receive(:rsync_single).
|
||||
helper_class.should_receive(:rsync_single).
|
||||
with(machine, ssh_info, opts).
|
||||
ordered
|
||||
end
|
||||
|
@ -63,81 +65,4 @@ describe VagrantPlugins::SyncedFolderRSync::SyncedFolder do
|
|||
subject.enable(machine, folders, {})
|
||||
end
|
||||
end
|
||||
|
||||
describe "#rsync_single" do
|
||||
let(:result) { Vagrant::Util::Subprocess::Result.new(0, "", "") }
|
||||
|
||||
let(:ssh_info) {{
|
||||
private_key_path: [],
|
||||
}}
|
||||
let(:opts) { {} }
|
||||
let(:ui) { machine.ui }
|
||||
|
||||
before do
|
||||
Vagrant::Util::Subprocess.stub(execute: result)
|
||||
|
||||
guest.stub(capability?: false)
|
||||
end
|
||||
|
||||
it "doesn't raise an error if it succeeds" do
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
|
||||
it "raises an error if the exit code is non-zero" do
|
||||
Vagrant::Util::Subprocess.stub(
|
||||
execute: Vagrant::Util::Subprocess::Result.new(1, "", ""))
|
||||
|
||||
expect {subject.rsync_single(machine, ssh_info, opts) }.
|
||||
to raise_error(Vagrant::Errors::RSyncError)
|
||||
end
|
||||
|
||||
it "executes within the root path" do
|
||||
Vagrant::Util::Subprocess.should_receive(:execute).with do |*args|
|
||||
expect(args.last).to be_kind_of(Hash)
|
||||
|
||||
opts = args.last
|
||||
expect(opts[:workdir]).to eql(machine.env.root_path.to_s)
|
||||
end
|
||||
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
|
||||
it "executes the rsync_pre capability first if it exists" do
|
||||
guest.should_receive(:capability?).with(:rsync_pre).and_return(true)
|
||||
guest.should_receive(:capability).with(:rsync_pre, opts).ordered
|
||||
Vagrant::Util::Subprocess.should_receive(:execute).ordered.and_return(result)
|
||||
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
|
||||
context "excluding files" do
|
||||
it "excludes files if given as a string" do
|
||||
opts[:exclude] = "foo"
|
||||
|
||||
Vagrant::Util::Subprocess.should_receive(:execute).with do |*args|
|
||||
index = args.find_index("foo")
|
||||
expect(index).to be > 0
|
||||
expect(args[index-1]).to eql("--exclude")
|
||||
end
|
||||
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
|
||||
it "excludes multiple files" do
|
||||
opts[:exclude] = ["foo", "bar"]
|
||||
|
||||
Vagrant::Util::Subprocess.should_receive(:execute).with do |*args|
|
||||
index = args.find_index("foo")
|
||||
expect(index).to be > 0
|
||||
expect(args[index-1]).to eql("--exclude")
|
||||
|
||||
index = args.find_index("bar")
|
||||
expect(index).to be > 0
|
||||
expect(args[index-1]).to eql("--exclude")
|
||||
end
|
||||
|
||||
subject.rsync_single(machine, ssh_info, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue