facter 1.0.1 → 1.1.1
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/CHANGES +12 -0
- data/Rakefile +47 -31
- data/bin/facter +6 -7
- data/install.rb +2 -2
- data/lib/facter.rb +390 -343
- metadata +2 -2
data/CHANGES
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
1.1.1:
|
2
|
+
Fixed a bug that occurs when you ask for the value of an unregistered
|
3
|
+
fact.
|
4
|
+
|
5
|
+
1.1.0:
|
6
|
+
Added support for OpenBSD (and probably NetBSD and FreeBSD), and significantly
|
7
|
+
refactored (heh) how facts and resolution mechanisms are added.
|
8
|
+
|
9
|
+
1.0.2:
|
10
|
+
Added SuSE distro
|
11
|
+
Added initial support for Cygwin, thanks to contributions from Eric Sorenson
|
12
|
+
|
1
13
|
1.0.1:
|
2
14
|
Added 'id' fact, which basically returns 'whoami'.
|
3
15
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# Rakefile for facter
|
2
2
|
|
3
3
|
begin
|
4
|
-
|
5
|
-
|
4
|
+
require 'rubygems'
|
5
|
+
require 'rake/gempackagetask'
|
6
6
|
rescue Exception
|
7
|
-
|
7
|
+
nil
|
8
8
|
end
|
9
9
|
|
10
10
|
require 'rake/clean'
|
@@ -32,6 +32,7 @@ else
|
|
32
32
|
PKG_VERSION = CURRENT_VERSION
|
33
33
|
end
|
34
34
|
|
35
|
+
DOWNDIR = "/export/docroots/reductivelabs.com/htdocs/downloads"
|
35
36
|
|
36
37
|
# The default task is run if rake is given no explicit arguments.
|
37
38
|
|
@@ -40,16 +41,16 @@ task :default => :unittests
|
|
40
41
|
|
41
42
|
# Test Tasks ---------------------------------------------------------
|
42
43
|
|
43
|
-
task :u => :unittests
|
44
|
-
task :a => :alltests
|
44
|
+
#task :u => :unittests
|
45
|
+
#task :a => :alltests
|
45
46
|
|
46
|
-
task :alltests => :unittests
|
47
|
+
#task :alltests => :unittests
|
47
48
|
|
48
|
-
Rake::TestTask.new(:unittests) do |t|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
49
|
+
#Rake::TestTask.new(:unittests) do |t|
|
50
|
+
# t.test_files = FileList['tests/*.rb']
|
51
|
+
# t.warning = true
|
52
|
+
# t.verbose = false
|
53
|
+
#end
|
53
54
|
|
54
55
|
# SVN Tasks ----------------------------------------------------------
|
55
56
|
# ... none.
|
@@ -58,18 +59,19 @@ end
|
|
58
59
|
|
59
60
|
desc "Install the application"
|
60
61
|
task :install do
|
61
|
-
|
62
|
+
ruby "install.rb"
|
62
63
|
end
|
63
64
|
|
64
65
|
# Create a task to build the RDOC documentation tree.
|
65
66
|
|
66
|
-
rd = Rake::RDocTask.new(
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
67
|
+
rd = Rake::RDocTask.new(:html) { |rdoc|
|
68
|
+
rdoc.rdoc_dir = 'html'
|
69
|
+
rdoc.template = 'html'
|
70
|
+
rdoc.title = "Facter"
|
71
|
+
rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README'
|
72
|
+
rdoc.rdoc_files.include('README', 'LICENSE', 'TODO', 'CHANGES')
|
73
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
74
|
+
CLEAN.include("html")
|
73
75
|
}
|
74
76
|
|
75
77
|
# ====================================================================
|
@@ -77,18 +79,18 @@ rd = Rake::RDocTask.new("rdoc") { |rdoc|
|
|
77
79
|
# tar, zip and gem files.
|
78
80
|
|
79
81
|
PKG_FILES = FileList[
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
82
|
+
'install.rb',
|
83
|
+
'[A-Z]*',
|
84
|
+
'bin/**/*',
|
85
|
+
'lib/**/*.rb',
|
86
|
+
'test/**/*.rb',
|
87
|
+
'doc/**/*',
|
88
|
+
'etc/*'
|
87
89
|
]
|
88
90
|
PKG_FILES.delete_if {|item| item.include?(".svn")}
|
89
91
|
|
90
92
|
if ! defined?(Gem)
|
91
|
-
|
93
|
+
puts "Package Target requires RubyGEMs"
|
92
94
|
else
|
93
95
|
spec = Gem::Specification.new do |s|
|
94
96
|
|
@@ -138,6 +140,8 @@ else
|
|
138
140
|
#pkg.need_zip = true
|
139
141
|
pkg.need_tar = true
|
140
142
|
end
|
143
|
+
|
144
|
+
CLEAN.include("pkg")
|
141
145
|
end
|
142
146
|
|
143
147
|
# Misc tasks =========================================================
|
@@ -192,10 +196,11 @@ desc "Make a new release"
|
|
192
196
|
task :release => [
|
193
197
|
:prerelease,
|
194
198
|
:clobber,
|
195
|
-
:alltests,
|
196
199
|
:update_version,
|
200
|
+
:tag,
|
197
201
|
:package,
|
198
|
-
:
|
202
|
+
:copy] do
|
203
|
+
#:alltests,
|
199
204
|
|
200
205
|
announce
|
201
206
|
announce "**************************************************************"
|
@@ -246,7 +251,7 @@ task :update_version => [:prerelease] do
|
|
246
251
|
open("lib/facter.rb") do |rakein|
|
247
252
|
open("lib/facter.rb.new", "w") do |rakeout|
|
248
253
|
rakein.each do |line|
|
249
|
-
if line =~
|
254
|
+
if line =~ /^\s*FACTERVERSION\s*=\s*/
|
250
255
|
rakeout.puts "FACTERVERSION = '#{PKG_VERSION}'"
|
251
256
|
else
|
252
257
|
rakeout.puts line
|
@@ -271,7 +276,18 @@ task :tag => [:prerelease] do
|
|
271
276
|
if ENV['RELTEST']
|
272
277
|
announce "Release Task Testing, skipping SVN tagging"
|
273
278
|
else
|
274
|
-
|
279
|
+
sh %{svn copy ../trunk/ ../tags/#{reltag}}
|
280
|
+
sh %{cd ../tags; svn ci -m 'Adding Release tag #{reltag}'}
|
275
281
|
end
|
276
282
|
end
|
277
283
|
|
284
|
+
desc "Copy the newly created package into the downloads directory"
|
285
|
+
task :copy => [:package, :html] do
|
286
|
+
sh %{cp pkg/facter-#{PKG_VERSION}.gem #{DOWNDIR}/gems}
|
287
|
+
sh %{generate_yaml_index.rb -d #{DOWNDIR}}
|
288
|
+
sh %{cp pkg/facter-#{PKG_VERSION}.tgz #{DOWNDIR}/facter}
|
289
|
+
sh %{ln -sf facter-#{PKG_VERSION}.tgz #{DOWNDIR}/facter/facter-latest.tgz}
|
290
|
+
sh %{cp -r html #{DOWNDIR}/facter/apidocs}
|
291
|
+
end
|
292
|
+
|
293
|
+
# $Id$
|
data/bin/facter
CHANGED
@@ -8,17 +8,15 @@
|
|
8
8
|
require 'getoptlong'
|
9
9
|
require 'facter'
|
10
10
|
|
11
|
-
Facter.load
|
12
|
-
|
13
11
|
$debug = 0
|
14
12
|
|
15
13
|
config = nil
|
16
14
|
|
17
15
|
result = GetoptLong.new(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
[ "--version", "-v", GetoptLong::NO_ARGUMENT ],
|
17
|
+
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
|
18
|
+
[ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
|
19
|
+
[ "--config", "-c", GetoptLong::REQUIRED_ARGUMENT ]
|
22
20
|
)
|
23
21
|
|
24
22
|
result.each { |opt,arg|
|
@@ -32,7 +30,8 @@ result.each { |opt,arg|
|
|
32
30
|
puts "There is no help yet"
|
33
31
|
exit
|
34
32
|
else
|
35
|
-
|
33
|
+
$stderr.puts "Invalid option '#{opt}'"
|
34
|
+
exit(12)
|
36
35
|
end
|
37
36
|
}
|
38
37
|
|
data/install.rb
CHANGED
@@ -283,7 +283,7 @@ EOS
|
|
283
283
|
prepare_installation
|
284
284
|
|
285
285
|
run_tests(tests) if InstallOptions.tests
|
286
|
-
build_rdoc(rdoc) if InstallOptions.rdoc
|
287
|
-
build_ri(ri) if InstallOptions.ri
|
286
|
+
#build_rdoc(rdoc) if InstallOptions.rdoc
|
287
|
+
#build_ri(ri) if InstallOptions.ri
|
288
288
|
do_bins(bins, Config::CONFIG['bindir'])
|
289
289
|
do_libs(libs)
|
data/lib/facter.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
|
-
# $Id: facter.rb
|
1
|
+
# $Id: facter.rb 78 2006-01-10 22:57:50Z luke $
|
2
2
|
#--
|
3
3
|
# Copyright 2004 Luke Kanies <luke@madstop.com>
|
4
4
|
#
|
5
5
|
# This program is free software. It may be redistributed and/or modified under
|
6
|
-
# the terms of the
|
7
|
-
# Ruby licence.
|
6
|
+
# the terms of the Apache license.
|
8
7
|
#
|
9
8
|
#--
|
10
9
|
|
11
|
-
#--------------------------------------------------------------------
|
12
10
|
class Facter
|
13
11
|
include Comparable
|
14
12
|
include Enumerable
|
15
13
|
|
16
|
-
|
14
|
+
FACTERVERSION = '1.1.1'
|
17
15
|
# = Facter 1.0
|
18
16
|
# Functions as a hash of 'facts' you might care about about your
|
19
17
|
# system, such as mac address, IP address, Video card, etc.
|
@@ -37,14 +35,14 @@ class Facter
|
|
37
35
|
|
38
36
|
attr_accessor :name, :os, :osrel, :hardware, :searching
|
39
37
|
|
40
|
-
#----------------------------------------------------------------
|
41
38
|
# module methods
|
42
|
-
#----------------------------------------------------------------
|
43
39
|
|
40
|
+
# Return the version of the library.
|
44
41
|
def Facter.version
|
45
42
|
return FACTERVERSION
|
46
43
|
end
|
47
44
|
|
45
|
+
# Add some debugging
|
48
46
|
def Facter.debug(string)
|
49
47
|
if string.nil?
|
50
48
|
return
|
@@ -54,18 +52,15 @@ class Facter
|
|
54
52
|
end
|
55
53
|
end
|
56
54
|
|
57
|
-
|
55
|
+
# Return a fact object by name. If you use this, you still have to call 'value'
|
56
|
+
# on it to retrieve the actual value.
|
58
57
|
def Facter.[](name)
|
59
|
-
|
60
|
-
return @@facts[name.downcase]
|
61
|
-
else
|
62
|
-
return Facter.add(name)
|
63
|
-
end
|
58
|
+
@@facts[name.to_s.downcase]
|
64
59
|
end
|
65
|
-
#----------------------------------------------------------------
|
66
60
|
|
67
|
-
|
68
|
-
|
61
|
+
# Add a resolution mechanism for a named fact. This does not distinguish between
|
62
|
+
# adding a new fact and adding a new way to resolve a fact.
|
63
|
+
def Facter.add(name, &block)
|
69
64
|
fact = nil
|
70
65
|
dcname = name.downcase
|
71
66
|
|
@@ -76,17 +71,18 @@ class Facter
|
|
76
71
|
fact = @@facts[dcname]
|
77
72
|
end
|
78
73
|
|
79
|
-
|
80
|
-
fact
|
74
|
+
unless block
|
75
|
+
return fact
|
81
76
|
end
|
82
77
|
|
78
|
+
fact.add(&block)
|
79
|
+
|
83
80
|
return fact
|
84
81
|
end
|
85
|
-
#----------------------------------------------------------------
|
86
82
|
|
87
|
-
#----------------------------------------------------------------
|
88
83
|
class << self
|
89
84
|
include Enumerable
|
85
|
+
# Iterate across all of the facts.
|
90
86
|
def each
|
91
87
|
@@facts.each { |name,fact|
|
92
88
|
if fact.suitable?
|
@@ -98,18 +94,28 @@ class Facter
|
|
98
94
|
}
|
99
95
|
end
|
100
96
|
end
|
101
|
-
#----------------------------------------------------------------
|
102
97
|
|
103
|
-
|
98
|
+
def Facter.value(name)
|
99
|
+
if @@facts.include?(name.to_s.downcase)
|
100
|
+
@@facts[name.to_s.downcase].value
|
101
|
+
else
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Flush all cached values.
|
107
|
+
def Facter.flush
|
108
|
+
@@facts.each { |fact| fact.flush }
|
109
|
+
end
|
110
|
+
|
111
|
+
# Remove them all.
|
104
112
|
def Facter.reset
|
105
113
|
@@facts.each { |name,fact|
|
106
114
|
@@facts.delete(name)
|
107
115
|
}
|
108
116
|
end
|
109
|
-
#----------------------------------------------------------------
|
110
117
|
|
111
|
-
|
112
|
-
#
|
118
|
+
# Set debugging on or off.
|
113
119
|
def Facter.debugging(bit)
|
114
120
|
if bit
|
115
121
|
case bit
|
@@ -134,64 +140,52 @@ class Facter
|
|
134
140
|
@@debug = 0
|
135
141
|
end
|
136
142
|
end
|
137
|
-
#----------------------------------------------------------------
|
138
143
|
|
139
|
-
|
140
|
-
#def Facter.init
|
141
|
-
# @@os = @@facts["operatingsystem"].value
|
142
|
-
# @@release = @@facts["operatingsystemrelease"].value
|
143
|
-
#end
|
144
|
-
#----------------------------------------------------------------
|
145
|
-
|
146
|
-
#----------------------------------------------------------------
|
144
|
+
# Return a list of all of the facts.
|
147
145
|
def Facter.list
|
148
146
|
return @@facts.keys
|
149
147
|
end
|
150
|
-
#----------------------------------------------------------------
|
151
|
-
|
152
|
-
#----------------------------------------------------------------
|
153
|
-
def Facter.os
|
154
|
-
return @@os
|
155
|
-
end
|
156
|
-
#----------------------------------------------------------------
|
157
|
-
|
158
|
-
#----------------------------------------------------------------
|
159
|
-
def Facter.release
|
160
|
-
return @@release
|
161
|
-
end
|
162
|
-
#----------------------------------------------------------------
|
163
148
|
|
164
|
-
|
149
|
+
# Compare one value to another.
|
165
150
|
def <=>(other)
|
166
151
|
return self.value <=> other
|
167
152
|
end
|
168
|
-
#----------------------------------------------------------------
|
169
153
|
|
170
|
-
|
154
|
+
# Are we the same? Used for case statements.
|
155
|
+
def ===(value)
|
156
|
+
self.value == value
|
157
|
+
end
|
158
|
+
|
159
|
+
# Create a new fact, with no resolution mechanisms.
|
171
160
|
def initialize(name)
|
172
161
|
@name = name.downcase
|
173
162
|
if @@facts.include?(@name)
|
174
|
-
raise "A fact named %s already exists" % name
|
163
|
+
raise ArgumentError, "A fact named %s already exists" % name
|
175
164
|
else
|
176
165
|
@@facts[@name] = self
|
177
166
|
end
|
178
167
|
|
179
168
|
@resolves = []
|
180
169
|
@searching = false
|
170
|
+
|
171
|
+
@value = nil
|
181
172
|
end
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
173
|
+
|
174
|
+
# Add a new resolution mechanism. This requires a block, which will then
|
175
|
+
# be evaluated in the context of the new mechanism.
|
176
|
+
def add(&block)
|
177
|
+
unless block_given?
|
178
|
+
raise ArgumentError, "You must pass a block to Fact<instance>.add"
|
179
|
+
end
|
180
|
+
|
190
181
|
resolve = Resolution.new(@name)
|
191
|
-
|
182
|
+
|
183
|
+
resolve.instance_eval(&block)
|
192
184
|
|
193
185
|
# skip resolves that will never be suitable for us
|
194
|
-
|
186
|
+
unless resolve.suitable?
|
187
|
+
return
|
188
|
+
end
|
195
189
|
|
196
190
|
# insert resolves in order of number of tags
|
197
191
|
inserted = false
|
@@ -207,41 +201,34 @@ class Facter
|
|
207
201
|
@resolves.push resolve
|
208
202
|
end
|
209
203
|
end
|
210
|
-
#----------------------------------------------------------------
|
211
204
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
205
|
+
# Return a count of resolution mechanisms available.
|
206
|
+
def count
|
207
|
+
return @resolves.length
|
208
|
+
end
|
209
|
+
|
210
|
+
# Iterate across all of the fact resolution mechanisms and yield each in
|
211
|
+
# turn. These are inserted in order of most tags.
|
216
212
|
def each
|
217
|
-
# @resolves.sort { |a,b|
|
218
|
-
# puts "for tag %s, alength is %s and blength is %s" %
|
219
|
-
# [@name, a.length, b.length]
|
220
|
-
# b.length <=> a.length
|
221
|
-
# }.each { |resolve|
|
222
|
-
# yield resolve
|
223
|
-
# }
|
224
213
|
@resolves.each { |r| yield r }
|
225
214
|
end
|
226
|
-
#----------------------------------------------------------------
|
227
215
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
216
|
+
# Flush any cached values.
|
217
|
+
def flush
|
218
|
+
@value = nil
|
219
|
+
@suitable = nil
|
232
220
|
end
|
233
|
-
#----------------------------------------------------------------
|
234
221
|
|
235
|
-
|
236
|
-
#
|
237
|
-
# again, this should really be optimizing by throwing away everything
|
238
|
-
# not suitable, but...
|
222
|
+
# Is this fact suitable for finding answers on this host? This is used
|
223
|
+
# to throw away any initially unsuitable mechanisms.
|
239
224
|
def suitable?
|
240
|
-
|
225
|
+
if @resolves.length == 0
|
226
|
+
return false
|
227
|
+
end
|
241
228
|
|
242
|
-
unless defined? @suitable
|
229
|
+
unless defined? @suitable or (defined? @suitable and @suitable.nil?)
|
243
230
|
@suitable = false
|
244
|
-
|
231
|
+
@resolves.each { |resolve|
|
245
232
|
if resolve.suitable?
|
246
233
|
@suitable = true
|
247
234
|
break
|
@@ -251,47 +238,47 @@ class Facter
|
|
251
238
|
|
252
239
|
return @suitable
|
253
240
|
end
|
254
|
-
#----------------------------------------------------------------
|
255
241
|
|
256
|
-
|
242
|
+
# Return the value for a given fact. Searches through all of the mechanisms
|
243
|
+
# and returns either the first value or nil.
|
257
244
|
def value
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
245
|
+
unless @value
|
246
|
+
# make sure we don't get stuck in recursive dependency loops
|
247
|
+
if @searching
|
248
|
+
Facter.debug "Caught recursion on %s" % @name
|
249
|
+
|
250
|
+
# return a cached value if we've got it
|
251
|
+
if @value
|
252
|
+
return @value
|
253
|
+
else
|
254
|
+
return nil
|
255
|
+
end
|
256
|
+
end
|
257
|
+
@value = nil
|
258
|
+
foundsuits = false
|
259
|
+
|
260
|
+
if @resolves.length == 0
|
261
|
+
Facter.debug "No resolves for %s" % @name
|
266
262
|
return nil
|
267
263
|
end
|
268
|
-
end
|
269
|
-
@value = nil
|
270
|
-
foundsuits = false
|
271
264
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
265
|
+
@searching = true
|
266
|
+
@resolves.each { |resolve|
|
267
|
+
#Facter.debug "Searching resolves for %s" % @name
|
268
|
+
if resolve.suitable?
|
269
|
+
@value = resolve.value
|
270
|
+
foundsuits = true
|
271
|
+
end
|
272
|
+
unless @value.nil? or @value == ""
|
273
|
+
break
|
274
|
+
end
|
275
|
+
}
|
276
|
+
@searching = false
|
276
277
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
if resolve.suitable?
|
281
|
-
@value = resolve.value
|
282
|
-
foundsuits = true
|
283
|
-
else
|
284
|
-
Facter.debug "Unsuitable resolve %s for %s" % [resolve,@name]
|
285
|
-
end
|
286
|
-
unless @value.nil? or @value == ""
|
287
|
-
break
|
278
|
+
unless foundsuits
|
279
|
+
Facter.debug "Found no suitable resolves of %s for %s" %
|
280
|
+
[@resolves.length,@name]
|
288
281
|
end
|
289
|
-
}
|
290
|
-
@searching = false
|
291
|
-
|
292
|
-
unless foundsuits
|
293
|
-
Facter.debug "Found no suitable resolves of %s for %s" %
|
294
|
-
[@resolves.length,@name]
|
295
282
|
end
|
296
283
|
|
297
284
|
if @value.nil?
|
@@ -302,12 +289,15 @@ class Facter
|
|
302
289
|
return @value
|
303
290
|
end
|
304
291
|
end
|
305
|
-
#----------------------------------------------------------------
|
306
292
|
|
307
|
-
|
293
|
+
# An actual fact resolution mechanism. These are largely just chunks of code,
|
294
|
+
# with optional tags restricting the mechanisms to only working on specific
|
295
|
+
# systems. Note that the tags are always ANDed, so any tags specified
|
296
|
+
# must all be true for the resolution to be suitable.
|
308
297
|
class Resolution
|
309
298
|
attr_accessor :interpreter, :code, :name
|
310
299
|
|
300
|
+
# Execute a chunk of code.
|
311
301
|
def Resolution.exec(code, interpreter = "/bin/sh")
|
312
302
|
if interpreter == "/bin/sh"
|
313
303
|
binary = code.split(/\s+/).shift
|
@@ -332,6 +322,7 @@ class Facter
|
|
332
322
|
out = %x{#{code}}.chomp
|
333
323
|
rescue => detail
|
334
324
|
$stderr.puts detail
|
325
|
+
return nil
|
335
326
|
end
|
336
327
|
if out == ""
|
337
328
|
return nil
|
@@ -339,29 +330,44 @@ class Facter
|
|
339
330
|
return out
|
340
331
|
end
|
341
332
|
else
|
342
|
-
raise "non-sh interpreters are not currently supported"
|
333
|
+
raise ArgumentError, "non-sh interpreters are not currently supported"
|
343
334
|
end
|
344
335
|
end
|
345
336
|
|
337
|
+
# Create a new resolution mechanism.
|
346
338
|
def initialize(name)
|
347
339
|
@name = name
|
348
340
|
@tags = []
|
341
|
+
@value = nil
|
349
342
|
end
|
350
343
|
|
344
|
+
# Return the number of tags.
|
351
345
|
def length
|
352
346
|
@tags.length
|
353
347
|
end
|
354
348
|
|
349
|
+
# Set our code for returning a value.
|
350
|
+
def setcode(string = nil, interp = nil, &block)
|
351
|
+
if string
|
352
|
+
@code = string
|
353
|
+
@interpreter = interp || "/bin/sh"
|
354
|
+
else
|
355
|
+
unless block_given?
|
356
|
+
raise ArgumentError, "You must pass either code or a block"
|
357
|
+
end
|
358
|
+
@code = block
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
# Is this resolution mechanism suitable on the system in question?
|
355
363
|
def suitable?
|
356
364
|
unless defined? @suitable
|
357
365
|
@suitable = true
|
358
366
|
if @tags.length == 0
|
359
|
-
#Facter.debug "'%s' has no tags" % @name
|
360
367
|
return true
|
361
368
|
end
|
362
369
|
@tags.each { |tag|
|
363
370
|
unless tag.true?
|
364
|
-
#Facter.debug "'%s' is false" % tag
|
365
371
|
@suitable = false
|
366
372
|
end
|
367
373
|
}
|
@@ -370,18 +376,19 @@ class Facter
|
|
370
376
|
return @suitable
|
371
377
|
end
|
372
378
|
|
373
|
-
|
374
|
-
|
379
|
+
# Add a new tag to the resolution mechanism.
|
380
|
+
def tag(fact,*values)
|
381
|
+
@tags.push Tag.new(fact,*values)
|
375
382
|
end
|
376
383
|
|
377
384
|
def to_s
|
378
385
|
return self.value()
|
379
386
|
end
|
380
387
|
|
381
|
-
#
|
388
|
+
# How we get a value for our resolution mechanism.
|
382
389
|
def value
|
383
|
-
#puts "called %s value" % @name
|
384
390
|
value = nil
|
391
|
+
|
385
392
|
if @code.is_a?(Proc)
|
386
393
|
value = @code.call()
|
387
394
|
else
|
@@ -401,66 +408,104 @@ class Facter
|
|
401
408
|
|
402
409
|
return value
|
403
410
|
end
|
411
|
+
|
404
412
|
end
|
405
|
-
#----------------------------------------------------------------
|
406
413
|
|
407
|
-
|
414
|
+
# A restricting tag for fact resolution mechanisms. The tag must be true
|
415
|
+
# for the resolution mechanism to be suitable.
|
408
416
|
class Tag
|
409
417
|
attr_accessor :fact, :op, :value
|
410
418
|
|
411
|
-
|
419
|
+
# Add the tag. Requires the fact name, an operator, and the value we're
|
420
|
+
# comparing to.
|
421
|
+
def initialize(fact, *values)
|
412
422
|
@fact = fact
|
413
|
-
|
414
|
-
op = "=="
|
415
|
-
end
|
416
|
-
@op = op
|
417
|
-
@value = value
|
423
|
+
@values = values
|
418
424
|
end
|
419
425
|
|
420
426
|
def to_s
|
421
|
-
return "'%s'
|
427
|
+
return "'%s' '%s'" % [@fact, @values.join(",")]
|
422
428
|
end
|
423
429
|
|
430
|
+
# Evaluate the fact, returning true or false.
|
424
431
|
def true?
|
425
|
-
|
432
|
+
fact = nil
|
433
|
+
unless fact = Facter[@fact]
|
434
|
+
Facter.debug "No fact for %s" % @fact
|
435
|
+
return false
|
436
|
+
end
|
437
|
+
value = fact.value
|
426
438
|
|
427
439
|
if value.nil?
|
428
440
|
return false
|
429
441
|
end
|
430
442
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
return true
|
435
|
-
else
|
436
|
-
return false
|
443
|
+
retval = @values.find { |v|
|
444
|
+
if value == v
|
445
|
+
break true
|
437
446
|
end
|
438
|
-
|
439
|
-
|
440
|
-
|
447
|
+
}
|
448
|
+
|
449
|
+
if retval
|
450
|
+
retval = true
|
451
|
+
else
|
452
|
+
retval = false
|
441
453
|
end
|
454
|
+
|
455
|
+
return retval || false
|
442
456
|
end
|
443
457
|
end
|
444
|
-
#----------------------------------------------------------------
|
445
458
|
|
446
459
|
# Load all of the default facts
|
447
460
|
def Facter.load
|
448
|
-
Facter
|
449
|
-
|
450
|
-
|
461
|
+
Facter.add("Kernel") do
|
462
|
+
setcode 'uname -s'
|
463
|
+
end
|
451
464
|
|
452
|
-
Facter
|
453
|
-
|
454
|
-
|
465
|
+
Facter.add("KernelRelease") do
|
466
|
+
setcode 'uname -r'
|
467
|
+
end
|
455
468
|
|
456
|
-
Facter
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
469
|
+
Facter.add("OperatingSystem") do
|
470
|
+
# Default to just returning the kernel as the operating system
|
471
|
+
setcode do Facter["Kernel"].value end
|
472
|
+
end
|
473
|
+
|
474
|
+
Facter.add("OperatingSystemRelease") do
|
475
|
+
setcode do Facter["KernelRelease"].value end
|
476
|
+
end
|
461
477
|
|
462
|
-
Facter
|
463
|
-
obj.
|
478
|
+
Facter.add("OperatingSystem") do
|
479
|
+
#obj.os = "Linux"
|
480
|
+
tag("kernel","SunOS")
|
481
|
+
setcode do "Solaris" end
|
482
|
+
end
|
483
|
+
|
484
|
+
Facter.add("OperatingSystem") do
|
485
|
+
#obj.os = "Linux"
|
486
|
+
tag("kernel","Linux")
|
487
|
+
setcode do
|
488
|
+
if FileTest.exists?("/etc/debian_version")
|
489
|
+
"Debian"
|
490
|
+
elsif FileTest.exists?("/etc/gentoo-release")
|
491
|
+
"Gentoo"
|
492
|
+
elsif FileTest.exists?("/etc/fedora-release")
|
493
|
+
"Fedora"
|
494
|
+
elsif FileTest.exists?("/etc/redhat-release")
|
495
|
+
"RedHat"
|
496
|
+
elsif FileTest.exists?("/etc/SuSE-release")
|
497
|
+
"SuSE"
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
Facter.add("HardwareModel") do
|
503
|
+
setcode 'uname -m'
|
504
|
+
#tag("operatingsystem","SunOS")
|
505
|
+
end
|
506
|
+
|
507
|
+
Facter.add("CfKey") do
|
508
|
+
setcode do
|
464
509
|
value = nil
|
465
510
|
["/usr/local/etc/cfkey.pub",
|
466
511
|
"/etc/cfkey.pub",
|
@@ -482,134 +527,148 @@ class Facter
|
|
482
527
|
}
|
483
528
|
|
484
529
|
value
|
485
|
-
|
486
|
-
|
530
|
+
end
|
531
|
+
end
|
487
532
|
|
488
|
-
Facter
|
489
|
-
|
533
|
+
Facter.add("Domain") do
|
534
|
+
setcode do
|
490
535
|
if defined? $domain and ! $domain.nil?
|
491
536
|
$domain
|
537
|
+
else
|
538
|
+
nil
|
492
539
|
end
|
493
|
-
|
494
|
-
|
495
|
-
Facter
|
496
|
-
|
497
|
-
domain = Resolution.exec('domainname')
|
540
|
+
end
|
541
|
+
end
|
542
|
+
Facter.add("Domain") do
|
543
|
+
setcode do
|
544
|
+
domain = Resolution.exec('domainname') or nil
|
498
545
|
# make sure it's a real domain
|
499
|
-
if domain =~ /.+\..+/
|
546
|
+
if domain and domain =~ /.+\..+/
|
500
547
|
domain
|
501
548
|
else
|
502
549
|
nil
|
503
550
|
end
|
504
|
-
|
505
|
-
|
506
|
-
Facter
|
507
|
-
|
551
|
+
end
|
552
|
+
end
|
553
|
+
Facter.add("Domain") do
|
554
|
+
setcode do
|
508
555
|
value = nil
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
end
|
556
|
+
if FileTest.exists?("/etc/resolv.conf")
|
557
|
+
File.open("/etc/resolv.conf") { |file|
|
558
|
+
# is the domain set?
|
559
|
+
file.each { |line|
|
560
|
+
if line =~ /domain\s+(\S+)/
|
561
|
+
value = $1
|
562
|
+
break
|
563
|
+
end
|
564
|
+
}
|
519
565
|
}
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
566
|
+
! value and File.open("/etc/resolv.conf") { |file|
|
567
|
+
# is the search path set?
|
568
|
+
file.each { |line|
|
569
|
+
if line =~ /search\s+(\S+)/
|
570
|
+
value = $1
|
571
|
+
break
|
572
|
+
end
|
573
|
+
}
|
528
574
|
}
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
575
|
+
value
|
576
|
+
else
|
577
|
+
nil
|
578
|
+
end
|
579
|
+
end
|
580
|
+
end
|
581
|
+
Facter.add("Hostname") do
|
582
|
+
setcode do
|
535
583
|
hostname = nil
|
536
|
-
name = Resolution.exec('hostname')
|
537
|
-
if name
|
538
|
-
|
539
|
-
|
540
|
-
|
584
|
+
name = Resolution.exec('hostname') or nil
|
585
|
+
if name
|
586
|
+
if name =~ /^([\w-]+)\.(.+)$/
|
587
|
+
hostname = $1
|
588
|
+
# the Domain class uses this
|
589
|
+
$domain = $2
|
590
|
+
else
|
591
|
+
hostname = name
|
592
|
+
end
|
593
|
+
hostname
|
541
594
|
else
|
542
|
-
|
595
|
+
nil
|
543
596
|
end
|
544
|
-
|
545
|
-
|
546
|
-
}
|
597
|
+
end
|
598
|
+
end
|
547
599
|
|
548
|
-
Facter
|
549
|
-
|
600
|
+
Facter.add("IPHostNumber") do
|
601
|
+
setcode do
|
550
602
|
require 'resolv'
|
551
603
|
|
552
604
|
begin
|
553
|
-
hostname = Facter["hostname"].value
|
554
|
-
|
555
|
-
|
556
|
-
|
605
|
+
if hostname = Facter["hostname"].value
|
606
|
+
ip = Resolv.getaddress(hostname)
|
607
|
+
unless ip == "127.0.0.1"
|
608
|
+
ip
|
609
|
+
end
|
610
|
+
else
|
611
|
+
nil
|
557
612
|
end
|
558
613
|
rescue Resolv::ResolvError
|
559
614
|
nil
|
560
615
|
rescue NoMethodError # i think this is a bug in resolv.rb?
|
561
616
|
nil
|
562
617
|
end
|
563
|
-
|
564
|
-
|
565
|
-
Facter
|
566
|
-
|
567
|
-
hostname = Facter["hostname"].value
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
618
|
+
end
|
619
|
+
end
|
620
|
+
Facter.add("IPHostNumber") do
|
621
|
+
setcode do
|
622
|
+
if hostname = Facter["hostname"].value
|
623
|
+
# we need Hostname to exist for this to work
|
624
|
+
if list = Resolution.exec("host #{hostname}").chomp.split(/\s/)
|
625
|
+
|
626
|
+
if defined? list[-1] and
|
627
|
+
list[-1] =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/
|
628
|
+
list[-1]
|
629
|
+
end
|
630
|
+
else
|
631
|
+
nil
|
632
|
+
end
|
633
|
+
else
|
634
|
+
nil
|
573
635
|
end
|
574
|
-
|
575
|
-
|
636
|
+
end
|
637
|
+
end
|
576
638
|
|
577
639
|
["/etc/ssh","/usr/local/etc/ssh","/etc","/usr/local/etc"].each { |dir|
|
578
640
|
{"SSHDSAKey" => "ssh_host_dsa_key.pub",
|
579
641
|
"SSHRSAKey" => "ssh_host_rsa_key.pub"}.each { |name,file|
|
580
|
-
Facter
|
581
|
-
|
642
|
+
Facter.add(name) do
|
643
|
+
setcode do
|
582
644
|
value = nil
|
583
645
|
filepath = File.join(dir,file)
|
584
646
|
if FileTest.file?(filepath)
|
585
647
|
begin
|
586
648
|
value = File.open(filepath).read.chomp
|
587
649
|
rescue
|
588
|
-
|
650
|
+
value = nil
|
589
651
|
end
|
590
652
|
end
|
591
|
-
|
592
|
-
|
593
|
-
|
653
|
+
value
|
654
|
+
end # end of proc
|
655
|
+
end # end of add
|
594
656
|
} # end of hash each
|
595
657
|
} # end of dir each
|
596
658
|
|
597
|
-
Facter
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
#obj.os = "SunOS"
|
611
|
-
obj.tag("operatingsystem","=","SunOS")
|
612
|
-
obj.code = proc {
|
659
|
+
Facter.add("UniqueId") do
|
660
|
+
setcode 'hostid', '/bin/sh'
|
661
|
+
tag("operatingsystem","Solaris")
|
662
|
+
end
|
663
|
+
|
664
|
+
Facter.add("HardwareISA") do
|
665
|
+
setcode 'uname -p', '/bin/sh'
|
666
|
+
tag("operatingsystem","Solaris")
|
667
|
+
end
|
668
|
+
|
669
|
+
Facter.add("MacAddress") do
|
670
|
+
tag("operatingsystem","Solaris")
|
671
|
+
setcode do
|
613
672
|
ether = nil
|
614
673
|
output = %x{/sbin/ifconfig -a}
|
615
674
|
|
@@ -617,12 +676,12 @@ class Facter
|
|
617
676
|
ether = $1
|
618
677
|
|
619
678
|
ether
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
679
|
+
end
|
680
|
+
end
|
681
|
+
|
682
|
+
Facter.add("MacAddress") do
|
683
|
+
tag("Kernel","Darwin")
|
684
|
+
setcode do
|
626
685
|
ether = nil
|
627
686
|
output = %x{/sbin/ifconfig}
|
628
687
|
|
@@ -634,12 +693,11 @@ class Facter
|
|
634
693
|
}
|
635
694
|
|
636
695
|
ether
|
637
|
-
|
638
|
-
|
639
|
-
Facter
|
640
|
-
|
641
|
-
|
642
|
-
obj.code = proc {
|
696
|
+
end
|
697
|
+
end
|
698
|
+
Facter.add("IPHostnumber") do
|
699
|
+
tag("Kernel","Darwin")
|
700
|
+
setcode do
|
643
701
|
ip = nil
|
644
702
|
output = %x{/sbin/ifconfig}
|
645
703
|
|
@@ -654,74 +712,76 @@ class Facter
|
|
654
712
|
}
|
655
713
|
|
656
714
|
ip
|
657
|
-
|
658
|
-
|
659
|
-
Facter
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
obj.tag("operatingsystemrelease","=","R7")
|
664
|
-
obj.code = proc {
|
715
|
+
end
|
716
|
+
end
|
717
|
+
Facter.add("Hostname") do
|
718
|
+
tag("Kernel","Darwin")
|
719
|
+
tag("KernelRelease","R7")
|
720
|
+
setcode do
|
665
721
|
hostname = nil
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
if found == 1
|
676
|
-
if line =~ /<string>([\w|-]+)<\/string>/
|
677
|
-
hostname = $1
|
678
|
-
break
|
722
|
+
if FileTest.exists?("/Library/Preferences/SystemConfiguration/preferences.plist")
|
723
|
+
File.open(
|
724
|
+
"/Library/Preferences/SystemConfiguration/preferences.plist"
|
725
|
+
) { |file|
|
726
|
+
found = 0
|
727
|
+
file.each { |line|
|
728
|
+
if line =~ /ComputerName/i
|
729
|
+
found = 1
|
730
|
+
next
|
679
731
|
end
|
680
|
-
|
732
|
+
if found == 1
|
733
|
+
if line =~ /<string>([\w|-]+)<\/string>/
|
734
|
+
hostname = $1
|
735
|
+
break
|
736
|
+
end
|
737
|
+
end
|
738
|
+
}
|
681
739
|
}
|
682
|
-
|
740
|
+
end
|
683
741
|
|
684
742
|
if hostname != nil
|
685
743
|
hostname
|
744
|
+
else
|
745
|
+
nil
|
686
746
|
end
|
687
|
-
|
688
|
-
|
689
|
-
Facter
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
obj.tag("operatingsystemrelease","=","R6")
|
694
|
-
obj.code = proc {
|
747
|
+
end
|
748
|
+
end
|
749
|
+
Facter.add("IPHostnumber") do
|
750
|
+
tag("Kernel","Darwin")
|
751
|
+
tag("KernelRelease","R6")
|
752
|
+
setcode do
|
695
753
|
hostname = nil
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
if found == 1
|
706
|
-
if line =~ /<string>([\w|-]+)<\/string>/
|
707
|
-
hostname = $1
|
708
|
-
break
|
754
|
+
if FileTest.exists?("/var/db/SystemConfiguration/preferences.xml")
|
755
|
+
File.open(
|
756
|
+
"/var/db/SystemConfiguration/preferences.xml"
|
757
|
+
) { |file|
|
758
|
+
found = 0
|
759
|
+
file.each { |line|
|
760
|
+
if line =~ /ComputerName/i
|
761
|
+
found = 1
|
762
|
+
next
|
709
763
|
end
|
710
|
-
|
764
|
+
if found == 1
|
765
|
+
if line =~ /<string>([\w|-]+)<\/string>/
|
766
|
+
hostname = $1
|
767
|
+
break
|
768
|
+
end
|
769
|
+
end
|
770
|
+
}
|
711
771
|
}
|
712
|
-
|
772
|
+
end
|
713
773
|
|
714
774
|
if hostname != nil
|
715
775
|
hostname
|
776
|
+
else
|
777
|
+
nil
|
716
778
|
end
|
717
|
-
|
718
|
-
|
719
|
-
Facter
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
obj.tag("operatingsystemrelease","=","R6")
|
724
|
-
obj.code = proc {
|
779
|
+
end
|
780
|
+
end
|
781
|
+
Facter.add("IPHostnumber") do
|
782
|
+
tag("Kernel","Darwin")
|
783
|
+
tag("KernelRelease","R6")
|
784
|
+
setcode do
|
725
785
|
ether = nil
|
726
786
|
output = %x{/sbin/ifconfig}
|
727
787
|
|
@@ -729,35 +789,22 @@ class Facter
|
|
729
789
|
ether = $1
|
730
790
|
|
731
791
|
ether
|
732
|
-
|
733
|
-
|
734
|
-
Facter["Distro"].add { |obj|
|
735
|
-
#obj.os = "Linux"
|
736
|
-
obj.tag("operatingsystem","=","Linux")
|
737
|
-
obj.code = proc {
|
738
|
-
if FileTest.exists?("/etc/debian_version")
|
739
|
-
return "Debian"
|
740
|
-
elsif FileTest.exists?("/etc/gentoo-release")
|
741
|
-
return "Gentoo"
|
742
|
-
elsif FileTest.exists?("/etc/fedora-release")
|
743
|
-
return "Fedora"
|
744
|
-
elsif FileTest.exists?("/etc/redhat-release")
|
745
|
-
return "RedHat"
|
746
|
-
end
|
747
|
-
}
|
748
|
-
}
|
749
|
-
Facter["ps"].add { |obj|
|
750
|
-
obj.code = "echo 'ps -ef'"
|
751
|
-
}
|
752
|
-
Facter["ps"].add { |obj|
|
753
|
-
obj.tag("operatingsystem","=","Darwin")
|
754
|
-
obj.code = "echo 'ps -auxwww'"
|
755
|
-
}
|
792
|
+
end
|
793
|
+
end
|
756
794
|
|
757
|
-
Facter
|
758
|
-
|
759
|
-
|
760
|
-
|
795
|
+
Facter.add("ps") do
|
796
|
+
setcode do 'ps -ef' end
|
797
|
+
end
|
798
|
+
|
799
|
+
Facter.add("ps") do
|
800
|
+
tag("operatingsystem","FreeBSD", "NetBSD", "OpenBSD", "Darwin")
|
801
|
+
setcode do 'ps -auxwww' end
|
802
|
+
end
|
803
|
+
|
804
|
+
Facter.add("id") do
|
805
|
+
tag("operatingsystem","Linux")
|
806
|
+
setcode "whoami"
|
807
|
+
end
|
761
808
|
end
|
762
809
|
|
763
810
|
Facter.load
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: facter
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date:
|
6
|
+
version: 1.1.1
|
7
|
+
date: 2006-01-10 00:00:00 -06:00
|
8
8
|
summary: Facter collects Operating system facts.
|
9
9
|
require_paths:
|
10
10
|
- lib
|