module Puppet::Interface::FaceCollection
Public Class Methods
[](name, version)
click to toggle source
# File lib/puppet/interface/face_collection.rb 18 def self.[](name, version) 19 name = underscorize(name) 20 get_face(name, version) or load_face(name, version) 21 end
faces()
click to toggle source
# File lib/puppet/interface/face_collection.rb 7 def self.faces 8 unless @loaded 9 @loaded = true 10 names = @loader.files_to_load(Puppet.lookup(:current_environment)).map do |fn| 11 ::File.basename(fn, '.rb') 12 end.uniq 13 names.each {|name| self[name, :current]} 14 end 15 @faces.keys.select {|name| @faces[name].length > 0 } 16 end
find_matching(range, versions)
click to toggle source
# File lib/puppet/interface/face_collection.rb 55 def self.find_matching(range, versions) 56 versions.select { |v| range === v }.sort.last 57 end
get_action_for_face(name, action_name, version)
click to toggle source
# File lib/puppet/interface/face_collection.rb 23 def self.get_action_for_face(name, action_name, version) 24 name = underscorize(name) 25 26 # If the version they request specifically doesn't exist, don't search 27 # elsewhere. Usually this will start from :current and all... 28 face = self[name, version] 29 return nil unless face 30 action = face.get_action(action_name) 31 unless action 32 # ...we need to search for it bound to an o{lder,ther} version. Since 33 # we load all actions when the face is first references, this will be in 34 # memory in the known set of versions of the face. 35 (@faces[name].keys - [ :current ]).sort.reverse_each do |vers| 36 action = @faces[name][vers].get_action(action_name) 37 break if action 38 end 39 end 40 41 return action 42 end
get_face(name, pattern)
click to toggle source
get face from memory, without loading.
# File lib/puppet/interface/face_collection.rb 45 def self.get_face(name, pattern) 46 return nil unless @faces.has_key? name 47 return @faces[name][:current] if pattern == :current 48 49 versions = @faces[name].keys - [ :current ] 50 range = pattern.is_a?(SemanticPuppet::Version) ? SemanticPuppet::VersionRange.new(pattern, pattern) : SemanticPuppet::VersionRange.parse(pattern) 51 found = find_matching(range, versions) 52 return @faces[name][found] 53 end
load_face(name, version)
click to toggle source
try to load the face, and return it.
# File lib/puppet/interface/face_collection.rb 60 def self.load_face(name, version) 61 # We always load the current version file; the common case is that we have 62 # the expected version and any compatibility versions in the same file, 63 # the default. Which means that this is almost always the case. 64 # 65 # We use require to avoid executing the code multiple times, like any 66 # other Ruby library that we might want to use. --daniel 2011-04-06 67 if safely_require name then 68 # If we wanted :current, we need to index to find that; direct version 69 # requests just work as they go. --daniel 2011-04-06 70 if version == :current then 71 # We need to find current out of this. This is the largest version 72 # number that doesn't have a dedicated on-disk file present; those 73 # represent "experimental" versions of faces, which we don't fully 74 # support yet. 75 # 76 # We walk the versions from highest to lowest and take the first version 77 # that is not defined in an explicitly versioned file on disk as the 78 # current version. 79 # 80 # This constrains us to only ship experimental versions with *one* 81 # version in the file, not multiple, but given you can't reliably load 82 # them except by side-effect when you ignore that rule this seems safe 83 # enough... 84 # 85 # Given those constraints, and that we are not going to ship a versioned 86 # interface that is not :current in this release, we are going to leave 87 # these thoughts in place, and just punt on the actual versioning. 88 # 89 # When we upgrade the core to support multiple versions we can solve the 90 # problems then; as lazy as possible. 91 # 92 # We do support multiple versions in the same file, though, so we sort 93 # versions here and return the last item in that set. 94 # 95 # --daniel 2011-04-06 96 latest_ver = @faces[name].keys.sort.last 97 @faces[name][:current] = @faces[name][latest_ver] 98 end 99 end 100 101 unless version == :current or get_face(name, version) 102 # Try an obsolete version of the face, if needed, to see if that helps? 103 safely_require name, version 104 end 105 106 return get_face(name, version) 107 end
register(face)
click to toggle source
# File lib/puppet/interface/face_collection.rb 125 def self.register(face) 126 @faces[underscorize(face.name)][face.version] = face 127 end
safely_require(name, version = nil)
click to toggle source
# File lib/puppet/interface/face_collection.rb 109 def self.safely_require(name, version = nil) 110 path = @loader.expand(version ? ::File.join(version.to_s, name.to_s) : name) 111 require path 112 true 113 114 rescue LoadError => e 115 raise unless e.message =~ %r{-- #{path}$} 116 # ...guess we didn't find the file; return a much better problem. 117 nil 118 rescue SyntaxError => e 119 raise unless e.message =~ %r{#{path}\.rb:\d+: } 120 Puppet.err _("Failed to load face %{name}:\n%{detail}") % { name: name, detail: e } 121 # ...but we just carry on after complaining. 122 nil 123 end
underscorize(name)
click to toggle source
# File lib/puppet/interface/face_collection.rb 129 def self.underscorize(name) 130 unless name.to_s =~ /^[-_a-z][-_a-z0-9]*$/i then 131 #TRANSLATORS 'face' refers to a programming API in Puppet 132 raise ArgumentError, _("%{name} (%{class_name}) is not a valid face name") % 133 { name: name.inspect, class_name: name.class } 134 end 135 136 name.to_s.downcase.split(/[-_]/).join('_').to_sym 137 end