facter 1.5.4 → 1.5.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 +75 -22
- data/COPYING +289 -623
- data/Rakefile +60 -55
- data/bin/facter +39 -26
- data/conf/osx/PackageInfo.plist +30 -30
- data/conf/osx/createpackage.sh +17 -17
- data/conf/osx/preflight +1 -1
- data/install.rb +226 -226
- data/lib/facter.rb +12 -12
- data/lib/facter/architecture.rb +14 -3
- data/lib/facter/ec2.rb +35 -0
- data/lib/facter/hardwareisa.rb +1 -1
- data/lib/facter/id.rb +1 -1
- data/lib/facter/ipaddress.rb +41 -41
- data/lib/facter/kernel.rb +2 -2
- data/lib/facter/kernelmajversion.rb +5 -0
- data/lib/facter/lsb.rb +5 -5
- data/lib/facter/lsbmajdistrelease.rb +1 -1
- data/lib/facter/macaddress.rb +6 -6
- data/lib/facter/manufacturer.rb +8 -8
- data/lib/facter/memory.rb +5 -4
- data/lib/facter/netmask.rb +4 -4
- data/lib/facter/network.rb +4 -5
- data/lib/facter/operatingsystem.rb +13 -7
- data/lib/facter/operatingsystemrelease.rb +5 -5
- data/lib/facter/selinux.rb +45 -0
- data/lib/facter/timezone.rb +1 -1
- data/lib/facter/uniqueid.rb +2 -2
- data/lib/facter/uptime.rb +3 -3
- data/lib/facter/util/confine.rb +12 -12
- data/lib/facter/util/ip.rb +18 -22
- data/lib/facter/util/macosx.rb +5 -0
- data/lib/facter/util/manufacturer.rb +37 -37
- data/lib/facter/util/plist/generator.rb +181 -179
- data/lib/facter/util/plist/parser.rb +162 -163
- data/lib/facter/util/resolution.rb +2 -2
- data/lib/facter/util/uptime.rb +10 -12
- data/lib/facter/util/values.rb +14 -0
- data/lib/facter/virtual.rb +54 -34
- data/spec/unit/data/darwin_ifconfig_all_with_multiple_interfaces +10 -0
- data/spec/unit/operatingsystem.rb +36 -0
- data/spec/unit/selinux.rb +48 -0
- data/spec/unit/util/confine.rb +70 -5
- data/spec/unit/util/ip.rb +29 -3
- metadata +89 -77
- data/documentation/custom.page +0 -22
- data/documentation/index.page +0 -19
@@ -21,207 +21,206 @@ module Plist
|
|
21
21
|
# If you encounter such an error, or if you have a Date element which
|
22
22
|
# can't be parsed into a Time object, please send your plist file to
|
23
23
|
# plist@hexane.org so that I can implement the proper support.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
class Listener
|
33
|
-
#include REXML::StreamListener
|
34
|
-
|
35
|
-
attr_accessor :result, :open
|
36
|
-
|
37
|
-
def initialize
|
38
|
-
@result = nil
|
39
|
-
@open = Array.new
|
24
|
+
def Plist::parse_xml( filename_or_xml )
|
25
|
+
listener = Listener.new
|
26
|
+
#parser = REXML::Parsers::StreamParser.new(File.new(filename), listener)
|
27
|
+
parser = StreamParser.new(filename_or_xml, listener)
|
28
|
+
parser.parse
|
29
|
+
listener.result
|
40
30
|
end
|
41
31
|
|
32
|
+
class Listener
|
33
|
+
#include REXML::StreamListener
|
42
34
|
|
43
|
-
|
44
|
-
@open.push PTag::mappings[name].new
|
45
|
-
end
|
35
|
+
attr_accessor :result, :open
|
46
36
|
|
47
|
-
|
48
|
-
|
49
|
-
|
37
|
+
def initialize
|
38
|
+
@result = nil
|
39
|
+
@open = Array.new
|
40
|
+
end
|
50
41
|
|
51
|
-
def tag_end(name)
|
52
|
-
last = @open.pop
|
53
|
-
if @open.empty?
|
54
|
-
@result = last.to_ruby
|
55
|
-
else
|
56
|
-
@open.last.children.push last
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
42
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
@listener = listener
|
65
|
-
end
|
43
|
+
def tag_start(name, attributes)
|
44
|
+
@open.push PTag::mappings[name].new
|
45
|
+
end
|
66
46
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
COMMENT_START = /\A<!--/u
|
71
|
-
COMMENT_END = /.*?-->/um
|
72
|
-
|
73
|
-
|
74
|
-
def parse
|
75
|
-
plist_tags = PTag::mappings.keys.join('|')
|
76
|
-
start_tag = /<(#{plist_tags})([^>]*)>/i
|
77
|
-
end_tag = /<\/(#{plist_tags})[^>]*>/i
|
78
|
-
|
79
|
-
require 'strscan'
|
80
|
-
|
81
|
-
contents = (
|
82
|
-
if (File.exists? @filename_or_xml)
|
83
|
-
File.open(@filename_or_xml) {|f| f.read}
|
84
|
-
else
|
85
|
-
@filename_or_xml
|
86
|
-
end
|
87
|
-
)
|
88
|
-
|
89
|
-
@scanner = StringScanner.new( contents )
|
90
|
-
until @scanner.eos?
|
91
|
-
if @scanner.scan(COMMENT_START)
|
92
|
-
@scanner.scan(COMMENT_END)
|
93
|
-
elsif @scanner.scan(XMLDECL_PATTERN)
|
94
|
-
elsif @scanner.scan(DOCTYPE_PATTERN)
|
95
|
-
elsif @scanner.scan(start_tag)
|
96
|
-
@listener.tag_start(@scanner[1], nil)
|
97
|
-
if (@scanner[2] =~ /\/$/)
|
98
|
-
@listener.tag_end(@scanner[1])
|
99
|
-
end
|
100
|
-
elsif @scanner.scan(TEXT)
|
101
|
-
@listener.text(@scanner[1])
|
102
|
-
elsif @scanner.scan(end_tag)
|
103
|
-
@listener.tag_end(@scanner[1])
|
104
|
-
else
|
105
|
-
raise "Unimplemented element"
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
47
|
+
def text( contents )
|
48
|
+
@open.last.text = contents if @open.last
|
49
|
+
end
|
110
50
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
51
|
+
def tag_end(name)
|
52
|
+
last = @open.pop
|
53
|
+
if @open.empty?
|
54
|
+
@result = last.to_ruby
|
55
|
+
else
|
56
|
+
@open.last.children.push last
|
57
|
+
end
|
58
|
+
end
|
115
59
|
end
|
116
60
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
61
|
+
class StreamParser
|
62
|
+
def initialize( filename_or_xml, listener )
|
63
|
+
@filename_or_xml = filename_or_xml
|
64
|
+
@listener = listener
|
65
|
+
end
|
121
66
|
|
122
|
-
|
67
|
+
TEXT = /([^<]+)/
|
68
|
+
XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>*/um
|
69
|
+
DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um
|
70
|
+
COMMENT_START = /\A<!--/u
|
71
|
+
COMMENT_END = /.*?-->/um
|
72
|
+
|
73
|
+
def parse
|
74
|
+
plist_tags = PTag::mappings.keys.join('|')
|
75
|
+
start_tag = /<(#{plist_tags})([^>]*)>/i
|
76
|
+
end_tag = /<\/(#{plist_tags})[^>]*>/i
|
77
|
+
|
78
|
+
require 'strscan'
|
79
|
+
|
80
|
+
contents = (
|
81
|
+
if (File.exists? @filename_or_xml)
|
82
|
+
File.open(@filename_or_xml) {|f| f.read}
|
83
|
+
else
|
84
|
+
@filename_or_xml
|
85
|
+
end
|
86
|
+
)
|
87
|
+
|
88
|
+
@scanner = StringScanner.new( contents )
|
89
|
+
until @scanner.eos?
|
90
|
+
if @scanner.scan(COMMENT_START)
|
91
|
+
@scanner.scan(COMMENT_END)
|
92
|
+
elsif @scanner.scan(XMLDECL_PATTERN)
|
93
|
+
elsif @scanner.scan(DOCTYPE_PATTERN)
|
94
|
+
elsif @scanner.scan(start_tag)
|
95
|
+
@listener.tag_start(@scanner[1], nil)
|
96
|
+
if (@scanner[2] =~ /\/$/)
|
97
|
+
@listener.tag_end(@scanner[1])
|
98
|
+
end
|
99
|
+
elsif @scanner.scan(TEXT)
|
100
|
+
@listener.text(@scanner[1])
|
101
|
+
elsif @scanner.scan(end_tag)
|
102
|
+
@listener.tag_end(@scanner[1])
|
103
|
+
else
|
104
|
+
raise "Unimplemented element"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
123
108
|
end
|
124
109
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
110
|
+
class PTag
|
111
|
+
@@mappings = { }
|
112
|
+
def PTag::mappings
|
113
|
+
@@mappings
|
114
|
+
end
|
129
115
|
|
130
|
-
|
131
|
-
|
116
|
+
def PTag::inherited( sub_class )
|
117
|
+
key = sub_class.to_s.downcase
|
118
|
+
key.gsub!(/^plist::/, '' )
|
119
|
+
key.gsub!(/^p/, '') unless key == "plist"
|
120
|
+
|
121
|
+
@@mappings[key] = sub_class
|
122
|
+
end
|
123
|
+
|
124
|
+
attr_accessor :text, :children
|
125
|
+
def initialize
|
126
|
+
@children = Array.new
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_ruby
|
130
|
+
raise "Unimplemented: " + self.class.to_s + "#to_ruby on #{self.inspect}"
|
131
|
+
end
|
132
132
|
end
|
133
|
-
end
|
134
133
|
|
135
|
-
|
136
|
-
|
137
|
-
|
134
|
+
class PList < PTag
|
135
|
+
def to_ruby
|
136
|
+
children.first.to_ruby if children.first
|
137
|
+
end
|
138
138
|
end
|
139
|
-
end
|
140
139
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
140
|
+
class PDict < PTag
|
141
|
+
def to_ruby
|
142
|
+
dict = Hash.new
|
143
|
+
key = nil
|
145
144
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
145
|
+
children.each do |c|
|
146
|
+
if key.nil?
|
147
|
+
key = c.to_ruby
|
148
|
+
else
|
149
|
+
dict[key] = c.to_ruby
|
150
|
+
key = nil
|
151
|
+
end
|
152
|
+
end
|
154
153
|
|
155
|
-
|
154
|
+
dict
|
155
|
+
end
|
156
156
|
end
|
157
|
-
end
|
158
157
|
|
159
|
-
|
160
|
-
|
161
|
-
|
158
|
+
class PKey < PTag
|
159
|
+
def to_ruby
|
160
|
+
CGI::unescapeHTML(text || '')
|
161
|
+
end
|
162
162
|
end
|
163
|
-
end
|
164
163
|
|
165
|
-
|
166
|
-
|
167
|
-
|
164
|
+
class PString < PTag
|
165
|
+
def to_ruby
|
166
|
+
CGI::unescapeHTML(text || '')
|
167
|
+
end
|
168
168
|
end
|
169
|
-
end
|
170
169
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
170
|
+
class PArray < PTag
|
171
|
+
def to_ruby
|
172
|
+
children.collect do |c|
|
173
|
+
c.to_ruby
|
174
|
+
end
|
175
|
+
end
|
176
176
|
end
|
177
|
-
end
|
178
177
|
|
179
|
-
|
180
|
-
|
181
|
-
|
178
|
+
class PInteger < PTag
|
179
|
+
def to_ruby
|
180
|
+
text.to_i
|
181
|
+
end
|
182
182
|
end
|
183
|
-
end
|
184
183
|
|
185
|
-
|
186
|
-
|
187
|
-
|
184
|
+
class PTrue < PTag
|
185
|
+
def to_ruby
|
186
|
+
true
|
187
|
+
end
|
188
188
|
end
|
189
|
-
end
|
190
189
|
|
191
|
-
|
192
|
-
|
193
|
-
|
190
|
+
class PFalse < PTag
|
191
|
+
def to_ruby
|
192
|
+
false
|
193
|
+
end
|
194
194
|
end
|
195
|
-
end
|
196
195
|
|
197
|
-
|
198
|
-
|
199
|
-
|
196
|
+
class PReal < PTag
|
197
|
+
def to_ruby
|
198
|
+
text.to_f
|
199
|
+
end
|
200
200
|
end
|
201
|
-
end
|
202
201
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
202
|
+
require 'date'
|
203
|
+
class PDate < PTag
|
204
|
+
def to_ruby
|
205
|
+
DateTime.parse(text)
|
206
|
+
end
|
207
207
|
end
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
208
|
+
|
209
|
+
require 'base64'
|
210
|
+
class PData < PTag
|
211
|
+
def to_ruby
|
212
|
+
data = Base64.decode64(text.gsub(/\s+/, ''))
|
213
|
+
|
214
|
+
begin
|
215
|
+
return Marshal.load(data)
|
216
|
+
rescue Exception => e
|
217
|
+
io = StringIO.new
|
218
|
+
io.write data
|
219
|
+
io.rewind
|
220
|
+
return io
|
221
|
+
end
|
222
|
+
end
|
223
223
|
end
|
224
|
-
end
|
225
224
|
end
|
226
225
|
|
227
226
|
# $Id: parser.rb 1781 2006-10-16 01:01:35Z luke $
|
@@ -16,7 +16,7 @@ class Facter::Util::Resolution
|
|
16
16
|
if Config::CONFIG['host_os'] =~ /mswin/
|
17
17
|
@have_which = false
|
18
18
|
else
|
19
|
-
%x{which which
|
19
|
+
%x{which which >/dev/null 2>&1}
|
20
20
|
@have_which = ($? == 0)
|
21
21
|
end
|
22
22
|
end
|
@@ -33,7 +33,7 @@ class Facter::Util::Resolution
|
|
33
33
|
if binary !~ /^\//
|
34
34
|
path = %x{which #{binary} 2>/dev/null}.chomp
|
35
35
|
# we don't have the binary necessary
|
36
|
-
return nil if path == ""
|
36
|
+
return nil if path == "" or path.match(/Command not found\./)
|
37
37
|
else
|
38
38
|
path = binary
|
39
39
|
end
|
data/lib/facter/util/uptime.rb
CHANGED
@@ -1,25 +1,25 @@
|
|
1
1
|
# A module to gather uptime facts
|
2
2
|
#
|
3
3
|
module Facter::Util::Uptime
|
4
|
-
|
5
4
|
def self.get_uptime_simple
|
6
5
|
time = Facter::Util::Resolution.exec('uptime')
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
if time =~ /up\s*(\d+\s\w+)/
|
7
|
+
$1
|
8
|
+
elsif time =~ /up\s*(\d+:\d+)/
|
9
|
+
$1 + " hours"
|
10
|
+
else
|
11
|
+
"unknown"
|
12
|
+
end
|
14
13
|
end
|
15
14
|
|
16
15
|
def self.get_uptime
|
17
|
-
|
16
|
+
r = IO.popen("/bin/cat /proc/uptime")
|
17
|
+
uptime, idletime = r.readline.split(" ")
|
18
|
+
r.close
|
18
19
|
uptime_seconds = uptime.to_i
|
19
20
|
end
|
20
21
|
|
21
22
|
def self.get_uptime_period(seconds, label)
|
22
|
-
|
23
23
|
case label
|
24
24
|
when 'days'
|
25
25
|
value = seconds / 86400
|
@@ -28,7 +28,5 @@ module Facter::Util::Uptime
|
|
28
28
|
when 'seconds'
|
29
29
|
seconds
|
30
30
|
end
|
31
|
-
|
32
31
|
end
|
33
|
-
|
34
32
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# A util module for facter containing helper methods
|
2
|
+
module Facter
|
3
|
+
module Util
|
4
|
+
module Values
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def convert(value)
|
8
|
+
value = value.to_s if value.is_a?(Symbol)
|
9
|
+
value = value.downcase if value.is_a?(String)
|
10
|
+
value
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/facter/virtual.rb
CHANGED
@@ -4,48 +4,67 @@ Facter.add("virtual") do
|
|
4
4
|
result = "physical"
|
5
5
|
|
6
6
|
setcode do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
require 'thread'
|
8
|
+
|
9
|
+
if FileTest.exists?("/sbin/zonename")
|
10
|
+
z = %x{"/sbin/zonename"}.chomp
|
11
|
+
if z != 'global'
|
12
|
+
result = zone
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
if FileTest.exists?("/proc/vz/veinfo")
|
17
|
+
if FileTest.exists?("/proc/vz/version")
|
13
18
|
result = "openvzhn"
|
14
19
|
else
|
15
20
|
result = "openvzve"
|
16
21
|
end
|
17
22
|
end
|
18
23
|
|
19
|
-
if FileTest.exists?("/proc/
|
24
|
+
if FileTest.exists?("/proc/self/status")
|
25
|
+
txt = File.read("/proc/self/status")
|
26
|
+
if txt =~ /^(s_context|VxID):[[:blank:]]*[1-9]/
|
27
|
+
result = "vserver"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
if FileTest.exists?("/proc/virtual")
|
32
|
+
result = "vserver_host"
|
33
|
+
end
|
34
|
+
|
35
|
+
# new Xen domains have this in dom0 not domu :(
|
36
|
+
if FileTest.exists?("/proc/sys/xen/independent_wallclock")
|
37
|
+
result = "xenu"
|
38
|
+
end
|
39
|
+
if FileTest.exists?("/sys/bus/xen")
|
40
|
+
result = "xenu"
|
41
|
+
end
|
42
|
+
|
43
|
+
if FileTest.exists?("/proc/xen/capabilities")
|
20
44
|
txt = File.read("/proc/xen/capabilities")
|
21
45
|
if txt =~ /control_d/i
|
22
|
-
result = "xen0"
|
23
|
-
else
|
24
|
-
result = "xenu"
|
46
|
+
result = "xen0"
|
25
47
|
end
|
26
48
|
end
|
27
|
-
|
49
|
+
|
28
50
|
if result == "physical"
|
29
|
-
|
30
|
-
if
|
31
|
-
output
|
32
|
-
output.each do |p|
|
51
|
+
output = Facter::Util::Resolution.exec('lspci')
|
52
|
+
if not output.nil?
|
53
|
+
output.each_line do |p|
|
33
54
|
# --- look for the vmware video card to determine if it is virtual => vmware.
|
34
55
|
# --- 00:0f.0 VGA compatible controller: VMware Inc [VMware SVGA II] PCI Display Adapter
|
35
56
|
result = "vmware" if p =~ /VM[wW]are/
|
36
57
|
end
|
37
58
|
else
|
38
|
-
|
39
|
-
if
|
40
|
-
output
|
41
|
-
output.each do |pd|
|
59
|
+
output = Facter::Util::Resolution.exec('dmidecode')
|
60
|
+
if not output.nil?
|
61
|
+
output.each_line do |pd|
|
42
62
|
result = "vmware" if pd =~ /VMware|Parallels/
|
43
63
|
end
|
44
64
|
else
|
45
|
-
|
46
|
-
if
|
47
|
-
output
|
48
|
-
output.each do |pd|
|
65
|
+
output = Facter::Util::Resolution.exec('prtdiag')
|
66
|
+
if not output.nil?
|
67
|
+
output.each_line do |pd|
|
49
68
|
result = "vmware" if pd =~ /VMware|Parallels/
|
50
69
|
end
|
51
70
|
end
|
@@ -58,18 +77,19 @@ Facter.add("virtual") do
|
|
58
77
|
result = "vmware_server"
|
59
78
|
end
|
60
79
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
80
|
+
result
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
Facter.add("is_virtual") do
|
85
|
+
confine :kernel => %w{Linux FreeBSD OpenBSD SunOS}
|
68
86
|
|
69
|
-
|
70
|
-
|
87
|
+
setcode do
|
88
|
+
case Facter.value(:virtual)
|
89
|
+
when "xenu", "openvzve", "vmware"
|
90
|
+
true
|
91
|
+
else
|
92
|
+
false
|
71
93
|
end
|
72
|
-
|
73
|
-
result
|
74
94
|
end
|
75
95
|
end
|