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
@@ -1,59 +1,55 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require 'thor'
|
5
4
|
require 'facter/framework/logging/logger.rb'
|
6
5
|
Facter::Log.output(STDERR)
|
7
6
|
require 'facter'
|
8
7
|
require 'facter/framework/cli/cli'
|
9
8
|
|
10
9
|
class CliLauncher
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
class << self
|
11
|
+
def prepare_arguments(args, task = Facter::Cli.default_task)
|
12
|
+
args.unshift(task) unless
|
13
|
+
check_if_arguments_is_known(Facter::Cli.all_tasks, args) ||
|
14
|
+
check_if_arguments_is_known(Facter::Cli.instance_variable_get(:@map), args) ||
|
15
|
+
!task
|
16
|
+
|
17
|
+
reorder_program_arguments(args)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def start(args)
|
21
|
+
# stop parsing arguments if we don't recognize them
|
22
|
+
Thor.check_unknown_options!
|
23
|
+
Facter::Cli.start(args, debug: true)
|
24
|
+
rescue Thor::UnknownArgumentError => e
|
25
|
+
Facter::OptionsValidator.write_error_and_exit("unrecognised option '#{e.unknown.first}'")
|
26
|
+
end
|
23
27
|
|
24
|
-
|
25
|
-
end
|
28
|
+
private
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
30
|
+
def check_if_arguments_is_known(known_arguments, program_arguments)
|
31
|
+
program_arguments.each do |argument|
|
32
|
+
return true if known_arguments.key?(argument)
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
program_arguments.each do |argument|
|
37
|
-
return true if known_arguments.key?(argument)
|
35
|
+
false
|
38
36
|
end
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def reorder_program_arguments(program_arguments)
|
44
|
-
priority_arguments = Facter::Cli.instance_variable_get(:@map)
|
38
|
+
def reorder_program_arguments(program_arguments)
|
39
|
+
priority_arguments = Facter::Cli.instance_variable_get(:@map)
|
45
40
|
|
46
|
-
|
47
|
-
|
41
|
+
priority_args = []
|
42
|
+
normal_args = []
|
48
43
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
program_arguments.each do |argument|
|
45
|
+
if priority_arguments.include?(argument)
|
46
|
+
priority_args << argument
|
47
|
+
else
|
48
|
+
normal_args << argument
|
49
|
+
end
|
54
50
|
end
|
55
|
-
end
|
56
51
|
|
57
|
-
|
52
|
+
priority_args.concat(normal_args)
|
53
|
+
end
|
58
54
|
end
|
59
55
|
end
|
@@ -1,19 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'facter/config'
|
4
|
+
|
3
5
|
module Facter
|
4
6
|
class FactGroups
|
5
|
-
attr_reader :groups, :block_list
|
7
|
+
attr_reader :groups, :block_list, :facts_ttls
|
6
8
|
|
7
9
|
@groups_ttls = []
|
8
10
|
|
9
11
|
STRING_TO_SECONDS = { 'seconds' => 1, 'minutes' => 60, 'hours' => 3600, 'days' => 3600 * 24 }.freeze
|
10
12
|
|
11
|
-
def initialize
|
12
|
-
|
13
|
-
@groups_file_path = group_list_path || default_path
|
14
|
-
@groups ||= File.readable?(@groups_file_path) ? Hocon.load(@groups_file_path) : {}
|
13
|
+
def initialize
|
14
|
+
@groups = Facter::Config::FACT_GROUPS.dup
|
15
15
|
load_groups
|
16
16
|
load_groups_from_options
|
17
|
+
load_facts_ttls
|
18
|
+
|
19
|
+
# Reverse sort facts so that children have precedence when caching. eg: os.macosx vs os
|
20
|
+
@facts_ttls = @facts_ttls.sort.reverse.to_h
|
17
21
|
end
|
18
22
|
|
19
23
|
# Breakes down blocked groups in blocked facts
|
@@ -31,6 +35,9 @@ module Facter
|
|
31
35
|
|
32
36
|
# Get the group name a fact is part of
|
33
37
|
def get_fact_group(fact_name)
|
38
|
+
fact = get_fact(fact_name)
|
39
|
+
return fact[:group] if fact
|
40
|
+
|
34
41
|
@groups.detect { |k, v| break k if Array(v).find { |f| fact_name =~ /^#{f}.*/ } }
|
35
42
|
end
|
36
43
|
|
@@ -41,6 +48,15 @@ module Facter
|
|
41
48
|
ttls_to_seconds(ttls[group_name])
|
42
49
|
end
|
43
50
|
|
51
|
+
def get_fact(fact_name)
|
52
|
+
return @facts_ttls[fact_name] if @facts_ttls[fact_name]
|
53
|
+
|
54
|
+
result = @facts_ttls.select { |name, fact| break fact if fact_name =~ /^#{name}\..*/ }
|
55
|
+
return nil if result == {}
|
56
|
+
|
57
|
+
result
|
58
|
+
end
|
59
|
+
|
44
60
|
private
|
45
61
|
|
46
62
|
def load_groups_from_options
|
@@ -55,10 +71,28 @@ module Facter
|
|
55
71
|
end
|
56
72
|
end
|
57
73
|
|
74
|
+
def load_facts_ttls
|
75
|
+
@facts_ttls ||= {}
|
76
|
+
return if @groups_ttls == []
|
77
|
+
|
78
|
+
@groups_ttls.reduce(:merge).each do |group, ttls|
|
79
|
+
ttls = ttls_to_seconds(ttls)
|
80
|
+
if @groups[group]
|
81
|
+
@groups[group].each do |fact|
|
82
|
+
if (@facts_ttls[fact] && @facts_ttls[fact][:ttls] < ttls) || @facts_ttls[fact].nil?
|
83
|
+
@facts_ttls[fact] = { ttls: ttls, group: group }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
else
|
87
|
+
@facts_ttls[group] = { ttls: ttls, group: group }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
58
92
|
def load_groups
|
59
93
|
config = ConfigReader.init(Options[:config])
|
60
|
-
@block_list = config.block_list ||
|
61
|
-
@groups_ttls = config.ttls ||
|
94
|
+
@block_list = config.block_list || []
|
95
|
+
@groups_ttls = config.ttls || []
|
62
96
|
@groups.merge!(config.fact_groups) if config.fact_groups
|
63
97
|
end
|
64
98
|
|
@@ -40,31 +40,47 @@ module Facter
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
43
|
+
def fact_cache_enabled?(fact_name)
|
44
|
+
fact = @fact_groups.get_fact(fact_name)
|
45
|
+
cached = if fact
|
46
|
+
!fact[:ttls].nil?
|
47
|
+
else
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
51
|
+
fact_group = @fact_groups.get_fact_group(fact_name)
|
52
|
+
delete_cache(fact_group) if fact_group && !cached
|
46
53
|
cached
|
47
54
|
end
|
48
55
|
|
49
56
|
private
|
50
57
|
|
51
58
|
def resolve_fact(searched_fact)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
59
|
+
fact_name = if searched_fact.file
|
60
|
+
File.basename(searched_fact.file)
|
61
|
+
else
|
62
|
+
searched_fact.name
|
63
|
+
end
|
57
64
|
|
58
|
-
return unless
|
65
|
+
return unless fact_cache_enabled?(fact_name)
|
59
66
|
|
60
|
-
|
67
|
+
fact = @fact_groups.get_fact(fact_name)
|
61
68
|
|
62
|
-
return unless
|
69
|
+
return unless fact
|
63
70
|
|
64
|
-
|
71
|
+
return unless check_ttls?(fact[:group], fact[:ttls])
|
72
|
+
|
73
|
+
read_fact(searched_fact, fact[:group])
|
74
|
+
end
|
75
|
+
|
76
|
+
def read_fact(searched_fact, fact_group)
|
77
|
+
data = nil
|
78
|
+
Facter::Framework::Benchmarking::Timer.measure(searched_fact.name, 'cached') do
|
79
|
+
data = read_group_json(fact_group)
|
80
|
+
end
|
65
81
|
return unless data
|
66
82
|
|
67
|
-
@log.debug("loading cached values for #{
|
83
|
+
@log.debug("loading cached values for #{searched_fact.name} facts")
|
68
84
|
|
69
85
|
create_facts(searched_fact, data)
|
70
86
|
end
|
@@ -86,14 +102,17 @@ module Facter
|
|
86
102
|
end
|
87
103
|
|
88
104
|
def cache_fact(fact)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
105
|
+
fact_name = if fact.file
|
106
|
+
File.basename(fact.file)
|
107
|
+
else
|
108
|
+
fact.name
|
109
|
+
end
|
110
|
+
|
111
|
+
group_name = @fact_groups.get_fact_group(fact_name)
|
112
|
+
|
94
113
|
return if !group_name || fact.value.nil?
|
95
114
|
|
96
|
-
return unless
|
115
|
+
return unless fact_cache_enabled?(fact_name)
|
97
116
|
|
98
117
|
@groups[group_name] ||= {}
|
99
118
|
@groups[group_name][fact.name] = fact.value
|
@@ -106,10 +125,12 @@ module Facter
|
|
106
125
|
end
|
107
126
|
|
108
127
|
@groups.each do |group_name, data|
|
109
|
-
next unless check_ttls?(group_name)
|
128
|
+
next unless check_ttls?(group_name, @fact_groups.get_group_ttls(group_name))
|
110
129
|
|
111
|
-
@log.debug("caching values for #{group_name} facts")
|
112
130
|
cache_file_name = File.join(@cache_dir, group_name)
|
131
|
+
next if File.readable?(cache_file_name)
|
132
|
+
|
133
|
+
@log.debug("caching values for #{group_name} facts")
|
113
134
|
File.write(cache_file_name, JSON.pretty_generate(data))
|
114
135
|
end
|
115
136
|
end
|
@@ -128,8 +149,7 @@ module Facter
|
|
128
149
|
@groups[group_name] = data
|
129
150
|
end
|
130
151
|
|
131
|
-
def check_ttls?(group_name)
|
132
|
-
ttls = @fact_groups.get_group_ttls(group_name)
|
152
|
+
def check_ttls?(group_name, ttls)
|
133
153
|
return false unless ttls
|
134
154
|
|
135
155
|
cache_file_name = File.join(@cache_dir, group_name)
|
@@ -20,45 +20,48 @@ module Facter
|
|
20
20
|
|
21
21
|
@facts = []
|
22
22
|
@external_facts = []
|
23
|
-
load_internal_facts(options)
|
24
|
-
load_external_facts(options)
|
25
23
|
|
26
|
-
@
|
24
|
+
@internal_facts = load_internal_facts(options)
|
25
|
+
@external_facts = load_external_facts(options)
|
26
|
+
|
27
|
+
@facts = @internal_facts + @external_facts
|
27
28
|
end
|
28
29
|
|
29
30
|
private
|
30
31
|
|
31
32
|
def load_internal_facts(options)
|
32
33
|
@log.debug('Loading internal facts')
|
34
|
+
internal_facts = []
|
33
35
|
|
34
36
|
if options[:user_query] || options[:show_legacy]
|
35
37
|
# if we have a user query, then we must search in core facts and legacy facts
|
36
38
|
@log.debug('Loading all internal facts')
|
37
|
-
|
39
|
+
internal_facts = @internal_loader.facts
|
38
40
|
else
|
39
41
|
@log.debug('Load only core facts')
|
40
|
-
|
42
|
+
internal_facts = @internal_loader.core_facts
|
41
43
|
end
|
42
44
|
|
43
|
-
|
44
|
-
@facts.concat(@internal_facts)
|
45
|
+
block_facts(internal_facts, options)
|
45
46
|
end
|
46
47
|
|
47
48
|
def load_external_facts(options)
|
48
49
|
@log.debug('Loading external facts')
|
50
|
+
external_facts = []
|
51
|
+
|
49
52
|
if options[:custom_facts]
|
50
53
|
@log.debug('Loading custom facts')
|
51
|
-
|
54
|
+
external_facts += @external_fact_loader.custom_facts
|
52
55
|
end
|
53
56
|
|
54
|
-
|
57
|
+
external_facts = block_facts(external_facts, options)
|
55
58
|
|
56
59
|
if options[:external_facts]
|
57
60
|
@log.debug('Loading external facts')
|
58
|
-
|
61
|
+
external_facts += @external_fact_loader.external_facts
|
59
62
|
end
|
60
63
|
|
61
|
-
|
64
|
+
external_facts
|
62
65
|
end
|
63
66
|
|
64
67
|
def block_facts(facts, options)
|
@@ -46,7 +46,9 @@ module Facter
|
|
46
46
|
return unless file_global_conf
|
47
47
|
|
48
48
|
if Options.cli?
|
49
|
-
|
49
|
+
unless file_global_conf['no-custom-facts'].nil?
|
50
|
+
@options[:no_custom_facts] = file_global_conf['no-custom-facts']
|
51
|
+
end
|
50
52
|
end
|
51
53
|
|
52
54
|
@options[:custom_dir] = file_global_conf['custom-dir'] unless file_global_conf['custom-dir'].nil?
|
@@ -57,7 +59,7 @@ module Facter
|
|
57
59
|
return unless global_conf
|
58
60
|
|
59
61
|
if Options.cli?
|
60
|
-
@options[:
|
62
|
+
@options[:no_external_facts] = global_conf['no-external-facts'] unless global_conf['no-external-facts'].nil?
|
61
63
|
end
|
62
64
|
|
63
65
|
@options[:external_dir] = [global_conf['external-dir']].flatten unless global_conf['external-dir'].nil?
|
@@ -67,7 +69,7 @@ module Facter
|
|
67
69
|
def augment_ruby(global_conf)
|
68
70
|
return unless global_conf
|
69
71
|
|
70
|
-
@options[:
|
72
|
+
@options[:no_ruby] = global_conf['no-ruby'].nil? ? false : global_conf['no-ruby']
|
71
73
|
end
|
72
74
|
|
73
75
|
def augment_show_legacy(global_conf)
|
@@ -8,28 +8,36 @@ module Facter
|
|
8
8
|
# TODO: constant is not yet available when running puppet facts
|
9
9
|
@log_level = :warn
|
10
10
|
@show_legacy = true
|
11
|
+
@custom_facts = true
|
12
|
+
@blocked_facts = []
|
13
|
+
@ruby = true
|
14
|
+
@external_facts = true
|
15
|
+
@config = nil
|
16
|
+
@user_query = []
|
17
|
+
@strict = false
|
18
|
+
@json = false
|
19
|
+
@cache = true
|
20
|
+
@yaml = false
|
21
|
+
@puppet = false
|
22
|
+
@ttls = []
|
11
23
|
@block = true
|
12
|
-
@
|
24
|
+
@cli = nil
|
13
25
|
@config_file_custom_dir = []
|
14
|
-
@custom_facts = true
|
15
|
-
@external_dir = []
|
16
26
|
@config_file_external_dir = []
|
17
27
|
@default_external_dir = []
|
18
|
-
@external_facts = true
|
19
|
-
@ruby = true
|
20
|
-
@cache = true
|
21
|
-
@blocked_facts = []
|
22
|
-
@user_query = []
|
23
|
-
@block_list = {}
|
24
28
|
@fact_groups = {}
|
25
|
-
@
|
29
|
+
@block_list = []
|
30
|
+
@color = true
|
31
|
+
@trace = false
|
26
32
|
@timing = false
|
33
|
+
@external_dir = []
|
34
|
+
@custom_dir = []
|
27
35
|
|
28
36
|
class << self
|
29
|
-
attr_reader :debug, :verbose, :log_level, :show_legacy,
|
30
|
-
:custom_facts, :blocked_facts
|
37
|
+
attr_reader :debug, :verbose, :log_level, :show_legacy,
|
38
|
+
:custom_facts, :blocked_facts, :ruby, :external_facts
|
31
39
|
|
32
|
-
attr_accessor :config, :user_query, :strict, :json,
|
40
|
+
attr_accessor :config, :user_query, :strict, :json,
|
33
41
|
:cache, :yaml, :puppet, :ttls, :block, :cli, :config_file_custom_dir,
|
34
42
|
:config_file_external_dir, :default_external_dir, :fact_groups,
|
35
43
|
:block_list, :color, :trace, :timing
|
@@ -45,16 +53,28 @@ module Facter
|
|
45
53
|
options
|
46
54
|
end
|
47
55
|
|
48
|
-
def
|
49
|
-
if bool
|
50
|
-
@ruby = true
|
51
|
-
else
|
56
|
+
def no_ruby=(bool)
|
57
|
+
if bool
|
52
58
|
@ruby = false
|
53
59
|
@custom_facts = false
|
54
60
|
@blocked_facts << 'ruby'
|
61
|
+
else
|
62
|
+
@ruby = true
|
55
63
|
end
|
56
64
|
end
|
57
65
|
|
66
|
+
def no_block=(bool)
|
67
|
+
@block = !bool
|
68
|
+
end
|
69
|
+
|
70
|
+
def no_cache=(bool)
|
71
|
+
@cache = !bool
|
72
|
+
end
|
73
|
+
|
74
|
+
def no_color=(bool)
|
75
|
+
@color = !bool
|
76
|
+
end
|
77
|
+
|
58
78
|
def external_dir
|
59
79
|
return fallback_external_dir if @external_dir.empty? && @external_facts
|
60
80
|
|
@@ -99,8 +119,8 @@ module Facter
|
|
99
119
|
end
|
100
120
|
end
|
101
121
|
|
102
|
-
def
|
103
|
-
if bool ==
|
122
|
+
def no_custom_facts=(bool)
|
123
|
+
if bool == false
|
104
124
|
@custom_facts = true
|
105
125
|
@ruby = true
|
106
126
|
else
|
@@ -108,6 +128,10 @@ module Facter
|
|
108
128
|
end
|
109
129
|
end
|
110
130
|
|
131
|
+
def no_external_facts=(bool)
|
132
|
+
@external_facts = !bool
|
133
|
+
end
|
134
|
+
|
111
135
|
def log_level=(level)
|
112
136
|
level = level.to_sym
|
113
137
|
case level
|
@@ -142,25 +166,34 @@ module Facter
|
|
142
166
|
# TODO: constant is not yet available when running puppet facts
|
143
167
|
@log_level = :warn
|
144
168
|
@show_legacy = true
|
145
|
-
@block = true
|
146
169
|
@ruby = true
|
147
170
|
@user_query = []
|
148
|
-
@
|
171
|
+
@json = false
|
149
172
|
@cache = true
|
150
|
-
@
|
173
|
+
@yaml = false
|
174
|
+
@puppet = false
|
175
|
+
@ttls = []
|
176
|
+
@block = true
|
177
|
+
@cli = nil
|
151
178
|
reset_config
|
152
179
|
end
|
153
180
|
|
154
181
|
def reset_config
|
155
|
-
@custom_dir = []
|
156
182
|
@custom_facts = true
|
157
|
-
@external_dir = []
|
158
|
-
@default_external_dir = []
|
159
|
-
@external_facts = true
|
160
183
|
@blocked_facts = []
|
184
|
+
@external_facts = true
|
185
|
+
@config = nil
|
186
|
+
@strict = false
|
187
|
+
@config_file_custom_dir = []
|
188
|
+
@config_file_external_dir = []
|
189
|
+
@default_external_dir = []
|
161
190
|
@fact_groups = {}
|
162
|
-
@block_list =
|
191
|
+
@block_list = []
|
192
|
+
@color = true
|
193
|
+
@trace = false
|
163
194
|
@timing = false
|
195
|
+
@external_dir = []
|
196
|
+
@custom_dir = []
|
164
197
|
end
|
165
198
|
|
166
199
|
def fallback_external_dir
|