facter 4.0.39 → 4.0.44

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/bin/facter +3 -4
  3. data/lib/facter.rb +107 -28
  4. data/lib/facter/config.rb +354 -0
  5. data/lib/facter/custom_facts/core/aggregate.rb +51 -17
  6. data/lib/facter/custom_facts/core/execution.rb +27 -35
  7. data/lib/facter/custom_facts/core/execution/base.rb +13 -7
  8. data/lib/facter/custom_facts/util/directory_loader.rb +1 -1
  9. data/lib/facter/custom_facts/util/fact.rb +1 -1
  10. data/lib/facter/custom_facts/util/resolution.rb +40 -11
  11. data/lib/facter/facts/aix/disks.rb +1 -1
  12. data/lib/facter/facts/linux/ec2_metadata.rb +5 -29
  13. data/lib/facter/facts/linux/ec2_userdata.rb +5 -27
  14. data/lib/facter/facts/linux/is_virtual.rb +7 -46
  15. data/lib/facter/facts/linux/virtual.rb +3 -58
  16. data/lib/facter/facts/rhel/os/release.rb +1 -1
  17. data/lib/facter/facts/solaris/disks.rb +1 -1
  18. data/lib/facter/facts/solaris/zones.rb +1 -1
  19. data/lib/facter/facts_utils/virtual_detector.rb +78 -0
  20. data/lib/facter/framework/benchmarking/timer.rb +4 -2
  21. data/lib/facter/framework/cli/cli.rb +83 -36
  22. data/lib/facter/framework/cli/cli_launcher.rb +34 -38
  23. data/lib/facter/framework/config/fact_groups.rb +41 -7
  24. data/lib/facter/framework/core/cache_manager.rb +43 -23
  25. data/lib/facter/framework/core/fact_loaders/fact_loader.rb +14 -11
  26. data/lib/facter/framework/core/options/config_file_options.rb +5 -3
  27. data/lib/facter/framework/core/options/option_store.rb +60 -27
  28. data/lib/facter/framework/detector/os_hierarchy.rb +5 -9
  29. data/lib/facter/framework/logging/logger.rb +1 -5
  30. data/lib/facter/resolvers/aix/architecture_resolver.rb +15 -1
  31. data/lib/facter/resolvers/aix/os_level.rb +1 -1
  32. data/lib/facter/resolvers/augeas_resolver.rb +7 -1
  33. data/lib/facter/resolvers/bsd/processors.rb +11 -7
  34. data/lib/facter/resolvers/disk_resolver.rb +11 -3
  35. data/lib/facter/resolvers/dmi_decode.rb +1 -0
  36. data/lib/facter/resolvers/dmi_resolver.rb +2 -2
  37. data/lib/facter/resolvers/freebsd/geom_resolver.rb +12 -20
  38. data/lib/facter/resolvers/freebsd/processors.rb +11 -7
  39. data/lib/facter/resolvers/memory_resolver.rb +12 -14
  40. data/lib/facter/resolvers/mountpoints_resolver.rb +50 -22
  41. data/lib/facter/resolvers/networking_linux_resolver.rb +10 -5
  42. data/lib/facter/resolvers/partitions.rb +60 -57
  43. data/lib/facter/resolvers/processors_resolver.rb +5 -1
  44. data/lib/facter/resolvers/solaris/dmi.rb +2 -0
  45. data/lib/facter/resolvers/solaris/mountpoints.rb +60 -0
  46. data/lib/facter/resolvers/solaris/networking.rb +1 -2
  47. data/lib/facter/resolvers/solaris/os_release.rb +4 -3
  48. data/lib/facter/resolvers/ssh_resolver.rb +4 -4
  49. data/lib/facter/version.rb +1 -1
  50. metadata +5 -4
  51. data/lib/facter/fact_groups.conf +0 -308
  52. data/lib/facter/os_hierarchy.json +0 -36
@@ -18,22 +18,31 @@ module Facter
18
18
  include LegacyFacter::Core::Resolvable
19
19
 
20
20
  # @!attribute [r] name
21
- # @return [Symbol] The name of the aggregate resolution
21
+ #
22
+ # @return [Symbol] The name of the aggregate resolution
23
+ #
24
+ # @api public
22
25
  attr_reader :name
23
26
 
24
27
  # @!attribute [r] deps
25
- # @api private
26
- # @return [LegacyFacter::Core::DirectedGraph]
28
+ #
29
+ # @return [LegacyFacter::Core::DirectedGraph]
30
+ #
31
+ # @api private
27
32
  attr_reader :deps
28
33
 
29
34
  # @!attribute [r] confines
30
- # @return [Array<LegacyFacter::Core::Confine>] An array of confines restricting
31
- # this to a specific platform
32
- # @see Facter::Core::Suitable
35
+ #
36
+ # @return [Array<LegacyFacter::Core::Confine>] An array of confines restricting
37
+ # this to a specific platform
38
+ #
39
+ # @api private
33
40
  attr_reader :confines
34
41
 
35
42
  # @!attribute [r] fact
43
+ #
36
44
  # @return [Facter::Util::Fact]
45
+ #
37
46
  # @api private
38
47
  attr_reader :fact
39
48
 
@@ -48,10 +57,20 @@ module Facter
48
57
  @deps = LegacyFacter::Core::DirectedGraph.new
49
58
  end
50
59
 
60
+ # Compares the weight of two aggregate facts
61
+ #
62
+ # @return [bool] Weight comparison result
63
+ #
64
+ # @api private
51
65
  def <=>(other)
52
66
  weight <=> other.weight
53
67
  end
54
68
 
69
+ # Sets options for the aggregate fact
70
+ #
71
+ # @return [nil]
72
+ #
73
+ # @api private
55
74
  def options(options)
56
75
  accepted_options = %i[name timeout weight fact_type]
57
76
  accepted_options.each do |option_name|
@@ -60,14 +79,17 @@ module Facter
60
79
  raise ArgumentError, "Invalid aggregate options #{options.keys.inspect}" unless options.keys.empty?
61
80
  end
62
81
 
82
+ # Evaluates the given block
83
+ #
84
+ # @return [String] Result of the block's evaluation
85
+ #
86
+ # @api private
63
87
  def evaluate(&block)
64
88
  instance_eval(&block)
65
89
  end
66
90
 
67
91
  # Define a new chunk for the given aggregate
68
92
  #
69
- # @api public
70
- #
71
93
  # @example Defining a chunk with no dependencies
72
94
  # aggregate.chunk(:mountpoints) do
73
95
  # # generate mountpoint information
@@ -80,14 +102,14 @@ module Facter
80
102
  # end
81
103
  #
82
104
  # @param name [Symbol] A name unique to this aggregate describing the chunk
83
- # @param opts [Hash]
84
- # @options opts [Array<Symbol>, Symbol] :require One or more chunks
85
- # to evaluate and pass to this block.
86
- # @yield [*Object] Zero or more chunk results
87
105
  #
88
- # @return [void]
106
+ # @param opts [Hash] Hash with options for the aggregate fact
107
+ #
108
+ # @return [Facter::Core::Aggregate] The aggregate object
109
+ #
110
+ # @api public
89
111
  def chunk(name, opts = {}, &block)
90
- raise ArgumentError, "#{self.class.name}#chunk requires a block" unless block_given?
112
+ evaluate_params(name, &block)
91
113
 
92
114
  deps = Array(opts.delete(:require))
93
115
 
@@ -97,12 +119,11 @@ module Facter
97
119
 
98
120
  @deps[name] = deps
99
121
  @chunks[name] = block
122
+ self
100
123
  end
101
124
 
102
125
  # Define how all chunks should be combined
103
126
  #
104
- # @api public
105
- #
106
127
  # @example Merge all chunks
107
128
  # aggregate.aggregate do |chunks|
108
129
  # final_result = {}
@@ -124,19 +145,32 @@ module Facter
124
145
  # @yield [Hash<Symbol, Object>] A hash containing chunk names and
125
146
  # chunk values
126
147
  #
127
- # @return [void]
148
+ # @return [Facter::Core::Aggregate] The aggregate fact
149
+ #
150
+ # @api public
128
151
  def aggregate(&block)
129
152
  raise ArgumentError, "#{self.class.name}#aggregate requires a block" unless block_given?
130
153
 
131
154
  @aggregate = block
155
+ self
132
156
  end
133
157
 
158
+ # Returns the fact's resolution type
159
+ #
160
+ # @return [Symbol] The fact's type
161
+ #
162
+ # @api private
134
163
  def resolution_type
135
164
  :aggregate
136
165
  end
137
166
 
138
167
  private
139
168
 
169
+ def evaluate_params(name)
170
+ raise ArgumentError, "#{self.class.name}#chunk requires a block" unless block_given?
171
+ raise ArgumentError, "#{self.class.name}#expected chunk name to be a Symbol" unless name.is_a? Symbol
172
+ end
173
+
140
174
  # Evaluate the results of this aggregate.
141
175
  #
142
176
  # @see Facter::Core::Resolvable#value
@@ -3,10 +3,6 @@
3
3
  module Facter
4
4
  module Core
5
5
  module Execution
6
- # require_relative 'execution/base'
7
- # require_relative 'execution/windows'
8
- # require_relative 'execution/posix'
9
-
10
6
  @@impl = if LegacyFacter::Util::Config.windows?
11
7
  Facter::Core::Execution::Windows.new
12
8
  else
@@ -20,24 +16,22 @@ module Facter
20
16
  module_function
21
17
 
22
18
  # Returns the locations to be searched when looking for a binary. This
23
- # is currently determined by the +PATH+ environment variable plus
24
- # `/sbin` and `/usr/sbin` when run on unix
19
+ # is currently determined by the +PATH+ environment variable plus
20
+ # `/sbin` and `/usr/sbin` when run on unix
21
+ #
22
+ # @return [Array<String>] The paths to be searched for binaries
25
23
  #
26
- # @return [Array<String>] the paths to be searched for binaries
27
24
  # @api private
28
25
  def search_paths
29
26
  @@impl.search_paths
30
27
  end
31
28
 
32
29
  # Determines the full path to a binary. If the supplied filename does not
33
- # already describe an absolute path then different locations (determined
34
- # by {search_paths}) will be searched for a match.
30
+ # already describe an absolute path then different locations (determined
31
+ # by {search_paths}) will be searched for a match.
32
+ # @param bin [String] The executable to locate
35
33
  #
36
- # Returns nil if no matching executable can be found otherwise returns
37
- # the expanded pathname.
38
- #
39
- # @param bin [String] the executable to locate
40
- # @return [String,nil] the full path to the executable or nil if not
34
+ # @return [String/nil] The full path to the executable or nil if not
41
35
  # found
42
36
  #
43
37
  # @api public
@@ -46,10 +40,12 @@ module Facter
46
40
  end
47
41
 
48
42
  # Determine in a platform-specific way whether a path is absolute. This
49
- # defaults to the local platform if none is specified.
43
+ # defaults to the local platform if none is specified.
44
+ # @param path [String] The path to check
45
+
46
+ # @param platform [:posix/:windows/nil] The platform logic to use
50
47
  #
51
- # @param path [String] the path to check
52
- # @param platform [:posix,:windows,nil] the platform logic to use
48
+ # @api private
53
49
  def absolute_path?(path, platform = nil)
54
50
  case platform
55
51
  when :posix
@@ -62,38 +58,35 @@ module Facter
62
58
  end
63
59
 
64
60
  # Given a command line, this returns the command line with the
65
- # executable written as an absolute path. If the executable contains
66
- # spaces, it has be put in double quotes to be properly recognized.
67
- #
61
+ # executable written as an absolute path. If the executable contains
62
+ # spaces, it has to be put in double quotes to be properly recognized.
68
63
  # @param command [String] the command line
69
64
  #
70
- # @return [String, nil] the command line with the executable's path
71
- # expanded, or nil if the executable cannot be found.
65
+ # @return [String/nil] The command line with the executable's path
66
+ # expanded, or nil if the executable cannot be found.
67
+ #
68
+ # @api private
72
69
  def expand_command(command)
73
70
  @@impl.expand_command(command)
74
71
  end
75
72
 
76
73
  # Overrides environment variables within a block of code. The
77
- # specified values will be set for the duration of the block, after
78
- # which the original values (if any) will be restored.
79
- #
80
- # @overload with_env(values, { || ... })
81
- #
74
+ # specified values will be set for the duration of the block, after
75
+ # which the original values (if any) will be restored.
82
76
  # @param values [Hash<String=>String>] A hash of the environment
83
77
  # variables to override
84
78
  #
85
- # @return [void]
79
+ # @return [String] The block's return string
86
80
  #
87
- # @api public
81
+ # @api private
88
82
  def with_env(values, &block)
89
83
  @@impl.with_env(values, &block)
90
84
  end
91
85
 
92
86
  # Try to execute a command and return the output.
87
+ # @param command [String] Command to run
93
88
  #
94
- # @param code [String] the program to run
95
- #
96
- # @return [String] the output of the program, or nil if the command does
89
+ # @return [String/nil] Output of the program, or nil if the command does
97
90
  # not exist or could not be executed.
98
91
  #
99
92
  # @deprecated Use #{execute} instead
@@ -103,9 +96,9 @@ module Facter
103
96
  end
104
97
 
105
98
  # Execute a command and return the output of that program.
99
+ # @param command [String] Command to run
106
100
  #
107
- # @param code [String] the program to run
108
- # @param options [Hash]
101
+ # @param options [Hash] Hash with options for the aggregate fact
109
102
  #
110
103
  # @option options [Object] :on_fail How to behave when the command could
111
104
  # not be run. Specifying :raise will raise an error, anything else will
@@ -118,7 +111,6 @@ module Facter
118
111
  # command execution failed and :on_fail was specified.
119
112
  #
120
113
  # @api public
121
- # @since 2.0.1
122
114
  def execute(command, options = {})
123
115
  @@impl.execute(command, options)
124
116
  end
@@ -90,7 +90,7 @@ module Facter
90
90
  end
91
91
 
92
92
  def execute_command(command, on_fail, logger = nil, time_limit = nil)
93
- time_limit ||= 1.5
93
+ time_limit ||= 300
94
94
  begin
95
95
  # Set LC_ALL and LANG to force i18n to C for the duration of this exec;
96
96
  # this ensures that any code that parses the
@@ -100,18 +100,24 @@ module Facter
100
100
  @log.debug("Executing command: #{command}")
101
101
  out, stderr = Open3.popen3(opts, command.to_s) do |_, stdout, stderr, wait_thr|
102
102
  pid = wait_thr.pid
103
- output = +''
104
- err = +''
103
+ stdout_messages = +''
104
+ stderr_messages = +''
105
+ out_reader = Thread.new { stdout.read }
106
+ err_reader = Thread.new { stderr.read }
105
107
  begin
106
108
  Timeout.timeout(time_limit) do
107
- output << stdout.read
108
- err << stderr.read
109
+ stdout_messages << out_reader.value
110
+ stderr_messages << err_reader.value
109
111
  end
110
112
  rescue Timeout::Error
111
- @log.debug("Timeout encounter after #{time_limit}s, killing process with pid: #{pid}")
113
+ message = "Timeout encounter after #{time_limit}s, killing process with pid: #{pid}"
112
114
  Process.kill('KILL', pid)
115
+ on_fail == :raise ? (raise StandardError, message) : @log.debug(message)
116
+ ensure
117
+ out_reader.kill
118
+ err_reader.kill
113
119
  end
114
- [output, err]
120
+ [stdout_messages, stderr_messages]
115
121
  end
116
122
  log_stderr(stderr, command, logger)
117
123
  rescue StandardError => e
@@ -59,7 +59,7 @@ module LegacyFacter
59
59
  basename = File.basename(file)
60
60
  next if file_blocked?(basename)
61
61
 
62
- if facts.find { |f| f.name == basename } && cm.group_cached?(basename)
62
+ if facts.find { |f| f.name == basename } && cm.fact_cache_enabled?(basename)
63
63
  Facter.log_exception(Exception.new("Caching is enabled for group \"#{basename}\" while "\
64
64
  'there are at least two external facts files with the same filename'))
65
65
  else
@@ -155,7 +155,7 @@ module Facter
155
155
  @searching
156
156
  end
157
157
 
158
- # Lock our searching process, so we never ge stuck in recursion.
158
+ # Lock our searching process, so we never get stuck in recursion.
159
159
  def searching
160
160
  raise "Caught recursion on #{@name}" if searching?
161
161
 
@@ -14,6 +14,8 @@ module Facter
14
14
  class Resolution
15
15
  # @api private
16
16
  attr_accessor :code, :fact_type
17
+
18
+ # @api private
17
19
  attr_writer :value
18
20
 
19
21
  extend Facter::Core::Execution
@@ -24,7 +26,12 @@ module Facter
24
26
  # compatibility.
25
27
  #
26
28
  # @deprecated
27
- public :search_paths, :which, :absolute_path?, :expand_command, :with_env, :exec
29
+ #
30
+ # @api public
31
+ public :which, :exec
32
+
33
+ # @api private
34
+ public :with_env
28
35
  end
29
36
 
30
37
  include LegacyFacter::Core::Resolvable
@@ -32,22 +39,27 @@ module Facter
32
39
 
33
40
  # @!attribute [rw] name
34
41
  # The name of this resolution. The resolution name should be unique with
35
- # respect to the given fact.
42
+ # respect to the given fact.
43
+ #
36
44
  # @return [String]
45
+ #
37
46
  # @api public
38
47
  attr_accessor :name
39
48
 
40
49
  # @!attribute [r] fact
41
- # @return [Facter::Util::Fact]
50
+ #
51
+ # @return [Facter::Util::Fact] Associated fact with this resolution.
52
+ #
42
53
  # @api private
43
54
  attr_reader :fact
44
55
 
45
56
  # Create a new resolution mechanism.
46
57
  #
47
58
  # @param name [String] The name of the resolution.
48
- # @return [void]
49
59
  #
50
- # @api private
60
+ # @return [Facter::Util::Resolution] The created resolution
61
+ #
62
+ # @api public
51
63
  def initialize(name, fact)
52
64
  @name = name
53
65
  @fact = fact
@@ -57,6 +69,11 @@ module Facter
57
69
  @weight = nil
58
70
  end
59
71
 
72
+ # Returns the fact's resolution type
73
+ #
74
+ # @return [Symbol] The fact's type
75
+ #
76
+ # @api private
60
77
  def resolution_type
61
78
  :simple
62
79
  end
@@ -64,7 +81,9 @@ module Facter
64
81
  # Evaluate the given block in the context of this resolution. If a block has
65
82
  # already been evaluated emit a warning to that effect.
66
83
  #
67
- # @return [void]
84
+ # @return [String] Result of the block's evaluation
85
+ #
86
+ # @api private
68
87
  def evaluate(&block)
69
88
  if @last_evaluated
70
89
  msg = "Already evaluated #{@name}"
@@ -85,6 +104,11 @@ module Facter
85
104
  end
86
105
  end
87
106
 
107
+ # Sets options for the aggregate fact
108
+ #
109
+ # @return [nil]
110
+ #
111
+ # @api private
88
112
  def options(options)
89
113
  accepted_options = %i[name value timeout weight fact_type file]
90
114
 
@@ -98,8 +122,6 @@ module Facter
98
122
  # Sets the code block or external program that will be evaluated to
99
123
  # get the value of the fact.
100
124
  #
101
- # @return [void]
102
- #
103
125
  # @overload setcode(string)
104
126
  # Sets an external program to call to get the value of the resolution
105
127
  # @param [String] string the external program to run to get the
@@ -111,6 +133,8 @@ module Facter
111
133
  # This block is run when the fact is evaluated. Errors raised from
112
134
  # inside the block are rescued and printed to stderr.
113
135
  #
136
+ # @return [Facter::Util::Resolution] Returns itself
137
+ #
114
138
  # @api public
115
139
  def setcode(string = nil, &block)
116
140
  if string
@@ -127,11 +151,16 @@ module Facter
127
151
  else
128
152
  raise ArgumentError, 'You must pass either code or a block'
129
153
  end
154
+ self
130
155
  end
131
156
 
132
- # Comparation is done based on weight and fact type.
133
- # The greatter the weight, the higher the priority.
134
- # If weights are equal, we consider external facts greater than custom facts
157
+ # Comparison is done based on weight and fact type.
158
+ # The greater the weight, the higher the priority.
159
+ # If weights are equal, we consider external facts greater than custom facts.
160
+ #
161
+ # @return [bool] Weight comparison result
162
+ #
163
+ # @api private
135
164
  def <=>(other)
136
165
  return compare_equal_weights(other) if weight == other.weight
137
166
  return 1 if weight > other.weight