puppet 4.0.0 → 4.1.0

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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/ext/build_defaults.yaml +8 -35
  3. data/ext/debian/puppet.default +0 -5
  4. data/ext/debian/puppet.init +1 -15
  5. data/lib/hiera/puppet_function.rb +15 -4
  6. data/lib/puppet/application/agent.rb +5 -0
  7. data/lib/puppet/application/apply.rb +23 -2
  8. data/lib/puppet/application/device.rb +8 -3
  9. data/lib/puppet/application/master.rb +16 -5
  10. data/lib/puppet/configurer.rb +7 -5
  11. data/lib/puppet/defaults.rb +18 -0
  12. data/lib/puppet/environments.rb +1 -1
  13. data/lib/puppet/error.rb +27 -1
  14. data/lib/puppet/file_serving/metadata.rb +13 -8
  15. data/lib/puppet/file_serving/terminus_helper.rb +7 -8
  16. data/lib/puppet/file_system.rb +13 -0
  17. data/lib/puppet/file_system/file_impl.rb +4 -0
  18. data/lib/puppet/file_system/memory_impl.rb +4 -0
  19. data/lib/puppet/file_system/windows.rb +8 -0
  20. data/lib/puppet/functions.rb +33 -3
  21. data/lib/puppet/functions/defined.rb +130 -0
  22. data/lib/puppet/functions/regsubst.rb +1 -1
  23. data/lib/puppet/functions/split.rb +1 -1
  24. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  25. data/lib/puppet/indirector/facts/facter.rb +11 -0
  26. data/lib/puppet/loaders.rb +1 -0
  27. data/lib/puppet/node.rb +17 -1
  28. data/lib/puppet/node/environment.rb +4 -0
  29. data/lib/puppet/parser/ast/pops_bridge.rb +4 -0
  30. data/lib/puppet/parser/compiler.rb +9 -0
  31. data/lib/puppet/parser/functions/defined.rb +25 -1
  32. data/lib/puppet/parser/functions/file.rb +3 -1
  33. data/lib/puppet/parser/scope.rb +11 -2
  34. data/lib/puppet/parser/templatewrapper.rb +2 -1
  35. data/lib/puppet/pops.rb +4 -0
  36. data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
  37. data/lib/puppet/pops/evaluator/closure.rb +28 -2
  38. data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
  39. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +4 -0
  40. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +4 -0
  41. data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
  42. data/lib/puppet/pops/evaluator/epp_evaluator.rb +7 -2
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +48 -14
  44. data/lib/puppet/pops/evaluator/runtime3_support.rb +10 -5
  45. data/lib/puppet/pops/functions/dispatch.rb +6 -1
  46. data/lib/puppet/pops/functions/dispatcher.rb +7 -1
  47. data/lib/puppet/pops/issue_reporter.rb +42 -16
  48. data/lib/puppet/pops/issues.rb +116 -2
  49. data/lib/puppet/pops/loader/loader.rb +11 -0
  50. data/lib/puppet/pops/loader/loader_paths.rb +67 -6
  51. data/lib/puppet/pops/loader/module_loaders.rb +19 -8
  52. data/lib/puppet/pops/loader/puppet_function_instantiator.rb +78 -0
  53. data/lib/puppet/pops/loaders.rb +6 -4
  54. data/lib/puppet/pops/migration/migration_checker.rb +54 -0
  55. data/lib/puppet/pops/model/factory.rb +5 -1
  56. data/lib/puppet/pops/model/model_label_provider.rb +2 -0
  57. data/lib/puppet/pops/model/model_meta.rb +5 -1
  58. data/lib/puppet/pops/parser/egrammar.ra +9 -10
  59. data/lib/puppet/pops/parser/eparser.rb +1061 -1047
  60. data/lib/puppet/pops/parser/epp_support.rb +18 -9
  61. data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
  62. data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
  63. data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
  64. data/lib/puppet/pops/parser/lexer2.rb +29 -12
  65. data/lib/puppet/pops/parser/lexer_support.rb +52 -23
  66. data/lib/puppet/pops/parser/parser_support.rb +11 -14
  67. data/lib/puppet/pops/parser/slurp_support.rb +22 -6
  68. data/lib/puppet/pops/types/type_calculator.rb +156 -55
  69. data/lib/puppet/pops/types/type_factory.rb +66 -13
  70. data/lib/puppet/pops/types/type_parser.rb +22 -13
  71. data/lib/puppet/pops/types/types.rb +23 -4
  72. data/lib/puppet/pops/types/types_meta.rb +13 -2
  73. data/lib/puppet/pops/validation.rb +25 -2
  74. data/lib/puppet/pops/validation/checker4_0.rb +63 -31
  75. data/lib/puppet/provider/group/windows_adsi.rb +8 -4
  76. data/lib/puppet/provider/mount/parsed.rb +145 -2
  77. data/lib/puppet/provider/package/apt.rb +1 -1
  78. data/lib/puppet/provider/package/pip.rb +11 -2
  79. data/lib/puppet/provider/package/pkgng.rb +134 -0
  80. data/lib/puppet/provider/package/portage.rb +1 -1
  81. data/lib/puppet/provider/package/ports.rb +0 -3
  82. data/lib/puppet/provider/package/windows/exe_package.rb +0 -1
  83. data/lib/puppet/provider/package/windows/msi_package.rb +0 -1
  84. data/lib/puppet/provider/package/zypper.rb +50 -15
  85. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +32 -7
  86. data/lib/puppet/provider/service/debian.rb +1 -1
  87. data/lib/puppet/provider/service/init.rb +7 -0
  88. data/lib/puppet/provider/user/openbsd.rb +1 -0
  89. data/lib/puppet/provider/user/windows_adsi.rb +45 -2
  90. data/lib/puppet/reference/indirection.rb +1 -1
  91. data/lib/puppet/resource.rb +1 -1
  92. data/lib/puppet/resource/catalog.rb +0 -4
  93. data/lib/puppet/settings.rb +19 -0
  94. data/lib/puppet/type/file.rb +1 -0
  95. data/lib/puppet/type/file/ensure.rb +1 -1
  96. data/lib/puppet/type/mount.rb +9 -1
  97. data/lib/puppet/type/scheduled_task.rb +13 -0
  98. data/lib/puppet/type/tidy.rb +3 -1
  99. data/lib/puppet/type/user.rb +32 -0
  100. data/lib/puppet/type/yumrepo.rb +5 -5
  101. data/lib/puppet/util/log.rb +50 -8
  102. data/lib/puppet/util/log/destinations.rb +23 -2
  103. data/lib/puppet/util/logging.rb +37 -1
  104. data/lib/puppet/util/run_mode.rb +1 -14
  105. data/lib/puppet/util/windows/adsi.rb +130 -58
  106. data/lib/puppet/version.rb +1 -1
  107. data/man/man5/puppet.conf.5 +48 -6
  108. data/man/man8/extlookup2hiera.8 +1 -1
  109. data/man/man8/puppet-agent.8 +4 -1
  110. data/man/man8/puppet-apply.8 +4 -1
  111. data/man/man8/puppet-ca.8 +1 -1
  112. data/man/man8/puppet-catalog.8 +1 -1
  113. data/man/man8/puppet-cert.8 +1 -1
  114. data/man/man8/puppet-certificate.8 +1 -1
  115. data/man/man8/puppet-certificate_request.8 +1 -1
  116. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  117. data/man/man8/puppet-config.8 +1 -1
  118. data/man/man8/puppet-describe.8 +1 -1
  119. data/man/man8/puppet-device.8 +6 -3
  120. data/man/man8/puppet-doc.8 +1 -1
  121. data/man/man8/puppet-epp.8 +1 -1
  122. data/man/man8/puppet-facts.8 +1 -1
  123. data/man/man8/puppet-file.8 +1 -1
  124. data/man/man8/puppet-filebucket.8 +1 -1
  125. data/man/man8/puppet-help.8 +1 -1
  126. data/man/man8/puppet-inspect.8 +1 -1
  127. data/man/man8/puppet-key.8 +1 -1
  128. data/man/man8/puppet-man.8 +1 -1
  129. data/man/man8/puppet-master.8 +4 -1
  130. data/man/man8/puppet-module.8 +1 -1
  131. data/man/man8/puppet-node.8 +1 -1
  132. data/man/man8/puppet-parser.8 +1 -1
  133. data/man/man8/puppet-plugin.8 +1 -1
  134. data/man/man8/puppet-report.8 +1 -1
  135. data/man/man8/puppet-resource.8 +1 -1
  136. data/man/man8/puppet-resource_type.8 +1 -1
  137. data/man/man8/puppet-status.8 +1 -1
  138. data/man/man8/puppet.8 +1 -1
  139. data/spec/fixtures/unit/data_providers/environments/production/lib/puppet/functions/environment/data.rb +3 -1
  140. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/functions/data.pp +6 -0
  141. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/lib/puppet/bindings/xyz/default.rb +9 -0
  142. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/manifests/init.pp +9 -0
  143. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcalled.pp +3 -0
  144. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller.pp +3 -0
  145. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller4.pp +3 -0
  146. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/lib/puppet/functions/user/callingpuppet.rb +5 -0
  147. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/functions/hello.pp +3 -0
  148. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/manifests/init.pp +3 -0
  149. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/metadata.json +10 -0
  150. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/hello.pp +3 -0
  151. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/subspace/hello.pp +3 -0
  152. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +1 -10
  153. data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
  154. data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
  155. data/spec/fixtures/unit/provider/package/pkgng/pkg.info +8 -0
  156. data/spec/fixtures/unit/provider/package/pkgng/pkg.query +1 -0
  157. data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +1 -0
  158. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +3 -0
  159. data/spec/fixtures/unit/provider/package/zypper/zypper-list-updates-empty.out +3 -0
  160. data/spec/integration/application/apply_spec.rb +49 -0
  161. data/spec/integration/faces/plugin_spec.rb +0 -4
  162. data/spec/integration/indirector/facts/facter_spec.rb +59 -0
  163. data/spec/integration/parser/compiler_spec.rb +850 -0
  164. data/spec/integration/parser/resource_expressions_spec.rb +3 -0
  165. data/spec/integration/parser/scope_spec.rb +26 -5
  166. data/spec/integration/transaction_spec.rb +1 -1
  167. data/spec/integration/type/file_spec.rb +318 -41
  168. data/spec/integration/util/windows/security_spec.rb +14 -5
  169. data/spec/lib/matchers/resource.rb +22 -1
  170. data/spec/lib/puppet_spec/matchers.rb +6 -4
  171. data/spec/unit/application/master_spec.rb +33 -7
  172. data/spec/unit/data_providers/function_data_provider_spec.rb +10 -1
  173. data/spec/unit/file_serving/metadata_spec.rb +1 -1
  174. data/spec/unit/file_serving/terminus_helper_spec.rb +2 -3
  175. data/spec/unit/file_system_spec.rb +38 -0
  176. data/spec/unit/functions/defined_spec.rb +289 -0
  177. data/spec/unit/functions/hiera_spec.rb +8 -6
  178. data/spec/unit/functions/regsubst_spec.rb +4 -0
  179. data/spec/unit/functions/split_spec.rb +8 -0
  180. data/spec/unit/functions4_spec.rb +97 -2
  181. data/spec/unit/indirector/facts/facter_spec.rb +7 -0
  182. data/spec/unit/node_spec.rb +6 -0
  183. data/spec/unit/parser/functions/file_spec.rb +7 -1
  184. data/spec/unit/parser/functions/template_spec.rb +1 -1
  185. data/spec/unit/parser/scope_spec.rb +2 -2
  186. data/spec/unit/parser/templatewrapper_spec.rb +1 -1
  187. data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
  188. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +84 -18
  189. data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
  190. data/spec/unit/pops/issues_spec.rb +16 -16
  191. data/spec/unit/pops/loaders/loaders_spec.rb +106 -48
  192. data/spec/unit/pops/migration_spec.rb +53 -0
  193. data/spec/unit/pops/parser/lexer2_spec.rb +142 -1
  194. data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
  195. data/spec/unit/pops/types/type_calculator_spec.rb +205 -12
  196. data/spec/unit/pops/validation_spec.rb +66 -0
  197. data/spec/unit/pops/validator/validator_spec.rb +1 -1
  198. data/spec/unit/provider/group/windows_adsi_spec.rb +57 -9
  199. data/spec/unit/provider/mount/parsed_spec.rb +31 -5
  200. data/spec/unit/provider/package/apt_spec.rb +5 -0
  201. data/spec/unit/provider/package/pip_spec.rb +9 -0
  202. data/spec/unit/provider/package/pkgng_spec.rb +172 -0
  203. data/spec/unit/provider/package/windows/exe_package_spec.rb +0 -1
  204. data/spec/unit/provider/package/windows/msi_package_spec.rb +0 -1
  205. data/spec/unit/provider/package/zypper_spec.rb +50 -19
  206. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
  207. data/spec/unit/provider/service/base_spec.rb +38 -27
  208. data/spec/unit/provider/service/debian_spec.rb +8 -0
  209. data/spec/unit/provider/service/freebsd_spec.rb +1 -0
  210. data/spec/unit/provider/service/gentoo_spec.rb +1 -0
  211. data/spec/unit/provider/service/init_spec.rb +18 -0
  212. data/spec/unit/provider/service/openbsd_spec.rb +1 -0
  213. data/spec/unit/provider/service/redhat_spec.rb +1 -0
  214. data/spec/unit/provider/user/windows_adsi_spec.rb +134 -5
  215. data/spec/unit/settings_spec.rb +11 -0
  216. data/spec/unit/util/log_spec.rb +113 -0
  217. data/spec/unit/util/windows/adsi_spec.rb +135 -41
  218. data/spec/unit/util/windows/sid_spec.rb +0 -10
  219. metadata +48 -2
@@ -58,7 +58,7 @@ Values fetched from the terminus are written to the cache.
58
58
 
59
59
  ### Interaction with REST
60
60
 
61
- REST endpoints have the form `/{environment}/{indirection}/{key}`, where the indirection can be singular or plural, following normal English spelling rules.
61
+ REST endpoints have the form `/{prefix}/{version}/{indirection}/{key}?environment={environment}`, where the indirection can be singular or plural, following normal English spelling rules.
62
62
  On the server side, REST responses are generated from the locally-configured endpoints.
63
63
 
64
64
  ### Indirections and Termini
@@ -509,7 +509,7 @@ class Puppet::Resource
509
509
  parameters.each do |name, value|
510
510
  next unless t = arg_types[name.to_s] # untyped, and parameters are symbols here (aargh, strings in the type)
511
511
  unless Puppet::Pops::Types::TypeCalculator.instance?(t, value.value)
512
- inferred_type = Puppet::Pops::Types::TypeCalculator.infer(value.value)
512
+ inferred_type = Puppet::Pops::Types::TypeCalculator.infer_set(value.value)
513
513
  actual = Puppet::Pops::Types::TypeCalculator.generalize!(inferred_type)
514
514
  fail Puppet::ParseError, "Expected parameter '#{name}' of '#{self}' to have type #{t.to_s}, got #{actual.to_s}"
515
515
  end
@@ -177,10 +177,6 @@ class Puppet::Resource::Catalog < Puppet::Graph::SimpleGraph
177
177
  transaction.report.as_logging_destination do
178
178
  transaction.evaluate
179
179
  end
180
- rescue Puppet::Error => detail
181
- Puppet.log_exception(detail, "Could not apply complete catalog: #{detail}")
182
- rescue => detail
183
- Puppet.log_exception(detail, "Got an uncaught exception of type #{detail.class}: #{detail}")
184
180
  ensure
185
181
  # Don't try to store state unless we're a host config
186
182
  # too recursive.
@@ -3,6 +3,7 @@ require 'getoptlong'
3
3
  require 'puppet/util/watched_file'
4
4
  require 'puppet/util/command_line/puppet_option_parser'
5
5
  require 'forwardable'
6
+ require 'fileutils'
6
7
 
7
8
  # The class for handling configuration files.
8
9
  class Puppet::Settings
@@ -338,9 +339,27 @@ class Puppet::Settings
338
339
  call_hooks_deferred_to_application_initialization
339
340
  issue_deprecations
340
341
 
342
+ REQUIRED_APP_SETTINGS.each do |key|
343
+ create_ancestors(Puppet[key])
344
+ end
345
+
341
346
  @app_defaults_initialized = true
342
347
  end
343
348
 
349
+ # Create ancestor directories.
350
+ #
351
+ # @param dir [String] absolute path for a required application default directory
352
+ # @api private
353
+
354
+ def create_ancestors(dir)
355
+ parent_dir = File.dirname(dir)
356
+
357
+ if !File.exist?(parent_dir)
358
+ FileUtils.mkdir_p(parent_dir)
359
+ end
360
+ end
361
+ private :create_ancestors
362
+
344
363
  def call_hooks_deferred_to_application_initialization(options = {})
345
364
  @hooks_to_call_on_application_initialization.each do |setting|
346
365
  begin
@@ -668,6 +668,7 @@ Puppet::Type.newtype(:file) do
668
668
  :links => self[:links],
669
669
  :recurse => (self[:recurse] == :remote ? true : self[:recurse]),
670
670
  :recurselimit => self[:recurselimit],
671
+ :source_permissions => self[:source_permissions],
671
672
  :ignore => self[:ignore],
672
673
  :checksum_type => (self[:source] || self[:content]) ? self[:checksum] : :none,
673
674
  :environment => catalog.environment_instance
@@ -115,7 +115,7 @@ module Puppet
115
115
  end
116
116
 
117
117
  def change_to_s(currentvalue, newvalue)
118
- return super unless newvalue.to_s == "file"
118
+ return super unless [:file, :present].include?(newvalue)
119
119
 
120
120
  return super unless property = @resource.property(:content)
121
121
 
@@ -254,8 +254,16 @@ module Puppet
254
254
  newvalues(:true, :false)
255
255
  defaultto do
256
256
  case Facter.value(:operatingsystem)
257
- when "FreeBSD", "Darwin", "AIX", "DragonFly", "OpenBSD"
257
+ when "FreeBSD", "Darwin", "DragonFly", "OpenBSD"
258
258
  false
259
+ when "AIX"
260
+ if Facter.value(:kernelmajversion) == "5300"
261
+ false
262
+ elsif resource[:device] and resource[:device].match(%r{^[^/]+:/})
263
+ false
264
+ else
265
+ true
266
+ end
259
267
  else
260
268
  true
261
269
  end
@@ -102,6 +102,9 @@ Puppet::Type.newtype(:scheduled_task) do
102
102
  * `start_date` --- The date when the trigger should first become active.
103
103
  Defaults to the current date. You should format dates as YYYY-MM-DD,
104
104
  although other date formats may work. (Under the hood, this uses `Date.parse`.)
105
+ * `minutes_interval` --- The repeat interval in minutes.
106
+ * `minutes_duration` --- The duration in minutes, needs to be greater than the
107
+ minutes_interval.
105
108
  * For `daily` triggers:
106
109
  * `every` --- How often the task should run, as a number of days. Defaults
107
110
  to 1. ("2" means every other day, "3" means every three days, etc.)
@@ -127,6 +130,7 @@ Puppet::Type.newtype(:scheduled_task) do
127
130
  when the task should run. Must be one of `first`, `second`, `third`,
128
131
  `fourth`, `fifth`, or `last`.
129
132
 
133
+
130
134
  Examples:
131
135
 
132
136
  # Run at 8am on the 1st, 15th, and last day of the month in January, March,
@@ -150,6 +154,15 @@ Puppet::Type.newtype(:scheduled_task) do
150
154
  day_of_week => [mon], # Must be specified
151
155
  }
152
156
 
157
+ # Run daily repeating every 30 minutes between 9am and 5pm (480 minutes) starting after August 31st, 2011.
158
+ trigger => {
159
+ schedule => daily,
160
+ start_date => '2011-08-31', # Defaults to current date
161
+ start_time => '8:00', # Must be specified
162
+ minutes_interval => 30,
163
+ minutes_duration => 480,
164
+ }
165
+
153
166
  EOT
154
167
 
155
168
  validate do |value|
@@ -253,7 +253,9 @@ Puppet::Type.newtype(:tidy) do
253
253
  else
254
254
  files = [self[:path]]
255
255
  end
256
- result = files.find_all { |path| tidy?(path) }.collect { |path| mkfile(path) }.each { |file| notice "Tidying #{file.ref}" }.sort { |a,b| b[:path] <=> a[:path] }
256
+ found_files = files.find_all { |path| tidy?(path) }.collect { |path| mkfile(path) }
257
+ result = found_files.each { |file| debug "Tidying #{file.ref}" }.sort { |a,b| b[:path] <=> a[:path] }
258
+ notice "Tidying #{found_files.size} files"
257
259
 
258
260
  # No need to worry about relationships if we don't have rmdirs; there won't be
259
261
  # any directories.
@@ -274,6 +274,38 @@ module Puppet
274
274
  raise ArgumentError, "Group names must be provided as an array, not a comma-separated list." if value.include?(",")
275
275
  raise ArgumentError, "Group names must not be empty. If you want to specify \"no groups\" pass an empty array" if value.empty?
276
276
  end
277
+
278
+ def change_to_s(currentvalue, newvalue)
279
+ newvalue = newvalue.split(",") if newvalue != :absent
280
+
281
+ if provider.respond_to?(:groups_to_s)
282
+ # for Windows ADSI
283
+ # de-dupe the "newvalue" when the sync event message is generated,
284
+ # due to final retrieve called after the resource has been modified
285
+ newvalue = provider.groups_to_s(newvalue).split(',').uniq
286
+ end
287
+
288
+ super(currentvalue, newvalue)
289
+ end
290
+
291
+ # override Puppet::Property::List#retrieve
292
+ def retrieve
293
+ if provider.respond_to?(:groups_to_s)
294
+ # Windows ADSI groups returns SIDs, but retrieve needs names
295
+ # must return qualified names for SIDs for "is" value and puppet resource
296
+ return provider.groups_to_s(provider.groups).split(',')
297
+ end
298
+
299
+ super
300
+ end
301
+
302
+ def insync?(current)
303
+ if provider.respond_to?(:groups_insync?)
304
+ return provider.groups_insync?(current, @should)
305
+ end
306
+
307
+ super(current)
308
+ end
277
309
  end
278
310
 
279
311
  newparam(:name) do
@@ -167,7 +167,7 @@ Puppet::Type.newtype(:yumrepo) do
167
167
  newproperty(:includepkgs) do
168
168
  desc "List of shell globs. If this is set, only packages
169
169
  matching one of the globs will be considered for
170
- update or install from this repo. #{ABSENT_DOC}"
170
+ update or install from this repository. #{ABSENT_DOC}"
171
171
 
172
172
  newvalues(/.*/, :absent)
173
173
  end
@@ -302,7 +302,7 @@ Puppet::Type.newtype(:yumrepo) do
302
302
  end
303
303
 
304
304
  newproperty(:s3_enabled) do
305
- desc "Access the repo via S3.
305
+ desc "Access the repository via S3.
306
306
  #{YUM_BOOLEAN_DOC}
307
307
  #{ABSENT_DOC}"
308
308
 
@@ -327,14 +327,14 @@ Puppet::Type.newtype(:yumrepo) do
327
327
 
328
328
  newproperty(:sslclientcert) do
329
329
  desc "Path to the SSL client certificate yum should use to connect
330
- to repos/remote sites. #{ABSENT_DOC}"
330
+ to repositories/remote sites. #{ABSENT_DOC}"
331
331
 
332
332
  newvalues(/.*/, :absent)
333
333
  end
334
334
 
335
335
  newproperty(:sslclientkey) do
336
336
  desc "Path to the SSL client key yum should use to connect
337
- to repos/remote sites. #{ABSENT_DOC}"
337
+ to repositories/remote sites. #{ABSENT_DOC}"
338
338
 
339
339
  newvalues(/.*/, :absent)
340
340
  end
@@ -370,7 +370,7 @@ Puppet::Type.newtype(:yumrepo) do
370
370
  end
371
371
 
372
372
  newproperty(:deltarpm_percentage) do
373
- desc "Percentage value that determines when to use deltas for this repo.
373
+ desc "Percentage value that determines when to use deltas for this repository.
374
374
  When the delta is larger than this percentage value of the package, the
375
375
  delta is not used.
376
376
  #{ABSENT_DOC}"
@@ -243,7 +243,7 @@ class Puppet::Util::Log
243
243
  obj
244
244
  end
245
245
 
246
- attr_accessor :time, :remote, :file, :line, :source
246
+ attr_accessor :time, :remote, :file, :line, :pos, :source, :issue_code, :environment, :node, :backtrace
247
247
  attr_reader :level, :message
248
248
 
249
249
  def initialize(args)
@@ -257,9 +257,10 @@ class Puppet::Util::Log
257
257
  tags.each { |t| self.tag(t) }
258
258
  end
259
259
 
260
- [:file, :line].each do |attr|
260
+ # Don't add these unless defined (preserve 3.x API as much as possible)
261
+ [:file, :line, :pos, :issue_code, :environment, :node, :backtrace].each do |attr|
261
262
  next unless value = args[attr]
262
- send(attr.to_s + "=", value)
263
+ send(attr.to_s + '=', value)
263
264
  end
264
265
 
265
266
  Log.newmessage(self)
@@ -274,8 +275,11 @@ class Puppet::Util::Log
274
275
  if @time.is_a? String
275
276
  @time = Time.parse(@time)
276
277
  end
277
- @file = data['file'] if data['file']
278
- @line = data['line'] if data['line']
278
+ # Don't add these unless defined (preserve 3.x API as much as possible)
279
+ %w(file line pos issue_code environment node backtrace).each do |name|
280
+ next unless value = data[name]
281
+ send(name + '=', value)
282
+ end
279
283
  end
280
284
 
281
285
  def to_hash
@@ -285,15 +289,30 @@ class Puppet::Util::Log
285
289
  def to_data_hash
286
290
  {
287
291
  'level' => @level,
288
- 'message' => @message,
292
+ 'message' => to_s,
289
293
  'source' => @source,
290
- 'tags' => @tags,
294
+ 'tags' => @tags.to_a,
291
295
  'time' => @time.iso8601(9),
292
296
  'file' => @file,
293
297
  'line' => @line,
294
298
  }
295
299
  end
296
300
 
301
+ def to_structured_hash
302
+ hash = {
303
+ 'level' => @level,
304
+ 'message' => @message,
305
+ 'source' => @source,
306
+ 'tags' => @tags.to_a,
307
+ 'time' => @time.iso8601(9),
308
+ }
309
+ %w(file line pos issue_code environment node backtrace).each do |name|
310
+ attr_name = "@#{name}"
311
+ hash[name] = instance_variable_get(attr_name) if instance_variable_defined?(attr_name)
312
+ end
313
+ hash
314
+ end
315
+
297
316
  def to_pson(*args)
298
317
  to_data_hash.to_pson(*args)
299
318
  end
@@ -331,7 +350,30 @@ class Puppet::Util::Log
331
350
  end
332
351
 
333
352
  def to_s
334
- message
353
+ msg = message
354
+
355
+ # Issue based messages do not have details in the message. It
356
+ # must be appended here
357
+ unless issue_code.nil?
358
+ msg = "Could not parse for environment #{environment}: #{msg}" unless environment.nil?
359
+ if file && line && pos
360
+ msg = "#{msg} at #{file}:#{line}:#{pos}"
361
+ elsif file and line
362
+ msg = "#{msg} at #{file}:#{line}"
363
+ elsif line && pos
364
+ msg = "#{msg} at line #{line}:#{pos}"
365
+ elsif line
366
+ msg = "#{msg} at line #{line}"
367
+ elsif file
368
+ msg = "#{msg} in #{file}"
369
+ end
370
+ msg = "#{msg} on node #{node}" unless node.nil?
371
+ if @backtrace.is_a?(Array)
372
+ msg += "\n"
373
+ msg += @backtrace.join("\n")
374
+ end
375
+ end
376
+ msg
335
377
  end
336
378
 
337
379
  end
@@ -65,6 +65,8 @@ Puppet::Util::Log.newdesttype :file do
65
65
 
66
66
  def initialize(path)
67
67
  @name = path
68
+ @json = path.end_with?('.json') ? 1 : 0
69
+
68
70
  # first make sure the directory exists
69
71
  # We can't just use 'Config.use' here, because they've
70
72
  # specified a "special" destination.
@@ -74,7 +76,21 @@ Puppet::Util::Log.newdesttype :file do
74
76
  end
75
77
 
76
78
  # create the log file, if it doesn't already exist
77
- file = File.open(path, File::WRONLY|File::CREAT|File::APPEND)
79
+ need_array_start = false
80
+ if @json == 1
81
+ need_array_start = true
82
+ if File.exists?(path)
83
+ sz = File.size(path)
84
+ need_array_start = sz == 0
85
+
86
+ # Assume that entries have been written and that a comma
87
+ # is needed before next entry
88
+ @json = 2 if sz > 2
89
+ end
90
+ end
91
+
92
+ file = File.open(path, File::WRONLY|File::CREAT|File::APPEND)
93
+ file.puts('[') if need_array_start
78
94
 
79
95
  # Give ownership to the user and group puppet will run as
80
96
  if Puppet.features.root? && !Puppet::Util::Platform.windows?
@@ -91,7 +107,12 @@ Puppet::Util::Log.newdesttype :file do
91
107
  end
92
108
 
93
109
  def handle(msg)
94
- @file.puts("#{msg.time} #{msg.source} (#{msg.level}): #{msg}")
110
+ if @json > 0
111
+ @json > 1 ? @file.puts(',') : @json = 2
112
+ JSON.dump(msg.to_structured_hash, @file)
113
+ else
114
+ @file.puts("#{msg.time} #{msg.source} (#{msg.level}): #{msg}")
115
+ end
95
116
 
96
117
  @file.flush if @autoflush
97
118
  end
@@ -46,8 +46,44 @@ module Puppet::Util::Logging
46
46
  # wish to log a message at all; in this case it is likely that you are only calling this method in order
47
47
  # to take advantage of the backtrace logging.
48
48
  def log_exception(exception, message = :default, options = {})
49
- err(format_exception(exception, message, Puppet[:trace] || options[:trace]))
49
+ trace = Puppet[:trace] || options[:trace]
50
+ if message == :default && exception.is_a?(Puppet::ParseErrorWithIssue)
51
+ # Retain all detailed info and keep plain message and stacktrace separate
52
+ backtrace = []
53
+ build_exception_trace(backtrace, exception, trace)
54
+ Puppet::Util::Log.create({
55
+ :level => :err,
56
+ :source => log_source,
57
+ :message => exception.basic_message,
58
+ :issue_code => exception.issue_code,
59
+ :backtrace => backtrace.empty? ? nil : backtrace,
60
+ :file => exception.file,
61
+ :line => exception.line,
62
+ :pos => exception.pos,
63
+ :environment => exception.environment,
64
+ :node => exception.node
65
+ }.merge(log_metadata))
66
+ else
67
+ err(format_exception(exception, message, trace))
68
+ end
69
+ end
70
+
71
+ def build_exception_trace(arr, exception, trace = true)
72
+ if trace and exception.backtrace
73
+ exception.backtrace.each do |line|
74
+ arr << line =~ /^(.+):(\d+.*)$/ ? ("#{Pathname($1).realpath}:#{$2}" rescue line) : line
75
+ end
76
+ end
77
+ if exception.respond_to?(:original)
78
+ original = exception.original
79
+ unless original.nil?
80
+ arr << 'Wrapped exception:'
81
+ arr << original.message
82
+ build_exception_trace(arr, original, trace)
83
+ end
84
+ end
50
85
  end
86
+ private :build_exception_trace
51
87
 
52
88
  def format_exception(exception, message = :default, trace = true)
53
89
  arr = []
@@ -1,5 +1,4 @@
1
1
  require 'etc'
2
- require 'fileutils'
3
2
 
4
3
  module Puppet
5
4
  module Util
@@ -53,19 +52,7 @@ module Puppet
53
52
  if Puppet.features.root?
54
53
  File.expand_path(system)
55
54
  else
56
- # Starting with puppet 4 and AIO packaging, AIO introduced new paths for
57
- # both root and non-root users. The paths used by the root user are created
58
- # by packaging, so no special action is required in the code.
59
- #
60
- # However, for non-root users, these new paths introduce deep paths (see below
61
- # in the two RunMode sub-classes). Since puppet doesn't create parent directories
62
- # for directories in the settings catalog, we take this opportunity to create
63
- # those parent directories. (Note that pre-AIO this code would have had to do the
64
- # same thing, except that everything was under ~/.puppet which was confdir so was
65
- # created.)
66
- expanded_user = File.expand_path(user)
67
- FileUtils.mkdir_p(File.dirname(expanded_user)) if File.exists?(File.expand_path('~'))
68
- expanded_user
55
+ File.expand_path(user)
69
56
  end
70
57
  end
71
58
  end