tylerrick-chef 0.10.8

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 (450) 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-expander.conf +8 -0
  10. data/distro/arch/etc/conf.d/chef-server-webui.conf +10 -0
  11. data/distro/arch/etc/conf.d/chef-server.conf +10 -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-expander +78 -0
  15. data/distro/arch/etc/rc.d/chef-server +78 -0
  16. data/distro/arch/etc/rc.d/chef-server-webui +78 -0
  17. data/distro/arch/etc/rc.d/chef-solr +78 -0
  18. data/distro/common/html/chef-client.8.html +146 -0
  19. data/distro/common/html/chef-expander.8.html +164 -0
  20. data/distro/common/html/chef-expanderctl.8.html +146 -0
  21. data/distro/common/html/chef-server-webui.8.html +185 -0
  22. data/distro/common/html/chef-server.8.html +182 -0
  23. data/distro/common/html/chef-solo.8.html +191 -0
  24. data/distro/common/html/chef-solr.8.html +165 -0
  25. data/distro/common/html/knife-bootstrap.1.html +243 -0
  26. data/distro/common/html/knife-client.1.html +219 -0
  27. data/distro/common/html/knife-configure.1.html +170 -0
  28. data/distro/common/html/knife-cookbook-site.1.html +241 -0
  29. data/distro/common/html/knife-cookbook.1.html +384 -0
  30. data/distro/common/html/knife-data-bag.1.html +234 -0
  31. data/distro/common/html/knife-environment.1.html +267 -0
  32. data/distro/common/html/knife-exec.1.html +134 -0
  33. data/distro/common/html/knife-index.1.html +125 -0
  34. data/distro/common/html/knife-node.1.html +250 -0
  35. data/distro/common/html/knife-recipe.1.html +92 -0
  36. data/distro/common/html/knife-role.1.html +200 -0
  37. data/distro/common/html/knife-search.1.html +288 -0
  38. data/distro/common/html/knife-ssh.1.html +157 -0
  39. data/distro/common/html/knife-status.1.html +128 -0
  40. data/distro/common/html/knife-tag.1.html +137 -0
  41. data/distro/common/html/knife.1.html +321 -0
  42. data/distro/common/html/shef.1.html +283 -0
  43. data/distro/common/man/man1/knife-bootstrap.1 +197 -0
  44. data/distro/common/man/man1/knife-client.1 +99 -0
  45. data/distro/common/man/man1/knife-configure.1 +88 -0
  46. data/distro/common/man/man1/knife-cookbook-site.1 +145 -0
  47. data/distro/common/man/man1/knife-cookbook.1 +345 -0
  48. data/distro/common/man/man1/knife-data-bag.1 +130 -0
  49. data/distro/common/man/man1/knife-environment.1 +178 -0
  50. data/distro/common/man/man1/knife-exec.1 +46 -0
  51. data/distro/common/man/man1/knife-index.1 +29 -0
  52. data/distro/common/man/man1/knife-node.1 +134 -0
  53. data/distro/common/man/man1/knife-role.1 +88 -0
  54. data/distro/common/man/man1/knife-search.1 +280 -0
  55. data/distro/common/man/man1/knife-ssh.1 +83 -0
  56. data/distro/common/man/man1/knife-status.1 +29 -0
  57. data/distro/common/man/man1/knife-tag.1 +43 -0
  58. data/distro/common/man/man1/knife.1 +292 -0
  59. data/distro/common/man/man1/shef.1 +256 -0
  60. data/distro/common/man/man8/chef-client.8 +104 -0
  61. data/distro/common/man/man8/chef-expander.8 +97 -0
  62. data/distro/common/man/man8/chef-expanderctl.8 +62 -0
  63. data/distro/common/man/man8/chef-server-webui.8 +155 -0
  64. data/distro/common/man/man8/chef-server.8 +147 -0
  65. data/distro/common/man/man8/chef-solo.8 +158 -0
  66. data/distro/common/man/man8/chef-solr.8 +122 -0
  67. data/distro/common/markdown/README +3 -0
  68. data/distro/common/markdown/man1/knife-bootstrap.mkd +142 -0
  69. data/distro/common/markdown/man1/knife-client.mkd +103 -0
  70. data/distro/common/markdown/man1/knife-configure.mkd +70 -0
  71. data/distro/common/markdown/man1/knife-cookbook-site.mkd +123 -0
  72. data/distro/common/markdown/man1/knife-cookbook.mkd +263 -0
  73. data/distro/common/markdown/man1/knife-data-bag.mkd +117 -0
  74. data/distro/common/markdown/man1/knife-environment.mkd +151 -0
  75. data/distro/common/markdown/man1/knife-exec.mkd +37 -0
  76. data/distro/common/markdown/man1/knife-index.mkd +30 -0
  77. data/distro/common/markdown/man1/knife-node.mkd +130 -0
  78. data/distro/common/markdown/man1/knife-role.mkd +85 -0
  79. data/distro/common/markdown/man1/knife-search.mkd +180 -0
  80. data/distro/common/markdown/man1/knife-ssh.mkd +72 -0
  81. data/distro/common/markdown/man1/knife-status.mkd +36 -0
  82. data/distro/common/markdown/man1/knife-tag.mkd +39 -0
  83. data/distro/common/markdown/man1/knife.mkd +220 -0
  84. data/distro/common/markdown/man1/shef.mkd +189 -0
  85. data/distro/common/markdown/man8/chef-client.mkd +75 -0
  86. data/distro/common/markdown/man8/chef-expander.mkd +82 -0
  87. data/distro/common/markdown/man8/chef-expanderctl.mkd +58 -0
  88. data/distro/common/markdown/man8/chef-server-webui.mkd +121 -0
  89. data/distro/common/markdown/man8/chef-server.mkd +121 -0
  90. data/distro/common/markdown/man8/chef-solo.mkd +107 -0
  91. data/distro/common/markdown/man8/chef-solr.mkd +89 -0
  92. data/distro/debian/etc/default/chef-client +4 -0
  93. data/distro/debian/etc/default/chef-expander +8 -0
  94. data/distro/debian/etc/default/chef-server +9 -0
  95. data/distro/debian/etc/default/chef-server-webui +9 -0
  96. data/distro/debian/etc/default/chef-solr +8 -0
  97. data/distro/debian/etc/init.d/chef-client +185 -0
  98. data/distro/debian/etc/init.d/chef-expander +176 -0
  99. data/distro/debian/etc/init.d/chef-server +122 -0
  100. data/distro/debian/etc/init.d/chef-server-webui +123 -0
  101. data/distro/debian/etc/init.d/chef-solr +176 -0
  102. data/distro/debian/etc/init/chef-client.conf +17 -0
  103. data/distro/debian/etc/init/chef-expander.conf +17 -0
  104. data/distro/debian/etc/init/chef-server-webui.conf +17 -0
  105. data/distro/debian/etc/init/chef-server.conf +17 -0
  106. data/distro/debian/etc/init/chef-solr.conf +17 -0
  107. data/distro/redhat/etc/init.d/chef-client +110 -0
  108. data/distro/redhat/etc/init.d/chef-expander +104 -0
  109. data/distro/redhat/etc/init.d/chef-server +112 -0
  110. data/distro/redhat/etc/init.d/chef-server-webui +112 -0
  111. data/distro/redhat/etc/init.d/chef-solr +104 -0
  112. data/distro/redhat/etc/logrotate.d/chef-client +8 -0
  113. data/distro/redhat/etc/logrotate.d/chef-expander +8 -0
  114. data/distro/redhat/etc/logrotate.d/chef-server +8 -0
  115. data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
  116. data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
  117. data/distro/redhat/etc/sysconfig/chef-client +15 -0
  118. data/distro/redhat/etc/sysconfig/chef-expander +7 -0
  119. data/distro/redhat/etc/sysconfig/chef-server +14 -0
  120. data/distro/redhat/etc/sysconfig/chef-server-webui +14 -0
  121. data/distro/redhat/etc/sysconfig/chef-solr +8 -0
  122. data/lib/chef.rb +41 -0
  123. data/lib/chef/api_client.rb +271 -0
  124. data/lib/chef/application.rb +152 -0
  125. data/lib/chef/application/agent.rb +18 -0
  126. data/lib/chef/application/client.rb +285 -0
  127. data/lib/chef/application/knife.rb +188 -0
  128. data/lib/chef/application/solo.rb +218 -0
  129. data/lib/chef/applications.rb +4 -0
  130. data/lib/chef/certificate.rb +194 -0
  131. data/lib/chef/checksum.rb +167 -0
  132. data/lib/chef/checksum/storage.rb +18 -0
  133. data/lib/chef/checksum/storage/filesystem.rb +56 -0
  134. data/lib/chef/checksum_cache.rb +189 -0
  135. data/lib/chef/client.rb +366 -0
  136. data/lib/chef/config.rb +248 -0
  137. data/lib/chef/cookbook/chefignore.rb +66 -0
  138. data/lib/chef/cookbook/cookbook_collection.rb +45 -0
  139. data/lib/chef/cookbook/cookbook_version_loader.rb +173 -0
  140. data/lib/chef/cookbook/file_system_file_vendor.rb +56 -0
  141. data/lib/chef/cookbook/file_vendor.rb +48 -0
  142. data/lib/chef/cookbook/metadata.rb +629 -0
  143. data/lib/chef/cookbook/remote_file_vendor.rb +88 -0
  144. data/lib/chef/cookbook/syntax_check.rb +136 -0
  145. data/lib/chef/cookbook_loader.rb +121 -0
  146. data/lib/chef/cookbook_site_streaming_uploader.rb +244 -0
  147. data/lib/chef/cookbook_uploader.rb +154 -0
  148. data/lib/chef/cookbook_version.rb +1096 -0
  149. data/lib/chef/cookbook_version_selector.rb +168 -0
  150. data/lib/chef/couchdb.rb +246 -0
  151. data/lib/chef/daemon.rb +172 -0
  152. data/lib/chef/data_bag.rb +235 -0
  153. data/lib/chef/data_bag_item.rb +273 -0
  154. data/lib/chef/encrypted_data_bag_item.rb +139 -0
  155. data/lib/chef/environment.rb +455 -0
  156. data/lib/chef/exceptions.rb +154 -0
  157. data/lib/chef/file_access_control.rb +144 -0
  158. data/lib/chef/file_cache.rb +218 -0
  159. data/lib/chef/handler.rb +227 -0
  160. data/lib/chef/handler/error_report.rb +33 -0
  161. data/lib/chef/handler/json_file.rb +58 -0
  162. data/lib/chef/index_queue.rb +29 -0
  163. data/lib/chef/index_queue/amqp_client.rb +116 -0
  164. data/lib/chef/index_queue/consumer.rb +76 -0
  165. data/lib/chef/index_queue/indexable.rb +109 -0
  166. data/lib/chef/json_compat.rb +52 -0
  167. data/lib/chef/knife.rb +520 -0
  168. data/lib/chef/knife/bootstrap.rb +207 -0
  169. data/lib/chef/knife/bootstrap/archlinux-gems.erb +60 -0
  170. data/lib/chef/knife/bootstrap/centos5-gems.erb +56 -0
  171. data/lib/chef/knife/bootstrap/fedora13-gems.erb +43 -0
  172. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +49 -0
  173. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +50 -0
  174. data/lib/chef/knife/client_bulk_delete.rb +65 -0
  175. data/lib/chef/knife/client_create.rb +79 -0
  176. data/lib/chef/knife/client_delete.rb +46 -0
  177. data/lib/chef/knife/client_edit.rb +45 -0
  178. data/lib/chef/knife/client_list.rb +42 -0
  179. data/lib/chef/knife/client_reregister.rb +58 -0
  180. data/lib/chef/knife/client_show.rb +52 -0
  181. data/lib/chef/knife/configure.rb +149 -0
  182. data/lib/chef/knife/configure_client.rb +50 -0
  183. data/lib/chef/knife/cookbook_bulk_delete.rb +72 -0
  184. data/lib/chef/knife/cookbook_create.rb +274 -0
  185. data/lib/chef/knife/cookbook_delete.rb +151 -0
  186. data/lib/chef/knife/cookbook_download.rb +137 -0
  187. data/lib/chef/knife/cookbook_list.rb +47 -0
  188. data/lib/chef/knife/cookbook_metadata.rb +107 -0
  189. data/lib/chef/knife/cookbook_metadata_from_file.rb +44 -0
  190. data/lib/chef/knife/cookbook_show.rb +102 -0
  191. data/lib/chef/knife/cookbook_site_download.rb +70 -0
  192. data/lib/chef/knife/cookbook_site_install.rb +148 -0
  193. data/lib/chef/knife/cookbook_site_list.rb +62 -0
  194. data/lib/chef/knife/cookbook_site_search.rb +51 -0
  195. data/lib/chef/knife/cookbook_site_share.rb +114 -0
  196. data/lib/chef/knife/cookbook_site_show.rb +57 -0
  197. data/lib/chef/knife/cookbook_site_unshare.rb +56 -0
  198. data/lib/chef/knife/cookbook_site_vendor.rb +46 -0
  199. data/lib/chef/knife/cookbook_test.rb +93 -0
  200. data/lib/chef/knife/cookbook_upload.rb +240 -0
  201. data/lib/chef/knife/core/bootstrap_context.rb +100 -0
  202. data/lib/chef/knife/core/cookbook_scm_repo.rb +148 -0
  203. data/lib/chef/knife/core/generic_presenter.rb +191 -0
  204. data/lib/chef/knife/core/node_editor.rb +127 -0
  205. data/lib/chef/knife/core/node_presenter.rb +136 -0
  206. data/lib/chef/knife/core/object_loader.rb +75 -0
  207. data/lib/chef/knife/core/subcommand_loader.rb +112 -0
  208. data/lib/chef/knife/core/text_formatter.rb +100 -0
  209. data/lib/chef/knife/core/ui.rb +216 -0
  210. data/lib/chef/knife/data_bag_create.rb +93 -0
  211. data/lib/chef/knife/data_bag_delete.rb +51 -0
  212. data/lib/chef/knife/data_bag_edit.rb +94 -0
  213. data/lib/chef/knife/data_bag_from_file.rb +87 -0
  214. data/lib/chef/knife/data_bag_list.rb +46 -0
  215. data/lib/chef/knife/data_bag_show.rb +81 -0
  216. data/lib/chef/knife/environment_create.rb +53 -0
  217. data/lib/chef/knife/environment_delete.rb +45 -0
  218. data/lib/chef/knife/environment_edit.rb +45 -0
  219. data/lib/chef/knife/environment_from_file.rb +50 -0
  220. data/lib/chef/knife/environment_list.rb +42 -0
  221. data/lib/chef/knife/environment_show.rb +46 -0
  222. data/lib/chef/knife/exec.rb +51 -0
  223. data/lib/chef/knife/help.rb +103 -0
  224. data/lib/chef/knife/help_topics.rb +4 -0
  225. data/lib/chef/knife/index_rebuild.rb +50 -0
  226. data/lib/chef/knife/node_bulk_delete.rb +80 -0
  227. data/lib/chef/knife/node_create.rb +50 -0
  228. data/lib/chef/knife/node_delete.rb +47 -0
  229. data/lib/chef/knife/node_edit.rb +72 -0
  230. data/lib/chef/knife/node_from_file.rb +50 -0
  231. data/lib/chef/knife/node_list.rb +46 -0
  232. data/lib/chef/knife/node_run_list_add.rb +67 -0
  233. data/lib/chef/knife/node_run_list_remove.rb +48 -0
  234. data/lib/chef/knife/node_show.rb +73 -0
  235. data/lib/chef/knife/recipe_list.rb +32 -0
  236. data/lib/chef/knife/role_bulk_delete.rb +70 -0
  237. data/lib/chef/knife/role_create.rb +55 -0
  238. data/lib/chef/knife/role_delete.rb +47 -0
  239. data/lib/chef/knife/role_edit.rb +48 -0
  240. data/lib/chef/knife/role_from_file.rb +56 -0
  241. data/lib/chef/knife/role_list.rb +43 -0
  242. data/lib/chef/knife/role_show.rb +54 -0
  243. data/lib/chef/knife/search.rb +141 -0
  244. data/lib/chef/knife/ssh.rb +367 -0
  245. data/lib/chef/knife/status.rb +104 -0
  246. data/lib/chef/knife/tag_create.rb +52 -0
  247. data/lib/chef/knife/tag_delete.rb +60 -0
  248. data/lib/chef/knife/tag_list.rb +47 -0
  249. data/lib/chef/log.rb +39 -0
  250. data/lib/chef/mash.rb +211 -0
  251. data/lib/chef/mixin/check_helper.rb +31 -0
  252. data/lib/chef/mixin/checksum.rb +32 -0
  253. data/lib/chef/mixin/command.rb +163 -0
  254. data/lib/chef/mixin/command/unix.rb +215 -0
  255. data/lib/chef/mixin/command/windows.rb +76 -0
  256. data/lib/chef/mixin/convert_to_class_name.rb +63 -0
  257. data/lib/chef/mixin/create_path.rb +57 -0
  258. data/lib/chef/mixin/deep_merge.rb +225 -0
  259. data/lib/chef/mixin/deprecation.rb +65 -0
  260. data/lib/chef/mixin/from_file.rb +50 -0
  261. data/lib/chef/mixin/get_source_from_package.rb +42 -0
  262. data/lib/chef/mixin/language.rb +163 -0
  263. data/lib/chef/mixin/language_include_attribute.rb +61 -0
  264. data/lib/chef/mixin/language_include_recipe.rb +52 -0
  265. data/lib/chef/mixin/params_validate.rb +225 -0
  266. data/lib/chef/mixin/recipe_definition_dsl_core.rb +78 -0
  267. data/lib/chef/mixin/shell_out.rb +41 -0
  268. data/lib/chef/mixin/template.rb +95 -0
  269. data/lib/chef/mixin/xml_escape.rb +140 -0
  270. data/lib/chef/mixins.rb +15 -0
  271. data/lib/chef/monkey_patches/dir.rb +36 -0
  272. data/lib/chef/monkey_patches/numeric.rb +15 -0
  273. data/lib/chef/monkey_patches/object.rb +9 -0
  274. data/lib/chef/monkey_patches/regexp.rb +34 -0
  275. data/lib/chef/monkey_patches/string.rb +49 -0
  276. data/lib/chef/monkey_patches/tempfile.rb +64 -0
  277. data/lib/chef/nil_argument.rb +3 -0
  278. data/lib/chef/node.rb +677 -0
  279. data/lib/chef/node/attribute.rb +487 -0
  280. data/lib/chef/openid_registration.rb +187 -0
  281. data/lib/chef/platform.rb +434 -0
  282. data/lib/chef/provider.rb +124 -0
  283. data/lib/chef/provider/breakpoint.rb +36 -0
  284. data/lib/chef/provider/cookbook_file.rb +100 -0
  285. data/lib/chef/provider/cron.rb +186 -0
  286. data/lib/chef/provider/cron/solaris.rb +195 -0
  287. data/lib/chef/provider/deploy.rb +418 -0
  288. data/lib/chef/provider/deploy/revision.rb +80 -0
  289. data/lib/chef/provider/deploy/timestamped.rb +33 -0
  290. data/lib/chef/provider/directory.rb +72 -0
  291. data/lib/chef/provider/env.rb +152 -0
  292. data/lib/chef/provider/env/windows.rb +75 -0
  293. data/lib/chef/provider/erl_call.rb +101 -0
  294. data/lib/chef/provider/execute.rb +65 -0
  295. data/lib/chef/provider/file.rb +226 -0
  296. data/lib/chef/provider/git.rb +243 -0
  297. data/lib/chef/provider/group.rb +133 -0
  298. data/lib/chef/provider/group/aix.rb +70 -0
  299. data/lib/chef/provider/group/dscl.rb +121 -0
  300. data/lib/chef/provider/group/gpasswd.rb +53 -0
  301. data/lib/chef/provider/group/groupadd.rb +91 -0
  302. data/lib/chef/provider/group/pw.rb +84 -0
  303. data/lib/chef/provider/group/suse.rb +53 -0
  304. data/lib/chef/provider/group/usermod.rb +57 -0
  305. data/lib/chef/provider/group/windows.rb +79 -0
  306. data/lib/chef/provider/http_request.rb +122 -0
  307. data/lib/chef/provider/ifconfig.rb +195 -0
  308. data/lib/chef/provider/link.rb +164 -0
  309. data/lib/chef/provider/log.rb +54 -0
  310. data/lib/chef/provider/mdadm.rb +91 -0
  311. data/lib/chef/provider/mount.rb +114 -0
  312. data/lib/chef/provider/mount/mount.rb +240 -0
  313. data/lib/chef/provider/mount/windows.rb +81 -0
  314. data/lib/chef/provider/ohai.rb +42 -0
  315. data/lib/chef/provider/package.rb +200 -0
  316. data/lib/chef/provider/package/apt.rb +145 -0
  317. data/lib/chef/provider/package/dpkg.rb +115 -0
  318. data/lib/chef/provider/package/easy_install.rb +136 -0
  319. data/lib/chef/provider/package/freebsd.rb +125 -0
  320. data/lib/chef/provider/package/macports.rb +105 -0
  321. data/lib/chef/provider/package/pacman.rb +101 -0
  322. data/lib/chef/provider/package/portage.rb +135 -0
  323. data/lib/chef/provider/package/rpm.rb +104 -0
  324. data/lib/chef/provider/package/rubygems.rb +465 -0
  325. data/lib/chef/provider/package/solaris.rb +130 -0
  326. data/lib/chef/provider/package/yum-dump.py +286 -0
  327. data/lib/chef/provider/package/yum.rb +1173 -0
  328. data/lib/chef/provider/package/zypper.rb +144 -0
  329. data/lib/chef/provider/remote_directory.rb +137 -0
  330. data/lib/chef/provider/remote_file.rb +118 -0
  331. data/lib/chef/provider/route.rb +193 -0
  332. data/lib/chef/provider/ruby_block.rb +34 -0
  333. data/lib/chef/provider/script.rb +55 -0
  334. data/lib/chef/provider/service.rb +122 -0
  335. data/lib/chef/provider/service/arch.rb +116 -0
  336. data/lib/chef/provider/service/debian.rb +130 -0
  337. data/lib/chef/provider/service/freebsd.rb +154 -0
  338. data/lib/chef/provider/service/gentoo.rb +53 -0
  339. data/lib/chef/provider/service/init.rb +71 -0
  340. data/lib/chef/provider/service/insserv.rb +52 -0
  341. data/lib/chef/provider/service/invokercd.rb +35 -0
  342. data/lib/chef/provider/service/redhat.rb +60 -0
  343. data/lib/chef/provider/service/simple.rb +120 -0
  344. data/lib/chef/provider/service/solaris.rb +85 -0
  345. data/lib/chef/provider/service/systemd.rb +102 -0
  346. data/lib/chef/provider/service/upstart.rb +198 -0
  347. data/lib/chef/provider/service/windows.rb +155 -0
  348. data/lib/chef/provider/subversion.rb +197 -0
  349. data/lib/chef/provider/template.rb +104 -0
  350. data/lib/chef/provider/user.rb +186 -0
  351. data/lib/chef/provider/user/dscl.rb +280 -0
  352. data/lib/chef/provider/user/pw.rb +113 -0
  353. data/lib/chef/provider/user/useradd.rb +137 -0
  354. data/lib/chef/provider/user/windows.rb +124 -0
  355. data/lib/chef/providers.rb +95 -0
  356. data/lib/chef/recipe.rb +129 -0
  357. data/lib/chef/resource.rb +609 -0
  358. data/lib/chef/resource/apt_package.rb +34 -0
  359. data/lib/chef/resource/bash.rb +33 -0
  360. data/lib/chef/resource/breakpoint.rb +35 -0
  361. data/lib/chef/resource/conditional.rb +90 -0
  362. data/lib/chef/resource/cookbook_file.rb +45 -0
  363. data/lib/chef/resource/cron.rb +188 -0
  364. data/lib/chef/resource/csh.rb +33 -0
  365. data/lib/chef/resource/deploy.rb +389 -0
  366. data/lib/chef/resource/deploy_revision.rb +40 -0
  367. data/lib/chef/resource/directory.rb +76 -0
  368. data/lib/chef/resource/dpkg_package.rb +34 -0
  369. data/lib/chef/resource/easy_install_package.rb +57 -0
  370. data/lib/chef/resource/env.rb +58 -0
  371. data/lib/chef/resource/erl_call.rb +83 -0
  372. data/lib/chef/resource/execute.rb +127 -0
  373. data/lib/chef/resource/file.rb +99 -0
  374. data/lib/chef/resource/freebsd_package.rb +35 -0
  375. data/lib/chef/resource/gem_package.rb +53 -0
  376. data/lib/chef/resource/git.rb +46 -0
  377. data/lib/chef/resource/group.rb +78 -0
  378. data/lib/chef/resource/http_request.rb +61 -0
  379. data/lib/chef/resource/ifconfig.rb +144 -0
  380. data/lib/chef/resource/link.rb +78 -0
  381. data/lib/chef/resource/log.rb +62 -0
  382. data/lib/chef/resource/macports_package.rb +29 -0
  383. data/lib/chef/resource/mdadm.rb +82 -0
  384. data/lib/chef/resource/mount.rb +134 -0
  385. data/lib/chef/resource/ohai.rb +40 -0
  386. data/lib/chef/resource/package.rb +80 -0
  387. data/lib/chef/resource/pacman_package.rb +33 -0
  388. data/lib/chef/resource/perl.rb +33 -0
  389. data/lib/chef/resource/portage_package.rb +33 -0
  390. data/lib/chef/resource/python.rb +33 -0
  391. data/lib/chef/resource/remote_directory.rb +109 -0
  392. data/lib/chef/resource/remote_file.rb +83 -0
  393. data/lib/chef/resource/route.rb +135 -0
  394. data/lib/chef/resource/rpm_package.rb +34 -0
  395. data/lib/chef/resource/ruby.rb +33 -0
  396. data/lib/chef/resource/ruby_block.rb +40 -0
  397. data/lib/chef/resource/scm.rb +147 -0
  398. data/lib/chef/resource/script.rb +60 -0
  399. data/lib/chef/resource/service.rb +151 -0
  400. data/lib/chef/resource/solaris_package.rb +36 -0
  401. data/lib/chef/resource/subversion.rb +36 -0
  402. data/lib/chef/resource/template.rb +69 -0
  403. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  404. data/lib/chef/resource/user.rb +130 -0
  405. data/lib/chef/resource/yum_package.rb +63 -0
  406. data/lib/chef/resource_collection.rb +217 -0
  407. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  408. data/lib/chef/resource_definition.rb +67 -0
  409. data/lib/chef/resource_definition_list.rb +38 -0
  410. data/lib/chef/resources.rb +64 -0
  411. data/lib/chef/rest.rb +400 -0
  412. data/lib/chef/rest/auth_credentials.rb +71 -0
  413. data/lib/chef/rest/cookie_jar.rb +31 -0
  414. data/lib/chef/rest/rest_request.rb +213 -0
  415. data/lib/chef/role.rb +343 -0
  416. data/lib/chef/run_context.rb +126 -0
  417. data/lib/chef/run_list.rb +165 -0
  418. data/lib/chef/run_list/run_list_expansion.rb +193 -0
  419. data/lib/chef/run_list/run_list_item.rb +92 -0
  420. data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
  421. data/lib/chef/run_status.rb +121 -0
  422. data/lib/chef/runner.rb +105 -0
  423. data/lib/chef/sandbox.rb +153 -0
  424. data/lib/chef/search/query.rb +65 -0
  425. data/lib/chef/shef.rb +327 -0
  426. data/lib/chef/shef/ext.rb +569 -0
  427. data/lib/chef/shef/model_wrapper.rb +120 -0
  428. data/lib/chef/shef/shef_rest.rb +28 -0
  429. data/lib/chef/shef/shef_session.rb +285 -0
  430. data/lib/chef/shell_out.rb +249 -0
  431. data/lib/chef/shell_out/unix.rb +223 -0
  432. data/lib/chef/shell_out/windows.rb +588 -0
  433. data/lib/chef/solr_query.rb +187 -0
  434. data/lib/chef/solr_query/lucene.treetop +150 -0
  435. data/lib/chef/solr_query/lucene_nodes.rb +285 -0
  436. data/lib/chef/solr_query/query_transform.rb +65 -0
  437. data/lib/chef/solr_query/solr_http_request.rb +132 -0
  438. data/lib/chef/streaming_cookbook_uploader.rb +201 -0
  439. data/lib/chef/tasks/chef_repo.rake +334 -0
  440. data/lib/chef/util/file_edit.rb +122 -0
  441. data/lib/chef/util/windows.rb +56 -0
  442. data/lib/chef/util/windows/net_group.rb +101 -0
  443. data/lib/chef/util/windows/net_use.rb +121 -0
  444. data/lib/chef/util/windows/net_user.rb +198 -0
  445. data/lib/chef/util/windows/volume.rb +59 -0
  446. data/lib/chef/version.rb +23 -0
  447. data/lib/chef/version_class.rb +70 -0
  448. data/lib/chef/version_constraint.rb +116 -0
  449. data/lib/chef/webui_user.rb +231 -0
  450. metadata +764 -0
@@ -0,0 +1,223 @@
1
+ class Chef
2
+ class ShellOut
3
+ module Unix
4
+
5
+ # Run the command, writing the command's standard out and standard error
6
+ # to +stdout+ and +stderr+, and saving its exit status object to +status+
7
+ # === Returns
8
+ # returns +self+; +stdout+, +stderr+, +status+, and +exitstatus+ will be
9
+ # populated with results of the command
10
+ # === Raises
11
+ # * Errno::EACCES when you are not privileged to execute the command
12
+ # * Errno::ENOENT when the command is not available on the system (or not
13
+ # in the current $PATH)
14
+ # * Chef::Exceptions::CommandTimeout when the command does not complete
15
+ # within +timeout+ seconds (default: 60s)
16
+ def run_command
17
+ @child_pid = fork_subprocess
18
+
19
+ configure_parent_process_file_descriptors
20
+ propagate_pre_exec_failure
21
+
22
+ @result = nil
23
+ @execution_time = 0
24
+
25
+ # Ruby 1.8.7 and 1.8.6 from mid 2009 try to allocate objects during GC
26
+ # when calling IO.select and IO#read. Some OS Vendors are not interested
27
+ # in updating their ruby packages (Apple, *cough*) and we *have to*
28
+ # make it work. So I give you this epic hack:
29
+ GC.disable
30
+ until @status
31
+ ready = IO.select(open_pipes, nil, nil, READ_WAIT_TIME)
32
+ unless ready
33
+ @execution_time += READ_WAIT_TIME
34
+ if @execution_time >= timeout && !@result
35
+ raise Chef::Exceptions::CommandTimeout, "command timed out:\n#{format_for_exception}"
36
+ end
37
+ end
38
+
39
+ if ready && ready.first.include?(child_stdout)
40
+ read_stdout_to_buffer
41
+ end
42
+ if ready && ready.first.include?(child_stderr)
43
+ read_stderr_to_buffer
44
+ end
45
+
46
+ unless @status
47
+ # make one more pass to get the last of the output after the
48
+ # child process dies
49
+ if results = Process.waitpid2(@child_pid, Process::WNOHANG)
50
+ @status = results.last
51
+ redo
52
+ end
53
+ end
54
+ end
55
+ self
56
+ rescue Exception
57
+ # do our best to kill zombies
58
+ Process.waitpid2(@child_pid, Process::WNOHANG) rescue nil
59
+ raise
60
+ ensure
61
+ # no matter what happens, turn the GC back on, and hope whatever busted
62
+ # version of ruby we're on doesn't allocate some objects during the next
63
+ # GC run.
64
+ GC.enable
65
+ close_all_pipes
66
+ end
67
+
68
+ private
69
+
70
+ def set_user
71
+ if user
72
+ Process.euid = uid
73
+ Process.uid = uid
74
+ end
75
+ end
76
+
77
+ def set_group
78
+ if group
79
+ Process.egid = gid
80
+ Process.gid = gid
81
+ end
82
+ end
83
+
84
+ def set_environment
85
+ environment.each do |env_var,value|
86
+ ENV[env_var] = value
87
+ end
88
+ end
89
+
90
+ def set_umask
91
+ File.umask(umask) if umask
92
+ end
93
+
94
+ def set_cwd
95
+ Dir.chdir(cwd) if cwd
96
+ end
97
+
98
+ def initialize_ipc
99
+ @stdout_pipe, @stderr_pipe, @process_status_pipe = IO.pipe, IO.pipe, IO.pipe
100
+ @process_status_pipe.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
101
+ end
102
+
103
+ def child_stdout
104
+ @stdout_pipe[0]
105
+ end
106
+
107
+ def child_stderr
108
+ @stderr_pipe[0]
109
+ end
110
+
111
+ def child_process_status
112
+ @process_status_pipe[0]
113
+ end
114
+
115
+ def close_all_pipes
116
+ child_stdout.close unless child_stdout.closed?
117
+ child_stderr.close unless child_stderr.closed?
118
+ child_process_status.close unless child_process_status.closed?
119
+ end
120
+
121
+ # replace stdout, and stderr with pipes to the parent, and close the
122
+ # reader side of the error marshaling side channel. Close STDIN so when we
123
+ # exec, the new program will know it's never getting input ever.
124
+ def configure_subprocess_file_descriptors
125
+ process_status_pipe.first.close
126
+
127
+ # HACK: for some reason, just STDIN.close isn't good enough when running
128
+ # under ruby 1.9.2, so make it good enough:
129
+ stdin_reader, stdin_writer = IO.pipe
130
+ stdin_writer.close
131
+ STDIN.reopen stdin_reader
132
+ stdin_reader.close
133
+
134
+ stdout_pipe.first.close
135
+ STDOUT.reopen stdout_pipe.last
136
+ stdout_pipe.last.close
137
+
138
+ stderr_pipe.first.close
139
+ STDERR.reopen stderr_pipe.last
140
+ stderr_pipe.last.close
141
+
142
+ STDOUT.sync = STDERR.sync = true
143
+ end
144
+
145
+ def configure_parent_process_file_descriptors
146
+ # Close the sides of the pipes we don't care about
147
+ stdout_pipe.last.close
148
+ stderr_pipe.last.close
149
+ process_status_pipe.last.close
150
+ # Get output as it happens rather than buffered
151
+ child_stdout.sync = true
152
+ child_stderr.sync = true
153
+
154
+ true
155
+ end
156
+
157
+ # Some patch levels of ruby in wide use (in particular the ruby 1.8.6 on OSX)
158
+ # segfault when you IO.select a pipe that's reached eof. Weak sauce.
159
+ def open_pipes
160
+ @open_pipes ||= [child_stdout, child_stderr]
161
+ end
162
+
163
+ def read_stdout_to_buffer
164
+ while chunk = child_stdout.read_nonblock(READ_SIZE)
165
+ @stdout << chunk
166
+ @live_stream << chunk if @live_stream
167
+ end
168
+ rescue Errno::EAGAIN
169
+ rescue EOFError
170
+ open_pipes.delete_at(0)
171
+ end
172
+
173
+ def read_stderr_to_buffer
174
+ while chunk = child_stderr.read_nonblock(READ_SIZE)
175
+ @stderr << chunk
176
+ end
177
+ rescue Errno::EAGAIN
178
+ rescue EOFError
179
+ open_pipes.delete_at(1)
180
+ end
181
+
182
+ def fork_subprocess
183
+ initialize_ipc
184
+
185
+ fork do
186
+ configure_subprocess_file_descriptors
187
+
188
+ set_group
189
+ set_user
190
+ set_environment
191
+ set_umask
192
+ set_cwd
193
+
194
+ begin
195
+ command.kind_of?(Array) ? exec(*command) : exec(command)
196
+
197
+ raise 'forty-two' # Should never get here
198
+ rescue Exception => e
199
+ Marshal.dump(e, process_status_pipe.last)
200
+ process_status_pipe.last.flush
201
+ end
202
+ process_status_pipe.last.close unless (process_status_pipe.last.closed?)
203
+ exit!
204
+ end
205
+ end
206
+
207
+ # Attempt to get a Marshaled error from the side-channel.
208
+ # If it's there, un-marshal it and raise. If it's not there,
209
+ # assume everything went well.
210
+ def propagate_pre_exec_failure
211
+ begin
212
+ e = Marshal.load child_process_status
213
+ raise(Exception === e ? e : "unknown failure: #{e.inspect}")
214
+ rescue EOFError # If we get an EOF error, then the exec was successful
215
+ true
216
+ ensure
217
+ child_process_status.close
218
+ end
219
+ end
220
+
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,588 @@
1
+ #--
2
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
3
+ # Author:: John Keiser (<jkeiser@opscode.com>)
4
+ # Copyright:: Copyright (c) 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 'win32/process'
21
+ require 'windows/handle'
22
+ require 'windows/process'
23
+ require 'windows/synchronize'
24
+
25
+ class Chef
26
+ class ShellOut
27
+ module Windows
28
+
29
+ include ::Windows::Handle
30
+ include ::Windows::Process
31
+ include ::Windows::Synchronize
32
+
33
+ TIME_SLICE = 0.05
34
+
35
+ #--
36
+ # Missing lots of features from the UNIX version, such as
37
+ # uid, etc.
38
+ def run_command
39
+
40
+ #
41
+ # Create pipes to capture stdout and stderr,
42
+ #
43
+ stdout_read, stdout_write = IO.pipe
44
+ stderr_read, stderr_write = IO.pipe
45
+ stdin_read, stdin_write = IO.pipe
46
+ open_streams = [ stdout_read, stderr_read ]
47
+
48
+ begin
49
+
50
+ #
51
+ # Set cwd, environment, appname, etc.
52
+ #
53
+ app_name, command_line = command_to_run
54
+ create_process_args = {
55
+ :app_name => app_name,
56
+ :command_line => command_line,
57
+ :startup_info => {
58
+ :stdout => stdout_write,
59
+ :stderr => stderr_write,
60
+ :stdin => stdin_read
61
+ },
62
+ :environment => inherit_environment.map { |k,v| "#{k}=#{v}" },
63
+ :close_handles => false
64
+ }
65
+ create_process_args[:cwd] = cwd if cwd
66
+
67
+ #
68
+ # Start the process
69
+ #
70
+ process = Process.create(create_process_args)
71
+ begin
72
+
73
+ #
74
+ # Wait for the process to finish, consuming output as we go
75
+ #
76
+ start_wait = Time.now
77
+ while true
78
+ wait_status = WaitForSingleObject(process.process_handle, 0)
79
+ case wait_status
80
+ when WAIT_OBJECT_0
81
+ # Get process exit code
82
+ exit_code = [0].pack('l')
83
+ unless GetExitCodeProcess(process.process_handle, exit_code)
84
+ raise get_last_error
85
+ end
86
+ @status = ThingThatLooksSortOfLikeAProcessStatus.new
87
+ @status.exitstatus = exit_code.unpack('l').first
88
+
89
+ return self
90
+ when WAIT_TIMEOUT
91
+ # Kill the process
92
+ if (Time.now - start_wait) > timeout
93
+ raise Chef::Exceptions::CommandTimeout, "command timed out:\n#{format_for_exception}"
94
+ end
95
+
96
+ consume_output(open_streams, stdout_read, stderr_read)
97
+ else
98
+ raise "Unknown response from WaitForSingleObject(#{process.process_handle}, #{timeout*1000}): #{wait_status}"
99
+ end
100
+
101
+ end
102
+
103
+ ensure
104
+ CloseHandle(process.thread_handle)
105
+ CloseHandle(process.process_handle)
106
+ end
107
+
108
+ ensure
109
+ #
110
+ # Consume all remaining data from the pipes until they are closed
111
+ #
112
+ stdout_write.close
113
+ stderr_write.close
114
+
115
+ while consume_output(open_streams, stdout_read, stderr_read)
116
+ end
117
+ end
118
+ end
119
+
120
+ private
121
+
122
+ class ThingThatLooksSortOfLikeAProcessStatus
123
+ attr_accessor :exitstatus
124
+ def success?
125
+ exitstatus == 0
126
+ end
127
+ end
128
+
129
+ def consume_output(open_streams, stdout_read, stderr_read)
130
+ return false if open_streams.length == 0
131
+ ready = IO.select(open_streams, nil, nil, READ_WAIT_TIME)
132
+ return true if ! ready
133
+
134
+ if ready.first.include?(stdout_read)
135
+ begin
136
+ next_chunk = stdout_read.readpartial(READ_SIZE)
137
+ @stdout << next_chunk
138
+ @live_stream << next_chunk if @live_stream
139
+ rescue EOFError
140
+ stdout_read.close
141
+ open_streams.delete(stdout_read)
142
+ end
143
+ end
144
+
145
+ if ready.first.include?(stderr_read)
146
+ begin
147
+ @stderr << stderr_read.readpartial(READ_SIZE)
148
+ rescue EOFError
149
+ stderr_read.close
150
+ open_streams.delete(stderr_read)
151
+ end
152
+ end
153
+
154
+ return true
155
+ end
156
+
157
+ IS_BATCH_FILE = /\.bat|\.cmd$/i
158
+
159
+ def command_to_run
160
+ if command =~ /^\s*"(.*)"/
161
+ # If we have quotes, do an exact match
162
+ candidate = $1
163
+ else
164
+ # Otherwise check everything up to the first space
165
+ candidate = command[0,command.index(/\s/) || command.length].strip
166
+ end
167
+
168
+ # Don't do searching for empty commands. Let it fail when it runs.
169
+ if candidate.length == 0
170
+ return [ nil, command ]
171
+ end
172
+
173
+ # Check if the exe exists directly. Otherwise, search PATH.
174
+ exe = find_exe_at_location(candidate)
175
+ if exe.nil? && exe !~ /[\\\/]/
176
+ exe = which(command[0,command.index(/\s/) || command.length])
177
+ end
178
+
179
+ if exe.nil? || exe =~ IS_BATCH_FILE
180
+ # Batch files MUST use cmd; and if we couldn't find the command we're looking for, we assume it must be a cmd builtin.
181
+ [ ENV['COMSPEC'], "cmd /c #{command}" ]
182
+ else
183
+ [ exe, command ]
184
+ end
185
+ end
186
+
187
+ def inherit_environment
188
+ result = {}
189
+ ENV.each_pair do |k,v|
190
+ result[k] = v
191
+ end
192
+
193
+ environment.each_pair do |k,v|
194
+ if v == nil
195
+ result.delete(k)
196
+ else
197
+ result[k] = v
198
+ end
199
+ end
200
+ result
201
+ end
202
+
203
+ def pathext
204
+ @pathext ||= ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') + [''] : ['']
205
+ end
206
+
207
+ def which(cmd)
208
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
209
+ exe = find_exe_at_location("#{path}/${cmd}")
210
+ return exe if exe
211
+ end
212
+ return nil
213
+ end
214
+
215
+ def find_exe_at_location(path)
216
+ return path if File.executable? path
217
+ pathext.each do |ext|
218
+ exe = "#{path}#{ext}"
219
+ return exe if File.executable? exe
220
+ end
221
+ return nil
222
+ end
223
+ end # class
224
+ end
225
+ end
226
+
227
+ #
228
+ # Override module Windows::Process.CreateProcess to fix bug when
229
+ # using both app_name and command_line
230
+ #
231
+ module Windows
232
+ module Process
233
+ API.new('CreateProcess', 'SPPPLLLPPP', 'B')
234
+ end
235
+ end
236
+
237
+ #
238
+ # Override Win32::Process.create to take a proper environment hash
239
+ # so that variables can contain semicolons
240
+ # (submitted patch to owner)
241
+ #
242
+ module Process
243
+ def create(args)
244
+ unless args.kind_of?(Hash)
245
+ raise TypeError, 'Expecting hash-style keyword arguments'
246
+ end
247
+
248
+ valid_keys = %w/
249
+ app_name command_line inherit creation_flags cwd environment
250
+ startup_info thread_inherit process_inherit close_handles with_logon
251
+ domain password
252
+ /
253
+
254
+ valid_si_keys = %/
255
+ startf_flags desktop title x y x_size y_size x_count_chars
256
+ y_count_chars fill_attribute sw_flags stdin stdout stderr
257
+ /
258
+
259
+ # Set default values
260
+ hash = {
261
+ 'app_name' => nil,
262
+ 'creation_flags' => 0,
263
+ 'close_handles' => true
264
+ }
265
+
266
+ # Validate the keys, and convert symbols and case to lowercase strings.
267
+ args.each{ |key, val|
268
+ key = key.to_s.downcase
269
+ unless valid_keys.include?(key)
270
+ raise ArgumentError, "invalid key '#{key}'"
271
+ end
272
+ hash[key] = val
273
+ }
274
+
275
+ si_hash = {}
276
+
277
+ # If the startup_info key is present, validate its subkeys
278
+ if hash['startup_info']
279
+ hash['startup_info'].each{ |key, val|
280
+ key = key.to_s.downcase
281
+ unless valid_si_keys.include?(key)
282
+ raise ArgumentError, "invalid startup_info key '#{key}'"
283
+ end
284
+ si_hash[key] = val
285
+ }
286
+ end
287
+
288
+ # The +command_line+ key is mandatory unless the +app_name+ key
289
+ # is specified.
290
+ unless hash['command_line']
291
+ if hash['app_name']
292
+ hash['command_line'] = hash['app_name']
293
+ hash['app_name'] = nil
294
+ else
295
+ raise ArgumentError, 'command_line or app_name must be specified'
296
+ end
297
+ end
298
+
299
+ # The environment string should be passed as an array of A=B paths, or
300
+ # as a string of ';' separated paths.
301
+ if hash['environment']
302
+ env = hash['environment']
303
+ if !env.respond_to?(:join)
304
+ # Backwards compat for ; separated paths
305
+ env = hash['environment'].split(File::PATH_SEPARATOR)
306
+ end
307
+ # The argument format is a series of null-terminated strings, with an additional null terminator.
308
+ env = env.map { |e| e + "\0" }.join("") + "\0"
309
+ if hash['with_logon']
310
+ env = env.multi_to_wide(e)
311
+ end
312
+ env = [env].pack('p*').unpack('L').first
313
+ else
314
+ env = nil
315
+ end
316
+
317
+ startinfo = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
318
+ startinfo = startinfo.pack('LLLLLLLLLLLLSSLLLL')
319
+ procinfo = [0,0,0,0].pack('LLLL')
320
+
321
+ # Process SECURITY_ATTRIBUTE structure
322
+ process_security = 0
323
+ if hash['process_inherit']
324
+ process_security = [0,0,0].pack('LLL')
325
+ process_security[0,4] = [12].pack('L') # sizeof(SECURITY_ATTRIBUTE)
326
+ process_security[8,4] = [1].pack('L') # TRUE
327
+ end
328
+
329
+ # Thread SECURITY_ATTRIBUTE structure
330
+ thread_security = 0
331
+ if hash['thread_inherit']
332
+ thread_security = [0,0,0].pack('LLL')
333
+ thread_security[0,4] = [12].pack('L') # sizeof(SECURITY_ATTRIBUTE)
334
+ thread_security[8,4] = [1].pack('L') # TRUE
335
+ end
336
+
337
+ # Automatically handle stdin, stdout and stderr as either IO objects
338
+ # or file descriptors. This won't work for StringIO, however.
339
+ ['stdin', 'stdout', 'stderr'].each{ |io|
340
+ if si_hash[io]
341
+ if si_hash[io].respond_to?(:fileno)
342
+ handle = get_osfhandle(si_hash[io].fileno)
343
+ else
344
+ handle = get_osfhandle(si_hash[io])
345
+ end
346
+
347
+ if handle == INVALID_HANDLE_VALUE
348
+ raise Error, get_last_error
349
+ end
350
+
351
+ # Most implementations of Ruby on Windows create inheritable
352
+ # handles by default, but some do not. RF bug #26988.
353
+ bool = SetHandleInformation(
354
+ handle,
355
+ HANDLE_FLAG_INHERIT,
356
+ HANDLE_FLAG_INHERIT
357
+ )
358
+
359
+ raise Error, get_last_error unless bool
360
+
361
+ si_hash[io] = handle
362
+ si_hash['startf_flags'] ||= 0
363
+ si_hash['startf_flags'] |= STARTF_USESTDHANDLES
364
+ hash['inherit'] = true
365
+ end
366
+ }
367
+
368
+ # The bytes not covered here are reserved (null)
369
+ unless si_hash.empty?
370
+ startinfo[0,4] = [startinfo.size].pack('L')
371
+ startinfo[8,4] = [si_hash['desktop']].pack('p*') if si_hash['desktop']
372
+ startinfo[12,4] = [si_hash['title']].pack('p*') if si_hash['title']
373
+ startinfo[16,4] = [si_hash['x']].pack('L') if si_hash['x']
374
+ startinfo[20,4] = [si_hash['y']].pack('L') if si_hash['y']
375
+ startinfo[24,4] = [si_hash['x_size']].pack('L') if si_hash['x_size']
376
+ startinfo[28,4] = [si_hash['y_size']].pack('L') if si_hash['y_size']
377
+ startinfo[32,4] = [si_hash['x_count_chars']].pack('L') if si_hash['x_count_chars']
378
+ startinfo[36,4] = [si_hash['y_count_chars']].pack('L') if si_hash['y_count_chars']
379
+ startinfo[40,4] = [si_hash['fill_attribute']].pack('L') if si_hash['fill_attribute']
380
+ startinfo[44,4] = [si_hash['startf_flags']].pack('L') if si_hash['startf_flags']
381
+ startinfo[48,2] = [si_hash['sw_flags']].pack('S') if si_hash['sw_flags']
382
+ startinfo[56,4] = [si_hash['stdin']].pack('L') if si_hash['stdin']
383
+ startinfo[60,4] = [si_hash['stdout']].pack('L') if si_hash['stdout']
384
+ startinfo[64,4] = [si_hash['stderr']].pack('L') if si_hash['stderr']
385
+ end
386
+
387
+ if hash['with_logon']
388
+ logon = multi_to_wide(hash['with_logon'])
389
+ domain = multi_to_wide(hash['domain'])
390
+ app = hash['app_name'].nil? ? nil : multi_to_wide(hash['app_name'])
391
+ cmd = hash['command_line'].nil? ? nil : multi_to_wide(hash['command_line'])
392
+ cwd = multi_to_wide(hash['cwd'])
393
+ passwd = multi_to_wide(hash['password'])
394
+
395
+ hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT
396
+
397
+ process_ran = CreateProcessWithLogonW(
398
+ logon, # User
399
+ domain, # Domain
400
+ passwd, # Password
401
+ LOGON_WITH_PROFILE, # Logon flags
402
+ app, # App name
403
+ cmd, # Command line
404
+ hash['creation_flags'], # Creation flags
405
+ env, # Environment
406
+ cwd, # Working directory
407
+ startinfo, # Startup Info
408
+ procinfo # Process Info
409
+ )
410
+ else
411
+ process_ran = CreateProcess(
412
+ hash['app_name'], # App name
413
+ hash['command_line'], # Command line
414
+ process_security, # Process attributes
415
+ thread_security, # Thread attributes
416
+ hash['inherit'], # Inherit handles?
417
+ hash['creation_flags'], # Creation flags
418
+ env, # Environment
419
+ hash['cwd'], # Working directory
420
+ startinfo, # Startup Info
421
+ procinfo # Process Info
422
+ )
423
+ end
424
+
425
+ # TODO: Close stdin, stdout and stderr handles in the si_hash unless
426
+ # they're pointing to one of the standard handles already. [Maybe]
427
+ if !process_ran
428
+ raise_last_error("CreateProcess()")
429
+ end
430
+
431
+ # Automatically close the process and thread handles in the
432
+ # PROCESS_INFORMATION struct unless explicitly told not to.
433
+ if hash['close_handles']
434
+ CloseHandle(procinfo[0,4].unpack('L').first)
435
+ CloseHandle(procinfo[4,4].unpack('L').first)
436
+ end
437
+
438
+ ProcessInfo.new(
439
+ procinfo[0,4].unpack('L').first, # hProcess
440
+ procinfo[4,4].unpack('L').first, # hThread
441
+ procinfo[8,4].unpack('L').first, # hProcessId
442
+ procinfo[12,4].unpack('L').first # hThreadId
443
+ )
444
+ end
445
+
446
+ def self.raise_last_error(operation)
447
+ error_string = "#{operation} failed: #{get_last_error}"
448
+ last_error_code = GetLastError()
449
+ if ERROR_CODE_MAP.has_key?(last_error_code)
450
+ raise ERROR_CODE_MAP[last_error_code], error_string
451
+ else
452
+ raise Error, error_string
453
+ end
454
+ end
455
+
456
+ # List from ruby/win32/win32.c
457
+ ERROR_CODE_MAP = {
458
+ ERROR_INVALID_FUNCTION => Errno::EINVAL,
459
+ ERROR_FILE_NOT_FOUND => Errno::ENOENT,
460
+ ERROR_PATH_NOT_FOUND => Errno::ENOENT,
461
+ ERROR_TOO_MANY_OPEN_FILES => Errno::EMFILE,
462
+ ERROR_ACCESS_DENIED => Errno::EACCES,
463
+ ERROR_INVALID_HANDLE => Errno::EBADF,
464
+ ERROR_ARENA_TRASHED => Errno::ENOMEM,
465
+ ERROR_NOT_ENOUGH_MEMORY => Errno::ENOMEM,
466
+ ERROR_INVALID_BLOCK => Errno::ENOMEM,
467
+ ERROR_BAD_ENVIRONMENT => Errno::E2BIG,
468
+ ERROR_BAD_FORMAT => Errno::ENOEXEC,
469
+ ERROR_INVALID_ACCESS => Errno::EINVAL,
470
+ ERROR_INVALID_DATA => Errno::EINVAL,
471
+ ERROR_INVALID_DRIVE => Errno::ENOENT,
472
+ ERROR_CURRENT_DIRECTORY => Errno::EACCES,
473
+ ERROR_NOT_SAME_DEVICE => Errno::EXDEV,
474
+ ERROR_NO_MORE_FILES => Errno::ENOENT,
475
+ ERROR_WRITE_PROTECT => Errno::EROFS,
476
+ ERROR_BAD_UNIT => Errno::ENODEV,
477
+ ERROR_NOT_READY => Errno::ENXIO,
478
+ ERROR_BAD_COMMAND => Errno::EACCES,
479
+ ERROR_CRC => Errno::EACCES,
480
+ ERROR_BAD_LENGTH => Errno::EACCES,
481
+ ERROR_SEEK => Errno::EIO,
482
+ ERROR_NOT_DOS_DISK => Errno::EACCES,
483
+ ERROR_SECTOR_NOT_FOUND => Errno::EACCES,
484
+ ERROR_OUT_OF_PAPER => Errno::EACCES,
485
+ ERROR_WRITE_FAULT => Errno::EIO,
486
+ ERROR_READ_FAULT => Errno::EIO,
487
+ ERROR_GEN_FAILURE => Errno::EACCES,
488
+ ERROR_LOCK_VIOLATION => Errno::EACCES,
489
+ ERROR_SHARING_VIOLATION => Errno::EACCES,
490
+ ERROR_WRONG_DISK => Errno::EACCES,
491
+ ERROR_SHARING_BUFFER_EXCEEDED => Errno::EACCES,
492
+ # ERROR_BAD_NETPATH => Errno::ENOENT,
493
+ # ERROR_NETWORK_ACCESS_DENIED => Errno::EACCES,
494
+ # ERROR_BAD_NET_NAME => Errno::ENOENT,
495
+ ERROR_FILE_EXISTS => Errno::EEXIST,
496
+ ERROR_CANNOT_MAKE => Errno::EACCES,
497
+ ERROR_FAIL_I24 => Errno::EACCES,
498
+ ERROR_INVALID_PARAMETER => Errno::EINVAL,
499
+ ERROR_NO_PROC_SLOTS => Errno::EAGAIN,
500
+ ERROR_DRIVE_LOCKED => Errno::EACCES,
501
+ ERROR_BROKEN_PIPE => Errno::EPIPE,
502
+ ERROR_DISK_FULL => Errno::ENOSPC,
503
+ ERROR_INVALID_TARGET_HANDLE => Errno::EBADF,
504
+ ERROR_INVALID_HANDLE => Errno::EINVAL,
505
+ ERROR_WAIT_NO_CHILDREN => Errno::ECHILD,
506
+ ERROR_CHILD_NOT_COMPLETE => Errno::ECHILD,
507
+ ERROR_DIRECT_ACCESS_HANDLE => Errno::EBADF,
508
+ ERROR_NEGATIVE_SEEK => Errno::EINVAL,
509
+ ERROR_SEEK_ON_DEVICE => Errno::EACCES,
510
+ ERROR_DIR_NOT_EMPTY => Errno::ENOTEMPTY,
511
+ # ERROR_DIRECTORY => Errno::ENOTDIR,
512
+ ERROR_NOT_LOCKED => Errno::EACCES,
513
+ ERROR_BAD_PATHNAME => Errno::ENOENT,
514
+ ERROR_MAX_THRDS_REACHED => Errno::EAGAIN,
515
+ # ERROR_LOCK_FAILED => Errno::EACCES,
516
+ ERROR_ALREADY_EXISTS => Errno::EEXIST,
517
+ ERROR_INVALID_STARTING_CODESEG => Errno::ENOEXEC,
518
+ ERROR_INVALID_STACKSEG => Errno::ENOEXEC,
519
+ ERROR_INVALID_MODULETYPE => Errno::ENOEXEC,
520
+ ERROR_INVALID_EXE_SIGNATURE => Errno::ENOEXEC,
521
+ ERROR_EXE_MARKED_INVALID => Errno::ENOEXEC,
522
+ ERROR_BAD_EXE_FORMAT => Errno::ENOEXEC,
523
+ ERROR_ITERATED_DATA_EXCEEDS_64k => Errno::ENOEXEC,
524
+ ERROR_INVALID_MINALLOCSIZE => Errno::ENOEXEC,
525
+ ERROR_DYNLINK_FROM_INVALID_RING => Errno::ENOEXEC,
526
+ ERROR_IOPL_NOT_ENABLED => Errno::ENOEXEC,
527
+ ERROR_INVALID_SEGDPL => Errno::ENOEXEC,
528
+ ERROR_AUTODATASEG_EXCEEDS_64k => Errno::ENOEXEC,
529
+ ERROR_RING2SEG_MUST_BE_MOVABLE => Errno::ENOEXEC,
530
+ ERROR_RELOC_CHAIN_XEEDS_SEGLIM => Errno::ENOEXEC,
531
+ ERROR_INFLOOP_IN_RELOC_CHAIN => Errno::ENOEXEC,
532
+ ERROR_FILENAME_EXCED_RANGE => Errno::ENOENT,
533
+ ERROR_NESTING_NOT_ALLOWED => Errno::EAGAIN,
534
+ # ERROR_PIPE_LOCAL => Errno::EPIPE,
535
+ ERROR_BAD_PIPE => Errno::EPIPE,
536
+ ERROR_PIPE_BUSY => Errno::EAGAIN,
537
+ ERROR_NO_DATA => Errno::EPIPE,
538
+ ERROR_PIPE_NOT_CONNECTED => Errno::EPIPE,
539
+ ERROR_OPERATION_ABORTED => Errno::EINTR,
540
+ # ERROR_NOT_ENOUGH_QUOTA => Errno::ENOMEM,
541
+ ERROR_MOD_NOT_FOUND => Errno::ENOENT,
542
+ WSAEINTR => Errno::EINTR,
543
+ WSAEBADF => Errno::EBADF,
544
+ # WSAEACCES => Errno::EACCES,
545
+ WSAEFAULT => Errno::EFAULT,
546
+ WSAEINVAL => Errno::EINVAL,
547
+ WSAEMFILE => Errno::EMFILE,
548
+ WSAEWOULDBLOCK => Errno::EWOULDBLOCK,
549
+ WSAEINPROGRESS => Errno::EINPROGRESS,
550
+ WSAEALREADY => Errno::EALREADY,
551
+ WSAENOTSOCK => Errno::ENOTSOCK,
552
+ WSAEDESTADDRREQ => Errno::EDESTADDRREQ,
553
+ WSAEMSGSIZE => Errno::EMSGSIZE,
554
+ WSAEPROTOTYPE => Errno::EPROTOTYPE,
555
+ WSAENOPROTOOPT => Errno::ENOPROTOOPT,
556
+ WSAEPROTONOSUPPORT => Errno::EPROTONOSUPPORT,
557
+ WSAESOCKTNOSUPPORT => Errno::ESOCKTNOSUPPORT,
558
+ WSAEOPNOTSUPP => Errno::EOPNOTSUPP,
559
+ WSAEPFNOSUPPORT => Errno::EPFNOSUPPORT,
560
+ WSAEAFNOSUPPORT => Errno::EAFNOSUPPORT,
561
+ WSAEADDRINUSE => Errno::EADDRINUSE,
562
+ WSAEADDRNOTAVAIL => Errno::EADDRNOTAVAIL,
563
+ WSAENETDOWN => Errno::ENETDOWN,
564
+ WSAENETUNREACH => Errno::ENETUNREACH,
565
+ WSAENETRESET => Errno::ENETRESET,
566
+ WSAECONNABORTED => Errno::ECONNABORTED,
567
+ WSAECONNRESET => Errno::ECONNRESET,
568
+ WSAENOBUFS => Errno::ENOBUFS,
569
+ WSAEISCONN => Errno::EISCONN,
570
+ WSAENOTCONN => Errno::ENOTCONN,
571
+ WSAESHUTDOWN => Errno::ESHUTDOWN,
572
+ WSAETOOMANYREFS => Errno::ETOOMANYREFS,
573
+ # WSAETIMEDOUT => Errno::ETIMEDOUT,
574
+ WSAECONNREFUSED => Errno::ECONNREFUSED,
575
+ WSAELOOP => Errno::ELOOP,
576
+ WSAENAMETOOLONG => Errno::ENAMETOOLONG,
577
+ WSAEHOSTDOWN => Errno::EHOSTDOWN,
578
+ WSAEHOSTUNREACH => Errno::EHOSTUNREACH,
579
+ # WSAEPROCLIM => Errno::EPROCLIM,
580
+ # WSAENOTEMPTY => Errno::ENOTEMPTY,
581
+ WSAEUSERS => Errno::EUSERS,
582
+ WSAEDQUOT => Errno::EDQUOT,
583
+ WSAESTALE => Errno::ESTALE,
584
+ WSAEREMOTE => Errno::EREMOTE
585
+ }
586
+
587
+ module_function :create
588
+ end