facter 4.0.39 → 4.0.44
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/facter +3 -4
- data/lib/facter.rb +107 -28
- data/lib/facter/config.rb +354 -0
- data/lib/facter/custom_facts/core/aggregate.rb +51 -17
- data/lib/facter/custom_facts/core/execution.rb +27 -35
- data/lib/facter/custom_facts/core/execution/base.rb +13 -7
- data/lib/facter/custom_facts/util/directory_loader.rb +1 -1
- data/lib/facter/custom_facts/util/fact.rb +1 -1
- data/lib/facter/custom_facts/util/resolution.rb +40 -11
- data/lib/facter/facts/aix/disks.rb +1 -1
- data/lib/facter/facts/linux/ec2_metadata.rb +5 -29
- data/lib/facter/facts/linux/ec2_userdata.rb +5 -27
- data/lib/facter/facts/linux/is_virtual.rb +7 -46
- data/lib/facter/facts/linux/virtual.rb +3 -58
- data/lib/facter/facts/rhel/os/release.rb +1 -1
- data/lib/facter/facts/solaris/disks.rb +1 -1
- data/lib/facter/facts/solaris/zones.rb +1 -1
- data/lib/facter/facts_utils/virtual_detector.rb +78 -0
- data/lib/facter/framework/benchmarking/timer.rb +4 -2
- data/lib/facter/framework/cli/cli.rb +83 -36
- data/lib/facter/framework/cli/cli_launcher.rb +34 -38
- data/lib/facter/framework/config/fact_groups.rb +41 -7
- data/lib/facter/framework/core/cache_manager.rb +43 -23
- data/lib/facter/framework/core/fact_loaders/fact_loader.rb +14 -11
- data/lib/facter/framework/core/options/config_file_options.rb +5 -3
- data/lib/facter/framework/core/options/option_store.rb +60 -27
- data/lib/facter/framework/detector/os_hierarchy.rb +5 -9
- data/lib/facter/framework/logging/logger.rb +1 -5
- data/lib/facter/resolvers/aix/architecture_resolver.rb +15 -1
- data/lib/facter/resolvers/aix/os_level.rb +1 -1
- data/lib/facter/resolvers/augeas_resolver.rb +7 -1
- data/lib/facter/resolvers/bsd/processors.rb +11 -7
- data/lib/facter/resolvers/disk_resolver.rb +11 -3
- data/lib/facter/resolvers/dmi_decode.rb +1 -0
- data/lib/facter/resolvers/dmi_resolver.rb +2 -2
- data/lib/facter/resolvers/freebsd/geom_resolver.rb +12 -20
- data/lib/facter/resolvers/freebsd/processors.rb +11 -7
- data/lib/facter/resolvers/memory_resolver.rb +12 -14
- data/lib/facter/resolvers/mountpoints_resolver.rb +50 -22
- data/lib/facter/resolvers/networking_linux_resolver.rb +10 -5
- data/lib/facter/resolvers/partitions.rb +60 -57
- data/lib/facter/resolvers/processors_resolver.rb +5 -1
- data/lib/facter/resolvers/solaris/dmi.rb +2 -0
- data/lib/facter/resolvers/solaris/mountpoints.rb +60 -0
- data/lib/facter/resolvers/solaris/networking.rb +1 -2
- data/lib/facter/resolvers/solaris/os_release.rb +4 -3
- data/lib/facter/resolvers/ssh_resolver.rb +4 -4
- data/lib/facter/version.rb +1 -1
- metadata +5 -4
- data/lib/facter/fact_groups.conf +0 -308
- data/lib/facter/os_hierarchy.json +0 -36
@@ -18,22 +18,31 @@ module Facter
|
|
18
18
|
include LegacyFacter::Core::Resolvable
|
19
19
|
|
20
20
|
# @!attribute [r] name
|
21
|
-
#
|
21
|
+
#
|
22
|
+
# @return [Symbol] The name of the aggregate resolution
|
23
|
+
#
|
24
|
+
# @api public
|
22
25
|
attr_reader :name
|
23
26
|
|
24
27
|
# @!attribute [r] deps
|
25
|
-
#
|
26
|
-
#
|
28
|
+
#
|
29
|
+
# @return [LegacyFacter::Core::DirectedGraph]
|
30
|
+
#
|
31
|
+
# @api private
|
27
32
|
attr_reader :deps
|
28
33
|
|
29
34
|
# @!attribute [r] confines
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
35
|
+
#
|
36
|
+
# @return [Array<LegacyFacter::Core::Confine>] An array of confines restricting
|
37
|
+
# this to a specific platform
|
38
|
+
#
|
39
|
+
# @api private
|
33
40
|
attr_reader :confines
|
34
41
|
|
35
42
|
# @!attribute [r] fact
|
43
|
+
#
|
36
44
|
# @return [Facter::Util::Fact]
|
45
|
+
#
|
37
46
|
# @api private
|
38
47
|
attr_reader :fact
|
39
48
|
|
@@ -48,10 +57,20 @@ module Facter
|
|
48
57
|
@deps = LegacyFacter::Core::DirectedGraph.new
|
49
58
|
end
|
50
59
|
|
60
|
+
# Compares the weight of two aggregate facts
|
61
|
+
#
|
62
|
+
# @return [bool] Weight comparison result
|
63
|
+
#
|
64
|
+
# @api private
|
51
65
|
def <=>(other)
|
52
66
|
weight <=> other.weight
|
53
67
|
end
|
54
68
|
|
69
|
+
# Sets options for the aggregate fact
|
70
|
+
#
|
71
|
+
# @return [nil]
|
72
|
+
#
|
73
|
+
# @api private
|
55
74
|
def options(options)
|
56
75
|
accepted_options = %i[name timeout weight fact_type]
|
57
76
|
accepted_options.each do |option_name|
|
@@ -60,14 +79,17 @@ module Facter
|
|
60
79
|
raise ArgumentError, "Invalid aggregate options #{options.keys.inspect}" unless options.keys.empty?
|
61
80
|
end
|
62
81
|
|
82
|
+
# Evaluates the given block
|
83
|
+
#
|
84
|
+
# @return [String] Result of the block's evaluation
|
85
|
+
#
|
86
|
+
# @api private
|
63
87
|
def evaluate(&block)
|
64
88
|
instance_eval(&block)
|
65
89
|
end
|
66
90
|
|
67
91
|
# Define a new chunk for the given aggregate
|
68
92
|
#
|
69
|
-
# @api public
|
70
|
-
#
|
71
93
|
# @example Defining a chunk with no dependencies
|
72
94
|
# aggregate.chunk(:mountpoints) do
|
73
95
|
# # generate mountpoint information
|
@@ -80,14 +102,14 @@ module Facter
|
|
80
102
|
# end
|
81
103
|
#
|
82
104
|
# @param name [Symbol] A name unique to this aggregate describing the chunk
|
83
|
-
# @param opts [Hash]
|
84
|
-
# @options opts [Array<Symbol>, Symbol] :require One or more chunks
|
85
|
-
# to evaluate and pass to this block.
|
86
|
-
# @yield [*Object] Zero or more chunk results
|
87
105
|
#
|
88
|
-
# @
|
106
|
+
# @param opts [Hash] Hash with options for the aggregate fact
|
107
|
+
#
|
108
|
+
# @return [Facter::Core::Aggregate] The aggregate object
|
109
|
+
#
|
110
|
+
# @api public
|
89
111
|
def chunk(name, opts = {}, &block)
|
90
|
-
|
112
|
+
evaluate_params(name, &block)
|
91
113
|
|
92
114
|
deps = Array(opts.delete(:require))
|
93
115
|
|
@@ -97,12 +119,11 @@ module Facter
|
|
97
119
|
|
98
120
|
@deps[name] = deps
|
99
121
|
@chunks[name] = block
|
122
|
+
self
|
100
123
|
end
|
101
124
|
|
102
125
|
# Define how all chunks should be combined
|
103
126
|
#
|
104
|
-
# @api public
|
105
|
-
#
|
106
127
|
# @example Merge all chunks
|
107
128
|
# aggregate.aggregate do |chunks|
|
108
129
|
# final_result = {}
|
@@ -124,19 +145,32 @@ module Facter
|
|
124
145
|
# @yield [Hash<Symbol, Object>] A hash containing chunk names and
|
125
146
|
# chunk values
|
126
147
|
#
|
127
|
-
# @return [
|
148
|
+
# @return [Facter::Core::Aggregate] The aggregate fact
|
149
|
+
#
|
150
|
+
# @api public
|
128
151
|
def aggregate(&block)
|
129
152
|
raise ArgumentError, "#{self.class.name}#aggregate requires a block" unless block_given?
|
130
153
|
|
131
154
|
@aggregate = block
|
155
|
+
self
|
132
156
|
end
|
133
157
|
|
158
|
+
# Returns the fact's resolution type
|
159
|
+
#
|
160
|
+
# @return [Symbol] The fact's type
|
161
|
+
#
|
162
|
+
# @api private
|
134
163
|
def resolution_type
|
135
164
|
:aggregate
|
136
165
|
end
|
137
166
|
|
138
167
|
private
|
139
168
|
|
169
|
+
def evaluate_params(name)
|
170
|
+
raise ArgumentError, "#{self.class.name}#chunk requires a block" unless block_given?
|
171
|
+
raise ArgumentError, "#{self.class.name}#expected chunk name to be a Symbol" unless name.is_a? Symbol
|
172
|
+
end
|
173
|
+
|
140
174
|
# Evaluate the results of this aggregate.
|
141
175
|
#
|
142
176
|
# @see Facter::Core::Resolvable#value
|
@@ -3,10 +3,6 @@
|
|
3
3
|
module Facter
|
4
4
|
module Core
|
5
5
|
module Execution
|
6
|
-
# require_relative 'execution/base'
|
7
|
-
# require_relative 'execution/windows'
|
8
|
-
# require_relative 'execution/posix'
|
9
|
-
|
10
6
|
@@impl = if LegacyFacter::Util::Config.windows?
|
11
7
|
Facter::Core::Execution::Windows.new
|
12
8
|
else
|
@@ -20,24 +16,22 @@ module Facter
|
|
20
16
|
module_function
|
21
17
|
|
22
18
|
# Returns the locations to be searched when looking for a binary. This
|
23
|
-
#
|
24
|
-
#
|
19
|
+
# is currently determined by the +PATH+ environment variable plus
|
20
|
+
# `/sbin` and `/usr/sbin` when run on unix
|
21
|
+
#
|
22
|
+
# @return [Array<String>] The paths to be searched for binaries
|
25
23
|
#
|
26
|
-
# @return [Array<String>] the paths to be searched for binaries
|
27
24
|
# @api private
|
28
25
|
def search_paths
|
29
26
|
@@impl.search_paths
|
30
27
|
end
|
31
28
|
|
32
29
|
# Determines the full path to a binary. If the supplied filename does not
|
33
|
-
#
|
34
|
-
#
|
30
|
+
# already describe an absolute path then different locations (determined
|
31
|
+
# by {search_paths}) will be searched for a match.
|
32
|
+
# @param bin [String] The executable to locate
|
35
33
|
#
|
36
|
-
#
|
37
|
-
# the expanded pathname.
|
38
|
-
#
|
39
|
-
# @param bin [String] the executable to locate
|
40
|
-
# @return [String,nil] the full path to the executable or nil if not
|
34
|
+
# @return [String/nil] The full path to the executable or nil if not
|
41
35
|
# found
|
42
36
|
#
|
43
37
|
# @api public
|
@@ -46,10 +40,12 @@ module Facter
|
|
46
40
|
end
|
47
41
|
|
48
42
|
# Determine in a platform-specific way whether a path is absolute. This
|
49
|
-
#
|
43
|
+
# defaults to the local platform if none is specified.
|
44
|
+
# @param path [String] The path to check
|
45
|
+
|
46
|
+
# @param platform [:posix/:windows/nil] The platform logic to use
|
50
47
|
#
|
51
|
-
# @
|
52
|
-
# @param platform [:posix,:windows,nil] the platform logic to use
|
48
|
+
# @api private
|
53
49
|
def absolute_path?(path, platform = nil)
|
54
50
|
case platform
|
55
51
|
when :posix
|
@@ -62,38 +58,35 @@ module Facter
|
|
62
58
|
end
|
63
59
|
|
64
60
|
# Given a command line, this returns the command line with the
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
61
|
+
# executable written as an absolute path. If the executable contains
|
62
|
+
# spaces, it has to be put in double quotes to be properly recognized.
|
68
63
|
# @param command [String] the command line
|
69
64
|
#
|
70
|
-
# @return [String
|
71
|
-
#
|
65
|
+
# @return [String/nil] The command line with the executable's path
|
66
|
+
# expanded, or nil if the executable cannot be found.
|
67
|
+
#
|
68
|
+
# @api private
|
72
69
|
def expand_command(command)
|
73
70
|
@@impl.expand_command(command)
|
74
71
|
end
|
75
72
|
|
76
73
|
# Overrides environment variables within a block of code. The
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
# @overload with_env(values, { || ... })
|
81
|
-
#
|
74
|
+
# specified values will be set for the duration of the block, after
|
75
|
+
# which the original values (if any) will be restored.
|
82
76
|
# @param values [Hash<String=>String>] A hash of the environment
|
83
77
|
# variables to override
|
84
78
|
#
|
85
|
-
# @return [
|
79
|
+
# @return [String] The block's return string
|
86
80
|
#
|
87
|
-
# @api
|
81
|
+
# @api private
|
88
82
|
def with_env(values, &block)
|
89
83
|
@@impl.with_env(values, &block)
|
90
84
|
end
|
91
85
|
|
92
86
|
# Try to execute a command and return the output.
|
87
|
+
# @param command [String] Command to run
|
93
88
|
#
|
94
|
-
# @
|
95
|
-
#
|
96
|
-
# @return [String] the output of the program, or nil if the command does
|
89
|
+
# @return [String/nil] Output of the program, or nil if the command does
|
97
90
|
# not exist or could not be executed.
|
98
91
|
#
|
99
92
|
# @deprecated Use #{execute} instead
|
@@ -103,9 +96,9 @@ module Facter
|
|
103
96
|
end
|
104
97
|
|
105
98
|
# Execute a command and return the output of that program.
|
99
|
+
# @param command [String] Command to run
|
106
100
|
#
|
107
|
-
# @param
|
108
|
-
# @param options [Hash]
|
101
|
+
# @param options [Hash] Hash with options for the aggregate fact
|
109
102
|
#
|
110
103
|
# @option options [Object] :on_fail How to behave when the command could
|
111
104
|
# not be run. Specifying :raise will raise an error, anything else will
|
@@ -118,7 +111,6 @@ module Facter
|
|
118
111
|
# command execution failed and :on_fail was specified.
|
119
112
|
#
|
120
113
|
# @api public
|
121
|
-
# @since 2.0.1
|
122
114
|
def execute(command, options = {})
|
123
115
|
@@impl.execute(command, options)
|
124
116
|
end
|
@@ -90,7 +90,7 @@ module Facter
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def execute_command(command, on_fail, logger = nil, time_limit = nil)
|
93
|
-
time_limit ||=
|
93
|
+
time_limit ||= 300
|
94
94
|
begin
|
95
95
|
# Set LC_ALL and LANG to force i18n to C for the duration of this exec;
|
96
96
|
# this ensures that any code that parses the
|
@@ -100,18 +100,24 @@ module Facter
|
|
100
100
|
@log.debug("Executing command: #{command}")
|
101
101
|
out, stderr = Open3.popen3(opts, command.to_s) do |_, stdout, stderr, wait_thr|
|
102
102
|
pid = wait_thr.pid
|
103
|
-
|
104
|
-
|
103
|
+
stdout_messages = +''
|
104
|
+
stderr_messages = +''
|
105
|
+
out_reader = Thread.new { stdout.read }
|
106
|
+
err_reader = Thread.new { stderr.read }
|
105
107
|
begin
|
106
108
|
Timeout.timeout(time_limit) do
|
107
|
-
|
108
|
-
|
109
|
+
stdout_messages << out_reader.value
|
110
|
+
stderr_messages << err_reader.value
|
109
111
|
end
|
110
112
|
rescue Timeout::Error
|
111
|
-
|
113
|
+
message = "Timeout encounter after #{time_limit}s, killing process with pid: #{pid}"
|
112
114
|
Process.kill('KILL', pid)
|
115
|
+
on_fail == :raise ? (raise StandardError, message) : @log.debug(message)
|
116
|
+
ensure
|
117
|
+
out_reader.kill
|
118
|
+
err_reader.kill
|
113
119
|
end
|
114
|
-
[
|
120
|
+
[stdout_messages, stderr_messages]
|
115
121
|
end
|
116
122
|
log_stderr(stderr, command, logger)
|
117
123
|
rescue StandardError => e
|
@@ -59,7 +59,7 @@ module LegacyFacter
|
|
59
59
|
basename = File.basename(file)
|
60
60
|
next if file_blocked?(basename)
|
61
61
|
|
62
|
-
if facts.find { |f| f.name == basename } && cm.
|
62
|
+
if facts.find { |f| f.name == basename } && cm.fact_cache_enabled?(basename)
|
63
63
|
Facter.log_exception(Exception.new("Caching is enabled for group \"#{basename}\" while "\
|
64
64
|
'there are at least two external facts files with the same filename'))
|
65
65
|
else
|
@@ -155,7 +155,7 @@ module Facter
|
|
155
155
|
@searching
|
156
156
|
end
|
157
157
|
|
158
|
-
# Lock our searching process, so we never
|
158
|
+
# Lock our searching process, so we never get stuck in recursion.
|
159
159
|
def searching
|
160
160
|
raise "Caught recursion on #{@name}" if searching?
|
161
161
|
|
@@ -14,6 +14,8 @@ module Facter
|
|
14
14
|
class Resolution
|
15
15
|
# @api private
|
16
16
|
attr_accessor :code, :fact_type
|
17
|
+
|
18
|
+
# @api private
|
17
19
|
attr_writer :value
|
18
20
|
|
19
21
|
extend Facter::Core::Execution
|
@@ -24,7 +26,12 @@ module Facter
|
|
24
26
|
# compatibility.
|
25
27
|
#
|
26
28
|
# @deprecated
|
27
|
-
|
29
|
+
#
|
30
|
+
# @api public
|
31
|
+
public :which, :exec
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
public :with_env
|
28
35
|
end
|
29
36
|
|
30
37
|
include LegacyFacter::Core::Resolvable
|
@@ -32,22 +39,27 @@ module Facter
|
|
32
39
|
|
33
40
|
# @!attribute [rw] name
|
34
41
|
# The name of this resolution. The resolution name should be unique with
|
35
|
-
#
|
42
|
+
# respect to the given fact.
|
43
|
+
#
|
36
44
|
# @return [String]
|
45
|
+
#
|
37
46
|
# @api public
|
38
47
|
attr_accessor :name
|
39
48
|
|
40
49
|
# @!attribute [r] fact
|
41
|
-
#
|
50
|
+
#
|
51
|
+
# @return [Facter::Util::Fact] Associated fact with this resolution.
|
52
|
+
#
|
42
53
|
# @api private
|
43
54
|
attr_reader :fact
|
44
55
|
|
45
56
|
# Create a new resolution mechanism.
|
46
57
|
#
|
47
58
|
# @param name [String] The name of the resolution.
|
48
|
-
# @return [void]
|
49
59
|
#
|
50
|
-
# @
|
60
|
+
# @return [Facter::Util::Resolution] The created resolution
|
61
|
+
#
|
62
|
+
# @api public
|
51
63
|
def initialize(name, fact)
|
52
64
|
@name = name
|
53
65
|
@fact = fact
|
@@ -57,6 +69,11 @@ module Facter
|
|
57
69
|
@weight = nil
|
58
70
|
end
|
59
71
|
|
72
|
+
# Returns the fact's resolution type
|
73
|
+
#
|
74
|
+
# @return [Symbol] The fact's type
|
75
|
+
#
|
76
|
+
# @api private
|
60
77
|
def resolution_type
|
61
78
|
:simple
|
62
79
|
end
|
@@ -64,7 +81,9 @@ module Facter
|
|
64
81
|
# Evaluate the given block in the context of this resolution. If a block has
|
65
82
|
# already been evaluated emit a warning to that effect.
|
66
83
|
#
|
67
|
-
# @return [
|
84
|
+
# @return [String] Result of the block's evaluation
|
85
|
+
#
|
86
|
+
# @api private
|
68
87
|
def evaluate(&block)
|
69
88
|
if @last_evaluated
|
70
89
|
msg = "Already evaluated #{@name}"
|
@@ -85,6 +104,11 @@ module Facter
|
|
85
104
|
end
|
86
105
|
end
|
87
106
|
|
107
|
+
# Sets options for the aggregate fact
|
108
|
+
#
|
109
|
+
# @return [nil]
|
110
|
+
#
|
111
|
+
# @api private
|
88
112
|
def options(options)
|
89
113
|
accepted_options = %i[name value timeout weight fact_type file]
|
90
114
|
|
@@ -98,8 +122,6 @@ module Facter
|
|
98
122
|
# Sets the code block or external program that will be evaluated to
|
99
123
|
# get the value of the fact.
|
100
124
|
#
|
101
|
-
# @return [void]
|
102
|
-
#
|
103
125
|
# @overload setcode(string)
|
104
126
|
# Sets an external program to call to get the value of the resolution
|
105
127
|
# @param [String] string the external program to run to get the
|
@@ -111,6 +133,8 @@ module Facter
|
|
111
133
|
# This block is run when the fact is evaluated. Errors raised from
|
112
134
|
# inside the block are rescued and printed to stderr.
|
113
135
|
#
|
136
|
+
# @return [Facter::Util::Resolution] Returns itself
|
137
|
+
#
|
114
138
|
# @api public
|
115
139
|
def setcode(string = nil, &block)
|
116
140
|
if string
|
@@ -127,11 +151,16 @@ module Facter
|
|
127
151
|
else
|
128
152
|
raise ArgumentError, 'You must pass either code or a block'
|
129
153
|
end
|
154
|
+
self
|
130
155
|
end
|
131
156
|
|
132
|
-
#
|
133
|
-
#
|
134
|
-
#
|
157
|
+
# Comparison is done based on weight and fact type.
|
158
|
+
# The greater the weight, the higher the priority.
|
159
|
+
# If weights are equal, we consider external facts greater than custom facts.
|
160
|
+
#
|
161
|
+
# @return [bool] Weight comparison result
|
162
|
+
#
|
163
|
+
# @api private
|
135
164
|
def <=>(other)
|
136
165
|
return compare_equal_weights(other) if weight == other.weight
|
137
166
|
return 1 if weight > other.weight
|