facter 1.5 → 1.5.2

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 (41) hide show
  1. data/CHANGELOG +51 -1
  2. data/Rakefile +10 -1
  3. data/conf/osx/PackageInfo.plist +36 -0
  4. data/conf/osx/createpackage.sh +167 -0
  5. data/conf/osx/preflight +11 -0
  6. data/conf/redhat/facter.spec +120 -0
  7. data/conf/solaris/pkginfo +7 -0
  8. data/documentation/custom.page +22 -0
  9. data/documentation/index.page +19 -0
  10. data/install.rb +227 -92
  11. data/lib/facter.rb +1 -1
  12. data/lib/facter/domain.rb +14 -0
  13. data/lib/facter/hardwaremodel.rb +8 -0
  14. data/lib/facter/ipaddress.rb +21 -2
  15. data/lib/facter/ipmess.rb +8 -37
  16. data/lib/facter/kernel.rb +7 -1
  17. data/lib/facter/kernelrelease.rb +16 -1
  18. data/lib/facter/kernelversion.rb +5 -0
  19. data/lib/facter/lsb.rb +1 -0
  20. data/lib/facter/macaddress.rb +15 -1
  21. data/lib/facter/operatingsystem.rb +6 -1
  22. data/lib/facter/operatingsystemrelease.rb +34 -7
  23. data/lib/facter/puppetversion.rb +1 -1
  24. data/lib/facter/util/ip.rb +37 -47
  25. data/lib/facter/util/manufacturer.rb +2 -2
  26. data/lib/facter/util/resolution.rb +13 -3
  27. data/lib/facter/virtual.rb +62 -0
  28. data/spec/Rakefile +18 -0
  29. data/spec/integration/facter.rb +27 -0
  30. data/spec/spec.opts +3 -0
  31. data/spec/spec_helper.rb +25 -0
  32. data/spec/unit/data/linux_ifconfig_all_with_single_interface +18 -0
  33. data/spec/unit/data/solaris_ifconfig_single_interface +3 -0
  34. data/spec/unit/facter.rb +134 -0
  35. data/spec/unit/util/collection.rb +255 -0
  36. data/spec/unit/util/confine.rb +75 -0
  37. data/spec/unit/util/fact.rb +129 -0
  38. data/spec/unit/util/ip.rb +40 -0
  39. data/spec/unit/util/loader.rb +219 -0
  40. data/spec/unit/util/resolution.rb +209 -0
  41. metadata +31 -2
@@ -0,0 +1,62 @@
1
+ Facter.add("virtual") do
2
+ confine :kernel => %w{Linux FreeBSD OpenBSD}
3
+
4
+ ENV["PATH"]="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/bin"
5
+
6
+ result = "physical"
7
+
8
+ setcode do
9
+
10
+ if FileTest.exists?("/proc/user_beancounters")
11
+ result = "openvz"
12
+ end
13
+
14
+ if FileTest.exists?("/proc/xen/capabilities") && FileTest.readable?("/proc/xen/capabilities")
15
+ txt = File.read("/proc/xen/capabilities")
16
+ if txt =~ /control_d/i
17
+ result = "xen0"
18
+ else
19
+ result = "xenu"
20
+ end
21
+ end
22
+
23
+ if result == "physical"
24
+ lspciexists = system "which lspci > /dev/null 2>&1"
25
+ if $?.exitstatus == 0
26
+ output = %x{lspci}
27
+ output.each {|p|
28
+ # --- look for the vmware video card to determine if it is virtual => vmware.
29
+ # --- 00:0f.0 VGA compatible controller: VMware Inc [VMware SVGA II] PCI Display Adapter
30
+ result = "vmware" if p =~ /VM[wW]are/
31
+ }
32
+ else
33
+ dmidecodeexists = system "which dmidecode > /dev/null 2>&1"
34
+ if $?.exitstatus == 0
35
+ outputd = %x{dmidecode}
36
+ outputd.each {|pd|
37
+ result = "vmware" if pd =~ /VMware|Parallels/
38
+ }
39
+ end
40
+ end
41
+ end
42
+
43
+ # VMware server 1.0.3 rpm places vmware-vmx in this place, other versions or platforms may not.
44
+ if FileTest.exists?("/usr/lib/vmware/bin/vmware-vmx")
45
+ result = "vmware_server"
46
+ end
47
+
48
+ mountexists = system "which mount > /dev/null 2>&1"
49
+ if $?.exitstatus == 0
50
+ output = %x{mount}
51
+ output.each {|p|
52
+ result = "vserver" if p =~ /\/dev\/hdv1/
53
+ }
54
+ end
55
+
56
+ if FileTest.directory?('/proc/virtual')
57
+ result = "vserver_host"
58
+ end
59
+
60
+ result
61
+ end
62
+ end
data/spec/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
+ require 'rake'
3
+ require 'spec/rake/spectask'
4
+
5
+ basedir = File.dirname(__FILE__)
6
+ puppetlibdir = File.join(basedir, "../lib")
7
+ puppettestlibdir = File.join(basedir, "../test/lib")
8
+ speclibdir = File.join(basedir, "lib")
9
+
10
+ libs = [puppetlibdir, puppettestlibdir, speclibdir]
11
+ desc "Run all specs"
12
+ Spec::Rake::SpecTask.new('all') do |t|
13
+ t.spec_files = FileList['integration/**/*.rb', 'unit/**/*.rb']
14
+ t.libs = libs
15
+ t.spec_opts = ['--options', 'spec.opts']
16
+ end
17
+
18
+ task :default => [:all]
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+
5
+ describe Facter do
6
+ before do
7
+ Facter.reset
8
+ end
9
+
10
+ after do
11
+ Facter.reset
12
+ end
13
+
14
+ it "should create a new collection if one does not exist" do
15
+ Facter.reset
16
+ coll = mock('coll')
17
+ Facter::Util::Collection.stubs(:new).returns coll
18
+ Facter.collection.should equal(coll)
19
+ Facter.reset
20
+ end
21
+
22
+ it "should remove the collection when reset" do
23
+ old = Facter.collection
24
+ Facter.reset
25
+ Facter.collection.should_not equal(old)
26
+ end
27
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --loadby
3
+ mtime
@@ -0,0 +1,25 @@
1
+ dir = File.expand_path(File.dirname(__FILE__))
2
+
3
+ $LOAD_PATH.unshift("#{dir}/")
4
+ $LOAD_PATH.unshift("#{dir}/../lib")
5
+
6
+ # include any gems in vendor/gems
7
+ Dir["#{dir}/../vendor/gems/**"].each do |path|
8
+ libpath = File.join(path, "lib")
9
+ if File.directory?(libpath)
10
+ $LOAD_PATH.unshift(libpath)
11
+ else
12
+ $LOAD_PATH.unshift(path)
13
+ end
14
+ end
15
+
16
+ require 'mocha'
17
+ require 'spec'
18
+ require 'facter'
19
+
20
+ # load any monkey-patches
21
+ Dir["#{dir}/monkey_patches/*.rb"].map { |file| require file }
22
+
23
+ Spec::Runner.configure do |config|
24
+ config.mock_with :mocha
25
+ end
@@ -0,0 +1,18 @@
1
+ eth0 Link encap:Ethernet HWaddr 00:0c:29:52:15:e9
2
+ inet addr:172.16.15.133 Bcast:172.16.15.255 Mask:255.255.255.0
3
+ inet6 addr: fe80::20c:29ff:fe52:15e9/64 Scope:Link
4
+ UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
5
+ RX packets:173 errors:173 dropped:0 overruns:0 frame:0
6
+ TX packets:208 errors:0 dropped:0 overruns:0 carrier:0
7
+ collisions:0 txqueuelen:1000
8
+ RX bytes:40970 (40.0 KB) TX bytes:24760 (24.1 KB)
9
+ Interrupt:16 Base address:0x2024
10
+
11
+ lo Link encap:Local Loopback
12
+ inet addr:127.0.0.1 Mask:255.0.0.0
13
+ inet6 addr: ::1/128 Scope:Host
14
+ UP LOOPBACK RUNNING MTU:16436 Metric:1
15
+ RX packets:1630 errors:0 dropped:0 overruns:0 frame:0
16
+ TX packets:1630 errors:0 dropped:0 overruns:0 carrier:0
17
+ collisions:0 txqueuelen:0
18
+ RX bytes:81500 (79.5 KB) TX bytes:81500 (79.5 KB)
@@ -0,0 +1,3 @@
1
+ e1000g0: flags=201004843<UP,BROADCAST,RUNNING,MULTICAST,DHCP,IPv4,CoS> mtu 1500 index 2
2
+ inet 172.16.15.138 netmask ffffff00 broadcast 172.16.15.255
3
+ ether 0:c:29:c1:70:2a
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+
5
+ describe Facter do
6
+
7
+ it "should have a version" do
8
+ Facter.version.should =~ /^[0-9]+(\.[0-9]+)*$/
9
+ end
10
+
11
+ it "should have a method for returning its collection" do
12
+ Facter.should respond_to(:collection)
13
+ end
14
+
15
+ it "should cache the collection" do
16
+ Facter.collection.should equal(Facter.collection)
17
+ end
18
+
19
+ it "should delegate the :flush method to the collection" do
20
+ Facter.collection.expects(:flush)
21
+ Facter.flush
22
+ end
23
+
24
+ it "should delegate the :fact method to the collection" do
25
+ Facter.collection.expects(:fact)
26
+ Facter.fact
27
+ end
28
+
29
+ it "should delegate the :list method to the collection" do
30
+ Facter.collection.expects(:list)
31
+ Facter.list
32
+ end
33
+
34
+ it "should load all facts when listing" do
35
+ Facter.collection.expects(:load_all)
36
+ Facter.collection.stubs(:list)
37
+ Facter.list
38
+ end
39
+
40
+ it "should delegate the :to_hash method to the collection" do
41
+ Facter.collection.expects(:to_hash)
42
+ Facter.to_hash
43
+ end
44
+
45
+ it "should load all facts when calling :to_hash" do
46
+ Facter.collection.expects(:load_all)
47
+ Facter.collection.stubs(:to_hash)
48
+ Facter.to_hash
49
+ end
50
+
51
+ it "should delegate the :value method to the collection" do
52
+ Facter.collection.expects(:value)
53
+ Facter.value
54
+ end
55
+
56
+ it "should delegate the :each method to the collection" do
57
+ Facter.collection.expects(:each)
58
+ Facter.each
59
+ end
60
+
61
+ it "should load all facts when calling :each" do
62
+ Facter.collection.expects(:load_all)
63
+ Facter.collection.stubs(:each)
64
+ Facter.each
65
+ end
66
+
67
+ it "should yield to the block when using :each" do
68
+ Facter.collection.stubs(:load_all)
69
+ Facter.collection.stubs(:each).yields "foo"
70
+ result = []
71
+ Facter.each { |f| result << f }
72
+ result.should == %w{foo}
73
+ end
74
+
75
+ describe "when provided code as a string" do
76
+ it "should execute the code in the shell" do
77
+ Facter.add("shell_testing") do
78
+ setcode "echo yup"
79
+ end
80
+
81
+ Facter["shell_testing"].value.should == "yup"
82
+ end
83
+ end
84
+
85
+ describe "when passed code as a block" do
86
+ it "should execute the provided block" do
87
+ Facter.add("block_testing") { setcode { "foo" } }
88
+
89
+ Facter["block_testing"].value.should == "foo"
90
+ end
91
+ end
92
+
93
+ describe Facter[:hostname] do
94
+ it "should have its ldapname set to 'cn'" do
95
+ Facter[:hostname].ldapname.should == "cn"
96
+ end
97
+ end
98
+
99
+ describe Facter[:ipaddress] do
100
+ it "should have its ldapname set to 'iphostnumber'" do
101
+ Facter[:ipaddress].ldapname.should == "iphostnumber"
102
+ end
103
+ end
104
+
105
+ # #33 Make sure we only get one mac address
106
+ it "should only return one mac address" do
107
+ Facter.value(:macaddress).should_not be_include(" ")
108
+ end
109
+
110
+ it "should have a method for registering directories to search" do
111
+ Facter.should respond_to(:search)
112
+ end
113
+
114
+ it "should have a method for returning the registered search directories" do
115
+ Facter.should respond_to(:search_path)
116
+ end
117
+
118
+ describe "when registering directories to search" do
119
+ after { Facter.instance_variable_set("@search_path", []) }
120
+
121
+ it "should allow registration of a directory" do
122
+ Facter.search "/my/dir"
123
+ end
124
+
125
+ it "should allow registration of multiple directories" do
126
+ Facter.search "/my/dir", "/other/dir"
127
+ end
128
+
129
+ it "should return all registered directories when asked" do
130
+ Facter.search "/my/dir", "/other/dir"
131
+ Facter.search_path.should == %w{/my/dir /other/dir}
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../../spec_helper'
4
+
5
+ require 'facter/util/collection'
6
+
7
+ describe Facter::Util::Collection do
8
+ it "should have a method for adding facts" do
9
+ Facter::Util::Collection.new.should respond_to(:add)
10
+ end
11
+
12
+ it "should have a method for returning a loader" do
13
+ Facter::Util::Collection.new.should respond_to(:loader)
14
+ end
15
+
16
+ it "should use an instance of the Loader class as its loader" do
17
+ Facter::Util::Collection.new.loader.should be_instance_of(Facter::Util::Loader)
18
+ end
19
+
20
+ it "should cache its loader" do
21
+ coll = Facter::Util::Collection.new
22
+ coll.loader.should equal(coll.loader)
23
+ end
24
+
25
+ it "should have a method for loading all facts" do
26
+ Facter::Util::Collection.new.should respond_to(:load_all)
27
+ end
28
+
29
+ it "should delegate its load_all method to its loader" do
30
+ coll = Facter::Util::Collection.new
31
+ coll.loader.expects(:load_all)
32
+ coll.load_all
33
+ end
34
+
35
+ describe "when adding facts" do
36
+ before do
37
+ @coll = Facter::Util::Collection.new
38
+ end
39
+
40
+ it "should create a new fact if no fact with the same name already exists" do
41
+ fact = mock 'fact'
42
+ Facter::Util::Fact.expects(:new).with { |name, *args| name == :myname }.returns fact
43
+
44
+ @coll.add(:myname)
45
+ end
46
+
47
+ it "should accept options" do
48
+ @coll.add(:myname, :ldapname => "whatever") { }
49
+ end
50
+
51
+ it "should set any appropriate options on the fact instances" do
52
+ # Use a real fact instance, because we're using respond_to?
53
+ fact = Facter::Util::Fact.new(:myname)
54
+ fact.expects(:ldapname=).with("testing")
55
+ Facter::Util::Fact.expects(:new).with(:myname).returns fact
56
+
57
+ @coll.add(:myname, :ldapname => "testing")
58
+ end
59
+
60
+ it "should set appropriate options on the resolution instance" do
61
+ fact = Facter::Util::Fact.new(:myname)
62
+ Facter::Util::Fact.expects(:new).with(:myname).returns fact
63
+
64
+ resolve = Facter::Util::Resolution.new(:myname) {}
65
+ fact.expects(:add).returns resolve
66
+
67
+ @coll.add(:myname, :timeout => "myval") {}
68
+ end
69
+
70
+ it "should not pass fact-specific options to resolutions" do
71
+ fact = Facter::Util::Fact.new(:myname)
72
+ Facter::Util::Fact.expects(:new).with(:myname).returns fact
73
+
74
+ resolve = Facter::Util::Resolution.new(:myname) {}
75
+ fact.expects(:add).returns resolve
76
+
77
+ fact.expects(:ldapname=).with("foo")
78
+ resolve.expects(:timeout=).with("myval")
79
+
80
+ @coll.add(:myname, :timeout => "myval", :ldapname => "foo") {}
81
+ end
82
+
83
+ it "should fail if invalid options are provided" do
84
+ lambda { @coll.add(:myname, :foo => :bar) }.should raise_error(ArgumentError)
85
+ end
86
+
87
+ describe "and a block is provided" do
88
+ it "should use the block to add a resolution to the fact" do
89
+ fact = mock 'fact'
90
+ Facter::Util::Fact.expects(:new).returns fact
91
+
92
+ fact.expects(:add)
93
+
94
+ @coll.add(:myname) {}
95
+ end
96
+ end
97
+ end
98
+
99
+ it "should have a method for retrieving facts by name" do
100
+ Facter::Util::Collection.new.should respond_to(:fact)
101
+ end
102
+
103
+ describe "when retrieving facts" do
104
+ before do
105
+ @coll = Facter::Util::Collection.new
106
+
107
+ @fact = @coll.add("YayNess")
108
+ end
109
+
110
+ it "should return the fact instance specified by the name" do
111
+ @coll.fact("YayNess").should equal(@fact)
112
+ end
113
+
114
+ it "should be case-insensitive" do
115
+ @coll.fact("yayness").should equal(@fact)
116
+ end
117
+
118
+ it "should treat strings and symbols equivalently" do
119
+ @coll.fact(:yayness).should equal(@fact)
120
+ end
121
+
122
+ it "should use its loader to try to load the fact if no fact can be found" do
123
+ @coll.loader.expects(:load).with(:testing)
124
+ @coll.fact("testing")
125
+ end
126
+
127
+ it "should return nil if it cannot find or load the fact" do
128
+ @coll.loader.expects(:load).with(:testing)
129
+ @coll.fact("testing").should be_nil
130
+ end
131
+ end
132
+
133
+ it "should have a method for returning a fact's value" do
134
+ Facter::Util::Collection.new.should respond_to(:value)
135
+ end
136
+
137
+ describe "when returning a fact's value" do
138
+ before do
139
+ @coll = Facter::Util::Collection.new
140
+ @fact = @coll.add("YayNess")
141
+
142
+ @fact.stubs(:value).returns "result"
143
+ end
144
+
145
+ it "should use the 'fact' method to retrieve the fact" do
146
+ @coll.expects(:fact).with(:yayness).returns @fact
147
+ @coll.value(:yayness)
148
+ end
149
+
150
+ it "should return the result of calling :value on the fact" do
151
+ @fact.expects(:value).returns "result"
152
+
153
+ @coll.value("YayNess").should == "result"
154
+ end
155
+
156
+ it "should be case-insensitive" do
157
+ @coll.value("yayness").should_not be_nil
158
+ end
159
+
160
+ it "should treat strings and symbols equivalently" do
161
+ @coll.value(:yayness).should_not be_nil
162
+ end
163
+ end
164
+
165
+ it "should return the fact's value when the array index method is used" do
166
+ @coll = Facter::Util::Collection.new
167
+ @coll.expects(:value).with("myfact").returns "foo"
168
+ @coll["myfact"].should == "foo"
169
+ end
170
+
171
+ it "should have a method for flushing all facts" do
172
+ @coll = Facter::Util::Collection.new
173
+ @fact = @coll.add("YayNess")
174
+
175
+ @fact.expects(:flush)
176
+
177
+ @coll.flush
178
+ end
179
+
180
+ it "should have a method that returns all fact names" do
181
+ @coll = Facter::Util::Collection.new
182
+ @coll.add(:one)
183
+ @coll.add(:two)
184
+
185
+ @coll.list.sort { |a,b| a.to_s <=> b.to_s }.should == [:one, :two]
186
+ end
187
+
188
+ it "should have a method for returning a hash of fact values" do
189
+ Facter::Util::Collection.new.should respond_to(:to_hash)
190
+ end
191
+
192
+ describe "when returning a hash of values" do
193
+ before do
194
+ @coll = Facter::Util::Collection.new
195
+ @fact = @coll.add(:one)
196
+ @fact.stubs(:value).returns "me"
197
+ end
198
+
199
+ it "should return a hash of fact names and values with the fact names as strings" do
200
+ @coll.to_hash.should == {"one" => "me"}
201
+ end
202
+
203
+ it "should not include facts that did not return a value" do
204
+ f = @coll.add(:two)
205
+ f.stubs(:value).returns nil
206
+ @coll.to_hash.should_not be_include(:two)
207
+ end
208
+ end
209
+
210
+ it "should have a method for iterating over all facts" do
211
+ Facter::Util::Collection.new.should respond_to(:each)
212
+ end
213
+
214
+ it "should include Enumerable" do
215
+ Facter::Util::Collection.ancestors.should be_include(Enumerable)
216
+ end
217
+
218
+ describe "when iterating over facts" do
219
+ before do
220
+ @coll = Facter::Util::Collection.new
221
+ @one = @coll.add(:one)
222
+ @two = @coll.add(:two)
223
+ end
224
+
225
+ it "should yield each fact name and the fact value" do
226
+ @one.stubs(:value).returns "ONE"
227
+ @two.stubs(:value).returns "TWO"
228
+ facts = {}
229
+ @coll.each do |fact, value|
230
+ facts[fact] = value
231
+ end
232
+ facts.should == {"one" => "ONE", "two" => "TWO"}
233
+ end
234
+
235
+ it "should convert the fact name to a string" do
236
+ @one.stubs(:value).returns "ONE"
237
+ @two.stubs(:value).returns "TWO"
238
+ facts = {}
239
+ @coll.each do |fact, value|
240
+ fact.should be_instance_of(String)
241
+ end
242
+ end
243
+
244
+ it "should only yield facts that have values" do
245
+ @one.stubs(:value).returns "ONE"
246
+ @two.stubs(:value).returns nil
247
+ facts = {}
248
+ @coll.each do |fact, value|
249
+ facts[fact] = value
250
+ end
251
+
252
+ facts.should_not be_include("two")
253
+ end
254
+ end
255
+ end