summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortyler-ball <tyleraball@gmail.com>2014-10-30 20:44:36 -0700
committertyler-ball <tyleraball@gmail.com>2014-10-30 20:44:36 -0700
commit2032e6179e9548038bfdc734c8c3b77fc4ea9273 (patch)
treecd3796eda78aa689e446f722d05441fa3f38da04
parentd8624671c53e522310ec616aa693632b667e6395 (diff)
downloadchef-2032e6179e9548038bfdc734c8c3b77fc4ea9273.tar.gz
Adding logic for exceptions from converge phase not interfering with audit phase and vice-versa
-rw-r--r--lib/chef/client.rb25
-rw-r--r--lib/chef/exceptions.rb22
-rw-r--r--lib/chef/formatters/doc.rb18
3 files changed, 50 insertions, 15 deletions
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 7fde1eb12e..b41db70689 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -246,7 +246,6 @@ class Chef
@policy_builder ||= Chef::PolicyBuilder.strategy.new(node_name, ohai.data, json_attribs, @override_runlist, events)
end
-
def save_updated_node
if Chef::Config[:solo]
# nothing to do
@@ -260,6 +259,7 @@ class Chef
def run_ohai
ohai.all_plugins
+ @events.ohai_completed(node)
end
def node_name
@@ -326,6 +326,7 @@ class Chef
converge_exception
end
+ # TODO are failed audits going to raise exceptions, or only be handled by the reporters?
def run_audits(run_context)
audit_exception = nil
begin
@@ -351,7 +352,6 @@ class Chef
policy_builder.expand_run_list
end
-
def do_windows_admin_check
if Chef::Platform.windows?
Chef::Log.debug("Checking for administrator privileges....")
@@ -398,7 +398,7 @@ class Chef
Chef::Log.debug("Chef-client request_id: #{request_id}")
enforce_path_sanity
run_ohai
- @events.ohai_completed(node)
+
register unless Chef::Config[:solo]
load_node
@@ -414,16 +414,14 @@ class Chef
run_context = setup_run_context
- converge_exception = converge(run_context)
- if converge_exception
-
- else
- save_updated_node
- end
-
- audit_exception = run_audits(run_context)
- if audit_exception
+ converge_error = converge(run_context)
+ save_updated_node unless converge_error
+ audit_error = run_audits(run_context)
+ if converge_error || audit_error
+ e = Chef::Exceptions::RunFailedWrappingError.new(converge_error, audit_error)
+ e.fill_backtrace
+ raise e
end
run_status.stop_clock
@@ -436,9 +434,6 @@ class Chef
true
- # TODO get rid of resuce here, push down into sub-methods, clean up this method, return exceptions and raise new
- # exception wrapping all known exceptions. sub-method should do all their own event reporting.
-
rescue Exception => e
# CHEF-3336: Send the error first in case something goes wrong below and we don't know why
Chef::Log.debug("Re-raising exception: #{e.class} - #{e.message}\n#{e.backtrace.join("\n ")}")
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index 2103812dca..eb7c27b2a8 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -368,5 +368,27 @@ class Chef
end
class NoAuditsProvided < RuntimeError; end
+
+ # If a converge or audit fails, we want to wrap the output from those errors into 1 error so we can
+ # see both issues in the output. It is possible that nil will be provided. You must call `fill_backtrace`
+ # to correctly populate the backtrace with the wrapped backtraces.
+ class RunFailedWrappingError < RuntimeError
+ attr_reader :wrapped_errors
+ def initialize(*errors)
+ errors = errors.select {|e| !e.nil?}
+ output = "Found #{errors.size} errors, they are stored in the backtrace\n"
+ @wrapped_errors = errors
+ super output
+ end
+
+ def fill_backtrace
+ backtrace = []
+ wrapped_errors.each_with_index do |e,i|
+ backtrace << "#{i+1}) #{e.message}"
+ backtrace += e.backtrace
+ backtrace << ""
+ end
+ end
+ end
end
end
diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb
index 4a08b9d095..66ee6ccabe 100644
--- a/lib/chef/formatters/doc.rb
+++ b/lib/chef/formatters/doc.rb
@@ -151,6 +151,24 @@ class Chef
unindent if @current_recipe
end
+ def converge_failed(e)
+ # TODO do we want to do anything else in here?
+ converge_complete
+ end
+
+ def audit_start(run_context)
+ # TODO read the number of `controls` blocks to run from the run_context.audit_runner
+ puts_line "Running collected audits"
+ end
+
+ def audit_complete
+ # TODO
+ end
+
+ def audit_failed(exception)
+ # TODO
+ end
+
# Called before action is executed on a resource.
def resource_action_start(resource, action, notification_type=nil, notifier=nil)
if resource.cookbook_name && resource.recipe_name