facter 4.2.1 → 4.2.5

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +202 -0
  3. data/lib/facter/custom_facts/core/execution/base.rb +14 -9
  4. data/lib/facter/custom_facts/core/execution.rb +25 -17
  5. data/lib/facter/custom_facts/core/file_loader.rb +0 -1
  6. data/lib/facter/custom_facts/core/legacy_facter.rb +0 -2
  7. data/lib/facter/custom_facts/core/resolvable.rb +1 -1
  8. data/lib/facter/custom_facts/util/collection.rb +6 -4
  9. data/lib/facter/custom_facts/util/confine.rb +9 -3
  10. data/lib/facter/custom_facts/util/directory_loader.rb +18 -6
  11. data/lib/facter/custom_facts/util/fact.rb +12 -10
  12. data/lib/facter/custom_facts/util/loader.rb +7 -3
  13. data/lib/facter/custom_facts/util/parser.rb +8 -2
  14. data/lib/facter/custom_facts/util/resolution.rb +5 -1
  15. data/lib/facter/facts/windows/os/windows/display_version.rb +19 -0
  16. data/lib/facter/framework/cli/cli.rb +4 -0
  17. data/lib/facter/framework/core/fact/internal/internal_fact_manager.rb +0 -2
  18. data/lib/facter/framework/core/fact_loaders/fact_loader.rb +0 -1
  19. data/lib/facter/framework/core/fact_manager.rb +14 -1
  20. data/lib/facter/framework/core/options/option_store.rb +3 -1
  21. data/lib/facter/framework/logging/logger.rb +61 -0
  22. data/lib/facter/framework/parsers/query_parser.rb +1 -4
  23. data/lib/facter/models/resolved_fact.rb +4 -0
  24. data/lib/facter/resolvers/aix/disks.rb +1 -1
  25. data/lib/facter/resolvers/aix/mountpoints.rb +1 -1
  26. data/lib/facter/resolvers/aix/partitions.rb +1 -1
  27. data/lib/facter/resolvers/aix/processors.rb +2 -1
  28. data/lib/facter/resolvers/linux/networking.rb +0 -1
  29. data/lib/facter/resolvers/lsb_release.rb +1 -2
  30. data/lib/facter/resolvers/macosx/{processor.rb → processors.rb} +21 -21
  31. data/lib/facter/resolvers/networking.rb +3 -1
  32. data/lib/facter/resolvers/os_release.rb +7 -4
  33. data/lib/facter/resolvers/partitions.rb +1 -3
  34. data/lib/facter/resolvers/windows/product_release.rb +13 -4
  35. data/lib/facter/util/aix/info_extractor.rb +60 -9
  36. data/lib/facter/util/facts/windows_release_finder.rb +4 -2
  37. data/lib/facter/util/linux/dhcp.rb +4 -1
  38. data/lib/facter/util/linux/socket_parser.rb +17 -2
  39. data/lib/facter/util/resolvers/http.rb +3 -0
  40. data/lib/facter/version.rb +1 -1
  41. data/lib/facter.rb +31 -18
  42. metadata +12 -5
  43. data/lib/facter/custom_facts/core/logging.rb +0 -203
@@ -91,7 +91,7 @@ module Facter
91
91
  msg = "Already evaluated #{@name}"
92
92
  msg << " at #{@last_evaluated}" if msg.is_a? String
93
93
  msg << ', reevaluating anyways'
94
- LegacyFacter.warn msg
94
+ log.warn msg
95
95
  end
96
96
 
97
97
  instance_eval(&block)
@@ -171,6 +171,10 @@ module Facter
171
171
 
172
172
  private
173
173
 
174
+ def log
175
+ @log ||= Facter::Log.new(self)
176
+ end
177
+
174
178
  # If the weights are equal, we consider external facts greater tan custom facts
175
179
  def compare_equal_weights(other)
176
180
  # Other is considered greater because self is custom fact and other is external
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Windows
5
+ module Os
6
+ module Windows
7
+ class DisplayVersion
8
+ FACT_NAME = 'os.windows.display_version'
9
+
10
+ def call_the_resolver
11
+ fact_value = Facter::Resolvers::ProductRelease.resolve(:display_version)
12
+
13
+ Facter::ResolvedFact.new(FACT_NAME, fact_value)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -97,6 +97,10 @@ module Facter
97
97
  type: :boolean,
98
98
  desc: 'Resolve facts sequentially'
99
99
 
100
+ class_option :http_debug,
101
+ type: :boolean,
102
+ desc: 'Whether to write HTTP request and responses to stderr. This should never be used in production.'
103
+
100
104
  class_option :puppet,
101
105
  type: :boolean,
102
106
  aliases: '-p',
@@ -11,10 +11,8 @@ module Facter
11
11
  def resolve_facts(searched_facts)
12
12
  internal_searched_facts = filter_internal_facts(searched_facts)
13
13
  resolved_facts = if Options[:sequential]
14
- log.debug('Resolving facts sequentially')
15
14
  resolve_sequentially(internal_searched_facts)
16
15
  else
17
- log.debug('Resolving fact in parallel')
18
16
  resolve_in_parallel(internal_searched_facts)
19
17
  end
20
18
 
@@ -29,7 +29,6 @@ module Facter
29
29
  end
30
30
 
31
31
  def load_internal_facts(user_query, options)
32
- @log.debug('Loading internal facts')
33
32
  internal_facts = []
34
33
  if user_query || options[:show_legacy]
35
34
  # if we have a user query, then we must search in core facts and legacy facts
@@ -13,6 +13,7 @@ module Facter
13
13
  end
14
14
 
15
15
  def resolve_facts(user_query = [])
16
+ log_resolving_method
16
17
  @options[:user_query] = user_query
17
18
  cache_manager = Facter::CacheManager.new
18
19
 
@@ -40,6 +41,7 @@ module Facter
40
41
  # - load all the core facts, external facts and env facts
41
42
  # - load all custom facts
42
43
  def resolve_fact(user_query)
44
+ log_resolving_method
43
45
  @options[:user_query] = user_query
44
46
  @log.debug("resolving fact with user_query: #{user_query}")
45
47
 
@@ -49,7 +51,9 @@ module Facter
49
51
  core_and_external_facts = core_or_external_fact(user_query) || []
50
52
  resolved_facts = core_and_external_facts + custom_facts
51
53
 
52
- resolved_facts = all_custom_facts(user_query) if resolved_facts.empty?
54
+ if resolved_facts.empty? || resolved_facts.none? { |rf| rf.resolves?(user_query) }
55
+ resolved_facts.concat(all_custom_facts(user_query))
56
+ end
53
57
 
54
58
  @cache_manager.cache_facts(resolved_facts)
55
59
 
@@ -58,12 +62,21 @@ module Facter
58
62
  end
59
63
 
60
64
  def resolve_core(user_query = [], options = {})
65
+ log_resolving_method
61
66
  @cache_manager = CacheManager.new
62
67
  core_fact(user_query, options)
63
68
  end
64
69
 
65
70
  private
66
71
 
72
+ def log_resolving_method
73
+ if Options[:sequential]
74
+ @log.debugonce('Resolving facts sequentially')
75
+ else
76
+ @log.debugonce('Resolving fact in parallel')
77
+ end
78
+ end
79
+
67
80
  def core_fact(user_query, options)
68
81
  loaded_facts_hash = @fact_loader.load_internal_facts(user_query, options)
69
82
 
@@ -36,6 +36,7 @@ module Facter
36
36
  @hocon = false
37
37
  @allow_external_loggers = true
38
38
  @force_dot_resolution = false
39
+ @http_debug = false
39
40
 
40
41
  class << self
41
42
  attr_reader :debug, :verbose, :log_level, :show_legacy,
@@ -44,7 +45,7 @@ module Facter
44
45
  attr_accessor :config, :strict, :json,
45
46
  :cache, :yaml, :puppet, :ttls, :block, :cli, :config_file_custom_dir,
46
47
  :config_file_external_dir, :default_external_dir, :fact_groups, :force_dot_resolution,
47
- :block_list, :color, :trace, :sequential, :timing, :hocon, :allow_external_loggers
48
+ :block_list, :color, :trace, :sequential, :timing, :hocon, :allow_external_loggers, :http_debug
48
49
 
49
50
  attr_writer :external_dir
50
51
 
@@ -179,6 +180,7 @@ module Facter
179
180
  @ttls = []
180
181
  @block = true
181
182
  @cli = nil
183
+ @http_debug = false
182
184
  reset_config
183
185
  end
184
186
 
@@ -15,8 +15,16 @@ module Facter
15
15
  @@logger = nil
16
16
  @@message_callback = nil
17
17
  @@has_errors = false
18
+ @@debug_messages = []
19
+ @@warn_messages = []
20
+ @@timing = false
18
21
 
19
22
  class << self
23
+ def clear_messages
24
+ @@debug_messages.clear
25
+ @@warn_messages.clear
26
+ end
27
+
20
28
  def on_message(&block)
21
29
  @@message_callback = block
22
30
  end
@@ -47,6 +55,41 @@ module Facter
47
55
  "[#{datetime}] #{severity} #{msg} \n"
48
56
  end
49
57
  end
58
+
59
+ # Print an exception message, and optionally a backtrace if trace is set
60
+
61
+ # Print timing information
62
+ #
63
+ # @param string [String] the time to print
64
+ # @return [void]
65
+ #
66
+ # @api private
67
+ def show_time(string)
68
+ return unless string && timing?
69
+
70
+ if @@message_callback
71
+ @@message_callback.call(:info, string)
72
+ else
73
+ warn("#{GREEN}#{string}#{RESET}")
74
+ end
75
+ end
76
+
77
+ # Enable or disable logging of timing information
78
+ #
79
+ # @param bool [true, false]
80
+ # @return [void]
81
+ #
82
+ # @api private
83
+ def timing(bool)
84
+ @@timing = bool
85
+ end
86
+
87
+ # Returns whether timing output is turned on
88
+ #
89
+ # @api private
90
+ def timing?
91
+ @@timing
92
+ end
50
93
  end
51
94
 
52
95
  def initialize(logged_class)
@@ -68,6 +111,16 @@ module Facter
68
111
  end
69
112
  end
70
113
 
114
+ def debugonce(msg)
115
+ return unless debugging_active?
116
+
117
+ message_string = msg.to_s
118
+ return if @@debug_messages.include? message_string
119
+
120
+ @@debug_messages << message_string
121
+ debug(message_string)
122
+ end
123
+
71
124
  def info(msg)
72
125
  if msg.nil? || msg.empty?
73
126
  empty_message_error(msg)
@@ -88,6 +141,14 @@ module Facter
88
141
  end
89
142
  end
90
143
 
144
+ def warnonce(message)
145
+ message_string = message.to_s
146
+ return if @@warn_messages.include? message_string
147
+
148
+ @@warn_messages << message_string
149
+ warn(message_string)
150
+ end
151
+
91
152
  def error(msg, colorize = false)
92
153
  @@has_errors = true
93
154
 
@@ -24,13 +24,11 @@ module Facter
24
24
  # Returns a list of SearchedFact objects that resolve the users query.
25
25
  def parse(query_list, loaded_fact)
26
26
  matched_facts = []
27
- @log.debug "User query is: #{query_list}"
28
27
  @query_list = query_list
29
28
 
30
29
  return no_user_query(loaded_fact) unless query_list.any?
31
30
 
32
31
  query_list.each do |query|
33
- @log.debug "Query is #{query}"
34
32
  found_facts = search_for_facts(query, loaded_fact)
35
33
  matched_facts << found_facts
36
34
  end
@@ -65,7 +63,6 @@ module Facter
65
63
  end
66
64
 
67
65
  def get_facts_matching_tokens(query_tokens, query_token_range, loaded_fact_hash)
68
- @log.debug "Checking query tokens #{query_tokens[query_token_range].join('.')}"
69
66
  resolvable_fact_list = []
70
67
 
71
68
  loaded_fact_hash.each do |loaded_fact|
@@ -77,7 +74,7 @@ module Facter
77
74
  resolvable_fact_list << searched_fact
78
75
  end
79
76
 
80
- @log.debug "List of resolvable facts: #{resolvable_fact_list.inspect}"
77
+ @log.debug "List of resolvable facts: #{resolvable_fact_list.inspect}" if resolvable_fact_list.any?
81
78
  resolvable_fact_list
82
79
  end
83
80
 
@@ -23,5 +23,9 @@ module Facter
23
23
  def to_s
24
24
  @value.to_s
25
25
  end
26
+
27
+ def resolves?(user_query)
28
+ @name == user_query
29
+ end
26
30
  end
27
31
  end
@@ -34,7 +34,7 @@ module Facter
34
34
 
35
35
  return if stdout.empty?
36
36
 
37
- info_size = Facter::Util::Aix::InfoExtractor.extract(stdout, /PP SIZE:|TOTAL PPs:|FREE PPs:|PV STATE:/)
37
+ info_size = Facter::Util::Aix::InfoExtractor.extract(stdout, :lspv)
38
38
 
39
39
  return unless info_size['PV STATE']
40
40
 
@@ -19,7 +19,7 @@ module Facter
19
19
  @fact_list[:mountpoints] = {}
20
20
  output = Facter::Core::Execution.execute('mount', logger: log)
21
21
  output.split("\n").map do |line|
22
- next if line =~ /node|---|procfs|ahafs/
22
+ next if line =~ /\s+node\s+|---|procfs|ahafs/
23
23
 
24
24
  elem = line.split("\s")
25
25
 
@@ -40,7 +40,7 @@ module Facter
40
40
 
41
41
  return if stdout.empty?
42
42
 
43
- info_hash = Facter::Util::Aix::InfoExtractor.extract(stdout, /PPs:|PP SIZE|TYPE:|LABEL:|MOUNT/)
43
+ info_hash = Facter::Util::Aix::InfoExtractor.extract(stdout, :lslv)
44
44
  size_bytes = compute_size(info_hash)
45
45
 
46
46
  part_info = {
@@ -42,8 +42,9 @@ module Facter
42
42
  return unless result
43
43
 
44
44
  names = retrieve_from_array(result.scan(/name\s=\s.*/), 1)
45
+ status = retrieve_from_array(result.scan(/\s+status\s=\s.*/), 1)
45
46
 
46
- names.each { |elem| query_cuat(elem) }
47
+ names.each_with_index { |elem, idx| query_cuat(elem) if status[idx] == '1' }
47
48
  end
48
49
 
49
50
  def query_cuat(name)
@@ -44,7 +44,6 @@ module Facter
44
44
 
45
45
  parse_ip_command_line(line, mtu_and_indexes)
46
46
  end
47
- log.debug("Associated MTU and index in ip command: #{mtu_and_indexes}")
48
47
  mtu_and_indexes
49
48
  end
50
49
 
@@ -25,8 +25,7 @@ module Facter
25
25
  end
26
26
 
27
27
  def lsb_release_installed?
28
- output = Facter::Core::Execution.execute('which lsb_release', logger: log)
29
- @fact_list[:lsb_release_installed] = !output.empty?
28
+ @fact_list[:lsb_release_installed] = !Facter::Core::Execution.which('lsb_release').nil?
30
29
  end
31
30
 
32
31
  def read_lsb_release_file
@@ -29,42 +29,42 @@ module Facter
29
29
 
30
30
  def read_processor_data(fact_name)
31
31
  output = Facter::Core::Execution.execute("sysctl #{ITEMS.values.join(' ')}", logger: log)
32
- build_fact_list(output.split("\n"))
32
+ processors_hash = Hash[*output.split("\n").collect { |v| [v.split(': ')[0], v.split(': ')[1]] }.flatten]
33
+ build_fact_list(processors_hash)
33
34
  @fact_list[fact_name]
34
35
  end
35
36
 
36
- def build_fact_list(processors_data)
37
- build_logical_count(processors_data[0])
38
- build_physical_count(processors_data[1])
39
- build_models(processors_data[2])
40
- build_speed(processors_data[3])
41
- build_cores_per_socket(processors_data[4])
42
- build_threads_per_core(processors_data[5], processors_data[4])
37
+ def build_fact_list(hash)
38
+ build_logical_count(hash)
39
+ build_physical_count(hash)
40
+ build_models(hash)
41
+ build_speed(hash)
42
+ build_cores_per_socket(hash)
43
+ build_threads_per_core(hash)
43
44
  end
44
45
 
45
- def build_logical_count(count)
46
- @fact_list[:logicalcount] = count.split(': ')[1].to_i
46
+ def build_logical_count(hash)
47
+ @fact_list[:logicalcount] = hash[ITEMS[:logical_count]].to_i
47
48
  end
48
49
 
49
- def build_physical_count(count)
50
- @fact_list[:physicalcount] = count.split(': ')[1].to_i
50
+ def build_physical_count(hash)
51
+ @fact_list[:physicalcount] = hash[ITEMS[:physical_count]].to_i
51
52
  end
52
53
 
53
- def build_models(model)
54
- brand = model.split(': ').fetch(1)
55
- @fact_list[:models] = Array.new(@fact_list[:logicalcount].to_i, brand)
54
+ def build_models(hash)
55
+ @fact_list[:models] = Array.new(@fact_list[:logicalcount].to_i, hash[ITEMS[:brand]])
56
56
  end
57
57
 
58
- def build_speed(value)
59
- @fact_list[:speed] = value.split(': ')[1].to_i
58
+ def build_speed(hash)
59
+ @fact_list[:speed] = hash[ITEMS[:speed]].to_i
60
60
  end
61
61
 
62
- def build_cores_per_socket(count)
63
- @fact_list[:cores_per_socket] = count.split(': ')[1].to_i
62
+ def build_cores_per_socket(hash)
63
+ @fact_list[:cores_per_socket] = hash[ITEMS[:cores_per_socket]].to_i
64
64
  end
65
65
 
66
- def build_threads_per_core(number_of_threads, number_of_cores)
67
- @fact_list[:threads_per_core] = number_of_threads.split(': ')[1].to_i / number_of_cores.split(': ')[1].to_i
66
+ def build_threads_per_core(hash)
67
+ @fact_list[:threads_per_core] = hash[ITEMS[:threads_per_core]].to_i / hash[ITEMS[:cores_per_socket]].to_i
68
68
  end
69
69
  end
70
70
  end
@@ -37,7 +37,9 @@ module Facter
37
37
 
38
38
  def clean_up_interfaces_response(response)
39
39
  # convert ip ranges into single ip. eg. 10.16.132.213 --> 10.16.132.213 is converted to 10.16.132.213
40
- response.gsub!(/(\d+(\.\d+)*)\s+-->\s+\d+(\.\d+)*/, '\\1')
40
+ # convert ip6 ranges into single ip. eg. 2001:db8:cafe::132:213 -->
41
+ # 2001:db8:cafe::132:213 is converted to 2001:db8:cafe::132:213
42
+ response.gsub!(/([\da-fA-F]+([\.:]+[\da-fA-F]+)*)\s+-->\s+[\da-fA-F]+([\.:]+[\da-fA-F]+)*/, '\\1')
41
43
  end
42
44
 
43
45
  def parse_interfaces_response(response)
@@ -53,12 +53,15 @@ module Facter
53
53
  end
54
54
 
55
55
  def process_name
56
- return unless @fact_list[:name]
56
+ os_name = @fact_list[:name]
57
+ return unless os_name
57
58
 
58
- @fact_list[:name] = if @fact_list[:name].downcase.start_with?('red', 'oracle')
59
- @fact_list[:name].split(' ')[0..1].join
59
+ @fact_list[:name] = if os_name.downcase.start_with?('red', 'oracle', 'arch', 'manjaro')
60
+ os_name = os_name.split(' ')[0..1].join
61
+ os_name = os_name.capitalize if os_name.downcase.start_with?('arch', 'manjaro')
62
+ os_name
60
63
  else
61
- @fact_list[:name].split(' ')[0].strip
64
+ os_name.split(' ')[0].strip
62
65
  end
63
66
  end
64
67
 
@@ -107,9 +107,7 @@ module Facter
107
107
 
108
108
  return blkid_and_lsblk[command_exists_key] unless blkid_and_lsblk[command_exists_key].nil?
109
109
 
110
- output = Facter::Core::Execution.execute("which #{command}", logger: log)
111
-
112
- blkid_and_lsblk[command_exists_key] = !output.empty?
110
+ blkid_and_lsblk[command_exists_key] = !Facter::Core::Execution.which(command).nil?
113
111
  end
114
112
 
115
113
  def execute_and_extract_blkid_info
@@ -24,10 +24,19 @@ module Facter
24
24
 
25
25
  def build_fact_list(reg)
26
26
  reg.each do |name, _value|
27
- @fact_list[:edition_id] = reg[name] if name == 'EditionID'
28
- @fact_list[:installation_type] = reg[name] if name == 'InstallationType'
29
- @fact_list[:product_name] = reg[name] if name == 'ProductName'
30
- @fact_list[:release_id] = reg[name] if name == 'ReleaseId'
27
+ case name
28
+ when 'EditionID'
29
+ @fact_list[:edition_id] = reg[name]
30
+ when 'InstallationType'
31
+ @fact_list[:installation_type] = reg[name]
32
+ when 'ProductName'
33
+ @fact_list[:product_name] = reg[name]
34
+ when 'DisplayVersion'
35
+ @fact_list[:release_id] = reg[name]
36
+ @fact_list[:display_version] = reg[name]
37
+ when 'ReleaseId'
38
+ @fact_list[:release_id] = reg[name] unless @fact_list[:release_id]
39
+ end
31
40
  end
32
41
  end
33
42
  end
@@ -6,17 +6,68 @@ module Facter
6
6
  module InfoExtractor
7
7
  MEGABYTES_EXPONENT = 1024**2
8
8
  GIGABYTES_EXPONENT = 1024**3
9
+ PROPERTIES = {
10
+ lslv: [
11
+ 'LOGICAL VOLUME:',
12
+ 'VOLUME GROUP:',
13
+ 'LV IDENTIFIER:',
14
+ 'PERMISSION:',
15
+ 'VG STATE:',
16
+ 'LV STATE:',
17
+ 'TYPE:',
18
+ 'WRITE VERIFY:',
19
+ 'MAX LPs:',
20
+ 'PP SIZE:',
21
+ 'COPIES:',
22
+ 'SCHED POLICY:',
23
+ 'LPs:',
24
+ 'PPs:',
25
+ 'STALE PPs:',
26
+ 'BB POLICY:',
27
+ 'INTER-POLICY:',
28
+ 'RELOCATABLE:',
29
+ 'INTRA-POLICY:',
30
+ 'UPPER BOUND:',
31
+ 'MOUNT POINT:',
32
+ 'LABEL:',
33
+ 'MIRROR WRITE CONSISTENCY:',
34
+ 'EACH LP COPY ON A SEPARATE PV ?:',
35
+ 'Serialize IO ?:'
36
+ ],
37
+ lspv: [
38
+ 'PHYSICAL VOLUME:',
39
+ 'VOLUME GROUP:',
40
+ 'PV IDENTIFIER:',
41
+ 'VG IDENTIFIER',
42
+ 'PV STATE:',
43
+ 'STALE PARTITIONS:',
44
+ 'ALLOCATABLE:',
45
+ 'PP SIZE:',
46
+ 'LOGICAL VOLUMES:',
47
+ 'TOTAL PPs:',
48
+ 'VG DESCRIPTORS:',
49
+ 'FREE PPs:',
50
+ 'HOT SPARE:',
51
+ 'USED PPs:',
52
+ 'MAX REQUEST:',
53
+ 'FREE DISTRIBUTION:',
54
+ 'USED DISTRIBUTION:',
55
+ 'MIRROR POOL:'
56
+ ]
57
+ }.freeze
9
58
 
10
- def self.extract(content, regex)
11
- content = content.each_line.map do |line|
12
- next unless regex =~ line
13
-
14
- line.split(/:\s*|\s{2,}/)
59
+ def self.extract(content, cmd)
60
+ property_hash = {}
61
+ properties = PROPERTIES[cmd]
62
+ properties.each do |property|
63
+ str = (properties - [property]).join('|')
64
+ matcher = content.match(/#{Regexp.escape(property)}([^\n]*?)(#{str}|\n|$)/s)
65
+ if matcher
66
+ value = matcher[1].strip
67
+ property_hash[property.split(':').first] = value
68
+ end
15
69
  end
16
-
17
- content.flatten!.reject!(&:nil?)
18
-
19
- Hash[*content]
70
+ property_hash
20
71
  end
21
72
  end
22
73
  end
@@ -23,9 +23,11 @@ module Facter
23
23
  private
24
24
 
25
25
  def check_version_10(consumerrel, kernel_version)
26
+ return '10' if consumerrel
27
+
26
28
  build_number = kernel_version[/([^.]*)$/].to_i
27
- if consumerrel
28
- '10'
29
+ if build_number >= 20_348
30
+ '2022'
29
31
  elsif build_number >= 17_623
30
32
  '2019'
31
33
  else
@@ -75,7 +75,10 @@ module Facter
75
75
  def search_with_dhcpcd_command(interface_name)
76
76
  @log.debug("Attempt to get DHCP for interface #{interface_name}, from dhcpcd command")
77
77
 
78
- output = Facter::Core::Execution.execute("dhcpcd -U #{interface_name}", logger: @log)
78
+ @dhcpcd_command ||= Facter::Core::Execution.which('dhcpcd')
79
+ return unless @dhcpcd_command
80
+
81
+ output = Facter::Core::Execution.execute("#{@dhcpcd_command} -U #{interface_name}", logger: @log)
79
82
  dhcp = output.match(/dhcp_server_identifier='(.*)'/)
80
83
  dhcp[1] if dhcp
81
84
  end
@@ -59,8 +59,23 @@ module Facter
59
59
  end
60
60
 
61
61
  def bond_master_of(interface_name)
62
- content = Facter::Core::Execution.execute("ip link show #{interface_name}", logger: @log)
63
- content.match(/master (\S*) /)&.captures&.first
62
+ content = get_ip_link_show_data(interface_name)
63
+ content&.match(/master (\S*) /)&.captures&.first
64
+ end
65
+
66
+ def get_ip_link_show_data(interface_name)
67
+ @ip_link_show_data ||= read_ip_link_show_data
68
+ @ip_link_show_data[interface_name]
69
+ end
70
+
71
+ def read_ip_link_show_data
72
+ ip_link_show_data = {}
73
+ output = Facter::Core::Execution.execute('ip -o link show', logger: @log)
74
+ output.each_line do |line|
75
+ interface_name = line.split(':')[1]&.strip if line
76
+ ip_link_show_data[interface_name] = line if interface_name
77
+ end
78
+ ip_link_show_data
64
79
  end
65
80
 
66
81
  def mac_from(ifaddr)
@@ -60,6 +60,9 @@ module Facter
60
60
  http = Net::HTTP.new(parsed_url.host)
61
61
  http.read_timeout = timeouts[:session] || SESSION_TIMEOUT
62
62
  http.open_timeout = timeouts[:connection] || CONNECTION_TIMEOUT
63
+
64
+ http.set_debug_output($stderr) if Options[:http_debug]
65
+
63
66
  http
64
67
  end
65
68
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Facter
4
- VERSION = '4.2.1' unless defined?(VERSION)
4
+ VERSION = '4.2.5' unless defined?(VERSION)
5
5
  end