facter 4.0.40 → 4.0.46

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/lib/facter.rb +72 -19
  3. data/lib/facter/config.rb +355 -0
  4. data/lib/facter/custom_facts/core/aggregate.rb +51 -17
  5. data/lib/facter/custom_facts/core/execution.rb +54 -38
  6. data/lib/facter/custom_facts/core/execution/base.rb +46 -40
  7. data/lib/facter/custom_facts/util/fact.rb +1 -1
  8. data/lib/facter/custom_facts/util/parser.rb +17 -3
  9. data/lib/facter/custom_facts/util/resolution.rb +40 -11
  10. data/lib/facter/facts/linux/ec2_metadata.rb +5 -30
  11. data/lib/facter/facts/linux/ec2_userdata.rb +5 -28
  12. data/lib/facter/facts/linux/is_virtual.rb +7 -46
  13. data/lib/facter/facts/linux/virtual.rb +3 -58
  14. data/lib/facter/facts/rhel/os/release.rb +1 -1
  15. data/lib/facter/facts/solaris/hypervisors/ldom.rb +3 -0
  16. data/lib/facter/facts/solaris/ldom.rb +4 -1
  17. data/lib/facter/facts/solaris/zones.rb +1 -1
  18. data/lib/facter/facts_utils/virtual_detector.rb +78 -0
  19. data/lib/facter/framework/benchmarking/timer.rb +4 -2
  20. data/lib/facter/framework/cli/cli.rb +19 -5
  21. data/lib/facter/framework/config/fact_groups.rb +10 -8
  22. data/lib/facter/framework/core/cache_manager.rb +78 -28
  23. data/lib/facter/framework/core/fact/internal/core_fact.rb +6 -1
  24. data/lib/facter/framework/core/fact/internal/internal_fact_manager.rb +38 -4
  25. data/lib/facter/framework/core/fact_augmenter.rb +1 -1
  26. data/lib/facter/framework/core/fact_loaders/fact_loader.rb +1 -1
  27. data/lib/facter/framework/core/fact_manager.rb +1 -1
  28. data/lib/facter/framework/core/options/config_file_options.rb +16 -5
  29. data/lib/facter/framework/core/options/option_store.rb +40 -20
  30. data/lib/facter/framework/detector/os_hierarchy.rb +5 -9
  31. data/lib/facter/resolvers/aio_agent_version.rb +1 -1
  32. data/lib/facter/resolvers/aix/architecture_resolver.rb +17 -2
  33. data/lib/facter/resolvers/aix/disks.rb +2 -1
  34. data/lib/facter/resolvers/aix/filesystem_resolver.rb +1 -1
  35. data/lib/facter/resolvers/aix/hardware_resolver.rb +2 -1
  36. data/lib/facter/resolvers/aix/load_averages_resolver.rb +2 -1
  37. data/lib/facter/resolvers/aix/memory.rb +2 -1
  38. data/lib/facter/resolvers/aix/mountpoints.rb +2 -1
  39. data/lib/facter/resolvers/aix/networking_resolver.rb +1 -1
  40. data/lib/facter/resolvers/aix/nim.rb +1 -1
  41. data/lib/facter/resolvers/aix/os_level.rb +2 -2
  42. data/lib/facter/resolvers/aix/partitions.rb +2 -1
  43. data/lib/facter/resolvers/aix/processors.rb +2 -1
  44. data/lib/facter/resolvers/aix/serialnumber.rb +1 -1
  45. data/lib/facter/resolvers/augeas_resolver.rb +8 -2
  46. data/lib/facter/resolvers/base_resolver.rb +11 -4
  47. data/lib/facter/resolvers/bsd/processors.rb +13 -8
  48. data/lib/facter/resolvers/cloud.rb +1 -1
  49. data/lib/facter/resolvers/containers.rb +2 -1
  50. data/lib/facter/resolvers/debian_version.rb +1 -1
  51. data/lib/facter/resolvers/disk_resolver.rb +15 -4
  52. data/lib/facter/resolvers/dmi_decode.rb +2 -1
  53. data/lib/facter/resolvers/dmi_resolver.rb +4 -3
  54. data/lib/facter/resolvers/ec2.rb +2 -1
  55. data/lib/facter/resolvers/eos_release_resolver.rb +1 -1
  56. data/lib/facter/resolvers/facterversion_resolver.rb +1 -1
  57. data/lib/facter/resolvers/filesystems_resolver.rb +4 -1
  58. data/lib/facter/resolvers/fips_enabled_resolver.rb +4 -1
  59. data/lib/facter/resolvers/freebsd/dmi_resolver.rb +1 -1
  60. data/lib/facter/resolvers/freebsd/freebsd_version_resolver.rb +9 -7
  61. data/lib/facter/resolvers/freebsd/geom_resolver.rb +14 -21
  62. data/lib/facter/resolvers/freebsd/processors.rb +13 -8
  63. data/lib/facter/resolvers/freebsd/swap_memory_resolver.rb +2 -1
  64. data/lib/facter/resolvers/freebsd/system_memory_resolver.rb +2 -1
  65. data/lib/facter/resolvers/gce.rb +2 -1
  66. data/lib/facter/resolvers/hostname_resolver.rb +2 -1
  67. data/lib/facter/resolvers/identity_resolver.rb +2 -1
  68. data/lib/facter/resolvers/linux/docker_uptime.rb +2 -1
  69. data/lib/facter/resolvers/linux/load_averages.rb +2 -1
  70. data/lib/facter/resolvers/load_averages.rb +2 -1
  71. data/lib/facter/resolvers/lpar_resolver.rb +1 -1
  72. data/lib/facter/resolvers/lsb_release_resolver.rb +1 -1
  73. data/lib/facter/resolvers/lspci.rb +1 -1
  74. data/lib/facter/resolvers/macosx/dmi_resolver.rb +1 -1
  75. data/lib/facter/resolvers/macosx/filesystems_resolver.rb +1 -1
  76. data/lib/facter/resolvers/macosx/load_averages_resolver.rb +2 -1
  77. data/lib/facter/resolvers/macosx/mountpoints_resolver.rb +2 -1
  78. data/lib/facter/resolvers/macosx/processor_resolver.rb +2 -1
  79. data/lib/facter/resolvers/macosx/swap_memory_resolver.rb +2 -1
  80. data/lib/facter/resolvers/macosx/system_memory_resolver.rb +2 -1
  81. data/lib/facter/resolvers/macosx/system_profiler_resolver.rb +1 -3
  82. data/lib/facter/resolvers/memory_resolver.rb +15 -15
  83. data/lib/facter/resolvers/mountpoints_resolver.rb +54 -23
  84. data/lib/facter/resolvers/networking_linux_resolver.rb +15 -9
  85. data/lib/facter/resolvers/networking_resolver.rb +1 -1
  86. data/lib/facter/resolvers/open_vz.rb +1 -1
  87. data/lib/facter/resolvers/os_release_resolver.rb +1 -1
  88. data/lib/facter/resolvers/partitions.rb +62 -58
  89. data/lib/facter/resolvers/path_resolver.rb +1 -1
  90. data/lib/facter/resolvers/processors_resolver.rb +9 -2
  91. data/lib/facter/resolvers/puppet_version_resolver.rb +1 -1
  92. data/lib/facter/resolvers/redhat_release_resolver.rb +1 -1
  93. data/lib/facter/resolvers/ruby_resolver.rb +1 -1
  94. data/lib/facter/resolvers/selinux_resolver.rb +1 -1
  95. data/lib/facter/resolvers/solaris/disks.rb +1 -1
  96. data/lib/facter/resolvers/solaris/dmi.rb +3 -1
  97. data/lib/facter/resolvers/solaris/dmi_sparc.rb +1 -1
  98. data/lib/facter/resolvers/solaris/filesystems.rb +1 -1
  99. data/lib/facter/resolvers/solaris/ipaddress.rb +2 -1
  100. data/lib/facter/resolvers/solaris/ldom.rb +1 -3
  101. data/lib/facter/resolvers/solaris/memory.rb +2 -1
  102. data/lib/facter/resolvers/solaris/mountpoints.rb +60 -0
  103. data/lib/facter/resolvers/solaris/networking.rb +2 -3
  104. data/lib/facter/resolvers/solaris/os_release.rb +6 -4
  105. data/lib/facter/resolvers/solaris/processors.rb +2 -1
  106. data/lib/facter/resolvers/solaris/zone.rb +1 -1
  107. data/lib/facter/resolvers/solaris/zone_name.rb +1 -1
  108. data/lib/facter/resolvers/ssh_resolver.rb +8 -5
  109. data/lib/facter/resolvers/suse_release_resolver.rb +1 -1
  110. data/lib/facter/resolvers/sw_vers_resolver.rb +2 -2
  111. data/lib/facter/resolvers/timezone_resolver.rb +1 -1
  112. data/lib/facter/resolvers/uname_resolver.rb +1 -1
  113. data/lib/facter/resolvers/uptime_resolver.rb +1 -1
  114. data/lib/facter/resolvers/utils/networking.rb +2 -0
  115. data/lib/facter/resolvers/virt_what.rb +1 -1
  116. data/lib/facter/resolvers/vmware.rb +1 -1
  117. data/lib/facter/resolvers/windows/aio_agent_version.rb +1 -1
  118. data/lib/facter/resolvers/windows/dmi_bios_resolver.rb +1 -1
  119. data/lib/facter/resolvers/windows/dmi_computersystem_resolver.rb +1 -1
  120. data/lib/facter/resolvers/windows/fips_resolver.rb +2 -1
  121. data/lib/facter/resolvers/windows/hardware_architecture_resolver.rb +2 -1
  122. data/lib/facter/resolvers/windows/identity_resolver.rb +2 -1
  123. data/lib/facter/resolvers/windows/kernel_resolver.rb +3 -1
  124. data/lib/facter/resolvers/windows/memory_resolver.rb +3 -1
  125. data/lib/facter/resolvers/windows/netkvm_resolver.rb +2 -1
  126. data/lib/facter/resolvers/windows/networking_resolver.rb +2 -1
  127. data/lib/facter/resolvers/windows/processors_resolver.rb +2 -1
  128. data/lib/facter/resolvers/windows/product_release_resolver.rb +2 -1
  129. data/lib/facter/resolvers/windows/ssh.rb +3 -1
  130. data/lib/facter/resolvers/windows/system32_resolver.rb +3 -1
  131. data/lib/facter/resolvers/windows/uptime_resolver.rb +2 -1
  132. data/lib/facter/resolvers/windows/virtualization_resolver.rb +2 -1
  133. data/lib/facter/resolvers/windows/win_os_description_resolver.rb +3 -1
  134. data/lib/facter/resolvers/wpar_resolver.rb +1 -1
  135. data/lib/facter/resolvers/xen.rb +1 -1
  136. data/lib/facter/resolvers/zfs.rb +2 -1
  137. data/lib/facter/resolvers/zpool.rb +2 -1
  138. data/lib/facter/version.rb +1 -1
  139. metadata +7 -5
  140. data/lib/facter/fact_groups.conf +0 -308
  141. data/lib/facter/os_hierarchy.json +0 -36
@@ -4,7 +4,8 @@ module Facter
4
4
  module Resolvers
5
5
  module Macosx
6
6
  class Processors < BaseResolver
7
- @fact_list = {}
7
+ init_resolver
8
+
8
9
  ITEMS = { logical_count: 'hw.logicalcpu_max',
9
10
  physical_count: 'hw.physicalcpu_max',
10
11
  brand: 'machdep.cpu.brand_string',
@@ -4,7 +4,8 @@ module Facter
4
4
  module Resolvers
5
5
  module Macosx
6
6
  class SwapMemory < BaseResolver
7
- @fact_list ||= {}
7
+ init_resolver
8
+
8
9
  class << self
9
10
  private
10
11
 
@@ -4,7 +4,8 @@ module Facter
4
4
  module Resolvers
5
5
  module Macosx
6
6
  class SystemMemory < BaseResolver
7
- @fact_list ||= {}
7
+ init_resolver
8
+
8
9
  class << self
9
10
  private
10
11
 
@@ -15,7 +15,7 @@ module Facter
15
15
  SP_ETHERNET_DATA_TYPE = %i[type bus vendor_id device_id subsystem_vendor_id
16
16
  subsystem_id revision_id bsd_name kext_name location version].freeze
17
17
 
18
- @fact_list = {}
18
+ init_resolver
19
19
 
20
20
  class << self
21
21
  private
@@ -25,8 +25,6 @@ module Facter
25
25
  end
26
26
 
27
27
  def retrieve_system_profiler(fact_name)
28
- @fact_list ||= {}
29
-
30
28
  case fact_name
31
29
  when *SP_HARDWARE_DATA_TYPE
32
30
  @fact_list.merge!(SystemProfileExecutor.execute('SPHardwareDataType'))
@@ -4,8 +4,10 @@ module Facter
4
4
  module Resolvers
5
5
  module Linux
6
6
  class Memory < BaseResolver
7
- @fact_list ||= {}
7
+ init_resolver
8
+
8
9
  @log = Facter::Log.new(self)
10
+
9
11
  class << self
10
12
  private
11
13
 
@@ -25,11 +27,21 @@ module Facter
25
27
 
26
28
  def read_system(output)
27
29
  @fact_list[:total] = kilobytes_to_bytes(output.match(/MemTotal:\s+(\d+)\s/)[1])
28
- @fact_list[:memfree] = kilobytes_to_bytes(output.match(/MemFree:\s+(\d+)\s/)[1])
29
- @fact_list[:used_bytes] = compute_used(@fact_list[:total], reclaimable_memory(output))
30
+ @fact_list[:memfree] = memfree(output)
31
+ @fact_list[:used_bytes] = compute_used(@fact_list[:total], @fact_list[:memfree])
30
32
  @fact_list[:capacity] = compute_capacity(@fact_list[:used_bytes], @fact_list[:total])
31
33
  end
32
34
 
35
+ def memfree(output)
36
+ available = output.match(/MemAvailable:\s+(\d+)\s/)
37
+ return kilobytes_to_bytes(available[1]) if available
38
+
39
+ buffers = kilobytes_to_bytes(output.match(/Buffers:\s+(\d+)\s/)[1])
40
+ cached = kilobytes_to_bytes(output.match(/Cached:\s+(\d+)\s/)[1])
41
+ memfree = kilobytes_to_bytes(output.match(/MemFree:\s+(\d+)\s/)[1])
42
+ memfree + buffers + cached
43
+ end
44
+
33
45
  def read_swap(output)
34
46
  total = output.match(/SwapTotal:\s+(\d+)\s/)[1]
35
47
  return if total.to_i.zero?
@@ -44,18 +56,6 @@ module Facter
44
56
  quantity.to_i * 1024
45
57
  end
46
58
 
47
- def reclaimable_memory(output)
48
- buffers = kilobytes_to_bytes(output.match(/Buffers:\s+(\d+)\s/)[1])
49
- cached = kilobytes_to_bytes(output.match(/Cached:\s+(\d+)\s/)[1])
50
- s_reclaimable = output.match(/SReclaimable:\s+(\d+)\s/)
51
- s_reclaimable = if s_reclaimable
52
- kilobytes_to_bytes(s_reclaimable[1])
53
- else
54
- 0
55
- end
56
- @fact_list[:memfree] + buffers + cached + s_reclaimable
57
- end
58
-
59
59
  def compute_capacity(used, total)
60
60
  format('%<computed_capacity>.2f', computed_capacity: (used / total.to_f * 100)) + '%'
61
61
  end
@@ -4,19 +4,36 @@ module Facter
4
4
  module Resolvers
5
5
  class Mountpoints < BaseResolver
6
6
  include Facter::FilesystemHelper
7
- @fact_list ||= {}
7
+
8
+ init_resolver
9
+
8
10
  @log = Facter::Log.new(self)
11
+
9
12
  class << self
10
13
  private
11
14
 
12
15
  def post_resolve(fact_name)
13
- @fact_list.fetch(fact_name) { read_mounts }
16
+ @fact_list.fetch(fact_name) { read_mounts(fact_name) }
14
17
  end
15
18
 
16
19
  def root_device
17
20
  cmdline = Util::FileHelper.safe_read('/proc/cmdline')
18
21
  match = cmdline.match(/root=([^\s]+)/)
19
- match&.captures&.first
22
+ root = match&.captures&.first
23
+
24
+ if !root.nil? && root.include?('=')
25
+ # We are dealing with the PARTUUID of the partition. Need to extract partition path.
26
+ root_partition_path = convert_partuuid_to_path(root)
27
+ root = root_partition_path unless root_partition_path.nil?
28
+ end
29
+ root
30
+ end
31
+
32
+ def convert_partuuid_to_path(root)
33
+ blkid_content = Facter::Core::Execution.execute('blkid', logger: log)
34
+ partuuid = root.split('=').last
35
+ match = blkid_content.match(/(.+)#{partuuid}/)
36
+ match&.captures&.first&.split(':')&.first
20
37
  end
21
38
 
22
39
  def compute_device(device)
@@ -26,32 +43,46 @@ module Facter
26
43
  device
27
44
  end
28
45
 
29
- def read_mounts # rubocop:disable Metrics/AbcSize
46
+ def read_mounts(fact_name)
30
47
  mounts = []
31
- FilesystemHelper.read_mountpoints.each do |fs|
32
- device = compute_device(fs.name)
33
- filesystem = fs.mount_type
34
- path = fs.mount_point
35
- options = fs.options.split(',').map(&:strip)
48
+ FilesystemHelper.read_mountpoints.each do |file_system|
49
+ mount = {}
50
+ get_mount_data(file_system, mount)
51
+
52
+ next if mount[:path] =~ %r{^/(proc|sys)} && mount[:filesystem] != 'tmpfs' || mount[:filesystem] == 'autofs'
53
+
54
+ get_mount_sizes(mount)
55
+ mounts << mount
56
+ end
36
57
 
37
- next if path =~ %r{^/(proc|sys)} && filesystem != 'tmpfs' || filesystem == 'autofs'
58
+ @fact_list[:mountpoints] = mounts
59
+ @fact_list[fact_name]
60
+ end
38
61
 
39
- stats = FilesystemHelper.read_mountpoint_stats(path)
40
- size_bytes = stats.bytes_total.abs
41
- available_bytes = stats.bytes_available.abs
62
+ def get_mount_data(file_system, mount)
63
+ mount[:device] = compute_device(file_system.name)
64
+ mount[:filesystem] = file_system.mount_type
65
+ mount[:path] = file_system.mount_point
66
+ mount[:options] = file_system.options.split(',').map(&:strip)
67
+ end
42
68
 
43
- used_bytes = stats.bytes_used.abs
44
- total_bytes = used_bytes + available_bytes
45
- capacity = FilesystemHelper.compute_capacity(used_bytes, total_bytes)
69
+ def get_mount_sizes(mount)
70
+ stats = FilesystemHelper.read_mountpoint_stats(mount[:path])
46
71
 
47
- size = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(size_bytes)
48
- available = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(available_bytes)
49
- used = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(used_bytes)
72
+ get_bytes_data(mount, stats)
50
73
 
51
- mounts << Hash[FilesystemHelper::MOUNT_KEYS.zip(FilesystemHelper::MOUNT_KEYS
52
- .map { |v| binding.local_variable_get(v) })]
53
- end
54
- @fact_list[:mountpoints] = mounts
74
+ total_bytes = mount[:used_bytes] + mount[:available_bytes]
75
+ mount[:capacity] = FilesystemHelper.compute_capacity(mount[:used_bytes], total_bytes)
76
+
77
+ mount[:size] = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(mount[:size_bytes])
78
+ mount[:available] = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(mount[:available_bytes])
79
+ mount[:used] = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(mount[:used_bytes])
80
+ end
81
+
82
+ def get_bytes_data(mount, stats)
83
+ mount[:size_bytes] = stats.bytes_total.abs
84
+ mount[:available_bytes] = stats.bytes_available.abs
85
+ mount[:used_bytes] = stats.bytes_used.abs
55
86
  end
56
87
  end
57
88
  end
@@ -3,22 +3,20 @@
3
3
  module Facter
4
4
  module Resolvers
5
5
  class NetworkingLinux < BaseResolver
6
- @fact_list = {}
6
+ init_resolver
7
+
7
8
  DIRS = ['/var/lib/dhclient/', '/var/lib/dhcp/', '/var/lib/dhcp3/', '/var/lib/NetworkManager/', '/var/db/'].freeze
8
9
 
9
10
  class << self
10
11
  private
11
12
 
12
13
  def post_resolve(fact_name)
13
- log.debug('in networking_linux_resolver')
14
14
  @fact_list.fetch(fact_name) { retrieve_network_info(fact_name) }
15
15
 
16
16
  @fact_list[fact_name]
17
17
  end
18
18
 
19
19
  def retrieve_network_info(fact_name)
20
- @fact_list ||= {}
21
-
22
20
  retrieve_interface_info
23
21
  retrieve_interfaces_mac_and_mtu
24
22
  retrieve_default_interface
@@ -60,9 +58,14 @@ module Facter
60
58
  return if !network_info[interface_name] || network_info[interface_name][:dhcp]
61
59
 
62
60
  index = tokens[0].delete(':')
63
- dhcp = Util::FileHelper.safe_read("/run/systemd/netif/leases/#{index}", nil)
64
- network_info[interface_name][:dhcp] = dhcp.match(/SERVER_ADDRESS=(.*)/)[1] if dhcp
65
- network_info[interface_name][:dhcp] ||= retrieve_from_other_directories(interface_name)
61
+ file_content = Util::FileHelper.safe_read("/run/systemd/netif/leases/#{index}", nil)
62
+ dhcp = file_content.match(/SERVER_ADDRESS=(.*)/) if file_content
63
+ if dhcp
64
+ network_info[interface_name][:dhcp] = dhcp[1]
65
+ else
66
+ alternate_dhcp = retrieve_from_other_directories(interface_name)
67
+ network_info[interface_name][:dhcp] = alternate_dhcp if alternate_dhcp
68
+ end
66
69
  end
67
70
 
68
71
  def retrieve_from_other_directories(interface_name)
@@ -76,7 +79,8 @@ module Facter
76
79
  content = Util::FileHelper.safe_read("#{dir}#{file}", nil)
77
80
  next unless content =~ /interface.*#{interface_name}/
78
81
 
79
- return content.match(/dhcp-server-identifier ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/)[1]
82
+ dhcp = content.match(/dhcp-server-identifier ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/)
83
+ return dhcp[1] if dhcp
80
84
  end
81
85
  end
82
86
  return unless File.readable?('/var/lib/NetworkManager/')
@@ -108,6 +112,8 @@ module Facter
108
112
  "ip4_mask_length = #{ip4_mask_length}")
109
113
 
110
114
  binding = ::Resolvers::Utils::Networking.build_binding(ip4_address, ip4_mask_length)
115
+ return unless binding
116
+
111
117
  build_network_info_structure!(network_info, interface_name, :bindings)
112
118
 
113
119
  network_info[interface_name][:bindings] << binding
@@ -115,7 +121,7 @@ module Facter
115
121
 
116
122
  def retrieve_name_and_ip_info(tokens)
117
123
  interface_name = tokens[1]
118
- ip_info = tokens[3].split('/')
124
+ ip_info = tokens[4] =~ /peer/ ? tokens[5].split('/') : tokens[3].split('/')
119
125
  ip_address = ip_info[0]
120
126
  ip_mask_length = ip_info[1]
121
127
 
@@ -3,7 +3,7 @@
3
3
  module Facter
4
4
  module Resolvers
5
5
  class Networking < BaseResolver
6
- @fact_list ||= {}
6
+ init_resolver
7
7
 
8
8
  class << self
9
9
  private
@@ -5,7 +5,7 @@ module Facter
5
5
  class OpenVz < BaseResolver
6
6
  # build
7
7
 
8
- @fact_list ||= {}
8
+ init_resolver
9
9
 
10
10
  class << self
11
11
  private
@@ -14,7 +14,7 @@ module Facter
14
14
  # :support_url
15
15
  # :bug_report_url
16
16
 
17
- @fact_list ||= {}
17
+ init_resolver
18
18
 
19
19
  class << self
20
20
  private
@@ -3,7 +3,8 @@
3
3
  module Facter
4
4
  module Resolvers
5
5
  class Partitions < BaseResolver
6
- @fact_list ||= {}
6
+ init_resolver
7
+
7
8
  BLOCK_PATH = '/sys/block'
8
9
  BLOCK_SIZE = 512
9
10
 
@@ -15,98 +16,122 @@ module Facter
15
16
  end
16
17
 
17
18
  def read_partitions(fact_name)
18
- @fact_list[:partitions] = {}
19
- return {} unless File.readable?(BLOCK_PATH)
19
+ return unless File.readable?(BLOCK_PATH)
20
20
 
21
21
  block_devices = Dir.entries(BLOCK_PATH).reject { |dir| dir =~ /^\.+/ }
22
+ @fact_list[:partitions] = {} unless block_devices.empty?
23
+ blkid_and_lsblk = {}
24
+
22
25
  block_devices.each do |block_device|
23
26
  block_path = "#{BLOCK_PATH}/#{block_device}"
24
27
  if File.directory?("#{block_path}/device")
25
- extract_from_device(block_path)
28
+ extract_from_device(block_path, blkid_and_lsblk)
26
29
  elsif File.directory?("#{block_path}/dm")
27
- extract_from_dm(block_path)
30
+ extract_from_dm(block_path, block_device, blkid_and_lsblk)
28
31
  elsif File.directory?("#{block_path}/loop")
29
- extract_from_loop(block_path)
32
+ extract_from_loop(block_path, block_device, blkid_and_lsblk)
30
33
  end
31
34
  end
35
+
32
36
  @fact_list[fact_name]
33
37
  end
34
38
 
35
- def extract_from_device(block_path)
39
+ def extract_from_device(block_path, blkid_and_lsblk)
36
40
  subdirs = browse_subdirectories(block_path)
37
41
  subdirs.each do |subdir|
38
42
  name = "/dev/#{subdir.split('/').last}"
39
- populate_partitions(name, subdir)
43
+ populate_partitions(name, subdir, blkid_and_lsblk)
40
44
  end
41
45
  end
42
46
 
43
- def extract_from_dm(block_path)
47
+ def extract_from_dm(block_path, block_device, blkid_and_lsblk)
44
48
  map_name = Util::FileHelper.safe_read("#{block_path}/dm/name").chomp
45
49
  if map_name.empty?
46
- populate_partitions("/dev#{block_path}", block_path)
50
+ populate_partitions("/dev/#{block_device}", block_path, blkid_and_lsblk)
47
51
  else
48
- populate_partitions("/dev/mapper/#{map_name}", block_path)
52
+ populate_partitions("/dev/mapper/#{map_name}", block_path, blkid_and_lsblk)
49
53
  end
50
54
  end
51
55
 
52
- def extract_from_loop(block_path)
56
+ def extract_from_loop(block_path, block_device, blkid_and_lsblk)
53
57
  backing_file = Util::FileHelper.safe_read("#{block_path}/loop/backing_file").chomp
54
58
  if backing_file.empty?
55
- populate_partitions("/dev#{block_path}", block_path)
59
+ populate_partitions("/dev/#{block_device}", block_path, blkid_and_lsblk)
56
60
  else
57
- populate_partitions("/dev#{block_path}", block_path, backing_file)
61
+ populate_partitions("/dev/#{block_device}", block_path, blkid_and_lsblk, backing_file)
58
62
  end
59
63
  end
60
64
 
61
- def populate_partitions(partition_name, block_path, backing_file = nil)
62
- @fact_list[:partitions][partition_name] = {}
65
+ def populate_partitions(partition_name, block_path, blkid_and_lsblk, backing_file = nil)
63
66
  size_bytes = Util::FileHelper.safe_read("#{block_path}/size", '0')
64
67
  .chomp.to_i * BLOCK_SIZE
65
68
  info_hash = { size_bytes: size_bytes,
66
69
  size: Facter::FactsUtils::UnitConverter.bytes_to_human_readable(size_bytes),
67
70
  backing_file: backing_file }
68
- info_hash.merge!(populate_from_syscalls(partition_name))
71
+ info_hash.merge!(populate_from_syscalls(partition_name, blkid_and_lsblk))
69
72
  @fact_list[:partitions][partition_name] = info_hash.reject { |_key, value| value.nil? }
70
73
  end
71
74
 
72
- def populate_from_syscalls(partition_name)
73
- part_info = populate_from_blkid(partition_name)
75
+ def populate_from_syscalls(partition_name, blkid_and_lsblk)
76
+ part_info = populate_from_blkid(partition_name, blkid_and_lsblk)
74
77
 
75
- return pupulate_from_lsblk(partition_name) if part_info.empty?
78
+ return populate_from_lsblk(partition_name, blkid_and_lsblk) if part_info.empty?
76
79
 
77
80
  part_info
78
81
  end
79
82
 
80
- def populate_from_blkid(partition_name)
81
- return {} unless blkid_command?
83
+ def browse_subdirectories(path)
84
+ dirs = Dir[File.join(path, '**', '*')].select { |p| File.directory? p }
85
+ dirs.select { |subdir| subdir.split('/').last.include?(path.split('/').last) }.reject(&:nil?)
86
+ end
87
+
88
+ def populate_from_blkid(partition_name, blkid_and_lsblk)
89
+ return {} unless available?('blkid', blkid_and_lsblk)
90
+
91
+ blkid_and_lsblk[:blkid] ||= execute_and_extract_blkid_info
92
+
93
+ partition_data = blkid_and_lsblk[:blkid][partition_name]
94
+ return {} unless partition_data
82
95
 
83
- @blkid_content ||= execute_and_extract_blkid_info
84
- return {} unless @blkid_content[partition_name]
96
+ filesys = partition_data['TYPE']
97
+ uuid = partition_data['UUID']
98
+ label = partition_data['LABEL']
99
+ part_uuid = partition_data['PARTUUID']
100
+ part_label = partition_data['PARTLABEL']
85
101
 
86
- filesys = @blkid_content[partition_name]['TYPE']
87
- uuid = @blkid_content[partition_name]['UUID']
88
- label = @blkid_content[partition_name]['LABEL']
89
- part_uuid = @blkid_content[partition_name]['PARTUUID']
90
- part_label = @blkid_content[partition_name]['PARTLABEL']
91
102
  { filesystem: filesys, uuid: uuid, label: label, partuuid: part_uuid, partlabel: part_label }
92
103
  end
93
104
 
94
- def blkid_command?
95
- return @blkid_exists unless @blkid_exists.nil?
105
+ def available?(command, blkid_and_lsblk)
106
+ command_exists_key = command == 'blkid' ? :blkid_exists : :lsblk_exists
96
107
 
97
- output = Facter::Core::Execution.execute('which blkid', logger: log)
108
+ return blkid_and_lsblk[command_exists_key] unless blkid_and_lsblk[command_exists_key].nil?
98
109
 
99
- @blkid_exists = !output.empty?
110
+ output = Facter::Core::Execution.execute("which #{command}", logger: log)
111
+
112
+ blkid_and_lsblk[:command_exists_key] = !output.empty?
113
+ end
114
+
115
+ def execute_and_extract_blkid_info
116
+ stdout = Facter::Core::Execution.execute('blkid', logger: log)
117
+ output_hash = Hash[*stdout.split(/^([^:]+):/)[1..-1]]
118
+ output_hash.each do |key, value|
119
+ output_hash[key] = Hash[*value.delete('"').chomp.rstrip.split(/ ([^= ]+)=/)[1..-1]]
120
+ end
100
121
  end
101
122
 
102
- def pupulate_from_lsblk(partition_name)
103
- return {} unless lsblk_command?
123
+ def populate_from_lsblk(partition_name, blkid_and_lsblk)
124
+ return {} unless available?('lsblk', blkid_and_lsblk)
104
125
 
105
- @lsblk_content ||= Facter::Core::Execution.execute('lsblk -fp', logger: log)
126
+ blkid_and_lsblk[:lsblk] ||= Facter::Core::Execution.execute('lsblk -fp', logger: log)
106
127
 
107
- part_info = @lsblk_content.match(/#{partition_name}.*/).to_s.split(' ')
128
+ part_info = blkid_and_lsblk[:lsblk].match(/#{partition_name}.*/).to_s.split(' ')
108
129
  return {} if part_info.empty?
109
130
 
131
+ parse_part_info(part_info)
132
+ end
133
+
134
+ def parse_part_info(part_info)
110
135
  result = { filesystem: part_info[1] }
111
136
 
112
137
  if part_info.count.eql?(5)
@@ -118,27 +143,6 @@ module Facter
118
143
 
119
144
  result
120
145
  end
121
-
122
- def lsblk_command?
123
- return @lsblk_exists unless @lsblk_exists.nil?
124
-
125
- output = Facter::Core::Execution.execute('which lsblk', logger: log)
126
-
127
- @lsblk_exists = !output.empty?
128
- end
129
-
130
- def execute_and_extract_blkid_info
131
- stdout = Facter::Core::Execution.execute('blkid', logger: log)
132
- output_hash = Hash[*stdout.split(/^([^:]+):/)[1..-1]]
133
- output_hash.each do |key, value|
134
- output_hash[key] = Hash[*value.delete('"').chomp.rstrip.split(/ ([^= ]+)=/)[1..-1]]
135
- end
136
- end
137
-
138
- def browse_subdirectories(path)
139
- dirs = Dir[File.join(path, '**', '*')].select { |p| File.directory? p }
140
- dirs.select { |subdir| subdir.split('/').last.include?(path.split('/').last) }.reject(&:nil?)
141
- end
142
146
  end
143
147
  end
144
148
  end