facter 4.0.37 → 4.0.42
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 +163 -23
- data/lib/facter/custom_facts/core/execution/base.rb +42 -6
- data/lib/facter/custom_facts/util/directory_loader.rb +1 -1
- data/lib/facter/facts/aix/disks.rb +1 -1
- data/lib/facter/facts/aix/kernel.rb +1 -1
- data/lib/facter/facts/aix/kernelmajversion.rb +1 -1
- data/lib/facter/facts/aix/kernelrelease.rb +1 -1
- data/lib/facter/facts/aix/kernelversion.rb +1 -1
- data/lib/facter/facts/aix/os/release.rb +1 -1
- data/lib/facter/facts/linux/cloud.rb +15 -0
- data/lib/facter/facts/linux/disks.rb +1 -1
- data/lib/facter/facts/linux/ec2_metadata.rb +5 -27
- 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 +2 -2
- data/lib/facter/facts/solaris/disks.rb +1 -1
- data/lib/facter/facts_utils/virtual_detector.rb +78 -0
- data/lib/facter/framework/cli/cli.rb +84 -36
- data/lib/facter/framework/cli/cli_launcher.rb +34 -38
- data/lib/facter/framework/config/fact_groups.rb +36 -2
- data/lib/facter/framework/core/cache_manager.rb +40 -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 +27 -10
- data/lib/facter/framework/logging/logger.rb +3 -11
- data/lib/facter/patches/sysfilesystem/sys/statvfs.rb +92 -0
- data/lib/facter/resolvers/aix/os_level.rb +27 -0
- data/lib/facter/resolvers/cloud.rb +39 -0
- data/lib/facter/resolvers/dmi_decode.rb +1 -0
- data/lib/facter/resolvers/memory_resolver.rb +12 -14
- data/lib/facter/resolvers/networking_linux_resolver.rb +0 -1
- data/lib/facter/resolvers/utils/filesystem_helper.rb +3 -1
- data/lib/facter/version.rb +1 -1
- metadata +7 -4
- data/lib/facter/resolvers/aix/os_level_resolver.rb +0 -25
- data/lib/facter/resolvers/os_level_resolver.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffa55de7f92a74b84788507b7e9667f158edc68abef1412f40ab5d3beb8f6aad
|
4
|
+
data.tar.gz: e92ff5798a9abab30f1887c5e4f934d75cef67975b2485e53ba6dc58b59ee899
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4841268cf5f76f1ad2b0ed2bf16b2527dd73e4d41728c64dbe13986b1a574759f900e2748e72ce72f6c677cf754d8a4f5115530140285412a07943e13b6312a5
|
7
|
+
data.tar.gz: bd48e0942af375429188957956a5555963297d62a9bc6549529ae1713b7670b41bfc5eea6b894d961e3e32507963e394779c372ad3b12a6422b5218f94b0f9e4
|
data/bin/facter
CHANGED
@@ -4,8 +4,7 @@
|
|
4
4
|
require 'pathname'
|
5
5
|
require 'facter/framework/cli/cli_launcher.rb'
|
6
6
|
|
7
|
-
|
7
|
+
Facter::OptionsValidator.validate(ARGV)
|
8
|
+
processed_arguments = CliLauncher.prepare_arguments(ARGV)
|
8
9
|
|
9
|
-
|
10
|
-
cli_launcher.prepare_arguments
|
11
|
-
cli_launcher.start
|
10
|
+
CliLauncher.start(processed_arguments)
|
data/lib/facter.rb
CHANGED
@@ -13,8 +13,31 @@ module Facter
|
|
13
13
|
Options.init
|
14
14
|
Log.output(STDOUT)
|
15
15
|
@already_searched = {}
|
16
|
+
@debug_once = []
|
17
|
+
@warn_once = []
|
16
18
|
|
17
19
|
class << self
|
20
|
+
def resolve(args_as_string)
|
21
|
+
require 'facter/framework/cli/cli_launcher'
|
22
|
+
|
23
|
+
args = args_as_string.split(' ')
|
24
|
+
|
25
|
+
Facter::OptionsValidator.validate(args)
|
26
|
+
processed_arguments = CliLauncher.prepare_arguments(args, nil)
|
27
|
+
|
28
|
+
cli = Facter::Cli.new([], processed_arguments)
|
29
|
+
|
30
|
+
if cli.args.include?(:version)
|
31
|
+
cli.invoke(:version, [])
|
32
|
+
elsif cli.args.include?('--list-cache-groups')
|
33
|
+
cli.invoke(:list_cache_groups, [])
|
34
|
+
elsif cli.args.include?('--list-block-groups')
|
35
|
+
cli.invoke(:list_block_groups, [])
|
36
|
+
else
|
37
|
+
cli.invoke(:arg_parser)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
18
41
|
def clear_messages
|
19
42
|
logger.debug('clear_messages is not implemented')
|
20
43
|
end
|
@@ -54,6 +77,8 @@ module Facter
|
|
54
77
|
# @api public
|
55
78
|
def clear
|
56
79
|
@already_searched = {}
|
80
|
+
@debug_once = []
|
81
|
+
@warn_once = []
|
57
82
|
LegacyFacter.clear
|
58
83
|
Options[:custom_dir] = []
|
59
84
|
LegacyFacter.collection.invalidate_custom_facts
|
@@ -68,24 +93,54 @@ module Facter
|
|
68
93
|
fact_collection.dig(*splitted_user_query)
|
69
94
|
end
|
70
95
|
|
71
|
-
#
|
72
|
-
# @param
|
96
|
+
# Logs debug message when debug option is set to true
|
97
|
+
# @param message [Object] Message object to be logged
|
98
|
+
#
|
99
|
+
# @return [nil]
|
100
|
+
#
|
101
|
+
# @api public
|
102
|
+
def debug(message)
|
103
|
+
return unless debugging?
|
104
|
+
|
105
|
+
logger.debug(message.to_s)
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
|
109
|
+
# Logs the same debug message only once when debug option is set to true
|
110
|
+
# @param message [Object] Message object to be logged
|
73
111
|
#
|
74
112
|
# @return [nil]
|
75
113
|
#
|
76
114
|
# @api public
|
77
|
-
def
|
115
|
+
def debugonce(message)
|
78
116
|
return unless debugging?
|
79
117
|
|
80
|
-
|
118
|
+
message_string = message.to_s
|
119
|
+
return if @debug_once.include? message_string
|
120
|
+
|
121
|
+
@debug_once << message_string
|
122
|
+
logger.debug(message_string)
|
81
123
|
nil
|
82
124
|
end
|
83
125
|
|
126
|
+
# Define a new fact or extend an existing fact.
|
127
|
+
#
|
128
|
+
# @param name [Symbol] The name of the fact to define
|
129
|
+
# @param options [Hash] A hash of options to set on the fact
|
130
|
+
#
|
131
|
+
# @return [Facter::Util::Fact] The fact that was defined
|
132
|
+
#
|
133
|
+
# @api public
|
134
|
+
def define_fact(name, options = {}, &block)
|
135
|
+
options[:fact_type] = :custom
|
136
|
+
LegacyFacter.define_fact(name, options, &block)
|
137
|
+
end
|
138
|
+
|
84
139
|
def on_message(&block)
|
85
140
|
Facter::Log.on_message(&block)
|
86
141
|
end
|
87
142
|
|
88
|
-
# Check whether
|
143
|
+
# Check whether debugging is enabled
|
89
144
|
#
|
90
145
|
# @return [bool]
|
91
146
|
#
|
@@ -104,11 +159,31 @@ module Facter
|
|
104
159
|
Facter::Options[:debug] = debug_bool
|
105
160
|
end
|
106
161
|
|
162
|
+
# Iterates over fact names and values
|
163
|
+
#
|
164
|
+
# @yieldparam [String] name the fact name
|
165
|
+
# @yieldparam [String] value the current value of the fact
|
166
|
+
#
|
167
|
+
# @return [Facter]
|
168
|
+
#
|
169
|
+
# @api public
|
170
|
+
def each
|
171
|
+
log_blocked_facts
|
172
|
+
resolved_facts = Facter::FactManager.instance.resolve_facts
|
173
|
+
SessionCache.invalidate_all_caches
|
174
|
+
|
175
|
+
resolved_facts.each do |fact|
|
176
|
+
yield(fact.name, fact.value)
|
177
|
+
end
|
178
|
+
|
179
|
+
self
|
180
|
+
end
|
181
|
+
|
107
182
|
# Returns a fact object by name. If you use this, you still have to
|
108
183
|
# call {Facter::Util::Fact#value `value`} on it to retrieve the actual
|
109
184
|
# value.
|
110
185
|
#
|
111
|
-
# @param
|
186
|
+
# @param user_query [String] the name of the fact
|
112
187
|
#
|
113
188
|
# @return [Facter::Util::Fact, nil] The fact object, or nil if no fact
|
114
189
|
# is found.
|
@@ -134,6 +209,16 @@ module Facter
|
|
134
209
|
nil
|
135
210
|
end
|
136
211
|
|
212
|
+
# Loads all facts
|
213
|
+
#
|
214
|
+
# @return [nil]
|
215
|
+
#
|
216
|
+
# @api public
|
217
|
+
def loadfacts
|
218
|
+
LegacyFacter.loadfacts
|
219
|
+
nil
|
220
|
+
end
|
221
|
+
|
137
222
|
# Register directories to be searched for custom facts. The registered directories
|
138
223
|
# must be absolute paths or they will be ignored.
|
139
224
|
#
|
@@ -199,7 +284,7 @@ module Facter
|
|
199
284
|
end
|
200
285
|
|
201
286
|
# Enable or disable trace
|
202
|
-
# @param
|
287
|
+
# @param bool [bool] Set trace on debug state
|
203
288
|
#
|
204
289
|
# @return [type] [description]
|
205
290
|
#
|
@@ -210,7 +295,7 @@ module Facter
|
|
210
295
|
|
211
296
|
# Gets the value for a fact. Returns `nil` if no such fact exists.
|
212
297
|
#
|
213
|
-
# @param
|
298
|
+
# @param user_query [String] the fact name
|
214
299
|
# @return [String] the value of the fact, or nil if no fact is found
|
215
300
|
#
|
216
301
|
# @api public
|
@@ -220,6 +305,18 @@ module Facter
|
|
220
305
|
@already_searched[user_query]&.value
|
221
306
|
end
|
222
307
|
|
308
|
+
def values(options, user_queries)
|
309
|
+
init_cli_options(options, user_queries)
|
310
|
+
resolved_facts = Facter::FactManager.instance.resolve_facts(user_queries)
|
311
|
+
Facter::SessionCache.invalidate_all_caches
|
312
|
+
|
313
|
+
if user_queries.count.zero?
|
314
|
+
Facter::FactCollection.new.build_fact_collection!(resolved_facts)
|
315
|
+
else
|
316
|
+
FormatterHelper.retrieve_facts_to_display_for_user_query(user_queries, resolved_facts)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
223
320
|
# Returns Facter version
|
224
321
|
#
|
225
322
|
# @return [String] Current version
|
@@ -247,23 +344,67 @@ module Facter
|
|
247
344
|
[fact_formatter.format(resolved_facts), status || 0]
|
248
345
|
end
|
249
346
|
|
250
|
-
def log_exception(exception, message =
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
elsif message
|
255
|
-
arr << message
|
256
|
-
end
|
257
|
-
if Options[:trace]
|
258
|
-
arr << 'backtrace:'
|
259
|
-
arr.concat(exception.backtrace)
|
260
|
-
end
|
347
|
+
def log_exception(exception, message = nil)
|
348
|
+
error_message = []
|
349
|
+
|
350
|
+
error_message << message.to_s unless message.nil? || (message.is_a?(String) && message.empty?)
|
261
351
|
|
262
|
-
|
352
|
+
parse_exception(exception, error_message)
|
353
|
+
logger.error(error_message.flatten.join("\n"))
|
354
|
+
end
|
355
|
+
|
356
|
+
# Returns a list with the names of all solved facts
|
357
|
+
#
|
358
|
+
# @return [Array] the list with all the fact names
|
359
|
+
#
|
360
|
+
# @api public
|
361
|
+
def list
|
362
|
+
to_hash.keys.sort
|
363
|
+
end
|
364
|
+
|
365
|
+
# Logs the message parameter as a warning.
|
366
|
+
#
|
367
|
+
# @param message [Object] the warning object to be displayed
|
368
|
+
#
|
369
|
+
# @return [nil]
|
370
|
+
#
|
371
|
+
# @api public
|
372
|
+
def warn(message)
|
373
|
+
logger.warn(message.to_s)
|
374
|
+
nil
|
375
|
+
end
|
376
|
+
|
377
|
+
# Logs only once the same warning message.
|
378
|
+
#
|
379
|
+
# @param message [Object] the warning message object
|
380
|
+
#
|
381
|
+
# @return [nil]
|
382
|
+
#
|
383
|
+
# @api public
|
384
|
+
def warnonce(message)
|
385
|
+
message_string = message.to_s
|
386
|
+
return if @warn_once.include? message_string
|
387
|
+
|
388
|
+
@warn_once << message_string
|
389
|
+
logger.warn(message_string)
|
390
|
+
nil
|
263
391
|
end
|
264
392
|
|
265
393
|
private
|
266
394
|
|
395
|
+
def parse_exception(exception, error_message)
|
396
|
+
if exception.is_a?(Exception)
|
397
|
+
error_message << exception.message if error_message.empty?
|
398
|
+
|
399
|
+
if Options[:trace] && !exception.backtrace.nil?
|
400
|
+
error_message << 'backtrace:'
|
401
|
+
error_message.concat(exception.backtrace)
|
402
|
+
end
|
403
|
+
elsif error_message.empty?
|
404
|
+
error_message << exception.to_s
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
267
408
|
def logger
|
268
409
|
@logger ||= Log.new(self)
|
269
410
|
end
|
@@ -303,10 +444,9 @@ module Facter
|
|
303
444
|
# Returns exit status when user query contains facts that do
|
304
445
|
# not exist
|
305
446
|
#
|
306
|
-
# @param
|
307
|
-
# @param dirs [Array] List of resolved facts
|
447
|
+
# @param resolved_facts [Array] List of resolved facts
|
308
448
|
#
|
309
|
-
# @return [
|
449
|
+
# @return [1/nil] Will return status 1 if user query contains
|
310
450
|
# facts that are not found or resolved, otherwise it will return nil
|
311
451
|
#
|
312
452
|
# @api private
|
@@ -6,6 +6,10 @@ module Facter
|
|
6
6
|
class Base
|
7
7
|
STDERR_MESSAGE = 'Command %s resulted with the following stderr message: %s'
|
8
8
|
|
9
|
+
def initialize
|
10
|
+
@log = Log.new(self)
|
11
|
+
end
|
12
|
+
|
9
13
|
# This is part of the public API. No race condition can happen
|
10
14
|
# here because custom facts are executed sequentially
|
11
15
|
def with_env(values)
|
@@ -36,9 +40,7 @@ module Facter
|
|
36
40
|
end
|
37
41
|
|
38
42
|
def execute(command, options = {})
|
39
|
-
on_fail = options
|
40
|
-
expand = options.fetch(:expand, true)
|
41
|
-
logger = options[:logger]
|
43
|
+
on_fail, expand, logger, time_limit = extract_options(options)
|
42
44
|
|
43
45
|
expanded_command = if !expand && builtin_command?(command) || logger
|
44
46
|
command
|
@@ -55,11 +57,21 @@ module Facter
|
|
55
57
|
return on_fail
|
56
58
|
end
|
57
59
|
|
58
|
-
execute_command(expanded_command, on_fail, logger)
|
60
|
+
execute_command(expanded_command, on_fail, logger, time_limit)
|
59
61
|
end
|
60
62
|
|
61
63
|
private
|
62
64
|
|
65
|
+
def extract_options(options)
|
66
|
+
on_fail = options.fetch(:on_fail, :raise)
|
67
|
+
expand = options.fetch(:expand, true)
|
68
|
+
logger = options[:logger]
|
69
|
+
time_limit = options[:limit].to_i
|
70
|
+
time_limit = time_limit.positive? ? time_limit : nil
|
71
|
+
|
72
|
+
[on_fail, expand, logger, time_limit]
|
73
|
+
end
|
74
|
+
|
63
75
|
def log_stderr(msg, command, logger)
|
64
76
|
return if !msg || msg.empty?
|
65
77
|
|
@@ -77,12 +89,36 @@ module Facter
|
|
77
89
|
output.chomp =~ /builtin/ ? true : false
|
78
90
|
end
|
79
91
|
|
80
|
-
def execute_command(command, on_fail, logger = nil)
|
92
|
+
def execute_command(command, on_fail, logger = nil, time_limit = nil)
|
93
|
+
time_limit ||= 300
|
81
94
|
begin
|
82
95
|
# Set LC_ALL and LANG to force i18n to C for the duration of this exec;
|
83
96
|
# this ensures that any code that parses the
|
84
97
|
# output of the command can expect it to be in a consistent / predictable format / locale
|
85
|
-
|
98
|
+
opts = { 'LC_ALL' => 'C', 'LANG' => 'C' }
|
99
|
+
require 'timeout'
|
100
|
+
@log.debug("Executing command: #{command}")
|
101
|
+
out, stderr = Open3.popen3(opts, command.to_s) do |_, stdout, stderr, wait_thr|
|
102
|
+
pid = wait_thr.pid
|
103
|
+
stdout_messages = +''
|
104
|
+
stderr_messages = +''
|
105
|
+
out_reader = Thread.new { stdout.read }
|
106
|
+
err_reader = Thread.new { stderr.read }
|
107
|
+
begin
|
108
|
+
Timeout.timeout(time_limit) do
|
109
|
+
stdout_messages << out_reader.value
|
110
|
+
stderr_messages << err_reader.value
|
111
|
+
end
|
112
|
+
rescue Timeout::Error
|
113
|
+
message = "Timeout encounter after #{time_limit}s, killing process with pid: #{pid}"
|
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
|
119
|
+
end
|
120
|
+
[stdout_messages, stderr_messages]
|
121
|
+
end
|
86
122
|
log_stderr(stderr, command, logger)
|
87
123
|
rescue StandardError => e
|
88
124
|
return '' if logger
|
@@ -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
|
@@ -24,7 +24,7 @@ module Facts
|
|
24
24
|
|
25
25
|
def add_legacy_facts(disks, facts)
|
26
26
|
disks.each do |disk_name, disk_info|
|
27
|
-
facts.push(Facter::ResolvedFact.new("blockdevice_#{disk_name}_size", disk_info[:size_bytes]
|
27
|
+
facts.push(Facter::ResolvedFact.new("blockdevice_#{disk_name}_size", disk_info[:size_bytes], :legacy))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -6,7 +6,7 @@ module Facts
|
|
6
6
|
FACT_NAME = 'kernelmajversion'
|
7
7
|
|
8
8
|
def call_the_resolver
|
9
|
-
fact_value = Facter::Resolvers::OsLevel.resolve(:build)
|
9
|
+
fact_value = Facter::Resolvers::Aix::OsLevel.resolve(:build)
|
10
10
|
kernelmajversion = fact_value.split('-')[0]
|
11
11
|
|
12
12
|
Facter::ResolvedFact.new(FACT_NAME, kernelmajversion)
|
@@ -6,7 +6,7 @@ module Facts
|
|
6
6
|
FACT_NAME = 'kernelversion'
|
7
7
|
|
8
8
|
def call_the_resolver
|
9
|
-
fact_value = Facter::Resolvers::OsLevel.resolve(:build)
|
9
|
+
fact_value = Facter::Resolvers::Aix::OsLevel.resolve(:build)
|
10
10
|
kernelversion = fact_value.split('-')[0]
|
11
11
|
|
12
12
|
Facter::ResolvedFact.new(FACT_NAME, kernelversion)
|
@@ -8,7 +8,7 @@ module Facts
|
|
8
8
|
ALIASES = %w[operatingsystemmajrelease operatingsystemrelease].freeze
|
9
9
|
|
10
10
|
def call_the_resolver
|
11
|
-
fact_value = Facter::Resolvers::OsLevel.resolve(:build)
|
11
|
+
fact_value = Facter::Resolvers::Aix::OsLevel.resolve(:build)
|
12
12
|
major = fact_value.split('-')[0]
|
13
13
|
|
14
14
|
[Facter::ResolvedFact.new(FACT_NAME, full: fact_value.strip, major: major),
|