Update rsync auto post command error handling to be more generic

Rescue and re-wrap any errors encountered when running the post
rsync capability. Rescue this exception type and notify of error
when encountered by rsync auto. Include test coverage.
This commit is contained in:
Chris Roberts 2018-12-14 17:03:42 -08:00
parent 480e992ea1
commit 818d1d97ae
7 changed files with 87 additions and 15 deletions

View File

@ -668,8 +668,8 @@ module Vagrant
error_key(:push_strategy_not_provided)
end
class RsyncChownCommandError < VagrantError
error_key(:rsync_chown_command_error)
class RSyncPostCommandError < VagrantError
error_key(:rsync_post_command_error)
end
class RSyncError < VagrantError

View File

@ -217,10 +217,10 @@ module VagrantPlugins
# halt is happening. Just notify the user but don't fail out.
opts[:machine].ui.error(I18n.t(
"vagrant.rsync_communicator_not_ready_callback"))
rescue Vagrant::Errors::RsyncChownCommandError
rescue Vagrant::Errors::RSyncPostCommandError => e
# Error executing rsync chown command
opts[:machine].ui.error(I18n.t(
"vagrant.rsync_chown_command_error"))
"vagrant.rsync_auto_post_command_error", message: e.to_s))
rescue Vagrant::Errors::RSyncError => e
# Error executing rsync, so show an error
opts[:machine].ui.error(I18n.t(

View File

@ -24,12 +24,7 @@ module VagrantPlugins
return
end
error_opts = {
error_class: Vagrant::Errors::RsyncChownCommandError,
error_key: :rsync_chown_command_error
}
machine.communicate.sudo(build_rsync_chown(opts), error_opts)
machine.communicate.sudo(build_rsync_chown(opts))
end
def build_rsync_chown(opts)

View File

@ -213,7 +213,14 @@ module VagrantPlugins
# If we have tasks to do after rsyncing, do those.
if machine.guest.capability?(:rsync_post)
machine.guest.capability(:rsync_post, opts)
begin
machine.guest.capability(:rsync_post, opts)
rescue Vagrant::Errors::VagrantError => err
raise Vagrant::Errors::RSyncPostCommandError,
guestpath: guestpath,
hostpath: hostpath,
message: err.to_s
end
end
end
end

View File

@ -235,10 +235,12 @@ en:
repeats, then please fix the issue:
%{message}
rsync_chown_command_error: |-
There was an error while executing find and chown command, when file missing.
This may not be critical since rsync chown command sometimes fails, but if this message
repeats, then please fix the issue.
rsync_auto_post_command_error: |-
There was an error while executing the rsync post command. This error is
shown below. This may not be critical but if this message repeats please
fix the issue:
%{message}
rsync_communicator_not_ready: |-
The machine is reporting that it is not ready for rsync to
communicate with it. Verify that this machine is properly running.
@ -1275,6 +1277,14 @@ en:
Guest path: %{guestpath}
Command: %{command}
Error: %{stderr}
rsync_post_command_error: |-
There was an error while attempting to run the post rsync
command for a synced folder. Please inspect the error message
below for more info.
Host path: %{hostpath}
Guest path: %{guestpath}
Error: %{message}
rsync_guest_install_error: |-
Installation of rsync into the guest has failed! The stdout
and stderr are shown below. Please read the error output, resolve

View File

@ -217,5 +217,50 @@ describe VagrantPlugins::SyncedFolderRSync::Command::RsyncAuto do
expect { subject.callback(paths, m, a, r) }.
to_not raise_error
end
context "on failure" do
let(:machine) { machine_stub("m1") }
let(:opts) { double("opts_m1") }
let(:paths) { {"/foo" => [machine: machine, opts: opts]} }
let(:args) { [paths, ["/foo/bar"], [], []] }
before do
allow_any_instance_of(Vagrant::Errors::VagrantError).
to receive(:translate_error)
allow(machine.ui).to receive(:error)
end
context "when rsync command fails" do
before do
expect(helper_class).to receive(:rsync_single).with(machine, machine.ssh_info, opts).
and_raise(Vagrant::Errors::RSyncError)
end
it "should notify on error" do
expect(machine.ui).to receive(:error)
subject.callback(*args)
end
it "should not raise error" do
expect { subject.callback(*args) }.not_to raise_error
end
end
context "when rsync post command capability fails" do
before do
expect(helper_class).to receive(:rsync_single).with(machine, machine.ssh_info, opts).
and_raise(Vagrant::Errors::RSyncPostCommandError)
end
it "should notify on error" do
expect(machine.ui).to receive(:error)
subject.callback(*args)
end
it "should not raise error" do
expect { subject.callback(*args) }.not_to raise_error
end
end
end
end
end

View File

@ -154,6 +154,21 @@ describe VagrantPlugins::SyncedFolderRSync::RsyncHelper do
subject.rsync_single(machine, ssh_info, opts)
end
context "with rsync_post capability" do
before do
allow(guest).to receive(:capability?).with(:rsync_post).and_return(true)
allow(Vagrant::Util::Subprocess).to receive(:execute).and_return(result)
end
it "should raise custom error when capability errors" do
expect(guest).to receive(:capability).with(:rsync_post, opts).
and_raise(Vagrant::Errors::VagrantError)
expect { subject.rsync_single(machine, ssh_info, opts) }.
to raise_error(Vagrant::Errors::RSyncPostCommandError)
end
end
context "excluding files" do
it "excludes files if given as a string" do
opts[:exclude] = "foo"