facter 4.0.39 → 4.0.44

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/bin/facter +3 -4
  3. data/lib/facter.rb +107 -28
  4. data/lib/facter/config.rb +354 -0
  5. data/lib/facter/custom_facts/core/aggregate.rb +51 -17
  6. data/lib/facter/custom_facts/core/execution.rb +27 -35
  7. data/lib/facter/custom_facts/core/execution/base.rb +13 -7
  8. data/lib/facter/custom_facts/util/directory_loader.rb +1 -1
  9. data/lib/facter/custom_facts/util/fact.rb +1 -1
  10. data/lib/facter/custom_facts/util/resolution.rb +40 -11
  11. data/lib/facter/facts/aix/disks.rb +1 -1
  12. data/lib/facter/facts/linux/ec2_metadata.rb +5 -29
  13. data/lib/facter/facts/linux/ec2_userdata.rb +5 -27
  14. data/lib/facter/facts/linux/is_virtual.rb +7 -46
  15. data/lib/facter/facts/linux/virtual.rb +3 -58
  16. data/lib/facter/facts/rhel/os/release.rb +1 -1
  17. data/lib/facter/facts/solaris/disks.rb +1 -1
  18. data/lib/facter/facts/solaris/zones.rb +1 -1
  19. data/lib/facter/facts_utils/virtual_detector.rb +78 -0
  20. data/lib/facter/framework/benchmarking/timer.rb +4 -2
  21. data/lib/facter/framework/cli/cli.rb +83 -36
  22. data/lib/facter/framework/cli/cli_launcher.rb +34 -38
  23. data/lib/facter/framework/config/fact_groups.rb +41 -7
  24. data/lib/facter/framework/core/cache_manager.rb +43 -23
  25. data/lib/facter/framework/core/fact_loaders/fact_loader.rb +14 -11
  26. data/lib/facter/framework/core/options/config_file_options.rb +5 -3
  27. data/lib/facter/framework/core/options/option_store.rb +60 -27
  28. data/lib/facter/framework/detector/os_hierarchy.rb +5 -9
  29. data/lib/facter/framework/logging/logger.rb +1 -5
  30. data/lib/facter/resolvers/aix/architecture_resolver.rb +15 -1
  31. data/lib/facter/resolvers/aix/os_level.rb +1 -1
  32. data/lib/facter/resolvers/augeas_resolver.rb +7 -1
  33. data/lib/facter/resolvers/bsd/processors.rb +11 -7
  34. data/lib/facter/resolvers/disk_resolver.rb +11 -3
  35. data/lib/facter/resolvers/dmi_decode.rb +1 -0
  36. data/lib/facter/resolvers/dmi_resolver.rb +2 -2
  37. data/lib/facter/resolvers/freebsd/geom_resolver.rb +12 -20
  38. data/lib/facter/resolvers/freebsd/processors.rb +11 -7
  39. data/lib/facter/resolvers/memory_resolver.rb +12 -14
  40. data/lib/facter/resolvers/mountpoints_resolver.rb +50 -22
  41. data/lib/facter/resolvers/networking_linux_resolver.rb +10 -5
  42. data/lib/facter/resolvers/partitions.rb +60 -57
  43. data/lib/facter/resolvers/processors_resolver.rb +5 -1
  44. data/lib/facter/resolvers/solaris/dmi.rb +2 -0
  45. data/lib/facter/resolvers/solaris/mountpoints.rb +60 -0
  46. data/lib/facter/resolvers/solaris/networking.rb +1 -2
  47. data/lib/facter/resolvers/solaris/os_release.rb +4 -3
  48. data/lib/facter/resolvers/ssh_resolver.rb +4 -4
  49. data/lib/facter/version.rb +1 -1
  50. metadata +5 -4
  51. data/lib/facter/fact_groups.conf +0 -308
  52. 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
- def initialize(args)
12
- @args = args
13
- end
14
-
15
- def validate_options
16
- Facter::OptionsValidator.validate(@args)
17
- end
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
- def prepare_arguments
20
- @args.unshift(Facter::Cli.default_task) unless
21
- check_if_arguments_is_known(Facter::Cli.all_tasks, @args) ||
22
- check_if_arguments_is_known(Facter::Cli.instance_variable_get(:@map), @args)
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
- @args = reorder_program_arguments(@args)
25
- end
28
+ private
26
29
 
27
- def start
28
- Facter::Cli.start(@args, debug: true)
29
- rescue Thor::UnknownArgumentError => e
30
- Facter::OptionsValidator.write_error_and_exit("unrecognised option '#{e.unknown.first}'")
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
- def check_if_arguments_is_known(known_arguments, program_arguments)
36
- program_arguments.each do |argument|
37
- return true if known_arguments.key?(argument)
35
+ false
38
36
  end
39
37
 
40
- false
41
- end
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
- priority_args = []
47
- normal_args = []
41
+ priority_args = []
42
+ normal_args = []
48
43
 
49
- program_arguments.each do |argument|
50
- if priority_arguments.include?(argument)
51
- priority_args << argument
52
- else
53
- normal_args << argument
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
- priority_args.concat(normal_args)
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(group_list_path = nil)
12
- default_path = File.join(File.dirname(__FILE__), '../../fact_groups.conf')
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 group_cached?(group_name)
44
- cached = @fact_groups.get_group_ttls(group_name) ? true : false
45
- delete_cache(group_name) unless cached
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
- group_name = if searched_fact.file
53
- searched_fact.name
54
- else
55
- @fact_groups.get_fact_group(searched_fact.name)
56
- end
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 group_name
65
+ return unless fact_cache_enabled?(fact_name)
59
66
 
60
- return unless group_cached?(group_name)
67
+ fact = @fact_groups.get_fact(fact_name)
61
68
 
62
- return unless check_ttls?(group_name)
69
+ return unless fact
63
70
 
64
- data = read_group_json(group_name)
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 #{group_name} facts")
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
- group_name = if fact.file
90
- File.basename(fact.file)
91
- else
92
- @fact_groups.get_fact_group(fact.name)
93
- end
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 group_cached?(group_name)
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
- @facts
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
- @internal_facts = @internal_loader.facts
39
+ internal_facts = @internal_loader.facts
38
40
  else
39
41
  @log.debug('Load only core facts')
40
- @internal_facts = @internal_loader.core_facts
42
+ internal_facts = @internal_loader.core_facts
41
43
  end
42
44
 
43
- @internal_facts = block_facts(@internal_facts, options)
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
- @external_facts.concat(@external_fact_loader.custom_facts)
54
+ external_facts += @external_fact_loader.custom_facts
52
55
  end
53
56
 
54
- @external_facts = block_facts(@external_facts, options)
57
+ external_facts = block_facts(external_facts, options)
55
58
 
56
59
  if options[:external_facts]
57
60
  @log.debug('Loading external facts')
58
- @external_facts.concat(@external_fact_loader.external_facts)
61
+ external_facts += @external_fact_loader.external_facts
59
62
  end
60
63
 
61
- @facts.concat(@external_facts)
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
- @options[:custom_facts] = !file_global_conf['no-custom-facts'] unless file_global_conf['no-custom-facts'].nil?
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[:external_facts] = !global_conf['no-external-facts'] unless global_conf['no-external-facts'].nil?
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[:ruby] = global_conf['no-ruby'].nil? ? true : !global_conf['no-ruby']
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
- @custom_dir = []
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
- @color = false
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, :ruby,
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, :haml, :external_facts,
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 ruby=(bool)
49
- if bool == true
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 custom_facts=(bool)
103
- if bool == true
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
- @cli = nil
171
+ @json = false
149
172
  @cache = true
150
- @trace = false
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