lib/puppet/provider/parsedfile.rb in puppet-3.1.1 vs lib/puppet/provider/parsedfile.rb in puppet-3.2.0.rc1
- old
+ new
@@ -101,10 +101,41 @@
%{# HEADER: This file was autogenerated at #{Time.now}
# HEADER: by puppet. While it can still be managed manually, it
# HEADER: is definitely not recommended.\n}
end
+ # An optional regular expression matched by third party headers.
+ #
+ # For example, this can be used to filter the vixie cron headers as
+ # erronously exported by older cron versions.
+ #
+ # @api private
+ # @abstract Providers based on ParsedFile may implement this to make it
+ # possible to identify a header maintained by a third party tool.
+ # The provider can then allow that header to remain near the top of the
+ # written file, or remove it after composing the file content.
+ # If implemented, the function must return a Regexp object.
+ # The expression must be tailored to match exactly one third party header.
+ # @see drop_native_header
+ # @note When specifying regular expressions in multiline mode, avoid
+ # greedy repititions such as '.*' (use .*? instead). Otherwise, the
+ # provider may drop file content between sparse headers.
+ def self.native_header_regex
+ nil
+ end
+
+ # How to handle third party headers.
+ # @api private
+ # @abstract Providers based on ParsedFile that make use of the support for
+ # third party headers may override this method to return +true+.
+ # When this is done, headers that are matched by the native_header_regex
+ # are not written back to disk.
+ # @see native_header_regex
+ def self.drop_native_header
+ false
+ end
+
# Add another type var.
def self.initvars
@records = []
@target_objects = {}
@@ -184,41 +215,69 @@
@records = prefetch_all_targets(resources)
match_providers_with_resources(resources)
end
+ # Match a list of catalog resources with provider instances
+ #
+ # @api private
+ #
+ # @param [Array<Puppet::Resource>] resources A list of resources using this class as a provider
def self.match_providers_with_resources(resources)
return unless resources
matchers = resources.dup
@records.each do |record|
# Skip things like comments and blank lines
next if skip_record?(record)
- if name = record[:name] and resource = resources[name]
+ if (resource = resource_for_record(record, resources))
resource.provider = new(record)
elsif respond_to?(:match)
if resource = match(record, matchers)
- # Remove this resource from circulation so we don't unnecessarily try to match
matchers.delete(resource.title)
record[:name] = resource[:name]
resource.provider = new(record)
end
end
end
end
+ # Look up a resource based on a parsed file record
+ #
+ # @api private
+ #
+ # @param [Hash<Symbol, Object>] record
+ # @param [Array<Puppet::Resource>] resources
+ #
+ # @return [Puppet::Resource, nil] The resource if found, else nil
+ def self.resource_for_record(record, resources)
+ name = record[:name]
+ if name
+ resources[name]
+ end
+ end
+
def self.prefetch_all_targets(resources)
records = []
targets(resources).each do |target|
records += prefetch_target(target)
end
records
end
# Prefetch an individual target.
def self.prefetch_target(target)
- target_records = retrieve(target).each do |r|
+
+ begin
+ target_records = retrieve(target)
+ rescue Puppet::Util::FileType::FileReadError => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not prefetch #{self.resource_type.name} provider '#{self.name}' target '#{target}': #{detail}. Treating as empty"
+ target_records = []
+ end
+
+ target_records.each do |r|
r[:on_disk] = true
r[:target] = target
r[:ensure] = :present
end
@@ -297,11 +356,29 @@
end
targets.uniq.compact
end
+ # Compose file contents from the set of records.
+ #
+ # If self.native_header_regex is not nil, possible vendor headers are
+ # identified by matching the return value against the expression.
+ # If one (or several consecutive) such headers, are found, they are
+ # either moved in front of the self.header if self.drop_native_header
+ # is false (this is the default), or removed from the return value otherwise.
+ #
+ # @api private
def self.to_file(records)
text = super
+ if native_header_regex and (match = text.match(native_header_regex))
+ if drop_native_header
+ # concatenate the text in front of and after the native header
+ text = match.pre_match + match.post_match
+ else
+ native_header = match[0]
+ return native_header + header + match.pre_match + match.post_match
+ end
+ end
header + text
end
def create
@resource.class.validproperties.each do |property|