Class Facter::Util::Resolution
In: lib/facter/util/resolution.rb
Parent: Object

Methods

confine   exec   have_which   length   limit   new   setcode   suitable?   to_s   value  

Attributes

code  [RW] 
interpreter  [RW] 
name  [RW] 
timeout  [RW] 

Public Class methods

Execute a chunk of code.

[Source]

    # File lib/facter/util/resolution.rb, line 27
27:     def self.exec(code, interpreter = "/bin/sh")
28:         raise ArgumentError, "non-sh interpreters are not currently supported" unless interpreter == "/bin/sh"
29:         binary = code.split(/\s+/).shift
30: 
31:         if have_which
32:             path = nil
33:             if binary !~ /^\//
34:                 path = %x{which #{binary} 2>/dev/null}.chomp
35:                 # we don't have the binary necessary
36:                 return nil if path == ""
37:             else
38:                 path = binary
39:             end
40: 
41:             return nil unless FileTest.exists?(path)
42:         end
43: 
44:         out = nil
45:         begin
46:             out = %x{#{code}}.chomp
47:         rescue => detail
48:             $stderr.puts detail
49:             return nil
50:         end
51:         if out == ""
52:             return nil
53:         else
54:             return out
55:         end
56:     end

[Source]

    # File lib/facter/util/resolution.rb, line 14
14:     def self.have_which
15:         if ! defined?(@have_which) or @have_which.nil?
16:             if Config::CONFIG['host_os'] =~ /mswin/
17:                 @have_which = false
18:             else
19:                 %x{which which 2>/dev/null}
20:                 @have_which = ($? == 0)
21:             end
22:         end
23:         @have_which
24:     end

Create a new resolution mechanism.

[Source]

    # File lib/facter/util/resolution.rb, line 66
66:     def initialize(name)
67:         @name = name
68:         @confines = []
69:         @value = nil
70:         @timeout = 0
71:     end

Public Instance methods

Add a new confine to the resolution mechanism.

[Source]

    # File lib/facter/util/resolution.rb, line 59
59:     def confine(confines)
60:         confines.each do |fact, values|
61:             @confines.push Facter::Util::Confine.new(fact, *values)
62:         end
63:     end

Return the number of confines.

[Source]

    # File lib/facter/util/resolution.rb, line 74
74:     def length
75:         @confines.length
76:     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.

[Source]

    # File lib/facter/util/resolution.rb, line 81
81:     def limit
82:         @timeout
83:     end

Set our code for returning a value.

[Source]

    # File lib/facter/util/resolution.rb, line 86
86:     def setcode(string = nil, interp = nil, &block)
87:         if string
88:             @code = string
89:             @interpreter = interp || "/bin/sh"
90:         else
91:             unless block_given?
92:                 raise ArgumentError, "You must pass either code or a block"
93:             end
94:             @code = block
95:         end
96:     end

Is this resolution mechanism suitable on the system in question?

[Source]

     # File lib/facter/util/resolution.rb, line 99
 99:     def suitable?
100:         unless defined? @suitable
101:             @suitable = ! @confines.detect { |confine| ! confine.true? }
102:         end
103: 
104:         return @suitable
105:     end

[Source]

     # File lib/facter/util/resolution.rb, line 107
107:     def to_s
108:         return self.value()
109:     end

How we get a value for our resolution mechanism.

[Source]

     # File lib/facter/util/resolution.rb, line 112
112:     def value
113:         result = nil
114:         begin
115:             Timeout.timeout(limit) do
116:                 if @code.is_a?(Proc)
117:                     result = @code.call()
118:                 else
119:                     result = Facter::Util::Resolution.exec(@code,@interpreter)
120:                 end
121:             end
122:         rescue Timeout::Error => detail
123:             warn "Timed out seeking value for %s" % self.name
124: 
125:             # This call avoids zombies -- basically, create a thread that will
126:             # dezombify all of the child processes that we're ignoring because
127:             # of the timeout.
128:             Thread.new { Process.waitall }
129:             return nil
130:         rescue => details
131:             warn "Could not retrieve %s: %s" % [self.name, details]
132:             return nil
133:         end
134: 
135:         return nil if result == ""
136:         return result
137:     end

[Validate]