summaryrefslogtreecommitdiffstats
path: root/lib/facter.rb
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-05-13 21:22:20 -0500
committerLuke Kanies <luke@madstop.com>2008-05-13 21:22:20 -0500
commitc5492c2b7c539fe6f6a33b7b31a59d931808658e (patch)
tree5ebd052833577bf5c2c00290be389055b31f319b /lib/facter.rb
parent4f39ec8dd205ecf0a3ad90c950c86046da3f454e (diff)
downloadfacter-c5492c2b7c539fe6f6a33b7b31a59d931808658e.tar.gz
facter-c5492c2b7c539fe6f6a33b7b31a59d931808658e.tar.xz
facter-c5492c2b7c539fe6f6a33b7b31a59d931808658e.zip
Splitting the different classes in Facter up, and adding some tests.
The Confine and Resolution classes are now in separate files, and I've got tests for Confine.
Diffstat (limited to 'lib/facter.rb')
-rw-r--r--lib/facter.rb205
1 files changed, 2 insertions, 203 deletions
diff --git a/lib/facter.rb b/lib/facter.rb
index 65ea57b..675b95d 100644
--- a/lib/facter.rb
+++ b/lib/facter.rb
@@ -18,6 +18,8 @@
#--
class Facter
+ require 'facter/resolution'
+
include Comparable
include Enumerable
@@ -376,209 +378,6 @@ class Facter
end
end
- # An actual fact resolution mechanism. These are largely just chunks of
- # code, with optional confinements restricting the mechanisms to only working on
- # specific systems. Note that the confinements are always ANDed, so any
- # confinements specified must all be true for the resolution to be
- # suitable.
- class Resolution
- attr_accessor :interpreter, :code, :name, :fact
-
- def Resolution.have_which
- if @have_which.nil?
- %x{which which 2>/dev/null}
- @have_which = ($? == 0)
- end
- @have_which
- end
-
- # Execute a chunk of code.
- def Resolution.exec(code, interpreter = "/bin/sh")
- if interpreter == "/bin/sh"
- binary = code.split(/\s+/).shift
-
- if have_which
- path = nil
- if binary !~ /^\//
- path = %x{which #{binary} 2>/dev/null}.chomp
- if path == ""
- # we don't have the binary necessary
- return nil
- end
- else
- path = binary
- end
-
- unless FileTest.exists?(path)
- # our binary does not exist
- return nil
- end
- end
-
- out = nil
- begin
- out = %x{#{code}}.chomp
- rescue => detail
- $stderr.puts detail
- return nil
- end
- if out == ""
- return nil
- else
- return out
- end
- else
- raise ArgumentError,
- "non-sh interpreters are not currently supported"
- end
- end
-
- # Add a new confine to the resolution mechanism.
- def confine(*args)
- if args[0].is_a? Hash
- args[0].each do |fact, values|
- @confines.push Confine.new(fact,*values)
- end
- else
- fact = args.shift
- @confines.push Confine.new(fact,*args)
- end
- end
-
- # Create a new resolution mechanism.
- def initialize(name)
- @name = name
- @confines = []
- @value = nil
- end
-
- # Return the number of confines.
- def length
- @confines.length
- end
-
- # Set our code for returning a value.
- def setcode(string = nil, interp = nil, &block)
- if string
- @code = string
- @interpreter = interp || "/bin/sh"
- else
- unless block_given?
- raise ArgumentError, "You must pass either code or a block"
- end
- @code = block
- end
- end
-
- # Set the name by which this parameter is known in LDAP. The default
- # is just the fact name.
- def setldapname(name)
- @fact.ldapname = name.to_s
- end
-
- # Is this resolution mechanism suitable on the system in question?
- def suitable?
- unless defined? @suitable
- @suitable = true
- if @confines.length == 0
- return true
- end
- @confines.each { |confine|
- unless confine.true?
- @suitable = false
- end
- }
- end
-
- return @suitable
- end
-
- # Set tags on our parent fact.
- def tag(*values)
- @fact.tag(*values)
- end
-
- def to_s
- return self.value()
- end
-
- # How we get a value for our resolution mechanism.
- def value
- value = nil
-
- if @code.is_a?(Proc)
- value = @code.call()
- else
- unless defined? @interpreter
- @interpreter = "/bin/sh"
- end
- if @code.nil?
- $stderr.puts "Code for %s is nil" % @name
- else
- value = Resolution.exec(@code,@interpreter)
- end
- end
-
- if value == ""
- value = nil
- end
-
- return value
- end
-
- end
-
- # A restricting tag for fact resolution mechanisms. The tag must be true
- # for the resolution mechanism to be suitable.
- class Confine
- attr_accessor :fact, :op, :value
-
- # Add the tag. Requires the fact name, an operator, and the value
- # we're comparing to.
- def initialize(fact, *values)
- fact = fact.to_s if fact.is_a? Symbol
- @fact = fact
- @values = values.collect do |value|
- if value.is_a? String
- value
- else
- value.to_s
- end
- end
- end
-
- def to_s
- return "'%s' '%s'" % [@fact, @values.join(",")]
- end
-
- # Evaluate the fact, returning true or false.
- def true?
- fact = nil
- unless fact = Facter[@fact]
- Facter.debug "No fact for %s" % @fact
- return false
- end
- value = fact.value
-
- if value.nil?
- return false
- end
-
- retval = @values.find { |v|
- if value.downcase == v.downcase
- break true
- end
- }
-
- if retval
- retval = true
- else
- retval = false
- end
-
- return retval || false
- end
- end
# Load all of the default facts
def self.loadfacts