puppet 6.11.1 → 6.16.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 (395) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +3 -8
  3. data/CONTRIBUTING.md +7 -13
  4. data/Gemfile +1 -0
  5. data/Gemfile.lock +39 -36
  6. data/README.md +17 -24
  7. data/ext/build_defaults.yaml +1 -0
  8. data/ext/project_data.yaml +1 -1
  9. data/ext/windows/service/daemon.rb +25 -20
  10. data/lib/puppet.rb +52 -13
  11. data/lib/puppet/agent.rb +20 -14
  12. data/lib/puppet/application/agent.rb +12 -14
  13. data/lib/puppet/application/describe.rb +7 -5
  14. data/lib/puppet/application/device.rb +2 -2
  15. data/lib/puppet/application/filebucket.rb +19 -15
  16. data/lib/puppet/application/plugin.rb +1 -0
  17. data/lib/puppet/application/resource.rb +1 -1
  18. data/lib/puppet/application/ssl.rb +4 -4
  19. data/lib/puppet/concurrent.rb +2 -0
  20. data/lib/puppet/concurrent/lock.rb +16 -0
  21. data/lib/puppet/concurrent/synchronized.rb +15 -0
  22. data/lib/puppet/concurrent/thread_local_singleton.rb +14 -0
  23. data/lib/puppet/configurer.rb +85 -83
  24. data/lib/puppet/configurer/plugin_handler.rb +10 -1
  25. data/lib/puppet/context/trusted_information.rb +14 -8
  26. data/lib/puppet/daemon.rb +13 -27
  27. data/lib/puppet/defaults.rb +158 -40
  28. data/lib/puppet/environments.rb +30 -20
  29. data/lib/puppet/error.rb +9 -1
  30. data/lib/puppet/face/facts.rb +8 -5
  31. data/lib/puppet/face/help.rb +29 -3
  32. data/lib/puppet/face/module/search.rb +5 -0
  33. data/lib/puppet/face/plugin.rb +2 -2
  34. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  35. data/lib/puppet/file_system/file_impl.rb +13 -9
  36. data/lib/puppet/file_system/memory_file.rb +6 -0
  37. data/lib/puppet/file_system/memory_impl.rb +13 -0
  38. data/lib/puppet/file_system/uniquefile.rb +4 -0
  39. data/lib/puppet/file_system/windows.rb +7 -10
  40. data/lib/puppet/forge.rb +3 -3
  41. data/lib/puppet/forge/errors.rb +2 -2
  42. data/lib/puppet/forge/repository.rb +31 -86
  43. data/lib/puppet/functions/call.rb +1 -1
  44. data/lib/puppet/functions/camelcase.rb +2 -2
  45. data/lib/puppet/functions/epp.rb +4 -4
  46. data/lib/puppet/functions/eyaml_lookup_key.rb +13 -8
  47. data/lib/puppet/functions/filter.rb +1 -0
  48. data/lib/puppet/functions/find_file.rb +9 -9
  49. data/lib/puppet/functions/find_template.rb +63 -0
  50. data/lib/puppet/functions/inline_epp.rb +5 -5
  51. data/lib/puppet/functions/reduce.rb +2 -4
  52. data/lib/puppet/http.rb +7 -0
  53. data/lib/puppet/http/client.rb +341 -54
  54. data/lib/puppet/http/errors.rb +2 -0
  55. data/lib/puppet/http/external_client.rb +90 -0
  56. data/lib/puppet/http/redirector.rb +34 -0
  57. data/lib/puppet/http/resolver.rb +57 -1
  58. data/lib/puppet/http/resolver/server_list.rb +98 -0
  59. data/lib/puppet/http/resolver/settings.rb +23 -2
  60. data/lib/puppet/http/resolver/srv.rb +36 -4
  61. data/lib/puppet/http/response.rb +68 -1
  62. data/lib/puppet/http/retry_after_handler.rb +39 -0
  63. data/lib/puppet/http/service.rb +179 -3
  64. data/lib/puppet/http/service/ca.rb +84 -21
  65. data/lib/puppet/http/service/compiler.rb +319 -0
  66. data/lib/puppet/http/service/file_server.rb +206 -0
  67. data/lib/puppet/http/service/report.rb +66 -0
  68. data/lib/puppet/http/session.rb +106 -31
  69. data/lib/puppet/indirector/catalog/compiler.rb +10 -0
  70. data/lib/puppet/indirector/catalog/rest.rb +34 -0
  71. data/lib/puppet/indirector/facts/rest.rb +42 -0
  72. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  73. data/lib/puppet/indirector/file_bucket_file/rest.rb +48 -0
  74. data/lib/puppet/indirector/file_content/http.rb +5 -0
  75. data/lib/puppet/indirector/file_content/rest.rb +30 -0
  76. data/lib/puppet/indirector/file_metadata/http.rb +4 -4
  77. data/lib/puppet/indirector/file_metadata/rest.rb +52 -0
  78. data/lib/puppet/indirector/json.rb +1 -1
  79. data/lib/puppet/indirector/msgpack.rb +1 -1
  80. data/lib/puppet/indirector/node/rest.rb +24 -0
  81. data/lib/puppet/indirector/report/rest.rb +19 -0
  82. data/lib/puppet/indirector/report/yaml.rb +23 -0
  83. data/lib/puppet/indirector/rest.rb +12 -0
  84. data/lib/puppet/indirector/status/rest.rb +18 -0
  85. data/lib/puppet/loaders.rb +6 -0
  86. data/lib/puppet/metatype/manager.rb +80 -80
  87. data/lib/puppet/network/http/base_pool.rb +19 -1
  88. data/lib/puppet/network/http/compression.rb +7 -0
  89. data/lib/puppet/network/http/connection.rb +6 -0
  90. data/lib/puppet/network/http/connection_adapter.rb +182 -0
  91. data/lib/puppet/network/http/nocache_pool.rb +2 -0
  92. data/lib/puppet/network/http/pool.rb +13 -6
  93. data/lib/puppet/network/http_pool.rb +2 -1
  94. data/lib/puppet/node/environment.rb +24 -8
  95. data/lib/puppet/pal/catalog_compiler.rb +5 -0
  96. data/lib/puppet/pal/pal_impl.rb +9 -29
  97. data/lib/puppet/parser/ast/pops_bridge.rb +6 -11
  98. data/lib/puppet/parser/compiler.rb +42 -32
  99. data/lib/puppet/parser/functions.rb +18 -13
  100. data/lib/puppet/parser/functions/epp.rb +3 -3
  101. data/lib/puppet/parser/functions/filter.rb +1 -0
  102. data/lib/puppet/parser/functions/inline_epp.rb +5 -5
  103. data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
  104. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
  105. data/lib/puppet/pops/evaluator/runtime3_support.rb +1 -1
  106. data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +12 -3
  107. data/lib/puppet/pops/loaders.rb +7 -5
  108. data/lib/puppet/pops/lookup/invocation.rb +10 -3
  109. data/lib/puppet/pops/model/pn_transformer.rb +5 -9
  110. data/lib/puppet/pops/parser/evaluating_parser.rb +8 -11
  111. data/lib/puppet/pops/serialization/json_path.rb +3 -3
  112. data/lib/puppet/pops/time/timespan.rb +3 -5
  113. data/lib/puppet/pops/types/p_object_type_extension.rb +10 -0
  114. data/lib/puppet/pops/types/string_converter.rb +6 -9
  115. data/lib/puppet/pops/types/type_calculator.rb +30 -10
  116. data/lib/puppet/pops/types/type_formatter.rb +9 -11
  117. data/lib/puppet/pops/types/type_parser.rb +3 -3
  118. data/lib/puppet/pops/validation/checker4_0.rb +1 -1
  119. data/lib/puppet/pops/validation/tasks_checker.rb +5 -1
  120. data/lib/puppet/provider/aix_object.rb +4 -2
  121. data/lib/puppet/provider/group/aix.rb +1 -0
  122. data/lib/puppet/provider/group/groupadd.rb +57 -24
  123. data/lib/puppet/provider/group/windows_adsi.rb +3 -3
  124. data/lib/puppet/provider/package/aix.rb +17 -2
  125. data/lib/puppet/provider/package/apt.rb +78 -4
  126. data/lib/puppet/provider/package/dnfmodule.rb +69 -15
  127. data/lib/puppet/provider/package/dpkg.rb +14 -7
  128. data/lib/puppet/provider/package/fink.rb +20 -3
  129. data/lib/puppet/provider/package/gem.rb +41 -7
  130. data/lib/puppet/provider/package/openbsd.rb +13 -1
  131. data/lib/puppet/provider/package/pacman.rb +2 -5
  132. data/lib/puppet/provider/package/pip.rb +143 -48
  133. data/lib/puppet/provider/package/pip3.rb +0 -2
  134. data/lib/puppet/provider/package/pkg.rb +18 -5
  135. data/lib/puppet/provider/package/pkgdmg.rb +1 -1
  136. data/lib/puppet/provider/package/pkgng.rb +16 -4
  137. data/lib/puppet/provider/package/portage.rb +5 -5
  138. data/lib/puppet/provider/package/puppet_gem.rb +6 -2
  139. data/lib/puppet/provider/package/rpm.rb +6 -213
  140. data/lib/puppet/provider/package/yum.rb +108 -24
  141. data/lib/puppet/provider/package/zypper.rb +59 -1
  142. data/lib/puppet/provider/package_targetable.rb +5 -4
  143. data/lib/puppet/provider/service/systemd.rb +23 -5
  144. data/lib/puppet/provider/user/aix.rb +1 -0
  145. data/lib/puppet/provider/user/directoryservice.rb +30 -5
  146. data/lib/puppet/provider/user/hpux.rb +1 -1
  147. data/lib/puppet/provider/user/useradd.rb +11 -8
  148. data/lib/puppet/reports/http.rb +13 -9
  149. data/lib/puppet/reports/store.rb +1 -1
  150. data/lib/puppet/resource/type_collection.rb +20 -16
  151. data/lib/puppet/runtime.rb +32 -1
  152. data/lib/puppet/settings.rb +4 -0
  153. data/lib/puppet/settings/http_extra_headers_setting.rb +25 -0
  154. data/lib/puppet/ssl.rb +1 -0
  155. data/lib/puppet/ssl/certificate.rb +2 -1
  156. data/lib/puppet/ssl/host.rb +4 -4
  157. data/lib/puppet/ssl/oids.rb +1 -0
  158. data/lib/puppet/ssl/ssl_provider.rb +20 -0
  159. data/lib/puppet/ssl/state_machine.rb +81 -35
  160. data/lib/puppet/ssl/verifier_adapter.rb +9 -1
  161. data/lib/puppet/test/test_helper.rb +7 -1
  162. data/lib/puppet/transaction.rb +33 -11
  163. data/lib/puppet/transaction/report.rb +2 -2
  164. data/lib/puppet/transaction/resource_harness.rb +1 -1
  165. data/lib/puppet/type.rb +7 -2
  166. data/lib/puppet/type/file.rb +13 -0
  167. data/lib/puppet/type/file/data_sync.rb +5 -1
  168. data/lib/puppet/type/file/source.rb +49 -58
  169. data/lib/puppet/type/group.rb +5 -4
  170. data/lib/puppet/type/package.rb +102 -10
  171. data/lib/puppet/type/service.rb +6 -8
  172. data/lib/puppet/type/user.rb +6 -30
  173. data/lib/puppet/util.rb +34 -11
  174. data/lib/puppet/util/at_fork.rb +1 -1
  175. data/lib/puppet/util/autoload.rb +4 -18
  176. data/lib/puppet/util/instance_loader.rb +14 -10
  177. data/lib/puppet/util/log/destinations.rb +2 -11
  178. data/lib/puppet/util/logging.rb +30 -18
  179. data/lib/puppet/util/package/version/debian.rb +175 -0
  180. data/lib/puppet/util/package/version/gem.rb +15 -0
  181. data/lib/puppet/util/package/version/pip.rb +167 -0
  182. data/lib/puppet/util/package/version/range.rb +53 -0
  183. data/lib/puppet/util/package/version/range/eq.rb +14 -0
  184. data/lib/puppet/util/package/version/range/gt.rb +14 -0
  185. data/lib/puppet/util/package/version/range/gt_eq.rb +14 -0
  186. data/lib/puppet/util/package/version/range/lt.rb +14 -0
  187. data/lib/puppet/util/package/version/range/lt_eq.rb +14 -0
  188. data/lib/puppet/util/package/version/range/min_max.rb +21 -0
  189. data/lib/puppet/util/package/version/range/simple.rb +11 -0
  190. data/lib/puppet/util/package/version/rpm.rb +73 -0
  191. data/lib/puppet/util/pidlock.rb +36 -10
  192. data/lib/puppet/util/platform.rb +5 -0
  193. data/lib/puppet/util/plist.rb +6 -0
  194. data/lib/puppet/util/rpm_compare.rb +193 -0
  195. data/lib/puppet/util/storage.rb +0 -1
  196. data/lib/puppet/util/windows/adsi.rb +50 -20
  197. data/lib/puppet/util/windows/process.rb +15 -14
  198. data/lib/puppet/util/windows/security.rb +1 -0
  199. data/lib/puppet/util/windows/sid.rb +3 -3
  200. data/lib/puppet/util/yaml.rb +1 -1
  201. data/lib/puppet/version.rb +1 -1
  202. data/lib/puppet/x509/cert_provider.rb +9 -5
  203. data/locales/puppet.pot +640 -521
  204. data/man/man5/puppet.conf.5 +88 -9
  205. data/man/man8/puppet-agent.8 +6 -6
  206. data/man/man8/puppet-apply.8 +1 -1
  207. data/man/man8/puppet-catalog.8 +1 -1
  208. data/man/man8/puppet-config.8 +1 -1
  209. data/man/man8/puppet-describe.8 +1 -1
  210. data/man/man8/puppet-device.8 +2 -2
  211. data/man/man8/puppet-doc.8 +1 -1
  212. data/man/man8/puppet-epp.8 +1 -1
  213. data/man/man8/puppet-facts.8 +1 -1
  214. data/man/man8/puppet-filebucket.8 +17 -2
  215. data/man/man8/puppet-generate.8 +1 -1
  216. data/man/man8/puppet-help.8 +6 -3
  217. data/man/man8/puppet-key.8 +1 -1
  218. data/man/man8/puppet-lookup.8 +1 -1
  219. data/man/man8/puppet-man.8 +1 -1
  220. data/man/man8/puppet-module.8 +4 -1
  221. data/man/man8/puppet-node.8 +1 -1
  222. data/man/man8/puppet-parser.8 +1 -1
  223. data/man/man8/puppet-plugin.8 +1 -1
  224. data/man/man8/puppet-report.8 +1 -1
  225. data/man/man8/puppet-resource.8 +1 -1
  226. data/man/man8/puppet-script.8 +1 -1
  227. data/man/man8/puppet-ssl.8 +2 -2
  228. data/man/man8/puppet-status.8 +1 -1
  229. data/man/man8/puppet.8 +2 -2
  230. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +67 -0
  231. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +48 -0
  232. data/spec/fixtures/ssl/unknown-ca-key.pem +67 -0
  233. data/spec/fixtures/ssl/unknown-ca.pem +59 -0
  234. data/spec/fixtures/unit/forge/bacula.json +76 -0
  235. data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-installed.txt → dnf-module-list.txt} +8 -0
  236. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +2 -0
  237. data/spec/fixtures/unit/provider/package/yum/yum-check-update-subscription-manager.txt +9 -0
  238. data/spec/fixtures/unit/provider/package/zypper/zypper-search-uninstalled.out +13 -0
  239. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
  240. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +1 -102
  241. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +1 -106
  242. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +1 -106
  243. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +1 -102
  244. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +1 -98
  245. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +1 -102
  246. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +1 -102
  247. data/spec/integration/application/agent_spec.rb +394 -0
  248. data/spec/integration/application/apply_spec.rb +132 -3
  249. data/spec/integration/application/filebucket_spec.rb +190 -0
  250. data/spec/integration/application/plugin_spec.rb +73 -0
  251. data/spec/integration/configurer_spec.rb +26 -7
  252. data/spec/integration/http/client_spec.rb +154 -0
  253. data/spec/integration/indirector/facts/facter_spec.rb +4 -0
  254. data/spec/integration/indirector/report/yaml.rb +83 -0
  255. data/spec/integration/module_tool/forge_spec.rb +51 -0
  256. data/spec/integration/network/http_pool_spec.rb +76 -20
  257. data/spec/integration/node/environment_spec.rb +15 -0
  258. data/spec/integration/util/windows/adsi_spec.rb +6 -1
  259. data/spec/lib/puppet/test_ca.rb +2 -2
  260. data/spec/lib/puppet_spec/https.rb +20 -9
  261. data/spec/lib/puppet_spec/puppetserver.rb +119 -0
  262. data/spec/shared_contexts/https.rb +29 -0
  263. data/spec/spec_helper.rb +6 -2
  264. data/spec/unit/agent_spec.rb +80 -26
  265. data/spec/unit/application/agent_spec.rb +9 -5
  266. data/spec/unit/application/apply_spec.rb +2 -12
  267. data/spec/unit/application/describe_spec.rb +88 -50
  268. data/spec/unit/application/device_spec.rb +2 -2
  269. data/spec/unit/application/filebucket_spec.rb +22 -2
  270. data/spec/unit/application/resource_spec.rb +2 -2
  271. data/spec/unit/concurrent/lock_spec.rb +29 -0
  272. data/spec/unit/configurer/fact_handler_spec.rb +0 -4
  273. data/spec/unit/configurer/plugin_handler_spec.rb +36 -19
  274. data/spec/unit/configurer_spec.rb +400 -406
  275. data/spec/unit/context/trusted_information_spec.rb +17 -0
  276. data/spec/unit/daemon_spec.rb +5 -64
  277. data/spec/unit/defaults_spec.rb +38 -4
  278. data/spec/unit/environments_spec.rb +65 -28
  279. data/spec/unit/face/facts_spec.rb +24 -20
  280. data/spec/unit/face/module/search_spec.rb +17 -0
  281. data/spec/unit/face/plugin_spec.rb +12 -10
  282. data/spec/unit/file_system/uniquefile_spec.rb +11 -0
  283. data/spec/unit/file_system_spec.rb +26 -2
  284. data/spec/unit/forge/errors_spec.rb +1 -1
  285. data/spec/unit/forge/forge_spec.rb +12 -54
  286. data/spec/unit/forge/module_release_spec.rb +19 -6
  287. data/spec/unit/forge/repository_spec.rb +63 -157
  288. data/spec/unit/forge_spec.rb +46 -116
  289. data/spec/unit/functions/find_template_spec.rb +69 -0
  290. data/spec/unit/functions/lookup_spec.rb +13 -0
  291. data/spec/unit/http/client_spec.rb +395 -27
  292. data/spec/unit/http/external_client_spec.rb +201 -0
  293. data/spec/unit/http/resolver_spec.rb +81 -12
  294. data/spec/unit/http/response_spec.rb +69 -0
  295. data/spec/unit/http/service/ca_spec.rb +100 -7
  296. data/spec/unit/http/service/compiler_spec.rb +627 -0
  297. data/spec/unit/http/service/file_server_spec.rb +308 -0
  298. data/spec/unit/http/service/report_spec.rb +118 -0
  299. data/spec/unit/http/service_spec.rb +117 -4
  300. data/spec/unit/http/session_spec.rb +237 -19
  301. data/spec/unit/indirector/catalog/compiler_spec.rb +47 -29
  302. data/spec/unit/indirector/catalog/rest_spec.rb +59 -2
  303. data/spec/unit/indirector/facts/rest_spec.rb +79 -24
  304. data/spec/unit/indirector/file_bucket_file/rest_spec.rb +82 -2
  305. data/spec/unit/indirector/file_content/rest_spec.rb +53 -2
  306. data/spec/unit/indirector/file_metadata/http_spec.rb +167 -0
  307. data/spec/unit/indirector/file_metadata/rest_spec.rb +110 -2
  308. data/spec/unit/indirector/node/rest_spec.rb +57 -2
  309. data/spec/unit/indirector/report/rest_spec.rb +58 -51
  310. data/spec/unit/indirector/resource/ral_spec.rb +7 -8
  311. data/spec/unit/indirector/rest_spec.rb +13 -0
  312. data/spec/unit/indirector/status/rest_spec.rb +43 -2
  313. data/spec/unit/network/http/connection_spec.rb +549 -176
  314. data/spec/unit/network/http/nocache_pool_spec.rb +25 -3
  315. data/spec/unit/network/http/pool_spec.rb +89 -11
  316. data/spec/unit/network/http_pool_spec.rb +63 -57
  317. data/spec/unit/network/http_spec.rb +1 -1
  318. data/spec/unit/node/environment_spec.rb +16 -0
  319. data/spec/unit/node/facts_spec.rb +2 -1
  320. data/spec/unit/node_spec.rb +7 -4
  321. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +8 -3
  322. data/spec/unit/pops/serialization/to_from_hr_spec.rb +6 -1
  323. data/spec/unit/pops/validator/validator_spec.rb +7 -2
  324. data/spec/unit/provider/aix_object_spec.rb +16 -2
  325. data/spec/unit/provider/group/groupadd_spec.rb +181 -56
  326. data/spec/unit/provider/group/windows_adsi_spec.rb +43 -10
  327. data/spec/unit/provider/package/aix_spec.rb +29 -0
  328. data/spec/unit/provider/package/apt_spec.rb +43 -2
  329. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  330. data/spec/unit/provider/package/dnfmodule_spec.rb +76 -15
  331. data/spec/unit/provider/package/dpkg_spec.rb +28 -6
  332. data/spec/unit/provider/package/gem_spec.rb +40 -0
  333. data/spec/unit/provider/package/openbsd_spec.rb +17 -0
  334. data/spec/unit/provider/package/pacman_spec.rb +6 -21
  335. data/spec/unit/provider/package/pip_spec.rb +68 -19
  336. data/spec/unit/provider/package/pkg_spec.rb +15 -1
  337. data/spec/unit/provider/package/pkgdmg_spec.rb +1 -1
  338. data/spec/unit/provider/package/pkgng_spec.rb +38 -0
  339. data/spec/unit/provider/package/portage_spec.rb +9 -4
  340. data/spec/unit/provider/package/puppet_gem_spec.rb +8 -0
  341. data/spec/unit/provider/package/rpm_spec.rb +0 -212
  342. data/spec/unit/provider/package/yum_spec.rb +292 -0
  343. data/spec/unit/provider/package/zypper_spec.rb +84 -0
  344. data/spec/unit/provider/package_targetable_spec.rb +60 -0
  345. data/spec/unit/provider/service/init_spec.rb +1 -0
  346. data/spec/unit/provider/service/openbsd_spec.rb +9 -0
  347. data/spec/unit/provider/service/openwrt_spec.rb +1 -0
  348. data/spec/unit/provider/service/redhat_spec.rb +9 -0
  349. data/spec/unit/provider/service/systemd_spec.rb +92 -12
  350. data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
  351. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  352. data/spec/unit/provider/user/useradd_spec.rb +21 -8
  353. data/spec/unit/provider/user/windows_adsi_spec.rb +3 -3
  354. data/spec/unit/puppet_pal_2pec.rb +0 -26
  355. data/spec/unit/puppet_pal_catalog_spec.rb +46 -0
  356. data/spec/unit/puppet_spec.rb +47 -0
  357. data/spec/unit/reports/http_spec.rb +70 -52
  358. data/spec/unit/settings/autosign_setting_spec.rb +1 -1
  359. data/spec/unit/settings/http_extra_headers_spec.rb +64 -0
  360. data/spec/unit/ssl/certificate_spec.rb +7 -0
  361. data/spec/unit/ssl/host_spec.rb +4 -2
  362. data/spec/unit/ssl/oids_spec.rb +1 -0
  363. data/spec/unit/ssl/ssl_provider_spec.rb +71 -0
  364. data/spec/unit/ssl/state_machine_spec.rb +99 -13
  365. data/spec/unit/transaction/persistence_spec.rb +1 -10
  366. data/spec/unit/transaction/report_spec.rb +4 -0
  367. data/spec/unit/transaction_spec.rb +45 -1
  368. data/spec/unit/type/file/content_spec.rb +9 -3
  369. data/spec/unit/type/file/ensure_spec.rb +1 -2
  370. data/spec/unit/type/file/source_spec.rb +86 -35
  371. data/spec/unit/type/package_spec.rb +8 -0
  372. data/spec/unit/type/service_spec.rb +9 -8
  373. data/spec/unit/type/user_spec.rb +1 -2
  374. data/spec/unit/util/at_fork_spec.rb +3 -2
  375. data/spec/unit/util/autoload_spec.rb +2 -1
  376. data/spec/unit/util/log/destinations_spec.rb +1 -29
  377. data/spec/unit/util/log_spec.rb +0 -138
  378. data/spec/unit/util/logging_spec.rb +200 -0
  379. data/spec/unit/util/package/version/debian_spec.rb +83 -0
  380. data/spec/unit/util/package/version/pip_spec.rb +464 -0
  381. data/spec/unit/util/package/version/range_spec.rb +175 -0
  382. data/spec/unit/util/package/version/rpm_spec.rb +121 -0
  383. data/spec/unit/util/pidlock_spec.rb +112 -42
  384. data/spec/unit/util/plist_spec.rb +20 -0
  385. data/spec/unit/util/rpm_compare_spec.rb +196 -0
  386. data/spec/unit/util/storage_spec.rb +1 -8
  387. data/spec/unit/util/windows/adsi_spec.rb +55 -4
  388. data/spec/unit/util/windows/sid_spec.rb +2 -2
  389. data/spec/unit/x509/cert_provider_spec.rb +24 -4
  390. data/tasks/generate_cert_fixtures.rake +15 -1
  391. data/tasks/manpages.rake +6 -35
  392. metadata +92 -12
  393. data/COMMITTERS.md +0 -244
  394. data/spec/integration/faces/plugin_spec.rb +0 -61
  395. data/spec/lib/puppet_spec/validators.rb +0 -37
@@ -1,8 +1,6 @@
1
1
  # Puppet package provider for Python's `pip3` package management frontend.
2
2
  # <http://pip.pypa.io/>
3
3
 
4
- require 'puppet/provider/package/pip'
5
-
6
4
  Puppet::Type.type(:package).provide :pip3,
7
5
  :parent => :pip do
8
6
 
@@ -56,7 +56,7 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
56
56
  ).merge(
57
57
  case flags[1..1]
58
58
  when 'f'
59
- {:ensure => 'held'}
59
+ {:mark => :hold}
60
60
  when '-'
61
61
  {}
62
62
  else
@@ -114,6 +114,10 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
114
114
  end).merge({:provider => self.name})
115
115
  end
116
116
 
117
+ def deprecated_hold
118
+ hold
119
+ end
120
+
117
121
  def hold
118
122
  pkg(:freeze, @resource[:name])
119
123
  end
@@ -214,8 +218,6 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
214
218
  def install(nofail = false)
215
219
  name = @resource[:name]
216
220
  should = @resource[:ensure]
217
- # always unhold if explicitly told to install/update
218
- self.unhold
219
221
  is = self.query
220
222
  if is[:ensure].to_sym == :absent
221
223
  command = 'install'
@@ -230,7 +232,12 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
230
232
  unless should.is_a? Symbol
231
233
  name += "@#{should}"
232
234
  end
233
- r = exec_cmd(command(:pkg), command, *args, name)
235
+ self.unhold if self.properties[:mark] == :hold
236
+ begin
237
+ r = exec_cmd(command(:pkg), command, *args, name)
238
+ ensure
239
+ self.hold if @resource[:mark] == :hold
240
+ end
234
241
  return r if nofail
235
242
  raise Puppet::Error, _("Unable to update %{package}") % { package: r[:out] } if r[:exit] != 0
236
243
  end
@@ -244,7 +251,13 @@ Puppet::Type.type(:package).provide :pkg, :parent => Puppet::Provider::Package d
244
251
  cmd << '-r'
245
252
  end
246
253
  cmd << @resource[:name]
247
- pkg cmd
254
+ self.unhold if self.properties[:mark] == :hold
255
+ begin
256
+ pkg cmd
257
+ rescue StandardError, LoadError => e
258
+ self.hold if self.properties[:mark] == :hold
259
+ raise e
260
+ end
248
261
  end
249
262
 
250
263
  # update the package to the latest version available
@@ -102,7 +102,7 @@ Puppet::Type.type(:package).provide :pkgdmg, :parent => Puppet::Provider::Packag
102
102
  if source =~ /\.dmg$/i
103
103
  # If you fix this to use open-uri again, you must update the docs above. -NF
104
104
  File.open(cached_source) do |dmg|
105
- xml_str = hdiutil "mount", "-plist", "-nobrowse", "-readonly", "-noidme", "-mountrandom", "/tmp", dmg.path
105
+ xml_str = hdiutil "mount", "-plist", "-nobrowse", "-readonly", "-mountrandom", "/tmp", dmg.path
106
106
  hdiutil_info = Puppet::Util::Plist.parse_plist(xml_str)
107
107
  raise Puppet::Error.new(_("No disk entities returned by mount at %{path}") % { path: dmg.path }) unless hdiutil_info.has_key?("system-entities")
108
108
  mounts = hdiutil_info["system-entities"].collect { |entity|
@@ -11,6 +11,7 @@ Puppet::Type.type(:package).provide :pkgng, :parent => Puppet::Provider::Package
11
11
 
12
12
  has_feature :versionable
13
13
  has_feature :upgradeable
14
+ has_feature :install_options
14
15
 
15
16
  def self.get_query
16
17
  pkg(['query', '-a', '%n %v %o'])
@@ -31,7 +32,11 @@ Puppet::Type.type(:package).provide :pkgng, :parent => Puppet::Provider::Package
31
32
  def self.get_latest_version(origin)
32
33
  latest_version = cached_version_list.lines.find { |l| l =~ /^#{origin} / }
33
34
  if latest_version
34
- latest_version = latest_version.split(' ').last.split(')').first
35
+ _name, compare, status = latest_version.chomp.split(' ', 3)
36
+ if ['!', '?'].include?(compare)
37
+ return nil
38
+ end
39
+ latest_version = status.split(' ').last.split(')').first
35
40
  return latest_version
36
41
  end
37
42
  nil
@@ -110,13 +115,16 @@ Puppet::Type.type(:package).provide :pkgng, :parent => Puppet::Provider::Package
110
115
  end
111
116
 
112
117
  if not source # install using default repo logic
113
- args = ['install', '-qy', installname]
118
+ args = ['install', '-qy']
114
119
  elsif source.scheme == 'urn' # install from repo named in URN
115
120
  tag = repo_tag_from_urn(source.to_s)
116
- args = ['install', '-qy', '-r', tag, installname]
121
+ args = ['install', '-qy', '-r', tag]
117
122
  else # add package located at URL
118
- args = ['add', '-q', source.to_s]
123
+ args = ['add', '-q']
124
+ installname = source.to_s
119
125
  end
126
+ args += install_options if @resource[:install_options]
127
+ args << installname
120
128
 
121
129
  pkg(args)
122
130
  end
@@ -158,4 +166,8 @@ Puppet::Type.type(:package).provide :pkgng, :parent => Puppet::Provider::Package
158
166
  @property_hash[:origin]
159
167
  end
160
168
 
169
+ def install_options
170
+ join_options(@resource[:install_options])
171
+ end
172
+
161
173
  end
@@ -20,9 +20,9 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
20
20
  end
21
21
  end
22
22
 
23
- confine :operatingsystem => :gentoo
23
+ confine :osfamily => :gentoo
24
24
 
25
- defaultfor :operatingsystem => :gentoo
25
+ defaultfor :osfamily => :gentoo
26
26
 
27
27
  def self.instances
28
28
  result_format = self.eix_result_format
@@ -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
@@ -1,5 +1,3 @@
1
- require 'puppet/provider/package/gem'
2
-
3
1
  Puppet::Type.type(:package).provide :puppet_gem, :parent => :gem do
4
2
  desc "Puppet Ruby Gem support. This provider is useful for managing
5
3
  gems needed by the ruby provided in the puppet-agent package."
@@ -14,4 +12,10 @@ Puppet::Type.type(:package).provide :puppet_gem, :parent => :gem do
14
12
  else
15
13
  commands :gemcmd => "/opt/puppetlabs/puppet/bin/gem"
16
14
  end
15
+
16
+ def uninstall
17
+ super
18
+ Puppet.debug("Invalidating rubygems cache after uninstalling gem '#{resource[:name]}'")
19
+ Puppet::Util::Autoload.gem_source.clear_paths
20
+ end
17
21
  end
@@ -1,13 +1,17 @@
1
1
  require 'puppet/provider/package'
2
+ require 'puppet/util/rpm_compare'
2
3
 
3
4
  # RPM packaging. Should work anywhere that has rpm installed.
4
5
  Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Provider::Package do
6
+ # provides Rpm parsing and comparison
7
+ include Puppet::Util::RpmCompare
8
+
5
9
  desc "RPM packaging support; should work anywhere with a working `rpm`
6
10
  binary.
7
11
 
8
12
  This provider supports the `install_options` and `uninstall_options`
9
13
  attributes, which allow command-line flags to be passed to rpm.
10
- These options should be specified as an array where each element is either a string or a hash."
14
+ These options should be specified as an array where each element is either a string or a hash."
11
15
 
12
16
  has_feature :versionable
13
17
  has_feature :install_options
@@ -23,31 +27,6 @@ These options should be specified as an array where each element is either a str
23
27
  self::NEVRA_FIELDS = [:name, :epoch, :version, :release, :arch]
24
28
  self::MULTIVERSION_SEPARATOR = "; "
25
29
 
26
- ARCH_LIST = [
27
- 'noarch',
28
- 'i386',
29
- 'i686',
30
- 'ppc',
31
- 'ppc64',
32
- 'armv3l',
33
- 'armv4b',
34
- 'armv4l',
35
- 'armv4tl',
36
- 'armv5tel',
37
- 'armv5tejl',
38
- 'armv6l',
39
- 'armv7l',
40
- 'm68kmint',
41
- 's390',
42
- 's390x',
43
- 'ia64',
44
- 'x86_64',
45
- 'sh3',
46
- 'sh4',
47
- ]
48
-
49
- ARCH_REGEX = Regexp.new(ARCH_LIST.join('|\.'))
50
-
51
30
  commands :rpm => "rpm"
52
31
 
53
32
  if command('rpm')
@@ -204,200 +183,14 @@ These options should be specified as an array where each element is either a str
204
183
  join_options(resource[:uninstall_options])
205
184
  end
206
185
 
207
- # This is an attempt at implementing RPM's
208
- # lib/rpmvercmp.c rpmvercmp(a, b) in Ruby.
209
- #
210
- # Some of the things in here look REALLY
211
- # UGLY and/or arbitrary. Our goal is to
212
- # match how RPM compares versions, quirks
213
- # and all.
214
- #
215
- # I've kept a lot of C-like string processing
216
- # in an effort to keep this as identical to RPM
217
- # as possible.
218
- #
219
- # returns 1 if str1 is newer than str2,
220
- # 0 if they are identical
221
- # -1 if str1 is older than str2
222
- def rpmvercmp(str1, str2)
223
- return 0 if str1 == str2
224
-
225
- front_strip_re = /^[^A-Za-z0-9~]+/
226
-
227
- while str1.length > 0 or str2.length > 0
228
- # trim anything that's in front_strip_re and != '~' off the beginning of each string
229
- str1 = str1.gsub(front_strip_re, '')
230
- str2 = str2.gsub(front_strip_re, '')
231
-
232
- # "handle the tilde separator, it sorts before everything else"
233
- if str1 =~ /^~/ && str2 =~ /^~/
234
- # if they both have ~, strip it
235
- str1 = str1[1..-1]
236
- str2 = str2[1..-1]
237
- next
238
- elsif str1 =~ /^~/
239
- return -1
240
- elsif str2 =~ /^~/
241
- return 1
242
- end
243
-
244
- break if str1.length == 0 or str2.length == 0
245
-
246
- # "grab first completely alpha or completely numeric segment"
247
- isnum = false
248
- # if the first char of str1 is a digit, grab the chunk of continuous digits from each string
249
- if str1 =~ /^[0-9]+/
250
- if str1 =~ /^[0-9]+/
251
- segment1 = $~.to_s
252
- str1 = $~.post_match
253
- else
254
- segment1 = ''
255
- end
256
- if str2 =~ /^[0-9]+/
257
- segment2 = $~.to_s
258
- str2 = $~.post_match
259
- else
260
- segment2 = ''
261
- end
262
- isnum = true
263
- # else grab the chunk of continuous alphas from each string (which may be '')
264
- else
265
- if str1 =~ /^[A-Za-z]+/
266
- segment1 = $~.to_s
267
- str1 = $~.post_match
268
- else
269
- segment1 = ''
270
- end
271
- if str2 =~ /^[A-Za-z]+/
272
- segment2 = $~.to_s
273
- str2 = $~.post_match
274
- else
275
- segment2 = ''
276
- end
277
- end
278
-
279
- # if the segments we just grabbed from the strings are different types (i.e. one numeric one alpha),
280
- # where alpha also includes ''; "numeric segments are always newer than alpha segments"
281
- if segment2.length == 0
282
- return 1 if isnum
283
- return -1
284
- end
285
-
286
- if isnum
287
- # "throw away any leading zeros - it's a number, right?"
288
- segment1 = segment1.gsub(/^0+/, '')
289
- segment2 = segment2.gsub(/^0+/, '')
290
- # "whichever number has more digits wins"
291
- return 1 if segment1.length > segment2.length
292
- return -1 if segment1.length < segment2.length
293
- end
294
-
295
- # "strcmp will return which one is greater - even if the two segments are alpha
296
- # or if they are numeric. don't return if they are equal because there might
297
- # be more segments to compare"
298
- rc = segment1 <=> segment2
299
- return rc if rc != 0
300
- end #end while loop
301
-
302
- # if we haven't returned anything yet, "whichever version still has characters left over wins"
303
- if str1.length > str2.length
304
- return 1
305
- elsif str1.length < str2.length
306
- return -1
307
- else
308
- return 0
309
- end
310
- end
311
-
312
186
  def insync?(is)
313
187
  return false if [:purged, :absent].include?(is)
314
188
  return false if is.include?(self.class::MULTIVERSION_SEPARATOR) && !@resource[:install_only]
315
189
 
316
190
  should = resource[:ensure]
317
191
  is.split(self.class::MULTIVERSION_SEPARATOR).any? do |version|
318
- 0 == self.rpm_compareEVR(rpm_parse_evr(should), rpm_parse_evr(version))
319
- end
320
- end
321
-
322
- # parse a rpm "version" specification
323
- # this re-implements rpm's
324
- # rpmUtils.miscutils.stringToVersion() in ruby
325
- def rpm_parse_evr(s)
326
- ei = s.index(':')
327
- if ei
328
- e = s[0,ei]
329
- s = s[ei+1,s.length]
330
- else
331
- e = nil
332
- end
333
- begin
334
- e = String(Integer(e))
335
- rescue
336
- # If there are non-digits in the epoch field, default to nil
337
- e = nil
338
- end
339
- ri = s.index('-')
340
- if ri
341
- v = s[0,ri]
342
- r = s[ri+1,s.length]
343
- arch = r.scan(ARCH_REGEX)[0]
344
- if arch
345
- a = arch.delete('.')
346
- r.gsub!(ARCH_REGEX, '')
347
- end
348
- else
349
- v = s
350
- r = nil
351
- end
352
- return { :epoch => e, :version => v, :release => r, :arch => a }
353
- end
354
-
355
- # how rpm compares two package versions:
356
- # rpmUtils.miscutils.compareEVR(), which massages data types and then calls
357
- # rpm.labelCompare(), found in rpm.git/python/header-py.c, which
358
- # sets epoch to 0 if null, then compares epoch, then ver, then rel
359
- # using compare_values() and returns the first non-0 result, else 0.
360
- # This function combines the logic of compareEVR() and labelCompare().
361
- #
362
- # "version_should" can be v, v-r, or e:v-r.
363
- # "version_is" will always be at least v-r, can be e:v-r
364
- def rpm_compareEVR(should_hash, is_hash)
365
- # pass on to rpm labelCompare
366
-
367
- if !should_hash[:epoch].nil?
368
- rc = compare_values(should_hash[:epoch], is_hash[:epoch])
369
- return rc unless rc == 0
370
- end
371
-
372
- rc = compare_values(should_hash[:version], is_hash[:version])
373
- return rc unless rc == 0
374
-
375
- # here is our special case, PUP-1244.
376
- # if should_hash[:release] is nil (not specified by the user),
377
- # and comparisons up to here are equal, return equal. We need to
378
- # evaluate to whatever level of detail the user specified, so we
379
- # don't end up upgrading or *downgrading* when not intended.
380
- #
381
- # This should NOT be triggered if we're trying to ensure latest.
382
- return 0 if should_hash[:release].nil?
383
-
384
- rc = compare_values(should_hash[:release], is_hash[:release])
385
-
386
- return rc
387
- end
388
-
389
- # this method is a native implementation of the
390
- # compare_values function in rpm's python bindings,
391
- # found in python/header-py.c, as used by rpm.
392
- def compare_values(s1, s2)
393
- if s1.nil? && s2.nil?
394
- return 0
395
- elsif ( not s1.nil? ) && s2.nil?
396
- return 1
397
- elsif s1.nil? && (not s2.nil?)
398
- return -1
192
+ 0 == rpm_compareEVR(should, version)
399
193
  end
400
- return rpmvercmp(s1, s2)
401
194
  end
402
195
 
403
196
  private
@@ -1,4 +1,11 @@
1
+ require 'puppet/util/package/version/range'
2
+ require 'puppet/util/package/version/rpm'
3
+ require 'puppet/util/rpm_compare'
4
+
1
5
  Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
6
+ # provides Rpm parsing and comparison
7
+ include Puppet::Util::RpmCompare
8
+
2
9
  desc "Support via `yum`.
3
10
 
4
11
  Using this provider's `uninstallable` feature will not remove dependent packages. To
@@ -10,6 +17,9 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
10
17
 
11
18
  has_feature :install_options, :versionable, :virtual_packages, :install_only
12
19
 
20
+ RPM_VERSION = Puppet::Util::Package::Version::Rpm
21
+ RPM_VERSION_RANGE = Puppet::Util::Package::Version::Range
22
+
13
23
  commands :cmd => "yum", :rpm => "rpm"
14
24
 
15
25
  if command('rpm')
@@ -25,6 +35,36 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
25
35
  defaultfor :operatingsystem => :amazon
26
36
  defaultfor :osfamily => :redhat, :operatingsystemmajrelease => (4..7).to_a
27
37
 
38
+ def insync?(is)
39
+ return false if [:purged, :absent].include?(is)
40
+ return false if is.include?(self.class::MULTIVERSION_SEPARATOR) && !@resource[:install_only]
41
+
42
+ should = @resource[:ensure]
43
+ if should.is_a?(String)
44
+ begin
45
+ should_version = RPM_VERSION_RANGE.parse(should, RPM_VERSION)
46
+
47
+ if should_version.is_a?(RPM_VERSION_RANGE::Eq)
48
+ return super
49
+ end
50
+ rescue RPM_VERSION_RANGE::ValidationFailure, RPM_VERSION::ValidationFailure
51
+ Puppet.debug("Cannot parse #{should} as a RPM version range")
52
+ return super
53
+ end
54
+
55
+ is.split(self.class::MULTIVERSION_SEPARATOR).any? do |version|
56
+ begin
57
+ is_version = RPM_VERSION.parse(version)
58
+ should_version.include?(is_version)
59
+ rescue RPM_VERSION::ValidationFailure
60
+ Puppet.debug("Cannot parse #{is} as a RPM version")
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ VERSION_REGEX = /^(?:(\d+):)?(\S+)-(\S+)$/
67
+
28
68
  def self.prefetch(packages)
29
69
  raise Puppet::Error, _("The yum provider can only be used as root") if Process.euid != 0
30
70
  super
@@ -86,23 +126,24 @@ defaultfor :osfamily => :redhat, :operatingsystemmajrelease => (4..7).to_a
86
126
  end
87
127
 
88
128
  def self.parse_updates(str)
89
- # Strip off all content before the first blank line
90
- body = str.partition(/^\s*\n/m).last
129
+ # Strip off all content that contains Obsoleting, Security: or Update
130
+ body = str.partition(/^(Obsoleting|Security:|Update)/).first
91
131
 
92
132
  updates = Hash.new { |h, k| h[k] = [] }
93
- body.split.each_slice(3) do |tuple|
94
- break if tuple[0] =~ /^(Obsoleting|Security:|Update)/
95
- break unless tuple[1] =~ /^(?:(\d+):)?(\S+)-(\S+)$/
96
- hash = update_to_hash(*tuple[0..1])
97
- # Create entries for both the package name without a version and a
98
- # version since yum considers those as mostly interchangeable.
99
- short_name = hash[:name]
100
- long_name = "#{hash[:name]}.#{hash[:arch]}"
101
-
102
- updates[short_name] << hash
103
- updates[long_name] << hash
104
- end
105
133
 
134
+ body.split(/^\s*\n/).each do |line|
135
+ line.split.each_slice(3) do |tuple|
136
+ next unless tuple[0].include?('.') && tuple[1] =~ VERSION_REGEX
137
+
138
+ hash = update_to_hash(*tuple[0..1])
139
+ # Create entries for both the package name without a version and a
140
+ # version since yum considers those as mostly interchangeable.
141
+ short_name = hash[:name]
142
+ long_name = "#{hash[:name]}.#{hash[:arch]}"
143
+ updates[short_name] << hash
144
+ updates[long_name] << hash
145
+ end
146
+ end
106
147
  updates
107
148
  end
108
149
 
@@ -117,7 +158,7 @@ defaultfor :osfamily => :redhat, :operatingsystemmajrelease => (4..7).to_a
117
158
  raise _("Failed to parse package name and architecture from '%{pkgname}'") % { pkgname: pkgname }
118
159
  end
119
160
 
120
- match = pkgversion.match(/^(?:(\d+):)?(\S+)-(\S+)$/)
161
+ match = pkgversion.match(VERSION_REGEX)
121
162
  epoch = match[1] || '0'
122
163
  version = match[2]
123
164
  release = match[3]
@@ -151,6 +192,44 @@ defaultfor :osfamily => :redhat, :operatingsystemmajrelease => (4..7).to_a
151
192
  'update'
152
193
  end
153
194
 
195
+ def best_version(should)
196
+ if should.is_a?(String)
197
+ begin
198
+ should_range = RPM_VERSION_RANGE.parse(should, RPM_VERSION)
199
+ if should_range.is_a?(RPM_VERSION_RANGE::Eq)
200
+ return should
201
+ end
202
+ rescue RPM_VERSION_RANGE::ValidationFailure, RPM_VERSION::ValidationFailure
203
+ Puppet.debug("Cannot parse #{should} as a RPM version range")
204
+ return should
205
+ end
206
+ sorted_versions = SortedSet.new
207
+ available_versions(@resource[:name]).each do |version|
208
+ begin
209
+ rpm_version = RPM_VERSION.parse(version)
210
+ sorted_versions << rpm_version if should_range.include?(rpm_version)
211
+ rescue RPM_VERSION::ValidationFailure
212
+ Puppet.debug("Cannot parse #{version} as a RPM version")
213
+ end
214
+ end
215
+
216
+ version = sorted_versions.entries.last
217
+
218
+ if version
219
+ version = version.to_s.sub(/^\d+:/, '')
220
+ return version
221
+ end
222
+
223
+ Puppet.debug("No available version for package #{@resource[:name]} is included in range #{should_range}")
224
+ should
225
+ end
226
+ end
227
+
228
+ def available_versions(package_name)
229
+ output = execute("yum list #{package_name} --showduplicates | sed -e '1,/Available Packages/ d' | awk '{print $2}'")
230
+ output.split("\n")
231
+ end
232
+
154
233
  def install
155
234
  wanted = @resource[:name]
156
235
  error_level = self.class.error_level
@@ -195,10 +274,11 @@ defaultfor :osfamily => :redhat, :operatingsystemmajrelease => (4..7).to_a
195
274
  self.debug "Installing directly from #{wanted}"
196
275
  else
197
276
  # No explicit source was specified, so add the package version
277
+ should = best_version(should)
198
278
  wanted += "-#{should}"
199
- if wanted.scan(ARCH_REGEX)
279
+ if wanted.scan(self.class::ARCH_REGEX)
200
280
  self.debug "Detected Arch argument in package! - Moving arch to end of version string"
201
- wanted.gsub!(/(.+)(#{ARCH_REGEX})(.+)/,'\1\3\2')
281
+ wanted.gsub!(/(.+)(#{self.class::ARCH_REGEX})(.+)/,'\1\3\2')
202
282
  end
203
283
  end
204
284
  current_package = self.query
@@ -206,10 +286,10 @@ defaultfor :osfamily => :redhat, :operatingsystemmajrelease => (4..7).to_a
206
286
  if @resource[:install_only]
207
287
  self.debug "Updating package #{@resource[:name]} from version #{current_package[:ensure]} to #{should} as install_only packages are never downgraded"
208
288
  operation = update_command
209
- elsif rpm_compareEVR(rpm_parse_evr(should), rpm_parse_evr(current_package[:ensure])) < 0
289
+ elsif rpm_compareEVR(should, current_package[:ensure]) < 0
210
290
  self.debug "Downgrading package #{@resource[:name]} from version #{current_package[:ensure]} to #{should}"
211
291
  operation = :downgrade
212
- elsif rpm_compareEVR(rpm_parse_evr(should), rpm_parse_evr(current_package[:ensure])) > 0
292
+ elsif rpm_compareEVR(should, current_package[:ensure]) > 0
213
293
  self.debug "Upgrading package #{@resource[:name]} from version #{current_package[:ensure]} to #{should}"
214
294
  operation = update_command
215
295
  end
@@ -286,12 +366,16 @@ defaultfor :osfamily => :redhat, :operatingsystemmajrelease => (4..7).to_a
286
366
  # @param key [String] The key to look for in all contained hashes
287
367
  # @return [Array<String>] All hash values with the given key.
288
368
  def scan_options(options, key)
289
- return [] if options.nil?
290
- options.inject([]) do |repos, opt|
291
- if opt.is_a? Hash and opt[key]
292
- repos << opt[key]
369
+ return [] unless options.is_a?(Enumerable)
370
+ values = options.map do | repo |
371
+ value = if repo.is_a?(String)
372
+ next unless repo.include?('=')
373
+ Hash[*repo.strip.split('=')] # make it a hash
374
+ else
375
+ repo
293
376
  end
294
- repos
377
+ value[key]
295
378
  end
379
+ values.compact.uniq
296
380
  end
297
381
  end