puppet 6.10.1 → 6.11.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 (242) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -4
  3. data/Gemfile.lock +20 -12
  4. data/ext/project_data.yaml +3 -2
  5. data/ext/regexp_nodes/regexp_nodes.rb +4 -4
  6. data/ext/windows/service/daemon.rb +33 -8
  7. data/install.rb +6 -6
  8. data/lib/puppet.rb +8 -0
  9. data/lib/puppet/application.rb +1 -1
  10. data/lib/puppet/application/agent.rb +3 -0
  11. data/lib/puppet/application/apply.rb +2 -2
  12. data/lib/puppet/application/describe.rb +3 -9
  13. data/lib/puppet/application/device.rb +3 -0
  14. data/lib/puppet/application/doc.rb +1 -1
  15. data/lib/puppet/application/lookup.rb +1 -1
  16. data/lib/puppet/application/script.rb +2 -2
  17. data/lib/puppet/application/ssl.rb +25 -21
  18. data/lib/puppet/configurer.rb +42 -0
  19. data/lib/puppet/configurer/downloader.rb +2 -6
  20. data/lib/puppet/context/trusted_information.rb +42 -4
  21. data/lib/puppet/defaults.rb +19 -4
  22. data/lib/puppet/face/module/list.rb +5 -5
  23. data/lib/puppet/face/module/search.rb +1 -1
  24. data/lib/puppet/face/module/uninstall.rb +1 -1
  25. data/lib/puppet/face/module/upgrade.rb +1 -1
  26. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  27. data/lib/puppet/file_system.rb +0 -8
  28. data/lib/puppet/file_system/memory_file.rb +1 -1
  29. data/lib/puppet/file_system/posix.rb +3 -2
  30. data/lib/puppet/forge.rb +3 -3
  31. data/lib/puppet/functions.rb +1 -2
  32. data/lib/puppet/gettext/module_translations.rb +1 -1
  33. data/lib/puppet/graph/rb_tree_map.rb +2 -2
  34. data/lib/puppet/graph/simple_graph.rb +4 -3
  35. data/lib/puppet/http.rb +29 -0
  36. data/lib/puppet/http/client.rb +156 -0
  37. data/lib/puppet/http/errors.rb +30 -0
  38. data/lib/puppet/http/redirector.rb +48 -0
  39. data/lib/puppet/http/resolver.rb +5 -0
  40. data/lib/puppet/http/resolver/settings.rb +5 -0
  41. data/lib/puppet/http/resolver/srv.rb +13 -0
  42. data/lib/puppet/http/response.rb +34 -0
  43. data/lib/puppet/http/retry_after_handler.rb +47 -0
  44. data/lib/puppet/http/service.rb +18 -0
  45. data/lib/puppet/http/service/ca.rb +49 -0
  46. data/lib/puppet/http/session.rb +55 -0
  47. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  48. data/lib/puppet/indirector/hiera.rb +2 -0
  49. data/lib/puppet/indirector/request.rb +1 -1
  50. data/lib/puppet/indirector/resource/ral.rb +1 -3
  51. data/lib/puppet/indirector/resource/validator.rb +1 -1
  52. data/lib/puppet/interface.rb +2 -1
  53. data/lib/puppet/interface/documentation.rb +1 -1
  54. data/lib/puppet/loaders.rb +0 -1
  55. data/lib/puppet/metatype/manager.rb +1 -1
  56. data/lib/puppet/module.rb +1 -1
  57. data/lib/puppet/module/task.rb +20 -4
  58. data/lib/puppet/module_tool/applications/installer.rb +1 -1
  59. data/lib/puppet/module_tool/applications/uninstaller.rb +3 -3
  60. data/lib/puppet/module_tool/metadata.rb +1 -1
  61. data/lib/puppet/module_tool/shared_behaviors.rb +4 -4
  62. data/lib/puppet/module_tool/tar/mini.rb +1 -1
  63. data/lib/puppet/network/http.rb +2 -6
  64. data/lib/puppet/network/http/api/indirected_routes.rb +12 -11
  65. data/lib/puppet/network/http/connection.rb +10 -12
  66. data/lib/puppet/network/http/pool.rb +2 -0
  67. data/lib/puppet/network/http/site.rb +5 -1
  68. data/lib/puppet/network/resolver.rb +4 -4
  69. data/lib/puppet/node/environment.rb +4 -2
  70. data/lib/puppet/pal/pal_impl.rb +2 -2
  71. data/lib/puppet/parser/ast.rb +1 -1
  72. data/lib/puppet/parser/ast/resourceparam.rb +1 -1
  73. data/lib/puppet/parser/functions.rb +1 -1
  74. data/lib/puppet/parser/scope.rb +8 -7
  75. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +1 -1
  76. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +1 -1
  77. data/lib/puppet/pops/evaluator/external_syntax_support.rb +3 -2
  78. data/lib/puppet/pops/evaluator/runtime3_support.rb +4 -7
  79. data/lib/puppet/pops/loader/module_loaders.rb +1 -1
  80. data/lib/puppet/pops/loader/task_instantiator.rb +4 -0
  81. data/lib/puppet/pops/loaders.rb +1 -1
  82. data/lib/puppet/pops/lookup/hiera_config.rb +1 -0
  83. data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
  84. data/lib/puppet/pops/merge_strategy.rb +22 -18
  85. data/lib/puppet/pops/parser/heredoc_support.rb +1 -1
  86. data/lib/puppet/pops/parser/interpolation_support.rb +4 -4
  87. data/lib/puppet/pops/parser/locator.rb +1 -1
  88. data/lib/puppet/pops/parser/pn_parser.rb +17 -16
  89. data/lib/puppet/pops/puppet_stack.rb +52 -48
  90. data/lib/puppet/pops/types/p_sensitive_type.rb +1 -1
  91. data/lib/puppet/pops/types/p_uri_type.rb +1 -1
  92. data/lib/puppet/pops/types/string_converter.rb +10 -10
  93. data/lib/puppet/pops/types/types.rb +3 -3
  94. data/lib/puppet/property.rb +1 -1
  95. data/lib/puppet/property/ensure.rb +1 -1
  96. data/lib/puppet/provider/exec.rb +6 -2
  97. data/lib/puppet/provider/nameservice/directoryservice.rb +1 -1
  98. data/lib/puppet/provider/nameservice/pw.rb +2 -2
  99. data/lib/puppet/provider/package/apt.rb +5 -1
  100. data/lib/puppet/provider/package/dnfmodule.rb +87 -0
  101. data/lib/puppet/provider/package/dpkg.rb +31 -17
  102. data/lib/puppet/provider/package/openbsd.rb +1 -1
  103. data/lib/puppet/provider/package/pip.rb +34 -9
  104. data/lib/puppet/provider/package/portage.rb +1 -1
  105. data/lib/puppet/provider/package/rpm.rb +5 -5
  106. data/lib/puppet/provider/package/windows/package.rb +1 -1
  107. data/lib/puppet/provider/package/yum.rb +1 -1
  108. data/lib/puppet/provider/parsedfile.rb +1 -1
  109. data/lib/puppet/provider/service/daemontools.rb +9 -9
  110. data/lib/puppet/provider/service/openbsd.rb +1 -1
  111. data/lib/puppet/provider/service/rcng.rb +2 -2
  112. data/lib/puppet/provider/service/runit.rb +2 -8
  113. data/lib/puppet/provider/service/systemd.rb +10 -10
  114. data/lib/puppet/provider/user/directoryservice.rb +1 -1
  115. data/lib/puppet/provider/user/user_role_add.rb +1 -1
  116. data/lib/puppet/provider/user/useradd.rb +22 -13
  117. data/lib/puppet/provider/user/windows_adsi.rb +4 -5
  118. data/lib/puppet/reference/indirection.rb +2 -2
  119. data/lib/puppet/reference/metaparameter.rb +1 -3
  120. data/lib/puppet/reference/providers.rb +1 -1
  121. data/lib/puppet/reference/type.rb +3 -9
  122. data/lib/puppet/reports.rb +1 -1
  123. data/lib/puppet/resource.rb +1 -1
  124. data/lib/puppet/resource/catalog.rb +1 -1
  125. data/lib/puppet/rest/errors.rb +1 -0
  126. data/lib/puppet/rest/response.rb +1 -0
  127. data/lib/puppet/rest/route.rb +1 -0
  128. data/lib/puppet/rest/routes.rb +3 -0
  129. data/lib/puppet/runtime.rb +25 -0
  130. data/lib/puppet/settings.rb +3 -3
  131. data/lib/puppet/settings/environment_conf.rb +1 -0
  132. data/lib/puppet/ssl/host.rb +1 -1
  133. data/lib/puppet/ssl/oids.rb +1 -1
  134. data/lib/puppet/ssl/state_machine.rb +23 -15
  135. data/lib/puppet/test/test_helper.rb +1 -1
  136. data/lib/puppet/transaction/report.rb +1 -1
  137. data/lib/puppet/trusted_external.rb +13 -0
  138. data/lib/puppet/type.rb +1 -3
  139. data/lib/puppet/type/exec.rb +7 -3
  140. data/lib/puppet/type/file.rb +1 -2
  141. data/lib/puppet/type/file/source.rb +2 -2
  142. data/lib/puppet/type/package.rb +10 -3
  143. data/lib/puppet/type/schedule.rb +1 -1
  144. data/lib/puppet/type/service.rb +1 -1
  145. data/lib/puppet/util.rb +2 -2
  146. data/lib/puppet/util/command_line/trollop.rb +1 -1
  147. data/lib/puppet/util/http_proxy.rb +2 -10
  148. data/lib/puppet/util/log.rb +2 -2
  149. data/lib/puppet/util/log/destinations.rb +2 -2
  150. data/lib/puppet/util/logging.rb +2 -2
  151. data/lib/puppet/util/metric.rb +2 -2
  152. data/lib/puppet/util/platform.rb +15 -4
  153. data/lib/puppet/util/provider_features.rb +2 -4
  154. data/lib/puppet/util/rdoc.rb +1 -1
  155. data/lib/puppet/util/reference.rb +1 -1
  156. data/lib/puppet/util/resource_template.rb +1 -1
  157. data/lib/puppet/util/selinux.rb +3 -1
  158. data/lib/puppet/util/windows/registry.rb +7 -5
  159. data/lib/puppet/vendor.rb +1 -1
  160. data/lib/puppet/vendor/require_vendored.rb +0 -1
  161. data/lib/puppet/version.rb +1 -1
  162. data/lib/puppet/x509/cert_provider.rb +4 -1
  163. data/locales/puppet.pot +279 -203
  164. data/man/man5/puppet.conf.5 +30 -8
  165. data/man/man8/puppet-agent.8 +4 -1
  166. data/man/man8/puppet-apply.8 +1 -1
  167. data/man/man8/puppet-catalog.8 +1 -1
  168. data/man/man8/puppet-config.8 +1 -1
  169. data/man/man8/puppet-describe.8 +1 -1
  170. data/man/man8/puppet-device.8 +1 -1
  171. data/man/man8/puppet-doc.8 +1 -1
  172. data/man/man8/puppet-epp.8 +1 -1
  173. data/man/man8/puppet-facts.8 +1 -1
  174. data/man/man8/puppet-filebucket.8 +1 -1
  175. data/man/man8/puppet-generate.8 +1 -1
  176. data/man/man8/puppet-help.8 +1 -1
  177. data/man/man8/puppet-key.8 +1 -1
  178. data/man/man8/puppet-lookup.8 +1 -1
  179. data/man/man8/puppet-man.8 +1 -1
  180. data/man/man8/puppet-module.8 +1 -1
  181. data/man/man8/puppet-node.8 +1 -1
  182. data/man/man8/puppet-parser.8 +1 -1
  183. data/man/man8/puppet-plugin.8 +1 -1
  184. data/man/man8/puppet-report.8 +1 -1
  185. data/man/man8/puppet-resource.8 +1 -1
  186. data/man/man8/puppet-script.8 +1 -1
  187. data/man/man8/puppet-ssl.8 +1 -1
  188. data/man/man8/puppet-status.8 +1 -1
  189. data/man/man8/puppet.8 +2 -2
  190. data/spec/fixtures/unit/provider/package/dnfmodule/dnf-module-list-installed.txt +11 -0
  191. data/spec/integration/configurer_spec.rb +52 -0
  192. data/spec/lib/puppet/certificate_factory.rb +2 -2
  193. data/spec/spec_helper.rb +24 -0
  194. data/spec/unit/application/device_spec.rb +6 -0
  195. data/spec/unit/application/ssl_spec.rb +4 -7
  196. data/spec/unit/configurer_spec.rb +1 -0
  197. data/spec/unit/context/trusted_information_spec.rb +41 -2
  198. data/spec/unit/http/client_spec.rb +440 -0
  199. data/spec/unit/http/resolver_spec.rb +45 -0
  200. data/spec/unit/http/service/ca_spec.rb +106 -0
  201. data/spec/unit/http/service_spec.rb +32 -0
  202. data/spec/unit/http/session_spec.rb +102 -0
  203. data/spec/unit/indirector/resource/ral_spec.rb +4 -4
  204. data/spec/unit/network/http/connection_spec.rb +119 -145
  205. data/spec/unit/network/http/site_spec.rb +7 -0
  206. data/spec/unit/parser/scope_spec.rb +10 -0
  207. data/spec/unit/pops/loaders/loaders_spec.rb +13 -2
  208. data/spec/unit/pops/loaders/module_loaders_spec.rb +37 -0
  209. data/spec/unit/provider/exec_spec.rb +209 -0
  210. data/spec/unit/provider/package/dnfmodule_spec.rb +186 -0
  211. data/spec/unit/provider/package/dpkg_spec.rb +238 -78
  212. data/spec/unit/provider/package/pip_spec.rb +51 -6
  213. data/spec/unit/provider/service/daemontools_spec.rb +24 -0
  214. data/spec/unit/provider/service/runit_spec.rb +24 -0
  215. data/spec/unit/provider/service/systemd_spec.rb +25 -25
  216. data/spec/unit/provider/user/useradd_spec.rb +46 -0
  217. data/spec/unit/ssl/host_spec.rb +0 -5
  218. data/spec/unit/ssl/state_machine_spec.rb +16 -10
  219. data/spec/unit/type/exec_spec.rb +6 -12
  220. data/spec/unit/type/file_spec.rb +9 -4
  221. data/spec/unit/type/package_spec.rb +5 -0
  222. data/spec/unit/util/execution_spec.rb +16 -0
  223. data/spec/unit/util/http_proxy_spec.rb +79 -27
  224. data/spec/unit/util/log/destinations_spec.rb +7 -3
  225. metadata +45 -22
  226. data/lib/puppet/pops/loader/null_loader.rb +0 -60
  227. data/lib/puppet/vendor/deep_merge/CHANGELOG +0 -45
  228. data/lib/puppet/vendor/deep_merge/Gemfile +0 -3
  229. data/lib/puppet/vendor/deep_merge/LICENSE +0 -21
  230. data/lib/puppet/vendor/deep_merge/PUPPET_README.md +0 -6
  231. data/lib/puppet/vendor/deep_merge/README.md +0 -113
  232. data/lib/puppet/vendor/deep_merge/Rakefile +0 -19
  233. data/lib/puppet/vendor/deep_merge/deep_merge.gemspec +0 -35
  234. data/lib/puppet/vendor/deep_merge/lib/deep_merge.rb +0 -2
  235. data/lib/puppet/vendor/deep_merge/lib/deep_merge/core.rb +0 -210
  236. data/lib/puppet/vendor/deep_merge/lib/deep_merge/deep_merge_hash.rb +0 -28
  237. data/lib/puppet/vendor/deep_merge/lib/deep_merge/rails_compat.rb +0 -27
  238. data/lib/puppet/vendor/deep_merge/test/test_deep_merge.rb +0 -608
  239. data/lib/puppet/vendor/load_deep_merge.rb +0 -1
  240. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_get/should_yield_to_the_block.yml +0 -24
  241. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_head/should_yield_to_the_block.yml +0 -24
  242. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_post/should_yield_to_the_block.yml +0 -24
@@ -22,7 +22,7 @@ class PSensitiveType < PTypeWithContainedType
22
22
  end
23
23
 
24
24
  def inspect
25
- "#<#{to_s}>"
25
+ "#<#{self}>"
26
26
  end
27
27
  end
28
28
 
@@ -175,7 +175,7 @@ class PURIType < PAnyType
175
175
  result[SCHEME] = scheme
176
176
  end
177
177
  result[USERINFO] = uri.userinfo unless uri.userinfo.nil?
178
- result[HOST] = uri.host.downcase unless uri.host.nil?
178
+ result[HOST] = uri.host.downcase unless uri.host.nil? || uri.host.empty?
179
179
  result[PORT] = uri.port.to_s unless uri.port.nil? || uri.port == 80 && 'http' == scheme || uri.port == 443 && 'https' == scheme
180
180
  result[PATH] = uri.path unless uri.path.nil? || uri.path.empty?
181
181
  result[QUERY] = uri.query unless uri.query.nil?
@@ -728,7 +728,7 @@ class StringConverter
728
728
  when :c
729
729
  char = [val].pack("U")
730
730
  char = f.alt? ? "\"#{char}\"" : char
731
- Kernel.format(f.orig_fmt.gsub('c','s'), char)
731
+ Kernel.format(f.orig_fmt.tr('c','s'), char)
732
732
 
733
733
  when :s
734
734
  fmt = f.alt? ? 'p' : 's'
@@ -781,7 +781,7 @@ class StringConverter
781
781
 
782
782
  when :p
783
783
  # width & precision applied to string, not the the name of the type
784
- "Binary(\"#{Kernel.format(f.orig_fmt.gsub('p', 's'), val.to_s)}\")"
784
+ "Binary(\"#{Kernel.format(f.orig_fmt.tr('p', 's'), val.to_s)}\")"
785
785
 
786
786
  when :b
787
787
  Kernel.format(f.orig_fmt.gsub('b', substitute), val.relaxed_to_s)
@@ -817,23 +817,23 @@ class StringConverter
817
817
 
818
818
  when :c
819
819
  c_val = val.capitalize
820
- f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.gsub('c', 's'), c_val)
820
+ f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.tr('c', 's'), c_val)
821
821
 
822
822
  when :C
823
823
  c_val = val.split('::').map {|s| s.capitalize }.join('::')
824
- f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.gsub('C', 's'), c_val)
824
+ f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.tr('C', 's'), c_val)
825
825
 
826
826
  when :u
827
827
  c_val = val.upcase
828
- f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.gsub('u', 's'), c_val)
828
+ f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.tr('u', 's'), c_val)
829
829
 
830
830
  when :d
831
831
  c_val = val.downcase
832
- f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.gsub('d', 's'), c_val)
832
+ f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.tr('d', 's'), c_val)
833
833
 
834
834
  when :t # trim
835
835
  c_val = val.strip
836
- f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.gsub('t', 's'), c_val)
836
+ f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.tr('t', 's'), c_val)
837
837
 
838
838
  else
839
839
  raise FormatError.new('String', f.format, 'cCudspt')
@@ -921,7 +921,7 @@ class StringConverter
921
921
  case f.format
922
922
  when :p
923
923
  str_regexp = PRegexpType.regexp_to_s_with_delimiters(val)
924
- f.orig_fmt == '%p' ? str_regexp : Kernel.format(f.orig_fmt.gsub('p', 's'), str_regexp)
924
+ f.orig_fmt == '%p' ? str_regexp : Kernel.format(f.orig_fmt.tr('p', 's'), str_regexp)
925
925
  when :s
926
926
  str_regexp = PRegexpType.regexp_to_s(val)
927
927
  str_regexp = puppet_quote(str_regexp) if f.alt?
@@ -1098,10 +1098,10 @@ class StringConverter
1098
1098
  f = get_format(val_type, format_map)
1099
1099
  case f.format
1100
1100
  when :s
1101
- str_val = f.alt? ? "\"#{val.to_s}\"" : val.to_s
1101
+ str_val = f.alt? ? "\"#{val}\"" : val.to_s
1102
1102
  Kernel.format(f.orig_fmt, str_val)
1103
1103
  when :p
1104
- Kernel.format(f.orig_fmt.gsub('p', 's'), val.to_s)
1104
+ Kernel.format(f.orig_fmt.tr('p', 's'), val.to_s)
1105
1105
  else
1106
1106
  raise FormatError.new('Type', f.format, 'sp')
1107
1107
  end
@@ -340,7 +340,7 @@ class PAnyType < TypedModelObject
340
340
  # @raises ArgumentError
341
341
  #
342
342
  def self.new_function(type)
343
- raise ArgumentError.new("Creation of new instance of type '#{type.to_s}' is not supported")
343
+ raise ArgumentError.new("Creation of new instance of type '#{type}' is not supported")
344
344
  end
345
345
 
346
346
  # Answers the question if instances of this type can represent themselves as a string that
@@ -1268,7 +1268,7 @@ class PFloatType < PNumericType
1268
1268
  else
1269
1269
  begin
1270
1270
  # support a binary as float
1271
- if from[0] == '0' && from[1].downcase == 'b'
1271
+ if from[0] == '0' && from[1].casecmp('b').zero?
1272
1272
  from = Integer(from)
1273
1273
  end
1274
1274
  Float(from)
@@ -1700,7 +1700,7 @@ class PRegexpType < PScalarType
1700
1700
  # @param regexp [Regexp] the regular expression
1701
1701
  # @return [String] the Regexp as a slash delimited string with slashes escaped
1702
1702
  def self.regexp_to_s_with_delimiters(regexp)
1703
- regexp.options == 0 ? regexp.inspect : "/#{regexp.to_s}/"
1703
+ regexp.options == 0 ? regexp.inspect : "/#{regexp}/"
1704
1704
  end
1705
1705
 
1706
1706
  # @param regexp [Regexp] the regular expression
@@ -207,7 +207,7 @@ class Puppet::Property < Puppet::Parameter
207
207
  else
208
208
  return "#{name} changed #{is_to_s(current_value)} to #{should_to_s(newvalue)}"
209
209
  end
210
- rescue Puppet::Error, Puppet::DevError
210
+ rescue Puppet::Error
211
211
  raise
212
212
  rescue => detail
213
213
  message = _("Could not convert change '%{name}' to string: %{detail}") % { name: name, detail: detail }
@@ -56,7 +56,7 @@ class Puppet::Property::Ensure < Puppet::Property
56
56
  else
57
57
  return _('%{name} changed %{is} to %{should}') % { name: name, is: is_to_s(currentvalue), should: should_to_s(newvalue) }
58
58
  end
59
- rescue Puppet::Error, Puppet::DevError
59
+ rescue Puppet::Error
60
60
  raise
61
61
  rescue => detail
62
62
  raise Puppet::DevError, _("Could not convert change %{name} to string: %{detail}") % { name: self.name, detail: detail }, detail.backtrace
@@ -52,7 +52,11 @@ class Puppet::Provider::Exec < Puppet::Provider
52
52
  # This is backwards compatible all the way to Ruby 1.8.7.
53
53
  Timeout::timeout(resource[:timeout], Timeout::Error) do
54
54
  cwd = resource[:cwd]
55
- cwd ||= Dir.pwd
55
+ # It's ok if cwd is nil. In that case Puppet::Util::Execution.execute() simply will not attempt to
56
+ # change the working directory, which is exactly the right behavior when no cwd parameter is
57
+ # expressed on the resource. Moreover, attempting to change to the directory that is already
58
+ # the working directory can fail under some circumstances, so avoiding the directory change attempt
59
+ # is preferable to defaulting cwd to that directory.
56
60
 
57
61
  # note that we are passing "false" for the "override_locale" parameter, which ensures that the user's
58
62
  # default/system locale will be respected. Callers may override this behavior by setting locale-related
@@ -96,6 +100,6 @@ class Puppet::Provider::Exec < Puppet::Provider
96
100
  def validatecmd(command)
97
101
  exe = extractexe(command)
98
102
  # if we're not fully qualified, require a path
99
- self.fail _("'%{command}' is not qualified and no path was specified. Please qualify the command or specify a path.") % { command: command } if !absolute_path?(exe) and resource[:path].nil?
103
+ self.fail _("'%{exe}' is not qualified and no path was specified. Please qualify the command or specify a path.") % { exe: exe } if !absolute_path?(exe) and resource[:path].nil?
100
104
  end
101
105
  end
@@ -289,7 +289,7 @@ class Puppet::Provider::NameService::DirectoryService < Puppet::Provider::NameSe
289
289
  end
290
290
  dscl_out = dscl(dscl_args)
291
291
  # We're ok with throwing away negative uids here.
292
- ids = dscl_out.split.compact.collect { |l| l.to_i if l.match(/^\d+$/) }
292
+ ids = dscl_out.split.compact.collect { |l| l.to_i if l =~ /^\d+$/ }
293
293
  ids.compact!.sort! { |a,b| a.to_f <=> b.to_f }
294
294
  # We're just looking for an unused id in our sorted array.
295
295
  ids.each_index do |i|
@@ -3,13 +3,13 @@ require 'puppet/provider/nameservice/objectadd'
3
3
  class Puppet::Provider::NameService
4
4
  class PW < ObjectAdd
5
5
  def deletecmd
6
- [command(:pw), "#{@resource.class.name.to_s}del", @resource[:name]]
6
+ [command(:pw), "#{@resource.class.name}del", @resource[:name]]
7
7
  end
8
8
 
9
9
  def modifycmd(param, value)
10
10
  cmd = [
11
11
  command(:pw),
12
- "#{@resource.class.name.to_s}mod",
12
+ "#{@resource.class.name}mod",
13
13
  @resource[:name],
14
14
  flag(param),
15
15
  munge(param, value)
@@ -8,7 +8,7 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
8
8
  These options should be specified as an array where each element is either a
9
9
  string or a hash."
10
10
 
11
- has_feature :versionable, :install_options
11
+ has_feature :versionable, :install_options, :virtual_packages
12
12
 
13
13
  commands :aptget => "/usr/bin/apt-get"
14
14
  commands :aptcache => "/usr/bin/apt-cache"
@@ -22,6 +22,10 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
22
22
  ENV['APT_LISTBUGS_FRONTEND'] = "none"
23
23
  ENV['APT_LISTCHANGES_FRONTEND'] = "none"
24
24
 
25
+ def self.defaultto_allow_virtual
26
+ false
27
+ end
28
+
25
29
  # A derivative of DPKG; this is how most people actually manage
26
30
  # Debian boxes, and the only thing that differs is that it can
27
31
  # install packages from remote sites.
@@ -0,0 +1,87 @@
1
+ # dnfmodule - A puppet package provider for DNF modules
2
+ #
3
+ # Installing a module:
4
+ # package { 'postgresql':
5
+ # provider => 'dnfmodule',
6
+ # ensure => '9.6', # install a specific stream
7
+ # flavor => 'client', # install a specific profile
8
+ # }
9
+
10
+
11
+ require 'puppet/provider/package'
12
+
13
+ Puppet::Type.type(:package).provide :dnfmodule, :parent => :dnf do
14
+
15
+ has_feature :installable, :uninstallable, :versionable
16
+ #has_feature :upgradeable
17
+ # it's not (yet) feasible to make this upgradeable since module streams don't
18
+ # always have matching version types (i.e. idm has streams DL1 and client,
19
+ # other modules have semver streams, others have string streams... we cannot
20
+ # programatically determine a latest version for ensure => 'latest'
21
+
22
+ commands :dnf => '/usr/bin/dnf'
23
+
24
+ def self.current_version
25
+ @current_version ||= dnf('--version').split.first
26
+ end
27
+
28
+ def self.prefetch(packages)
29
+ if Puppet::Util::Package.versioncmp(current_version, '3.0.1') < 0
30
+ raise Puppet::Error, _("Modules are not supported on DNF versions lower than 3.0.1")
31
+ end
32
+ super
33
+ end
34
+
35
+ def self.instances
36
+ packages = []
37
+ cmd = "#{command(:dnf)} module list --installed -d 0 -e #{error_level}"
38
+ execute(cmd).each_line do |line|
39
+ next unless line =~ /\[i\][, ]/ # get rid of non-package lines (including last Hint line)
40
+ line.gsub!(/\[[de]\]/, '') # we don't care about default/enabled flags
41
+ packages << new(
42
+ name: line.split[0],
43
+ ensure: line.split[1],
44
+ flavor: line.split('[i]').first.split.last, # this is nasty
45
+ provider: name
46
+ )
47
+ end
48
+ packages
49
+ end
50
+
51
+ def query
52
+ pkg = self.class.instances.find do |package|
53
+ @resource[:name] == package.name
54
+ end
55
+ pkg ? pkg.properties : nil
56
+ end
57
+
58
+ def reset
59
+ execute([command(:dnf), 'module', 'reset', '-d', '0', '-e', self.class.error_level, '-y', @resource[:name]])
60
+ end
61
+
62
+ # to install specific streams and profiles:
63
+ # $ dnf module install module-name:stream/profile
64
+ # $ dnf module install perl:5.24/minimal
65
+ # if unspecified, they will be defaulted (see [d] param in dnf module list output)
66
+ def install
67
+ args = @resource[:name]
68
+ # ensure we start fresh (remove existing stream)
69
+ uninstall unless [:absent, :purged].include?(@property_hash[:ensure])
70
+ case @resource[:ensure]
71
+ when true, false, Symbol
72
+ # pass
73
+ else
74
+ args << ":#{@resource[:ensure]}"
75
+ end
76
+ if @resource[:flavor]
77
+ args << "/#{@resource[:flavor]}"
78
+ end
79
+ execute([command(:dnf), 'module', 'install', '-d', '0', '-e', self.class.error_level, '-y', args])
80
+ end
81
+
82
+ def uninstall
83
+ execute([command(:dnf), 'module', 'remove', '-d', '0', '-e', self.class.error_level, '-y', @resource[:name]])
84
+ reset # reset module to the default stream
85
+ end
86
+ end
87
+
@@ -5,8 +5,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
5
5
  and not `apt`, you must specify the source of any packages you want
6
6
  to manage."
7
7
 
8
- has_feature :holdable
9
-
8
+ has_feature :holdable, :virtual_packages
10
9
  commands :dpkg => "/usr/bin/dpkg"
11
10
  commands :dpkg_deb => "/usr/bin/dpkg-deb"
12
11
  commands :dpkgquery => "/usr/bin/dpkg-query"
@@ -45,16 +44,22 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
45
44
  # Note: self:: is required here to keep these constants in the context of what will
46
45
  # eventually become this Puppet::Type::Package::ProviderDpkg class.
47
46
  self::DPKG_QUERY_FORMAT_STRING = %Q{'${Status} ${Package} ${Version}\\n'}
47
+ self::DPKG_QUERY_PROVIDES_FORMAT_STRING = %Q{'${Status} ${Package} ${Version} [${Provides}]\\n'}
48
48
  self::FIELDS_REGEX = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*)$}
49
+ self::FIELDS_REGEX_WITH_PROVIDES = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*) \[.*\]$}
49
50
  self::FIELDS= [:desired, :error, :status, :name, :ensure]
50
51
 
52
+ def self.defaultto_allow_virtual
53
+ false
54
+ end
55
+
51
56
  # @param line [String] one line of dpkg-query output
52
57
  # @return [Hash,nil] a hash of FIELDS or nil if we failed to match
53
58
  # @api private
54
- def self.parse_line(line)
59
+ def self.parse_line(line, regex=self::FIELDS_REGEX)
55
60
  hash = nil
56
61
 
57
- match = self::FIELDS_REGEX.match(line)
62
+ match = regex.match(line)
58
63
  if match
59
64
  hash = {}
60
65
 
@@ -105,7 +110,11 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
105
110
 
106
111
  # Return the version from the package.
107
112
  def latest
108
- output = dpkg_deb "--show", @resource[:source]
113
+ source = @resource[:source]
114
+ unless source
115
+ @resource.fail _("Could not update: You cannot install dpkg packages without a source")
116
+ end
117
+ output = dpkg_deb "--show", source
109
118
  matches = /^(\S+)\t(\S+)$/.match(output).captures
110
119
  warning _("source doesn't contain named package, but %{name}") % { name: matches[0] } unless matches[0].match( Regexp.escape(@resource[:name]) )
111
120
  matches[1]
@@ -116,6 +125,20 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
116
125
 
117
126
  # list out our specific package
118
127
  begin
128
+ if @resource.allow_virtual?
129
+ output = dpkgquery(
130
+ "-W",
131
+ "--showformat",
132
+ self.class::DPKG_QUERY_PROVIDES_FORMAT_STRING
133
+ #the regex searches for the resource[:name] in the dpkquery result in which the Provides field is also available
134
+ #it will search for the packages only in the brackets ex: [rubygems]
135
+ ).lines.find {|package| package.match(/[\[ ](#{Regexp.escape(@resource[:name])})[\],]/)}
136
+ if output
137
+ hash = self.class.parse_line(output,self.class::FIELDS_REGEX_WITH_PROVIDES)
138
+ Puppet.info("Package #{@resource[:name]} is virtual, defaulting to #{hash[:name]}")
139
+ @resource[:name] = hash[:name]
140
+ end
141
+ end
119
142
  output = dpkgquery(
120
143
  "-W",
121
144
  "--showformat",
@@ -148,7 +171,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
148
171
  end
149
172
 
150
173
  def hold
151
- if package_not_installed?(@resource[:name])
174
+ if package_not_installed?
152
175
  self.install
153
176
  end
154
177
  Tempfile.open('puppet_dpkg_set_selection') do |tmpfile|
@@ -166,16 +189,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
166
189
  end
167
190
  end
168
191
 
169
- def package_not_installed?(name)
170
- if !name.nil? && !name.empty?
171
- begin
172
- dpkgquery("-W", "--showformat", self.class::DPKG_QUERY_FORMAT_STRING, name)
173
- rescue Puppet::ExecutionFailure
174
- # return true if exception is generated because package is not found
175
- return true
176
- end
177
- return false
178
- end
179
- raise ArgumentError.new("Package name is nil or empty")
192
+ def package_not_installed?
193
+ query[:status] != "installed"
180
194
  end
181
195
  end
@@ -185,7 +185,7 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
185
185
  # If :ensure contains a version, use that instead of looking it up.
186
186
  # This allows for installing packages with the same stem, but multiple
187
187
  # version such as openldap-server.
188
- if /(\d[^-]*)$/.match(@resource[:ensure].to_s)
188
+ if @resource[:ensure].to_s =~ /(\d[^-]*)$/
189
189
  use_version = @resource[:ensure]
190
190
  else
191
191
  use_version = get_version
@@ -35,16 +35,25 @@ Puppet::Type.type(:package).provide :pip, :parent => ::Puppet::Provider::Package
35
35
  if Puppet::Util::Platform.windows?
36
36
  ["pip.exe"]
37
37
  else
38
- ["pip", "pip-python"]
38
+ ["pip", "pip-python", "pip2", "pip-2"]
39
39
  end
40
40
  end
41
41
 
42
42
  def self.pip_version(command)
43
- execpipe [command, '--version'] do |process|
43
+ version = nil
44
+ execpipe [quote(command), '--version'] do |process|
44
45
  process.collect do |line|
45
- return line.strip.match(/^pip (\d+\.\d+\.?\d*).*$/)[1]
46
+ md = line.strip.match(/^pip (\d+\.\d+\.?\d*).*$/)
47
+ if md
48
+ version = md[1]
49
+ break
50
+ end
46
51
  end
47
52
  end
53
+
54
+ raise Puppet::Error, _("Cannot resolve pip version") unless version
55
+
56
+ version
48
57
  end
49
58
 
50
59
  # Return an array of structured information about every installed package
@@ -102,7 +111,7 @@ Puppet::Type.type(:package).provide :pip, :parent => ::Puppet::Provider::Package
102
111
  self.class.validate_command(command)
103
112
 
104
113
  self.class.instances(command).each do |pkg|
105
- return pkg.properties if @resource[:name].downcase == pkg.name.downcase
114
+ return pkg.properties if @resource[:name].casecmp(pkg.name).zero?
106
115
  end
107
116
  return nil
108
117
  end
@@ -122,14 +131,17 @@ Puppet::Type.type(:package).provide :pip, :parent => ::Puppet::Provider::Package
122
131
  end
123
132
  end
124
133
 
134
+ # Less resource-intensive approach for pip version 1.5.4 and newer.
135
+
125
136
  def latest_with_new_pip
126
137
  command = resource_or_provider_command
127
138
  self.class.validate_command(command)
128
139
 
129
- # Less resource intensive approach for pip version 1.5.4 and above
130
- execpipe [command, "install", "#{@resource[:name]}==versionplease"] do |process|
140
+ command_and_options = [command, 'install', "#{@resource[:name]}==versionplease"]
141
+ command_and_options << install_options if @resource[:install_options]
142
+ execpipe command_and_options do |process|
131
143
  process.collect do |line|
132
- # PIP OUTPUT: Could not find a version that satisfies the requirement Django==versionplease (from versions: 1.1.3, 1.8rc1)
144
+ # PIP OUTPUT: Could not find a version that satisfies the requirement example==versionplease (from versions: 1.2.3, 4.5.6)
133
145
  if line =~ /from versions: /
134
146
  textAfterLastMatch = $'.chomp(")\n")
135
147
  versionList = textAfterLastMatch.split(', ').sort do |x,y|
@@ -142,14 +154,18 @@ Puppet::Type.type(:package).provide :pip, :parent => ::Puppet::Provider::Package
142
154
  end
143
155
  end
144
156
 
157
+ # More resource-intensive approach for pip version 1.5.3 and older.
158
+
145
159
  def latest_with_old_pip
146
160
  command = resource_or_provider_command
147
161
  self.class.validate_command(command)
148
162
 
149
163
  Dir.mktmpdir("puppet_pip") do |dir|
150
- execpipe [command, "install", "#{@resource[:name]}", "-d", "#{dir}", "-v"] do |process|
164
+ command_and_options = [command, 'install', "#{@resource[:name]}", '-d', "#{dir}", '-v']
165
+ command_and_options << install_options if @resource[:install_options]
166
+ execpipe command_and_options do |process|
151
167
  process.collect do |line|
152
- # PIP OUTPUT: Using version 0.10.1 (newest of versions: 0.10.1, 0.10, 0.9, 0.8.1, 0.8, 0.7.2, 0.7.1, 0.7, 0.6.1, 0.6, 0.5.2, 0.5.1, 0.5, 0.4, 0.3.1, 0.3, 0.2, 0.1)
168
+ # PIP OUTPUT: Using version 0.10.1 (newest of versions: 1.2.3, 4.5.6)
153
169
  if line =~ /Using version (.+?) \(newest of versions/
154
170
  return $1
155
171
  end
@@ -209,4 +225,13 @@ Puppet::Type.type(:package).provide :pip, :parent => ::Puppet::Provider::Package
209
225
  def install_options
210
226
  join_options(@resource[:install_options])
211
227
  end
228
+
229
+ def self.quote(path)
230
+ if path.include?(" ")
231
+ "\"#{path}\""
232
+ else
233
+ path
234
+ end
235
+ end
236
+ private_class_method :quote
212
237
  end