puppet 6.11.1-universal-darwin → 6.12.0-universal-darwin

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +1 -1
  3. data/Gemfile +1 -0
  4. data/Gemfile.lock +16 -16
  5. data/README.md +1 -1
  6. data/ext/build_defaults.yaml +1 -0
  7. data/ext/windows/service/daemon.rb +22 -17
  8. data/lib/puppet/concurrent.rb +2 -0
  9. data/lib/puppet/concurrent/lock.rb +16 -0
  10. data/lib/puppet/concurrent/synchronized.rb +15 -0
  11. data/lib/puppet/concurrent/thread_local_singleton.rb +14 -0
  12. data/lib/puppet/configurer.rb +45 -31
  13. data/lib/puppet/defaults.rb +42 -3
  14. data/lib/puppet/environments.rb +3 -0
  15. data/lib/puppet/error.rb +9 -1
  16. data/lib/puppet/forge.rb +3 -3
  17. data/lib/puppet/forge/errors.rb +2 -2
  18. data/lib/puppet/forge/repository.rb +30 -86
  19. data/lib/puppet/functions/camelcase.rb +2 -2
  20. data/lib/puppet/functions/epp.rb +4 -4
  21. data/lib/puppet/functions/find_file.rb +9 -9
  22. data/lib/puppet/functions/find_template.rb +63 -0
  23. data/lib/puppet/functions/inline_epp.rb +5 -5
  24. data/lib/puppet/http.rb +2 -0
  25. data/lib/puppet/http/client.rb +89 -17
  26. data/lib/puppet/http/resolver.rb +14 -1
  27. data/lib/puppet/http/resolver/server_list.rb +38 -0
  28. data/lib/puppet/http/resolver/settings.rb +3 -2
  29. data/lib/puppet/http/resolver/srv.rb +10 -4
  30. data/lib/puppet/http/service.rb +32 -0
  31. data/lib/puppet/http/service/ca.rb +11 -10
  32. data/lib/puppet/http/service/report.rb +40 -0
  33. data/lib/puppet/http/session.rb +11 -32
  34. data/lib/puppet/network/http/base_pool.rb +13 -0
  35. data/lib/puppet/node/environment.rb +13 -7
  36. data/lib/puppet/pal/pal_impl.rb +5 -0
  37. data/lib/puppet/parser/functions/epp.rb +3 -3
  38. data/lib/puppet/parser/functions/inline_epp.rb +5 -5
  39. data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -1
  40. data/lib/puppet/pops/lookup/invocation.rb +10 -3
  41. data/lib/puppet/pops/model/pn_transformer.rb +5 -9
  42. data/lib/puppet/pops/parser/evaluating_parser.rb +3 -4
  43. data/lib/puppet/pops/serialization/json_path.rb +3 -3
  44. data/lib/puppet/pops/time/timespan.rb +3 -5
  45. data/lib/puppet/pops/types/string_converter.rb +6 -9
  46. data/lib/puppet/pops/types/type_calculator.rb +6 -10
  47. data/lib/puppet/pops/types/type_formatter.rb +9 -11
  48. data/lib/puppet/pops/types/type_parser.rb +3 -3
  49. data/lib/puppet/provider/package/portage.rb +3 -3
  50. data/lib/puppet/provider/package_targetable.rb +5 -4
  51. data/lib/puppet/provider/service/systemd.rb +1 -1
  52. data/lib/puppet/provider/user/hpux.rb +1 -1
  53. data/lib/puppet/runtime.rb +1 -0
  54. data/lib/puppet/ssl/ssl_provider.rb +20 -0
  55. data/lib/puppet/transaction.rb +33 -11
  56. data/lib/puppet/type.rb +1 -1
  57. data/lib/puppet/type/file/data_sync.rb +5 -1
  58. data/lib/puppet/type/group.rb +3 -2
  59. data/lib/puppet/type/user.rb +3 -2
  60. data/lib/puppet/util.rb +34 -11
  61. data/lib/puppet/util/logging.rb +30 -18
  62. data/lib/puppet/util/windows/adsi.rb +48 -18
  63. data/lib/puppet/version.rb +1 -1
  64. data/lib/puppet/x509/cert_provider.rb +9 -5
  65. data/locales/puppet.pot +155 -141
  66. data/man/man5/puppet.conf.5 +33 -3
  67. data/man/man8/puppet-agent.8 +1 -1
  68. data/man/man8/puppet-apply.8 +1 -1
  69. data/man/man8/puppet-catalog.8 +1 -1
  70. data/man/man8/puppet-config.8 +1 -1
  71. data/man/man8/puppet-describe.8 +1 -1
  72. data/man/man8/puppet-device.8 +1 -1
  73. data/man/man8/puppet-doc.8 +1 -1
  74. data/man/man8/puppet-epp.8 +1 -1
  75. data/man/man8/puppet-facts.8 +1 -1
  76. data/man/man8/puppet-filebucket.8 +1 -1
  77. data/man/man8/puppet-generate.8 +1 -1
  78. data/man/man8/puppet-help.8 +1 -1
  79. data/man/man8/puppet-key.8 +1 -1
  80. data/man/man8/puppet-lookup.8 +1 -1
  81. data/man/man8/puppet-man.8 +1 -1
  82. data/man/man8/puppet-module.8 +1 -1
  83. data/man/man8/puppet-node.8 +1 -1
  84. data/man/man8/puppet-parser.8 +1 -1
  85. data/man/man8/puppet-plugin.8 +1 -1
  86. data/man/man8/puppet-report.8 +1 -1
  87. data/man/man8/puppet-resource.8 +1 -1
  88. data/man/man8/puppet-script.8 +1 -1
  89. data/man/man8/puppet-ssl.8 +1 -1
  90. data/man/man8/puppet-status.8 +1 -1
  91. data/man/man8/puppet.8 +2 -2
  92. data/spec/fixtures/unit/forge/bacula.json +76 -0
  93. data/spec/integration/http/client_spec.rb +144 -0
  94. data/spec/integration/module_tool/forge_spec.rb +64 -0
  95. data/spec/lib/puppet_spec/https.rb +5 -3
  96. data/spec/spec_helper.rb +6 -2
  97. data/spec/unit/concurrent/lock_spec.rb +29 -0
  98. data/spec/unit/configurer_spec.rb +394 -399
  99. data/spec/unit/defaults_spec.rb +15 -4
  100. data/spec/unit/forge/errors_spec.rb +1 -1
  101. data/spec/unit/forge/forge_spec.rb +12 -54
  102. data/spec/unit/forge/module_release_spec.rb +19 -6
  103. data/spec/unit/forge/repository_spec.rb +63 -157
  104. data/spec/unit/forge_spec.rb +46 -116
  105. data/spec/unit/functions/find_template_spec.rb +69 -0
  106. data/spec/unit/http/client_spec.rb +138 -6
  107. data/spec/unit/http/resolver_spec.rb +49 -12
  108. data/spec/unit/http/service/ca_spec.rb +56 -5
  109. data/spec/unit/http/service/report_spec.rb +100 -0
  110. data/spec/unit/http/service_spec.rb +20 -0
  111. data/spec/unit/http/session_spec.rb +53 -18
  112. data/spec/unit/network/http/connection_spec.rb +0 -1
  113. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +8 -3
  114. data/spec/unit/provider/package/portage_spec.rb +4 -4
  115. data/spec/unit/provider/package_targetable_spec.rb +60 -0
  116. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  117. data/spec/unit/ssl/ssl_provider_spec.rb +71 -0
  118. data/spec/unit/transaction_spec.rb +46 -0
  119. data/spec/unit/type/file/content_spec.rb +9 -3
  120. data/spec/unit/util/log_spec.rb +0 -138
  121. data/spec/unit/util/logging_spec.rb +200 -0
  122. data/spec/unit/util/windows/adsi_spec.rb +51 -0
  123. data/spec/unit/x509/cert_provider_spec.rb +24 -4
  124. data/tasks/manpages.rake +1 -0
  125. metadata +24 -5
  126. data/spec/lib/puppet_spec/validators.rb +0 -37
@@ -1,3 +1,5 @@
1
+ require 'puppet/thread_local'
2
+
1
3
  require_relative 'explainer'
2
4
 
3
5
  module Puppet::Pops
@@ -7,7 +9,11 @@ class Invocation
7
9
  attr_reader :scope, :override_values, :default_values, :explainer, :module_name, :top_key, :adapter_class
8
10
 
9
11
  def self.current
10
- @current
12
+ (@current ||= Puppet::ThreadLocal.new(nil)).value
13
+ end
14
+
15
+ def self.current=(new_value)
16
+ @current.value = new_value
11
17
  end
12
18
 
13
19
  # Creates a new instance with same settings as this instance but with a new given scope
@@ -37,6 +43,7 @@ class Invocation
37
43
  @default_values = default_values
38
44
 
39
45
  parent_invocation = self.class.current
46
+
40
47
  if parent_invocation && (adapter_class.nil? || adapter_class == parent_invocation.adapter_class)
41
48
  # Inherit from parent invocation (track recursion)
42
49
  @name_stack = parent_invocation.name_stack
@@ -71,10 +78,10 @@ class Invocation
71
78
  yield
72
79
  else
73
80
  begin
74
- self.class.instance_variable_set(:@current, self)
81
+ self.class.current = self
75
82
  yield
76
83
  ensure
77
- self.class.instance_variable_set(:@current, save_current)
84
+ self.class.current = save_current
78
85
  end
79
86
  end
80
87
  end
@@ -1,22 +1,18 @@
1
+ require 'puppet/concurrent/thread_local_singleton'
2
+
1
3
  module Puppet::Pops
2
4
  module Model
3
5
 
4
6
 
5
7
  class PNTransformer
6
- def self.visitor
7
- @visitor ||= Visitor.new(nil, 'transform', 0, 0)
8
- end
9
-
10
- def self.singleton
11
- @singleton ||= new(visitor)
12
- end
8
+ extend Puppet::Concurrent::ThreadLocalSingleton
13
9
 
14
10
  def self.transform(ast)
15
11
  singleton.transform(ast)
16
12
  end
17
13
 
18
- def initialize(visitor)
19
- @visitor = visitor
14
+ def initialize
15
+ @visitor = Visitor.new(nil, 'transform', 0, 0)
20
16
  end
21
17
 
22
18
  def transform(ast)
@@ -1,9 +1,12 @@
1
+ require 'puppet/concurrent/thread_local_singleton'
2
+
1
3
  module Puppet::Pops
2
4
  module Parser
3
5
 
4
6
  # Does not support "import" and parsing ruby files
5
7
  #
6
8
  class EvaluatingParser
9
+ extend Puppet::Concurrent::ThreadLocalSingleton
7
10
 
8
11
  attr_reader :parser
9
12
 
@@ -11,10 +14,6 @@ class EvaluatingParser
11
14
  @parser = Parser.new()
12
15
  end
13
16
 
14
- def self.singleton
15
- @instance ||= new
16
- end
17
-
18
17
  def parse_string(s, file_source = nil)
19
18
  @file_source = file_source
20
19
  clear()
@@ -1,3 +1,5 @@
1
+ require 'puppet/concurrent/thread_local_singleton'
2
+
1
3
  module Puppet::Pops
2
4
  module Serialization
3
5
  module JsonPath
@@ -31,9 +33,7 @@ module JsonPath
31
33
  #
32
34
  # @api private
33
35
  class Resolver
34
- def self.singleton
35
- @singleton ||= self.new
36
- end
36
+ extend Puppet::Concurrent::ThreadLocalSingleton
37
37
 
38
38
  def initialize
39
39
  @parser = Parser::Parser.new
@@ -1,3 +1,5 @@
1
+ require 'puppet/concurrent/thread_local_singleton'
2
+
1
3
  module Puppet::Pops
2
4
  module Time
3
5
  NSECS_PER_USEC = 1000
@@ -581,9 +583,7 @@ module Time
581
583
 
582
584
  # Parses a string into a Timestamp::Format instance
583
585
  class FormatParser
584
- def self.singleton
585
- @singleton
586
- end
586
+ extend Puppet::Concurrent::ThreadLocalSingleton
587
587
 
588
588
  def initialize
589
589
  @formats = Hash.new { |hash, str| hash[str] = internal_parse(str) }
@@ -706,8 +706,6 @@ module Time
706
706
  end
707
707
  Format.new(str, bld)
708
708
  end
709
-
710
- @singleton = FormatParser.new
711
709
  end
712
710
 
713
711
  class Format
@@ -1,3 +1,5 @@
1
+ require 'puppet/concurrent/thread_local_singleton'
2
+
1
3
  module Puppet::Pops
2
4
  module Types
3
5
 
@@ -238,22 +240,17 @@ class StringConverter
238
240
  end
239
241
  end
240
242
 
243
+ extend Puppet::Concurrent::ThreadLocalSingleton
244
+
241
245
  # @api public
242
246
  def self.convert(value, string_formats = :default)
243
247
  singleton.convert(value, string_formats)
244
248
  end
245
249
 
246
- # @return [TypeConverter] the singleton instance
247
- #
248
- # @api public
249
- def self.singleton
250
- @tconv_instance ||= new
251
- end
252
-
253
250
  # @api private
254
251
  #
255
252
  def initialize
256
- @@string_visitor ||= Visitor.new(self, "string", 3, 3)
253
+ @string_visitor = Visitor.new(self, "string", 3, 3)
257
254
  end
258
255
 
259
256
  DEFAULT_INDENTATION = Indentation.new(0, true, false).freeze
@@ -523,7 +520,7 @@ class StringConverter
523
520
  # end
524
521
 
525
522
  def _convert(val_type, value, format_map, indentation)
526
- @@string_visitor.visit_this_3(self, val_type, value, format_map, indentation)
523
+ @string_visitor.visit_this_3(self, val_type, value, format_map, indentation)
527
524
  end
528
525
  private :_convert
529
526
 
@@ -1,3 +1,5 @@
1
+ require 'puppet/concurrent/thread_local_singleton'
2
+
1
3
  module Puppet::Pops
2
4
  module Types
3
5
  # The TypeCalculator can answer questions about puppet types.
@@ -99,6 +101,7 @@ module Types
99
101
  # @api public
100
102
  #
101
103
  class TypeCalculator
104
+ extend Puppet::Concurrent::ThreadLocalSingleton
102
105
 
103
106
  # @api public
104
107
  def self.assignable?(t1, t2)
@@ -135,18 +138,11 @@ class TypeCalculator
135
138
  singleton.iterable(t)
136
139
  end
137
140
 
138
- # @return [TypeCalculator] the singleton instance
139
- #
140
- # @api private
141
- def self.singleton
142
- @tc_instance ||= new
143
- end
144
-
145
141
  # @api public
146
142
  #
147
143
  def initialize
148
- @@infer_visitor ||= Visitor.new(nil, 'infer',0,0)
149
- @@extract_visitor ||= Visitor.new(nil, 'extract',0,0)
144
+ @infer_visitor = Visitor.new(nil, 'infer',0,0)
145
+ @extract_visitor = Visitor.new(nil, 'extract',0,0)
150
146
  end
151
147
 
152
148
  # Answers 'can an instance of type t2 be assigned to a variable of type t'.
@@ -250,7 +246,7 @@ class TypeCalculator
250
246
  elsif o.is_a?(Evaluator::PuppetProc)
251
247
  infer_PuppetProc(o)
252
248
  else
253
- @@infer_visitor.visit_this_0(self, o)
249
+ @infer_visitor.visit_this_0(self, o)
254
250
  end
255
251
  end
256
252
 
@@ -1,3 +1,5 @@
1
+ require 'puppet/concurrent/thread_local_singleton'
2
+
1
3
  module Puppet::Pops
2
4
  module Types
3
5
  # String
@@ -7,6 +9,8 @@ module Types
7
9
  # @api public
8
10
  #
9
11
  class TypeFormatter
12
+ extend Puppet::Concurrent::ThreadLocalSingleton
13
+
10
14
  # Produces a String representation of the given type.
11
15
  # @param t [PAnyType] the type to produce a string form
12
16
  # @return [String] the type in string form
@@ -14,14 +18,11 @@ class TypeFormatter
14
18
  # @api public
15
19
  #
16
20
  def self.string(t)
17
- @singleton.string(t)
21
+ singleton.string(t)
18
22
  end
19
23
 
20
- # @return [TypeCalculator] the singleton instance
21
- #
22
- # @api private
23
- def self.singleton
24
- @singleton
24
+ def initialize
25
+ @string_visitor = Visitor.new(nil, 'string',0,0)
25
26
  end
26
27
 
27
28
  def expanded
@@ -105,13 +106,13 @@ class TypeFormatter
105
106
  @ruby = false
106
107
  begin
107
108
  @bld << @ref_ctor << '('
108
- @@string_visitor.visit_this_0(self, TypeFormatter.new.string(t))
109
+ @string_visitor.visit_this_0(self, TypeFormatter.new.string(t))
109
110
  @bld << ')'
110
111
  ensure
111
112
  @ruby = true
112
113
  end
113
114
  else
114
- @@string_visitor.visit_this_0(self, t)
115
+ @string_visitor.visit_this_0(self, t)
115
116
  end
116
117
  end
117
118
 
@@ -794,9 +795,6 @@ class TypeFormatter
794
795
  def chomp_list
795
796
  @bld.chomp!(COMMA_SEP)
796
797
  end
797
-
798
- @singleton = new
799
- @@string_visitor = Visitor.new(nil, 'string',0,0)
800
798
  end
801
799
  end
802
800
  end
@@ -1,3 +1,5 @@
1
+ require 'puppet/concurrent/thread_local_singleton'
2
+
1
3
  # This class provides parsing of Type Specification from a string into the Type
2
4
  # Model that is produced by the TypeFactory.
3
5
  #
@@ -8,9 +10,7 @@
8
10
  module Puppet::Pops
9
11
  module Types
10
12
  class TypeParser
11
- def self.singleton
12
- @singleton ||= TypeParser.new
13
- end
13
+ extend Puppet::Concurrent::ThreadLocalSingleton
14
14
 
15
15
  # @api public
16
16
  def initialize
@@ -69,7 +69,7 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
69
69
  name = qatom[:pfx] + name if qatom[:pfx]
70
70
  name = name + '-' + qatom[:pv] if qatom[:pv]
71
71
  name = name + '-' + qatom[:pr] if qatom[:pr]
72
- name = name + qatom[:slot] if qatom[:slot]
72
+ name = name + ':' + qatom[:slot] if qatom[:slot]
73
73
  cmd << '--update' if [:latest].include?(should)
74
74
  cmd += install_options if @resource[:install_options]
75
75
  cmd << name
@@ -83,7 +83,7 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
83
83
  name = qatom[:pfx] + name if qatom[:pfx]
84
84
  name = name + '-' + qatom[:pv] if qatom[:pv]
85
85
  name = name + '-' + qatom[:pr] if qatom[:pr]
86
- name = name + qatom[:slot] if qatom[:slot]
86
+ name = name + ':' + qatom[:slot] if qatom[:slot]
87
87
  cmd += uninstall_options if @resource[:uninstall_options]
88
88
  cmd << name
89
89
  if [:purged].include?(should)
@@ -257,7 +257,7 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
257
257
  # [2.7.12: 2.7
258
258
  # 3.4.5: 3.4
259
259
  # 3.5.2: 3.5]
260
- version_for_slot = versions_and_slots.find { |version_and_slot| version_and_slot.last == slot[1..-1] }
260
+ version_for_slot = versions_and_slots.find { |version_and_slot| version_and_slot.last == slot }
261
261
  # [3.5.2: 3.5]
262
262
  version_for_slot.first if version_for_slot
263
263
  # 3.5.2
@@ -25,24 +25,25 @@ require 'puppet/provider/package'
25
25
  class Puppet::Provider::Package::Targetable < Puppet::Provider::Package
26
26
  # Prefetch our package list, yo.
27
27
  def self.prefetch(packages)
28
- catalog_packages = packages.first[1]::catalog::resources.select{ |p| p.provider.class == self }
28
+ catalog_packages = packages.values.first.catalog.resources.select{ |p| p.provider.class == self }
29
29
  package_commands = catalog_packages.map { |catalog_package| catalog_package::original_parameters[:command] }.uniq
30
30
  package_commands.each do |command|
31
31
  instances(command).each do |instance|
32
32
  catalog_packages.each do |catalog_package|
33
- if catalog_package[:name] == instance.name && catalog_package::original_parameters[:command] == command
33
+ if catalog_package[:name] == instance.name && catalog_package.original_parameters[:command] == command
34
34
  catalog_package.provider = instance
35
- self.debug "Prefetched instance: %{name} via command: %{command}" % { name: instance.name, cmd: (command || :default)}
35
+ self.debug "Prefetched instance: %{name} via command: %{cmd}" % { name: instance.name, cmd: (command || :default) }
36
36
  end
37
37
  end
38
38
  end
39
39
  end
40
+ package_commands
40
41
  end
41
42
 
42
43
  # Returns the resource command or provider command.
43
44
 
44
45
  def resource_or_provider_command
45
- resource::original_parameters[:command] || self.class.provider_command
46
+ resource.original_parameters[:command] || self.class.provider_command
46
47
  end
47
48
 
48
49
  # Targetable providers use has_command/is_optional to defer validation of provider suitability.
@@ -25,7 +25,7 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
25
25
  notdefaultfor :operatingsystem => :LinuxMint, :operatingsystemmajrelease => ["10", "11", "12", "13", "14", "15", "16", "17"] # These are using upstart
26
26
  defaultfor :operatingsystem => :ubuntu
27
27
  notdefaultfor :operatingsystem => :ubuntu, :operatingsystemmajrelease => ["10.04", "12.04", "14.04", "14.10"] # These are using upstart
28
- defaultfor :operatingsystem => :cumuluslinux, :operatingsystemmajrelease => ["3"]
28
+ defaultfor :operatingsystem => :cumuluslinux, :operatingsystemmajrelease => ["3", "4"]
29
29
 
30
30
  def self.instances
31
31
  i = []
@@ -29,7 +29,7 @@ Puppet::Type.type(:user).provide :hpuxuseradd, :parent => :useradd do
29
29
 
30
30
  def modifycmd(param,value)
31
31
  cmd = super(param, value)
32
- cmd << "-F"
32
+ cmd.insert(1,"-F")
33
33
  if trusted then
34
34
  # Append an additional command to reset the password age to 0
35
35
  # until a workaround with expiry module can be found for trusted
@@ -1,4 +1,5 @@
1
1
  require 'puppet/http'
2
+ require 'singleton'
2
3
 
3
4
  class Puppet::Runtime
4
5
  include Singleton
@@ -36,6 +36,26 @@ class Puppet::SSL::SSLProvider
36
36
  Puppet::SSL::SSLContext.new(store: store, cacerts: cacerts, crls: crls, revocation: revocation).freeze
37
37
  end
38
38
 
39
+ # Create an `SSLContext` using the trusted `cacerts` and any certs in OpenSSL's
40
+ # default verify path locations. When running puppet as a gem, the location is
41
+ # system dependent. When running puppet from puppet-agent packages, the location
42
+ # refers to the cacerts bundle in the puppet-agent package.
43
+ #
44
+ # Connections made from the returned context will authenticate the server,
45
+ # i.e. `VERIFY_PEER`, but will not use a client certificate and will not
46
+ # perform revocation checking.
47
+ #
48
+ # @param cacerts [Array<OpenSSL::X509::Certificate>] Array of trusted CA certs
49
+ # @return [Puppet::SSL::SSLContext] A context to use to create connections
50
+ # @raise (see #create_context)
51
+ # @api private
52
+ def create_system_context(cacerts:)
53
+ store = create_x509_store(cacerts, [], false)
54
+ store.set_default_paths
55
+
56
+ Puppet::SSL::SSLContext.new(store: store, cacerts: cacerts, crls: [], revocation: false).freeze
57
+ end
58
+
39
59
  # Create an `SSLContext` using the trusted `cacerts`, `crls`, `private_key`,
40
60
  # `client_cert`, and `revocation` mode. Connections made from the returned
41
61
  # context will be mutually authenticated.
@@ -57,7 +57,11 @@ class Puppet::Transaction
57
57
 
58
58
  @prefetch_failed_providers = Hash.new { |h,k| h[k] = {} }
59
59
 
60
+ # With merge_dependency_warnings, notify and warn about class dependency failures ... just once per class. TJK 2019-09-09
61
+ @merge_dependency_warnings = Puppet[:merge_dependency_warnings]
60
62
  @failed_dependencies_already_notified = Set.new()
63
+ @failed_class_dependencies_already_notified = Set.new()
64
+ @failed_class_dependencies_already_warned = Set.new()
61
65
  end
62
66
 
63
67
  # Invoke the pre_run_check hook in every resource in the catalog.
@@ -291,15 +295,25 @@ class Puppet::Transaction
291
295
  # explosion of edges, we also ended up reporting failures for containers
292
296
  # like class and stage. This is undesirable; while just skipping the
293
297
  # output isn't perfect, it is RC-safe. --daniel 2011-06-07
294
- suppress_report = (resource.class == Puppet::Type.type(:whit))
295
-
298
+ is_puppet_class = resource.class == Puppet::Type.type(:whit)
299
+ # With merge_dependency_warnings, notify about class dependency failures ... just once per class. TJK 2019-09-09
296
300
  s = resource_status(resource)
297
301
  if s && s.dependency_failed?
298
- # See above. --daniel 2011-06-06
299
- unless suppress_report then
300
- s.failed_dependencies.find_all { |d| !(@failed_dependencies_already_notified.include?(d.ref)) }.each do |dep|
301
- resource.notice _("Dependency %{dep} has failures: %{status}") % { dep: dep, status: resource_status(dep).failed }
302
- @failed_dependencies_already_notified.add(dep.ref)
302
+ if @merge_dependency_warnings && is_puppet_class
303
+ # Notes: Puppet::Resource::Status.failed_dependencies() is an Array of Puppet::Resource(s) and
304
+ # Puppet::Resource.ref() calls Puppet::Resource.to_s() which is: "#{type}[#{title}]" and
305
+ # Puppet::Resource.resource_status(resource) calls Puppet::Resource.to_s()
306
+ class_dependencies_to_be_notified = (s.failed_dependencies.map(&:ref) - @failed_class_dependencies_already_notified.to_a)
307
+ class_dependencies_to_be_notified.each do |dep_ref|
308
+ resource.notice _("Class dependency %{dep} has failures: %{status}") % { dep: dep_ref, status: resource_status(dep_ref).failed }
309
+ end
310
+ @failed_class_dependencies_already_notified.merge(class_dependencies_to_be_notified)
311
+ else
312
+ unless @merge_dependency_warnings || is_puppet_class
313
+ s.failed_dependencies.find_all { |d| !(@failed_dependencies_already_notified.include?(d.ref)) }.each do |dep|
314
+ resource.notice _("Dependency %{dep} has failures: %{status}") % { dep: dep, status: resource_status(dep).failed }
315
+ @failed_dependencies_already_notified.add(dep.ref)
316
+ end
303
317
  end
304
318
  end
305
319
  end
@@ -399,11 +413,19 @@ class Puppet::Transaction
399
413
  # explosion of edges, we also ended up reporting failures for containers
400
414
  # like class and stage. This is undesirable; while just skipping the
401
415
  # output isn't perfect, it is RC-safe. --daniel 2011-06-07
402
- unless resource.class == Puppet::Type.type(:whit) then
403
- resource.warning _("Skipping because of failed dependencies")
416
+ # With merge_dependency_warnings, warn about class dependency failures ... just once per class. TJK 2019-09-09
417
+ unless resource.class == Puppet::Type.type(:whit)
418
+ if @merge_dependency_warnings && resource.parent && failed_dependencies?(resource.parent)
419
+ ps = resource_status(resource.parent)
420
+ ps.failed_dependencies.find_all { |d| !(@failed_class_dependencies_already_warned.include?(d.ref)) }.each do |dep|
421
+ resource.parent.warning _("Skipping resources in class because of failed class dependencies")
422
+ @failed_class_dependencies_already_warned.add(dep.ref)
423
+ end
424
+ else
425
+ resource.warning _("Skipping because of failed dependencies")
426
+ end
404
427
  end
405
- elsif resource_status(resource).failed? &&
406
- @prefetch_failed_providers[resource.type][resource.provider.class.name]
428
+ elsif resource_status(resource).failed? && @prefetch_failed_providers[resource.type][resource.provider.class.name]
407
429
  #Do not try to evaluate a resource with a known failed provider
408
430
  resource.warning _("Skipping because provider prefetch failed")
409
431
  elsif resource.virtual?