TrueCar-chef 0.10.0.beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +171 -0
  3. data/bin/chef-client +26 -0
  4. data/bin/chef-solo +25 -0
  5. data/bin/knife +26 -0
  6. data/bin/shef +34 -0
  7. data/distro/README +2 -0
  8. data/distro/arch/etc/conf.d/chef-client.conf +5 -0
  9. data/distro/arch/etc/conf.d/chef-server-webui.conf +10 -0
  10. data/distro/arch/etc/conf.d/chef-server.conf +10 -0
  11. data/distro/arch/etc/conf.d/chef-solr-indexer.conf +8 -0
  12. data/distro/arch/etc/conf.d/chef-solr.conf +8 -0
  13. data/distro/arch/etc/rc.d/chef-client +76 -0
  14. data/distro/arch/etc/rc.d/chef-server +78 -0
  15. data/distro/arch/etc/rc.d/chef-server-webui +78 -0
  16. data/distro/arch/etc/rc.d/chef-solr +78 -0
  17. data/distro/arch/etc/rc.d/chef-solr-indexer +78 -0
  18. data/distro/common/man/man1/chef-indexer.1 +42 -0
  19. data/distro/common/man/man1/chef-server-webui.1 +106 -0
  20. data/distro/common/man/man1/chef-server.1 +107 -0
  21. data/distro/common/man/man1/chef-solr-indexer.1 +55 -0
  22. data/distro/common/man/man1/chef-solr.1 +55 -0
  23. data/distro/common/man/man8/chef-client.8 +63 -0
  24. data/distro/common/man/man8/chef-solo.8 +57 -0
  25. data/distro/common/man/man8/chef-solr-rebuild.8 +37 -0
  26. data/distro/common/man/man8/knife.8 +1349 -0
  27. data/distro/common/man/man8/shef.8 +45 -0
  28. data/distro/common/markdown/README +3 -0
  29. data/distro/common/markdown/knife.mkd +865 -0
  30. data/distro/debian/etc/default/chef-client +4 -0
  31. data/distro/debian/etc/default/chef-server +9 -0
  32. data/distro/debian/etc/default/chef-server-webui +9 -0
  33. data/distro/debian/etc/default/chef-solr +8 -0
  34. data/distro/debian/etc/default/chef-solr-indexer +7 -0
  35. data/distro/debian/etc/init.d/chef-client +175 -0
  36. data/distro/debian/etc/init.d/chef-server +122 -0
  37. data/distro/debian/etc/init.d/chef-server-webui +123 -0
  38. data/distro/debian/etc/init.d/chef-solr +176 -0
  39. data/distro/debian/etc/init.d/chef-solr-indexer +176 -0
  40. data/distro/debian/etc/init/chef-client.conf +17 -0
  41. data/distro/debian/etc/init/chef-server-webui.conf +17 -0
  42. data/distro/debian/etc/init/chef-server.conf +17 -0
  43. data/distro/debian/etc/init/chef-solr-indexer.conf +17 -0
  44. data/distro/debian/etc/init/chef-solr.conf +17 -0
  45. data/distro/redhat/etc/init.d/chef-client +106 -0
  46. data/distro/redhat/etc/init.d/chef-server +112 -0
  47. data/distro/redhat/etc/init.d/chef-server-webui +112 -0
  48. data/distro/redhat/etc/init.d/chef-solr +104 -0
  49. data/distro/redhat/etc/init.d/chef-solr-indexer +104 -0
  50. data/distro/redhat/etc/logrotate.d/chef-client +8 -0
  51. data/distro/redhat/etc/logrotate.d/chef-server +8 -0
  52. data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
  53. data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
  54. data/distro/redhat/etc/logrotate.d/chef-solr-indexer +8 -0
  55. data/distro/redhat/etc/sysconfig/chef-client +15 -0
  56. data/distro/redhat/etc/sysconfig/chef-server +14 -0
  57. data/distro/redhat/etc/sysconfig/chef-server-webui +14 -0
  58. data/distro/redhat/etc/sysconfig/chef-solr +8 -0
  59. data/distro/redhat/etc/sysconfig/chef-solr-indexer +7 -0
  60. data/lib/chef.rb +40 -0
  61. data/lib/chef/api_client.rb +264 -0
  62. data/lib/chef/application.rb +137 -0
  63. data/lib/chef/application/agent.rb +18 -0
  64. data/lib/chef/application/client.rb +242 -0
  65. data/lib/chef/application/knife.rb +169 -0
  66. data/lib/chef/application/solo.rb +217 -0
  67. data/lib/chef/applications.rb +4 -0
  68. data/lib/chef/certificate.rb +194 -0
  69. data/lib/chef/checksum.rb +182 -0
  70. data/lib/chef/checksum_cache.rb +189 -0
  71. data/lib/chef/client.rb +362 -0
  72. data/lib/chef/config.rb +244 -0
  73. data/lib/chef/cookbook/chefignore.rb +66 -0
  74. data/lib/chef/cookbook/cookbook_collection.rb +45 -0
  75. data/lib/chef/cookbook/cookbook_version_loader.rb +151 -0
  76. data/lib/chef/cookbook/file_system_file_vendor.rb +56 -0
  77. data/lib/chef/cookbook/file_vendor.rb +48 -0
  78. data/lib/chef/cookbook/metadata.rb +592 -0
  79. data/lib/chef/cookbook/remote_file_vendor.rb +87 -0
  80. data/lib/chef/cookbook/syntax_check.rb +136 -0
  81. data/lib/chef/cookbook_loader.rb +103 -0
  82. data/lib/chef/cookbook_site_streaming_uploader.rb +244 -0
  83. data/lib/chef/cookbook_uploader.rb +125 -0
  84. data/lib/chef/cookbook_version.rb +979 -0
  85. data/lib/chef/cookbook_version_selector.rb +163 -0
  86. data/lib/chef/couchdb.rb +247 -0
  87. data/lib/chef/daemon.rb +172 -0
  88. data/lib/chef/data_bag.rb +223 -0
  89. data/lib/chef/data_bag_item.rb +267 -0
  90. data/lib/chef/encrypted_data_bag_item.rb +126 -0
  91. data/lib/chef/environment.rb +386 -0
  92. data/lib/chef/exceptions.rb +153 -0
  93. data/lib/chef/file_access_control.rb +140 -0
  94. data/lib/chef/file_cache.rb +218 -0
  95. data/lib/chef/handler.rb +206 -0
  96. data/lib/chef/handler/json_file.rb +58 -0
  97. data/lib/chef/index_queue.rb +29 -0
  98. data/lib/chef/index_queue/amqp_client.rb +116 -0
  99. data/lib/chef/index_queue/consumer.rb +76 -0
  100. data/lib/chef/index_queue/indexable.rb +109 -0
  101. data/lib/chef/json_compat.rb +52 -0
  102. data/lib/chef/knife.rb +424 -0
  103. data/lib/chef/knife/bootstrap.rb +185 -0
  104. data/lib/chef/knife/bootstrap/archlinux-gems.erb +47 -0
  105. data/lib/chef/knife/bootstrap/centos5-gems.erb +41 -0
  106. data/lib/chef/knife/bootstrap/client-install.vbs +80 -0
  107. data/lib/chef/knife/bootstrap/fedora13-gems.erb +38 -0
  108. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +32 -0
  109. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +46 -0
  110. data/lib/chef/knife/bootstrap/windows-gems.erb +34 -0
  111. data/lib/chef/knife/client_bulk_delete.rb +43 -0
  112. data/lib/chef/knife/client_create.rb +73 -0
  113. data/lib/chef/knife/client_delete.rb +48 -0
  114. data/lib/chef/knife/client_edit.rb +48 -0
  115. data/lib/chef/knife/client_list.rb +43 -0
  116. data/lib/chef/knife/client_reregister.rb +59 -0
  117. data/lib/chef/knife/client_show.rb +53 -0
  118. data/lib/chef/knife/configure.rb +136 -0
  119. data/lib/chef/knife/configure_client.rb +52 -0
  120. data/lib/chef/knife/cookbook_bulk_delete.rb +61 -0
  121. data/lib/chef/knife/cookbook_create.rb +274 -0
  122. data/lib/chef/knife/cookbook_delete.rb +149 -0
  123. data/lib/chef/knife/cookbook_download.rb +134 -0
  124. data/lib/chef/knife/cookbook_list.rb +50 -0
  125. data/lib/chef/knife/cookbook_metadata.rb +102 -0
  126. data/lib/chef/knife/cookbook_metadata_from_file.rb +44 -0
  127. data/lib/chef/knife/cookbook_show.rb +101 -0
  128. data/lib/chef/knife/cookbook_site_download.rb +58 -0
  129. data/lib/chef/knife/cookbook_site_list.rb +56 -0
  130. data/lib/chef/knife/cookbook_site_search.rb +51 -0
  131. data/lib/chef/knife/cookbook_site_share.rb +114 -0
  132. data/lib/chef/knife/cookbook_site_show.rb +57 -0
  133. data/lib/chef/knife/cookbook_site_unshare.rb +56 -0
  134. data/lib/chef/knife/cookbook_site_vendor.rb +145 -0
  135. data/lib/chef/knife/cookbook_test.rb +82 -0
  136. data/lib/chef/knife/cookbook_upload.rb +146 -0
  137. data/lib/chef/knife/data_bag_create.rb +94 -0
  138. data/lib/chef/knife/data_bag_delete.rb +51 -0
  139. data/lib/chef/knife/data_bag_edit.rb +94 -0
  140. data/lib/chef/knife/data_bag_from_file.rb +85 -0
  141. data/lib/chef/knife/data_bag_list.rb +46 -0
  142. data/lib/chef/knife/data_bag_show.rb +81 -0
  143. data/lib/chef/knife/environment_create.rb +53 -0
  144. data/lib/chef/knife/environment_delete.rb +45 -0
  145. data/lib/chef/knife/environment_edit.rb +45 -0
  146. data/lib/chef/knife/environment_from_file.rb +39 -0
  147. data/lib/chef/knife/environment_list.rb +42 -0
  148. data/lib/chef/knife/environment_show.rb +46 -0
  149. data/lib/chef/knife/exec.rb +51 -0
  150. data/lib/chef/knife/index_rebuild.rb +50 -0
  151. data/lib/chef/knife/node_bulk_delete.rb +46 -0
  152. data/lib/chef/knife/node_create.rb +50 -0
  153. data/lib/chef/knife/node_delete.rb +47 -0
  154. data/lib/chef/knife/node_edit.rb +163 -0
  155. data/lib/chef/knife/node_from_file.rb +45 -0
  156. data/lib/chef/knife/node_list.rb +46 -0
  157. data/lib/chef/knife/node_run_list_add.rb +67 -0
  158. data/lib/chef/knife/node_run_list_remove.rb +48 -0
  159. data/lib/chef/knife/node_show.rb +62 -0
  160. data/lib/chef/knife/recipe_list.rb +33 -0
  161. data/lib/chef/knife/role_bulk_delete.rb +47 -0
  162. data/lib/chef/knife/role_create.rb +55 -0
  163. data/lib/chef/knife/role_delete.rb +47 -0
  164. data/lib/chef/knife/role_edit.rb +48 -0
  165. data/lib/chef/knife/role_from_file.rb +49 -0
  166. data/lib/chef/knife/role_list.rb +43 -0
  167. data/lib/chef/knife/role_show.rb +54 -0
  168. data/lib/chef/knife/search.rb +123 -0
  169. data/lib/chef/knife/ssh.rb +318 -0
  170. data/lib/chef/knife/status.rb +90 -0
  171. data/lib/chef/knife/subcommand_loader.rb +101 -0
  172. data/lib/chef/knife/tag_create.rb +31 -0
  173. data/lib/chef/knife/tag_delete.rb +31 -0
  174. data/lib/chef/knife/tag_list.rb +29 -0
  175. data/lib/chef/knife/ui.rb +227 -0
  176. data/lib/chef/knife/windows_bootstrap.rb +157 -0
  177. data/lib/chef/log.rb +39 -0
  178. data/lib/chef/mash.rb +211 -0
  179. data/lib/chef/mixin/check_helper.rb +31 -0
  180. data/lib/chef/mixin/checksum.rb +32 -0
  181. data/lib/chef/mixin/command.rb +221 -0
  182. data/lib/chef/mixin/command/unix.rb +215 -0
  183. data/lib/chef/mixin/command/windows.rb +76 -0
  184. data/lib/chef/mixin/convert_to_class_name.rb +63 -0
  185. data/lib/chef/mixin/create_path.rb +56 -0
  186. data/lib/chef/mixin/deep_merge.rb +225 -0
  187. data/lib/chef/mixin/deprecation.rb +65 -0
  188. data/lib/chef/mixin/from_file.rb +50 -0
  189. data/lib/chef/mixin/language.rb +165 -0
  190. data/lib/chef/mixin/language_include_attribute.rb +61 -0
  191. data/lib/chef/mixin/language_include_recipe.rb +52 -0
  192. data/lib/chef/mixin/params_validate.rb +225 -0
  193. data/lib/chef/mixin/recipe_definition_dsl_core.rb +81 -0
  194. data/lib/chef/mixin/shell_out.rb +40 -0
  195. data/lib/chef/mixin/template.rb +95 -0
  196. data/lib/chef/mixin/xml_escape.rb +140 -0
  197. data/lib/chef/mixins.rb +15 -0
  198. data/lib/chef/monkey_patches/dir.rb +36 -0
  199. data/lib/chef/monkey_patches/numeric.rb +7 -0
  200. data/lib/chef/monkey_patches/regexp.rb +34 -0
  201. data/lib/chef/monkey_patches/string.rb +28 -0
  202. data/lib/chef/monkey_patches/tempfile.rb +64 -0
  203. data/lib/chef/nil_argument.rb +3 -0
  204. data/lib/chef/node.rb +661 -0
  205. data/lib/chef/node/attribute.rb +487 -0
  206. data/lib/chef/openid_registration.rb +187 -0
  207. data/lib/chef/platform.rb +409 -0
  208. data/lib/chef/provider.rb +124 -0
  209. data/lib/chef/provider/breakpoint.rb +36 -0
  210. data/lib/chef/provider/cookbook_file.rb +101 -0
  211. data/lib/chef/provider/cron.rb +186 -0
  212. data/lib/chef/provider/cron/solaris.rb +195 -0
  213. data/lib/chef/provider/deploy.rb +320 -0
  214. data/lib/chef/provider/deploy/revision.rb +80 -0
  215. data/lib/chef/provider/deploy/timestamped.rb +33 -0
  216. data/lib/chef/provider/directory.rb +72 -0
  217. data/lib/chef/provider/env.rb +152 -0
  218. data/lib/chef/provider/env/windows.rb +75 -0
  219. data/lib/chef/provider/erl_call.rb +100 -0
  220. data/lib/chef/provider/execute.rb +60 -0
  221. data/lib/chef/provider/file.rb +222 -0
  222. data/lib/chef/provider/git.rb +221 -0
  223. data/lib/chef/provider/group.rb +133 -0
  224. data/lib/chef/provider/group/aix.rb +70 -0
  225. data/lib/chef/provider/group/dscl.rb +121 -0
  226. data/lib/chef/provider/group/gpasswd.rb +53 -0
  227. data/lib/chef/provider/group/groupadd.rb +81 -0
  228. data/lib/chef/provider/group/pw.rb +84 -0
  229. data/lib/chef/provider/group/usermod.rb +57 -0
  230. data/lib/chef/provider/group/windows.rb +79 -0
  231. data/lib/chef/provider/http_request.rb +122 -0
  232. data/lib/chef/provider/ifconfig.rb +132 -0
  233. data/lib/chef/provider/link.rb +161 -0
  234. data/lib/chef/provider/log.rb +54 -0
  235. data/lib/chef/provider/mdadm.rb +91 -0
  236. data/lib/chef/provider/mount.rb +117 -0
  237. data/lib/chef/provider/mount/mount.rb +232 -0
  238. data/lib/chef/provider/mount/windows.rb +80 -0
  239. data/lib/chef/provider/ohai.rb +41 -0
  240. data/lib/chef/provider/package.rb +160 -0
  241. data/lib/chef/provider/package/apt.rb +110 -0
  242. data/lib/chef/provider/package/dpkg.rb +112 -0
  243. data/lib/chef/provider/package/easy_install.rb +136 -0
  244. data/lib/chef/provider/package/freebsd.rb +123 -0
  245. data/lib/chef/provider/package/macports.rb +105 -0
  246. data/lib/chef/provider/package/pacman.rb +101 -0
  247. data/lib/chef/provider/package/portage.rb +135 -0
  248. data/lib/chef/provider/package/rpm.rb +101 -0
  249. data/lib/chef/provider/package/rubygems.rb +462 -0
  250. data/lib/chef/provider/package/solaris.rb +127 -0
  251. data/lib/chef/provider/package/yum-dump.py +128 -0
  252. data/lib/chef/provider/package/yum.rb +261 -0
  253. data/lib/chef/provider/package/zypper.rb +133 -0
  254. data/lib/chef/provider/remote_directory.rb +138 -0
  255. data/lib/chef/provider/remote_file.rb +119 -0
  256. data/lib/chef/provider/route.rb +195 -0
  257. data/lib/chef/provider/ruby_block.rb +33 -0
  258. data/lib/chef/provider/script.rb +55 -0
  259. data/lib/chef/provider/service.rb +128 -0
  260. data/lib/chef/provider/service/arch.rb +109 -0
  261. data/lib/chef/provider/service/debian.rb +130 -0
  262. data/lib/chef/provider/service/freebsd.rb +156 -0
  263. data/lib/chef/provider/service/gentoo.rb +54 -0
  264. data/lib/chef/provider/service/init.rb +71 -0
  265. data/lib/chef/provider/service/insserv.rb +52 -0
  266. data/lib/chef/provider/service/redhat.rb +60 -0
  267. data/lib/chef/provider/service/simple.rb +118 -0
  268. data/lib/chef/provider/service/solaris.rb +85 -0
  269. data/lib/chef/provider/service/upstart.rb +192 -0
  270. data/lib/chef/provider/service/windows.rb +146 -0
  271. data/lib/chef/provider/subversion.rb +194 -0
  272. data/lib/chef/provider/template.rb +105 -0
  273. data/lib/chef/provider/user.rb +187 -0
  274. data/lib/chef/provider/user/dscl.rb +280 -0
  275. data/lib/chef/provider/user/pw.rb +113 -0
  276. data/lib/chef/provider/user/useradd.rb +137 -0
  277. data/lib/chef/provider/user/windows.rb +124 -0
  278. data/lib/chef/providers.rb +93 -0
  279. data/lib/chef/recipe.rb +128 -0
  280. data/lib/chef/resource.rb +530 -0
  281. data/lib/chef/resource/apt_package.rb +34 -0
  282. data/lib/chef/resource/bash.rb +33 -0
  283. data/lib/chef/resource/breakpoint.rb +35 -0
  284. data/lib/chef/resource/cookbook_file.rb +45 -0
  285. data/lib/chef/resource/cron.rb +188 -0
  286. data/lib/chef/resource/csh.rb +33 -0
  287. data/lib/chef/resource/deploy.rb +371 -0
  288. data/lib/chef/resource/deploy_revision.rb +35 -0
  289. data/lib/chef/resource/directory.rb +76 -0
  290. data/lib/chef/resource/dpkg_package.rb +34 -0
  291. data/lib/chef/resource/easy_install_package.rb +57 -0
  292. data/lib/chef/resource/env.rb +58 -0
  293. data/lib/chef/resource/erl_call.rb +83 -0
  294. data/lib/chef/resource/execute.rb +127 -0
  295. data/lib/chef/resource/file.rb +99 -0
  296. data/lib/chef/resource/freebsd_package.rb +35 -0
  297. data/lib/chef/resource/gem_package.rb +53 -0
  298. data/lib/chef/resource/git.rb +37 -0
  299. data/lib/chef/resource/group.rb +70 -0
  300. data/lib/chef/resource/http_request.rb +61 -0
  301. data/lib/chef/resource/ifconfig.rb +134 -0
  302. data/lib/chef/resource/link.rb +78 -0
  303. data/lib/chef/resource/log.rb +62 -0
  304. data/lib/chef/resource/macports_package.rb +29 -0
  305. data/lib/chef/resource/mdadm.rb +82 -0
  306. data/lib/chef/resource/mount.rb +135 -0
  307. data/lib/chef/resource/ohai.rb +40 -0
  308. data/lib/chef/resource/package.rb +80 -0
  309. data/lib/chef/resource/pacman_package.rb +33 -0
  310. data/lib/chef/resource/perl.rb +33 -0
  311. data/lib/chef/resource/portage_package.rb +33 -0
  312. data/lib/chef/resource/python.rb +33 -0
  313. data/lib/chef/resource/remote_directory.rb +109 -0
  314. data/lib/chef/resource/remote_file.rb +83 -0
  315. data/lib/chef/resource/route.rb +135 -0
  316. data/lib/chef/resource/rpm_package.rb +34 -0
  317. data/lib/chef/resource/ruby.rb +33 -0
  318. data/lib/chef/resource/ruby_block.rb +40 -0
  319. data/lib/chef/resource/scm.rb +147 -0
  320. data/lib/chef/resource/script.rb +60 -0
  321. data/lib/chef/resource/service.rb +160 -0
  322. data/lib/chef/resource/solaris_package.rb +36 -0
  323. data/lib/chef/resource/subversion.rb +36 -0
  324. data/lib/chef/resource/template.rb +69 -0
  325. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  326. data/lib/chef/resource/user.rb +130 -0
  327. data/lib/chef/resource/yum_package.rb +43 -0
  328. data/lib/chef/resource_collection.rb +217 -0
  329. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  330. data/lib/chef/resource_definition.rb +67 -0
  331. data/lib/chef/resource_definition_list.rb +38 -0
  332. data/lib/chef/resources.rb +64 -0
  333. data/lib/chef/rest.rb +386 -0
  334. data/lib/chef/rest/auth_credentials.rb +71 -0
  335. data/lib/chef/rest/cookie_jar.rb +31 -0
  336. data/lib/chef/rest/rest_request.rb +188 -0
  337. data/lib/chef/role.rb +341 -0
  338. data/lib/chef/run_context.rb +126 -0
  339. data/lib/chef/run_list.rb +165 -0
  340. data/lib/chef/run_list/run_list_expansion.rb +193 -0
  341. data/lib/chef/run_list/run_list_item.rb +92 -0
  342. data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
  343. data/lib/chef/run_status.rb +121 -0
  344. data/lib/chef/runner.rb +99 -0
  345. data/lib/chef/sandbox.rb +153 -0
  346. data/lib/chef/search/query.rb +65 -0
  347. data/lib/chef/shef.rb +326 -0
  348. data/lib/chef/shef/ext.rb +569 -0
  349. data/lib/chef/shef/model_wrapper.rb +120 -0
  350. data/lib/chef/shef/shef_rest.rb +28 -0
  351. data/lib/chef/shef/shef_session.rb +284 -0
  352. data/lib/chef/shell_out.rb +238 -0
  353. data/lib/chef/shell_out/unix.rb +223 -0
  354. data/lib/chef/shell_out/windows.rb +98 -0
  355. data/lib/chef/solr_query.rb +187 -0
  356. data/lib/chef/solr_query/lucene.treetop +150 -0
  357. data/lib/chef/solr_query/lucene_nodes.rb +285 -0
  358. data/lib/chef/solr_query/query_transform.rb +65 -0
  359. data/lib/chef/solr_query/solr_http_request.rb +118 -0
  360. data/lib/chef/streaming_cookbook_uploader.rb +201 -0
  361. data/lib/chef/tasks/chef_repo.rake +256 -0
  362. data/lib/chef/util/file_edit.rb +122 -0
  363. data/lib/chef/util/windows.rb +56 -0
  364. data/lib/chef/util/windows/net_group.rb +101 -0
  365. data/lib/chef/util/windows/net_use.rb +121 -0
  366. data/lib/chef/util/windows/net_user.rb +198 -0
  367. data/lib/chef/util/windows/volume.rb +59 -0
  368. data/lib/chef/version.rb +23 -0
  369. data/lib/chef/version_class.rb +70 -0
  370. data/lib/chef/version_constraint.rb +116 -0
  371. data/lib/chef/webui_user.rb +231 -0
  372. metadata +600 -0
@@ -0,0 +1,66 @@
1
+ #--
2
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
3
+ # Copyright:: Copyright (c) 2011 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
+ class Chef
20
+ class Cookbook
21
+ class Chefignore
22
+
23
+ COMMENTS_AND_WHITESPACE = /^\w*(?:#.*)?$/
24
+
25
+ attr_reader :ignores
26
+
27
+ def initialize(ignore_file_or_repo)
28
+ @ignore_file = find_ignore_file(ignore_file_or_repo)
29
+ @ignores = parse_ignore_file
30
+ end
31
+
32
+ def remove_ignores_from(file_list)
33
+ Array(file_list).inject([]) do |unignored, file|
34
+ ignored?(file) ? unignored : unignored << file
35
+ end
36
+ end
37
+
38
+ def ignored?(file_name)
39
+ @ignores.any? {|glob| File.fnmatch?(glob, file_name)}
40
+ end
41
+
42
+ private
43
+
44
+ def parse_ignore_file
45
+ ignore_globs = []
46
+ if File.exist?(@ignore_file) && File.readable?(@ignore_file)
47
+ File.foreach(@ignore_file) do |line|
48
+ ignore_globs << line.strip unless line =~ COMMENTS_AND_WHITESPACE
49
+ end
50
+ else
51
+ Chef::Log.debug("No chefignore file found at #@ignore_file no files will be ignored")
52
+ end
53
+ ignore_globs
54
+ end
55
+
56
+ def find_ignore_file(path)
57
+ if File.basename(path) =~ /chefignore/
58
+ path
59
+ else
60
+ File.join(path, 'chefignore')
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
@@ -0,0 +1,45 @@
1
+ #--
2
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
3
+ # Author:: Christopher Walters (<cw@opscode.com>)
4
+ # Copyright:: Copyright (c) 2010 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'chef/mash'
21
+
22
+ class Chef
23
+ # == Chef::CookbookCollection
24
+ # This class is the consistent interface for a node to obtain its
25
+ # cookbooks by name.
26
+ #
27
+ # This class is basically a glorified Hash, but since there are
28
+ # several ways this cookbook information is collected,
29
+ # (e.g. CookbookLoader for solo, hash of auto-vivified Cookbook
30
+ # objects for lazily-loaded remote cookbooks), it gets transformed
31
+ # into this.
32
+ class CookbookCollection < Mash
33
+
34
+ # The input is a mapping of cookbook name to CookbookVersion objects. We
35
+ # simply extract them
36
+ def initialize(cookbook_versions={})
37
+ super() do |hash, key|
38
+ raise Chef::Exceptions::CookbookNotFound, "Cookbook #{key} not found. " <<
39
+ "If you're loading #{key} from another cookbook, make sure you configure the dependency in your metadata"
40
+ end
41
+ cookbook_versions.each{ |cookbook_name, cookbook_version| self[cookbook_name] = cookbook_version }
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,151 @@
1
+
2
+ require 'chef/config'
3
+ require 'chef/cookbook_version'
4
+ require 'chef/cookbook/chefignore'
5
+ require 'chef/cookbook/metadata'
6
+
7
+ class Chef
8
+ class Cookbook
9
+ class CookbookVersionLoader
10
+
11
+ FILETYPES_SUBJECT_TO_IGNORE = [ :attribute_filenames,
12
+ :definition_filenames,
13
+ :recipe_filenames,
14
+ :template_filenames,
15
+ :file_filenames,
16
+ :library_filenames,
17
+ :resource_filenames,
18
+ :provider_filenames]
19
+
20
+
21
+ attr_reader :cookbook_name
22
+ attr_reader :cookbook_settings
23
+ attr_reader :metadata_filenames
24
+
25
+ def initialize(path, chefignore=nil)
26
+ @cookbook_path = File.expand_path( path )
27
+ @cookbook_name = File.basename( path )
28
+ @chefignore = chefignore
29
+ @metadata = Hash.new
30
+ @relative_path = /#{Regexp.escape(@cookbook_path)}\/(.+)$/
31
+ @cookbook_settings = {
32
+ :attribute_filenames => {},
33
+ :definition_filenames => {},
34
+ :recipe_filenames => {},
35
+ :template_filenames => {},
36
+ :file_filenames => {},
37
+ :library_filenames => {},
38
+ :resource_filenames => {},
39
+ :provider_filenames => {},
40
+ :root_filenames => {}
41
+ }
42
+
43
+ @metadata_filenames = []
44
+ end
45
+
46
+ def load_cookbooks
47
+ load_as(:attribute_filenames, 'attributes', '*.rb')
48
+ load_as(:definition_filenames, 'definitions', '*.rb')
49
+ load_as(:recipe_filenames, 'recipes', '*.rb')
50
+ load_as(:library_filenames, 'libraries', '*.rb')
51
+ load_recursively_as(:template_filenames, "templates", "*")
52
+ load_recursively_as(:file_filenames, "files", "*")
53
+ load_recursively_as(:resource_filenames, "resources", "*.rb")
54
+ load_recursively_as(:provider_filenames, "providers", "*.rb")
55
+ load_root_files
56
+
57
+ remove_ignored_files
58
+
59
+ if File.exists?(File.join(@cookbook_path, "metadata.json"))
60
+ @metadata_filenames << File.join(@cookbook_path, "metadata.json")
61
+ end
62
+
63
+ if empty?
64
+ Chef::Log.warn "found a directory #{cookbook_name} in the cookbook path, but it contains no cookbook files. skipping."
65
+ end
66
+ @cookbook_settings
67
+ end
68
+
69
+ def cookbook_version
70
+ return nil if empty?
71
+
72
+ Chef::CookbookVersion.new(@cookbook_name.to_sym).tap do |c|
73
+ c.root_dir = @cookbook_path
74
+ c.attribute_filenames = cookbook_settings[:attribute_filenames].values
75
+ c.definition_filenames = cookbook_settings[:definition_filenames].values
76
+ c.recipe_filenames = cookbook_settings[:recipe_filenames].values
77
+ c.template_filenames = cookbook_settings[:template_filenames].values
78
+ c.file_filenames = cookbook_settings[:file_filenames].values
79
+ c.library_filenames = cookbook_settings[:library_filenames].values
80
+ c.resource_filenames = cookbook_settings[:resource_filenames].values
81
+ c.provider_filenames = cookbook_settings[:provider_filenames].values
82
+ c.root_filenames = cookbook_settings[:root_filenames].values
83
+ c.metadata_filenames = @metadata_filenames
84
+ c.metadata = metadata(c)
85
+ end
86
+ end
87
+
88
+ # Generates the Cookbook::Metadata object
89
+ def metadata(cookbook_version)
90
+ @metadata = Chef::Cookbook::Metadata.new(cookbook_version)
91
+ @metadata_filenames.each do |meta_json|
92
+ begin
93
+ @metadata.from_json(IO.read(meta_json))
94
+ rescue JSON::ParserError
95
+ Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + meta_json)
96
+ raise
97
+ end
98
+ end
99
+ @metadata
100
+ end
101
+
102
+ def empty?
103
+ cookbook_settings.inject(true) do |all_empty, files|
104
+ all_empty && files.last.empty?
105
+ end
106
+ end
107
+
108
+ def merge!(other_cookbook_loader)
109
+ other_cookbook_settings = other_cookbook_loader.cookbook_settings
110
+ @cookbook_settings.each do |file_type, file_list|
111
+ file_list.merge!(other_cookbook_settings[file_type])
112
+ end
113
+ @metadata_filenames.concat(other_cookbook_loader.metadata_filenames)
114
+ end
115
+
116
+ def chefignore
117
+ @chefignore ||= Chefignore.new(File.basename(@cookbook_path))
118
+ end
119
+
120
+ def load_root_files
121
+ Dir.glob(File.join(@cookbook_path, '*'), File::FNM_DOTMATCH).each do |file|
122
+ next if File.directory?(file)
123
+ @cookbook_settings[:root_filenames][file[@relative_path, 1]] = file
124
+ end
125
+ end
126
+
127
+ def load_recursively_as(category, category_dir, glob)
128
+ file_spec = File.join(@cookbook_path, category_dir, '**', glob)
129
+ Dir.glob(file_spec, File::FNM_DOTMATCH).each do |file|
130
+ next if File.directory?(file)
131
+ @cookbook_settings[category][file[@relative_path, 1]] = file
132
+ end
133
+ end
134
+
135
+ def load_as(category, *path_glob)
136
+ Dir[File.join(@cookbook_path, *path_glob)].each do |file|
137
+ @cookbook_settings[category][file[@relative_path, 1]] = file
138
+ end
139
+ end
140
+
141
+ def remove_ignored_files
142
+ @cookbook_settings.each_value do |file_list|
143
+ file_list.reject! do |relative_path, full_path|
144
+ chefignore.ignored?(relative_path)
145
+ end
146
+ end
147
+ end
148
+
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,56 @@
1
+ #--
2
+ # Author:: Christopher Walters (<cw@opscode.com>)
3
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
4
+ # Copyright:: Copyright (c) 2010 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'chef/cookbook/file_vendor'
21
+
22
+ class Chef
23
+ class Cookbook
24
+ # == Chef::Cookbook::FileSystemFileVendor
25
+ # This FileVendor loads files from Chef::Config.cookbook_path. The
26
+ # thing that's sort of janky about this FileVendor implementation is
27
+ # that it basically takes only the cookbook's name from the manifest
28
+ # and throws the rest away then re-builds the list of files on the
29
+ # disk. This is due to the manifest not having the on-disk file
30
+ # locations, since in the chef-client case, that information is
31
+ # non-sensical.
32
+ class FileSystemFileVendor < FileVendor
33
+
34
+ def initialize(manifest, *repo_paths)
35
+ @cookbook_name = manifest[:cookbook_name]
36
+ @repo_paths = repo_paths.flatten
37
+ raise ArgumentError, "You must specify at least one repo path" if @repo_paths.empty?
38
+ end
39
+
40
+ # Implements abstract base's requirement. It looks in the
41
+ # Chef::Config.cookbook_path file hierarchy for the requested
42
+ # file.
43
+ def get_filename(filename)
44
+ location = @repo_paths.inject(nil) do |memo, basepath|
45
+ candidate_location = File.join(basepath, @cookbook_name, filename)
46
+ memo = candidate_location if File.exist?(candidate_location)
47
+ memo
48
+ end
49
+ raise "File #{filename} does not exist for cookbook #{@cookbook_name}" unless location
50
+
51
+ location
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,48 @@
1
+ #
2
+ # Author:: Christopher Walters (<cw@opscode.com>)
3
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
4
+ # Copyright:: Copyright (c) 2010 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+
21
+ class Chef
22
+ class Cookbook
23
+ # == Chef::Cookbook::FileVendor
24
+ # This class handles fetching of cookbook files based on specificity.
25
+ class FileVendor
26
+
27
+ def self.on_create(&block)
28
+ @instance_creator = block
29
+ end
30
+
31
+ # Factory method that creates the appropriate kind of
32
+ # Cookbook::FileVendor to serve the contents of the manifest
33
+ def self.create_from_manifest(manifest)
34
+ raise "Must call Chef::Cookbook::FileVendor.on_create before calling create_from_manifest factory" unless defined?(@instance_creator)
35
+ @instance_creator.call(manifest)
36
+ end
37
+
38
+ # Gets the on-disk location for the given cookbook file.
39
+ #
40
+ # Subclasses are responsible for determining exactly how the
41
+ # files are obtained and where they are stored.
42
+ def get_filename(filename)
43
+ raise NotImplemented, "Subclasses must implement this method"
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,592 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: AJ Christensen (<aj@opscode.com>)
4
+ # Author:: Seth Falcon (<seth@opscode.com>)
5
+ # Copyright:: Copyright 2008-2010 Opscode, Inc.
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ require 'chef/mixin/from_file'
22
+ require 'chef/mixin/params_validate'
23
+ require 'chef/mixin/check_helper'
24
+ require 'chef/log'
25
+ require 'chef/version_class'
26
+ require 'chef/version_constraint'
27
+
28
+ class Chef
29
+ class Cookbook
30
+ # == Chef::Cookbook::Metadata
31
+ # Chef::Cookbook::Metadata provides a convenient DSL for declaring metadata
32
+ # about Chef Cookbooks.
33
+ class Metadata
34
+
35
+ COMPARISON_FIELDS = [ :name, :description, :long_description, :maintainer,
36
+ :maintainer_email, :license, :platforms, :dependencies,
37
+ :recommendations, :suggestions, :conflicting, :providing,
38
+ :replacing, :attributes, :groupings, :recipes, :version]
39
+
40
+ VERSION_CONSTRAINTS = {:depends => "dependencies",
41
+ :recommends => "recommendations",
42
+ :suggests => "suggestions",
43
+ :conflicts => "conflicting",
44
+ :provides => "providing",
45
+ :replaces => "replacing" }
46
+
47
+ include Chef::Mixin::CheckHelper
48
+ include Chef::Mixin::ParamsValidate
49
+ include Chef::Mixin::FromFile
50
+
51
+ attr_reader :cookbook,
52
+ :platforms,
53
+ :dependencies,
54
+ :recommendations,
55
+ :suggestions,
56
+ :conflicting,
57
+ :providing,
58
+ :replacing,
59
+ :attributes,
60
+ :groupings,
61
+ :recipes,
62
+ :version
63
+
64
+ # Builds a new Chef::Cookbook::Metadata object.
65
+ #
66
+ # === Parameters
67
+ # cookbook<String>:: An optional cookbook object
68
+ # maintainer<String>:: An optional maintainer
69
+ # maintainer_email<String>:: An optional maintainer email
70
+ # license<String>::An optional license. Default is Apache v2.0
71
+ #
72
+ # === Returns
73
+ # metadata<Chef::Cookbook::Metadata>
74
+ def initialize(cookbook=nil, maintainer='Your Name', maintainer_email='youremail@example.com', license='Apache v2.0')
75
+ @cookbook = cookbook
76
+ @name = cookbook ? cookbook.name : ""
77
+ @long_description = ""
78
+ self.maintainer(maintainer)
79
+ self.maintainer_email(maintainer_email)
80
+ self.license(license)
81
+ self.description('A fabulous new cookbook')
82
+ @platforms = Mash.new
83
+ @dependencies = Mash.new
84
+ @recommendations = Mash.new
85
+ @suggestions = Mash.new
86
+ @conflicting = Mash.new
87
+ @providing = Mash.new
88
+ @replacing = Mash.new
89
+ @attributes = Mash.new
90
+ @groupings = Mash.new
91
+ @recipes = Mash.new
92
+ @version = Version.new "0.0.0"
93
+ if cookbook
94
+ @recipes = cookbook.fully_qualified_recipe_names.inject({}) do |r, e|
95
+ e = self.name if e =~ /::default$/
96
+ r[e] = ""
97
+ self.provides e
98
+ r
99
+ end
100
+ end
101
+ end
102
+
103
+ def ==(other)
104
+ COMPARISON_FIELDS.inject(true) do |equal_so_far, field|
105
+ equal_so_far && other.respond_to?(field) && (other.send(field) == send(field))
106
+ end
107
+ end
108
+
109
+ # Sets the cookbooks maintainer, or returns it.
110
+ #
111
+ # === Parameters
112
+ # maintainer<String>:: The maintainers name
113
+ #
114
+ # === Returns
115
+ # maintainer<String>:: Returns the current maintainer.
116
+ def maintainer(arg=nil)
117
+ set_or_return(
118
+ :maintainer,
119
+ arg,
120
+ :kind_of => [ String ]
121
+ )
122
+ end
123
+
124
+ # Sets the maintainers email address, or returns it.
125
+ #
126
+ # === Parameters
127
+ # maintainer_email<String>:: The maintainers email address
128
+ #
129
+ # === Returns
130
+ # maintainer_email<String>:: Returns the current maintainer email.
131
+ def maintainer_email(arg=nil)
132
+ set_or_return(
133
+ :maintainer_email,
134
+ arg,
135
+ :kind_of => [ String ]
136
+ )
137
+ end
138
+
139
+ # Sets the current license, or returns it.
140
+ #
141
+ # === Parameters
142
+ # license<String>:: The current license.
143
+ #
144
+ # === Returns
145
+ # license<String>:: Returns the current license
146
+ def license(arg=nil)
147
+ set_or_return(
148
+ :license,
149
+ arg,
150
+ :kind_of => [ String ]
151
+ )
152
+ end
153
+
154
+ # Sets the current description, or returns it. Should be short - one line only!
155
+ #
156
+ # === Parameters
157
+ # description<String>:: The new description
158
+ #
159
+ # === Returns
160
+ # description<String>:: Returns the description
161
+ def description(arg=nil)
162
+ set_or_return(
163
+ :description,
164
+ arg,
165
+ :kind_of => [ String ]
166
+ )
167
+ end
168
+
169
+ # Sets the current long description, or returns it. Might come from a README, say.
170
+ #
171
+ # === Parameters
172
+ # long_description<String>:: The new long description
173
+ #
174
+ # === Returns
175
+ # long_description<String>:: Returns the long description
176
+ def long_description(arg=nil)
177
+ set_or_return(
178
+ :long_description,
179
+ arg,
180
+ :kind_of => [ String ]
181
+ )
182
+ end
183
+
184
+ # Sets the current cookbook version, or returns it. Can be two or three digits, seperated
185
+ # by dots. ie: '2.1', '1.5.4' or '0.9'.
186
+ #
187
+ # === Parameters
188
+ # version<String>:: The curent version, as a string
189
+ #
190
+ # === Returns
191
+ # version<String>:: Returns the current version
192
+ def version(arg=nil)
193
+ if arg
194
+ @version = Chef::Version.new(arg)
195
+ end
196
+
197
+ @version.to_s
198
+ end
199
+
200
+ # Sets the name of the cookbook, or returns it.
201
+ #
202
+ # === Parameters
203
+ # name<String>:: The curent cookbook name.
204
+ #
205
+ # === Returns
206
+ # name<String>:: Returns the current cookbook name.
207
+ def name(arg=nil)
208
+ set_or_return(
209
+ :name,
210
+ arg,
211
+ :kind_of => [ String ]
212
+ )
213
+ end
214
+
215
+ # Adds a supported platform, with version checking strings.
216
+ #
217
+ # === Parameters
218
+ # platform<String>,<Symbol>:: The platform (like :ubuntu or :mac_os_x)
219
+ # version<String>:: A version constraint of the form "OP VERSION",
220
+ # where OP is one of < <= = > >= ~> and VERSION has
221
+ # the form x.y.z or x.y.
222
+ #
223
+ # === Returns
224
+ # versions<Array>:: Returns the list of versions for the platform
225
+ def supports(platform, *version_args)
226
+ version = new_args_format(:supports, platform, version_args)
227
+ validate_version_constraint(:supports, platform, version)
228
+ @platforms[platform] = version
229
+ @platforms[platform]
230
+ end
231
+
232
+ # Adds a dependency on another cookbook, with version checking strings.
233
+ #
234
+ # === Parameters
235
+ # cookbook<String>:: The cookbook
236
+ # version<String>:: A version constraint of the form "OP VERSION",
237
+ # where OP is one of < <= = > >= ~> and VERSION has
238
+ # the form x.y.z or x.y.
239
+ #
240
+ # === Returns
241
+ # versions<Array>:: Returns the list of versions for the platform
242
+ def depends(cookbook, *version_args)
243
+ version = new_args_format(:depends, cookbook, version_args)
244
+ validate_version_constraint(:depends, cookbook, version)
245
+ @dependencies[cookbook] = version
246
+ @dependencies[cookbook]
247
+ end
248
+
249
+ # Adds a recommendation for another cookbook, with version checking strings.
250
+ #
251
+ # === Parameters
252
+ # cookbook<String>:: The cookbook
253
+ # version<String>:: A version constraint of the form "OP VERSION",
254
+ # where OP is one of < <= = > >= ~> and VERSION has
255
+ # the form x.y.z or x.y.
256
+ #
257
+ # === Returns
258
+ # versions<Array>:: Returns the list of versions for the platform
259
+ def recommends(cookbook, *version_args)
260
+ version = new_args_format(:recommends, cookbook, version_args)
261
+ validate_version_constraint(:recommends, cookbook, version)
262
+ @recommendations[cookbook] = version
263
+ @recommendations[cookbook]
264
+ end
265
+
266
+ # Adds a suggestion for another cookbook, with version checking strings.
267
+ #
268
+ # === Parameters
269
+ # cookbook<String>:: The cookbook
270
+ # version<String>:: A version constraint of the form "OP VERSION",
271
+ # where OP is one of < <= = > >= ~> and VERSION has the
272
+ # formx.y.z or x.y.
273
+ #
274
+ # === Returns
275
+ # versions<Array>:: Returns the list of versions for the platform
276
+ def suggests(cookbook, *version_args)
277
+ version = new_args_format(:suggests, cookbook, version_args)
278
+ validate_version_constraint(:suggests, cookbook, version)
279
+ @suggestions[cookbook] = version
280
+ @suggestions[cookbook]
281
+ end
282
+
283
+ # Adds a conflict for another cookbook, with version checking strings.
284
+ #
285
+ # === Parameters
286
+ # cookbook<String>:: The cookbook
287
+ # version<String>:: A version constraint of the form "OP VERSION",
288
+ # where OP is one of < <= = > >= ~> and VERSION has
289
+ # the form x.y.z or x.y.
290
+ #
291
+ # === Returns
292
+ # versions<Array>:: Returns the list of versions for the platform
293
+ def conflicts(cookbook, *version_args)
294
+ version = new_args_format(:conflicts, cookbook, version_args)
295
+ validate_version_constraint(:conflicts, cookbook, version)
296
+ @conflicting[cookbook] = version
297
+ @conflicting[cookbook]
298
+ end
299
+
300
+ # Adds a recipe, definition, or resource provided by this cookbook.
301
+ #
302
+ # Recipes are specified as normal
303
+ # Definitions are followed by (), and can include :params for prototyping
304
+ # Resources are the stringified version (service[apache2])
305
+ #
306
+ # === Parameters
307
+ # recipe, definition, resource<String>:: The thing we provide
308
+ # version<String>:: A version constraint of the form "OP VERSION",
309
+ # where OP is one of < <= = > >= ~> and VERSION has
310
+ # the form x.y.z or x.y.
311
+ #
312
+ # === Returns
313
+ # versions<Array>:: Returns the list of versions for the platform
314
+ def provides(cookbook, *version_args)
315
+ version = new_args_format(:provides, cookbook, version_args)
316
+ validate_version_constraint(:provides, cookbook, version)
317
+ @providing[cookbook] = version
318
+ @providing[cookbook]
319
+ end
320
+
321
+ # Adds a cookbook that is replaced by this one, with version checking strings.
322
+ #
323
+ # === Parameters
324
+ # cookbook<String>:: The cookbook we replace
325
+ # version<String>:: A version constraint of the form "OP VERSION",
326
+ # where OP is one of < <= = > >= ~> and VERSION has the form x.y.z or x.y.
327
+ #
328
+ # === Returns
329
+ # versions<Array>:: Returns the list of versions for the platform
330
+ def replaces(cookbook, *version_args)
331
+ version = new_args_format(:replaces, cookbook, version_args)
332
+ validate_version_constraint(:replaces, cookbook, version)
333
+ @replacing[cookbook] = version
334
+ @replacing[cookbook]
335
+ end
336
+
337
+ # Adds a description for a recipe.
338
+ #
339
+ # === Parameters
340
+ # recipe<String>:: The recipe
341
+ # description<String>:: The description of the recipe
342
+ #
343
+ # === Returns
344
+ # description<String>:: Returns the current description
345
+ def recipe(name, description)
346
+ @recipes[name] = description
347
+ end
348
+
349
+ # Adds an attribute )hat a user needs to configure for this cookbook. Takes
350
+ # a name (with the / notation for a nested attribute), followed by any of
351
+ # these options
352
+ #
353
+ # display_name<String>:: What a UI should show for this attribute
354
+ # description<String>:: A hint as to what this attr is for
355
+ # choice<Array>:: An array of choices to present to the user.
356
+ # calculated<Boolean>:: If true, the default value is calculated by the recipe and cannot be displayed.
357
+ # type<String>:: "string" or "array" - default is "string" ("hash" is supported for backwards compatibility)
358
+ # required<String>:: Whether this attr is 'required', 'recommended' or 'optional' - default 'optional' (true/false values also supported for backwards compatibility)
359
+ # recipes<Array>:: An array of recipes which need this attr set.
360
+ # default<String>,<Array>,<Hash>:: The default value
361
+ #
362
+ # === Parameters
363
+ # name<String>:: The name of the attribute ('foo', or 'apache2/log_dir')
364
+ # options<Hash>:: The description of the options
365
+ #
366
+ # === Returns
367
+ # options<Hash>:: Returns the current options hash
368
+ def attribute(name, options)
369
+ validate(
370
+ options,
371
+ {
372
+ :display_name => { :kind_of => String },
373
+ :description => { :kind_of => String },
374
+ :choice => { :kind_of => [ Array ], :default => [] },
375
+ :calculated => { :equal_to => [ true, false ], :default => false },
376
+ :type => { :equal_to => [ "string", "array", "hash", "symbol" ], :default => "string" },
377
+ :required => { :equal_to => [ "required", "recommended", "optional", true, false ], :default => "optional" },
378
+ :recipes => { :kind_of => [ Array ], :default => [] },
379
+ :default => { :kind_of => [ String, Array, Hash ] }
380
+ }
381
+ )
382
+ options[:required] = remap_required_attribute(options[:required]) unless options[:required].nil?
383
+ validate_string_array(options[:choice])
384
+ validate_calculated_default_rule(options)
385
+ validate_choice_default_rule(options)
386
+
387
+ @attributes[name] = options
388
+ @attributes[name]
389
+ end
390
+
391
+ def grouping(name, options)
392
+ validate(
393
+ options,
394
+ {
395
+ :title => { :kind_of => String },
396
+ :description => { :kind_of => String }
397
+ }
398
+ )
399
+ @groupings[name] = options
400
+ @groupings[name]
401
+ end
402
+
403
+ def to_hash
404
+ {
405
+ 'name' => self.name,
406
+ 'description' => self.description,
407
+ 'long_description' => self.long_description,
408
+ 'maintainer' => self.maintainer,
409
+ 'maintainer_email' => self.maintainer_email,
410
+ 'license' => self.license,
411
+ 'platforms' => self.platforms,
412
+ 'dependencies' => self.dependencies,
413
+ 'recommendations' => self.recommendations,
414
+ 'suggestions' => self.suggestions,
415
+ 'conflicting' => self.conflicting,
416
+ 'providing' => self.providing,
417
+ 'replacing' => self.replacing,
418
+ 'attributes' => self.attributes,
419
+ 'groupings' => self.groupings,
420
+ 'recipes' => self.recipes,
421
+ 'version' => self.version
422
+ }
423
+ end
424
+
425
+ def to_json(*a)
426
+ self.to_hash.to_json(*a)
427
+ end
428
+
429
+ def self.from_hash(o)
430
+ cm = self.new()
431
+ cm.from_hash(o)
432
+ cm
433
+ end
434
+
435
+ def from_hash(o)
436
+ @name = o['name'] if o.has_key?('name')
437
+ @description = o['description'] if o.has_key?('description')
438
+ @long_description = o['long_description'] if o.has_key?('long_description')
439
+ @maintainer = o['maintainer'] if o.has_key?('maintainer')
440
+ @maintainer_email = o['maintainer_email'] if o.has_key?('maintainer_email')
441
+ @license = o['license'] if o.has_key?('license')
442
+ @platforms = o['platforms'] if o.has_key?('platforms')
443
+ @dependencies = handle_deprecated_constraints(o['dependencies']) if o.has_key?('dependencies')
444
+ @recommendations = handle_deprecated_constraints(o['recommendations']) if o.has_key?('recommendations')
445
+ @suggestions = handle_deprecated_constraints(o['suggestions']) if o.has_key?('suggestions')
446
+ @conflicting = handle_deprecated_constraints(o['conflicting']) if o.has_key?('conflicting')
447
+ @providing = o['providing'] if o.has_key?('providing')
448
+ @replacing = handle_deprecated_constraints(o['replacing']) if o.has_key?('replacing')
449
+ @attributes = o['attributes'] if o.has_key?('attributes')
450
+ @groupings = o['groupings'] if o.has_key?('groupings')
451
+ @recipes = o['recipes'] if o.has_key?('recipes')
452
+ @version = o['version'] if o.has_key?('version')
453
+ self
454
+ end
455
+
456
+ def self.from_json(string)
457
+ o = Chef::JSONCompat.from_json(string)
458
+ self.from_hash(o)
459
+ end
460
+
461
+ def self.validate_json(json_str)
462
+ o = Chef::JSONCompat.from_json(json_str)
463
+ metadata = new()
464
+ VERSION_CONSTRAINTS.each do |method_name, hash_key|
465
+ if constraints = o[hash_key]
466
+ constraints.each do |cb_name, constraints|
467
+ metadata.send(method_name, cb_name, *Array(constraints))
468
+ end
469
+ end
470
+ end
471
+ true
472
+ end
473
+
474
+ def from_json(string)
475
+ o = Chef::JSONCompat.from_json(string)
476
+ from_hash(o)
477
+ end
478
+
479
+ private
480
+
481
+ def new_args_format(caller_name, dep_name, version_constraints)
482
+ if version_constraints.empty?
483
+ ">= 0.0.0"
484
+ elsif version_constraints.size == 1
485
+ version_constraints.first
486
+ else
487
+ msg=<<-OBSOLETED
488
+ The dependency specification syntax you are using is no longer valid. You may not
489
+ specify more than one version constraint for a particular cookbook.
490
+ Consult http://wiki.opscode.com/display/chef/Metadata for the updated syntax.
491
+
492
+ Called by: #{caller_name} '#{dep_name}', #{version_constraints.map {|vc| vc.inspect}.join(", ")}
493
+ Called from:
494
+ #{caller[0...5].map {|line| " " + line}.join("\n")}
495
+ OBSOLETED
496
+ raise Exceptions::ObsoleteDependencySyntax, msg
497
+ end
498
+ end
499
+
500
+ def validate_version_constraint(caller_name, dep_name, constraint_str)
501
+ Chef::VersionConstraint.new(constraint_str)
502
+ rescue Chef::Exceptions::InvalidVersionConstraint => e
503
+ Log.debug(e)
504
+
505
+ msg=<<-INVALID
506
+ The version constraint syntax you are using is not valid. If you recently
507
+ upgraded to Chef 0.10.0, be aware that you no may longer use "<<" and ">>" for
508
+ 'less than' and 'greater than'; use '<' and '>' instead.
509
+ Consult http://wiki.opscode.com/display/chef/Metadata for more information.
510
+
511
+ Called by: #{caller_name} '#{dep_name}', '#{constraint_str}'
512
+ Called from:
513
+ #{caller[0...5].map {|line| " " + line}.join("\n")}
514
+ INVALID
515
+ raise Exceptions::InvalidVersionConstraint, msg
516
+ end
517
+ # Verify that the given array is an array of strings
518
+ #
519
+ # Raise an exception if the members of the array are not Strings
520
+ #
521
+ # === Parameters
522
+ # arry<Array>:: An array to be validated
523
+ def validate_string_array(arry)
524
+ if arry.kind_of?(Array)
525
+ arry.each do |choice|
526
+ validate( {:choice => choice}, {:choice => {:kind_of => String}} )
527
+ end
528
+ end
529
+ end
530
+
531
+ # For backwards compatibility, remap Boolean values to String
532
+ # true is mapped to "required"
533
+ # false is mapped to "optional"
534
+ #
535
+ # === Parameters
536
+ # required_attr<String><Boolean>:: The value of options[:required]
537
+ #
538
+ # === Returns
539
+ # required_attr<String>:: "required", "recommended", or "optional"
540
+ def remap_required_attribute(value)
541
+ case value
542
+ when true
543
+ value = "required"
544
+ when false
545
+ value = "optional"
546
+ end
547
+ value
548
+ end
549
+
550
+ def validate_calculated_default_rule(options)
551
+ calculated_conflict = ((options[:default].is_a?(Array) && !options[:default].empty?) ||
552
+ (options[:default].is_a?(String) && !options[:default] != "")) &&
553
+ options[:calculated] == true
554
+ raise ArgumentError, "Default cannot be specified if calculated is true!" if calculated_conflict
555
+ end
556
+
557
+ def validate_choice_default_rule(options)
558
+ return if !options[:choice].is_a?(Array) || options[:choice].empty?
559
+
560
+ if options[:default].is_a?(String) && options[:default] != ""
561
+ raise ArgumentError, "Default must be one of your choice values!" if options[:choice].index(options[:default]) == nil
562
+ end
563
+
564
+ if options[:default].is_a?(Array) && !options[:default].empty?
565
+ options[:default].each do |val|
566
+ raise ArgumentError, "Default values must be a subset of your choice values!" if options[:choice].index(val) == nil
567
+ end
568
+ end
569
+ end
570
+
571
+ # This method translates version constraint strings from
572
+ # cookbooks with the old format.
573
+ #
574
+ # Before we began respecting version constraints, we allowed
575
+ # multiple constraints to be placed on cookbooks, as well as the
576
+ # << and >> operators, which are now just < and >. For
577
+ # specifications with more than one constraint, we return an
578
+ # empty array (otherwise, we're silently abiding only part of
579
+ # the contract they have specified to us). If there is only one
580
+ # constraint, we are replacing the old << and >> with the new <
581
+ # and >.
582
+ def handle_deprecated_constraints(specification)
583
+ specification.inject(Mash.new) do |acc, (cb, constraints)|
584
+ constraints = Array(constraints)
585
+ acc[cb] = (constraints.empty? || constraints.size > 1) ? [] : constraints.first.gsub(/>>/, '>').gsub(/<</, '<')
586
+ acc
587
+ end
588
+ end
589
+
590
+ end
591
+ end
592
+ end