facter 4.0.39 → 4.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|