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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/bin/facter +3 -4
  3. data/lib/facter.rb +163 -23
  4. data/lib/facter/custom_facts/core/execution/base.rb +42 -6
  5. data/lib/facter/custom_facts/util/directory_loader.rb +1 -1
  6. data/lib/facter/facts/aix/disks.rb +1 -1
  7. data/lib/facter/facts/aix/kernel.rb +1 -1
  8. data/lib/facter/facts/aix/kernelmajversion.rb +1 -1
  9. data/lib/facter/facts/aix/kernelrelease.rb +1 -1
  10. data/lib/facter/facts/aix/kernelversion.rb +1 -1
  11. data/lib/facter/facts/aix/os/release.rb +1 -1
  12. data/lib/facter/facts/linux/cloud.rb +15 -0
  13. data/lib/facter/facts/linux/disks.rb +1 -1
  14. data/lib/facter/facts/linux/ec2_metadata.rb +5 -27
  15. data/lib/facter/facts/linux/ec2_userdata.rb +5 -27
  16. data/lib/facter/facts/linux/is_virtual.rb +7 -46
  17. data/lib/facter/facts/linux/virtual.rb +3 -58
  18. data/lib/facter/facts/rhel/os/release.rb +2 -2
  19. data/lib/facter/facts/solaris/disks.rb +1 -1
  20. data/lib/facter/facts_utils/virtual_detector.rb +78 -0
  21. data/lib/facter/framework/cli/cli.rb +84 -36
  22. data/lib/facter/framework/cli/cli_launcher.rb +34 -38
  23. data/lib/facter/framework/config/fact_groups.rb +36 -2
  24. data/lib/facter/framework/core/cache_manager.rb +40 -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 +27 -10
  28. data/lib/facter/framework/logging/logger.rb +3 -11
  29. data/lib/facter/patches/sysfilesystem/sys/statvfs.rb +92 -0
  30. data/lib/facter/resolvers/aix/os_level.rb +27 -0
  31. data/lib/facter/resolvers/cloud.rb +39 -0
  32. data/lib/facter/resolvers/dmi_decode.rb +1 -0
  33. data/lib/facter/resolvers/memory_resolver.rb +12 -14
  34. data/lib/facter/resolvers/networking_linux_resolver.rb +0 -1
  35. data/lib/facter/resolvers/utils/filesystem_helper.rb +3 -1
  36. data/lib/facter/version.rb +1 -1
  37. metadata +7 -4
  38. data/lib/facter/resolvers/aix/os_level_resolver.rb +0 -25
  39. data/lib/facter/resolvers/os_level_resolver.rb +0 -28
@@ -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
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Facter
4
4
  class FactGroups
5
- attr_reader :groups, :block_list
5
+ attr_reader :groups, :block_list, :facts_ttls
6
6
 
7
7
  @groups_ttls = []
8
8
 
@@ -14,6 +14,10 @@ module Facter
14
14
  @groups ||= File.readable?(@groups_file_path) ? Hocon.load(@groups_file_path) : {}
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
94
  @block_list = config.block_list || {}
61
- @groups_ttls = config.ttls || {}
95
+ @groups_ttls = config.ttls || []
62
96
  @groups.merge!(config.fact_groups) if config.fact_groups
63
97
  end
64
98
 
@@ -40,31 +40,44 @@ 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 = read_group_json(fact_group)
65
78
  return unless data
66
79
 
67
- @log.debug("loading cached values for #{group_name} facts")
80
+ @log.debug("loading cached values for #{searched_fact.name} facts")
68
81
 
69
82
  create_facts(searched_fact, data)
70
83
  end
@@ -86,14 +99,17 @@ module Facter
86
99
  end
87
100
 
88
101
  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
102
+ fact_name = if fact.file
103
+ File.basename(fact.file)
104
+ else
105
+ fact.name
106
+ end
107
+
108
+ group_name = @fact_groups.get_fact_group(fact_name)
109
+
94
110
  return if !group_name || fact.value.nil?
95
111
 
96
- return unless group_cached?(group_name)
112
+ return unless fact_cache_enabled?(fact_name)
97
113
 
98
114
  @groups[group_name] ||= {}
99
115
  @groups[group_name][fact.name] = fact.value
@@ -106,10 +122,12 @@ module Facter
106
122
  end
107
123
 
108
124
  @groups.each do |group_name, data|
109
- next unless check_ttls?(group_name)
125
+ next unless check_ttls?(group_name, @fact_groups.get_group_ttls(group_name))
110
126
 
111
- @log.debug("caching values for #{group_name} facts")
112
127
  cache_file_name = File.join(@cache_dir, group_name)
128
+ next if File.readable?(cache_file_name)
129
+
130
+ @log.debug("caching values for #{group_name} facts")
113
131
  File.write(cache_file_name, JSON.pretty_generate(data))
114
132
  end
115
133
  end
@@ -128,8 +146,7 @@ module Facter
128
146
  @groups[group_name] = data
129
147
  end
130
148
 
131
- def check_ttls?(group_name)
132
- ttls = @fact_groups.get_group_ttls(group_name)
149
+ def check_ttls?(group_name, ttls)
133
150
  return false unless ttls
134
151
 
135
152
  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)
@@ -22,14 +22,14 @@ module Facter
22
22
  @user_query = []
23
23
  @block_list = {}
24
24
  @fact_groups = {}
25
- @color = false
25
+ @color = true
26
26
  @timing = false
27
27
 
28
28
  class << self
29
- attr_reader :debug, :verbose, :log_level, :show_legacy, :ruby,
30
- :custom_facts, :blocked_facts
29
+ attr_reader :debug, :verbose, :log_level, :show_legacy,
30
+ :custom_facts, :blocked_facts, :ruby, :external_facts
31
31
 
32
- attr_accessor :config, :user_query, :strict, :json, :haml, :external_facts,
32
+ attr_accessor :config, :user_query, :strict, :json, :haml,
33
33
  :cache, :yaml, :puppet, :ttls, :block, :cli, :config_file_custom_dir,
34
34
  :config_file_external_dir, :default_external_dir, :fact_groups,
35
35
  :block_list, :color, :trace, :timing
@@ -45,16 +45,28 @@ module Facter
45
45
  options
46
46
  end
47
47
 
48
- def ruby=(bool)
49
- if bool == true
50
- @ruby = true
51
- else
48
+ def no_ruby=(bool)
49
+ if bool
52
50
  @ruby = false
53
51
  @custom_facts = false
54
52
  @blocked_facts << 'ruby'
53
+ else
54
+ @ruby = true
55
55
  end
56
56
  end
57
57
 
58
+ def no_block=(bool)
59
+ @block = !bool
60
+ end
61
+
62
+ def no_cache=(bool)
63
+ @cache = !bool
64
+ end
65
+
66
+ def no_color=(bool)
67
+ @color = !bool
68
+ end
69
+
58
70
  def external_dir
59
71
  return fallback_external_dir if @external_dir.empty? && @external_facts
60
72
 
@@ -99,8 +111,8 @@ module Facter
99
111
  end
100
112
  end
101
113
 
102
- def custom_facts=(bool)
103
- if bool == true
114
+ def no_custom_facts=(bool)
115
+ if bool == false
104
116
  @custom_facts = true
105
117
  @ruby = true
106
118
  else
@@ -108,6 +120,10 @@ module Facter
108
120
  end
109
121
  end
110
122
 
123
+ def no_external_facts=(bool)
124
+ @external_facts = !bool
125
+ end
126
+
111
127
  def log_level=(level)
112
128
  level = level.to_sym
113
129
  case level
@@ -156,6 +172,7 @@ module Facter
156
172
  @custom_facts = true
157
173
  @external_dir = []
158
174
  @default_external_dir = []
175
+ @config_file_external_dir = []
159
176
  @external_facts = true
160
177
  @blocked_facts = []
161
178
  @fact_groups = {}
@@ -60,9 +60,7 @@ module Facter
60
60
  def debug(msg)
61
61
  return unless debugging_active?
62
62
 
63
- if msg.nil? || msg.empty?
64
- empty_message_error(msg)
65
- elsif @@message_callback
63
+ if @@message_callback
66
64
  @@message_callback.call(:debug, msg)
67
65
  else
68
66
  msg = colorize(msg, CYAN) if Options[:color]
@@ -82,9 +80,7 @@ module Facter
82
80
  end
83
81
 
84
82
  def warn(msg)
85
- if msg.nil? || msg.empty?
86
- empty_message_error(msg)
87
- elsif @@message_callback
83
+ if @@message_callback
88
84
  @@message_callback.call(:warn, msg)
89
85
  else
90
86
  msg = colorize(msg, YELLOW) if Options[:color]
@@ -95,9 +91,7 @@ module Facter
95
91
  def error(msg, colorize = false)
96
92
  @@has_errors = true
97
93
 
98
- if msg.nil? || msg.empty?
99
- empty_message_error(msg)
100
- elsif @@message_callback
94
+ if @@message_callback
101
95
  @@message_callback.call(:error, msg)
102
96
  else
103
97
  msg = colorize(msg, RED) if colorize || Options[:color]
@@ -115,8 +109,6 @@ module Facter
115
109
  private
116
110
 
117
111
  def colorize(msg, color)
118
- return msg if OsDetector.instance.identifier.eql?(:windows)
119
-
120
112
  "#{color}#{msg}#{RESET}"
121
113
  end
122
114