diff options
Diffstat (limited to 'lib/puppet/server')
-rwxr-xr-x | lib/puppet/server/report.rb | 134 |
1 files changed, 49 insertions, 85 deletions
diff --git a/lib/puppet/server/report.rb b/lib/puppet/server/report.rb index 027c78f9d..6253f6a0e 100755 --- a/lib/puppet/server/report.rb +++ b/lib/puppet/server/report.rb @@ -2,18 +2,29 @@ module Puppet class Server # A simple server for triggering a new run on a Puppet client. class Report < Handler + class << self + include Puppet::Util::ClassGen + end + + module ReportBase + include Puppet::Util::Docs + attr_writer :useyaml + + def useyaml? + if defined? @useyaml + @useyaml + else + false + end + end + end + @interface = XMLRPC::Service::Interface.new("puppetreports") { |iface| iface.add_method("string report(array)") } Puppet.setdefaults(:reporting, - :reportdirectory => {:default => "$vardir/reports", - :mode => 0750, - :owner => "$user", - :group => "$group", - :desc => "The directory in which to store reports received from the - client. Each client gets a separate subdirectory."}, - :reports => ["none", + :reports => ["store", "The list of reports to generate. All reports are looked for in puppet/reports/<name>.rb, and multiple report names should be comma-separated (whitespace is okay)." @@ -27,19 +38,19 @@ class Server attr_reader :hooks end - def self.reportmethod(report) - "report_" + report.to_s - end + # Add a new report type. + def self.newreport(name, options = {}, &block) + name = symbolize(name) - # Add a hook for processing reports. - def self.newreport(name, &block) - name = name.intern if name.is_a? String - method = reportmethod(name) + mod = genmodule(name, :extend => ReportBase, :hash => @reports, :block => block) - # We want to define a method so that reports can use 'return'. - define_method(method, &block) + if options[:useyaml] + mod.useyaml = true + end - @reports[name] = method + mod.send(:define_method, :report_name) do + name + end end # Load a report. @@ -58,8 +69,12 @@ class Server return nil end end + @reports[symbolize(name)] + end - @reports[name] + def self.reports + @reportloader.loadall + @reports.keys end def initialize(*args) @@ -68,24 +83,8 @@ class Server Puppet.config.use(:metrics) end - # Dynamically create the report methods as necessary. - def method_missing(name, *args) - if name.to_s =~ /^report_(.+)$/ - if self.class.report($1) - send(name, *args) - else - super - end - else - super - end - end - # Accept a report from a client. def report(report, client = nil, clientip = nil) - # We need the client name for storing files. - client ||= Facter["hostname"].value - # Unescape the report unless @local report = CGI.unescape(report) @@ -99,74 +98,39 @@ class Server puts detail.backtrace end end - - # We don't want any tracking back in the fs. Unlikely, but there - # you go. - client.gsub("..",".") - - dir = File.join(Puppet[:reportdirectory], client) - - unless FileTest.exists?(dir) - mkclientdir(client, dir) - end - - # Now store the report. - now = Time.now.gmtime - name = %w{year month day hour min}.collect do |method| - # Make sure we're at least two digits everywhere - "%02d" % now.send(method).to_s - end.join("") + ".yaml" - - file = File.join(dir, name) - - begin - File.open(file, "w", 0640) do |f| - f.puts report - end - rescue => detail - if Puppet[:trace] - puts detail.backtrace - end - Puppet.warning "Could not write report for %s at %s: %s" % - [client, file, detail] - end - - - # Our report is in YAML - return file end private - def mkclientdir(client, dir) - Puppet.config.setdefaults("reportclient-#{client}", - "clientdir-#{client}" => { :default => dir, - :mode => 0750, - :owner => "$user", - :group => "$group" - } - ) - - Puppet.config.use("reportclient-#{client}") - end - # Process the report using all of the existing hooks. - def process(report) + def process(yaml) return if Puppet[:reports] == "none" # First convert the report to real objects begin - report = YAML.load(report) + report = YAML.load(yaml) rescue => detail Puppet.warning "Could not load report: %s" % detail return end + # Used for those reports that accept yaml + client = report.host + reports().each do |name| - if method = self.class.report(name) and respond_to? method + if mod = self.class.report(name) Puppet.info "Processing report %s" % name + + # We have to use a dup because we're including a module in the + # report. + newrep = report.dup begin - send(method, report) + newrep.extend(mod) + if mod.useyaml? + newrep.process(yaml) + else + newrep.process + end rescue => detail if Puppet[:trace] puts detail.backtrace |