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,118 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
4
+ # Copyright:: Copyright (c) 2009-2011 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 'net/http'
21
+ require 'uri'
22
+ require 'chef/json_compat'
23
+ require 'chef/config'
24
+
25
+ class Chef
26
+ class SolrQuery
27
+ class SolrHTTPRequest
28
+ CLASS_FOR_METHOD = {:GET => Net::HTTP::Get, :POST => Net::HTTP::Post}
29
+
30
+ UPDATE_URL = '/solr/update'
31
+ TEXT_XML = {"Content-Type" => "text/xml"}
32
+
33
+ def self.solr_url=(solr_url)
34
+ @solr_url = solr_url
35
+ @http_client = nil
36
+ end
37
+
38
+ def self.solr_url
39
+ @solr_url || Chef::Config[:solr_url]
40
+ end
41
+
42
+ def self.http_client
43
+ @http_client ||= begin
44
+ uri = URI.parse(solr_url)
45
+ Net::HTTP.new(uri.host, uri.port)
46
+ end
47
+ end
48
+
49
+ def self.select(params={})
50
+ url = "/solr/select?#{url_join(params)}"
51
+ Chef::Log.debug("Sending #{url} to Solr")
52
+ request = new(:GET, url)
53
+ json_response = request.run("Search Query to Solr '#{solr_url}#{url}'")
54
+ Chef::JSONCompat.from_json(json_response)
55
+ end
56
+
57
+ def self.update(doc)
58
+ Chef::Log.debug("POSTing document to SOLR:\n#{doc}")
59
+ request = new(:POST, UPDATE_URL, TEXT_XML) { |req| req.body = doc.to_s }
60
+ request.run("POST to Solr '#{UPDATE_URL}', data: #{doc}")
61
+ end
62
+
63
+ def self.url_join(params_hash={})
64
+ params = params_hash.inject("") do |param_str, params|
65
+ param_str << "#{params[0]}=#{escape(params[1])}&"
66
+ end
67
+ params.chop! # trailing &
68
+ params
69
+ end
70
+
71
+ def self.escape(s)
72
+ s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
73
+ '%'+$1.unpack('H2'*$1.size).join('%').upcase
74
+ }.tr(' ', '+')
75
+ end
76
+
77
+ def initialize(method, url, headers=nil)
78
+ args = headers ? [url, headers] : url
79
+ @request = CLASS_FOR_METHOD[method].new(*args)
80
+ yield @request if block_given?
81
+ end
82
+
83
+ def http_client
84
+ self.class.http_client
85
+ end
86
+
87
+ def solr_url
88
+ self.class.solr_url
89
+ end
90
+
91
+ def run(description="HTTP Request to Solr")
92
+ response = http_client.request(@request)
93
+ request_failed!(response, description) unless response.kind_of?(Net::HTTPSuccess)
94
+ response.body
95
+ rescue NoMethodError => e
96
+ # http://redmine.ruby-lang.org/issues/show/2708
97
+ # http://redmine.ruby-lang.org/issues/show/2758
98
+ if e.to_s =~ /#{Regexp.escape(%q|undefined method 'closed?' for nil:NilClass|)}/
99
+ Chef::Log.fatal("#{description} failed. Chef::Exceptions::SolrConnectionError exception: Errno::ECONNREFUSED (net/http undefined method closed?) attempting to contact #{solr_url}")
100
+ Chef::Log.debug("rescued error in http connect, treating it as Errno::ECONNREFUSED to hide bug in net/http")
101
+ Chef::Log.debug(e.backtrace.join("\n"))
102
+ raise Chef::Exceptions::SolrConnectionError, "Errno::ECONNREFUSED: Connection refused attempting to contact #{solr_url}"
103
+ else
104
+ raise
105
+ end
106
+ end
107
+
108
+ def request_failed!(response, description='HTTP call')
109
+ Chef::Log.fatal("#{description} failed (#{response.class} #{response.code} #{response.message})")
110
+ response.error!
111
+ rescue Timeout::Error, Errno::EINVAL, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT => e
112
+ Chef::Log.debug(e.backtrace.join("\n"))
113
+ raise Chef::Exceptions::SolrConnectionError, "#{e.class.name}: #{e.to_s}"
114
+ end
115
+
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,201 @@
1
+ # inspired by/cargo-culted from http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html
2
+ # On Apr 6, 2010, at 3:00 PM, Stanislav Vitvitskiy wrote:
3
+ #
4
+ # It's free to use / modify / distribute. No need to mention anything. Just copy/paste and use.
5
+ #
6
+ # Regards,
7
+ # Stan
8
+
9
+ require 'net/http'
10
+ require 'mixlib/authentication/signedheaderauth'
11
+ require 'openssl'
12
+ require 'chef/version'
13
+
14
+ class Chef
15
+ class StreamingCookbookUploader
16
+
17
+ DefaultHeaders = { 'accept' => 'application/json', 'x-chef-version' => ::Chef::VERSION }
18
+
19
+ class << self
20
+
21
+ def post(to_url, user_id, secret_key_filename, params = {}, headers = {})
22
+ make_request(:post, to_url, user_id, secret_key_filename, params, headers)
23
+ end
24
+
25
+ def put(to_url, user_id, secret_key_filename, params = {}, headers = {})
26
+ make_request(:put, to_url, user_id, secret_key_filename, params, headers)
27
+ end
28
+
29
+ def make_request(http_verb, to_url, user_id, secret_key_filename, params = {}, headers = {})
30
+ boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ'
31
+ parts = []
32
+ content_file = nil
33
+
34
+ timestamp = Time.now.utc.iso8601
35
+ secret_key = OpenSSL::PKey::RSA.new(File.read(secret_key_filename))
36
+
37
+ unless params.nil? || params.empty?
38
+ params.each do |key, value|
39
+ if value.kind_of?(File)
40
+ content_file = value
41
+ filepath = value.path
42
+ filename = File.basename(filepath)
43
+ parts << StringPart.new( "--" + boundary + "\r\n" +
44
+ "Content-Disposition: form-data; name=\"" + key.to_s + "\"; filename=\"" + filename + "\"\r\n" +
45
+ "Content-Type: application/octet-stream\r\n\r\n")
46
+ parts << StreamPart.new(value, File.size(filepath))
47
+ parts << StringPart.new("\r\n")
48
+ else
49
+ parts << StringPart.new( "--" + boundary + "\r\n" +
50
+ "Content-Disposition: form-data; name=\"" + key.to_s + "\"\r\n\r\n")
51
+ parts << StringPart.new(value.to_s + "\r\n")
52
+ end
53
+ end
54
+ parts << StringPart.new("--" + boundary + "--\r\n")
55
+ end
56
+
57
+ body_stream = MultipartStream.new(parts)
58
+
59
+ timestamp = Time.now.utc.iso8601
60
+
61
+ url = URI.parse(to_url)
62
+
63
+ Chef::Log.logger.debug("Signing: method: #{http_verb}, path: #{url.path}, file: #{content_file}, User-id: #{user_id}, Timestamp: #{timestamp}")
64
+
65
+ # We use the body for signing the request if the file parameter
66
+ # wasn't a valid file or wasn't included. Extract the body (with
67
+ # multi-part delimiters intact) to sign the request.
68
+ # TODO: tim: 2009-12-28: It'd be nice to remove this special case, and
69
+ # always hash the entire request body. In the file case it would just be
70
+ # expanded multipart text - the entire body of the POST.
71
+ content_body = parts.inject("") { |result,part| result + part.read(0, part.size) }
72
+ content_file.rewind if content_file # we consumed the file for the above operation, so rewind it.
73
+
74
+ signing_options = {
75
+ :http_method=>http_verb,
76
+ :path=>url.path,
77
+ :user_id=>user_id,
78
+ :timestamp=>timestamp}
79
+ (content_file && signing_options[:file] = content_file) || (signing_options[:body] = (content_body || ""))
80
+
81
+ headers.merge!(Mixlib::Authentication::SignedHeaderAuth.signing_object(signing_options).sign(secret_key))
82
+
83
+ content_file.rewind if content_file
84
+
85
+ # net/http doesn't like symbols for header keys, so we'll to_s each one just in case
86
+ headers = DefaultHeaders.merge(Hash[*headers.map{ |k,v| [k.to_s, v] }.flatten])
87
+
88
+ req = case http_verb
89
+ when :put
90
+ Net::HTTP::Put.new(url.path, headers)
91
+ when :post
92
+ Net::HTTP::Post.new(url.path, headers)
93
+ end
94
+ req.content_length = body_stream.size
95
+ req.content_type = 'multipart/form-data; boundary=' + boundary unless parts.empty?
96
+ req.body_stream = body_stream
97
+
98
+ http = Net::HTTP.new(url.host, url.port)
99
+ if url.scheme == "https"
100
+ http.use_ssl = true
101
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
102
+ end
103
+ res = http.request(req)
104
+ #res = http.start {|http_proc| http_proc.request(req) }
105
+
106
+ # alias status to code and to_s to body for test purposes
107
+ # TODO: stop the following madness!
108
+ class << res
109
+ alias :to_s :body
110
+
111
+ # BUGBUG this makes the response compatible with what respsonse_steps expects to test headers (response.headers[] -> response[])
112
+ def headers
113
+ self
114
+ end
115
+
116
+ def status
117
+ code.to_i
118
+ end
119
+ end
120
+ res
121
+ end
122
+
123
+ end
124
+
125
+ class StreamPart
126
+ def initialize(stream, size)
127
+ @stream, @size = stream, size
128
+ end
129
+
130
+ def size
131
+ @size
132
+ end
133
+
134
+ # read the specified amount from the stream
135
+ def read(offset, how_much)
136
+ @stream.read(how_much)
137
+ end
138
+ end
139
+
140
+ class StringPart
141
+ def initialize(str)
142
+ @str = str
143
+ end
144
+
145
+ def size
146
+ @str.length
147
+ end
148
+
149
+ # read the specified amount from the string startiung at the offset
150
+ def read(offset, how_much)
151
+ @str[offset, how_much]
152
+ end
153
+ end
154
+
155
+ class MultipartStream
156
+ def initialize(parts)
157
+ @parts = parts
158
+ @part_no = 0
159
+ @part_offset = 0
160
+ end
161
+
162
+ def size
163
+ @parts.inject(0) {|size, part| size + part.size}
164
+ end
165
+
166
+ def read(how_much)
167
+ return nil if @part_no >= @parts.size
168
+
169
+ how_much_current_part = @parts[@part_no].size - @part_offset
170
+
171
+ how_much_current_part = if how_much_current_part > how_much
172
+ how_much
173
+ else
174
+ how_much_current_part
175
+ end
176
+
177
+ how_much_next_part = how_much - how_much_current_part
178
+
179
+ current_part = @parts[@part_no].read(@part_offset, how_much_current_part)
180
+
181
+ # recurse into the next part if the current one was not large enough
182
+ if how_much_next_part > 0
183
+ @part_no += 1
184
+ @part_offset = 0
185
+ next_part = read(how_much_next_part)
186
+ current_part + if next_part
187
+ next_part
188
+ else
189
+ ''
190
+ end
191
+ else
192
+ @part_offset += how_much_current_part
193
+ current_part
194
+ end
195
+ end
196
+ end
197
+
198
+ end
199
+
200
+
201
+ end
@@ -0,0 +1,256 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008, 2009 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 'rubygems'
20
+ require 'chef/json_compat'
21
+ require 'chef'
22
+ require 'chef/role'
23
+ require 'chef/cookbook/metadata'
24
+ require 'tempfile'
25
+ require 'rake'
26
+
27
+ # Allow REMOTE options to be overridden on the command line
28
+ REMOTE_HOST = ENV["REMOTE_HOST"] if ENV["REMOTE_HOST"] != nil
29
+ REMOTE_SUDO = ENV["REMOTE_SUDO"] if ENV["REMOTE_SUDO"] != nil
30
+ if defined? REMOTE_HOST
31
+ REMOTE_PATH_PREFIX = "#{REMOTE_HOST}:"
32
+ REMOTE_EXEC_PREFIX = "ssh #{REMOTE_HOST}"
33
+ REMOTE_EXEC_PREFIX += " sudo" if defined? REMOTE_SUDO
34
+ LOCAL_EXEC_PREFIX = ""
35
+ else
36
+ REMOTE_PATH_PREFIX = ""
37
+ REMOTE_EXEC_PREFIX = ""
38
+ LOCAL_EXEC_PREFIX = "sudo"
39
+ end
40
+
41
+ desc "Update your repository from source control"
42
+ task :update do
43
+ puts "** Updating your repository"
44
+
45
+ case $vcs
46
+ when :svn
47
+ sh %{svn up}
48
+ when :git
49
+ pull = false
50
+ IO.foreach(File.join(TOPDIR, ".git", "config")) do |line|
51
+ pull = true if line =~ /\[remote "origin"\]/
52
+ end
53
+ if pull
54
+ sh %{git pull}
55
+ else
56
+ puts "* Skipping git pull, no origin specified"
57
+ end
58
+ else
59
+ puts "* No SCM configured, skipping update"
60
+ end
61
+ end
62
+
63
+ desc "Install the latest copy of the repository on this Chef Server"
64
+ task :install => [ :update, :roles, :upload_cookbooks ] do
65
+ if File.exists?(File.join(TOPDIR, "config", "server.rb"))
66
+ puts "* Installing new Chef Server Config"
67
+ sh "#{LOCAL_EXEC_PREFIX} rsync -rlt --delete --exclude '.svn' --exclude '.git*' config/server.rb #{REMOTE_PATH_PREFIX}#{CHEF_SERVER_CONFIG}"
68
+ end
69
+ if File.exists?(File.join(TOPDIR, "config", "client.rb"))
70
+ puts "* Installing new Chef Client Config"
71
+ sh "#{LOCAL_EXEC_PREFIX} rsync -rlt --delete --exclude '.svn' --exclude '.git*' config/client.rb #{REMOTE_PATH_PREFIX}#{CHEF_CLIENT_CONFIG}"
72
+ end
73
+ end
74
+
75
+ desc "By default, run rake test_cookbooks"
76
+ task :default => [ :test_cookbooks ]
77
+
78
+ desc "Create a new cookbook (with COOKBOOK=name, optional CB_PREFIX=site-)"
79
+ task :new_cookbook do
80
+ puts "***WARN: rake new_cookbook is deprecated. Please use 'knife cookbook new COOKBOOK' command.***"
81
+ create_cookbook(File.join(TOPDIR, "#{ENV["CB_PREFIX"]}cookbooks"))
82
+ create_readme(File.join(TOPDIR, "#{ENV["CB_PREFIX"]}cookbooks"))
83
+ create_metadata(File.join(TOPDIR, "#{ENV["CB_PREFIX"]}cookbooks"))
84
+ end
85
+
86
+ def create_cookbook(dir)
87
+ raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
88
+ puts "** Creating cookbook #{ENV["COOKBOOK"]}"
89
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "attributes")}"
90
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "recipes")}"
91
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "definitions")}"
92
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "libraries")}"
93
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "resources")}"
94
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "providers")}"
95
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "files", "default")}"
96
+ sh "mkdir -p #{File.join(dir, ENV["COOKBOOK"], "templates", "default")}"
97
+ unless File.exists?(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"))
98
+ open(File.join(dir, ENV["COOKBOOK"], "recipes", "default.rb"), "w") do |file|
99
+ file.puts <<-EOH
100
+ #
101
+ # Cookbook Name:: #{ENV["COOKBOOK"]}
102
+ # Recipe:: default
103
+ #
104
+ # Copyright #{Time.now.year}, #{COMPANY_NAME}
105
+ #
106
+ EOH
107
+ case NEW_COOKBOOK_LICENSE
108
+ when :apachev2
109
+ file.puts <<-EOH
110
+ # Licensed under the Apache License, Version 2.0 (the "License");
111
+ # you may not use this file except in compliance with the License.
112
+ # You may obtain a copy of the License at
113
+ #
114
+ # http://www.apache.org/licenses/LICENSE-2.0
115
+ #
116
+ # Unless required by applicable law or agreed to in writing, software
117
+ # distributed under the License is distributed on an "AS IS" BASIS,
118
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119
+ # See the License for the specific language governing permissions and
120
+ # limitations under the License.
121
+ #
122
+ EOH
123
+ when :none
124
+ file.puts <<-EOH
125
+ # All rights reserved - Do Not Redistribute
126
+ #
127
+ EOH
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ def create_readme(dir)
134
+ raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
135
+ puts "** Creating README for cookbook: #{ENV["COOKBOOK"]}"
136
+ unless File.exists?(File.join(dir, ENV["COOKBOOK"], "README.rdoc"))
137
+ open(File.join(dir, ENV["COOKBOOK"], "README.rdoc"), "w") do |file|
138
+ file.puts <<-EOH
139
+ = DESCRIPTION:
140
+
141
+ = REQUIREMENTS:
142
+
143
+ = ATTRIBUTES:
144
+
145
+ = USAGE:
146
+
147
+ EOH
148
+ end
149
+ end
150
+ end
151
+
152
+ def create_metadata(dir)
153
+ raise "Must provide a COOKBOOK=" unless ENV["COOKBOOK"]
154
+ puts "** Creating metadata for cookbook: #{ENV["COOKBOOK"]}"
155
+
156
+ case NEW_COOKBOOK_LICENSE
157
+ when :apachev2
158
+ license = "Apache 2.0"
159
+ when :none
160
+ license = "All rights reserved"
161
+ end
162
+
163
+ unless File.exists?(File.join(dir, ENV["COOKBOOK"], "metadata.rb"))
164
+ open(File.join(dir, ENV["COOKBOOK"], "metadata.rb"), "w") do |file|
165
+ if File.exists?(File.join(dir, ENV["COOKBOOK"], 'README.rdoc'))
166
+ long_description = "long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))"
167
+ end
168
+ file.puts <<-EOH
169
+ maintainer "#{COMPANY_NAME}"
170
+ maintainer_email "#{SSL_EMAIL_ADDRESS}"
171
+ license "#{license}"
172
+ description "Installs/Configures #{ENV["COOKBOOK"]}"
173
+ #{long_description}
174
+ version "0.1"
175
+ EOH
176
+ end
177
+ end
178
+ end
179
+
180
+ desc "Create a new self-signed SSL certificate for FQDN=foo.example.com"
181
+ task :ssl_cert do
182
+ $expect_verbose = true
183
+ fqdn = ENV["FQDN"]
184
+ fqdn =~ /^(.+?)\.(.+)$/
185
+ hostname = $1
186
+ domain = $2
187
+ keyfile = fqdn.gsub("*", "wildcard")
188
+ raise "Must provide FQDN!" unless fqdn && hostname && domain
189
+ puts "** Creating self signed SSL Certificate for #{fqdn}"
190
+ sh("(cd #{CADIR} && openssl genrsa 2048 > #{keyfile}.key)")
191
+ sh("(cd #{CADIR} && chmod 644 #{keyfile}.key)")
192
+ puts "* Generating Self Signed Certificate Request"
193
+ tf = Tempfile.new("#{keyfile}.ssl-conf")
194
+ ssl_config = <<EOH
195
+ [ req ]
196
+ distinguished_name = req_distinguished_name
197
+ prompt = no
198
+
199
+ [ req_distinguished_name ]
200
+ C = #{SSL_COUNTRY_NAME}
201
+ ST = #{SSL_STATE_NAME}
202
+ L = #{SSL_LOCALITY_NAME}
203
+ O = #{COMPANY_NAME}
204
+ OU = #{SSL_ORGANIZATIONAL_UNIT_NAME}
205
+ CN = #{fqdn}
206
+ emailAddress = #{SSL_EMAIL_ADDRESS}
207
+ EOH
208
+ tf.puts(ssl_config)
209
+ tf.close
210
+ sh("(cd #{CADIR} && openssl req -config '#{tf.path}' -new -x509 -nodes -sha1 -days 3650 -key #{keyfile}.key > #{keyfile}.crt)")
211
+ sh("(cd #{CADIR} && openssl x509 -noout -fingerprint -text < #{keyfile}.crt > #{keyfile}.info)")
212
+ sh("(cd #{CADIR} && cat #{keyfile}.crt #{keyfile}.key > #{keyfile}.pem)")
213
+ sh("(cd #{CADIR} && chmod 644 #{keyfile}.pem)")
214
+ end
215
+
216
+ rule(%r{\b(?:site-)?cookbooks/[^/]+/metadata\.json\Z} => [ proc { |task_name| task_name.sub(/\.[^.]+$/, '.rb') } ]) do |t|
217
+ system("knife cookbook metadata from file #{t.source}")
218
+ end
219
+
220
+ desc "Build cookbook metadata.json from metadata.rb"
221
+ task :metadata => FileList[File.join(TOPDIR, '*cookbooks', ENV['COOKBOOK'] || '*', 'metadata.rb')].pathmap('%X.json')
222
+
223
+ rule(%r{\broles/\S+\.json\Z} => [ proc { |task_name| task_name.sub(/\.[^.]+$/, '.rb') } ]) do |t|
224
+ system("knife role from file #{t.source}")
225
+ end
226
+
227
+ desc "Update roles"
228
+ task :roles => FileList[File.join(TOPDIR, 'roles', '**', '*.rb')].pathmap('%X.json')
229
+
230
+ desc "Update a specific role"
231
+ task :role, :role_name do |t, args|
232
+ system("knife role from file #{File.join(TOPDIR, 'roles', args.role_name)}.rb")
233
+ end
234
+
235
+ desc "Upload all cookbooks"
236
+ task :upload_cookbooks => [ :metadata ]
237
+ task :upload_cookbooks do
238
+ system("knife cookbook upload --all")
239
+ end
240
+
241
+ desc "Upload a single cookbook"
242
+ task :upload_cookbook => [ :metadata ]
243
+ task :upload_cookbook, :cookbook do |t, args|
244
+ system("knife cookbook upload #{args.cookbook}")
245
+ end
246
+
247
+ desc "Test all cookbooks"
248
+ task :test_cookbooks do
249
+ system("knife cookbook test --all")
250
+ end
251
+
252
+ desc "Test a single cookbook"
253
+ task :test_cookbook, :cookbook do |t, args|
254
+ system("knife cookbook test #{args.cookbook}")
255
+ end
256
+