microwave 11.400.3 → 11.400.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (551) hide show
  1. data/distro/README +2 -0
  2. data/distro/arch/etc/conf.d/chef-client.conf +5 -0
  3. data/distro/arch/etc/conf.d/chef-expander.conf +8 -0
  4. data/distro/arch/etc/conf.d/chef-server-webui.conf +10 -0
  5. data/distro/arch/etc/conf.d/chef-server.conf +10 -0
  6. data/distro/arch/etc/conf.d/chef-solr.conf +8 -0
  7. data/distro/arch/etc/rc.d/chef-client +90 -0
  8. data/distro/arch/etc/rc.d/chef-expander +78 -0
  9. data/distro/arch/etc/rc.d/chef-server +78 -0
  10. data/distro/arch/etc/rc.d/chef-server-webui +78 -0
  11. data/distro/arch/etc/rc.d/chef-solr +78 -0
  12. data/distro/common/html/chef-client.8.html +145 -0
  13. data/distro/common/html/chef-expander.8.html +164 -0
  14. data/distro/common/html/chef-expanderctl.8.html +146 -0
  15. data/distro/common/html/chef-server-webui.8.html +185 -0
  16. data/distro/common/html/chef-server.8.html +182 -0
  17. data/distro/common/html/chef-shell.1.html +286 -0
  18. data/distro/common/html/chef-solo.8.html +191 -0
  19. data/distro/common/html/chef-solr.8.html +165 -0
  20. data/distro/common/html/knife-bootstrap.1.html +241 -0
  21. data/distro/common/html/knife-client.1.html +219 -0
  22. data/distro/common/html/knife-configure.1.html +170 -0
  23. data/distro/common/html/knife-cookbook-site.1.html +241 -0
  24. data/distro/common/html/knife-cookbook.1.html +384 -0
  25. data/distro/common/html/knife-data-bag.1.html +238 -0
  26. data/distro/common/html/knife-environment.1.html +267 -0
  27. data/distro/common/html/knife-exec.1.html +134 -0
  28. data/distro/common/html/knife-index.1.html +125 -0
  29. data/distro/common/html/knife-node.1.html +250 -0
  30. data/distro/common/html/knife-role.1.html +200 -0
  31. data/distro/common/html/knife-search.1.html +288 -0
  32. data/distro/common/html/knife-ssh.1.html +156 -0
  33. data/distro/common/html/knife-status.1.html +128 -0
  34. data/distro/common/html/knife-tag.1.html +137 -0
  35. data/distro/common/html/knife.1.html +315 -0
  36. data/distro/common/man/man1/chef-shell.1 +220 -0
  37. data/distro/common/man/man1/knife-bootstrap.1 +201 -0
  38. data/distro/common/man/man1/knife-client.1 +99 -0
  39. data/distro/common/man/man1/knife-configure.1 +88 -0
  40. data/distro/common/man/man1/knife-cookbook-site.1 +145 -0
  41. data/distro/common/man/man1/knife-cookbook.1 +345 -0
  42. data/distro/common/man/man1/knife-data-bag.1 +136 -0
  43. data/distro/common/man/man1/knife-environment.1 +178 -0
  44. data/distro/common/man/man1/knife-exec.1 +43 -0
  45. data/distro/common/man/man1/knife-index.1 +29 -0
  46. data/distro/common/man/man1/knife-node.1 +134 -0
  47. data/distro/common/man/man1/knife-role.1 +88 -0
  48. data/distro/common/man/man1/knife-search.1 +280 -0
  49. data/distro/common/man/man1/knife-ssh.1 +79 -0
  50. data/distro/common/man/man1/knife-status.1 +29 -0
  51. data/distro/common/man/man1/knife-tag.1 +43 -0
  52. data/distro/common/man/man1/knife.1 +285 -0
  53. data/distro/common/man/man8/chef-client.8 +104 -0
  54. data/distro/common/man/man8/chef-expander.8 +97 -0
  55. data/distro/common/man/man8/chef-expanderctl.8 +62 -0
  56. data/distro/common/man/man8/chef-server-webui.8 +155 -0
  57. data/distro/common/man/man8/chef-server.8 +147 -0
  58. data/distro/common/man/man8/chef-solo.8 +158 -0
  59. data/distro/common/man/man8/chef-solr.8 +122 -0
  60. data/distro/common/markdown/README +3 -0
  61. data/distro/common/markdown/man1/chef-shell.mkd +195 -0
  62. data/distro/common/markdown/man1/knife-bootstrap.mkd +141 -0
  63. data/distro/common/markdown/man1/knife-client.mkd +103 -0
  64. data/distro/common/markdown/man1/knife-configure.mkd +70 -0
  65. data/distro/common/markdown/man1/knife-cookbook-site.mkd +123 -0
  66. data/distro/common/markdown/man1/knife-cookbook.mkd +263 -0
  67. data/distro/common/markdown/man1/knife-data-bag.mkd +121 -0
  68. data/distro/common/markdown/man1/knife-environment.mkd +151 -0
  69. data/distro/common/markdown/man1/knife-exec.mkd +42 -0
  70. data/distro/common/markdown/man1/knife-index.mkd +30 -0
  71. data/distro/common/markdown/man1/knife-node.mkd +130 -0
  72. data/distro/common/markdown/man1/knife-role.mkd +85 -0
  73. data/distro/common/markdown/man1/knife-search.mkd +180 -0
  74. data/distro/common/markdown/man1/knife-ssh.mkd +69 -0
  75. data/distro/common/markdown/man1/knife-status.mkd +36 -0
  76. data/distro/common/markdown/man1/knife-tag.mkd +39 -0
  77. data/distro/common/markdown/man1/knife.mkd +213 -0
  78. data/distro/common/markdown/man8/chef-client.mkd +74 -0
  79. data/distro/common/markdown/man8/chef-expander.mkd +82 -0
  80. data/distro/common/markdown/man8/chef-expanderctl.mkd +58 -0
  81. data/distro/common/markdown/man8/chef-server-webui.mkd +121 -0
  82. data/distro/common/markdown/man8/chef-server.mkd +121 -0
  83. data/distro/common/markdown/man8/chef-solo.mkd +107 -0
  84. data/distro/common/markdown/man8/chef-solr.mkd +89 -0
  85. data/distro/debian/etc/default/chef-client +4 -0
  86. data/distro/debian/etc/default/chef-expander +8 -0
  87. data/distro/debian/etc/default/chef-server +9 -0
  88. data/distro/debian/etc/default/chef-server-webui +9 -0
  89. data/distro/debian/etc/default/chef-solr +8 -0
  90. data/distro/debian/etc/init.d/chef-client +210 -0
  91. data/distro/debian/etc/init.d/chef-expander +176 -0
  92. data/distro/debian/etc/init.d/chef-server +122 -0
  93. data/distro/debian/etc/init.d/chef-server-webui +123 -0
  94. data/distro/debian/etc/init.d/chef-solr +176 -0
  95. data/distro/debian/etc/init/chef-client.conf +17 -0
  96. data/distro/debian/etc/init/chef-expander.conf +17 -0
  97. data/distro/debian/etc/init/chef-server-webui.conf +17 -0
  98. data/distro/debian/etc/init/chef-server.conf +17 -0
  99. data/distro/debian/etc/init/chef-solr.conf +17 -0
  100. data/distro/redhat/etc/init.d/chef-client +121 -0
  101. data/distro/redhat/etc/init.d/chef-expander +104 -0
  102. data/distro/redhat/etc/init.d/chef-server +112 -0
  103. data/distro/redhat/etc/init.d/chef-server-webui +112 -0
  104. data/distro/redhat/etc/init.d/chef-solr +104 -0
  105. data/distro/redhat/etc/logrotate.d/chef-client +8 -0
  106. data/distro/redhat/etc/logrotate.d/chef-expander +8 -0
  107. data/distro/redhat/etc/logrotate.d/chef-server +8 -0
  108. data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
  109. data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
  110. data/distro/redhat/etc/sysconfig/chef-client +15 -0
  111. data/distro/redhat/etc/sysconfig/chef-expander +7 -0
  112. data/distro/redhat/etc/sysconfig/chef-server +14 -0
  113. data/distro/redhat/etc/sysconfig/chef-server-webui +14 -0
  114. data/distro/redhat/etc/sysconfig/chef-solr +8 -0
  115. data/distro/windows/service_manager.rb +164 -0
  116. data/lib/chef/api_client.rb +205 -0
  117. data/lib/chef/api_client/registration.rb +126 -0
  118. data/lib/chef/application.rb +225 -0
  119. data/lib/chef/application/agent.rb +18 -0
  120. data/lib/chef/application/apply.rb +160 -0
  121. data/lib/chef/application/client.rb +340 -0
  122. data/lib/chef/application/knife.rb +183 -0
  123. data/lib/chef/application/solo.rb +263 -0
  124. data/lib/chef/application/windows_service.rb +230 -0
  125. data/lib/chef/applications.rb +5 -0
  126. data/lib/chef/checksum/storage.rb +18 -0
  127. data/lib/chef/checksum/storage/filesystem.rb +56 -0
  128. data/lib/chef/chef_fs.rb +11 -0
  129. data/lib/chef/chef_fs/command_line.rb +232 -0
  130. data/lib/chef/chef_fs/file_pattern.rb +312 -0
  131. data/lib/chef/chef_fs/file_system.rb +358 -0
  132. data/lib/chef/chef_fs/file_system/base_fs_dir.rb +47 -0
  133. data/lib/chef/chef_fs/file_system/base_fs_object.rb +121 -0
  134. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +109 -0
  135. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +31 -0
  136. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +84 -0
  137. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +188 -0
  138. data/lib/chef/chef_fs/file_system/cookbook_file.rb +78 -0
  139. data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +54 -0
  140. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +68 -0
  141. data/lib/chef/chef_fs/file_system/data_bag_dir.rb +78 -0
  142. data/lib/chef/chef_fs/file_system/data_bag_item.rb +59 -0
  143. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +66 -0
  144. data/lib/chef/chef_fs/file_system/file_system_entry.rb +90 -0
  145. data/lib/chef/chef_fs/file_system/file_system_error.rb +31 -0
  146. data/lib/chef/chef_fs/file_system/file_system_root_dir.rb +31 -0
  147. data/lib/chef/chef_fs/file_system/must_delete_recursively_error.rb +31 -0
  148. data/lib/chef/chef_fs/file_system/nodes_dir.rb +47 -0
  149. data/lib/chef/chef_fs/file_system/nonexistent_fs_object.rb +40 -0
  150. data/lib/chef/chef_fs/file_system/not_found_error.rb +31 -0
  151. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +84 -0
  152. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +123 -0
  153. data/lib/chef/chef_fs/knife.rb +77 -0
  154. data/lib/chef/chef_fs/path_utils.rb +64 -0
  155. data/lib/chef/client.rb +556 -0
  156. data/lib/chef/config.rb +354 -0
  157. data/lib/chef/cookbook/chefignore.rb +66 -0
  158. data/lib/chef/cookbook/cookbook_collection.rb +45 -0
  159. data/lib/chef/cookbook/cookbook_version_loader.rb +171 -0
  160. data/lib/chef/cookbook/file_system_file_vendor.rb +56 -0
  161. data/lib/chef/cookbook/file_vendor.rb +48 -0
  162. data/lib/chef/cookbook/metadata.rb +627 -0
  163. data/lib/chef/cookbook/remote_file_vendor.rb +84 -0
  164. data/lib/chef/cookbook/synchronizer.rb +216 -0
  165. data/lib/chef/cookbook/syntax_check.rb +183 -0
  166. data/lib/chef/cookbook_loader.rb +134 -0
  167. data/lib/chef/cookbook_site_streaming_uploader.rb +244 -0
  168. data/lib/chef/cookbook_uploader.rb +164 -0
  169. data/lib/chef/cookbook_version.rb +782 -0
  170. data/lib/chef/daemon.rb +172 -0
  171. data/lib/chef/data_bag.rb +145 -0
  172. data/lib/chef/data_bag_item.rb +214 -0
  173. data/lib/chef/digester.rb +73 -0
  174. data/lib/chef/dsl.rb +6 -0
  175. data/lib/chef/dsl/data_query.rb +71 -0
  176. data/lib/chef/dsl/include_attribute.rb +63 -0
  177. data/lib/chef/dsl/include_recipe.rb +45 -0
  178. data/lib/chef/dsl/platform_introspection.rb +218 -0
  179. data/lib/chef/dsl/recipe.rb +87 -0
  180. data/lib/chef/dsl/registry_helper.rb +59 -0
  181. data/lib/chef/encrypted_data_bag_item.rb +323 -0
  182. data/lib/chef/environment.rb +287 -0
  183. data/lib/chef/event_dispatch/base.rb +311 -0
  184. data/lib/chef/event_dispatch/dispatcher.rb +42 -0
  185. data/lib/chef/exceptions.rb +275 -0
  186. data/lib/chef/file_access_control.rb +75 -0
  187. data/lib/chef/file_access_control/unix.rb +216 -0
  188. data/lib/chef/file_access_control/windows.rb +310 -0
  189. data/lib/chef/file_cache.rb +220 -0
  190. data/lib/chef/formatters/base.rb +250 -0
  191. data/lib/chef/formatters/doc.rb +236 -0
  192. data/lib/chef/formatters/error_descriptor.rb +66 -0
  193. data/lib/chef/formatters/error_inspectors.rb +19 -0
  194. data/lib/chef/formatters/error_inspectors/api_error_formatting.rb +111 -0
  195. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +106 -0
  196. data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +146 -0
  197. data/lib/chef/formatters/error_inspectors/cookbook_sync_error_inspector.rb +80 -0
  198. data/lib/chef/formatters/error_inspectors/node_load_error_inspector.rb +125 -0
  199. data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +137 -0
  200. data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +117 -0
  201. data/lib/chef/formatters/error_inspectors/run_list_expansion_error_inspector.rb +118 -0
  202. data/lib/chef/formatters/error_mapper.rb +85 -0
  203. data/lib/chef/formatters/minimal.rb +235 -0
  204. data/lib/chef/handler.rb +235 -0
  205. data/lib/chef/handler/error_report.rb +33 -0
  206. data/lib/chef/handler/json_file.rb +65 -0
  207. data/lib/chef/json_compat.rb +147 -0
  208. data/lib/chef/knife.rb +589 -0
  209. data/lib/chef/knife/bootstrap.rb +233 -0
  210. data/lib/chef/knife/bootstrap/archlinux-gems.erb +62 -0
  211. data/lib/chef/knife/bootstrap/centos5-gems.erb +62 -0
  212. data/lib/chef/knife/bootstrap/chef-full.erb +60 -0
  213. data/lib/chef/knife/bootstrap/fedora13-gems.erb +44 -0
  214. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +53 -0
  215. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +48 -0
  216. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +46 -0
  217. data/lib/chef/knife/client_bulk_delete.rb +65 -0
  218. data/lib/chef/knife/client_create.rb +80 -0
  219. data/lib/chef/knife/client_delete.rb +46 -0
  220. data/lib/chef/knife/client_edit.rb +45 -0
  221. data/lib/chef/knife/client_list.rb +42 -0
  222. data/lib/chef/knife/client_reregister.rb +59 -0
  223. data/lib/chef/knife/client_show.rb +52 -0
  224. data/lib/chef/knife/configure.rb +170 -0
  225. data/lib/chef/knife/configure_client.rb +50 -0
  226. data/lib/chef/knife/cookbook_bulk_delete.rb +72 -0
  227. data/lib/chef/knife/cookbook_create.rb +447 -0
  228. data/lib/chef/knife/cookbook_delete.rb +151 -0
  229. data/lib/chef/knife/cookbook_download.rb +137 -0
  230. data/lib/chef/knife/cookbook_list.rb +47 -0
  231. data/lib/chef/knife/cookbook_metadata.rb +108 -0
  232. data/lib/chef/knife/cookbook_metadata_from_file.rb +44 -0
  233. data/lib/chef/knife/cookbook_show.rb +102 -0
  234. data/lib/chef/knife/cookbook_site_download.rb +109 -0
  235. data/lib/chef/knife/cookbook_site_install.rb +164 -0
  236. data/lib/chef/knife/cookbook_site_list.rb +62 -0
  237. data/lib/chef/knife/cookbook_site_search.rb +51 -0
  238. data/lib/chef/knife/cookbook_site_share.rb +114 -0
  239. data/lib/chef/knife/cookbook_site_show.rb +60 -0
  240. data/lib/chef/knife/cookbook_site_unshare.rb +56 -0
  241. data/lib/chef/knife/cookbook_site_vendor.rb +46 -0
  242. data/lib/chef/knife/cookbook_test.rb +94 -0
  243. data/lib/chef/knife/cookbook_upload.rb +295 -0
  244. data/lib/chef/knife/core/bootstrap_context.rb +106 -0
  245. data/lib/chef/knife/core/cookbook_scm_repo.rb +160 -0
  246. data/lib/chef/knife/core/generic_presenter.rb +204 -0
  247. data/lib/chef/knife/core/node_editor.rb +130 -0
  248. data/lib/chef/knife/core/node_presenter.rb +137 -0
  249. data/lib/chef/knife/core/object_loader.rb +112 -0
  250. data/lib/chef/knife/core/subcommand_loader.rb +112 -0
  251. data/lib/chef/knife/core/text_formatter.rb +86 -0
  252. data/lib/chef/knife/core/ui.rb +219 -0
  253. data/lib/chef/knife/data_bag_create.rb +93 -0
  254. data/lib/chef/knife/data_bag_delete.rb +51 -0
  255. data/lib/chef/knife/data_bag_edit.rb +94 -0
  256. data/lib/chef/knife/data_bag_from_file.rb +136 -0
  257. data/lib/chef/knife/data_bag_list.rb +46 -0
  258. data/lib/chef/knife/data_bag_show.rb +81 -0
  259. data/lib/chef/knife/delete.rb +39 -0
  260. data/lib/chef/knife/diff.rb +46 -0
  261. data/lib/chef/knife/download.rb +50 -0
  262. data/lib/chef/knife/environment_create.rb +53 -0
  263. data/lib/chef/knife/environment_delete.rb +45 -0
  264. data/lib/chef/knife/environment_edit.rb +45 -0
  265. data/lib/chef/knife/environment_from_file.rb +83 -0
  266. data/lib/chef/knife/environment_list.rb +42 -0
  267. data/lib/chef/knife/environment_show.rb +53 -0
  268. data/lib/chef/knife/exec.rb +86 -0
  269. data/lib/chef/knife/help.rb +103 -0
  270. data/lib/chef/knife/help_topics.rb +4 -0
  271. data/lib/chef/knife/index_rebuild.rb +134 -0
  272. data/lib/chef/knife/list.rb +109 -0
  273. data/lib/chef/knife/node_bulk_delete.rb +80 -0
  274. data/lib/chef/knife/node_create.rb +50 -0
  275. data/lib/chef/knife/node_delete.rb +47 -0
  276. data/lib/chef/knife/node_edit.rb +72 -0
  277. data/lib/chef/knife/node_from_file.rb +50 -0
  278. data/lib/chef/knife/node_list.rb +46 -0
  279. data/lib/chef/knife/node_run_list_add.rb +75 -0
  280. data/lib/chef/knife/node_run_list_remove.rb +48 -0
  281. data/lib/chef/knife/node_show.rb +73 -0
  282. data/lib/chef/knife/raw.rb +108 -0
  283. data/lib/chef/knife/recipe_list.rb +32 -0
  284. data/lib/chef/knife/role_bulk_delete.rb +70 -0
  285. data/lib/chef/knife/role_create.rb +55 -0
  286. data/lib/chef/knife/role_delete.rb +47 -0
  287. data/lib/chef/knife/role_edit.rb +48 -0
  288. data/lib/chef/knife/role_from_file.rb +56 -0
  289. data/lib/chef/knife/role_list.rb +43 -0
  290. data/lib/chef/knife/role_show.rb +54 -0
  291. data/lib/chef/knife/search.rb +159 -0
  292. data/lib/chef/knife/show.rb +32 -0
  293. data/lib/chef/knife/ssh.rb +463 -0
  294. data/lib/chef/knife/status.rb +119 -0
  295. data/lib/chef/knife/tag_create.rb +52 -0
  296. data/lib/chef/knife/tag_delete.rb +60 -0
  297. data/lib/chef/knife/tag_list.rb +47 -0
  298. data/lib/chef/knife/upload.rb +50 -0
  299. data/lib/chef/knife/user_create.rb +93 -0
  300. data/lib/chef/knife/user_delete.rb +46 -0
  301. data/lib/chef/knife/user_edit.rb +53 -0
  302. data/lib/chef/knife/user_list.rb +42 -0
  303. data/lib/chef/knife/user_reregister.rb +59 -0
  304. data/lib/chef/knife/user_show.rb +52 -0
  305. data/lib/chef/log.rb +39 -0
  306. data/lib/chef/mash.rb +225 -0
  307. data/lib/chef/mixin/checksum.rb +32 -0
  308. data/lib/chef/mixin/command.rb +164 -0
  309. data/lib/chef/mixin/command/unix.rb +220 -0
  310. data/lib/chef/mixin/command/windows.rb +76 -0
  311. data/lib/chef/mixin/convert_to_class_name.rb +65 -0
  312. data/lib/chef/mixin/create_path.rb +57 -0
  313. data/lib/chef/mixin/deep_merge.rb +168 -0
  314. data/lib/chef/mixin/deprecation.rb +100 -0
  315. data/lib/chef/mixin/enforce_ownership_and_permissions.rb +39 -0
  316. data/lib/chef/mixin/file_class.rb +46 -0
  317. data/lib/chef/mixin/from_file.rb +50 -0
  318. data/lib/chef/mixin/get_source_from_package.rb +42 -0
  319. data/lib/chef/mixin/language.rb +48 -0
  320. data/lib/chef/mixin/language_include_attribute.rb +35 -0
  321. data/lib/chef/mixin/language_include_recipe.rb +32 -0
  322. data/lib/chef/mixin/params_validate.rb +225 -0
  323. data/lib/chef/mixin/path_sanity.rb +67 -0
  324. data/lib/chef/mixin/recipe_definition_dsl_core.rb +35 -0
  325. data/lib/chef/mixin/securable.rb +205 -0
  326. data/lib/chef/mixin/shell_out.rb +69 -0
  327. data/lib/chef/mixin/template.rb +140 -0
  328. data/lib/chef/mixin/why_run.rb +332 -0
  329. data/lib/chef/mixin/xml_escape.rb +140 -0
  330. data/lib/chef/mixins.rb +14 -0
  331. data/lib/chef/monkey_patches/dir.rb +36 -0
  332. data/lib/chef/monkey_patches/fileutils.rb +65 -0
  333. data/lib/chef/monkey_patches/net_http.rb +22 -0
  334. data/lib/chef/monkey_patches/numeric.rb +15 -0
  335. data/lib/chef/monkey_patches/object.rb +9 -0
  336. data/lib/chef/monkey_patches/regexp.rb +34 -0
  337. data/lib/chef/monkey_patches/string.rb +49 -0
  338. data/lib/chef/monkey_patches/tempfile.rb +64 -0
  339. data/lib/chef/nil_argument.rb +3 -0
  340. data/lib/chef/node.rb +509 -0
  341. data/lib/chef/node/attribute.rb +398 -0
  342. data/lib/chef/node/attribute_collections.rb +206 -0
  343. data/lib/chef/node/immutable_collections.rb +186 -0
  344. data/lib/chef/platform.rb +519 -0
  345. data/lib/chef/provider.rb +176 -0
  346. data/lib/chef/provider/breakpoint.rb +36 -0
  347. data/lib/chef/provider/cookbook_file.rb +113 -0
  348. data/lib/chef/provider/cron.rb +214 -0
  349. data/lib/chef/provider/cron/solaris.rb +56 -0
  350. data/lib/chef/provider/deploy.rb +475 -0
  351. data/lib/chef/provider/deploy/revision.rb +80 -0
  352. data/lib/chef/provider/deploy/timestamped.rb +32 -0
  353. data/lib/chef/provider/directory.rb +131 -0
  354. data/lib/chef/provider/env.rb +152 -0
  355. data/lib/chef/provider/env/windows.rb +75 -0
  356. data/lib/chef/provider/erl_call.rb +106 -0
  357. data/lib/chef/provider/execute.rb +68 -0
  358. data/lib/chef/provider/file.rb +328 -0
  359. data/lib/chef/provider/git.rb +260 -0
  360. data/lib/chef/provider/group.rb +158 -0
  361. data/lib/chef/provider/group/aix.rb +70 -0
  362. data/lib/chef/provider/group/dscl.rb +129 -0
  363. data/lib/chef/provider/group/gpasswd.rb +65 -0
  364. data/lib/chef/provider/group/groupadd.rb +96 -0
  365. data/lib/chef/provider/group/groupmod.rb +120 -0
  366. data/lib/chef/provider/group/pw.rb +93 -0
  367. data/lib/chef/provider/group/suse.rb +60 -0
  368. data/lib/chef/provider/group/usermod.rb +68 -0
  369. data/lib/chef/provider/group/windows.rb +79 -0
  370. data/lib/chef/provider/http_request.rb +119 -0
  371. data/lib/chef/provider/ifconfig.rb +214 -0
  372. data/lib/chef/provider/link.rb +132 -0
  373. data/lib/chef/provider/log.rb +54 -0
  374. data/lib/chef/provider/lwrp_base.rb +150 -0
  375. data/lib/chef/provider/mdadm.rb +92 -0
  376. data/lib/chef/provider/mount.rb +128 -0
  377. data/lib/chef/provider/mount/mount.rb +252 -0
  378. data/lib/chef/provider/mount/windows.rb +81 -0
  379. data/lib/chef/provider/ohai.rb +47 -0
  380. data/lib/chef/provider/package.rb +229 -0
  381. data/lib/chef/provider/package/apt.rb +147 -0
  382. data/lib/chef/provider/package/dpkg.rb +128 -0
  383. data/lib/chef/provider/package/easy_install.rb +136 -0
  384. data/lib/chef/provider/package/freebsd.rb +149 -0
  385. data/lib/chef/provider/package/ips.rb +101 -0
  386. data/lib/chef/provider/package/macports.rb +105 -0
  387. data/lib/chef/provider/package/pacman.rb +111 -0
  388. data/lib/chef/provider/package/portage.rb +138 -0
  389. data/lib/chef/provider/package/rpm.rb +121 -0
  390. data/lib/chef/provider/package/rubygems.rb +548 -0
  391. data/lib/chef/provider/package/smartos.rb +84 -0
  392. data/lib/chef/provider/package/solaris.rb +139 -0
  393. data/lib/chef/provider/package/yum-dump.py +307 -0
  394. data/lib/chef/provider/package/yum.rb +1255 -0
  395. data/lib/chef/provider/package/zypper.rb +144 -0
  396. data/lib/chef/provider/registry_key.rb +156 -0
  397. data/lib/chef/provider/remote_directory.rb +180 -0
  398. data/lib/chef/provider/remote_file.rb +141 -0
  399. data/lib/chef/provider/resource_update.rb +55 -0
  400. data/lib/chef/provider/route.rb +223 -0
  401. data/lib/chef/provider/ruby_block.rb +42 -0
  402. data/lib/chef/provider/script.rb +57 -0
  403. data/lib/chef/provider/service.rb +173 -0
  404. data/lib/chef/provider/service/arch.rb +113 -0
  405. data/lib/chef/provider/service/debian.rb +152 -0
  406. data/lib/chef/provider/service/freebsd.rb +175 -0
  407. data/lib/chef/provider/service/gentoo.rb +67 -0
  408. data/lib/chef/provider/service/init.rb +89 -0
  409. data/lib/chef/provider/service/insserv.rb +52 -0
  410. data/lib/chef/provider/service/invokercd.rb +35 -0
  411. data/lib/chef/provider/service/macosx.rb +144 -0
  412. data/lib/chef/provider/service/redhat.rb +77 -0
  413. data/lib/chef/provider/service/simple.rb +172 -0
  414. data/lib/chef/provider/service/solaris.rb +86 -0
  415. data/lib/chef/provider/service/systemd.rb +115 -0
  416. data/lib/chef/provider/service/upstart.rb +232 -0
  417. data/lib/chef/provider/service/windows.rb +163 -0
  418. data/lib/chef/provider/subversion.rb +214 -0
  419. data/lib/chef/provider/template.rb +120 -0
  420. data/lib/chef/provider/template_finder.rb +61 -0
  421. data/lib/chef/provider/user.rb +206 -0
  422. data/lib/chef/provider/user/dscl.rb +288 -0
  423. data/lib/chef/provider/user/pw.rb +113 -0
  424. data/lib/chef/provider/user/useradd.rb +144 -0
  425. data/lib/chef/provider/user/windows.rb +124 -0
  426. data/lib/chef/providers.rb +103 -0
  427. data/lib/chef/recipe.rb +135 -0
  428. data/lib/chef/reserved_names.rb +9 -0
  429. data/lib/chef/resource.rb +794 -0
  430. data/lib/chef/resource/apt_package.rb +43 -0
  431. data/lib/chef/resource/bash.rb +33 -0
  432. data/lib/chef/resource/breakpoint.rb +35 -0
  433. data/lib/chef/resource/chef_gem.rb +53 -0
  434. data/lib/chef/resource/conditional.rb +101 -0
  435. data/lib/chef/resource/cookbook_file.rb +52 -0
  436. data/lib/chef/resource/cron.rb +202 -0
  437. data/lib/chef/resource/csh.rb +33 -0
  438. data/lib/chef/resource/deploy.rb +403 -0
  439. data/lib/chef/resource/deploy_revision.rb +40 -0
  440. data/lib/chef/resource/directory.rb +65 -0
  441. data/lib/chef/resource/dpkg_package.rb +34 -0
  442. data/lib/chef/resource/easy_install_package.rb +57 -0
  443. data/lib/chef/resource/env.rb +63 -0
  444. data/lib/chef/resource/erl_call.rb +86 -0
  445. data/lib/chef/resource/execute.rb +132 -0
  446. data/lib/chef/resource/file.rb +96 -0
  447. data/lib/chef/resource/freebsd_package.rb +35 -0
  448. data/lib/chef/resource/gem_package.rb +53 -0
  449. data/lib/chef/resource/git.rb +46 -0
  450. data/lib/chef/resource/group.rb +83 -0
  451. data/lib/chef/resource/http_request.rb +65 -0
  452. data/lib/chef/resource/ifconfig.rb +149 -0
  453. data/lib/chef/resource/ips_package.rb +42 -0
  454. data/lib/chef/resource/link.rb +92 -0
  455. data/lib/chef/resource/log.rb +74 -0
  456. data/lib/chef/resource/lwrp_base.rb +127 -0
  457. data/lib/chef/resource/macports_package.rb +29 -0
  458. data/lib/chef/resource/mdadm.rb +105 -0
  459. data/lib/chef/resource/mount.rb +139 -0
  460. data/lib/chef/resource/ohai.rb +54 -0
  461. data/lib/chef/resource/package.rb +84 -0
  462. data/lib/chef/resource/pacman_package.rb +33 -0
  463. data/lib/chef/resource/perl.rb +33 -0
  464. data/lib/chef/resource/portage_package.rb +33 -0
  465. data/lib/chef/resource/python.rb +33 -0
  466. data/lib/chef/resource/registry_key.rb +86 -0
  467. data/lib/chef/resource/remote_directory.rb +126 -0
  468. data/lib/chef/resource/remote_file.rb +81 -0
  469. data/lib/chef/resource/route.rb +140 -0
  470. data/lib/chef/resource/rpm_package.rb +34 -0
  471. data/lib/chef/resource/ruby.rb +33 -0
  472. data/lib/chef/resource/ruby_block.rb +51 -0
  473. data/lib/chef/resource/scm.rb +151 -0
  474. data/lib/chef/resource/script.rb +63 -0
  475. data/lib/chef/resource/service.rb +178 -0
  476. data/lib/chef/resource/smartos_package.rb +36 -0
  477. data/lib/chef/resource/solaris_package.rb +36 -0
  478. data/lib/chef/resource/subversion.rb +37 -0
  479. data/lib/chef/resource/template.rb +76 -0
  480. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  481. data/lib/chef/resource/user.rb +134 -0
  482. data/lib/chef/resource/yum_package.rb +63 -0
  483. data/lib/chef/resource_collection.rb +221 -0
  484. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  485. data/lib/chef/resource_definition.rb +67 -0
  486. data/lib/chef/resource_definition_list.rb +38 -0
  487. data/lib/chef/resource_platform_map.rb +151 -0
  488. data/lib/chef/resource_reporter.rb +281 -0
  489. data/lib/chef/resources.rb +69 -0
  490. data/lib/chef/rest.rb +438 -0
  491. data/lib/chef/rest/auth_credentials.rb +57 -0
  492. data/lib/chef/rest/cookie_jar.rb +31 -0
  493. data/lib/chef/rest/rest_request.rb +229 -0
  494. data/lib/chef/role.rb +253 -0
  495. data/lib/chef/run_context.rb +214 -0
  496. data/lib/chef/run_context/cookbook_compiler.rb +280 -0
  497. data/lib/chef/run_list.rb +163 -0
  498. data/lib/chef/run_list/run_list_expansion.rb +191 -0
  499. data/lib/chef/run_list/run_list_item.rb +99 -0
  500. data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
  501. data/lib/chef/run_lock.rb +90 -0
  502. data/lib/chef/run_status.rb +124 -0
  503. data/lib/chef/runner.rb +118 -0
  504. data/lib/chef/sandbox.rb +20 -0
  505. data/lib/chef/scan_access_control.rb +133 -0
  506. data/lib/chef/search/query.rb +65 -0
  507. data/lib/chef/shef/ext.rb +19 -0
  508. data/lib/chef/shell.rb +329 -0
  509. data/lib/chef/shell/ext.rb +593 -0
  510. data/lib/chef/shell/model_wrapper.rb +120 -0
  511. data/lib/chef/shell/shell_rest.rb +28 -0
  512. data/lib/chef/shell/shell_session.rb +298 -0
  513. data/lib/chef/shell_out.rb +13 -0
  514. data/lib/chef/streaming_cookbook_uploader.rb +201 -0
  515. data/lib/chef/tasks/chef_repo.rake +334 -0
  516. data/lib/chef/user.rb +182 -0
  517. data/lib/chef/util/file_edit.rb +132 -0
  518. data/lib/chef/util/windows.rb +56 -0
  519. data/lib/chef/util/windows/net_group.rb +101 -0
  520. data/lib/chef/util/windows/net_use.rb +121 -0
  521. data/lib/chef/util/windows/net_user.rb +198 -0
  522. data/lib/chef/util/windows/volume.rb +59 -0
  523. data/lib/chef/version.rb +23 -0
  524. data/lib/chef/version_class.rb +70 -0
  525. data/lib/chef/version_constraint.rb +116 -0
  526. data/lib/chef/win32/api.rb +364 -0
  527. data/lib/chef/win32/api/error.rb +921 -0
  528. data/lib/chef/win32/api/file.rb +535 -0
  529. data/lib/chef/win32/api/memory.rb +105 -0
  530. data/lib/chef/win32/api/process.rb +41 -0
  531. data/lib/chef/win32/api/psapi.rb +51 -0
  532. data/lib/chef/win32/api/security.rb +385 -0
  533. data/lib/chef/win32/api/system.rb +192 -0
  534. data/lib/chef/win32/api/unicode.rb +178 -0
  535. data/lib/chef/win32/error.rb +73 -0
  536. data/lib/chef/win32/file.rb +167 -0
  537. data/lib/chef/win32/file/info.rb +100 -0
  538. data/lib/chef/win32/handle.rb +55 -0
  539. data/lib/chef/win32/memory.rb +101 -0
  540. data/lib/chef/win32/process.rb +84 -0
  541. data/lib/chef/win32/registry.rb +382 -0
  542. data/lib/chef/win32/security.rb +508 -0
  543. data/lib/chef/win32/security/ace.rb +125 -0
  544. data/lib/chef/win32/security/acl.rb +101 -0
  545. data/lib/chef/win32/security/securable_object.rb +109 -0
  546. data/lib/chef/win32/security/security_descriptor.rb +93 -0
  547. data/lib/chef/win32/security/sid.rb +199 -0
  548. data/lib/chef/win32/security/token.rb +64 -0
  549. data/lib/chef/win32/unicode.rb +43 -0
  550. data/lib/chef/win32/version.rb +119 -0
  551. metadata +553 -3
@@ -0,0 +1,1255 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/provider/package'
20
+ require 'chef/mixin/command'
21
+ require 'chef/resource/package'
22
+ require 'singleton'
23
+ require 'chef/mixin/get_source_from_package'
24
+
25
+
26
+ class Chef
27
+ class Provider
28
+ class Package
29
+ class Yum < Chef::Provider::Package
30
+
31
+ class RPMUtils
32
+ class << self
33
+
34
+ # RPM::Version version_parse equivalent
35
+ def version_parse(evr)
36
+ return if evr.nil?
37
+
38
+ epoch = nil
39
+ # assume this is a version
40
+ version = evr
41
+ release = nil
42
+
43
+ lead = 0
44
+ tail = evr.size
45
+
46
+ if evr =~ %r{^([\d]+):}
47
+ epoch = $1.to_i
48
+ lead = $1.length + 1
49
+ elsif evr[0].ord == ":".ord
50
+ epoch = 0
51
+ lead = 1
52
+ end
53
+
54
+ if evr =~ %r{:?.*-(.*)$}
55
+ release = $1
56
+ tail = evr.length - release.length - lead - 1
57
+
58
+ if release.empty?
59
+ release = nil
60
+ end
61
+ end
62
+
63
+ version = evr[lead,tail]
64
+ if version.empty?
65
+ version = nil
66
+ end
67
+
68
+ [ epoch, version, release ]
69
+ end
70
+
71
+ # verify
72
+ def isalnum(x)
73
+ isalpha(x) or isdigit(x)
74
+ end
75
+
76
+ def isalpha(x)
77
+ v = x.ord
78
+ (v >= 65 and v <= 90) or (v >= 97 and v <= 122)
79
+ end
80
+
81
+ def isdigit(x)
82
+ v = x.ord
83
+ v >= 48 and v <= 57
84
+ end
85
+
86
+ # based on the reference spec in lib/rpmvercmp.c in rpm 4.9.0
87
+ def rpmvercmp(x, y)
88
+ # easy! :)
89
+ return 0 if x == y
90
+
91
+ if x.nil?
92
+ x = ""
93
+ end
94
+
95
+ if y.nil?
96
+ y = ""
97
+ end
98
+
99
+ # not so easy :(
100
+ #
101
+ # takes 2 strings like
102
+ #
103
+ # x = "1.20.b18.el5"
104
+ # y = "1.20.b17.el5"
105
+ #
106
+ # breaks into purely alpha and numeric segments and compares them using
107
+ # some rules
108
+ #
109
+ # * 10 > 1
110
+ # * 1 > a
111
+ # * z > a
112
+ # * Z > A
113
+ # * z > Z
114
+ # * leading zeros are ignored
115
+ # * separators (periods, commas) are ignored
116
+ # * "1.20.b18.el5.extrastuff" > "1.20.b18.el5"
117
+
118
+ x_pos = 0 # overall string element reference position
119
+ x_pos_max = x.length - 1 # number of elements in string, starting from 0
120
+ x_seg_pos = 0 # segment string element reference position
121
+ x_comp = nil # segment to compare
122
+
123
+ y_pos = 0
124
+ y_seg_pos = 0
125
+ y_pos_max = y.length - 1
126
+ y_comp = nil
127
+
128
+ while (x_pos <= x_pos_max and y_pos <= y_pos_max)
129
+ # first we skip over anything non alphanumeric
130
+ while (x_pos <= x_pos_max) and (isalnum(x[x_pos]) == false)
131
+ x_pos += 1 # +1 over pos_max if end of string
132
+ end
133
+ while (y_pos <= y_pos_max) and (isalnum(y[y_pos]) == false)
134
+ y_pos += 1
135
+ end
136
+
137
+ # if we hit the end of either we are done matching segments
138
+ if (x_pos == x_pos_max + 1) or (y_pos == y_pos_max + 1)
139
+ break
140
+ end
141
+
142
+ # we are now at the start of a alpha or numeric segment
143
+ x_seg_pos = x_pos
144
+ y_seg_pos = y_pos
145
+
146
+ # grab segment so we can compare them
147
+ if isdigit(x[x_seg_pos].ord)
148
+ x_seg_is_num = true
149
+
150
+ # already know it's a digit
151
+ x_seg_pos += 1
152
+
153
+ # gather up our digits
154
+ while (x_seg_pos <= x_pos_max) and isdigit(x[x_seg_pos])
155
+ x_seg_pos += 1
156
+ end
157
+ # copy the segment but not the unmatched character that x_seg_pos will
158
+ # refer to
159
+ x_comp = x[x_pos,x_seg_pos - x_pos]
160
+
161
+ while (y_seg_pos <= y_pos_max) and isdigit(y[y_seg_pos])
162
+ y_seg_pos += 1
163
+ end
164
+ y_comp = y[y_pos,y_seg_pos - y_pos]
165
+ else
166
+ # we are comparing strings
167
+ x_seg_is_num = false
168
+
169
+ while (x_seg_pos <= x_pos_max) and isalpha(x[x_seg_pos])
170
+ x_seg_pos += 1
171
+ end
172
+ x_comp = x[x_pos,x_seg_pos - x_pos]
173
+
174
+ while (y_seg_pos <= y_pos_max) and isalpha(y[y_seg_pos])
175
+ y_seg_pos += 1
176
+ end
177
+ y_comp = y[y_pos,y_seg_pos - y_pos]
178
+ end
179
+
180
+ # if y_seg_pos didn't advance in the above loop it means the segments are
181
+ # different types
182
+ if y_pos == y_seg_pos
183
+ # numbers always win over letters
184
+ return x_seg_is_num ? 1 : -1
185
+ end
186
+
187
+ # move the ball forward before we mess with the segments
188
+ x_pos += x_comp.length # +1 over pos_max if end of string
189
+ y_pos += y_comp.length
190
+
191
+ # we are comparing numbers - simply convert them
192
+ if x_seg_is_num
193
+ x_comp = x_comp.to_i
194
+ y_comp = y_comp.to_i
195
+ end
196
+
197
+ # compares ints or strings
198
+ # don't return if equal - try the next segment
199
+ if x_comp > y_comp
200
+ return 1
201
+ elsif x_comp < y_comp
202
+ return -1
203
+ end
204
+
205
+ # if we've reached here than the segments are the same - try again
206
+ end
207
+
208
+ # we must have reached the end of one or both of the strings and they
209
+ # matched up until this point
210
+
211
+ # segments matched completely but the segment separators were different -
212
+ # rpm reference code treats these as equal.
213
+ if (x_pos == x_pos_max + 1) and (y_pos == y_pos_max + 1)
214
+ return 0
215
+ end
216
+
217
+ # the most unprocessed characters left wins
218
+ if (x_pos_max - x_pos) > (y_pos_max - y_pos)
219
+ return 1
220
+ else
221
+ return -1
222
+ end
223
+ end
224
+
225
+ end # self
226
+ end # RPMUtils
227
+
228
+ class RPMVersion
229
+ include Comparable
230
+
231
+ def initialize(*args)
232
+ if args.size == 1
233
+ @e, @v, @r = RPMUtils.version_parse(args[0])
234
+ elsif args.size == 3
235
+ @e = args[0].to_i
236
+ @v = args[1]
237
+ @r = args[2]
238
+ else
239
+ raise ArgumentError, "Expecting either 'epoch-version-release' or 'epoch, " +
240
+ "version, release'"
241
+ end
242
+ end
243
+ attr_reader :e, :v, :r
244
+ alias :epoch :e
245
+ alias :version :v
246
+ alias :release :r
247
+
248
+ def self.parse(*args)
249
+ self.new(*args)
250
+ end
251
+
252
+ def <=>(y)
253
+ compare_versions(y)
254
+ end
255
+
256
+ def compare(y)
257
+ compare_versions(y, false)
258
+ end
259
+
260
+ def partial_compare(y)
261
+ compare_versions(y, true)
262
+ end
263
+
264
+ # RPM::Version rpm_version_to_s equivalent
265
+ def to_s
266
+ if @r.nil?
267
+ @v
268
+ else
269
+ "#{@v}-#{@r}"
270
+ end
271
+ end
272
+
273
+ def evr
274
+ "#{@e}:#{@v}-#{@r}"
275
+ end
276
+
277
+ private
278
+
279
+ # Rough RPM::Version rpm_version_cmp equivalent - except much slower :)
280
+ #
281
+ # partial lets epoch and version segment equality be good enough to return equal, eg:
282
+ #
283
+ # 2:1.2-1 == 2:1.2
284
+ # 2:1.2-1 == 2:
285
+ #
286
+ def compare_versions(y, partial=false)
287
+ x = self
288
+
289
+ # compare epoch
290
+ if (x.e.nil? == false and x.e > 0) and y.e.nil?
291
+ return 1
292
+ elsif x.e.nil? and (y.e.nil? == false and y.e > 0)
293
+ return -1
294
+ elsif x.e.nil? == false and y.e.nil? == false
295
+ if x.e < y.e
296
+ return -1
297
+ elsif x.e > y.e
298
+ return 1
299
+ end
300
+ end
301
+
302
+ # compare version
303
+ if partial and (x.v.nil? or y.v.nil?)
304
+ return 0
305
+ elsif x.v.nil? == false and y.v.nil?
306
+ return 1
307
+ elsif x.v.nil? and y.v.nil? == false
308
+ return -1
309
+ elsif x.v.nil? == false and y.v.nil? == false
310
+ cmp = RPMUtils.rpmvercmp(x.v, y.v)
311
+ return cmp if cmp != 0
312
+ end
313
+
314
+ # compare release
315
+ if partial and (x.r.nil? or y.r.nil?)
316
+ return 0
317
+ elsif x.r.nil? == false and y.r.nil?
318
+ return 1
319
+ elsif x.r.nil? and y.r.nil? == false
320
+ return -1
321
+ elsif x.r.nil? == false and y.r.nil? == false
322
+ cmp = RPMUtils.rpmvercmp(x.r, y.r)
323
+ return cmp
324
+ end
325
+
326
+ return 0
327
+ end
328
+ end
329
+
330
+ class RPMPackage
331
+ include Comparable
332
+
333
+ def initialize(*args)
334
+ if args.size == 4
335
+ @n = args[0]
336
+ @version = RPMVersion.new(args[1])
337
+ @a = args[2]
338
+ @provides = args[3]
339
+ elsif args.size == 6
340
+ @n = args[0]
341
+ e = args[1].to_i
342
+ v = args[2]
343
+ r = args[3]
344
+ @version = RPMVersion.new(e,v,r)
345
+ @a = args[4]
346
+ @provides = args[5]
347
+ else
348
+ raise ArgumentError, "Expecting either 'name, epoch-version-release, arch, provides' " +
349
+ "or 'name, epoch, version, release, arch, provides'"
350
+ end
351
+
352
+ # We always have one, ourselves!
353
+ if @provides.empty?
354
+ @provides = [ RPMProvide.new(@n, @version.evr, :==) ]
355
+ end
356
+ end
357
+ attr_reader :n, :a, :version, :provides
358
+ alias :name :n
359
+ alias :arch :a
360
+
361
+ def <=>(y)
362
+ compare(y)
363
+ end
364
+
365
+ def compare(y)
366
+ x = self
367
+
368
+ # easy! :)
369
+ return 0 if x.nevra == y.nevra
370
+
371
+ # compare name
372
+ if x.n.nil? == false and y.n.nil?
373
+ return 1
374
+ elsif x.n.nil? and y.n.nil? == false
375
+ return -1
376
+ elsif x.n.nil? == false and y.n.nil? == false
377
+ if x.n < y.n
378
+ return -1
379
+ elsif x.n > y.n
380
+ return 1
381
+ end
382
+ end
383
+
384
+ # compare version
385
+ if x.version > y.version
386
+ return 1
387
+ elsif x.version < y.version
388
+ return -1
389
+ end
390
+
391
+ # compare arch
392
+ if x.a.nil? == false and y.a.nil?
393
+ return 1
394
+ elsif x.a.nil? and y.a.nil? == false
395
+ return -1
396
+ elsif x.a.nil? == false and y.a.nil? == false
397
+ if x.a < y.a
398
+ return -1
399
+ elsif x.a > y.a
400
+ return 1
401
+ end
402
+ end
403
+
404
+ return 0
405
+ end
406
+
407
+ def to_s
408
+ nevra
409
+ end
410
+
411
+ def nevra
412
+ "#{@n}-#{@version.evr}.#{@a}"
413
+ end
414
+ end
415
+
416
+ # Simple implementation from rpm and ruby-rpm reference code
417
+ class RPMDependency
418
+ def initialize(*args)
419
+ if args.size == 3
420
+ @name = args[0]
421
+ @version = RPMVersion.new(args[1])
422
+ # Our requirement to other dependencies
423
+ @flag = args[2] || :==
424
+ elsif args.size == 5
425
+ @name = args[0]
426
+ e = args[1].to_i
427
+ v = args[2]
428
+ r = args[3]
429
+ @version = RPMVersion.new(e,v,r)
430
+ @flag = args[4] || :==
431
+ else
432
+ raise ArgumentError, "Expecting either 'name, epoch-version-release, flag' or " +
433
+ "'name, epoch, version, release, flag'"
434
+ end
435
+ end
436
+ attr_reader :name, :version, :flag
437
+
438
+ # Parses 2 forms:
439
+ #
440
+ # "mtr >= 2:0.71-3.0"
441
+ # "mta"
442
+ def self.parse(string)
443
+ if string =~ %r{^(\S+)\s+(>|>=|=|==|<=|<)\s+(\S+)$}
444
+ name = $1
445
+ if $2 == "="
446
+ flag = :==
447
+ else
448
+ flag = :"#{$2}"
449
+ end
450
+ version = $3
451
+
452
+ return self.new(name, version, flag)
453
+ else
454
+ name = string
455
+ return self.new(name, nil, nil)
456
+ end
457
+ end
458
+
459
+ # Test if another RPMDependency satisfies our requirements
460
+ def satisfy?(y)
461
+ unless y.kind_of?(RPMDependency)
462
+ raise ArgumentError, "Expecting an RPMDependency object"
463
+ end
464
+
465
+ x = self
466
+
467
+ # Easy!
468
+ if x.name != y.name
469
+ return false
470
+ end
471
+
472
+ # Partial compare
473
+ #
474
+ # eg: x.version 2.3 == y.version 2.3-1
475
+ sense = x.version.partial_compare(y.version)
476
+
477
+ # Thanks to rpmdsCompare() rpmds.c
478
+ if sense < 0 and (x.flag == :> || x.flag == :>=) || (y.flag == :<= || y.flag == :<)
479
+ return true
480
+ elsif sense > 0 and (x.flag == :< || x.flag == :<=) || (y.flag == :>= || y.flag == :>)
481
+ return true
482
+ elsif sense == 0 and (
483
+ ((x.flag == :== or x.flag == :<= or x.flag == :>=) and (y.flag == :== or y.flag == :<= or y.flag == :>=)) or
484
+ (x.flag == :< and y.flag == :<) or
485
+ (x.flag == :> and y.flag == :>)
486
+ )
487
+ return true
488
+ end
489
+
490
+ return false
491
+ end
492
+ end
493
+
494
+ class RPMProvide < RPMDependency; end
495
+ class RPMRequire < RPMDependency; end
496
+
497
+ class RPMDbPackage < RPMPackage
498
+ # <rpm parts>, installed, available
499
+ def initialize(*args)
500
+ @repoid = args.pop
501
+ # state
502
+ @available = args.pop
503
+ @installed = args.pop
504
+ super(*args)
505
+ end
506
+ attr_reader :repoid, :available, :installed
507
+ end
508
+
509
+ # Simple storage for RPMPackage objects - keeps them unique and sorted
510
+ class RPMDb
511
+ def initialize
512
+ # package name => [ RPMPackage, RPMPackage ] of different versions
513
+ @rpms = Hash.new
514
+ # package nevra => RPMPackage for lookups
515
+ @index = Hash.new
516
+ # provide name (aka feature) => [RPMPackage, RPMPackage] each providing this feature
517
+ @provides = Hash.new
518
+ # RPMPackages listed as available
519
+ @available = Set.new
520
+ # RPMPackages listed as installed
521
+ @installed = Set.new
522
+ end
523
+
524
+ def [](package_name)
525
+ self.lookup(package_name)
526
+ end
527
+
528
+ # Lookup package_name and return a descending array of package objects
529
+ def lookup(package_name)
530
+ pkgs = @rpms[package_name]
531
+ if pkgs
532
+ return pkgs.sort.reverse
533
+ else
534
+ return nil
535
+ end
536
+ end
537
+
538
+ def lookup_provides(provide_name)
539
+ @provides[provide_name]
540
+ end
541
+
542
+ # Using the package name as a key, and nevra for an index, keep a unique list of packages.
543
+ # The available/installed state can be overwritten for existing packages.
544
+ def push(*args)
545
+ args.flatten.each do |new_rpm|
546
+ unless new_rpm.kind_of?(RPMDbPackage)
547
+ raise ArgumentError, "Expecting an RPMDbPackage object"
548
+ end
549
+
550
+ @rpms[new_rpm.n] ||= Array.new
551
+
552
+ # we may already have this one, like when the installed list is refreshed
553
+ idx = @index[new_rpm.nevra]
554
+ if idx
555
+ # grab the existing package if it's not
556
+ curr_rpm = idx
557
+ else
558
+ @rpms[new_rpm.n] << new_rpm
559
+
560
+ new_rpm.provides.each do |provide|
561
+ @provides[provide.name] ||= Array.new
562
+ @provides[provide.name] << new_rpm
563
+ end
564
+
565
+ curr_rpm = new_rpm
566
+ end
567
+
568
+ # Track the nevra -> RPMPackage association to avoid having to compare versions
569
+ # with @rpms[new_rpm.n] on the next round
570
+ @index[new_rpm.nevra] = curr_rpm
571
+
572
+ # these are overwritten for existing packages
573
+ if new_rpm.available
574
+ @available << curr_rpm
575
+ end
576
+ if new_rpm.installed
577
+ @installed << curr_rpm
578
+ end
579
+ end
580
+ end
581
+
582
+ def <<(*args)
583
+ self.push(args)
584
+ end
585
+
586
+ def clear
587
+ @rpms.clear
588
+ @index.clear
589
+ @provides.clear
590
+ clear_available
591
+ clear_installed
592
+ end
593
+
594
+ def clear_available
595
+ @available.clear
596
+ end
597
+
598
+ def clear_installed
599
+ @installed.clear
600
+ end
601
+
602
+ def size
603
+ @rpms.size
604
+ end
605
+ alias :length :size
606
+
607
+ def available_size
608
+ @available.size
609
+ end
610
+
611
+ def installed_size
612
+ @installed.size
613
+ end
614
+
615
+ def available?(package)
616
+ @available.include?(package)
617
+ end
618
+
619
+ def installed?(package)
620
+ @installed.include?(package)
621
+ end
622
+
623
+ def whatprovides(rpmdep)
624
+ unless rpmdep.kind_of?(RPMDependency)
625
+ raise ArgumentError, "Expecting an RPMDependency object"
626
+ end
627
+
628
+ what = []
629
+
630
+ packages = lookup_provides(rpmdep.name)
631
+ if packages
632
+ packages.each do |pkg|
633
+ pkg.provides.each do |provide|
634
+ if provide.satisfy?(rpmdep)
635
+ what << pkg
636
+ end
637
+ end
638
+ end
639
+ end
640
+
641
+ return what
642
+ end
643
+ end
644
+
645
+ # Cache for our installed and available packages, pulled in from yum-dump.py
646
+ class YumCache
647
+ include Chef::Mixin::Command
648
+ include Singleton
649
+
650
+ def initialize
651
+ @rpmdb = RPMDb.new
652
+
653
+ # Next time @rpmdb is accessed:
654
+ # :all - Trigger a run of "yum-dump.py --options --installed-provides", updates
655
+ # yum's cache and parses options from /etc/yum.conf. Pulls in Provides
656
+ # dependency data for installed packages only - this data is slow to
657
+ # gather.
658
+ # :provides - Same as :all but pulls in Provides data for available packages as well.
659
+ # Used as a last resort when we can't find a Provides match.
660
+ # :installed - Trigger a run of "yum-dump.py --installed", only reads the local rpm
661
+ # db. Used between client runs for a quick refresh.
662
+ # :none - Do nothing, a call to one of the reload methods is required.
663
+ @next_refresh = :all
664
+
665
+ @allow_multi_install = []
666
+
667
+ @extra_repo_control = nil
668
+
669
+ # these are for subsequent runs if we are on an interval
670
+ Chef::Client.when_run_starts do
671
+ YumCache.instance.reload
672
+ end
673
+ end
674
+
675
+ attr_reader :extra_repo_control
676
+
677
+ # Cache management
678
+ #
679
+
680
+ def refresh
681
+ case @next_refresh
682
+ when :none
683
+ return nil
684
+ when :installed
685
+ reset_installed
686
+ # fast
687
+ opts=" --installed"
688
+ when :all
689
+ reset
690
+ # medium
691
+ opts=" --options --installed-provides"
692
+ when :provides
693
+ reset
694
+ # slow!
695
+ opts=" --options --all-provides"
696
+ else
697
+ raise ArgumentError, "Unexpected value in next_refresh: #{@next_refresh}"
698
+ end
699
+
700
+ if @extra_repo_control
701
+ opts << " #{@extra_repo_control}"
702
+ end
703
+
704
+ one_line = false
705
+ error = nil
706
+
707
+ helper = ::File.join(::File.dirname(__FILE__), 'yum-dump.py')
708
+
709
+ status = popen4("/usr/bin/python #{helper}#{opts}", :waitlast => true) do |pid, stdin, stdout, stderr|
710
+ stdout.each do |line|
711
+ one_line = true
712
+
713
+ line.chomp!
714
+
715
+ if line =~ %r{\[option (.*)\] (.*)}
716
+ if $1 == "installonlypkgs"
717
+ @allow_multi_install = $2.split
718
+ else
719
+ raise Chef::Exceptions::Package, "Strange, unknown option line '#{line}' from yum-dump.py"
720
+ end
721
+ next
722
+ end
723
+
724
+ if line =~ %r{^(\S+) ([0-9]+) (\S+) (\S+) (\S+) \[(.*)\] ([i,a,r]) (\S+)$}
725
+ name = $1
726
+ epoch = $2
727
+ version = $3
728
+ release = $4
729
+ arch = $5
730
+ provides = parse_provides($6)
731
+ type = $7
732
+ repoid = $8
733
+ else
734
+ Chef::Log.warn("Problem parsing line '#{line}' from yum-dump.py! " +
735
+ "Please check your yum configuration.")
736
+ next
737
+ end
738
+
739
+ case type
740
+ when "i"
741
+ # if yum-dump was called with --installed this may not be true, but it's okay
742
+ # since we don't touch the @available Set in reload_installed
743
+ available = false
744
+ installed = true
745
+ when "a"
746
+ available = true
747
+ installed = false
748
+ when "r"
749
+ available = true
750
+ installed = true
751
+ end
752
+
753
+ pkg = RPMDbPackage.new(name, epoch, version, release, arch, provides, installed, available, repoid)
754
+ @rpmdb << pkg
755
+ end
756
+
757
+ error = stderr.readlines
758
+ end
759
+
760
+ if status.exitstatus != 0
761
+ raise Chef::Exceptions::Package, "Yum failed - #{status.inspect} - returns: #{error}"
762
+ else
763
+ unless one_line
764
+ Chef::Log.warn("Odd, no output from yum-dump.py. Please check " +
765
+ "your yum configuration.")
766
+ end
767
+ end
768
+
769
+ # A reload method must be called before the cache is altered
770
+ @next_refresh = :none
771
+ end
772
+
773
+ def reload
774
+ @next_refresh = :all
775
+ end
776
+
777
+ def reload_installed
778
+ @next_refresh = :installed
779
+ end
780
+
781
+ def reload_provides
782
+ @next_refresh = :provides
783
+ end
784
+
785
+ def reset
786
+ @rpmdb.clear
787
+ end
788
+
789
+ def reset_installed
790
+ @rpmdb.clear_installed
791
+ end
792
+
793
+ # Querying the cache
794
+ #
795
+
796
+ # Check for package by name or name+arch
797
+ def package_available?(package_name)
798
+ refresh
799
+
800
+ if @rpmdb.lookup(package_name)
801
+ return true
802
+ else
803
+ if package_name =~ %r{^(.*)\.(.*)$}
804
+ pkg_name = $1
805
+ pkg_arch = $2
806
+
807
+ if matches = @rpmdb.lookup(pkg_name)
808
+ matches.each do |m|
809
+ return true if m.arch == pkg_arch
810
+ end
811
+ end
812
+ end
813
+ end
814
+
815
+ return false
816
+ end
817
+
818
+ # Returns a array of packages satisfying an RPMDependency
819
+ def packages_from_require(rpmdep)
820
+ refresh
821
+ @rpmdb.whatprovides(rpmdep)
822
+ end
823
+
824
+ # Check if a package-version.arch is available to install
825
+ def version_available?(package_name, desired_version, arch=nil)
826
+ version(package_name, arch, true, false) do |v|
827
+ return true if desired_version == v
828
+ end
829
+
830
+ return false
831
+ end
832
+
833
+ # Return the source repository for a package-version.arch
834
+ def package_repository(package_name, desired_version, arch=nil)
835
+ package(package_name, arch, true, false) do |pkg|
836
+ return pkg.repoid if desired_version == pkg.version.to_s
837
+ end
838
+
839
+ return nil
840
+ end
841
+
842
+ # Return the latest available version for a package.arch
843
+ def available_version(package_name, arch=nil)
844
+ version(package_name, arch, true, false)
845
+ end
846
+ alias :candidate_version :available_version
847
+
848
+ # Return the currently installed version for a package.arch
849
+ def installed_version(package_name, arch=nil)
850
+ version(package_name, arch, false, true)
851
+ end
852
+
853
+ # Return an array of packages allowed to be installed multiple times, such as the kernel
854
+ def allow_multi_install
855
+ refresh
856
+ @allow_multi_install
857
+ end
858
+
859
+ def enable_extra_repo_control(arg)
860
+ # Don't touch cache if it's the same repos as the last load
861
+ unless @extra_repo_control == arg
862
+ @extra_repo_control = arg
863
+ reload
864
+ end
865
+ end
866
+
867
+ def disable_extra_repo_control
868
+ # Only force reload when set
869
+ if @extra_repo_control
870
+ @extra_repo_control = nil
871
+ reload
872
+ end
873
+ end
874
+
875
+ private
876
+
877
+ def version(package_name, arch=nil, is_available=false, is_installed=false)
878
+ package(package_name, arch, is_available, is_installed) do |pkg|
879
+ if block_given?
880
+ yield pkg.version.to_s
881
+ else
882
+ # first match is latest version
883
+ return pkg.version.to_s
884
+ end
885
+ end
886
+
887
+ if block_given?
888
+ return self
889
+ else
890
+ return nil
891
+ end
892
+ end
893
+
894
+ def package(package_name, arch=nil, is_available=false, is_installed=false)
895
+ refresh
896
+ packages = @rpmdb[package_name]
897
+ if packages
898
+ packages.each do |pkg|
899
+ if is_available
900
+ next unless @rpmdb.available?(pkg)
901
+ end
902
+ if is_installed
903
+ next unless @rpmdb.installed?(pkg)
904
+ end
905
+ if arch
906
+ next unless pkg.arch == arch
907
+ end
908
+
909
+ if block_given?
910
+ yield pkg
911
+ else
912
+ # first match is latest version
913
+ return pkg
914
+ end
915
+ end
916
+ end
917
+
918
+ if block_given?
919
+ return self
920
+ else
921
+ return nil
922
+ end
923
+ end
924
+
925
+ # Parse provides from yum-dump.py output
926
+ def parse_provides(string)
927
+ ret = []
928
+ # ['atk = 1.12.2-1.fc6', 'libatk-1.0.so.0']
929
+ string.split(", ").each do |seg|
930
+ # 'atk = 1.12.2-1.fc6'
931
+ if seg =~ %r{^'(.*)'$}
932
+ ret << RPMProvide.parse($1)
933
+ end
934
+ end
935
+
936
+ return ret
937
+ end
938
+
939
+ end # YumCache
940
+
941
+ include Chef::Mixin::GetSourceFromPackage
942
+
943
+ def initialize(new_resource, run_context)
944
+ super
945
+
946
+ @yum = YumCache.instance
947
+ end
948
+
949
+ # Extra attributes
950
+ #
951
+
952
+ def arch
953
+ if @new_resource.respond_to?("arch")
954
+ @new_resource.arch
955
+ else
956
+ nil
957
+ end
958
+ end
959
+
960
+ def flush_cache
961
+ if @new_resource.respond_to?("flush_cache")
962
+ @new_resource.flush_cache
963
+ else
964
+ { :before => false, :after => false }
965
+ end
966
+ end
967
+
968
+ def allow_downgrade
969
+ if @new_resource.respond_to?("allow_downgrade")
970
+ @new_resource.allow_downgrade
971
+ else
972
+ false
973
+ end
974
+ end
975
+
976
+ # Helpers
977
+ #
978
+
979
+ def yum_arch
980
+ arch ? ".#{arch}" : nil
981
+ end
982
+
983
+ def yum_command(command)
984
+ status, stdout, stderr = output_of_command(command, {})
985
+
986
+ # This is fun: rpm can encounter errors in the %post/%postun scripts which aren't
987
+ # considered fatal - meaning the rpm is still successfully installed. These issue
988
+ # cause yum to emit a non fatal warning but still exit(1). As there's currently no
989
+ # way to suppress this behavior and an exit(1) will break a Chef run we make an
990
+ # effort to trap these and re-run the same install command - it will either fail a
991
+ # second time or succeed.
992
+ #
993
+ # A cleaner solution would have to be done in python and better hook into
994
+ # yum/rpm to handle exceptions as we see fit.
995
+ if status.exitstatus == 1
996
+ stdout.each_line do |l|
997
+ # rpm-4.4.2.3 lib/psm.c line 2182
998
+ if l =~ %r{^error: %(post|postun)\(.*\) scriptlet failed, exit status \d+$}
999
+ Chef::Log.warn("#{@new_resource} caught non-fatal scriptlet issue: \"#{l}\". Can't trust yum exit status " +
1000
+ "so running install again to verify.")
1001
+ status, stdout, stderr = output_of_command(command, {})
1002
+ break
1003
+ end
1004
+ end
1005
+ end
1006
+
1007
+ if status.exitstatus > 0
1008
+ command_output = "STDOUT: #{stdout}"
1009
+ command_output << "STDERR: #{stderr}"
1010
+ handle_command_failures(status, command_output, {})
1011
+ end
1012
+ end
1013
+
1014
+ # Standard Provider methods for Parent
1015
+ #
1016
+
1017
+ def load_current_resource
1018
+ if flush_cache[:before]
1019
+ @yum.reload
1020
+ end
1021
+
1022
+ if @new_resource.options
1023
+ repo_control = []
1024
+ @new_resource.options.split.each do |opt|
1025
+ if opt =~ %r{--(enable|disable)repo=.+}
1026
+ repo_control << opt
1027
+ end
1028
+ end
1029
+
1030
+ if repo_control.size > 0
1031
+ @yum.enable_extra_repo_control(repo_control.join(" "))
1032
+ else
1033
+ @yum.disable_extra_repo_control
1034
+ end
1035
+ else
1036
+ @yum.disable_extra_repo_control
1037
+ end
1038
+
1039
+ # At this point package_name could be:
1040
+ #
1041
+ # 1) a package name, eg: "foo"
1042
+ # 2) a package name.arch, eg: "foo.i386"
1043
+ # 3) or a dependency, eg: "foo >= 1.1"
1044
+
1045
+ # Check if we have name or name+arch which has a priority over a dependency
1046
+ unless @yum.package_available?(@new_resource.package_name)
1047
+ # If they aren't in the installed packages they could be a dependency
1048
+ parse_dependency
1049
+ end
1050
+
1051
+ # Don't overwrite an existing arch
1052
+ unless arch
1053
+ parse_arch
1054
+ end
1055
+
1056
+ @current_resource = Chef::Resource::Package.new(@new_resource.name)
1057
+ @current_resource.package_name(@new_resource.package_name)
1058
+
1059
+ if @new_resource.source
1060
+ unless ::File.exists?(@new_resource.source)
1061
+ raise Chef::Exceptions::Package, "Package #{@new_resource.name} not found: #{@new_resource.source}"
1062
+ end
1063
+
1064
+ Chef::Log.debug("#{@new_resource} checking rpm status")
1065
+ status = popen4("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{@new_resource.source}") do |pid, stdin, stdout, stderr|
1066
+ stdout.each do |line|
1067
+ case line
1068
+ when /([\w\d_.-]+)\s([\w\d_.-]+)/
1069
+ @current_resource.package_name($1)
1070
+ @new_resource.version($2)
1071
+ end
1072
+ end
1073
+ end
1074
+ end
1075
+
1076
+ if @new_resource.version
1077
+ new_resource = "#{@new_resource.package_name}-#{@new_resource.version}#{yum_arch}"
1078
+ else
1079
+ new_resource = "#{@new_resource.package_name}#{yum_arch}"
1080
+ end
1081
+
1082
+ Chef::Log.debug("#{@new_resource} checking yum info for #{new_resource}")
1083
+
1084
+ installed_version = @yum.installed_version(@new_resource.package_name, arch)
1085
+ @current_resource.version(installed_version)
1086
+
1087
+ @candidate_version = @yum.candidate_version(@new_resource.package_name, arch)
1088
+
1089
+ Chef::Log.debug("#{@new_resource} installed version: #{installed_version || "(none)"} candidate version: " +
1090
+ "#{@candidate_version || "(none)"}")
1091
+
1092
+ @current_resource
1093
+ end
1094
+
1095
+ def install_package(name, version)
1096
+ if @new_resource.source
1097
+ yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} localinstall #{@new_resource.source}")
1098
+ else
1099
+ # Work around yum not exiting with an error if a package doesn't exist for CHEF-2062
1100
+ if @yum.version_available?(name, version, arch)
1101
+ method = "install"
1102
+ log_method = "installing"
1103
+
1104
+ # More Yum fun:
1105
+ #
1106
+ # yum install of an old name+version will exit(1)
1107
+ # yum install of an old name+version+arch will exit(0) for some reason
1108
+ #
1109
+ # Some packages can be installed multiple times like the kernel
1110
+ unless @yum.allow_multi_install.include?(name)
1111
+ if RPMVersion.parse(@current_resource.version) > RPMVersion.parse(version)
1112
+ # Unless they want this...
1113
+ if allow_downgrade
1114
+ method = "downgrade"
1115
+ log_method = "downgrading"
1116
+ else
1117
+ # we bail like yum when the package is older
1118
+ raise Chef::Exceptions::Package, "Installed package #{name}-#{@current_resource.version} is newer " +
1119
+ "than candidate package #{name}-#{version}"
1120
+ end
1121
+ end
1122
+ end
1123
+
1124
+ repo = @yum.package_repository(name, version, arch)
1125
+ Chef::Log.info("#{@new_resource} #{log_method} #{name}-#{version}#{yum_arch} from #{repo} repository")
1126
+
1127
+ yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} #{method} #{name}-#{version}#{yum_arch}")
1128
+ else
1129
+ raise Chef::Exceptions::Package, "Version #{version} of #{name} not found. Did you specify both version " +
1130
+ "and release? (version-release, e.g. 1.84-10.fc6)"
1131
+ end
1132
+ end
1133
+
1134
+ if flush_cache[:after]
1135
+ @yum.reload
1136
+ else
1137
+ @yum.reload_installed
1138
+ end
1139
+ end
1140
+
1141
+ # Keep upgrades from trying to install an older candidate version. Can happen when a new
1142
+ # version is installed then removed from a repository, now the older available version
1143
+ # shows up as a viable install candidate.
1144
+ #
1145
+ # Can be done in upgrade_package but an upgraded from->to log message slips out
1146
+ #
1147
+ # Hacky - better overall solution? Custom compare in Package provider?
1148
+ def action_upgrade
1149
+ # Could be uninstalled or have no candidate
1150
+ if @current_resource.version.nil? || candidate_version.nil?
1151
+ super
1152
+ # Ensure the candidate is newer
1153
+ elsif RPMVersion.parse(candidate_version) > RPMVersion.parse(@current_resource.version)
1154
+ super
1155
+ else
1156
+ Chef::Log.debug("#{@new_resource} is at the latest version - nothing to do")
1157
+ end
1158
+ end
1159
+
1160
+ def upgrade_package(name, version)
1161
+ install_package(name, version)
1162
+ end
1163
+
1164
+ def remove_package(name, version)
1165
+ if version
1166
+ yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} remove #{name}-#{version}#{yum_arch}")
1167
+ else
1168
+ yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} remove #{name}#{yum_arch}")
1169
+ end
1170
+
1171
+ if flush_cache[:after]
1172
+ @yum.reload
1173
+ else
1174
+ @yum.reload_installed
1175
+ end
1176
+ end
1177
+
1178
+ def purge_package(name, version)
1179
+ remove_package(name, version)
1180
+ end
1181
+
1182
+ private
1183
+
1184
+ def parse_arch
1185
+ # Allow for foo.x86_64 style package_name like yum uses in it's output
1186
+ #
1187
+ if @new_resource.package_name =~ %r{^(.*)\.(.*)$}
1188
+ new_package_name = $1
1189
+ new_arch = $2
1190
+ # foo.i386 and foo.beta1 are both valid package names or expressions of an arch.
1191
+ # Ensure we don't have an existing package matching package_name, then ensure we at
1192
+ # least have a match for the new_package+new_arch before we overwrite. If neither
1193
+ # then fall through to standard package handling.
1194
+ if (@yum.installed_version(@new_resource.package_name).nil? and @yum.candidate_version(@new_resource.package_name).nil?) and
1195
+ (@yum.installed_version(new_package_name, new_arch) or @yum.candidate_version(new_package_name, new_arch))
1196
+ @new_resource.package_name(new_package_name)
1197
+ @new_resource.arch(new_arch)
1198
+ end
1199
+ end
1200
+ end
1201
+
1202
+ # If we don't have the package we could have been passed a 'whatprovides' feature
1203
+ #
1204
+ # eg: yum install "perl(Config)"
1205
+ # yum install "mtr = 2:0.71-3.1"
1206
+ # yum install "mtr > 2:0.71"
1207
+ #
1208
+ # We support resolving these out of the Provides data imported from yum-dump.py and
1209
+ # matching them up with an actual package so the standard resource handling can apply.
1210
+ #
1211
+ # There is currently no support for filename matching.
1212
+ def parse_dependency
1213
+ # Transform the package_name into a requirement
1214
+ yum_require = RPMRequire.parse(@new_resource.package_name)
1215
+ # and gather all the packages that have a Provides feature satisfying the requirement.
1216
+ # It could be multiple be we can only manage one
1217
+ packages = @yum.packages_from_require(yum_require)
1218
+
1219
+ if packages.empty?
1220
+ # Don't bother if we are just ensuring a package is removed - we don't need Provides data
1221
+ actions = Array(@new_resource.action)
1222
+ unless actions.size == 1 and (actions[0] == :remove || actions[0] == :purge)
1223
+ Chef::Log.debug("#{@new_resource} couldn't match #{@new_resource.package_name} in " +
1224
+ "installed Provides, loading available Provides - this may take a moment")
1225
+ @yum.reload_provides
1226
+ packages = @yum.packages_from_require(yum_require)
1227
+ end
1228
+ end
1229
+
1230
+ unless packages.empty?
1231
+ new_package_name = packages.first.name
1232
+ Chef::Log.debug("#{@new_resource} no package found for #{@new_resource.package_name} " +
1233
+ "but matched Provides for #{new_package_name}")
1234
+
1235
+ # Ensure it's not the same package under a different architecture
1236
+ unique_names = []
1237
+ packages.each do |pkg|
1238
+ unique_names << "#{pkg.name}-#{pkg.version.evr}"
1239
+ end
1240
+ unique_names.uniq!
1241
+
1242
+ if unique_names.size > 1
1243
+ Chef::Log.warn("#{@new_resource} matched multiple Provides for #{@new_resource.package_name} " +
1244
+ "but we can only use the first match: #{new_package_name}. Please use a more " +
1245
+ "specific version.")
1246
+ end
1247
+
1248
+ @new_resource.package_name(new_package_name)
1249
+ end
1250
+ end
1251
+
1252
+ end
1253
+ end
1254
+ end
1255
+ end