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.

Files changed (47) hide show
  1. data/CHANGELOG +75 -22
  2. data/COPYING +289 -623
  3. data/Rakefile +60 -55
  4. data/bin/facter +39 -26
  5. data/conf/osx/PackageInfo.plist +30 -30
  6. data/conf/osx/createpackage.sh +17 -17
  7. data/conf/osx/preflight +1 -1
  8. data/install.rb +226 -226
  9. data/lib/facter.rb +12 -12
  10. data/lib/facter/architecture.rb +14 -3
  11. data/lib/facter/ec2.rb +35 -0
  12. data/lib/facter/hardwareisa.rb +1 -1
  13. data/lib/facter/id.rb +1 -1
  14. data/lib/facter/ipaddress.rb +41 -41
  15. data/lib/facter/kernel.rb +2 -2
  16. data/lib/facter/kernelmajversion.rb +5 -0
  17. data/lib/facter/lsb.rb +5 -5
  18. data/lib/facter/lsbmajdistrelease.rb +1 -1
  19. data/lib/facter/macaddress.rb +6 -6
  20. data/lib/facter/manufacturer.rb +8 -8
  21. data/lib/facter/memory.rb +5 -4
  22. data/lib/facter/netmask.rb +4 -4
  23. data/lib/facter/network.rb +4 -5
  24. data/lib/facter/operatingsystem.rb +13 -7
  25. data/lib/facter/operatingsystemrelease.rb +5 -5
  26. data/lib/facter/selinux.rb +45 -0
  27. data/lib/facter/timezone.rb +1 -1
  28. data/lib/facter/uniqueid.rb +2 -2
  29. data/lib/facter/uptime.rb +3 -3
  30. data/lib/facter/util/confine.rb +12 -12
  31. data/lib/facter/util/ip.rb +18 -22
  32. data/lib/facter/util/macosx.rb +5 -0
  33. data/lib/facter/util/manufacturer.rb +37 -37
  34. data/lib/facter/util/plist/generator.rb +181 -179
  35. data/lib/facter/util/plist/parser.rb +162 -163
  36. data/lib/facter/util/resolution.rb +2 -2
  37. data/lib/facter/util/uptime.rb +10 -12
  38. data/lib/facter/util/values.rb +14 -0
  39. data/lib/facter/virtual.rb +54 -34
  40. data/spec/unit/data/darwin_ifconfig_all_with_multiple_interfaces +10 -0
  41. data/spec/unit/operatingsystem.rb +36 -0
  42. data/spec/unit/selinux.rb +48 -0
  43. data/spec/unit/util/confine.rb +70 -5
  44. data/spec/unit/util/ip.rb +29 -3
  45. metadata +89 -77
  46. data/documentation/custom.page +0 -22
  47. 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
- 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
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
- def tag_start(name, attributes)
44
- @open.push PTag::mappings[name].new
45
- end
35
+ attr_accessor :result, :open
46
36
 
47
- def text( contents )
48
- @open.last.text = contents if @open.last
49
- end
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
- class StreamParser
62
- def initialize( filename_or_xml, listener )
63
- @filename_or_xml = filename_or_xml
64
- @listener = listener
65
- end
43
+ def tag_start(name, attributes)
44
+ @open.push PTag::mappings[name].new
45
+ end
66
46
 
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
-
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
- class PTag
112
- @@mappings = { }
113
- def PTag::mappings
114
- @@mappings
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
- def PTag::inherited( sub_class )
118
- key = sub_class.to_s.downcase
119
- key.gsub!(/^plist::/, '' )
120
- key.gsub!(/^p/, '') unless key == "plist"
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
- @@mappings[key] = sub_class
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
- attr_accessor :text, :children
126
- def initialize
127
- @children = Array.new
128
- end
110
+ class PTag
111
+ @@mappings = { }
112
+ def PTag::mappings
113
+ @@mappings
114
+ end
129
115
 
130
- def to_ruby
131
- raise "Unimplemented: " + self.class.to_s + "#to_ruby on #{self.inspect}"
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
- class PList < PTag
136
- def to_ruby
137
- children.first.to_ruby if children.first
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
- class PDict < PTag
142
- def to_ruby
143
- dict = Hash.new
144
- key = nil
140
+ class PDict < PTag
141
+ def to_ruby
142
+ dict = Hash.new
143
+ key = nil
145
144
 
146
- children.each do |c|
147
- if key.nil?
148
- key = c.to_ruby
149
- else
150
- dict[key] = c.to_ruby
151
- key = nil
152
- end
153
- end
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
- dict
154
+ dict
155
+ end
156
156
  end
157
- end
158
157
 
159
- class PKey < PTag
160
- def to_ruby
161
- CGI::unescapeHTML(text || '')
158
+ class PKey < PTag
159
+ def to_ruby
160
+ CGI::unescapeHTML(text || '')
161
+ end
162
162
  end
163
- end
164
163
 
165
- class PString < PTag
166
- def to_ruby
167
- CGI::unescapeHTML(text || '')
164
+ class PString < PTag
165
+ def to_ruby
166
+ CGI::unescapeHTML(text || '')
167
+ end
168
168
  end
169
- end
170
169
 
171
- class PArray < PTag
172
- def to_ruby
173
- children.collect do |c|
174
- c.to_ruby
175
- end
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
- class PInteger < PTag
180
- def to_ruby
181
- text.to_i
178
+ class PInteger < PTag
179
+ def to_ruby
180
+ text.to_i
181
+ end
182
182
  end
183
- end
184
183
 
185
- class PTrue < PTag
186
- def to_ruby
187
- true
184
+ class PTrue < PTag
185
+ def to_ruby
186
+ true
187
+ end
188
188
  end
189
- end
190
189
 
191
- class PFalse < PTag
192
- def to_ruby
193
- false
190
+ class PFalse < PTag
191
+ def to_ruby
192
+ false
193
+ end
194
194
  end
195
- end
196
195
 
197
- class PReal < PTag
198
- def to_ruby
199
- text.to_f
196
+ class PReal < PTag
197
+ def to_ruby
198
+ text.to_f
199
+ end
200
200
  end
201
- end
202
201
 
203
- require 'date'
204
- class PDate < PTag
205
- def to_ruby
206
- DateTime.parse(text)
202
+ require 'date'
203
+ class PDate < PTag
204
+ def to_ruby
205
+ DateTime.parse(text)
206
+ end
207
207
  end
208
- end
209
-
210
- require 'base64'
211
- class PData < PTag
212
- def to_ruby
213
- data = Base64.decode64(text.gsub(/\s+/, ''))
214
-
215
- begin
216
- return Marshal.load(data)
217
- rescue Exception => e
218
- io = StringIO.new
219
- io.write data
220
- io.rewind
221
- return io
222
- end
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 2>/dev/null}
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
@@ -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
- if time =~ /up\s*(\d+\s\w+)/
8
- $1
9
- elsif time =~ /up\s*(\d+:\d+)/
10
- $1 + " hours"
11
- else
12
- "unknown"
13
- end
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
- uptime, idletime = File.open("/proc/uptime").gets.split(" ")
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
@@ -4,48 +4,67 @@ Facter.add("virtual") do
4
4
  result = "physical"
5
5
 
6
6
  setcode do
7
- if FileTest.exists?("/proc/user_beancounters")
8
- # openvz. can be hardware node or virtual environment
9
- # read the init process' status file, it has laxer permissions
10
- # than /proc/user_beancounters (so this won't fail as non-root)
11
- txt = File.read("/proc/1/status")
12
- if txt =~ /^envID:[[:blank:]]+0$/mi
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/xen/capabilities") && FileTest.readable?("/proc/xen/capabilities")
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
- path = %x{which lspci 2> /dev/null}.chomp
30
- if path !~ /no lspci/
31
- output = %x{#{path}}
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
- path = %x{which dmidecode 2> /dev/null}.chomp
39
- if path !~ /no dmidecode/
40
- output = %x{#{path}}
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
- path = %x{which prtdiag 2> /dev/null}.chomp
46
- if path !~ /no prtdiag/
47
- output = %x{#{path}}
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
- mountexists = system "which mount > /dev/null 2>&1"
62
- if $?.exitstatus == 0
63
- output = %x{mount}
64
- output.each do |p|
65
- result = "vserver" if p =~ /\/dev\/hdv1/
66
- end
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
- if FileTest.directory?('/proc/virtual')
70
- result = "vserver_host"
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