Add a new confine to the resolution mechanism.
# File lib/facter/util/resolution.rb, line 80 def confine(confines) confines.each do |fact, values| @confines.push Facter::Util::Confine.new(fact, *values) end end
# File lib/facter/util/resolution.rb, line 86 def has_weight(weight) @weight = weight end
# File lib/facter/util/resolution.rb, line 134 def interpreter=(interp) Facter.warnonce "The 'Facter::Util::Resolution.interpreter=' method is deprecated and will be removed in a future version." @interpreter = interp end
We need this as a getter for ‘timeout’, because some versions of ruby seem to already have a ‘timeout’ method and we can’t seem to override the instance methods, somehow.
# File lib/facter/util/resolution.rb, line 111 def limit @timeout end
Set our code for returning a value.
# File lib/facter/util/resolution.rb, line 116 def setcode(string = nil, interp = nil, &block) Facter.warnonce "The interpreter parameter to 'setcode' is deprecated and will be removed in a future version." if interp if string @code = string @interpreter = interp || INTERPRETER else unless block_given? raise ArgumentError, "You must pass either code or a block" end @code = block end end
Is this resolution mechanism suitable on the system in question?
# File lib/facter/util/resolution.rb, line 140 def suitable? unless defined? @suitable @suitable = ! @confines.detect { |confine| ! confine.true? } end return @suitable end
# File lib/facter/util/resolution.rb, line 148 def to_s return self.value() end
How we get a value for our resolution mechanism.
# File lib/facter/util/resolution.rb, line 153 def value result = nil return result if @code == nil starttime = Time.now.to_f begin Timeout.timeout(limit) do if @code.is_a?(Proc) result = @code.call() else result = Facter::Util::Resolution.exec(@code) end end rescue Timeout::Error => detail warn "Timed out seeking value for %s" % self.name # This call avoids zombies -- basically, create a thread that will # dezombify all of the child processes that we're ignoring because # of the timeout. Thread.new { Process.waitall } return nil rescue => details warn "Could not retrieve %s: %s" % [self.name, details] return nil end finishtime = Time.now.to_f ms = (finishtime - starttime) * 1000 Facter.show_time "#{self.name}: #{"%.2f" % ms}ms" return nil if result == "" return result end
Return the importance of this resolution.
# File lib/facter/util/resolution.rb, line 100 def weight if @weight @weight else @confines.length end end
Execute a program and return the output of that program.
Returns nil if the program can’t be found, or if there is a problem executing the code.
# File lib/facter/util/resolution.rb, line 33 def self.exec(code, interpreter = nil) Facter.warnonce "The interpreter parameter to 'exec' is deprecated and will be removed in a future version." if interpreter # Try to guess whether the specified code can be executed by looking at the # first word. If it cannot be found on the PATH defer on resolving the fact # by returning nil. # This only fails on shell built-ins, most of which are masked by stuff in # /bin or of dubious value anyways. In the worst case, "sh -c 'builtin'" can # be used to work around this limitation # # Windows' %x{} throws Errno::ENOENT when the command is not found, so we # can skip the check there. This is good, since builtins cannot be found # elsewhere. if have_which and !Facter::Util::Config.is_windows? path = nil binary = code.split.first if code =~ %r^\// path = binary else path = %x{which #{binary} 2>/dev/null}.chomp # we don't have the binary necessary return nil if path == "" or path.match(%rCommand not found\./) end return nil unless FileTest.exists?(path) end out = nil begin out = %x{#{code}}.chomp rescue Errno::ENOENT => detail # command not found on Windows return nil rescue => detail $stderr.puts detail return nil end if out == "" return nil else return out end end
# File lib/facter/util/resolution.rb, line 16 def self.have_which if ! defined?(@have_which) or @have_which.nil? if Facter.value(:kernel) == 'windows' @have_which = false else %x{which which >/dev/null 2>&1} @have_which = ($? == 0) end end @have_which end
Create a new resolution mechanism.
# File lib/facter/util/resolution.rb, line 91 def initialize(name) @name = name @confines = [] @value = nil @timeout = 0 @weight = nil end