facter 4.0.38 → 4.0.39

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4cded925592073cd18baac69fc11f1154cbeda4370359e9d3e6655f97194d467
4
- data.tar.gz: 16ea8f7a28b6ae86b0098a8c9412329dfa2665e1ca1a66ca3cc2d7e734452fa7
3
+ metadata.gz: e1cc7c2dc4026c1c24f4140c319b3ac68c5b77dd1b42e61c46f07facff044380
4
+ data.tar.gz: 3565addd16973284508cfc3058aab779dcf3bb30d4c65257fc9831cee898a380
5
5
  SHA512:
6
- metadata.gz: be78011c78dab1cdc01e44af6a2e2e053f3600c43a4c758e1edbf2b6a067052de36a8166749148fc2740694394af682c38cd7f72d516f75a323af9c69a278667
7
- data.tar.gz: 3b614e324b33c54c571e5857ea184dcf89d0e7e1fdc9030ee57478bdc3eaa6c0511d73f8f18441e33d31258ea5be7f227b3412770a90f82ed8fe789f9f3690f8
6
+ metadata.gz: ca715b689b8b050d20021ed104770a75737fed542236826592068d01066adfc369b222dbf94f2d1eb867c5b3d2023689f8ebd458f690f3f969e98c1c39375ddb
7
+ data.tar.gz: cf6be422f902d75dcbf6fb6d147c3c95f718ab2129a18756b0ffe0626f3cfb3fd4f652a8c9f3278801826a7e15e35e9574cf11e22780593f79db315c6aa3b87b
@@ -102,6 +102,19 @@ module Facter
102
102
  nil
103
103
  end
104
104
 
105
+ # Define a new fact or extend an existing fact.
106
+ #
107
+ # @param name [Symbol] The name of the fact to define
108
+ # @param options [Hash] A hash of options to set on the fact
109
+ #
110
+ # @return [Facter::Util::Fact] The fact that was defined
111
+ #
112
+ # @api public
113
+ def define_fact(name, options = {}, &block)
114
+ options[:fact_type] = :custom
115
+ LegacyFacter.define_fact(name, options, &block)
116
+ end
117
+
105
118
  def on_message(&block)
106
119
  Facter::Log.on_message(&block)
107
120
  end
@@ -125,6 +138,26 @@ module Facter
125
138
  Facter::Options[:debug] = debug_bool
126
139
  end
127
140
 
141
+ # Iterates over fact names and values
142
+ #
143
+ # @yieldparam [String] name the fact name
144
+ # @yieldparam [String] value the current value of the fact
145
+ #
146
+ # @return [Facter]
147
+ #
148
+ # @api public
149
+ def each
150
+ log_blocked_facts
151
+ resolved_facts = Facter::FactManager.instance.resolve_facts
152
+ SessionCache.invalidate_all_caches
153
+
154
+ resolved_facts.each do |fact|
155
+ yield(fact.name, fact.value)
156
+ end
157
+
158
+ self
159
+ end
160
+
128
161
  # Returns a fact object by name. If you use this, you still have to
129
162
  # call {Facter::Util::Fact#value `value`} on it to retrieve the actual
130
163
  # value.
@@ -155,6 +188,16 @@ module Facter
155
188
  nil
156
189
  end
157
190
 
191
+ # Loads all facts
192
+ #
193
+ # @return [nil]
194
+ #
195
+ # @api public
196
+ def loadfacts
197
+ LegacyFacter.loadfacts
198
+ nil
199
+ end
200
+
158
201
  # Register directories to be searched for custom facts. The registered directories
159
202
  # must be absolute paths or they will be ignored.
160
203
  #
@@ -6,6 +6,10 @@ module Facter
6
6
  class Base
7
7
  STDERR_MESSAGE = 'Command %s resulted with the following stderr message: %s'
8
8
 
9
+ def initialize
10
+ @log = Log.new(self)
11
+ end
12
+
9
13
  # This is part of the public API. No race condition can happen
10
14
  # here because custom facts are executed sequentially
11
15
  def with_env(values)
@@ -36,9 +40,7 @@ module Facter
36
40
  end
37
41
 
38
42
  def execute(command, options = {})
39
- on_fail = options.fetch(:on_fail, :raise)
40
- expand = options.fetch(:expand, true)
41
- logger = options[:logger]
43
+ on_fail, expand, logger, time_limit = extract_options(options)
42
44
 
43
45
  expanded_command = if !expand && builtin_command?(command) || logger
44
46
  command
@@ -55,11 +57,21 @@ module Facter
55
57
  return on_fail
56
58
  end
57
59
 
58
- execute_command(expanded_command, on_fail, logger)
60
+ execute_command(expanded_command, on_fail, logger, time_limit)
59
61
  end
60
62
 
61
63
  private
62
64
 
65
+ def extract_options(options)
66
+ on_fail = options.fetch(:on_fail, :raise)
67
+ expand = options.fetch(:expand, true)
68
+ logger = options[:logger]
69
+ time_limit = options[:limit].to_i
70
+ time_limit = time_limit.positive? ? time_limit : nil
71
+
72
+ [on_fail, expand, logger, time_limit]
73
+ end
74
+
63
75
  def log_stderr(msg, command, logger)
64
76
  return if !msg || msg.empty?
65
77
 
@@ -77,12 +89,30 @@ module Facter
77
89
  output.chomp =~ /builtin/ ? true : false
78
90
  end
79
91
 
80
- def execute_command(command, on_fail, logger = nil)
92
+ def execute_command(command, on_fail, logger = nil, time_limit = nil)
93
+ time_limit ||= 1.5
81
94
  begin
82
95
  # Set LC_ALL and LANG to force i18n to C for the duration of this exec;
83
96
  # this ensures that any code that parses the
84
97
  # output of the command can expect it to be in a consistent / predictable format / locale
85
- out, stderr, _status_ = Open3.capture3({ 'LC_ALL' => 'C', 'LANG' => 'C' }, command.to_s)
98
+ opts = { 'LC_ALL' => 'C', 'LANG' => 'C' }
99
+ require 'timeout'
100
+ @log.debug("Executing command: #{command}")
101
+ out, stderr = Open3.popen3(opts, command.to_s) do |_, stdout, stderr, wait_thr|
102
+ pid = wait_thr.pid
103
+ output = +''
104
+ err = +''
105
+ begin
106
+ Timeout.timeout(time_limit) do
107
+ output << stdout.read
108
+ err << stderr.read
109
+ end
110
+ rescue Timeout::Error
111
+ @log.debug("Timeout encounter after #{time_limit}s, killing process with pid: #{pid}")
112
+ Process.kill('KILL', pid)
113
+ end
114
+ [output, err]
115
+ end
86
116
  log_stderr(stderr, command, logger)
87
117
  rescue StandardError => e
88
118
  return '' if logger
@@ -6,7 +6,7 @@ module Facts
6
6
  FACT_NAME = 'kernel'
7
7
 
8
8
  def call_the_resolver
9
- fact_value = Facter::Resolvers::OsLevel.resolve(:kernel)
9
+ fact_value = Facter::Resolvers::Aix::OsLevel.resolve(:kernel)
10
10
 
11
11
  Facter::ResolvedFact.new(FACT_NAME, fact_value)
12
12
  end
@@ -6,7 +6,7 @@ module Facts
6
6
  FACT_NAME = 'kernelmajversion'
7
7
 
8
8
  def call_the_resolver
9
- fact_value = Facter::Resolvers::OsLevel.resolve(:build)
9
+ fact_value = Facter::Resolvers::Aix::OsLevel.resolve(:build)
10
10
  kernelmajversion = fact_value.split('-')[0]
11
11
 
12
12
  Facter::ResolvedFact.new(FACT_NAME, kernelmajversion)
@@ -6,7 +6,7 @@ module Facts
6
6
  FACT_NAME = 'kernelrelease'
7
7
 
8
8
  def call_the_resolver
9
- fact_value = Facter::Resolvers::OsLevel.resolve(:build).strip
9
+ fact_value = Facter::Resolvers::Aix::OsLevel.resolve(:build).strip
10
10
 
11
11
  Facter::ResolvedFact.new(FACT_NAME, fact_value)
12
12
  end
@@ -6,7 +6,7 @@ module Facts
6
6
  FACT_NAME = 'kernelversion'
7
7
 
8
8
  def call_the_resolver
9
- fact_value = Facter::Resolvers::OsLevel.resolve(:build)
9
+ fact_value = Facter::Resolvers::Aix::OsLevel.resolve(:build)
10
10
  kernelversion = fact_value.split('-')[0]
11
11
 
12
12
  Facter::ResolvedFact.new(FACT_NAME, kernelversion)
@@ -8,7 +8,7 @@ module Facts
8
8
  ALIASES = %w[operatingsystemmajrelease operatingsystemrelease].freeze
9
9
 
10
10
  def call_the_resolver
11
- fact_value = Facter::Resolvers::OsLevel.resolve(:build)
11
+ fact_value = Facter::Resolvers::Aix::OsLevel.resolve(:build)
12
12
  major = fact_value.split('-')[0]
13
13
 
14
14
  [Facter::ResolvedFact.new(FACT_NAME, full: fact_value.strip, major: major),
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facts
4
+ module Linux
5
+ class Cloud
6
+ FACT_NAME = 'cloud'
7
+
8
+ def call_the_resolver
9
+ cloud_provider = Facter::Resolvers::Cloud.resolve(:cloud_provider)
10
+
11
+ Facter::ResolvedFact.new(FACT_NAME, cloud_provider)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -25,7 +25,7 @@ module Facts
25
25
  def add_legacy_facts(disks, facts)
26
26
  disks.each do |disk_name, disk_info|
27
27
  facts.push(Facter::ResolvedFact.new("blockdevice_#{disk_name}_model", disk_info[:model], :legacy))
28
- facts.push(Facter::ResolvedFact.new("blockdevice_#{disk_name}_size", disk_info[:size_bytes].to_s, :legacy))
28
+ facts.push(Facter::ResolvedFact.new("blockdevice_#{disk_name}_size", disk_info[:size_bytes], :legacy))
29
29
  facts.push(Facter::ResolvedFact.new("blockdevice_#{disk_name}_vendor", disk_info[:vendor], :legacy))
30
30
  end
31
31
  end
@@ -16,9 +16,11 @@ module Facts
16
16
  private
17
17
 
18
18
  def aws_hypervisors?
19
- virtual = check_virt_what || check_xen || check_product_name || check_bios_vendor || check_lspci
19
+ virtual =~ /kvm|xen|aws/
20
+ end
20
21
 
21
- virtual == 'kvm' || virtual =~ /xen/
22
+ def virtual
23
+ check_virt_what || check_xen || check_product_name || check_bios_vendor || check_lspci
22
24
  end
23
25
 
24
26
  def check_virt_what
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sys/filesystem'
4
+
5
+ module Sys
6
+ class Filesystem
7
+ module Structs
8
+ class Statvfs < FFI::Struct
9
+ # We must remove the instance variable layout defined by sys-filesystem, because setting
10
+ # it the second time will make FFI log a warning message.
11
+ remove_instance_variable(:@layout) if @layout
12
+
13
+ if RbConfig::CONFIG['host_os'] =~ /darwin|osx|mach/i
14
+ layout(
15
+ :f_bsize, :ulong,
16
+ :f_frsize, :ulong,
17
+ :f_blocks, :uint,
18
+ :f_bfree, :uint,
19
+ :f_bavail, :uint,
20
+ :f_files, :uint,
21
+ :f_ffree, :uint,
22
+ :f_favail, :uint,
23
+ :f_fsid, :ulong,
24
+ :f_flag, :ulong,
25
+ :f_namemax, :ulong
26
+ )
27
+ elsif RbConfig::CONFIG['host'] =~ /bsd/i
28
+ layout(
29
+ :f_bavail, :uint64,
30
+ :f_bfree, :uint64,
31
+ :f_blocks, :uint64,
32
+ :f_favail, :uint64,
33
+ :f_ffree, :uint64,
34
+ :f_files, :uint64,
35
+ :f_bsize, :ulong,
36
+ :f_flag, :ulong,
37
+ :f_frsize, :ulong,
38
+ :f_fsid, :ulong,
39
+ :f_namemax, :ulong
40
+ )
41
+ elsif RbConfig::CONFIG['host'] =~ /sunos|solaris/i
42
+ layout(
43
+ :f_bsize, :ulong,
44
+ :f_frsize, :ulong,
45
+ :f_blocks, :uint64_t,
46
+ :f_bfree, :uint64_t,
47
+ :f_bavail, :uint64_t,
48
+ :f_files, :uint64_t,
49
+ :f_ffree, :uint64_t,
50
+ :f_favail, :uint64_t,
51
+ :f_fsid, :ulong,
52
+ :f_basetype, [:char, 16],
53
+ :f_flag, :ulong,
54
+ :f_namemax, :ulong,
55
+ :f_fstr, [:char, 32],
56
+ :f_filler, [:ulong, 16]
57
+ )
58
+ elsif RbConfig::CONFIG['host'] =~ /i686/i
59
+ layout(
60
+ :f_bsize, :ulong,
61
+ :f_frsize, :ulong,
62
+ :f_blocks, :uint,
63
+ :f_bfree, :uint,
64
+ :f_bavail, :uint,
65
+ :f_files, :uint,
66
+ :f_ffree, :uint,
67
+ :f_favail, :uint,
68
+ :f_fsid, :ulong,
69
+ :f_flag, :ulong,
70
+ :f_namemax, :ulong,
71
+ :f_spare, [:int, 6]
72
+ )
73
+ else
74
+ layout(
75
+ :f_bsize, :ulong,
76
+ :f_frsize, :ulong,
77
+ :f_blocks, :uint64,
78
+ :f_bfree, :uint64,
79
+ :f_bavail, :uint64,
80
+ :f_files, :uint64,
81
+ :f_ffree, :uint64,
82
+ :f_favail, :uint64,
83
+ :f_fsid, :ulong,
84
+ :f_flag, :ulong,
85
+ :f_namemax, :ulong,
86
+ :f_spare, [:int, 6]
87
+ )
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facter
4
+ module Resolvers
5
+ module Aix
6
+ class OsLevel < BaseResolver
7
+ @fact_list ||= {}
8
+
9
+ class << self
10
+ private
11
+
12
+ def post_resolve(fact_name)
13
+ @fact_list.fetch(fact_name) { read_oslevel(fact_name) }
14
+ end
15
+
16
+ def read_oslevel(fact_name)
17
+ output = Facter::Core::Execution.execute('/usr/bin/oslevel -s', { limit: 2, logger: log })
18
+ @fact_list[:build] = output unless output.empty?
19
+ @fact_list[:kernel] = 'AIX'
20
+
21
+ @fact_list[fact_name]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Facter
4
+ module Resolvers
5
+ class Cloud < BaseResolver
6
+ # cloud_provider
7
+
8
+ @fact_list ||= {}
9
+
10
+ class << self
11
+ private
12
+
13
+ def post_resolve(fact_name)
14
+ @fact_list.fetch(fact_name) { detect_azure(fact_name) }
15
+ end
16
+
17
+ def detect_azure(fact_name)
18
+ search_dirs = %w[/var/lib/dhcp /var/lib/NetworkManager]
19
+ search_dirs.each do |path|
20
+ next if !File.readable?(path) || !File.directory?(path)
21
+
22
+ files = Dir.entries(path)
23
+ files.select! { |filename| filename =~ /^dhclient.*lease.*$/ }
24
+ files.each do |file|
25
+ path = File.join([path, file])
26
+ output = Util::FileHelper.safe_read(path)
27
+
28
+ if output.include?('option unknown-245') || output.include?('option 245')
29
+ @fact_list[:cloud_provider] = 'azure'
30
+ return @fact_list[fact_name]
31
+ end
32
+ end
33
+ end
34
+ nil
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -7,7 +7,9 @@ module Facter
7
7
  size_bytes used used_bytes capacity].freeze
8
8
  class << self
9
9
  def read_mountpoints
10
- require 'sys/filesystem'
10
+ # TODO: this require must be replaced with "require 'sys/filesystem'" when a new release of
11
+ # djberg96/sys-filesystem gem is available
12
+ require_relative '../../patches/sysfilesystem/sys/statvfs.rb'
11
13
  force_utf(Sys::Filesystem.mounts)
12
14
  end
13
15
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Facter
4
- VERSION = '4.0.38' unless defined?(VERSION)
4
+ VERSION = '4.0.39' 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.0.38
4
+ version: 4.0.39
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-16 00:00:00.000000000 Z
11
+ date: 2020-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -385,6 +385,7 @@ files:
385
385
  - lib/facter/facts/freebsd/zpool_version.rb
386
386
  - lib/facter/facts/linux/aio_agent_version.rb
387
387
  - lib/facter/facts/linux/augeas/version.rb
388
+ - lib/facter/facts/linux/cloud.rb
388
389
  - lib/facter/facts/linux/dhcp_servers.rb
389
390
  - lib/facter/facts/linux/disks.rb
390
391
  - lib/facter/facts/linux/dmi/bios/release_date.rb
@@ -853,6 +854,7 @@ files:
853
854
  - lib/facter/models/resolved_fact.rb
854
855
  - lib/facter/models/searched_fact.rb
855
856
  - lib/facter/os_hierarchy.json
857
+ - lib/facter/patches/sysfilesystem/sys/statvfs.rb
856
858
  - lib/facter/resolvers/aio_agent_version.rb
857
859
  - lib/facter/resolvers/aix/architecture_resolver.rb
858
860
  - lib/facter/resolvers/aix/disks.rb
@@ -864,7 +866,7 @@ files:
864
866
  - lib/facter/resolvers/aix/mountpoints.rb
865
867
  - lib/facter/resolvers/aix/networking_resolver.rb
866
868
  - lib/facter/resolvers/aix/nim.rb
867
- - lib/facter/resolvers/aix/os_level_resolver.rb
869
+ - lib/facter/resolvers/aix/os_level.rb
868
870
  - lib/facter/resolvers/aix/partitions.rb
869
871
  - lib/facter/resolvers/aix/processors.rb
870
872
  - lib/facter/resolvers/aix/serialnumber.rb
@@ -874,6 +876,7 @@ files:
874
876
  - lib/facter/resolvers/base_resolver.rb
875
877
  - lib/facter/resolvers/bsd/ffi/ffi_helper.rb
876
878
  - lib/facter/resolvers/bsd/processors.rb
879
+ - lib/facter/resolvers/cloud.rb
877
880
  - lib/facter/resolvers/containers.rb
878
881
  - lib/facter/resolvers/debian_version.rb
879
882
  - lib/facter/resolvers/disk_resolver.rb
@@ -914,7 +917,6 @@ files:
914
917
  - lib/facter/resolvers/networking_linux_resolver.rb
915
918
  - lib/facter/resolvers/networking_resolver.rb
916
919
  - lib/facter/resolvers/open_vz.rb
917
- - lib/facter/resolvers/os_level_resolver.rb
918
920
  - lib/facter/resolvers/os_release_resolver.rb
919
921
  - lib/facter/resolvers/partitions.rb
920
922
  - lib/facter/resolvers/path_resolver.rb
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Facter
4
- module Resolvers
5
- class OsLevel < BaseResolver
6
- @fact_list ||= {}
7
-
8
- class << self
9
- private
10
-
11
- def post_resolve(fact_name)
12
- @fact_list.fetch(fact_name) { read_oslevel(fact_name) }
13
- end
14
-
15
- def read_oslevel(fact_name)
16
- output = Facter::Core::Execution.execute('/usr/bin/oslevel -s', logger: log)
17
- @fact_list[:build] = output
18
- @fact_list[:kernel] = 'AIX'
19
-
20
- @fact_list[fact_name]
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Facter
4
- module Resolvers
5
- class OsLevel < BaseResolver
6
- # build
7
-
8
- @fact_list ||= {}
9
-
10
- class << self
11
- private
12
-
13
- def post_resolve(fact_name)
14
- @fact_list.fetch(fact_name) { read_oslevel(fact_name) }
15
- end
16
-
17
- def read_oslevel(fact_name)
18
- output = Facter::Core::Execution.execute('/usr/bin/oslevel -s', logger: log)
19
-
20
- @fact_list[:build] = output unless output.empty?
21
- @fact_list[:kernel] = 'AIX'
22
-
23
- @fact_list[fact_name]
24
- end
25
- end
26
- end
27
- end
28
- end