lib/chef/handler.rb in chef-0.9.0.rc01 vs lib/chef/handler.rb in chef-0.9.0.rc02

- old
+ new

@@ -13,50 +13,109 @@ # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # +require 'forwardable' class Chef class Handler - attr_accessor :config + extend Forwardable - def initialize(config={}) - @config = config - @config[:path] ||= "/var/chef/reports" - @config + attr_reader :run_status + + ## + # :method: start_time + # + # The time the chef run started + def_delegator :@run_status, :start_time + + ## + # :method: end_time + # + # The time the chef run ended + def_delegator :@run_status, :end_time + + ## + # :method: run_context + # + # The Chef::RunContext object used by the chef run + def_delegator :@run_status, :run_context + + ## + # :method: exception + # + # The uncaught Exception that terminated the chef run, or nil if the run + # completed successfully + def_delegator :@run_status, :exception + + ## + # :method: backtrace + # + # The backtrace captured by the uncaught exception that terminated the chef + # run, or nil if the run completed successfully + def_delegator :@run_status, :backtrace + + ## + # :method: node + # + # The Chef::Node for this client run + def_delegator :@run_status, :node + + ## + # :method: all_resources + # + # An Array containing all resources in the chef run's resource_collection + def_delegator :@run_status, :all_resources + + ## + # :method: updated_resources + # + # An Array containing all resources that were updated during the chef run + def_delegator :@run_status, :updated_resources + + ## + # :method: success? + # + # Was the chef run successful? True if the chef run did not raise an + # uncaught exception + def_delegator :@run_status, :success? + + ## + # :method: failed? + # + # Did the chef run fail? True if the chef run raised an uncaught exception + def_delegator :@run_status, :failed? + + # The main entry point for report handling. Subclasses should override this + # method with their own report handling logic. + def report end - def build_report_data(node, runner, start_time, end_time, elapsed_time, exception=nil) - data = Hash.new - data[:node] = node if node - if runner - data[:resources] = { - :all => runner.run_context.resource_collection.all_resources, - :updated => runner.run_context.resource_collection.inject([]) { |m, r| m << r if r.updated; m } - } - end - if exception - data[:success] = false - data[:exception] = { - :message => exception.message, - :backtrace => exception.backtrace - } - else - data[:success] = true - end - data[:elapsed_time] = elapsed_time - data[:start_time] = start_time - data[:end_time] = end_time - data + # Runs the report handler, rescuing and logging any errors it may cause. + # This ensures that all handlers get a chance to run even if one fails. + # This method should not be overridden by subclasses unless you know what + # you're doing. + def run_report_safely(run_status) + run_report_unsafe(run_status) + rescue Exception => e + Chef::Log.error("Report handler #{self.class.name} raised #{e.inspect}") + Array(e.backtrace).each { |line| Chef::Log.error(line) } + ensure + @run_status = nil end - def build_report_dir - unless File.exists?(config[:path]) - FileUtils.mkdir_p(config[:path]) - File.chmod(octal_mode("0700"), config[:path]) - end + # Runs the report handler without any error handling. This method should + # not be used directly except in testing. + def run_report_unsafe(run_status) + @run_status = run_status + report + end + + # Return the Hash representation of the run_status + def data + @run_status.to_hash end end end