summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet')
-rw-r--r--lib/puppet/application/inspect.rb18
-rw-r--r--lib/puppet/configurer.rb12
-rw-r--r--lib/puppet/parser/ast.rb4
-rw-r--r--lib/puppet/relationship.rb4
-rw-r--r--lib/puppet/resource.rb4
-rw-r--r--lib/puppet/resource/status.rb25
-rw-r--r--lib/puppet/resource/type_collection.rb4
-rw-r--r--lib/puppet/simple_graph.rb4
-rw-r--r--lib/puppet/transaction.rb29
-rw-r--r--lib/puppet/transaction/change.rb75
-rw-r--r--lib/puppet/transaction/event.rb13
-rw-r--r--lib/puppet/transaction/report.rb62
-rw-r--r--lib/puppet/transaction/resource_harness.rb143
-rw-r--r--lib/puppet/type.rb2
-rw-r--r--lib/puppet/type/file.rb2
-rw-r--r--lib/puppet/type/file/ctime.rb18
-rw-r--r--lib/puppet/type/file/mtime.rb17
-rwxr-xr-xlib/puppet/type/file/type.rb17
-rw-r--r--lib/puppet/util/checksums.rb11
-rw-r--r--lib/puppet/util/log.rb6
-rw-r--r--lib/puppet/util/log_paths.rb2
-rw-r--r--lib/puppet/util/logging.rb2
-rw-r--r--lib/puppet/util/metric.rb1
23 files changed, 262 insertions, 213 deletions
diff --git a/lib/puppet/application/inspect.rb b/lib/puppet/application/inspect.rb
index c76f9e4da..8c3a0011f 100644
--- a/lib/puppet/application/inspect.rb
+++ b/lib/puppet/application/inspect.rb
@@ -49,10 +49,10 @@ class Puppet::Application::Inspect < Puppet::Application
raise "Could not find catalog for #{Puppet[:certname]}"
end
- retrieval_time = Time.now - retrieval_starttime
- @report.add_times("config_retrieval", retrieval_time)
+ @report.configuration_version = catalog.version
- starttime = Time.now
+ inspect_starttime = Time.now
+ @report.add_times("config_retrieval", inspect_starttime - retrieval_starttime)
catalog.to_ral.resources.each do |ral_resource|
audited_attributes = ral_resource[:audit]
@@ -62,13 +62,19 @@ class Puppet::Application::Inspect < Puppet::Application
status = Puppet::Resource::Status.new(ral_resource)
audited_attributes.each do |name|
- event = ral_resource.event(:previous_value => audited_resource[name], :property => name, :status => "audit", :message => "inspected value is #{audited_resource[name].inspect}")
- status.add_event(event)
+ next if audited_resource[name].nil?
+ # Skip :absent properties of :absent resources. Really, it would be nicer if the RAL returned nil for those, but it doesn't. ~JW
+ if name == :ensure or audited_resource[:ensure] != :absent or audited_resource[name] != :absent
+ event = ral_resource.event(:previous_value => audited_resource[name], :property => name, :status => "audit", :message => "inspected value is #{audited_resource[name].inspect}")
+ status.add_event(event)
+ end
end
@report.add_resource_status(status)
end
- @report.add_metric(:time, {"config_retrieval" => retrieval_time, "inspect" => Time.now - starttime})
+ finishtime = Time.now
+ @report.add_times("inspect", finishtime - inspect_starttime)
+ @report.finalize_report
begin
Puppet::Transaction::Report.indirection.save(@report)
diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb
index 50aaa0d1f..72e387c64 100644
--- a/lib/puppet/configurer.rb
+++ b/lib/puppet/configurer.rb
@@ -72,10 +72,6 @@ class Puppet::Configurer
@splayed = false
end
- def initialize_report
- Puppet::Transaction::Report.new
- end
-
# Prepare for catalog retrieval. Downloads everything necessary, etc.
def prepare(options)
dostorage
@@ -134,7 +130,7 @@ class Puppet::Configurer
Puppet.err "Failed to prepare catalog: #{detail}"
end
- options[:report] ||= initialize_report
+ options[:report] ||= Puppet::Transaction::Report.new("apply")
report = options[:report]
Puppet::Util::Log.newdestination(report)
@@ -145,6 +141,8 @@ class Puppet::Configurer
return
end
+ report.configuration_version = catalog.version
+
transaction = nil
begin
@@ -171,8 +169,8 @@ class Puppet::Configurer
send_report(report, transaction)
end
- def send_report(report, trans = nil)
- trans.generate_report if trans
+ def send_report(report, trans)
+ report.finalize_report if trans
puts report.summary if Puppet[:summarize]
save_last_run_summary(report)
if Puppet[:report]
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index 03891160b..122b4dd7a 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -19,6 +19,10 @@ class Puppet::Parser::AST
attr_accessor :parent, :scope
+ def inspect
+ "( #{self.class} #{self.to_s} #{@children.inspect} )"
+ end
+
# don't fetch lexer comment by default
def use_docs
self.class.use_docs
diff --git a/lib/puppet/relationship.rb b/lib/puppet/relationship.rb
index 7079fb44b..08d7d042b 100644
--- a/lib/puppet/relationship.rb
+++ b/lib/puppet/relationship.rb
@@ -71,6 +71,10 @@ class Puppet::Relationship
"#{source} => #{target}"
end
+ def inspect
+ "{ #{source} => #{target} }"
+ end
+
def to_pson_data_hash
data = {
'source' => source.to_s,
diff --git a/lib/puppet/resource.rb b/lib/puppet/resource.rb
index 4f0d50750..b0a3ecee6 100644
--- a/lib/puppet/resource.rb
+++ b/lib/puppet/resource.rb
@@ -46,6 +46,10 @@ class Puppet::Resource
resource
end
+ def inspect
+ "#{@type}[#{@title}]#{to_hash.inspect}"
+ end
+
def to_pson_data_hash
data = ([:type, :title, :tags] + ATTRIBUTES).inject({}) do |hash, param|
next hash unless value = self.send(param)
diff --git a/lib/puppet/resource/status.rb b/lib/puppet/resource/status.rb
index 2bdfbbfef..ee83004bb 100644
--- a/lib/puppet/resource/status.rb
+++ b/lib/puppet/resource/status.rb
@@ -4,13 +4,15 @@ module Puppet
include Puppet::Util::Tagging
include Puppet::Util::Logging
- ATTRIBUTES = [:resource, :node, :version, :file, :line, :current_values, :skipped_reason, :status, :evaluation_time, :change_count]
- attr_accessor *ATTRIBUTES
+ attr_accessor :resource, :node, :file, :line, :current_values, :status, :evaluation_time
STATES = [:skipped, :failed, :failed_to_restart, :restarted, :changed, :out_of_sync, :scheduled]
attr_accessor *STATES
attr_reader :source_description, :default_log_level, :time, :resource
+ attr_reader :change_count, :out_of_sync_count, :resource_type, :title
+
+ YAML_ATTRIBUTES = %w{@resource @file @line @evaluation_time @change_count @out_of_sync_count @tags @time @events @out_of_sync @changed @resource_type @title}
# Provide a boolean method for each of the states.
STATES.each do |attr|
@@ -28,6 +30,13 @@ module Puppet
@events << event
if event.status == 'failure'
self.failed = true
+ elsif event.status == 'success'
+ @change_count += 1
+ @changed = true
+ end
+ if event.status != 'audit'
+ @out_of_sync_count += 1
+ @out_of_sync = true
end
end
@@ -38,14 +47,24 @@ module Puppet
def initialize(resource)
@source_description = resource.path
@resource = resource.to_s
+ @change_count = 0
+ @out_of_sync_count = 0
+ @changed = false
+ @out_of_sync = false
- [:file, :line, :version].each do |attr|
+ [:file, :line].each do |attr|
send(attr.to_s + "=", resource.send(attr))
end
tag(*resource.tags)
@time = Time.now
@events = []
+ @resource_type = resource.type.to_s.capitalize
+ @title = resource.title
+ end
+
+ def to_yaml_properties
+ (YAML_ATTRIBUTES & instance_variables).sort
end
private
diff --git a/lib/puppet/resource/type_collection.rb b/lib/puppet/resource/type_collection.rb
index a96927613..6ab978f7c 100644
--- a/lib/puppet/resource/type_collection.rb
+++ b/lib/puppet/resource/type_collection.rb
@@ -25,6 +25,10 @@ class Puppet::Resource::TypeCollection
end
end
+ def inspect
+ "TypeCollection" + { :hostclasses => @hostclasses.keys, :definitions => @definitions.keys, :nodes => @nodes.keys }.inspect
+ end
+
def <<(thing)
add(thing)
self
diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb
index 6d153b46d..9d7f218a6 100644
--- a/lib/puppet/simple_graph.rb
+++ b/lib/puppet/simple_graph.rb
@@ -395,6 +395,10 @@ class Puppet::SimpleGraph
@vertex = vertex
@adjacencies = adjacencies
end
+
+ def inspect
+ { :@adjacencies => @adjacencies, :@vertex => @vertex.to_s }.inspect
+ end
end
# instance_variable_get is used by Object.to_zaml to get instance
diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb
index 4c0ea9ac5..eba601cfe 100644
--- a/lib/puppet/transaction.rb
+++ b/lib/puppet/transaction.rb
@@ -6,7 +6,6 @@ require 'puppet/util/tagging'
require 'puppet/application'
class Puppet::Transaction
- require 'puppet/transaction/change'
require 'puppet/transaction/event'
require 'puppet/transaction/event_manager'
require 'puppet/transaction/resource_harness'
@@ -222,12 +221,6 @@ class Puppet::Transaction
end
end
- # Generate a transaction report.
- def generate_report
- @report.calculate_metrics
- @report
- end
-
# Should we ignore tags?
def ignore_tags?
! (@catalog.host_config? or Puppet[:name] == "puppet")
@@ -238,7 +231,7 @@ class Puppet::Transaction
def initialize(catalog)
@catalog = catalog
- @report = Report.new
+ @report = Puppet::Transaction::Report.new("apply")
@event_manager = Puppet::Transaction::EventManager.new(self)
@@ -285,26 +278,6 @@ class Puppet::Transaction
catalog.relationship_graph
end
- # Send off the transaction report.
- def send_report
- begin
- report = generate_report
- rescue => detail
- Puppet.err "Could not generate report: #{detail}"
- return
- end
-
- puts report.summary if Puppet[:summarize]
-
- if Puppet[:report]
- begin
- Puppet::Transaction::Report.indirection.save(report)
- rescue => detail
- Puppet.err "Reporting failed: #{detail}"
- end
- end
- end
-
def add_resource_status(status)
report.add_resource_status status
end
diff --git a/lib/puppet/transaction/change.rb b/lib/puppet/transaction/change.rb
deleted file mode 100644
index d57ac1917..000000000
--- a/lib/puppet/transaction/change.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require 'puppet/transaction'
-require 'puppet/transaction/event'
-
-# Handle all of the work around performing an actual change,
-# including calling 'sync' on the properties and producing events.
-class Puppet::Transaction::Change
- attr_accessor :is, :should, :property, :proxy, :auditing, :old_audit_value
-
- def auditing?
- auditing
- end
-
- def initialize(property, currentvalue)
- @property = property
- @is = currentvalue
-
- @should = property.should
-
- @changed = false
- end
-
- def apply
- event = property.event
- event.previous_value = is
- event.desired_value = should
- event.historical_value = old_audit_value
-
- if auditing? and old_audit_value != is
- event.message = "audit change: previously recorded value #{property.is_to_s(old_audit_value)} has been changed to #{property.is_to_s(is)}"
- event.status = "audit"
- event.audited = true
- brief_audit_message = " (previously recorded value was #{property.is_to_s(old_audit_value)})"
- else
- brief_audit_message = ""
- end
-
- if property.insync?(is)
- # nothing happens
- elsif noop?
- event.message = "is #{property.is_to_s(is)}, should be #{property.should_to_s(should)} (noop)#{brief_audit_message}"
- event.status = "noop"
- else
- property.sync
- event.message = [ property.change_to_s(is, should), brief_audit_message ].join
- event.status = "success"
- end
- event
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- event.status = "failure"
-
- event.message = "change from #{property.is_to_s(is)} to #{property.should_to_s(should)} failed: #{detail}"
- event
- ensure
- event.send_log
- end
-
- # Is our property noop? This is used for generating special events.
- def noop?
- @property.noop
- end
-
- # The resource that generated this change. This is used for handling events,
- # and the proxy resource is used for generated resources, since we can't
- # send an event to a resource we don't have a direct relationship with. If we
- # have a proxy resource, then the events will be considered to be from
- # that resource, rather than us, so the graph resolution will still work.
- def resource
- self.proxy || @property.resource
- end
-
- def to_s
- "change #{@property.change_to_s(@is, @should)}"
- end
-end
diff --git a/lib/puppet/transaction/event.rb b/lib/puppet/transaction/event.rb
index da5b14727..cd695cff8 100644
--- a/lib/puppet/transaction/event.rb
+++ b/lib/puppet/transaction/event.rb
@@ -7,7 +7,8 @@ class Puppet::Transaction::Event
include Puppet::Util::Tagging
include Puppet::Util::Logging
- ATTRIBUTES = [:name, :resource, :property, :previous_value, :desired_value, :historical_value, :status, :message, :node, :version, :file, :line, :source_description, :audited]
+ ATTRIBUTES = [:name, :resource, :property, :previous_value, :desired_value, :historical_value, :status, :message, :file, :line, :source_description, :audited]
+ YAML_ATTRIBUTES = %w{@audited @property @previous_value @desired_value @historical_value @message @name @status @time}
attr_accessor *ATTRIBUTES
attr_writer :tags
attr_accessor :time
@@ -15,9 +16,9 @@ class Puppet::Transaction::Event
EVENT_STATUSES = %w{noop success failure audit}
- def initialize(*args)
- options = args.last.is_a?(Hash) ? args.pop : ATTRIBUTES.inject({}) { |hash, attr| hash[attr] = args.pop; hash }
- options.each { |attr, value| send(attr.to_s + "=", value) unless value.nil? }
+ def initialize(options = {})
+ @audited = false
+ options.each { |attr, value| send(attr.to_s + "=", value) }
@time = Time.now
end
@@ -46,6 +47,10 @@ class Puppet::Transaction::Event
message
end
+ def to_yaml_properties
+ (YAML_ATTRIBUTES & instance_variables).sort
+ end
+
private
# If it's a failure, use 'err', else use either the resource's log level (if available)
diff --git a/lib/puppet/transaction/report.rb b/lib/puppet/transaction/report.rb
index 492d15da2..16fee42ae 100644
--- a/lib/puppet/transaction/report.rb
+++ b/lib/puppet/transaction/report.rb
@@ -10,7 +10,8 @@ class Puppet::Transaction::Report
indirects :report, :terminus_class => :processor
- attr_reader :resource_statuses, :logs, :metrics, :host, :time, :kind
+ attr_accessor :configuration_version
+ attr_reader :resource_statuses, :logs, :metrics, :host, :time, :kind, :status
# This is necessary since Marshall doesn't know how to
# dump hash with default proc (see below @records)
@@ -42,14 +43,26 @@ class Puppet::Transaction::Report
@resource_statuses[status.resource] = status
end
- def calculate_metrics
- calculate_resource_metrics
- calculate_time_metrics
- calculate_change_metrics
- calculate_event_metrics
+ def compute_status(resource_metrics, change_metric)
+ if (resource_metrics["failed"] || 0) > 0
+ 'failed'
+ elsif change_metric > 0
+ 'changed'
+ else
+ 'unchanged'
+ end
+ end
+
+ def finalize_report
+ resource_metrics = add_metric(:resources, calculate_resource_metrics)
+ add_metric(:time, calculate_time_metrics)
+ change_metric = calculate_change_metric
+ add_metric(:changes, {"total" => change_metric})
+ add_metric(:events, calculate_event_metrics)
+ @status = compute_status(resource_metrics, change_metric)
end
- def initialize(kind = "apply")
+ def initialize(kind, configuration_version=nil)
@metrics = {}
@logs = []
@resource_statuses = {}
@@ -57,6 +70,10 @@ class Puppet::Transaction::Report
@host = Puppet[:certname]
@time = Time.now
@kind = kind
+ @report_format = 2
+ @puppet_version = Puppet.version
+ @configuration_version = configuration_version
+ @status = 'failed' # assume failed until the report is finalized
end
def name
@@ -111,44 +128,45 @@ class Puppet::Transaction::Report
# individual bits represent the presence of different metrics.
def exit_status
status = 0
- status |= 2 if @metrics["changes"][:total] > 0
- status |= 4 if @metrics["resources"][:failed] > 0
+ status |= 2 if @metrics["changes"]["total"] > 0
+ status |= 4 if @metrics["resources"]["failed"] > 0
status
end
+ def to_yaml_properties
+ (instance_variables - ["@external_times"]).sort
+ end
+
private
- def calculate_change_metrics
- metrics = Hash.new(0)
- resource_statuses.each do |name, status|
- metrics[:total] += status.change_count if status.change_count
- end
- add_metric(:changes, metrics)
+ def calculate_change_metric
+ resource_statuses.map { |name, status| status.change_count || 0 }.inject(0) { |a,b| a+b }
end
def calculate_event_metrics
metrics = Hash.new(0)
+ metrics["total"] = 0
resource_statuses.each do |name, status|
- metrics[:total] += status.events.length
+ metrics["total"] += status.events.length
status.events.each do |event|
metrics[event.status] += 1
end
end
- add_metric(:events, metrics)
+ metrics
end
def calculate_resource_metrics
metrics = Hash.new(0)
- metrics[:total] = resource_statuses.length
+ metrics["total"] = resource_statuses.length
resource_statuses.each do |name, status|
Puppet::Resource::Status::STATES.each do |state|
- metrics[state] += 1 if status.send(state)
+ metrics[state.to_s] += 1 if status.send(state)
end
end
- add_metric(:resources, metrics)
+ metrics
end
def calculate_time_metrics
@@ -162,6 +180,8 @@ class Puppet::Transaction::Report
metrics[name.to_s.downcase] = value
end
- add_metric(:time, metrics)
+ metrics["total"] = metrics.values.inject(0) { |a,b| a+b }
+
+ metrics
end
end
diff --git a/lib/puppet/transaction/resource_harness.rb b/lib/puppet/transaction/resource_harness.rb
index c978e5545..c259d3e05 100644
--- a/lib/puppet/transaction/resource_harness.rb
+++ b/lib/puppet/transaction/resource_harness.rb
@@ -7,22 +7,15 @@ class Puppet::Transaction::ResourceHarness
attr_reader :transaction
def allow_changes?(resource)
- return true unless resource.purging? and resource.deleting?
- return true unless deps = relationship_graph.dependents(resource) and ! deps.empty? and deps.detect { |d| ! d.deleting? }
-
- deplabel = deps.collect { |r| r.ref }.join(",")
- plurality = deps.length > 1 ? "":"s"
- resource.warning "#{deplabel} still depend#{plurality} on me -- not purging"
- false
- end
-
- def apply_changes(status, changes)
- changes.each do |change|
- status << change.apply
-
- cache(change.property.resource, change.property.name, change.is) if change.auditing?
+ if resource.purging? and resource.deleting? and deps = relationship_graph.dependents(resource) \
+ and ! deps.empty? and deps.detect { |d| ! d.deleting? }
+ deplabel = deps.collect { |r| r.ref }.join(",")
+ plurality = deps.length > 1 ? "":"s"
+ resource.warning "#{deplabel} still depend#{plurality} on me -- not purging"
+ false
+ else
+ true
end
- status.changed = true
end
# Used mostly for scheduling and auditing at this point.
@@ -35,66 +28,114 @@ class Puppet::Transaction::ResourceHarness
Puppet::Util::Storage.cache(resource)[name] = value
end
- def changes_to_perform(status, resource)
+ def perform_changes(resource)
current = resource.retrieve_resource
cache resource, :checked, Time.now
return [] if ! allow_changes?(resource)
- audited = copy_audited_parameters(resource, current)
+ current_values = current.to_hash
+ historical_values = Puppet::Util::Storage.cache(resource).dup
+ desired_values = resource.to_resource.to_hash
+ audited_params = (resource[:audit] || []).map { |p| p.to_sym }
+ synced_params = []
- if param = resource.parameter(:ensure)
- return [] if absent_and_not_being_created?(current, param)
- unless ensure_is_insync?(current, param)
- audited.keys.reject{|name| name == :ensure}.each do |name|
- resource.parameter(name).notice "audit change: previously recorded value #{audited[name]} has been changed to #{current[param]}"
- cache(resource, name, current[param])
+ # Record the current state in state.yml.
+ audited_params.each do |param|
+ cache(resource, param, current_values[param])
+ end
+
+ # Update the machine state & create logs/events
+ events = []
+ ensure_param = resource.parameter(:ensure)
+ if desired_values[:ensure] && !ensure_param.insync?(current_values[:ensure])
+ events << apply_parameter(ensure_param, current_values[:ensure], audited_params.include?(:ensure), historical_values[:ensure])
+ synced_params << :ensure
+ elsif current_values[:ensure] != :absent
+ work_order = resource.properties # Note: only the resource knows what order to apply changes in
+ work_order.each do |param|
+ if !param.insync?(current_values[param.name])
+ events << apply_parameter(param, current_values[param.name], audited_params.include?(param.name), historical_values[param.name])
+ synced_params << param.name
end
- return [Puppet::Transaction::Change.new(param, current[:ensure])]
end
- return [] if ensure_should_be_absent?(current, param)
end
- resource.properties.reject { |param| param.name == :ensure }.select do |param|
- (audited.include?(param.name) && audited[param.name] != current[param.name]) || (param.should != nil && !param_is_insync?(current, param))
- end.collect do |param|
- change = Puppet::Transaction::Change.new(param, current[param.name])
- change.auditing = true if audited.include?(param.name)
- change.old_audit_value = audited[param.name]
- change
+ # Add more events to capture audit results
+ audited_params.each do |param_name|
+ if historical_values.include?(param_name)
+ if historical_values[param_name] != current_values[param_name] && !synced_params.include?(param_name)
+ event = create_change_event(resource.parameter(param_name), current_values[param_name], true, historical_values[param_name])
+ event.send_log
+ events << event
+ end
+ else
+ resource.property(param_name).notice "audit change: newly-recorded value #{current_values[param_name]}"
+ end
end
+
+ events
end
- def copy_audited_parameters(resource, current)
- return {} unless audit = resource[:audit]
- audit = Array(audit).collect { |p| p.to_sym }
- audited = {}
- audit.find_all do |param|
- if value = cached(resource, param)
- audited[param] = value
- else
- resource.property(param).notice "audit change: newly-recorded recorded value #{current[param]}"
- cache(resource, param, current[param])
+ def create_change_event(property, current_value, do_audit, historical_value)
+ event = property.event
+ event.previous_value = current_value
+ event.desired_value = property.should
+ event.historical_value = historical_value
+
+ if do_audit
+ event.audited = true
+ event.status = "audit"
+ if historical_value != current_value
+ event.message = "audit change: previously recorded value #{property.is_to_s(historical_value)} has been changed to #{property.is_to_s(current_value)}"
end
end
- audited
+ event
+ end
+
+ def apply_parameter(property, current_value, do_audit, historical_value)
+ event = create_change_event(property, current_value, do_audit, historical_value)
+
+ if do_audit && historical_value && historical_value != current_value
+ brief_audit_message = " (previously recorded value was #{property.is_to_s(historical_value)})"
+ else
+ brief_audit_message = ""
+ end
+
+ if property.noop
+ event.message = "current_value #{property.is_to_s(current_value)}, should be #{property.should_to_s(property.should)} (noop)#{brief_audit_message}"
+ event.status = "noop"
+ else
+ property.sync
+ event.message = [ property.change_to_s(current_value, property.should), brief_audit_message ].join
+ event.status = "success"
+ end
+ event
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ event.status = "failure"
+
+ event.message = "change from #{property.is_to_s(current_value)} to #{property.should_to_s(property.should)} failed: #{detail}"
+ event
+ ensure
+ event.send_log
end
def evaluate(resource)
start = Time.now
status = Puppet::Resource::Status.new(resource)
- if changes = changes_to_perform(status, resource) and ! changes.empty?
- status.out_of_sync = true
- status.change_count = changes.length
- apply_changes(status, changes)
- if ! resource.noop?
- cache(resource, :synced, Time.now)
- resource.flush if resource.respond_to?(:flush)
- end
+ perform_changes(resource).each do |event|
+ status << event
end
+
+ if status.changed? && ! resource.noop?
+ cache(resource, :synced, Time.now)
+ resource.flush if resource.respond_to?(:flush)
+ end
+
return status
rescue => detail
resource.fail "Could not create resource status: #{detail}" unless status
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index 1b6e7dcd7..ea3944b4e 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -446,7 +446,7 @@ class Type
# Create a transaction event. Called by Transaction or by
# a property.
def event(options = {})
- Puppet::Transaction::Event.new({:resource => self, :file => file, :line => line, :tags => tags, :version => version}.merge(options))
+ Puppet::Transaction::Event.new({:resource => self, :file => file, :line => line, :tags => tags}.merge(options))
end
# Let the catalog determine whether a given cached value is
diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb
index b3461277c..457afd4f5 100644
--- a/lib/puppet/type/file.rb
+++ b/lib/puppet/type/file.rb
@@ -797,3 +797,5 @@ require 'puppet/type/file/group'
require 'puppet/type/file/mode'
require 'puppet/type/file/type'
require 'puppet/type/file/selcontext' # SELinux file context
+require 'puppet/type/file/ctime'
+require 'puppet/type/file/mtime'
diff --git a/lib/puppet/type/file/ctime.rb b/lib/puppet/type/file/ctime.rb
new file mode 100644
index 000000000..24b098703
--- /dev/null
+++ b/lib/puppet/type/file/ctime.rb
@@ -0,0 +1,18 @@
+module Puppet
+ Puppet::Type.type(:file).newproperty(:ctime) do
+ desc "A read-only state to check the file ctime."
+
+ def retrieve
+ current_value = :absent
+ if stat = @resource.stat(false)
+ current_value = stat.ctime
+ end
+ current_value
+ end
+
+ validate do
+ fail "ctime is read-only"
+ end
+ end
+end
+
diff --git a/lib/puppet/type/file/mtime.rb b/lib/puppet/type/file/mtime.rb
new file mode 100644
index 000000000..8ca7ed0d6
--- /dev/null
+++ b/lib/puppet/type/file/mtime.rb
@@ -0,0 +1,17 @@
+module Puppet
+ Puppet::Type.type(:file).newproperty(:mtime) do
+ desc "A read-only state to check the file mtime."
+
+ def retrieve
+ current_value = :absent
+ if stat = @resource.stat(false)
+ current_value = stat.mtime
+ end
+ current_value
+ end
+
+ validate do
+ fail "mtime is read-only"
+ end
+ end
+end
diff --git a/lib/puppet/type/file/type.rb b/lib/puppet/type/file/type.rb
index eb50b81f9..4da54e2cb 100755
--- a/lib/puppet/type/file/type.rb
+++ b/lib/puppet/type/file/type.rb
@@ -3,23 +3,16 @@ module Puppet
require 'etc'
desc "A read-only state to check the file type."
- #munge do |value|
- # raise Puppet::Error, ":type is read-only"
- #end
-
def retrieve
- currentvalue = :absent
+ current_value = :absent
if stat = @resource.stat(false)
- currentvalue = stat.ftype
+ current_value = stat.ftype
end
- # so this state is never marked out of sync
- @should = [currentvalue]
- currentvalue
+ current_value
end
-
- def sync
- raise Puppet::Error, ":type is read-only"
+ validate do
+ fail "type is read-only"
end
end
end
diff --git a/lib/puppet/util/checksums.rb b/lib/puppet/util/checksums.rb
index 5aebd8392..6fdf14ecf 100644
--- a/lib/puppet/util/checksums.rb
+++ b/lib/puppet/util/checksums.rb
@@ -1,6 +1,12 @@
# A stand-alone module for calculating checksums
# in a generic way.
module Puppet::Util::Checksums
+ class FakeChecksum
+ def <<(*args)
+ self
+ end
+ end
+
# Is the provided string a checksum?
def checksum?(string)
string =~ /^\{(\w{3,5})\}\S+/
@@ -55,7 +61,10 @@ module Puppet::Util::Checksums
end
# by definition this doesn't exist
+ # but we still need to execute the block given
def mtime_stream
+ noop_digest = FakeChecksum.new
+ yield noop_digest
nil
end
@@ -105,6 +114,8 @@ module Puppet::Util::Checksums
end
def none_stream
+ noop_digest = FakeChecksum.new
+ yield noop_digest
""
end
diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb
index 9a9e291a6..2f9f356bb 100644
--- a/lib/puppet/util/log.rb
+++ b/lib/puppet/util/log.rb
@@ -190,7 +190,7 @@ class Puppet::Util::Log
@levels.include?(level)
end
- attr_accessor :time, :remote, :file, :line, :version, :source
+ attr_accessor :time, :remote, :file, :line, :source
attr_reader :level, :message
def initialize(args)
@@ -204,7 +204,7 @@ class Puppet::Util::Log
tags.each { |t| self.tag(t) }
end
- [:file, :line, :version].each do |attr|
+ [:file, :line].each do |attr|
next unless value = args[attr]
send(attr.to_s + "=", value)
end
@@ -235,7 +235,7 @@ class Puppet::Util::Log
descriptors[:tags].each { |t| tag(t) }
- [:file, :line, :version].each do |param|
+ [:file, :line].each do |param|
next unless descriptors[param]
send(param.to_s + "=", descriptors[param])
end
diff --git a/lib/puppet/util/log_paths.rb b/lib/puppet/util/log_paths.rb
index f59197ed1..2fefd4505 100644
--- a/lib/puppet/util/log_paths.rb
+++ b/lib/puppet/util/log_paths.rb
@@ -15,7 +15,7 @@ module Puppet::Util::LogPaths
descriptors[:tags] = tags
- [:path, :file, :line, :version].each do |param|
+ [:path, :file, :line].each do |param|
next unless value = send(param)
descriptors[param] = value
end
diff --git a/lib/puppet/util/logging.rb b/lib/puppet/util/logging.rb
index f20444a3b..bc52b17f0 100644
--- a/lib/puppet/util/logging.rb
+++ b/lib/puppet/util/logging.rb
@@ -26,7 +26,7 @@ module Puppet::Util::Logging
end
def log_metadata
- [:file, :line, :version, :tags].inject({}) do |result, attr|
+ [:file, :line, :tags].inject({}) do |result, attr|
result[attr] = send(attr) if respond_to?(attr)
result
end
diff --git a/lib/puppet/util/metric.rb b/lib/puppet/util/metric.rb
index 7fdc6951f..835e1d610 100644
--- a/lib/puppet/util/metric.rb
+++ b/lib/puppet/util/metric.rb
@@ -132,6 +132,7 @@ class Puppet::Util::Metric
end
def newvalue(name,value,label = nil)
+ raise ArgumentError.new("metric name #{name.inspect} is not a string") unless name.is_a? String
label ||= self.class.labelize(name)
@values.push [name,label,value]
end