facter 1.3.8 → 1.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of facter might be problematic. Click here for more details.
- data/CHANGELOG +68 -0
- data/README +1 -1
- data/Rakefile +2 -1
- data/bin/facter +16 -11
- data/lib/facter.rb +55 -1001
- data/lib/facter/Cfkey.rb +42 -0
- data/lib/facter/architecture.rb +14 -0
- data/lib/facter/domain.rb +64 -0
- data/lib/facter/facterversion.rb +3 -0
- data/lib/facter/fqdn.rb +10 -0
- data/lib/facter/hardwareisa.rb +4 -0
- data/lib/facter/hardwaremodel.rb +13 -0
- data/lib/facter/hostname.rb +25 -0
- data/lib/facter/id.rb +4 -0
- data/lib/facter/ipaddress.rb +151 -0
- data/lib/facter/iphostnumber.rb +18 -0
- data/lib/facter/ipmess.rb +64 -74
- data/lib/facter/kernel.rb +3 -0
- data/lib/facter/kernelrelease.rb +8 -0
- data/lib/facter/lsb.rb +37 -0
- data/lib/facter/lsbmajdistrelease.rb +15 -0
- data/lib/facter/macaddress.rb +65 -0
- data/lib/facter/macosx.rb +25 -55
- data/lib/facter/manufacturer.rb +7 -45
- data/lib/facter/memory.rb +26 -49
- data/lib/facter/netmask.rb +17 -0
- data/lib/facter/operatingsystem.rb +37 -0
- data/lib/facter/operatingsystemrelease.rb +63 -0
- data/lib/facter/processor.rb +36 -14
- data/lib/facter/ps.rb +8 -0
- data/lib/facter/puppetversion.rb +10 -0
- data/lib/facter/rubysitedir.rb +8 -0
- data/lib/facter/rubyversion.rb +3 -0
- data/lib/facter/ssh.rb +33 -0
- data/lib/facter/uniqueid.rb +4 -0
- data/lib/facter/util/collection.rb +126 -0
- data/lib/facter/util/confine.rb +41 -0
- data/lib/facter/util/fact.rb +122 -0
- data/lib/facter/util/ip.rb +98 -0
- data/lib/facter/util/loader.rb +96 -0
- data/lib/facter/util/macosx.rb +50 -0
- data/lib/facter/util/manufacturer.rb +39 -0
- data/lib/facter/util/memory.rb +54 -0
- data/lib/facter/util/netmask.rb +36 -0
- data/lib/facter/util/resolution.rb +125 -0
- metadata +76 -34
data/CHANGELOG
CHANGED
@@ -1,3 +1,71 @@
|
|
1
|
+
1.5:
|
2
|
+
Fixed #1400 - OperatingSystemRelease should now work on CentOS
|
3
|
+
|
4
|
+
Changed 'timeout' option to 'limit' to avoid scope issue
|
5
|
+
|
6
|
+
Fixes #1376 - Display memory facts for AIX
|
7
|
+
|
8
|
+
Fixes #1334 - Forced Facter to use LANG=C
|
9
|
+
|
10
|
+
Fixes #1357 - Change ps syntax for OSX and BSD
|
11
|
+
|
12
|
+
Set the timeout on the AIX kernelrelease fact to 5 seconds.
|
13
|
+
|
14
|
+
Refactored so each fact resolution can specify a separate timeout,
|
15
|
+
but the default is still 0.5.
|
16
|
+
|
17
|
+
Refactered ipmess.rb and util/ip.rb to support separate *BSD logic for
|
18
|
+
*BSD aliased interfaces.
|
19
|
+
|
20
|
+
Updated dmidecode facts fixing ticket #60
|
21
|
+
|
22
|
+
Added AIX support for some facts
|
23
|
+
|
24
|
+
Add lsbmajdistrelease fact for CentOS and Red Hat
|
25
|
+
|
26
|
+
Updated Red Hat spec file for new version
|
27
|
+
The 'facter' executable now has an option (-p|--puppet) for loading the
|
28
|
+
Puppet libraries, which gives it access to Puppet's facts.
|
29
|
+
|
30
|
+
Added autoloading to Facter with a default of not loading all facts,
|
31
|
+
which results in a significant speedup when only one fact is sought.
|
32
|
+
Facts are autoloaded in either a single file named after the fact or
|
33
|
+
in any file in a directory named after the fact.
|
34
|
+
|
35
|
+
Significantly refactored Facter's internals, including creating tests
|
36
|
+
for all internal classes.
|
37
|
+
|
38
|
+
A netmask fact has been added closing ticket #46. It only returns the
|
39
|
+
netmask of the primary interface (in the same behaviour as the ipaddress
|
40
|
+
and macaddress facts).
|
41
|
+
|
42
|
+
Facts to return multiple interfaces on a host have also been updated.
|
43
|
+
If you have multiple interfaces on Linux, *BSD, or Solaris/SunOS you will
|
44
|
+
now get facts for each interface's IP address, MAC address and netmask.
|
45
|
+
The facts will be structured like:
|
46
|
+
ipaddress_int = 10.0.0.x
|
47
|
+
macaddress_int = xx:xx:xx:xx
|
48
|
+
netmask_int = 255.255.255.0
|
49
|
+
|
50
|
+
Facter now identifies Ubuntu hosts and their releases using the
|
51
|
+
operatingsystem and operatingsystemrelease facts.
|
52
|
+
|
53
|
+
The Debian operatingsystemrelease fact now correctly returns the current
|
54
|
+
Debian release.
|
55
|
+
|
56
|
+
Fixed ticket #48 - ioperatingsystem and operatingsystemrelease for CentOS
|
57
|
+
|
58
|
+
Fixed ticket #44 and allowed support for Xen multiple interfaces and aliased
|
59
|
+
interfaces. Supports both Linux and *BSD.
|
60
|
+
|
61
|
+
Added interfaces fact to add as index for ip/MAC address facts
|
62
|
+
|
63
|
+
Added Mandrake support for operatingsystem fact - closed ticket #47
|
64
|
+
|
65
|
+
Fixed ticket #45
|
66
|
+
|
67
|
+
Added netmask.rb closing ticket #46
|
68
|
+
|
1
69
|
1.3.8:
|
2
70
|
Fixed Rdoc::usage bug on CentOS 5 - closed Puppet #753 and Facter #40
|
3
71
|
|
data/README
CHANGED
@@ -6,5 +6,5 @@ processors, etc.
|
|
6
6
|
It currently cannot collect very much information, but it is architected to be
|
7
7
|
both OS and OS version specific.
|
8
8
|
|
9
|
-
See bin/facter or http://reductivelabs.com/
|
9
|
+
See bin/facter or http://reductivelabs.com/trac/enhost for an example of the
|
10
10
|
interface.
|
data/Rakefile
CHANGED
@@ -35,6 +35,8 @@ project.mkgemtask do |gem|
|
|
35
35
|
gem.bindir = "bin" # Use these for applications.
|
36
36
|
gem.executables = ["facter"]
|
37
37
|
gem.default_executable = "facter"
|
38
|
+
|
39
|
+
gem.author = "Luke Kanies"
|
38
40
|
end
|
39
41
|
|
40
42
|
if project.has?(:epm)
|
@@ -43,4 +45,3 @@ if project.has?(:epm)
|
|
43
45
|
task.rubylibs = FileList.new('lib/**/*')
|
44
46
|
end
|
45
47
|
end
|
46
|
-
# $Id$
|
data/bin/facter
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
#
|
7
7
|
# = Usage
|
8
8
|
#
|
9
|
-
# facter [-d|--debug] [-h|--help] [-v|--version] [-y|--yaml] [fact] [fact] [...]
|
9
|
+
# facter [-d|--debug] [-h|--help] [-p|--puppet] [-v|--version] [-y|--yaml] [fact] [fact] [...]
|
10
10
|
#
|
11
11
|
# = Description
|
12
12
|
#
|
@@ -24,6 +24,9 @@
|
|
24
24
|
# help::
|
25
25
|
# Print this help message
|
26
26
|
#
|
27
|
+
# puppet::
|
28
|
+
# Load the Puppet libraries, thus allowing Facter to load Puppet-specific facts.
|
29
|
+
#
|
27
30
|
# version::
|
28
31
|
# Print the version and exit.
|
29
32
|
#
|
@@ -64,7 +67,8 @@ result = GetoptLong.new(
|
|
64
67
|
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
|
65
68
|
[ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
|
66
69
|
[ "--yaml", "-y", GetoptLong::NO_ARGUMENT ],
|
67
|
-
[ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ]
|
70
|
+
[ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ],
|
71
|
+
[ "--puppet", "-p", GetoptLong::NO_ARGUMENT ]
|
68
72
|
)
|
69
73
|
|
70
74
|
options = {
|
@@ -74,8 +78,14 @@ options = {
|
|
74
78
|
result.each { |opt,arg|
|
75
79
|
case opt
|
76
80
|
when "--version"
|
77
|
-
|
78
|
-
|
81
|
+
puts "%s" % Facter.version
|
82
|
+
exit
|
83
|
+
when "--puppet"
|
84
|
+
begin
|
85
|
+
require 'puppet'
|
86
|
+
rescue LoadError => detail
|
87
|
+
$stderr.puts "Could not load Puppet: %s" % detail
|
88
|
+
end
|
79
89
|
when "--yaml"
|
80
90
|
options[:yaml] = true
|
81
91
|
when "--debug"
|
@@ -107,13 +117,10 @@ ARGV.each { |item|
|
|
107
117
|
names.push item
|
108
118
|
}
|
109
119
|
|
110
|
-
facts = {}
|
111
|
-
|
112
120
|
if names.empty?
|
113
|
-
Facter.
|
114
|
-
facts[name] = fact
|
115
|
-
}
|
121
|
+
facts = Facter.to_hash
|
116
122
|
else
|
123
|
+
facts = {}
|
117
124
|
names.each { |name|
|
118
125
|
begin
|
119
126
|
facts[name] = Facter.value(name)
|
@@ -139,5 +146,3 @@ facts.sort { |a, b| a[0].to_s <=> b[0].to_s }.each { |name,value|
|
|
139
146
|
puts "%s => %s" % [name,value]
|
140
147
|
end
|
141
148
|
}
|
142
|
-
|
143
|
-
# $Id: facter,v 1.1.1.1 2004/03/21 21:06:27 luke Exp $
|
data/lib/facter.rb
CHANGED
@@ -17,11 +17,17 @@
|
|
17
17
|
#
|
18
18
|
#--
|
19
19
|
|
20
|
-
|
20
|
+
module Facter
|
21
|
+
# This is just so the other classes have the constant.
|
22
|
+
module Util; end
|
23
|
+
|
24
|
+
require 'facter/util/fact'
|
25
|
+
require 'facter/util/collection'
|
26
|
+
|
21
27
|
include Comparable
|
22
28
|
include Enumerable
|
23
29
|
|
24
|
-
FACTERVERSION = '1.
|
30
|
+
FACTERVERSION = '1.5'
|
25
31
|
# = Facter
|
26
32
|
# Functions as a hash of 'facts' you might care about about your
|
27
33
|
# system, such as mac address, IP address, Video card, etc.
|
@@ -35,23 +41,23 @@ class Facter
|
|
35
41
|
# puts Facter['operatingsystem']
|
36
42
|
#
|
37
43
|
|
44
|
+
# Set LANG to force i18n to C
|
45
|
+
#
|
46
|
+
ENV['LANG'] = 'C'
|
38
47
|
|
39
|
-
@@facts = Hash.new { |hash, key|
|
40
|
-
key = key.to_s.downcase.intern
|
41
|
-
if hash.include?(key)
|
42
|
-
hash[key]
|
43
|
-
else
|
44
|
-
nil
|
45
|
-
end
|
46
|
-
}
|
47
48
|
GREEN = "[0;32m"
|
48
49
|
RESET = "[0m"
|
49
50
|
@@debug = 0
|
50
51
|
|
51
|
-
attr_accessor :name, :searching, :ldapname
|
52
|
-
|
53
52
|
# module methods
|
54
53
|
|
54
|
+
def self.collection
|
55
|
+
unless defined?(@collection) and @collection
|
56
|
+
@collection = Facter::Util::Collection.new
|
57
|
+
end
|
58
|
+
@collection
|
59
|
+
end
|
60
|
+
|
55
61
|
# Return the version of the library.
|
56
62
|
def self.version
|
57
63
|
return FACTERVERSION
|
@@ -70,41 +76,41 @@ class Facter
|
|
70
76
|
# Return a fact object by name. If you use this, you still have to call
|
71
77
|
# 'value' on it to retrieve the actual value.
|
72
78
|
def self.[](name)
|
73
|
-
|
79
|
+
collection.fact(name)
|
74
80
|
end
|
75
81
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
unless fact = @@facts[name]
|
82
|
-
fact = Facter.new(name)
|
82
|
+
class << self
|
83
|
+
[:fact, :flush, :list, :value].each do |method|
|
84
|
+
define_method(method) do |*args|
|
85
|
+
collection.send(method, *args)
|
86
|
+
end
|
83
87
|
end
|
84
88
|
|
85
|
-
|
86
|
-
|
89
|
+
[:list, :to_hash].each do |method|
|
90
|
+
define_method(method) do |*args|
|
91
|
+
collection.load_all
|
92
|
+
collection.send(method, *args)
|
93
|
+
end
|
87
94
|
end
|
95
|
+
end
|
88
96
|
|
89
|
-
fact.add(&block)
|
90
97
|
|
91
|
-
|
98
|
+
# Add a resolution mechanism for a named fact. This does not distinguish
|
99
|
+
# between adding a new fact and adding a new way to resolve a fact.
|
100
|
+
def self.add(name, options = {}, &block)
|
101
|
+
collection.add(name, options, &block)
|
92
102
|
end
|
93
103
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
value = fact.value
|
101
|
-
unless value.nil?
|
102
|
-
yield name.to_s, fact.value
|
103
|
-
end
|
104
|
-
end
|
105
|
-
}
|
104
|
+
def self.each
|
105
|
+
# Make sure all facts are loaded.
|
106
|
+
collection.load_all
|
107
|
+
|
108
|
+
collection.each do |*args|
|
109
|
+
yield(*args)
|
106
110
|
end
|
111
|
+
end
|
107
112
|
|
113
|
+
class << self
|
108
114
|
# Allow users to call fact names directly on the Facter class,
|
109
115
|
# either retrieving the value or comparing it to an existing value.
|
110
116
|
def method_missing(name, *args)
|
@@ -114,7 +120,7 @@ class Facter
|
|
114
120
|
name = name.to_s.sub(/\?$/,'')
|
115
121
|
end
|
116
122
|
|
117
|
-
if fact =
|
123
|
+
if fact = @collection.fact(name)
|
118
124
|
if question
|
119
125
|
value = fact.value.downcase
|
120
126
|
args.each do |arg|
|
@@ -130,7 +136,7 @@ class Facter
|
|
130
136
|
end
|
131
137
|
else
|
132
138
|
# Else, fail like a normal missing method.
|
133
|
-
|
139
|
+
raise NoMethodError, "Could not find fact '%s'" % name
|
134
140
|
end
|
135
141
|
end
|
136
142
|
end
|
@@ -167,977 +173,25 @@ class Facter
|
|
167
173
|
end
|
168
174
|
end
|
169
175
|
|
170
|
-
# Flush all cached values.
|
171
|
-
def self.flush
|
172
|
-
@@facts.each { |name, fact| fact.flush }
|
173
|
-
end
|
174
|
-
|
175
|
-
# Return a list of all of the facts.
|
176
|
-
def self.list
|
177
|
-
return @@facts.keys
|
178
|
-
end
|
179
|
-
|
180
176
|
# Remove them all.
|
181
177
|
def self.reset
|
182
|
-
|
183
|
-
end
|
184
|
-
|
185
|
-
# Return a hash of all of our facts.
|
186
|
-
def self.to_hash(*tags)
|
187
|
-
@@facts.inject({}) do |h, ary|
|
188
|
-
if ary[1].suitable? and (tags.empty? or ary[1].tagged?(*tags))
|
189
|
-
value = ary[1].value
|
190
|
-
if value
|
191
|
-
# For backwards compatibility, convert the fact name to a string.
|
192
|
-
h[ary[0].to_s] = value
|
193
|
-
end
|
194
|
-
end
|
195
|
-
h
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def self.value(name)
|
200
|
-
if fact = @@facts[name]
|
201
|
-
fact.value
|
202
|
-
else
|
203
|
-
nil
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
# Compare one value to another.
|
208
|
-
def <=>(other)
|
209
|
-
return self.value <=> other
|
210
|
-
end
|
211
|
-
|
212
|
-
# Are we the same? Used for case statements.
|
213
|
-
def ===(value)
|
214
|
-
self.value == value
|
215
|
-
end
|
216
|
-
|
217
|
-
# Create a new fact, with no resolution mechanisms.
|
218
|
-
def initialize(name)
|
219
|
-
@name = name.to_s.downcase.intern
|
220
|
-
if @@facts.include?(@name)
|
221
|
-
raise ArgumentError, "A fact named %s already exists" % @name
|
222
|
-
else
|
223
|
-
@@facts[@name] = self
|
224
|
-
end
|
225
|
-
|
226
|
-
@resolves = []
|
227
|
-
@tags = []
|
228
|
-
@searching = false
|
229
|
-
|
230
|
-
@value = nil
|
231
|
-
|
232
|
-
@ldapname = name.to_s
|
233
|
-
end
|
234
|
-
|
235
|
-
# Add a new resolution mechanism. This requires a block, which will then
|
236
|
-
# be evaluated in the context of the new mechanism.
|
237
|
-
def add(&block)
|
238
|
-
unless block_given?
|
239
|
-
raise ArgumentError, "You must pass a block to Fact<instance>.add"
|
240
|
-
end
|
241
|
-
|
242
|
-
resolve = Resolution.new(@name)
|
243
|
-
|
244
|
-
resolve.fact = self
|
245
|
-
|
246
|
-
resolve.instance_eval(&block)
|
247
|
-
|
248
|
-
# skip resolves that will never be suitable for us
|
249
|
-
unless resolve.suitable?
|
250
|
-
return
|
251
|
-
end
|
252
|
-
|
253
|
-
# insert resolves in order of number of confinements
|
254
|
-
inserted = false
|
255
|
-
@resolves.each_with_index { |r,index|
|
256
|
-
if resolve.length > r.length
|
257
|
-
@resolves.insert(index,resolve)
|
258
|
-
inserted = true
|
259
|
-
break
|
260
|
-
end
|
261
|
-
}
|
262
|
-
|
263
|
-
unless inserted
|
264
|
-
@resolves.push resolve
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
# Return a count of resolution mechanisms available.
|
269
|
-
def count
|
270
|
-
return @resolves.length
|
178
|
+
@collection = nil
|
271
179
|
end
|
272
180
|
|
273
|
-
#
|
274
|
-
|
275
|
-
|
276
|
-
@resolves.each { |r| yield r }
|
277
|
-
end
|
278
|
-
|
279
|
-
# Flush any cached values.
|
280
|
-
def flush
|
281
|
-
@value = nil
|
282
|
-
@suitable = nil
|
283
|
-
end
|
284
|
-
|
285
|
-
# Is this fact suitable for finding answers on this host? This is used
|
286
|
-
# to throw away any initially unsuitable mechanisms.
|
287
|
-
def suitable?
|
288
|
-
if @resolves.length == 0
|
289
|
-
return false
|
290
|
-
end
|
291
|
-
|
292
|
-
unless defined? @suitable or (defined? @suitable and @suitable.nil?)
|
293
|
-
@suitable = false
|
294
|
-
@resolves.each { |resolve|
|
295
|
-
if resolve.suitable?
|
296
|
-
@suitable = true
|
297
|
-
break
|
298
|
-
end
|
299
|
-
}
|
300
|
-
end
|
301
|
-
|
302
|
-
return @suitable
|
303
|
-
end
|
304
|
-
|
305
|
-
# Add one ore more tags
|
306
|
-
def tag(*tags)
|
307
|
-
tags.each do |t|
|
308
|
-
t = t.to_s.downcase.intern
|
309
|
-
@tags << t unless @tags.include?(t)
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
# Is our fact tagged with all of the specified tags?
|
314
|
-
def tagged?(*tags)
|
315
|
-
tags.each do |t|
|
316
|
-
unless @tags.include? t.to_s.downcase.intern
|
317
|
-
return false
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
return true
|
322
|
-
end
|
323
|
-
|
324
|
-
def tags
|
325
|
-
@tags.dup
|
326
|
-
end
|
327
|
-
|
328
|
-
# Return the value for a given fact. Searches through all of the mechanisms
|
329
|
-
# and returns either the first value or nil.
|
330
|
-
def value
|
331
|
-
unless @value
|
332
|
-
# make sure we don't get stuck in recursive dependency loops
|
333
|
-
if @searching
|
334
|
-
Facter.debug "Caught recursion on %s" % @name
|
335
|
-
|
336
|
-
# return a cached value if we've got it
|
337
|
-
if @value
|
338
|
-
return @value
|
339
|
-
else
|
340
|
-
return nil
|
341
|
-
end
|
342
|
-
end
|
343
|
-
@value = nil
|
344
|
-
foundsuits = false
|
345
|
-
|
346
|
-
if @resolves.length == 0
|
347
|
-
Facter.debug "No resolves for %s" % @name
|
348
|
-
return nil
|
349
|
-
end
|
350
|
-
|
351
|
-
@searching = true
|
352
|
-
@resolves.each { |resolve|
|
353
|
-
#Facter.debug "Searching resolves for %s" % @name
|
354
|
-
if resolve.suitable?
|
355
|
-
@value = resolve.value
|
356
|
-
foundsuits = true
|
357
|
-
end
|
358
|
-
unless @value.nil? or @value == ""
|
359
|
-
break
|
360
|
-
end
|
361
|
-
}
|
362
|
-
@searching = false
|
363
|
-
|
364
|
-
unless foundsuits
|
365
|
-
Facter.debug "Found no suitable resolves of %s for %s" %
|
366
|
-
[@resolves.length,@name]
|
367
|
-
end
|
368
|
-
end
|
369
|
-
|
370
|
-
if @value.nil?
|
371
|
-
# nothing
|
372
|
-
Facter.debug("value for %s is still nil" % @name)
|
373
|
-
return nil
|
374
|
-
else
|
375
|
-
return @value
|
376
|
-
end
|
181
|
+
# Load all of the default facts, and then everything from disk.
|
182
|
+
def self.loadfacts
|
183
|
+
collection.load_all
|
377
184
|
end
|
378
185
|
|
379
|
-
|
380
|
-
# code, with optional confinements restricting the mechanisms to only working on
|
381
|
-
# specific systems. Note that the confinements are always ANDed, so any
|
382
|
-
# confinements specified must all be true for the resolution to be
|
383
|
-
# suitable.
|
384
|
-
class Resolution
|
385
|
-
attr_accessor :interpreter, :code, :name, :fact
|
386
|
-
|
387
|
-
def Resolution.have_which
|
388
|
-
if @have_which.nil?
|
389
|
-
%x{which which 2>/dev/null}
|
390
|
-
@have_which = ($? == 0)
|
391
|
-
end
|
392
|
-
@have_which
|
393
|
-
end
|
394
|
-
|
395
|
-
# Execute a chunk of code.
|
396
|
-
def Resolution.exec(code, interpreter = "/bin/sh")
|
397
|
-
if interpreter == "/bin/sh"
|
398
|
-
binary = code.split(/\s+/).shift
|
399
|
-
|
400
|
-
if have_which
|
401
|
-
path = nil
|
402
|
-
if binary !~ /^\//
|
403
|
-
path = %x{which #{binary} 2>/dev/null}.chomp
|
404
|
-
if path == ""
|
405
|
-
# we don't have the binary necessary
|
406
|
-
return nil
|
407
|
-
end
|
408
|
-
else
|
409
|
-
path = binary
|
410
|
-
end
|
411
|
-
|
412
|
-
unless FileTest.exists?(path)
|
413
|
-
# our binary does not exist
|
414
|
-
return nil
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
out = nil
|
419
|
-
begin
|
420
|
-
out = %x{#{code}}.chomp
|
421
|
-
rescue => detail
|
422
|
-
$stderr.puts detail
|
423
|
-
return nil
|
424
|
-
end
|
425
|
-
if out == ""
|
426
|
-
return nil
|
427
|
-
else
|
428
|
-
return out
|
429
|
-
end
|
430
|
-
else
|
431
|
-
raise ArgumentError,
|
432
|
-
"non-sh interpreters are not currently supported"
|
433
|
-
end
|
434
|
-
end
|
435
|
-
|
436
|
-
# Add a new confine to the resolution mechanism.
|
437
|
-
def confine(*args)
|
438
|
-
if args[0].is_a? Hash
|
439
|
-
args[0].each do |fact, values|
|
440
|
-
@confines.push Confine.new(fact,*values)
|
441
|
-
end
|
442
|
-
else
|
443
|
-
fact = args.shift
|
444
|
-
@confines.push Confine.new(fact,*args)
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
|
-
# Create a new resolution mechanism.
|
449
|
-
def initialize(name)
|
450
|
-
@name = name
|
451
|
-
@confines = []
|
452
|
-
@value = nil
|
453
|
-
end
|
454
|
-
|
455
|
-
# Return the number of confines.
|
456
|
-
def length
|
457
|
-
@confines.length
|
458
|
-
end
|
459
|
-
|
460
|
-
# Set our code for returning a value.
|
461
|
-
def setcode(string = nil, interp = nil, &block)
|
462
|
-
if string
|
463
|
-
@code = string
|
464
|
-
@interpreter = interp || "/bin/sh"
|
465
|
-
else
|
466
|
-
unless block_given?
|
467
|
-
raise ArgumentError, "You must pass either code or a block"
|
468
|
-
end
|
469
|
-
@code = block
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
# Set the name by which this parameter is known in LDAP. The default
|
474
|
-
# is just the fact name.
|
475
|
-
def setldapname(name)
|
476
|
-
@fact.ldapname = name.to_s
|
477
|
-
end
|
478
|
-
|
479
|
-
# Is this resolution mechanism suitable on the system in question?
|
480
|
-
def suitable?
|
481
|
-
unless defined? @suitable
|
482
|
-
@suitable = true
|
483
|
-
if @confines.length == 0
|
484
|
-
return true
|
485
|
-
end
|
486
|
-
@confines.each { |confine|
|
487
|
-
unless confine.true?
|
488
|
-
@suitable = false
|
489
|
-
end
|
490
|
-
}
|
491
|
-
end
|
492
|
-
|
493
|
-
return @suitable
|
494
|
-
end
|
495
|
-
|
496
|
-
# Set tags on our parent fact.
|
497
|
-
def tag(*values)
|
498
|
-
@fact.tag(*values)
|
499
|
-
end
|
500
|
-
|
501
|
-
def to_s
|
502
|
-
return self.value()
|
503
|
-
end
|
504
|
-
|
505
|
-
# How we get a value for our resolution mechanism.
|
506
|
-
def value
|
507
|
-
value = nil
|
508
|
-
|
509
|
-
if @code.is_a?(Proc)
|
510
|
-
value = @code.call()
|
511
|
-
else
|
512
|
-
unless defined? @interpreter
|
513
|
-
@interpreter = "/bin/sh"
|
514
|
-
end
|
515
|
-
if @code.nil?
|
516
|
-
$stderr.puts "Code for %s is nil" % @name
|
517
|
-
else
|
518
|
-
value = Resolution.exec(@code,@interpreter)
|
519
|
-
end
|
520
|
-
end
|
521
|
-
|
522
|
-
if value == ""
|
523
|
-
value = nil
|
524
|
-
end
|
525
|
-
|
526
|
-
return value
|
527
|
-
end
|
186
|
+
@search_path = []
|
528
187
|
|
188
|
+
# Register a directory to search through.
|
189
|
+
def self.search(*dirs)
|
190
|
+
@search_path += dirs
|
529
191
|
end
|
530
192
|
|
531
|
-
#
|
532
|
-
|
533
|
-
|
534
|
-
attr_accessor :fact, :op, :value
|
535
|
-
|
536
|
-
# Add the tag. Requires the fact name, an operator, and the value
|
537
|
-
# we're comparing to.
|
538
|
-
def initialize(fact, *values)
|
539
|
-
fact = fact.to_s if fact.is_a? Symbol
|
540
|
-
@fact = fact
|
541
|
-
@values = values.collect do |value|
|
542
|
-
if value.is_a? String
|
543
|
-
value
|
544
|
-
else
|
545
|
-
value.to_s
|
546
|
-
end
|
547
|
-
end
|
548
|
-
end
|
549
|
-
|
550
|
-
def to_s
|
551
|
-
return "'%s' '%s'" % [@fact, @values.join(",")]
|
552
|
-
end
|
553
|
-
|
554
|
-
# Evaluate the fact, returning true or false.
|
555
|
-
def true?
|
556
|
-
fact = nil
|
557
|
-
unless fact = Facter[@fact]
|
558
|
-
Facter.debug "No fact for %s" % @fact
|
559
|
-
return false
|
560
|
-
end
|
561
|
-
value = fact.value
|
562
|
-
|
563
|
-
if value.nil?
|
564
|
-
return false
|
565
|
-
end
|
566
|
-
|
567
|
-
retval = @values.find { |v|
|
568
|
-
if value.downcase == v.downcase
|
569
|
-
break true
|
570
|
-
end
|
571
|
-
}
|
572
|
-
|
573
|
-
if retval
|
574
|
-
retval = true
|
575
|
-
else
|
576
|
-
retval = false
|
577
|
-
end
|
578
|
-
|
579
|
-
return retval || false
|
580
|
-
end
|
193
|
+
# Return our registered search directories.
|
194
|
+
def self.search_path
|
195
|
+
@search_path.dup
|
581
196
|
end
|
582
|
-
|
583
|
-
# Load all of the default facts
|
584
|
-
def self.loadfacts
|
585
|
-
Facter.add(:facterversion) do
|
586
|
-
setcode { FACTERVERSION.to_s }
|
587
|
-
end
|
588
|
-
|
589
|
-
Facter.add(:rubyversion) do
|
590
|
-
setcode { RUBY_VERSION.to_s }
|
591
|
-
end
|
592
|
-
|
593
|
-
Facter.add(:puppetversion) do
|
594
|
-
setcode {
|
595
|
-
begin
|
596
|
-
require 'puppet'
|
597
|
-
Puppet::PUPPETVERSION.to_s
|
598
|
-
rescue LoadError
|
599
|
-
nil
|
600
|
-
end
|
601
|
-
}
|
602
|
-
end
|
603
|
-
|
604
|
-
Facter.add :rubysitedir do
|
605
|
-
setcode do
|
606
|
-
version = RUBY_VERSION.to_s.sub(/\.\d+$/, '')
|
607
|
-
$:.find do |dir|
|
608
|
-
dir =~ /#{File.join("site_ruby", version)}$/
|
609
|
-
end
|
610
|
-
end
|
611
|
-
end
|
612
|
-
|
613
|
-
Facter.add(:kernel) do
|
614
|
-
setcode 'uname -s'
|
615
|
-
end
|
616
|
-
|
617
|
-
Facter.add(:kernelrelease) do
|
618
|
-
setcode 'uname -r'
|
619
|
-
end
|
620
|
-
|
621
|
-
{ "LSBRelease" => %r{^LSB Version:\t(.*)$},
|
622
|
-
"LSBDistId" => %r{^Distributor ID:\t(.*)$},
|
623
|
-
"LSBDistRelease" => %r{^Release:\t(.*)$},
|
624
|
-
"LSBDistDescription" => %r{^Description:\t(.*)$},
|
625
|
-
"LSBDistCodeName" => %r{^Codename:\t(.*)$}
|
626
|
-
}.each do |fact, pattern|
|
627
|
-
Facter.add(fact) do
|
628
|
-
setcode do
|
629
|
-
unless defined?(@@lsbdata) and defined?(@@lsbtime) and (Time.now.to_i - @@lsbtime.to_i < 5)
|
630
|
-
type = nil
|
631
|
-
@@lsbtime = Time.now
|
632
|
-
@@lsbdata = Resolution.exec('lsb_release -a 2>/dev/null')
|
633
|
-
end
|
634
|
-
if pattern.match(@@lsbdata)
|
635
|
-
$1
|
636
|
-
else
|
637
|
-
nil
|
638
|
-
end
|
639
|
-
end
|
640
|
-
end
|
641
|
-
end
|
642
|
-
|
643
|
-
Facter.add(:operatingsystem) do
|
644
|
-
confine :kernel => :sunos
|
645
|
-
setcode do "Solaris" end
|
646
|
-
end
|
647
|
-
|
648
|
-
Facter.add(:operatingsystem) do
|
649
|
-
confine :kernel => :linux
|
650
|
-
setcode do
|
651
|
-
if FileTest.exists?("/etc/debian_version")
|
652
|
-
"Debian"
|
653
|
-
elsif FileTest.exists?("/etc/gentoo-release")
|
654
|
-
"Gentoo"
|
655
|
-
elsif FileTest.exists?("/etc/fedora-release")
|
656
|
-
"Fedora"
|
657
|
-
elsif FileTest.exists?("/etc/mandriva-release")
|
658
|
-
"Mandriva"
|
659
|
-
elsif FileTest.exists?("/etc/redhat-release")
|
660
|
-
txt = File.read("/etc/redhat-release")
|
661
|
-
if txt =~ /centos/i
|
662
|
-
"CentOS"
|
663
|
-
else
|
664
|
-
"RedHat"
|
665
|
-
end
|
666
|
-
elsif FileTest.exists?("/etc/SuSE-release")
|
667
|
-
"SuSE"
|
668
|
-
end
|
669
|
-
end
|
670
|
-
end
|
671
|
-
|
672
|
-
Facter.add(:operatingsystem) do
|
673
|
-
# Default to just returning the kernel as the operating system
|
674
|
-
setcode do Facter[:kernel].value end
|
675
|
-
end
|
676
|
-
|
677
|
-
Facter.add(:operatingsystemrelease) do
|
678
|
-
confine :operatingsystem => :fedora
|
679
|
-
setcode do
|
680
|
-
File::open("/etc/fedora-release", "r") do |f|
|
681
|
-
line = f.readline.chomp
|
682
|
-
if line =~ /\(Rawhide\)$/
|
683
|
-
"Rawhide"
|
684
|
-
elsif line =~ /release (\d+)/
|
685
|
-
$1
|
686
|
-
end
|
687
|
-
end
|
688
|
-
end
|
689
|
-
end
|
690
|
-
|
691
|
-
Facter.add(:operatingsystemrelease) do
|
692
|
-
confine :operatingsystem => :redhat
|
693
|
-
setcode do
|
694
|
-
File::open("/etc/redhat-release", "r") do |f|
|
695
|
-
line = f.readline.chomp
|
696
|
-
if line =~ /\(Rawhide\)$/
|
697
|
-
"Rawhide"
|
698
|
-
elsif line =~ /release (\d+)/
|
699
|
-
$1
|
700
|
-
end
|
701
|
-
end
|
702
|
-
end
|
703
|
-
end
|
704
|
-
|
705
|
-
Facter.add(:operatingsystemrelease) do
|
706
|
-
setcode do Facter[:kernelrelease].value end
|
707
|
-
end
|
708
|
-
|
709
|
-
Facter.add(:hardwaremodel) do
|
710
|
-
setcode 'uname -m'
|
711
|
-
end
|
712
|
-
|
713
|
-
Facter.add(:architecture) do
|
714
|
-
confine :kernel => :linux
|
715
|
-
setcode do
|
716
|
-
model = Facter.hardwaremodel
|
717
|
-
case model
|
718
|
-
# most linuxen use "x86_64"
|
719
|
-
when 'x86_64':
|
720
|
-
Facter.operatingsystem == "Debian" ? "amd64" : model;
|
721
|
-
when /(i[3456]86|pentium)/: "i386"
|
722
|
-
else
|
723
|
-
model
|
724
|
-
end
|
725
|
-
end
|
726
|
-
end
|
727
|
-
|
728
|
-
Facter.add(:Cfkey) do
|
729
|
-
setcode do
|
730
|
-
value = nil
|
731
|
-
["/usr/local/etc/cfkey.pub",
|
732
|
-
"/etc/cfkey.pub",
|
733
|
-
"/var/cfng/keys/localhost.pub",
|
734
|
-
"/var/cfengine/ppkeys/localhost.pub",
|
735
|
-
"/var/lib/cfengine/ppkeys/localhost.pub",
|
736
|
-
"/var/lib/cfengine2/ppkeys/localhost.pub"
|
737
|
-
].each { |file|
|
738
|
-
if FileTest.file?(file)
|
739
|
-
File.open(file) { |openfile|
|
740
|
-
value = openfile.readlines.reject { |line|
|
741
|
-
line =~ /PUBLIC KEY/
|
742
|
-
}.collect { |line|
|
743
|
-
line.chomp
|
744
|
-
}.join("")
|
745
|
-
}
|
746
|
-
end
|
747
|
-
if value
|
748
|
-
break
|
749
|
-
end
|
750
|
-
}
|
751
|
-
|
752
|
-
value
|
753
|
-
end
|
754
|
-
end
|
755
|
-
|
756
|
-
Facter.add(:domain) do
|
757
|
-
setcode do
|
758
|
-
# First force the hostname to be checked
|
759
|
-
Facter.hostname
|
760
|
-
|
761
|
-
# Now check to see if it set the domain
|
762
|
-
if defined? $domain and ! $domain.nil?
|
763
|
-
$domain
|
764
|
-
else
|
765
|
-
nil
|
766
|
-
end
|
767
|
-
end
|
768
|
-
end
|
769
|
-
# Look for the DNS domain name command first.
|
770
|
-
Facter.add(:domain) do
|
771
|
-
setcode do
|
772
|
-
domain = Resolution.exec('dnsdomainname') or nil
|
773
|
-
# make sure it's a real domain
|
774
|
-
if domain and domain =~ /.+\..+/
|
775
|
-
domain
|
776
|
-
else
|
777
|
-
nil
|
778
|
-
end
|
779
|
-
end
|
780
|
-
end
|
781
|
-
Facter.add(:domain) do
|
782
|
-
setcode do
|
783
|
-
domain = Resolution.exec('domainname') or nil
|
784
|
-
# make sure it's a real domain
|
785
|
-
if domain and domain =~ /.+\..+/
|
786
|
-
domain
|
787
|
-
else
|
788
|
-
nil
|
789
|
-
end
|
790
|
-
end
|
791
|
-
end
|
792
|
-
Facter.add(:domain) do
|
793
|
-
setcode do
|
794
|
-
value = nil
|
795
|
-
if FileTest.exists?("/etc/resolv.conf")
|
796
|
-
File.open("/etc/resolv.conf") { |file|
|
797
|
-
# is the domain set?
|
798
|
-
file.each { |line|
|
799
|
-
if line =~ /domain\s+(\S+)/
|
800
|
-
value = $1
|
801
|
-
break
|
802
|
-
end
|
803
|
-
}
|
804
|
-
}
|
805
|
-
! value and File.open("/etc/resolv.conf") { |file|
|
806
|
-
# is the search path set?
|
807
|
-
file.each { |line|
|
808
|
-
if line =~ /search\s+(\S+)/
|
809
|
-
value = $1
|
810
|
-
break
|
811
|
-
end
|
812
|
-
}
|
813
|
-
}
|
814
|
-
value
|
815
|
-
else
|
816
|
-
nil
|
817
|
-
end
|
818
|
-
end
|
819
|
-
end
|
820
|
-
Facter.add(:hostname) do
|
821
|
-
setldapname "cn"
|
822
|
-
setcode do
|
823
|
-
hostname = nil
|
824
|
-
name = Resolution.exec('hostname') or nil
|
825
|
-
if name
|
826
|
-
if name =~ /^([\w-]+)\.(.+)$/
|
827
|
-
hostname = $1
|
828
|
-
# the Domain class uses this
|
829
|
-
$domain = $2
|
830
|
-
else
|
831
|
-
hostname = name
|
832
|
-
end
|
833
|
-
hostname
|
834
|
-
else
|
835
|
-
nil
|
836
|
-
end
|
837
|
-
end
|
838
|
-
end
|
839
|
-
|
840
|
-
Facter.add(:fqdn) do
|
841
|
-
setcode do
|
842
|
-
host = Facter.value(:hostname)
|
843
|
-
domain = Facter.value(:domain)
|
844
|
-
if host and domain
|
845
|
-
[host, domain].join(".")
|
846
|
-
else
|
847
|
-
nil
|
848
|
-
end
|
849
|
-
end
|
850
|
-
end
|
851
|
-
|
852
|
-
Facter.add(:ipaddress) do
|
853
|
-
setldapname "iphostnumber"
|
854
|
-
setcode do
|
855
|
-
require 'resolv'
|
856
|
-
|
857
|
-
begin
|
858
|
-
if hostname = Facter.hostname
|
859
|
-
ip = Resolv.getaddress(hostname)
|
860
|
-
unless ip == "127.0.0.1"
|
861
|
-
ip
|
862
|
-
end
|
863
|
-
else
|
864
|
-
nil
|
865
|
-
end
|
866
|
-
rescue Resolv::ResolvError
|
867
|
-
nil
|
868
|
-
rescue NoMethodError # i think this is a bug in resolv.rb?
|
869
|
-
nil
|
870
|
-
end
|
871
|
-
end
|
872
|
-
end
|
873
|
-
Facter.add(:ipaddress) do
|
874
|
-
setcode do
|
875
|
-
if hostname = Facter.hostname
|
876
|
-
# we need Hostname to exist for this to work
|
877
|
-
host = nil
|
878
|
-
if host = Resolution.exec("host #{hostname}")
|
879
|
-
host = host.chomp.split(/\s/)
|
880
|
-
if defined? list[-1] and
|
881
|
-
list[-1] =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/
|
882
|
-
list[-1]
|
883
|
-
end
|
884
|
-
else
|
885
|
-
nil
|
886
|
-
end
|
887
|
-
else
|
888
|
-
nil
|
889
|
-
end
|
890
|
-
end
|
891
|
-
end
|
892
|
-
|
893
|
-
["/etc/ssh","/usr/local/etc/ssh","/etc","/usr/local/etc"].each { |dir|
|
894
|
-
{"SSHDSAKey" => "ssh_host_dsa_key.pub",
|
895
|
-
"SSHRSAKey" => "ssh_host_rsa_key.pub"}.each { |name,file|
|
896
|
-
Facter.add(name) do
|
897
|
-
setcode do
|
898
|
-
value = nil
|
899
|
-
filepath = File.join(dir,file)
|
900
|
-
if FileTest.file?(filepath)
|
901
|
-
begin
|
902
|
-
File.open(filepath) { |f|
|
903
|
-
value = f.read.chomp.split(/\s+/)[1]
|
904
|
-
}
|
905
|
-
rescue
|
906
|
-
value = nil
|
907
|
-
end
|
908
|
-
end
|
909
|
-
value
|
910
|
-
end # end of proc
|
911
|
-
end # end of add
|
912
|
-
} # end of hash each
|
913
|
-
} # end of dir each
|
914
|
-
|
915
|
-
Facter.add(:uniqueid) do
|
916
|
-
setcode 'hostid', '/bin/sh'
|
917
|
-
confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
|
918
|
-
end
|
919
|
-
|
920
|
-
Facter.add(:hardwareisa) do
|
921
|
-
setcode 'uname -p', '/bin/sh'
|
922
|
-
confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo FreeBSD OpenBSD NetBSD}
|
923
|
-
end
|
924
|
-
|
925
|
-
Facter.add(:macaddress) do
|
926
|
-
confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
|
927
|
-
setcode do
|
928
|
-
ether = []
|
929
|
-
output = %x{/sbin/ifconfig -a}
|
930
|
-
output.each {|s|
|
931
|
-
ether.push($1) if s =~ /(?:ether|HWaddr) (\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/
|
932
|
-
}
|
933
|
-
ether[0]
|
934
|
-
end
|
935
|
-
end
|
936
|
-
|
937
|
-
Facter.add(:macaddress) do
|
938
|
-
confine :operatingsystem => %w{FreeBSD OpenBSD}
|
939
|
-
setcode do
|
940
|
-
ether = []
|
941
|
-
output = %x{/sbin/ifconfig}
|
942
|
-
output.each {|s|
|
943
|
-
if s =~ /(?:ether|lladdr)\s+(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
|
944
|
-
ether.push($1)
|
945
|
-
end
|
946
|
-
}
|
947
|
-
ether[0]
|
948
|
-
end
|
949
|
-
end
|
950
|
-
|
951
|
-
Facter.add(:macaddress) do
|
952
|
-
confine :kernel => :darwin
|
953
|
-
setcode do
|
954
|
-
ether = nil
|
955
|
-
output = %x{/sbin/ifconfig}
|
956
|
-
|
957
|
-
output.split(/^\S/).each { |str|
|
958
|
-
if str =~ /10baseT/ # we're wired
|
959
|
-
str =~ /ether (\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
|
960
|
-
ether = $1
|
961
|
-
end
|
962
|
-
}
|
963
|
-
|
964
|
-
ether
|
965
|
-
end
|
966
|
-
end
|
967
|
-
|
968
|
-
Facter.add(:ipaddress) do
|
969
|
-
confine :kernel => :linux
|
970
|
-
setcode do
|
971
|
-
ip = nil
|
972
|
-
output = %x{/sbin/ifconfig}
|
973
|
-
|
974
|
-
output.split(/^\S/).each { |str|
|
975
|
-
if str =~ /inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
|
976
|
-
tmp = $1
|
977
|
-
unless tmp =~ /127\./
|
978
|
-
ip = tmp
|
979
|
-
break
|
980
|
-
end
|
981
|
-
end
|
982
|
-
}
|
983
|
-
|
984
|
-
ip
|
985
|
-
end
|
986
|
-
end
|
987
|
-
Facter.add(:ipaddress) do
|
988
|
-
confine :kernel => %w{FreeBSD OpenBSD solaris}
|
989
|
-
setcode do
|
990
|
-
ip = nil
|
991
|
-
output = %x{/sbin/ifconfig}
|
992
|
-
|
993
|
-
output.split(/^\S/).each { |str|
|
994
|
-
if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
|
995
|
-
tmp = $1
|
996
|
-
unless tmp =~ /127\./
|
997
|
-
ip = tmp
|
998
|
-
break
|
999
|
-
end
|
1000
|
-
end
|
1001
|
-
}
|
1002
|
-
|
1003
|
-
ip
|
1004
|
-
end
|
1005
|
-
end
|
1006
|
-
Facter.add(:ipaddress) do
|
1007
|
-
confine :kernel => %w{NetBSD}
|
1008
|
-
setcode do
|
1009
|
-
ip = nil
|
1010
|
-
output = %x{/sbin/ifconfig -a}
|
1011
|
-
|
1012
|
-
output.split(/^\S/).each { |str|
|
1013
|
-
if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
|
1014
|
-
tmp = $1
|
1015
|
-
unless tmp =~ /127\./
|
1016
|
-
ip = tmp
|
1017
|
-
break
|
1018
|
-
end
|
1019
|
-
end
|
1020
|
-
}
|
1021
|
-
|
1022
|
-
ip
|
1023
|
-
end
|
1024
|
-
end
|
1025
|
-
Facter.add(:ipaddress) do
|
1026
|
-
confine :kernel => %w{darwin}
|
1027
|
-
setcode do
|
1028
|
-
ip = nil
|
1029
|
-
iface = ""
|
1030
|
-
output = %x{/usr/sbin/netstat -rn}
|
1031
|
-
if output =~ /^default\s*\S*\s*\S*\s*\S*\s*\S*\s*(\S*).*/
|
1032
|
-
iface = $1
|
1033
|
-
else
|
1034
|
-
warn "Could not find a default route. Using first non-loopback interface"
|
1035
|
-
end
|
1036
|
-
if(iface != "")
|
1037
|
-
output = %x{/sbin/ifconfig #{iface}}
|
1038
|
-
else
|
1039
|
-
output = %x{/sbin/ifconfig}
|
1040
|
-
end
|
1041
|
-
|
1042
|
-
output.split(/^\S/).each { |str|
|
1043
|
-
if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
|
1044
|
-
tmp = $1
|
1045
|
-
unless tmp =~ /127\./
|
1046
|
-
ip = tmp
|
1047
|
-
break
|
1048
|
-
end
|
1049
|
-
end
|
1050
|
-
}
|
1051
|
-
|
1052
|
-
ip
|
1053
|
-
end
|
1054
|
-
end
|
1055
|
-
Facter.add(:hostname) do
|
1056
|
-
confine :kernel => :darwin, :kernelrelease => "R7"
|
1057
|
-
setcode do
|
1058
|
-
%x{/usr/sbin/scutil --get LocalHostName}
|
1059
|
-
end
|
1060
|
-
end
|
1061
|
-
Facter.add(:iphostnumber) do
|
1062
|
-
confine :kernel => :darwin, :kernelrelease => "R6"
|
1063
|
-
setcode do
|
1064
|
-
%x{/usr/sbin/scutil --get LocalHostName}
|
1065
|
-
end
|
1066
|
-
end
|
1067
|
-
Facter.add(:iphostnumber) do
|
1068
|
-
confine :kernel => :darwin, :kernelrelease => "R6"
|
1069
|
-
setcode do
|
1070
|
-
ether = nil
|
1071
|
-
output = %x{/sbin/ifconfig}
|
1072
|
-
|
1073
|
-
output =~ /HWaddr (\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
|
1074
|
-
ether = $1
|
1075
|
-
|
1076
|
-
ether
|
1077
|
-
end
|
1078
|
-
end
|
1079
|
-
|
1080
|
-
Facter.add(:ps) do
|
1081
|
-
setcode do 'ps -ef' end
|
1082
|
-
end
|
1083
|
-
|
1084
|
-
Facter.add(:ps) do
|
1085
|
-
confine :operatingsystem => %w{FreeBSD NetBSD OpenBSD Darwin}
|
1086
|
-
setcode do 'ps -auxwww' end
|
1087
|
-
end
|
1088
|
-
|
1089
|
-
Facter.add(:id) do
|
1090
|
-
#confine :kernel => %w{Solaris Linux}
|
1091
|
-
confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
|
1092
|
-
setcode "whoami"
|
1093
|
-
end
|
1094
|
-
|
1095
|
-
locals = []
|
1096
|
-
|
1097
|
-
# Now find all our loadable facts
|
1098
|
-
factdirs = [] # All the places to check for facts
|
1099
|
-
|
1100
|
-
# See if we can find any other facts in the regular Ruby lib
|
1101
|
-
# paths
|
1102
|
-
$:.each do |dir|
|
1103
|
-
fdir = File.join(dir, "facter")
|
1104
|
-
if FileTest.exists?(fdir) and FileTest.directory?(fdir)
|
1105
|
-
factdirs.push(fdir)
|
1106
|
-
end
|
1107
|
-
end
|
1108
|
-
# Also check anything in 'FACTERLIB'
|
1109
|
-
if ENV['FACTERLIB']
|
1110
|
-
ENV['FACTERLIB'].split(":").each do |fdir|
|
1111
|
-
factdirs.push(fdir)
|
1112
|
-
end
|
1113
|
-
end
|
1114
|
-
factdirs.each do |fdir|
|
1115
|
-
Dir.glob("#{fdir}/*.rb").each do |file|
|
1116
|
-
# Load here, rather than require, because otherwise
|
1117
|
-
# the facts won't get reloaded if someone calls
|
1118
|
-
# "loadfacts". Really only important in testing, but,
|
1119
|
-
# well, it's important in testing.
|
1120
|
-
begin
|
1121
|
-
load file
|
1122
|
-
rescue => detail
|
1123
|
-
warn "Could not load %s: %s" %
|
1124
|
-
[file, detail]
|
1125
|
-
end
|
1126
|
-
end
|
1127
|
-
end
|
1128
|
-
|
1129
|
-
|
1130
|
-
# Now try to get facts from the environment
|
1131
|
-
ENV.each do |name, value|
|
1132
|
-
if name =~ /^facter_?(\w+)$/i
|
1133
|
-
Facter.add($1) do
|
1134
|
-
setcode { value }
|
1135
|
-
end
|
1136
|
-
end
|
1137
|
-
end
|
1138
|
-
end
|
1139
|
-
|
1140
|
-
Facter.loadfacts
|
1141
197
|
end
|
1142
|
-
|
1143
|
-
# $Id$
|