class Puppet::FileServing::Fileset
Operate recursively on a path, returning a set of file paths.
Constants
- FileSetEntry
Attributes
checksum_type[RW]
ignore[R]
links[R]
max_files[RW]
path[R]
recurse[RW]
recurselimit[RW]
Public Class Methods
merge(*filesets)
click to toggle source
Produce a hash of files, with merged so that earlier files with the same postfix win. E.g., /dir1/subfile beats /dir2/subfile. It's a hash because we need to know the relative path of each file, and the base directory.
This will probably only ever be used for searching for plugins.
# File lib/puppet/file_serving/fileset.rb 16 def self.merge(*filesets) 17 result = {} 18 19 filesets.each do |fileset| 20 fileset.files.each do |file| 21 result[file] ||= fileset.path 22 end 23 end 24 25 result 26 end
new(path, options = {})
click to toggle source
# File lib/puppet/file_serving/fileset.rb 28 def initialize(path, options = {}) 29 if Puppet::Util::Platform.windows? 30 # REMIND: UNC path 31 path = path.chomp(File::SEPARATOR) unless path =~ /^[A-Za-z]:\/$/ 32 else 33 path = path.chomp(File::SEPARATOR) unless path == File::SEPARATOR 34 end 35 raise ArgumentError.new(_("Fileset paths must be fully qualified: %{path}") % { path: path }) unless Puppet::Util.absolute_path?(path) 36 37 @path = path 38 39 # Set our defaults. 40 self.ignore = [] 41 self.links = :manage 42 @recurse = false 43 @recurselimit = :infinite 44 @max_files = 0 45 46 if options.is_a?(Puppet::Indirector::Request) 47 initialize_from_request(options) 48 else 49 initialize_from_hash(options) 50 end 51 52 raise ArgumentError.new(_("Fileset paths must exist")) unless valid?(path) 53 #TRANSLATORS "recurse" and "recurselimit" are parameter names and should not be translated 54 raise ArgumentError.new(_("Fileset recurse parameter must not be a number anymore, please use recurselimit")) if @recurse.is_a?(Integer) 55 end
Public Instance Methods
files()
click to toggle source
Return a list of all files in our fileset. This is different from the normal definition of find in that we support specific levels of recursion, which means we need to know when we're going another level deep, which Find doesn't do.
# File lib/puppet/file_serving/fileset.rb 61 def files 62 files = perform_recursion 63 soft_max_files = 1000 64 65 # munged_max_files is needed since puppet http handler is keeping negative numbers as strings 66 # https://github.com/puppetlabs/puppet/blob/main/lib/puppet/network/http/handler.rb#L196-L197 67 munged_max_files = max_files == '-1' ? -1 : max_files 68 69 if munged_max_files > 0 && files.size > munged_max_files 70 raise Puppet::Error.new _("The directory '%{path}' contains %{entries} entries, which exceeds the limit of %{munged_max_files} specified by the max_files parameter for this resource. The limit may be increased, but be aware that large number of file resources can result in excessive resource consumption and degraded performance. Consider using an alternate method to manage large directory trees") % { path: path, entries: files.size, munged_max_files: munged_max_files } 71 elsif munged_max_files == 0 && files.size > soft_max_files 72 Puppet.warning _("The directory '%{path}' contains %{entries} entries, which exceeds the default soft limit %{soft_max_files} and may cause excessive resource consumption and degraded performance. To remove this warning set a value for `max_files` parameter or consider using an alternate method to manage large directory trees") % { path: path, entries: files.size, soft_max_files: soft_max_files } 73 end 74 75 # Now strip off the leading path, so each file becomes relative, and remove 76 # any slashes that might end up at the beginning of the path. 77 result = files.collect { |file| file.sub(%r{^#{Regexp.escape(@path)}/*}, '') } 78 79 # And add the path itself. 80 result.unshift(".") 81 82 result 83 end
ignore=(values)
click to toggle source
# File lib/puppet/file_serving/fileset.rb 85 def ignore=(values) 86 values = [values] unless values.is_a?(Array) 87 @ignore = values.collect(&:to_s) 88 end
links=(links)
click to toggle source
# File lib/puppet/file_serving/fileset.rb 90 def links=(links) 91 links = links.to_sym 92 #TRANSLATORS ":links" is a parameter name and should not be translated 93 raise(ArgumentError, _("Invalid :links value '%{links}'") % { links: links }) unless [:manage, :follow].include?(links) 94 @links = links 95 @stat_method = @links == :manage ? :lstat : :stat 96 end
Private Instance Methods
continue_recursion_at?(depth)
click to toggle source
# File lib/puppet/file_serving/fileset.rb 183 def continue_recursion_at?(depth) 184 # recurse if told to, and infinite recursion or current depth not at the limit 185 self.recurse && (self.recurselimit == :infinite || depth <= self.recurselimit) 186 end
initialize_from_hash(options)
click to toggle source
# File lib/puppet/file_serving/fileset.rb 100 def initialize_from_hash(options) 101 options.each do |option, value| 102 method = option.to_s + "=" 103 begin 104 send(method, value) 105 rescue NoMethodError 106 raise ArgumentError, _("Invalid option '%{option}'") % { option: option }, $!.backtrace 107 end 108 end 109 end
initialize_from_request(request)
click to toggle source
# File lib/puppet/file_serving/fileset.rb 111 def initialize_from_request(request) 112 [:links, :ignore, :recurse, :recurselimit, :max_files, :checksum_type].each do |param| 113 if request.options.include?(param) # use 'include?' so the values can be false 114 value = request.options[param] 115 elsif request.options.include?(param.to_s) 116 value = request.options[param.to_s] 117 end 118 next if value.nil? 119 value = true if value == "true" 120 value = false if value == "false" 121 value = Integer(value) if value.is_a?(String) and value =~ /^\d+$/ 122 send(param.to_s + "=", value) 123 end 124 end
perform_recursion()
click to toggle source
Pull the recursion logic into one place. It's moderately hairy, and this allows us to keep the hairiness apart from what we do with the files.
# File lib/puppet/file_serving/fileset.rb 159 def perform_recursion 160 current_dirs = [FileSetEntry.new(0, @path, @ignore, @stat_method)] 161 162 result = [] 163 164 while entry = current_dirs.shift #rubocop:disable Lint/AssignmentInCondition 165 if continue_recursion_at?(entry.depth + 1) 166 entry.children.each do |child| 167 result << child.path 168 current_dirs << child 169 end 170 end 171 end 172 173 result 174 end
valid?(path)
click to toggle source
# File lib/puppet/file_serving/fileset.rb 176 def valid?(path) 177 Puppet::FileSystem.send(@stat_method, path) 178 true 179 rescue Errno::ENOENT, Errno::EACCES 180 false 181 end