facter 4.7.1 → 4.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 512cdd220f22069dbf686592dfc08d3b4ecccf97702313117b333d5e568ebe8e
4
- data.tar.gz: 373406fac7fe5ec363b13e6afa26acabfb6bb62716d9f0b977b1f2e768e6381d
3
+ metadata.gz: 97c091ad872480f9a35f8c56682e89b65cd221d2b7da74b6bab229e37e27dda0
4
+ data.tar.gz: c55e4ec6c3e39148ca2c8ce0819eecc4dcf33eddd1ece53442d293eddb405955
5
5
  SHA512:
6
- metadata.gz: ed2f2ac6dcec58364ba37df4acee50fb44f90f46f6de28f8f2524aa89d8d5634e7499be547234e65e4930126e59652b0d6b56f2d602e74598227d7808c504bf7
7
- data.tar.gz: ef408018f71cd5884a56cf0dc3aab243fe119978e45c99e4b8069242d4ecf27011a3c106b53f12960665729bc0209aee452a02138e6642749f2c2b51e46a67bc
6
+ metadata.gz: 8d87380c0d913de5c09f664a5b9a7a35a26434ff806b5788c4712b70cfa6bb85e9fa6670e9bd05dbd275a6f87cd20001d620596e97f732b351d05afe9c5a47d7
7
+ data.tar.gz: 5900798a818340f42464fff9eec375d2810157f1b73a143fb0191c342149f92634344a4077589af2c19597d3c984aff673bfcb611b14f59a6438c1f2f27eb232
data/lib/facter/config.rb CHANGED
@@ -26,6 +26,8 @@ module Facter
26
26
  Meego
27
27
  Oel
28
28
  Ovs
29
+ Mariner
30
+ Azurelinux
29
31
  ]
30
32
  },
31
33
  {
@@ -34,13 +36,13 @@ module Facter
34
36
  Sled
35
37
  ]
36
38
  },
39
+ 'Archlinux',
37
40
  'Gentoo',
38
41
  'Alpine',
39
42
  'Photon',
40
43
  'Slackware',
41
44
  'Mageia',
42
- 'Openwrt',
43
- 'Mariner'
45
+ 'Openwrt'
44
46
  ]
45
47
  },
46
48
  {
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Archlinux
5
+ module Os
6
+ class Release
7
+ FACT_NAME = 'os.release'
8
+
9
+ def call_the_resolver
10
+ # Arch Linux is rolling release and has no version numbers
11
+ # For historical reasons facter used the kernel version as OS version on Arch Linux
12
+ kernelrelease = Facter::Resolvers::Uname.resolve(:kernelrelease)
13
+ versions = kernelrelease.split('.')
14
+ hash = { full: kernelrelease, major: versions[0], minor: versions[1] }
15
+
16
+ Facter::ResolvedFact.new(FACT_NAME, hash)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Azurelinux
5
+ module Os
6
+ class Release
7
+ FACT_NAME = 'os.release'
8
+ ALIASES = %w[operatingsystemmajrelease operatingsystemrelease].freeze
9
+
10
+ def call_the_resolver
11
+ version = from_specific_file || from_os_release
12
+
13
+ return Facter::ResolvedFact.new(FACT_NAME, nil) unless version
14
+
15
+ [Facter::ResolvedFact.new(FACT_NAME, version),
16
+ Facter::ResolvedFact.new(ALIASES.first, version['major'], :legacy),
17
+ Facter::ResolvedFact.new(ALIASES.last, version['full'], :legacy)]
18
+ end
19
+
20
+ def from_specific_file
21
+ version = Facter::Resolvers::SpecificReleaseFile.resolve(:release,
22
+ { release_file: '/etc/azurelinux-release',
23
+ regex: /AZURELINUX_BUILD_NUMBER=([0-9.]+)/ })
24
+ Facter::Util::Facts.release_hash_from_matchdata(version)
25
+ end
26
+
27
+ def from_os_release
28
+ version = Facter::Resolvers::OsRelease.resolve(:version_id)
29
+
30
+ Facter::Util::Facts.release_hash_from_string(version)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Linux
5
+ module Processors
6
+ class Extensions
7
+ FACT_NAME = 'processors.extensions'
8
+
9
+ def call_the_resolver
10
+ fact_value = Facter::Resolvers::Linux::Processors.resolve(:extensions)
11
+ Facter::ResolvedFact.new(FACT_NAME, fact_value)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -246,6 +246,12 @@ os_hierarchy.each do |os|
246
246
 
247
247
  require_relative '../../resolvers/amzn/os_release_rpm'
248
248
 
249
+ when 'archlinux'
250
+ require_relative '../../facts/archlinux/os/release'
251
+
252
+ when 'azurelinux'
253
+ require_relative '../../facts/azurelinux/os/release'
254
+
249
255
  when 'bsd'
250
256
  require_relative '../../facts/bsd/kernelmajversion'
251
257
  require_relative '../../facts/bsd/kernelversion'
@@ -372,6 +378,7 @@ os_hierarchy.each do |os|
372
378
  when 'linux'
373
379
  require_relative '../../util/linux/dhcp'
374
380
  require_relative '../../util/linux/if_inet6'
381
+ require_relative '../../util/linux/proc'
375
382
  require_relative '../../util/linux/routing_table'
376
383
  require_relative '../../util/linux/socket_parser'
377
384
 
@@ -482,6 +489,7 @@ os_hierarchy.each do |os|
482
489
  require_relative '../../facts/linux/processor'
483
490
  require_relative '../../facts/linux/processors/cores'
484
491
  require_relative '../../facts/linux/processors/count'
492
+ require_relative '../../facts/linux/processors/extensions'
485
493
  require_relative '../../facts/linux/processors/isa'
486
494
  require_relative '../../facts/linux/processors/models'
487
495
  require_relative '../../facts/linux/processors/physicalcount'
@@ -68,6 +68,7 @@ class OsDetector
68
68
 
69
69
  def detect_based_on_release_file
70
70
  @identifier = :devuan if File.readable?('/etc/devuan_version')
71
+ @identifier = :archlinux if File.readable?('/etc/arch-release')
71
72
  end
72
73
 
73
74
  def detect_distro
@@ -31,9 +31,14 @@ module Facter
31
31
  def add_mount_points_fact(line)
32
32
  elem = line.split("\s")
33
33
 
34
- elem.shift unless line[0] == ' '
34
+ if line[0] != ' '
35
+ server = elem.shift
36
+ device = "#{server}:#{elem[0]}"
37
+ else
38
+ device = elem[0]
39
+ end
35
40
 
36
- @fact_list[:mountpoints][elem[1]] = { device: elem[0], filesystem: elem[2],
41
+ @fact_list[:mountpoints][elem[1]] = { device: device, filesystem: elem[2],
37
42
  options: elem.last.include?(':') ? [] : elem.last.split(',') }
38
43
  end
39
44
 
@@ -14,45 +14,65 @@ module Facter
14
14
  private
15
15
 
16
16
  def post_resolve(fact_name, _options)
17
- @fact_list.fetch(fact_name) { read_cgroup(fact_name) }
17
+ @fact_list.fetch(fact_name) do
18
+ read_environ(fact_name) || read_cgroup(fact_name)
19
+ end
18
20
  end
19
21
 
20
22
  def read_cgroup(fact_name)
21
23
  output_cgroup = Facter::Util::FileHelper.safe_read('/proc/1/cgroup', nil)
22
- output_environ = Facter::Util::FileHelper.safe_read('/proc/1/environ', nil)
23
- return unless output_cgroup && output_environ
24
+ return unless output_cgroup
24
25
 
25
26
  output_docker = %r{docker/(.+)}.match(output_cgroup)
26
27
  output_lxc = %r{^/lxc/([^/]+)}.match(output_cgroup)
27
- lxc_from_environ = /container=lxc/ =~ output_environ
28
28
 
29
- info, vm = extract_vm_and_info(output_docker, output_lxc, lxc_from_environ)
30
- info, vm = extract_for_nspawn(output_environ) unless vm
29
+ info, vm = extract_vm_and_info(output_docker, output_lxc)
30
+ @fact_list[:vm] = vm
31
+ @fact_list[:hypervisor] = { vm.to_sym => info } if vm
32
+ @fact_list[fact_name]
33
+ end
34
+
35
+ def read_environ(fact_name)
36
+ begin
37
+ container = Facter::Util::Linux::Proc.getenv_for_pid(1, 'container')
38
+ rescue StandardError => e
39
+ log.warn("Unable to getenv for pid 1, '#{e}'")
40
+ return nil
41
+ end
42
+ return if container.nil? || container.empty?
43
+
44
+ info = {}
45
+ case container
46
+ when 'lxc'
47
+ vm = 'lxc'
48
+ when 'podman'
49
+ vm = 'podman'
50
+ when 'crio'
51
+ vm = 'crio'
52
+ when 'systemd-nspawn'
53
+ vm = 'systemd_nspawn'
54
+ info = { 'id' => Facter::Util::FileHelper.safe_read('/etc/machine-id', nil).strip }
55
+ else
56
+ vm = 'container_other'
57
+ log.warn("Container runtime, '#{container}', is unsupported, setting to '#{vm}'")
58
+ end
31
59
  @fact_list[:vm] = vm
32
60
  @fact_list[:hypervisor] = { vm.to_sym => info } if vm
33
61
  @fact_list[fact_name]
34
62
  end
35
63
 
36
- def extract_vm_and_info(output_docker, output_lxc, lxc_from_environ)
64
+ def extract_vm_and_info(output_docker, output_lxc)
37
65
  vm = nil
38
66
  if output_docker
39
67
  vm = 'docker'
40
68
  info = output_docker[1]
69
+ elsif output_lxc
70
+ vm = 'lxc'
71
+ info = output_lxc[1]
41
72
  end
42
- vm = 'lxc' if output_lxc || lxc_from_environ
43
- info = output_lxc[1] if output_lxc
44
73
 
45
74
  [info ? { INFO[vm] => info } : {}, vm]
46
75
  end
47
-
48
- def extract_for_nspawn(output_environ)
49
- nspawn = /container=systemd-nspawn/ =~ output_environ
50
- if nspawn
51
- vm = 'systemd_nspawn'
52
- info = Facter::Util::FileHelper.safe_read('/etc/machine-id', nil)
53
- end
54
- [info ? { 'id' => info.strip } : {}, vm]
55
- end
56
76
  end
57
77
  end
58
78
  end
@@ -22,7 +22,7 @@ module Facter
22
22
  end
23
23
 
24
24
  def query_for_metadata
25
- gce_data = extract_to_hash(Facter::Util::Resolvers::Http.get_request(METADATA_URL, HEADERS, false))
25
+ gce_data = extract_to_hash(Facter::Util::Resolvers::Http.get_request(METADATA_URL, HEADERS, {}, false))
26
26
  parse_instance(gce_data)
27
27
 
28
28
  gce_data.empty? ? nil : gce_data
@@ -96,6 +96,8 @@ module Facter
96
96
  @fact_list[:name] = if os_name.downcase.start_with?('red', 'oracle', 'arch', 'manjaro')
97
97
  os_name = os_name.split(' ')[0..1].join
98
98
  os_name
99
+ elsif os_name.downcase.end_with?('azure linux')
100
+ os_name.split(' ')[1..2].join
99
101
  elsif os_name.downcase.end_with?('mariner')
100
102
  os_name.split(' ')[-1].strip
101
103
  else
@@ -69,13 +69,14 @@ module Facter
69
69
  size: Facter::Util::Facts::UnitConverter.bytes_to_human_readable(size_bytes),
70
70
  backing_file: backing_file }
71
71
  info_hash.merge!(populate_from_syscalls(partition_name, blkid_and_lsblk))
72
- @fact_list[:partitions][partition_name] = info_hash.reject { |_key, value| value.nil? }
72
+ @fact_list[:partitions][partition_name] = info_hash.compact
73
73
  end
74
74
 
75
75
  def populate_from_syscalls(partition_name, blkid_and_lsblk)
76
- part_info = populate_from_blkid(partition_name, blkid_and_lsblk)
76
+ # Prefer lsblk over blkid since lsblk does not require root, returns more information, and is recommended by blkid
77
+ part_info = populate_from_lsblk(partition_name, blkid_and_lsblk)
77
78
 
78
- return populate_from_lsblk(partition_name, blkid_and_lsblk) if part_info.empty?
79
+ return populate_from_blkid(partition_name, blkid_and_lsblk) if part_info.empty?
79
80
 
80
81
  part_info
81
82
  end
@@ -121,26 +122,47 @@ module Facter
121
122
  def populate_from_lsblk(partition_name, blkid_and_lsblk)
122
123
  return {} unless available?('lsblk', blkid_and_lsblk)
123
124
 
124
- blkid_and_lsblk[:lsblk] ||= Facter::Core::Execution.execute('lsblk -fp', logger: log)
125
+ lsblk_version_raw = Facter::Core::Execution.execute('lsblk --version 2>&1', logger: log)
126
+ # Return if the version of lsblk is too old (< 2.22) to support the --version flag
127
+ lsblk_version_raw.match?(/ \d\.\d+/) ? lsblk_version = lsblk_version_raw.match(/ \d\.\d+/)[0].to_f : (return {})
125
128
 
126
- part_info = blkid_and_lsblk[:lsblk].match(/#{partition_name}.*/).to_s.split(' ')
127
- return {} if part_info.empty?
129
+ # The -p/--paths option was added in lsblk 2.23, return early and fall back to blkid with earlier versions
130
+ return {} if lsblk_version < 2.23
128
131
 
129
- parse_part_info(part_info)
130
- end
132
+ blkid_and_lsblk[:lsblk] ||= execute_and_extract_lsblk_info(lsblk_version)
131
133
 
132
- def parse_part_info(part_info)
133
- result = { filesystem: part_info[1] }
134
+ partition_data = blkid_and_lsblk[:lsblk][partition_name]
135
+ return {} unless partition_data
134
136
 
135
- if part_info.count.eql?(5)
136
- result[:label] = part_info[2]
137
- result[:uuid] = part_info[3]
138
- else
139
- result[:uuid] = part_info[2]
140
- end
137
+ filesys = partition_data['FSTYPE']
138
+ uuid = partition_data['UUID']
139
+ label = partition_data['LABEL']
140
+ part_uuid = partition_data['PARTUUID']
141
+ part_label = partition_data['PARTLABEL']
142
+ part_type = partition_data['PARTTYPE']
143
+
144
+ result = { filesystem: filesys, uuid: uuid, label: label, partuuid: part_uuid, partlabel: part_label }
145
+ result[:parttype] = part_type if part_type
141
146
 
142
147
  result
143
148
  end
149
+
150
+ def execute_and_extract_lsblk_info(lsblk_version)
151
+ # lsblk 2.25 added support for GPT partition type GUIDs
152
+ stdout = if lsblk_version >= 2.25
153
+ Facter::Core::Execution.execute('lsblk -p -P -o NAME,FSTYPE,UUID,LABEL,PARTUUID,PARTLABEL,PARTTYPE', logger: log)
154
+ else
155
+ Facter::Core::Execution.execute('lsblk -p -P -o NAME,FSTYPE,LABEL,UUID,PARTUUID,PARTLABEL', logger: log)
156
+ end
157
+
158
+ output_hash = Hash[*stdout.split(/^(NAME=\S+)/)[1..-1]]
159
+ output_hash.transform_keys! { |key| key.delete('NAME=')[1..-2] }
160
+ output_hash.each do |key, value|
161
+ output_hash[key] = Hash[*value.chomp.rstrip.split(/ ([^= ]+)=/)[1..-1].each { |x| x.delete!('"') }]
162
+ end
163
+ output_hash.each_value { |value_hash| value_hash.delete_if { |_k, v| v.empty? } }
164
+ output_hash.delete_if { |_k, v| v.empty? }
165
+ end
144
166
  end
145
167
  end
146
168
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'set'
4
+
3
5
  module Facter
4
6
  module Resolvers
5
7
  module Linux
@@ -10,6 +12,7 @@ module Facter
10
12
 
11
13
  class << self
12
14
  # :count
15
+ # :extensions
13
16
  # :models
14
17
  # :physical_count
15
18
  # :speed
@@ -32,6 +35,7 @@ module Facter
32
35
  end
33
36
 
34
37
  def read_processors(cpuinfo_output)
38
+ @fact_list[:extensions] = Set[Facter::Resolvers::Uname.resolve(:processor)]
35
39
  @fact_list[:processors] = 0
36
40
  @fact_list[:models] = []
37
41
  @fact_list[:physical_processors] = []
@@ -41,7 +45,10 @@ module Facter
41
45
  construct_models_list(tokens)
42
46
  count_physical_processors(tokens)
43
47
  build_speed(tokens)
48
+ check_extensions(tokens)
44
49
  end
50
+ @fact_list[:extensions] = @fact_list[:extensions].to_a
51
+ @fact_list[:extensions].sort!
45
52
  end
46
53
 
47
54
  def count_processors(tokens)
@@ -82,6 +89,21 @@ module Facter
82
89
  speed = tokens.last.strip.match(/^(\d+).*/)[1]
83
90
  @fact_list[:speed] = speed.to_i * MHZ_TO_HZ
84
91
  end
92
+
93
+ def check_extensions(tokens)
94
+ return unless tokens.first.strip == 'flags'
95
+
96
+ flags = tokens.last.split(' ')
97
+
98
+ # TODO: As we gain support for other arches, change the guard
99
+ # so we only check the flags for the corosponding arches
100
+ return unless @fact_list[:extensions].include?('x86_64')
101
+
102
+ @fact_list[:extensions].add('x86_64-v1') if (%w[cmov cx8 fpu fxsr lm mmx syscall sse2] - flags).empty?
103
+ @fact_list[:extensions].add('x86_64-v2') if (%w[cx16 lahf_lm popcnt sse4_1 sse4_2 ssse3] - flags).empty?
104
+ @fact_list[:extensions].add('x86_64-v3') if (%w[abm avx avx2 bmi1 bmi2 f16c fma movbe xsave] - flags).empty?
105
+ @fact_list[:extensions].add('x86_64-v4') if (%w[avx512f avx512bw avx512cd avx512dq avx512vl] - flags).empty?
106
+ end
85
107
  end
86
108
  end
87
109
  end
@@ -10,7 +10,7 @@ module Facter
10
10
 
11
11
  PHYSICAL_HYPERVISORS = %w[physical xen0 vmware_server vmware_workstation openvzhn vserver_host].freeze
12
12
  REDHAT_FAMILY = %w[redhat rhel fedora centos scientific ascendos cloudlinux psbm
13
- oraclelinux ovs oel amazon xenserver xcp-ng virtuozzo photon mariner].freeze
13
+ oraclelinux ovs oel amazon xenserver xcp-ng virtuozzo photon mariner azurelinux].freeze
14
14
  DEBIAN_FAMILY = %w[debian ubuntu huaweios linuxmint devuan kde].freeze
15
15
  SUSE_FAMILY = %w[sles sled suse].freeze
16
16
  GENTOO_FAMILY = ['gentoo'].freeze
@@ -15,12 +15,14 @@ module Facter
15
15
  default_return
16
16
  end
17
17
 
18
- def safe_readlines(path, default_return = [])
19
- return File.readlines(path, encoding: Encoding::UTF_8) if File.readable?(path)
18
+ # rubocop:disable Style/SpecialGlobalVars
19
+ def safe_readlines(path, default_return = [], sep = $/, chomp: false)
20
+ return File.readlines(path, sep, chomp: chomp, encoding: Encoding::UTF_8) if File.readable?(path)
20
21
 
21
22
  log_failed_to_read(path)
22
23
  default_return
23
24
  end
25
+ # rubocop:enable Style/SpecialGlobalVars
24
26
 
25
27
  # This previously acted as a helper method for versions of Ruby older
26
28
  # than 2.5, before Dir.children was added. As it isn't a private
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facter
4
+ module Util
5
+ module Linux
6
+ class Proc
7
+ class << self
8
+ def getenv_for_pid(pid, field)
9
+ path = "/proc/#{pid}/environ"
10
+ lines = Facter::Util::FileHelper.safe_readlines(path, [], "\0", chomp: true)
11
+ lines.each do |line|
12
+ key, value = line.split('=', 2)
13
+ return value if key == field
14
+ end
15
+ nil
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Facter
4
- VERSION = '4.7.1' unless defined?(VERSION)
4
+ VERSION = '4.9.0' unless defined?(VERSION)
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: facter
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.7.1
4
+ version: 4.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-06 00:00:00.000000000 Z
11
+ date: 2024-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -346,6 +346,8 @@ files:
346
346
  - lib/facter/facts/amzn/os/distro/id.rb
347
347
  - lib/facter/facts/amzn/os/distro/release.rb
348
348
  - lib/facter/facts/amzn/os/release.rb
349
+ - lib/facter/facts/archlinux/os/release.rb
350
+ - lib/facter/facts/azurelinux/os/release.rb
349
351
  - lib/facter/facts/bsd/kernelmajversion.rb
350
352
  - lib/facter/facts/bsd/kernelversion.rb
351
353
  - lib/facter/facts/bsd/load_averages.rb
@@ -556,6 +558,7 @@ files:
556
558
  - lib/facter/facts/linux/processor.rb
557
559
  - lib/facter/facts/linux/processors/cores.rb
558
560
  - lib/facter/facts/linux/processors/count.rb
561
+ - lib/facter/facts/linux/processors/extensions.rb
559
562
  - lib/facter/facts/linux/processors/isa.rb
560
563
  - lib/facter/facts/linux/processors/models.rb
561
564
  - lib/facter/facts/linux/processors/physicalcount.rb
@@ -1149,6 +1152,7 @@ files:
1149
1152
  - lib/facter/util/file_helper.rb
1150
1153
  - lib/facter/util/linux/dhcp.rb
1151
1154
  - lib/facter/util/linux/if_inet6.rb
1155
+ - lib/facter/util/linux/proc.rb
1152
1156
  - lib/facter/util/linux/routing_table.rb
1153
1157
  - lib/facter/util/linux/socket_parser.rb
1154
1158
  - lib/facter/util/macosx/system_profile_executor.rb