facter 1.7.6 → 2.0.1.rc1
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.
- checksums.yaml +7 -0
- data/COMMITTERS.md +194 -0
- data/CONTRIBUTING.md +63 -235
- data/Gemfile +12 -8
- data/README.md +1 -2
- data/Rakefile +1 -1
- data/bin/facter +0 -4
- data/ext/build_defaults.yaml +2 -2
- data/ext/project_data.yaml +18 -0
- data/install.rb +1 -16
- data/lib/facter.rb +171 -171
- data/lib/facter/application.rb +65 -54
- data/lib/facter/core/aggregate.rb +220 -0
- data/lib/facter/core/directed_graph.rb +46 -0
- data/lib/facter/core/execution.rb +100 -0
- data/lib/facter/core/execution/base.rb +73 -0
- data/lib/facter/core/execution/posix.rb +50 -0
- data/lib/facter/core/execution/windows.rb +57 -0
- data/lib/facter/core/logging.rb +169 -0
- data/lib/facter/core/resolvable.rb +94 -0
- data/lib/facter/core/suitable.rb +117 -0
- data/lib/facter/domain.rb +15 -9
- data/lib/facter/filesystems.rb +1 -1
- data/lib/facter/hardwaremodel.rb +1 -1
- data/lib/facter/hostname.rb +3 -3
- data/lib/facter/interfaces.rb +6 -1
- data/lib/facter/ipaddress.rb +2 -2
- data/lib/facter/kernel.rb +1 -1
- data/lib/facter/kernelrelease.rb +1 -1
- data/lib/facter/ldom.rb +1 -1
- data/lib/facter/lsbdistcodename.rb +1 -1
- data/lib/facter/lsbdistdescription.rb +1 -1
- data/lib/facter/lsbdistid.rb +1 -1
- data/lib/facter/lsbdistrelease.rb +1 -1
- data/lib/facter/lsbrelease.rb +1 -1
- data/lib/facter/macaddress.rb +1 -14
- data/lib/facter/macosx.rb +2 -2
- data/lib/facter/memory.rb +8 -19
- data/lib/facter/operatingsystem.rb +1 -1
- data/lib/facter/operatingsystemrelease.rb +34 -1
- data/lib/facter/physicalprocessorcount.rb +6 -6
- data/lib/facter/processor.rb +11 -10
- data/lib/facter/selinux.rb +4 -15
- data/lib/facter/ssh.rb +5 -2
- data/lib/facter/util/architecture.rb +2 -2
- data/lib/facter/util/collection.rb +42 -38
- data/lib/facter/util/config.rb +19 -9
- data/lib/facter/util/confine.rb +34 -4
- data/lib/facter/util/ec2.rb +1 -1
- data/lib/facter/util/fact.rb +108 -36
- data/lib/facter/util/file_read.rb +7 -6
- data/lib/facter/util/formatter.rb +38 -0
- data/lib/facter/util/ip.rb +3 -3
- data/lib/facter/util/loader.rb +62 -42
- data/lib/facter/util/macosx.rb +7 -8
- data/lib/facter/util/manufacturer.rb +3 -3
- data/lib/facter/util/memory.rb +13 -13
- data/lib/facter/util/monkey_patches.rb +0 -31
- data/lib/facter/util/netmask.rb +3 -3
- data/lib/facter/util/normalization.rb +94 -0
- data/lib/facter/util/nothing_loader.rb +3 -6
- data/lib/facter/util/parser.rb +3 -5
- data/lib/facter/util/plist/generator.rb +1 -1
- data/lib/facter/util/processor.rb +15 -15
- data/lib/facter/util/resolution.rb +112 -289
- data/lib/facter/util/solaris_zones.rb +4 -4
- data/lib/facter/util/uptime.rb +8 -3
- data/lib/facter/util/values.rb +67 -1
- data/lib/facter/util/virtual.rb +10 -10
- data/lib/facter/util/xendomains.rb +1 -1
- data/lib/facter/version.rb +42 -39
- data/lib/facter/virtual.rb +6 -7
- data/lib/facter/zfs_version.rb +3 -3
- data/lib/facter/zpool_version.rb +3 -3
- data/spec/fixtures/unit/netmask/darwin_10_8_5.txt +30 -0
- data/spec/unit/application_spec.rb +46 -1
- data/spec/unit/core/aggregate_spec.rb +125 -0
- data/spec/unit/core/directed_graph_spec.rb +79 -0
- data/spec/unit/core/execution/base_spec.rb +119 -0
- data/spec/unit/core/execution/posix_spec.rb +86 -0
- data/spec/unit/core/execution/windows_spec.rb +106 -0
- data/spec/unit/core/execution_spec.rb +37 -0
- data/spec/unit/core/logging_spec.rb +104 -0
- data/spec/unit/core/resolvable_spec.rb +81 -0
- data/spec/unit/core/suitable_spec.rb +96 -0
- data/spec/unit/domain_spec.rb +5 -5
- data/spec/unit/facter_spec.rb +61 -222
- data/spec/unit/filesystems_spec.rb +2 -2
- data/spec/unit/hardwareisa_spec.rb +5 -5
- data/spec/unit/hardwaremodel_spec.rb +1 -1
- data/spec/unit/hostname_spec.rb +4 -4
- data/spec/unit/id_spec.rb +3 -3
- data/spec/unit/interfaces_spec.rb +10 -0
- data/spec/unit/ipaddress6_spec.rb +4 -4
- data/spec/unit/ipaddress_spec.rb +1 -1
- data/spec/unit/kernel_spec.rb +2 -2
- data/spec/unit/kernelmajversion_spec.rb +1 -1
- data/spec/unit/kernelrelease_spec.rb +4 -4
- data/spec/unit/kernelversion_spec.rb +2 -2
- data/spec/unit/ldom_spec.rb +2 -2
- data/spec/unit/lsbdistcodename_spec.rb +2 -2
- data/spec/unit/lsbdistdescription_spec.rb +2 -2
- data/spec/unit/lsbdistid_spec.rb +2 -2
- data/spec/unit/lsbdistrelease_spec.rb +2 -2
- data/spec/unit/lsbrelease_spec.rb +2 -2
- data/spec/unit/manufacturer_spec.rb +1 -1
- data/spec/unit/memory_spec.rb +24 -31
- data/spec/unit/netmask_spec.rb +9 -0
- data/spec/unit/operatingsystem_spec.rb +1 -1
- data/spec/unit/operatingsystemrelease_spec.rb +62 -4
- data/spec/unit/physicalprocessorcount_spec.rb +10 -10
- data/spec/unit/processor_spec.rb +11 -11
- data/spec/unit/selinux_spec.rb +2 -8
- data/spec/unit/ssh_spec.rb +3 -2
- data/spec/unit/uniqueid_spec.rb +3 -3
- data/spec/unit/util/collection_spec.rb +37 -35
- data/spec/unit/util/config_spec.rb +20 -0
- data/spec/unit/util/confine_spec.rb +21 -0
- data/spec/unit/util/directory_loader_spec.rb +1 -0
- data/spec/unit/util/ec2_spec.rb +6 -6
- data/spec/unit/util/fact_spec.rb +92 -90
- data/spec/unit/util/ip_spec.rb +2 -2
- data/spec/unit/util/loader_spec.rb +127 -186
- data/spec/unit/util/macaddress_spec.rb +2 -2
- data/spec/unit/util/macosx_spec.rb +8 -8
- data/spec/unit/util/manufacturer_spec.rb +3 -3
- data/spec/unit/util/normalization_spec.rb +113 -0
- data/spec/unit/util/parser_spec.rb +25 -3
- data/spec/unit/util/processor_spec.rb +2 -2
- data/spec/unit/util/resolution_spec.rb +60 -631
- data/spec/unit/util/solaris_zones_spec.rb +5 -5
- data/spec/unit/util/uptime_spec.rb +1 -1
- data/spec/unit/util/values_spec.rb +131 -0
- data/spec/unit/util/virtual_spec.rb +16 -16
- data/spec/unit/util/xendomains_spec.rb +2 -2
- data/spec/unit/virtual_spec.rb +39 -39
- data/spec/unit/zfs_version_spec.rb +11 -11
- data/spec/unit/zonename_spec.rb +2 -2
- data/spec/unit/zones_spec.rb +1 -1
- data/spec/unit/zpool_version_spec.rb +11 -11
- metadata +466 -447
- data/lib/facter/util/cfpropertylist.rb +0 -6
- data/lib/facter/util/cfpropertylist/LICENSE +0 -19
- data/lib/facter/util/cfpropertylist/README +0 -44
- data/lib/facter/util/cfpropertylist/Rakefile +0 -44
- data/lib/facter/util/cfpropertylist/THANKS +0 -7
- data/lib/facter/util/cfpropertylist/lib/cfpropertylist.rb +0 -6
- data/lib/facter/util/cfpropertylist/lib/rbBinaryCFPropertyList.rb +0 -562
- data/lib/facter/util/cfpropertylist/lib/rbCFPlistError.rb +0 -26
- data/lib/facter/util/cfpropertylist/lib/rbCFPropertyList.rb +0 -407
- data/lib/facter/util/cfpropertylist/lib/rbCFTypes.rb +0 -244
- data/lib/facter/util/cfpropertylist/lib/rbLibXMLParser.rb +0 -135
- data/lib/facter/util/cfpropertylist/lib/rbNokogiriParser.rb +0 -140
- data/lib/facter/util/cfpropertylist/lib/rbREXMLParser.rb +0 -136
- data/spec/unit/util/monkey_patches_spec.rb +0 -42
data/lib/facter/util/confine.rb
CHANGED
@@ -10,19 +10,40 @@ class Facter::Util::Confine
|
|
10
10
|
|
11
11
|
# Add the restriction. Requires the fact name, an operator, and the value
|
12
12
|
# we're comparing to.
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
#
|
14
|
+
# @param fact [Symbol] Name of the fact
|
15
|
+
# @param values [Array] One or more values to match against.
|
16
|
+
# They can be any type that provides a === method.
|
17
|
+
# @param block [Proc] Alternatively a block can be supplied as a check. The fact
|
18
|
+
# value will be passed as the argument to the block. If the block returns
|
19
|
+
# true then the fact will be enabled, otherwise it will be disabled.
|
20
|
+
def initialize(fact = nil, *values, &block)
|
21
|
+
raise ArgumentError, "The fact name must be provided" unless fact or block_given?
|
22
|
+
if values.empty? and not block_given?
|
23
|
+
raise ArgumentError, "One or more values or a block must be provided"
|
24
|
+
end
|
16
25
|
@fact = fact
|
17
26
|
@values = values
|
27
|
+
@block = block
|
18
28
|
end
|
19
29
|
|
20
30
|
def to_s
|
31
|
+
return @block.to_s if @block
|
21
32
|
return "'%s' '%s'" % [@fact, @values.join(",")]
|
22
33
|
end
|
23
34
|
|
24
35
|
# Evaluate the fact, returning true or false.
|
36
|
+
# if we have a block paramter then we only evaluate that instead
|
25
37
|
def true?
|
38
|
+
if @block and not @fact then
|
39
|
+
begin
|
40
|
+
return !! @block.call
|
41
|
+
rescue StandardError => error
|
42
|
+
Facter.debug "Confine raised #{error.class} #{error}"
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
26
47
|
unless fact = Facter[@fact]
|
27
48
|
Facter.debug "No fact for %s" % @fact
|
28
49
|
return false
|
@@ -31,6 +52,15 @@ class Facter::Util::Confine
|
|
31
52
|
|
32
53
|
return false if value.nil?
|
33
54
|
|
34
|
-
|
55
|
+
if @block then
|
56
|
+
begin
|
57
|
+
return !! @block.call(value)
|
58
|
+
rescue StandardError => error
|
59
|
+
Facter.debug "Confine raised #{error.class} #{error}"
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
return @values.any? do |v| convert(v) === value end
|
35
65
|
end
|
36
66
|
end
|
data/lib/facter/util/ec2.rb
CHANGED
data/lib/facter/util/fact.rb
CHANGED
@@ -1,24 +1,33 @@
|
|
1
1
|
require 'facter'
|
2
2
|
require 'facter/util/resolution'
|
3
|
-
|
3
|
+
require 'facter/core/aggregate'
|
4
|
+
|
5
|
+
# This class represents a fact. Each fact has a name and multiple
|
6
|
+
# {Facter::Util::Resolution resolutions}.
|
7
|
+
#
|
8
|
+
# Create facts using {Facter.add}
|
9
|
+
#
|
10
|
+
# @api public
|
4
11
|
class Facter::Util::Fact
|
5
|
-
|
6
|
-
|
7
|
-
attr_accessor :name
|
8
|
-
|
9
|
-
#
|
12
|
+
# The name of the fact
|
13
|
+
# @return [String]
|
14
|
+
attr_accessor :name
|
15
|
+
|
16
|
+
# @return [String]
|
17
|
+
# @deprecated
|
18
|
+
attr_accessor :ldapname
|
19
|
+
|
20
|
+
# Creates a new fact, with no resolution mechanisms. See {Facter.add}
|
21
|
+
# for the public API for creating facts.
|
22
|
+
# @param name [String] the fact name
|
23
|
+
# @param options [Hash] optional parameters
|
24
|
+
# @option options [String] :ldapname set the ldapname property on the fact
|
25
|
+
#
|
26
|
+
# @api private
|
10
27
|
def initialize(name, options = {})
|
11
28
|
@name = name.to_s.downcase.intern
|
12
29
|
|
13
|
-
|
14
|
-
# worst we'll have one. If we add more, this should be made more efficient.
|
15
|
-
options.each do |name, value|
|
16
|
-
case name
|
17
|
-
when :ldapname; self.ldapname = value
|
18
|
-
else
|
19
|
-
raise ArgumentError, "Invalid fact option '%s'" % name
|
20
|
-
end
|
21
|
-
end
|
30
|
+
extract_ldapname_option!(options)
|
22
31
|
|
23
32
|
@ldapname ||= @name.to_s
|
24
33
|
|
@@ -28,33 +37,68 @@ class Facter::Util::Fact
|
|
28
37
|
@value = nil
|
29
38
|
end
|
30
39
|
|
31
|
-
#
|
32
|
-
# be evaluated in the context of the new
|
33
|
-
|
34
|
-
|
35
|
-
|
40
|
+
# Adds a new {Facter::Util::Resolution resolution}. This requires a
|
41
|
+
# block, which will then be evaluated in the context of the new
|
42
|
+
# resolution.
|
43
|
+
#
|
44
|
+
# @param options [Hash] A hash of options to set on the resolution
|
45
|
+
#
|
46
|
+
# @return [Facter::Util::Resolution]
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
def add(options = {}, &block)
|
50
|
+
define_resolution(nil, options, &block)
|
51
|
+
end
|
36
52
|
|
37
|
-
|
38
|
-
|
53
|
+
# Define a new named resolution or return an existing resolution with
|
54
|
+
# the given name.
|
55
|
+
#
|
56
|
+
# @param resolution_name [String] The name of the resolve to define or look up
|
57
|
+
# @param options [Hash] A hash of options to set on the resolution
|
58
|
+
# @return [Facter::Util::Resolution]
|
59
|
+
#
|
60
|
+
# @api public
|
61
|
+
def define_resolution(resolution_name, options = {}, &block)
|
39
62
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
63
|
+
resolution_type = options.delete(:type) || :simple
|
64
|
+
|
65
|
+
resolve = create_or_return_resolution(resolution_name, resolution_type)
|
66
|
+
|
67
|
+
resolve.set_options(options) unless options.empty?
|
68
|
+
resolve.evaluate(&block) if block
|
69
|
+
|
70
|
+
resolve
|
71
|
+
rescue => e
|
72
|
+
Facter.log_exception(e, "Unable to add resolve #{resolution_name.inspect} for fact #{@name}: #{e.message}")
|
45
73
|
end
|
46
74
|
|
47
|
-
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
75
|
+
# Retrieve an existing resolution by name
|
76
|
+
#
|
77
|
+
# @param name [String]
|
78
|
+
#
|
79
|
+
# @return [Facter::Util::Resolution, nil] The resolution if exists, nil if
|
80
|
+
# it doesn't exist or name is nil
|
81
|
+
def resolution(name)
|
82
|
+
return nil if name.nil?
|
83
|
+
|
84
|
+
@resolves.find { |resolve| resolve.name == name }
|
85
|
+
end
|
86
|
+
|
87
|
+
# Flushes any cached values.
|
88
|
+
#
|
89
|
+
# @return [void]
|
90
|
+
#
|
91
|
+
# @api private
|
51
92
|
def flush
|
52
93
|
@resolves.each { |r| r.flush }
|
53
94
|
@value = nil
|
54
95
|
end
|
55
96
|
|
56
|
-
#
|
57
|
-
# and
|
97
|
+
# Returns the value for this fact. This searches all resolutions by
|
98
|
+
# suitability and weight (see {Facter::Util::Resolution}). If no
|
99
|
+
# suitable resolution is found, it returns nil.
|
100
|
+
#
|
101
|
+
# @api public
|
58
102
|
def value
|
59
103
|
return @value if @value
|
60
104
|
|
@@ -75,6 +119,14 @@ class Facter::Util::Fact
|
|
75
119
|
end
|
76
120
|
end
|
77
121
|
|
122
|
+
# @api private
|
123
|
+
# @deprecated
|
124
|
+
def extract_ldapname_option!(options)
|
125
|
+
if options[:ldapname]
|
126
|
+
Facter.warnonce("ldapname is deprecated and will be removed in a future version")
|
127
|
+
self.ldapname = options.delete(:ldapname)
|
128
|
+
end
|
129
|
+
end
|
78
130
|
|
79
131
|
private
|
80
132
|
|
@@ -106,7 +158,7 @@ class Facter::Util::Fact
|
|
106
158
|
|
107
159
|
def find_first_real_value(resolutions)
|
108
160
|
resolutions.each do |resolve|
|
109
|
-
value =
|
161
|
+
value = resolve.value
|
110
162
|
if not value.nil?
|
111
163
|
return value
|
112
164
|
end
|
@@ -126,7 +178,27 @@ class Facter::Util::Fact
|
|
126
178
|
end
|
127
179
|
end
|
128
180
|
|
129
|
-
def
|
130
|
-
|
181
|
+
def create_or_return_resolution(resolution_name, resolution_type)
|
182
|
+
resolve = self.resolution(resolution_name)
|
183
|
+
|
184
|
+
if resolve
|
185
|
+
if resolution_type != resolve.resolution_type
|
186
|
+
raise ArgumentError, "Cannot return resolution #{resolution_name} with type" +
|
187
|
+
" #{resolution_type}; already defined as #{resolve.resolution_type}"
|
188
|
+
end
|
189
|
+
else
|
190
|
+
case resolution_type
|
191
|
+
when :simple
|
192
|
+
resolve = Facter::Util::Resolution.new(resolution_name, self)
|
193
|
+
when :aggregate
|
194
|
+
resolve = Facter::Core::Aggregate.new(resolution_name, self)
|
195
|
+
else
|
196
|
+
raise ArgumentError, "Expected resolution type to be one of (:simple, :aggregate) but was #{resolution_type}"
|
197
|
+
end
|
198
|
+
|
199
|
+
@resolves << resolve
|
200
|
+
end
|
201
|
+
|
202
|
+
resolve
|
131
203
|
end
|
132
204
|
end
|
@@ -1,26 +1,27 @@
|
|
1
1
|
module Facter
|
2
2
|
module Util
|
3
|
-
|
3
|
+
|
4
4
|
# {Facter::Util::FileRead} is a utility module intended to provide easily
|
5
5
|
# mockable methods that delegate to simple file read methods. The intent is to
|
6
6
|
# avoid the need to execute the `cat` system command or `File.read` directly in
|
7
7
|
# Ruby, as mocking these behaviors can have wide-ranging effects.
|
8
8
|
#
|
9
9
|
# All Facter facts are encouraged to use this method instead of File.read or
|
10
|
-
# Facter::
|
10
|
+
# Facter::Core::Execution.exec('cat ...')
|
11
11
|
#
|
12
12
|
# @api public
|
13
13
|
module FileRead
|
14
|
-
##
|
15
14
|
# read returns the raw content of a file as a string. If the file does not
|
16
15
|
# exist, or the process does not have permission to read the file then nil is
|
17
16
|
# returned.
|
18
17
|
#
|
19
18
|
# @api public
|
20
19
|
#
|
21
|
-
# @
|
22
|
-
#
|
23
|
-
#
|
20
|
+
# @param path [String] the path to be read
|
21
|
+
#
|
22
|
+
# @return [String, nil] the raw contents of the file or `nil` if the
|
23
|
+
# file cannot be read because it does not exist or the process does not have
|
24
|
+
# permission to read the file.
|
24
25
|
def self.read(path)
|
25
26
|
File.read(path)
|
26
27
|
rescue Errno::ENOENT, Errno::EACCES => detail
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Facter
|
4
|
+
module Util
|
5
|
+
module Formatter
|
6
|
+
|
7
|
+
def self.format_json(hash)
|
8
|
+
if Facter.json?
|
9
|
+
JSON.pretty_generate(hash)
|
10
|
+
else
|
11
|
+
raise "Cannot format facts as JSON; 'json' library is not present"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.format_yaml(hash)
|
16
|
+
YAML.dump(hash)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.format_plaintext(hash)
|
20
|
+
output = ''
|
21
|
+
|
22
|
+
# Print the value of a single fact, otherwise print a list sorted by fact
|
23
|
+
# name and separated by "=>"
|
24
|
+
if hash.length == 1
|
25
|
+
if value = hash.values.first
|
26
|
+
output = value
|
27
|
+
end
|
28
|
+
else
|
29
|
+
hash.sort_by { |(name, value)| name }.each do |name,value|
|
30
|
+
output << "#{name} => #{value}\n"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
output
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/facter/util/ip.rb
CHANGED
@@ -96,7 +96,7 @@ module Facter::Util::IP
|
|
96
96
|
#
|
97
97
|
# @return [String] the output of `ifconfig #{arguments} 2>/dev/null` or nil
|
98
98
|
def self.exec_ifconfig(additional_arguments=[])
|
99
|
-
Facter::
|
99
|
+
Facter::Core::Execution.exec("#{self.get_ifconfig} #{additional_arguments.join(' ')}")
|
100
100
|
end
|
101
101
|
##
|
102
102
|
# get_ifconfig looks up the ifconfig binary
|
@@ -110,7 +110,7 @@ module Facter::Util::IP
|
|
110
110
|
# hpux_netstat_in is a delegate method that allows us to stub netstat -in
|
111
111
|
# without stubbing exec.
|
112
112
|
def self.hpux_netstat_in
|
113
|
-
Facter::
|
113
|
+
Facter::Core::Execution.exec("/bin/netstat -in")
|
114
114
|
end
|
115
115
|
|
116
116
|
def self.get_infiniband_macaddress(interface)
|
@@ -160,7 +160,7 @@ module Facter::Util::IP
|
|
160
160
|
end
|
161
161
|
|
162
162
|
def self.hpux_lanscan
|
163
|
-
Facter::
|
163
|
+
Facter::Core::Execution.exec("/usr/sbin/lanscan")
|
164
164
|
end
|
165
165
|
|
166
166
|
def self.get_output_for_interface_and_label(interface, label)
|
data/lib/facter/util/loader.rb
CHANGED
@@ -5,45 +5,48 @@ require 'facter/util/directory_loader'
|
|
5
5
|
# Load facts on demand.
|
6
6
|
class Facter::Util::Loader
|
7
7
|
|
8
|
-
def initialize
|
8
|
+
def initialize(environment_vars = ENV)
|
9
9
|
@loaded = []
|
10
|
-
@
|
10
|
+
@environment_vars = environment_vars
|
11
11
|
end
|
12
12
|
|
13
13
|
# Load all resolutions for a single fact.
|
14
|
+
#
|
15
|
+
# @api public
|
16
|
+
# @param name [Symbol]
|
14
17
|
def load(fact)
|
15
18
|
# Now load from the search path
|
16
19
|
shortname = fact.to_s.downcase
|
17
20
|
load_env(shortname)
|
18
21
|
|
19
22
|
filename = shortname + ".rb"
|
20
|
-
search_path.each do |dir|
|
21
|
-
# Load individual files
|
22
|
-
file = File.join(dir, filename)
|
23
23
|
|
24
|
-
|
24
|
+
paths = search_path
|
25
|
+
unless paths.nil?
|
26
|
+
paths.each do |dir|
|
27
|
+
# Load individual files
|
28
|
+
file = File.join(dir, filename)
|
25
29
|
|
26
|
-
|
27
|
-
|
28
|
-
load_dir(factdir) if FileTest.directory?(factdir)
|
30
|
+
load_file(file) if File.file?(file)
|
31
|
+
end
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
32
35
|
# Load all facts from all directories.
|
36
|
+
#
|
37
|
+
# @api public
|
33
38
|
def load_all
|
34
39
|
return if defined?(@loaded_all)
|
35
40
|
|
36
41
|
load_env
|
37
42
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
elsif file =~ /\.rb$/
|
46
|
-
load_file(File.join(dir, file))
|
43
|
+
paths = search_path
|
44
|
+
unless paths.nil?
|
45
|
+
paths.each do |dir|
|
46
|
+
# dir is already an absolute path
|
47
|
+
Dir.glob(File.join(dir, '*.rb')).each do |path|
|
48
|
+
# exclude dirs that end with .rb
|
49
|
+
load_file(path) if File.file?(path)
|
47
50
|
end
|
48
51
|
end
|
49
52
|
end
|
@@ -51,43 +54,60 @@ class Facter::Util::Loader
|
|
51
54
|
@loaded_all = true
|
52
55
|
end
|
53
56
|
|
54
|
-
#
|
57
|
+
# List directories to search for fact files.
|
58
|
+
#
|
59
|
+
# Search paths are gathered from the following sources:
|
60
|
+
#
|
61
|
+
# 1. $LOAD_PATH entries are expanded to absolute paths
|
62
|
+
# 2. ENV['FACTERLIB'] is split and used verbatim
|
63
|
+
# 3. Entries from Facter.search_path are used verbatim
|
64
|
+
#
|
65
|
+
# A warning will be generated for paths in Facter.search_path that are not
|
66
|
+
# absolute directories.
|
67
|
+
#
|
68
|
+
# @api public
|
69
|
+
# @return [Array<String>]
|
55
70
|
def search_path
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
71
|
+
search_paths = []
|
72
|
+
search_paths += $LOAD_PATH.map { |path| File.expand_path('facter', path) }
|
73
|
+
|
74
|
+
if @environment_vars.include?("FACTERLIB")
|
75
|
+
search_paths += @environment_vars["FACTERLIB"].split(File::PATH_SEPARATOR)
|
60
76
|
end
|
61
77
|
|
62
|
-
|
63
|
-
result += Facter.search_path
|
78
|
+
search_paths.delete_if { |path| ! valid_search_path?(path) }
|
64
79
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
80
|
+
Facter.search_path.each do |path|
|
81
|
+
if valid_search_path?(path)
|
82
|
+
search_paths << path
|
83
|
+
else
|
84
|
+
Facter.warn "Excluding #{path} from search path. Fact file paths must be an absolute directory"
|
85
|
+
end
|
69
86
|
end
|
70
|
-
end
|
71
87
|
|
72
|
-
|
73
|
-
return @valid_path[path] unless @valid_path[path].nil?
|
88
|
+
search_paths.delete_if { |path| ! File.directory?(path) }
|
74
89
|
|
75
|
-
|
90
|
+
search_paths.uniq
|
76
91
|
end
|
77
|
-
private :valid_search_path?
|
78
92
|
|
79
93
|
private
|
80
94
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
95
|
+
# Validate that the given path is valid, ie it is an absolute path.
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
# @param path [String]
|
99
|
+
# @return [Boolean]
|
100
|
+
def valid_search_path?(path)
|
101
|
+
Pathname.new(path).absolute?
|
87
102
|
end
|
88
103
|
|
104
|
+
# Load a file and record is paths to prevent duplicate loads.
|
105
|
+
#
|
106
|
+
# @api private
|
107
|
+
# @params file [String] The *absolute path* to the file to load
|
89
108
|
def load_file(file)
|
90
109
|
return if @loaded.include? file
|
110
|
+
|
91
111
|
# We have to specify Kernel.load, because we have a load method.
|
92
112
|
begin
|
93
113
|
# Store the file path so we don't try to reload it
|
@@ -97,7 +117,7 @@ class Facter::Util::Loader
|
|
97
117
|
# Don't store the path if the file can't be loaded
|
98
118
|
# in case it's loadable later on.
|
99
119
|
@loaded.delete(file)
|
100
|
-
Facter.
|
120
|
+
Facter.log_exception(detail, "Error loading fact #{file}: #{detail.message}")
|
101
121
|
end
|
102
122
|
end
|
103
123
|
|
@@ -105,7 +125,7 @@ class Facter::Util::Loader
|
|
105
125
|
# all will be loaded.
|
106
126
|
def load_env(fact = nil)
|
107
127
|
# Load from the environment, if possible
|
108
|
-
|
128
|
+
@environment_vars.each do |name, value|
|
109
129
|
# Skip anything that doesn't match our regex.
|
110
130
|
next unless name =~ /^facter_?(\w+)$/i
|
111
131
|
env_name = $1
|