Permalink
Browse files

Merge branch '2.6.next' into 2.6.x

* 2.6.next:
  Fix #4339 - Locally save the last report to $lastrunreport
  Fix #4339 - Save a last run report summary to $statedir/last_run_summary.yaml
  Fixed #3127 - removed legacy debug code
  Fixed #3127 - Fixed gem selection regex
  (#5437) Invalidate cached TypeCollection when there was an error parsing
  (#6937) Adjust formatting of recurse's desc
  (#6937) Document the recurse parameter of File type.
  (#6893) Document the cron type in the case of specials.
  (#5670) Don't trigger refresh from a failed resource
  Fixed #6554 - Missing $haveftool if/else conditional in install.rb breaking Ruby 1.9
  • Loading branch information...
2 parents 1e4968e + f7c6db9 commit da4457be4dedaed5368bacf81a08f0429e21cd45 @MaxMartin MaxMartin committed Apr 7, 2011
View
@@ -92,8 +92,12 @@ def do_configs(configs, target, strip = 'conf/')
Dir.mkdir(target) unless File.directory? target
configs.each do |cf|
ocf = File.join(InstallOptions.config_dir, cf.gsub(/#{strip}/, ''))
- File.install(cf, ocf, 0644, true)
- end
+ if $haveftools
+ File.install(cf, ocf, 0644, true)
+ else
+ FileUtils.install(cf, ocf, {:mode => 0644, :verbose => true})
+ end
+ end
end
def do_bins(bins, target, strip = 's?bin/')
@@ -229,6 +229,8 @@ def setup
Puppet::SSL::Host.ca_location = options[:fingerprint] ? :none : :remote
Puppet::Transaction::Report.terminus_class = :rest
+ # we want the last report to be persisted locally
+ Puppet::Transaction::Report.cache_class = :yaml
# Override the default; puppetd needs this, usually.
# You can still override this on the command-line with, e.g., :compiler.
@@ -148,6 +148,9 @@ def setup
exit(1)
end
+ # we want the last report to be persisted locally
+ Puppet::Transaction::Report.cache_class = :yaml
+
if options[:debug]
Puppet::Util::Log.level = :debug
elsif options[:verbose]
@@ -166,19 +166,28 @@ def run(options = {})
execute_postrun_command
Puppet::Util::Log.close(report)
-
send_report(report, transaction)
end
def send_report(report, trans)
report.finalize_report if trans
puts report.summary if Puppet[:summarize]
+ save_last_run_summary(report)
report.save if Puppet[:report]
rescue => detail
puts detail.backtrace if Puppet[:trace]
Puppet.err "Could not send report: #{detail}"
end
+ def save_last_run_summary(report)
+ Puppet::Util::FileLocking.writelock(Puppet[:lastrunfile], 0660) do |file|
+ file.print YAML.dump(report.raw_summary)
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not save last run local report: #{detail}"
+ end
+
private
def self.timeout
@@ -607,6 +607,14 @@ module Puppet
:report => [false,
"Whether to send reports after every transaction."
],
+ :lastrunfile => { :default => "$statedir/last_run_summary.yaml",
+ :mode => 0660,
+ :desc => "Where puppet agent stores the last run report summary in yaml format."
+ },
+ :lastrunreport => { :default => "$statedir/last_run_report.yaml",
+ :mode => 0660,
+ :desc => "Where puppet agent stores the last run report in yaml format."
+ },
:graph => [false, "Whether to create dot graph files for the different
configuration graphs. These dot files can be interpreted by tools
like OmniGraffle or dot (which is part of ImageMagick)."],
@@ -0,0 +1,11 @@
+require 'puppet/transaction/report'
+require 'puppet/indirector/yaml'
+
+class Puppet::Transaction::Report::Yaml < Puppet::Indirector::Yaml
+ desc "Store last report as a flat file, serialized using YAML."
+
+ # Force report to be saved there
+ def path(name,ext='.yaml')
+ Puppet[:lastrunreport]
+ end
+end
@@ -79,7 +79,7 @@ def known_resource_types
# environment has changed do we delve deeper.
Thread.current[:known_resource_types] = nil if (krt = Thread.current[:known_resource_types]) && krt.environment != self
Thread.current[:known_resource_types] ||= synchronize {
- if @known_resource_types.nil? or @known_resource_types.stale?
+ if @known_resource_types.nil? or @known_resource_types.require_reparse?
@known_resource_types = Puppet::Resource::TypeCollection.new(self)
@known_resource_types.perform_initial_import
end
@@ -22,7 +22,7 @@ def self.gemlist(hash)
end
if name = hash[:justme]
- command << name
+ command << name + "$"
end
begin
@@ -94,7 +94,7 @@ def install(useversion = true)
command << "--source" << "#{source}" << resource[:name]
end
else
- command << resource[:name]
+ command << "--no-rdoc" << "--no-ri" << resource[:name]
end
output = execute(command)
@@ -166,12 +166,18 @@ def perform_initial_import
end
parser.parse
rescue => detail
+ @parse_failed = true
+
msg = "Could not parse for environment #{environment}: #{detail}"
error = Puppet::Error.new(msg)
error.set_backtrace(detail.backtrace)
raise error
end
+ def require_reparse?
+ @parse_failed || stale?
+ end
+
def stale?
@watched_files.values.detect { |file| file.changed? }
end
@@ -47,7 +47,7 @@ def any_failed?
def apply(resource, ancestor = nil)
status = resource_harness.evaluate(resource)
add_resource_status(status)
- event_manager.queue_events(ancestor || resource, status.events)
+ event_manager.queue_events(ancestor || resource, status.events) unless status.failed?
rescue => detail
resource.err "Could not evaluate: #{detail}"
end
@@ -80,30 +80,49 @@ def name
host
end
- # Provide a summary of this report.
+ # Provide a human readable textual summary of this report.
def summary
+ report = raw_summary
+
ret = ""
+ report.keys.sort { |a,b| a.to_s <=> b.to_s }.each do |key|
+ ret += "#{Puppet::Util::Metric.labelize(key)}:\n"
- @metrics.sort { |a,b| a[1].label <=> b[1].label }.each do |name, metric|
- ret += "#{metric.label}:\n"
- metric.values.sort { |a,b|
+ report[key].keys.sort { |a,b|
# sort by label
- if a[0] == :total
+ if a == :total
1
- elsif b[0] == :total
+ elsif b == :total
-1
else
- a[1] <=> b[1]
+ report[key][a].to_s <=> report[key][b].to_s
end
- }.each do |name, label, value|
+ }.each do |label|
+ value = report[key][label]
next if value == 0
value = "%0.2f" % value if value.is_a?(Float)
- ret += " %15s %s\n" % [label + ":", value]
+ ret += " %15s %s\n" % [Puppet::Util::Metric.labelize(label) + ":", value]
end
end
ret
end
+ # Provide a raw hash summary of this report.
+ def raw_summary
+ report = {}
+
+ @metrics.each do |name, metric|
+ key = metric.name.to_s
+ report[key] = {}
+ metric.values.each do |name, label, value|
+ report[key][name.to_s] = value
+ end
+ report[key]["total"] = 0 unless key == "time" or report[key].include?("total")
+ end
+ (report["time"] ||= {})["last_run"] = Time.now.tv_sec
+ report
+ end
+
# Based on the contents of this report's metrics, compute a single number
# that represents the report. The resulting number is a bitmask where
# individual bits represent the presence of different metrics.
@@ -142,7 +161,6 @@ def calculate_resource_metrics
metrics["total"] = resource_statuses.length
resource_statuses.each do |name, status|
-
Puppet::Resource::Status::STATES.each do |state|
metrics[state.to_s] += 1 if status.send(state)
end
@@ -226,7 +226,9 @@ def should
end
newproperty(:special) do
- desc "Special schedules"
+ desc "A special value such as 'reboot' or 'annually'.
+ Only available on supported systems such as Vixie Cron.
+ Overrides more specific time of day/week settings."
def specials
%w{reboot yearly annually monthly weekly daily midnight hourly}
@@ -122,7 +122,18 @@ def self.title_patterns
newparam(:recurse) do
desc "Whether and how deeply to do recursive
- management."
+ management. Options are:
+
+ * `inf,true` --- Regular style recursion on both remote and local
+ directory structure.
+ * `remote` --- Descends recursively into the remote directory
+ but not the local directory. Allows copying of
+ a few files into a directory containing many
+ unmanaged files without scanning all the local files.
+ * `false` --- Default of no recursion.
+ * `[0-9]+` --- Same as true, but limit recursion. Warning: this syntax
+ has been deprecated in favor of the `recurselimit` attribute.
+ "
newvalues(:true, :false, :inf, :remote, /^[0-9]+$/)
@@ -122,7 +122,7 @@ def graph(range = nil)
def initialize(name,label = nil)
@name = name.to_s
- @label = label || labelize(name)
+ @label = label || self.class.labelize(name)
@values = []
end
@@ -133,7 +133,7 @@ def path
def newvalue(name,value,label = nil)
raise ArgumentError.new("metric name #{name.inspect} is not a string") unless name.is_a? String
- label ||= labelize(name)
+ label ||= self.class.labelize(name)
@values.push [name,label,value]
end
@@ -174,10 +174,8 @@ def values
@values.sort { |a, b| a[1] <=> b[1] }
end
- private
-
# Convert a name into a label.
- def labelize(name)
+ def self.labelize(name)
name.to_s.capitalize.gsub("_", " ")
end
end
@@ -5,6 +5,8 @@
require 'puppet/configurer'
describe Puppet::Configurer do
+ include PuppetSpec::Files
+
describe "when downloading plugins" do
it "should use the :pluginsignore setting, split on whitespace, for ignoring remote files" do
resource = Puppet::Type.type(:notify).new :name => "yay"
@@ -17,19 +19,50 @@
end
describe "when running" do
- it "should send a transaction report with valid data" do
- catalog = Puppet::Resource::Catalog.new
- catalog.add_resource(Puppet::Type.type(:notify).new(:title => "testing"))
+ before(:each) do
+ @catalog = Puppet::Resource::Catalog.new
+ @catalog.add_resource(Puppet::Type.type(:notify).new(:title => "testing"))
- configurer = Puppet::Configurer.new
+ # Make sure we don't try to persist the local state after the transaction ran,
+ # because it will fail during test (the state file is in an not existing directory)
+ # and we need the transaction to be successful to be able to produce a summary report
+ @catalog.host_config = false
+
+ @configurer = Puppet::Configurer.new
+ end
+
+ it "should send a transaction report with valid data" do
+ @configurer.stubs(:save_last_run_summary)
Puppet::Transaction::Report.indirection.expects(:save).with do |x, report|
report.time.class == Time and report.logs.length > 0
end
Puppet[:report] = true
- configurer.run :catalog => catalog
+ @configurer.run :catalog => @catalog
+ end
+
+ it "should save a correct last run summary" do
+ report = Puppet::Transaction::Report.new("apply")
+ report.stubs(:save)
+
+ Puppet[:lastrunfile] = tmpfile("lastrunfile")
+ Puppet[:report] = true
+
+ @configurer.run :catalog => @catalog, :report => report
+
+ summary = nil
+ File.open(Puppet[:lastrunfile], "r") do |fd|
+ summary = YAML.load(fd.read)
+ end
+
+ summary.should be_a(Hash)
+ %w{time changes events resources}.each do |key|
+ summary.should be_key(key)
+ end
+ summary["time"].should be_key("notify")
+ summary["time"]["last_run"].should >= Time.now.tv_sec
end
end
end
Oops, something went wrong. Retry.

0 comments on commit da4457b

Please sign in to comment.