summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@chef.io>2019-12-09 10:23:25 -0800
committerGitHub <noreply@github.com>2019-12-09 10:23:25 -0800
commit0e021a705ac0d7c2dad4517443974398ade8b2dd (patch)
tree9ebece2d58c3705df514fbec52df385dc0ae7029
parent1584bde92cba8151a5a850bef8c4ed9a92c798b6 (diff)
parent52871d2c8d8bc8ed526b8e3eda9aadb5fa0f93e5 (diff)
downloadchef-0e021a705ac0d7c2dad4517443974398ade8b2dd.tar.gz
Add output for the file provider verification (#9039)
Add output for the file provider verification
-rw-r--r--lib/chef/guard_interpreter/default_guard_interpreter.rb2
-rw-r--r--lib/chef/provider/file.rb5
-rw-r--r--lib/chef/resource/file/verification.rb5
-rw-r--r--spec/spec_helper.rb2
-rw-r--r--spec/support/shared/unit/provider/file.rb20
5 files changed, 28 insertions, 6 deletions
diff --git a/lib/chef/guard_interpreter/default_guard_interpreter.rb b/lib/chef/guard_interpreter/default_guard_interpreter.rb
index 7ed0570291..b14b714c7d 100644
--- a/lib/chef/guard_interpreter/default_guard_interpreter.rb
+++ b/lib/chef/guard_interpreter/default_guard_interpreter.rb
@@ -23,6 +23,7 @@ class Chef
class GuardInterpreter
class DefaultGuardInterpreter
include Chef::Mixin::ShellOut
+ attr_reader :output
def initialize(command, opts)
@command = command
@@ -31,6 +32,7 @@ class Chef
def evaluate
result = shell_out(@command, default_env: false, **@command_opts)
+ @output = "STDOUT: #{result.stdout}\nSTDERR: #{result.stderr}\n"
Chef::Log.debug "Command failed: #{result.stderr}" unless result.status.success?
result.status.success?
# Timeout fails command rather than chef-client run, see:
diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb
index a2b956c282..1b1f73b9d5 100644
--- a/lib/chef/provider/file.rb
+++ b/lib/chef/provider/file.rb
@@ -341,7 +341,10 @@ class Chef
if tempfile
new_resource.verify.each do |v|
unless v.verify(tempfile.path)
- raise Chef::Exceptions::ValidationFailed.new "Proposed content for #{new_resource.path} failed verification #{new_resource.sensitive ? "[sensitive]" : v}"
+ backupfile = "#{Chef::Config[:file_cache_path]}/failed_validations/#{::File.basename(tempfile.path)}"
+ FileUtils.mkdir_p ::File.dirname(backupfile)
+ FileUtils.cp tempfile.path, backupfile
+ raise Chef::Exceptions::ValidationFailed.new "Proposed content for #{new_resource.path} failed verification #{new_resource.sensitive ? "[sensitive]" : "#{v}\n#{v.output}"}\nTemporary file moved to #{backupfile}"
end
end
end
diff --git a/lib/chef/resource/file/verification.rb b/lib/chef/resource/file/verification.rb
index 7cd3144509..59d0981ddc 100644
--- a/lib/chef/resource/file/verification.rb
+++ b/lib/chef/resource/file/verification.rb
@@ -63,6 +63,7 @@ class Chef
class Verification
extend Chef::Mixin::DescendantsTracker
+ attr_reader :output
def self.provides(name)
@provides = name
@@ -117,7 +118,9 @@ class Chef
command = @command % { path: path }
interpreter = Chef::GuardInterpreter.for_resource(@parent_resource, command, @command_opts)
- interpreter.evaluate
+ ret = interpreter.evaluate
+ @output = interpreter.output
+ ret
end
def verify_registered_verification(path, opts)
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 27cf301d67..3154e2f255 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -123,8 +123,10 @@ RSpec.configure do |config|
config.filter_run_excluding external: true
# Explicitly disable :should syntax
+ # And set max_formatted_output_length to nil to prevent RSpec from doing truncation.
config.expect_with :rspec do |c|
c.syntax = :expect
+ c.max_formatted_output_length = nil
end
config.mock_with :rspec do |c|
c.syntax = :expect
diff --git a/spec/support/shared/unit/provider/file.rb b/spec/support/shared/unit/provider/file.rb
index 36b19675c2..3df8eecc6f 100644
--- a/spec/support/shared/unit/provider/file.rb
+++ b/spec/support/shared/unit/provider/file.rb
@@ -458,14 +458,24 @@ shared_examples_for Chef::Provider::File do
end
context "do_validate_content" do
- before { setup_normal_file }
+ let(:tempfile_name) { "foo-bar-baz" }
+ let(:backupfile) { "/tmp/failed_validations/#{tempfile_name}" }
let(:tempfile) do
- t = double("Tempfile", path: "/tmp/foo-bar-baz", closed?: true)
+ t = double("Tempfile", path: "/tmp/#{tempfile_name}", closed?: true)
allow(content).to receive(:tempfile).and_return(t)
t
end
+ before do
+ Chef::Config[:file_cache_path] = "/tmp"
+ allow(File).to receive(:dirname).and_return(tempfile)
+ allow(File).to receive(:basename).and_return(tempfile_name)
+ allow(FileUtils).to receive(:mkdir_p).and_return(true)
+ allow(FileUtils).to receive(:cp).and_return(true)
+ setup_normal_file
+ end
+
context "with user-supplied verifications" do
it "calls #verify on each verification with tempfile path" do
provider.new_resource.verify windows? ? "REM" : "true"
@@ -477,7 +487,8 @@ shared_examples_for Chef::Provider::File do
allow(File).to receive(:directory?).with("C:\\Windows\\system32/cmd.exe").and_return(false)
provider.new_resource.verify windows? ? "REM" : "true"
provider.new_resource.verify windows? ? "cmd.exe /c exit 1" : "false"
- expect { provider.send(:do_validate_content) }.to raise_error(Chef::Exceptions::ValidationFailed, "Proposed content for #{provider.new_resource.path} failed verification #{windows? ? "cmd.exe /c exit 1" : "false"}")
+ msg = "Proposed content for #{provider.new_resource.path} failed verification #{windows? ? "cmd.exe /c exit 1" : "false"}"
+ expect { provider.send(:do_validate_content) }.to raise_error(Chef::Exceptions::ValidationFailed, /#{msg}/)
end
it "does not show verification for sensitive resources" do
@@ -485,7 +496,8 @@ shared_examples_for Chef::Provider::File do
provider.new_resource.verify windows? ? "REM" : "true"
provider.new_resource.verify windows? ? "cmd.exe /c exit 1" : "false"
provider.new_resource.sensitive true
- expect { provider.send(:do_validate_content) }.to raise_error(Chef::Exceptions::ValidationFailed, "Proposed content for #{provider.new_resource.path} failed verification [sensitive]")
+ msg = "Proposed content for #{provider.new_resource.path} failed verification [sensitive]\nTemporary file moved to #{backupfile}"
+ expect { provider.send(:do_validate_content) }.to raise_error(Chef::Exceptions::ValidationFailed, msg)
end
end
end