facter 4.2.1 → 4.2.5

Sign up to get free protection for your applications and to get access to all the features.
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