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