chef 10.34.6 → 11.0.0.beta.0

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 (506) hide show
  1. data/CONTRIBUTING.md +155 -0
  2. data/README.md +89 -0
  3. data/Rakefile +4 -12
  4. data/bin/chef-apply +25 -0
  5. data/bin/chef-shell +34 -0
  6. data/bin/shef +6 -5
  7. data/distro/common/html/chef-client.8.html +4 -4
  8. data/distro/common/html/chef-expander.8.html +4 -4
  9. data/distro/common/html/chef-expanderctl.8.html +4 -4
  10. data/distro/common/html/chef-server-webui.8.html +4 -4
  11. data/distro/common/html/chef-server.8.html +4 -4
  12. data/distro/common/html/{shef.1.html → chef-shell.1.html} +49 -46
  13. data/distro/common/html/chef-solo.8.html +18 -12
  14. data/distro/common/html/chef-solr.8.html +4 -4
  15. data/distro/common/html/knife-bootstrap.1.html +4 -4
  16. data/distro/common/html/knife-client.1.html +4 -4
  17. data/distro/common/html/knife-configure.1.html +4 -4
  18. data/distro/common/html/knife-cookbook-site.1.html +4 -4
  19. data/distro/common/html/knife-cookbook.1.html +10 -7
  20. data/distro/common/html/knife-data-bag.1.html +10 -7
  21. data/distro/common/html/knife-environment.1.html +8 -6
  22. data/distro/common/html/knife-exec.1.html +9 -9
  23. data/distro/common/html/knife-index.1.html +4 -4
  24. data/distro/common/html/knife-node.1.html +4 -4
  25. data/distro/common/html/knife-role.1.html +4 -4
  26. data/distro/common/html/knife-search.1.html +4 -4
  27. data/distro/common/html/knife-ssh.1.html +4 -4
  28. data/distro/common/html/knife-status.1.html +4 -4
  29. data/distro/common/html/knife-tag.1.html +4 -4
  30. data/distro/common/html/knife.1.html +8 -13
  31. data/distro/common/man/man1/{shef.1 → chef-shell.1} +21 -57
  32. data/distro/common/man/man1/knife-bootstrap.1 +1 -1
  33. data/distro/common/man/man1/knife-client.1 +1 -1
  34. data/distro/common/man/man1/knife-configure.1 +1 -1
  35. data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
  36. data/distro/common/man/man1/knife-cookbook.1 +15 -2
  37. data/distro/common/man/man1/knife-data-bag.1 +15 -2
  38. data/distro/common/man/man1/knife-environment.1 +12 -2
  39. data/distro/common/man/man1/knife-exec.1 +4 -7
  40. data/distro/common/man/man1/knife-index.1 +1 -1
  41. data/distro/common/man/man1/knife-node.1 +1 -1
  42. data/distro/common/man/man1/knife-role.1 +1 -1
  43. data/distro/common/man/man1/knife-search.1 +1 -1
  44. data/distro/common/man/man1/knife-ssh.1 +1 -1
  45. data/distro/common/man/man1/knife-status.1 +1 -1
  46. data/distro/common/man/man1/knife-tag.1 +1 -1
  47. data/distro/common/man/man1/knife.1 +3 -6
  48. data/distro/common/man/man8/chef-client.8 +1 -1
  49. data/distro/common/man/man8/chef-expander.8 +1 -1
  50. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  51. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  52. data/distro/common/man/man8/chef-server.8 +1 -1
  53. data/distro/common/man/man8/chef-solo.8 +36 -4
  54. data/distro/common/man/man8/chef-solr.8 +1 -1
  55. data/distro/common/markdown/man1/{shef.mkd → chef-shell.mkd} +49 -43
  56. data/distro/common/markdown/man1/knife-exec.mkd +11 -6
  57. data/distro/common/markdown/man1/knife.mkd +4 -9
  58. data/distro/debian/etc/default/chef-client +0 -1
  59. data/distro/debian/etc/init.d/chef-client +2 -2
  60. data/lib/chef.rb +2 -5
  61. data/lib/chef/api_client.rb +20 -130
  62. data/lib/chef/api_client/registration.rb +126 -0
  63. data/lib/chef/application.rb +71 -14
  64. data/lib/chef/application/apply.rb +160 -0
  65. data/lib/chef/application/client.rb +25 -18
  66. data/lib/chef/application/knife.rb +0 -2
  67. data/lib/chef/application/solo.rb +23 -8
  68. data/lib/chef/application/windows_service.rb +5 -2
  69. data/lib/chef/applications.rb +1 -0
  70. data/lib/chef/chef_fs.rb +11 -0
  71. data/lib/chef/chef_fs/command_line.rb +232 -0
  72. data/lib/chef/chef_fs/file_pattern.rb +312 -0
  73. data/lib/chef/chef_fs/file_system.rb +358 -0
  74. data/lib/chef/chef_fs/file_system/base_fs_dir.rb +47 -0
  75. data/lib/chef/chef_fs/file_system/base_fs_object.rb +121 -0
  76. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +109 -0
  77. data/{spec/unit/monkey_patches/uri_spec.rb → lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb} +12 -15
  78. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +84 -0
  79. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +188 -0
  80. data/lib/chef/chef_fs/file_system/cookbook_file.rb +78 -0
  81. data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +54 -0
  82. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +68 -0
  83. data/lib/chef/chef_fs/file_system/data_bag_dir.rb +78 -0
  84. data/lib/chef/chef_fs/file_system/data_bag_item.rb +59 -0
  85. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +66 -0
  86. data/lib/chef/chef_fs/file_system/file_system_entry.rb +90 -0
  87. data/lib/chef/{index_queue.rb → chef_fs/file_system/file_system_error.rb} +14 -12
  88. data/lib/chef/{resource/whyrun_safe_ruby_block.rb → chef_fs/file_system/file_system_root_dir.rb} +10 -10
  89. data/lib/chef/chef_fs/file_system/must_delete_recursively_error.rb +31 -0
  90. data/lib/chef/chef_fs/file_system/nodes_dir.rb +47 -0
  91. data/lib/chef/{provider/whyrun_safe_ruby_block.rb → chef_fs/file_system/nonexistent_fs_object.rb} +19 -9
  92. data/lib/chef/chef_fs/file_system/not_found_error.rb +31 -0
  93. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +84 -0
  94. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +123 -0
  95. data/lib/chef/chef_fs/knife.rb +77 -0
  96. data/lib/chef/chef_fs/path_utils.rb +64 -0
  97. data/lib/chef/client.rb +44 -21
  98. data/lib/chef/config.rb +52 -43
  99. data/lib/chef/cookbook/synchronizer.rb +6 -8
  100. data/lib/chef/cookbook/syntax_check.rb +61 -14
  101. data/lib/chef/cookbook_loader.rb +39 -26
  102. data/lib/chef/cookbook_uploader.rb +17 -19
  103. data/lib/chef/cookbook_version.rb +3 -302
  104. data/lib/chef/daemon.rb +3 -18
  105. data/lib/chef/data_bag.rb +4 -97
  106. data/lib/chef/data_bag_item.rb +2 -65
  107. data/lib/chef/digester.rb +73 -0
  108. data/lib/chef/dsl.rb +6 -0
  109. data/lib/chef/dsl/data_query.rb +66 -0
  110. data/lib/chef/dsl/include_attribute.rb +60 -0
  111. data/lib/chef/dsl/include_recipe.rb +42 -0
  112. data/lib/chef/dsl/platform_introspection.rb +213 -0
  113. data/lib/chef/dsl/recipe.rb +84 -0
  114. data/lib/chef/dsl/registry_helper.rb +59 -0
  115. data/lib/chef/encrypted_data_bag_item.rb +74 -19
  116. data/lib/chef/environment.rb +9 -180
  117. data/lib/chef/exceptions.rb +87 -14
  118. data/lib/chef/formatters/base.rb +4 -1
  119. data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +0 -4
  120. data/lib/chef/json_compat.rb +1 -97
  121. data/lib/chef/knife.rb +90 -41
  122. data/lib/chef/knife/bootstrap/archlinux-gems.erb +2 -2
  123. data/lib/chef/knife/bootstrap/centos5-gems.erb +2 -2
  124. data/lib/chef/knife/bootstrap/chef-full.erb +3 -3
  125. data/lib/chef/knife/bootstrap/fedora13-gems.erb +2 -2
  126. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
  127. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +2 -2
  128. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +2 -2
  129. data/lib/chef/knife/configure.rb +1 -2
  130. data/lib/chef/knife/cookbook_metadata.rb +1 -0
  131. data/lib/chef/knife/cookbook_test.rb +3 -2
  132. data/lib/chef/knife/cookbook_upload.rb +12 -7
  133. data/lib/chef/knife/core/bootstrap_context.rb +1 -1
  134. data/lib/chef/knife/core/generic_presenter.rb +26 -13
  135. data/lib/chef/knife/core/node_editor.rb +36 -16
  136. data/lib/chef/knife/core/node_presenter.rb +1 -1
  137. data/lib/chef/knife/core/text_formatter.rb +23 -37
  138. data/lib/chef/knife/core/ui.rb +15 -9
  139. data/lib/chef/knife/delete.rb +39 -0
  140. data/lib/chef/knife/diff.rb +46 -0
  141. data/lib/chef/knife/download.rb +50 -0
  142. data/lib/chef/knife/environment_show.rb +7 -0
  143. data/lib/chef/knife/exec.rb +5 -5
  144. data/lib/chef/knife/help_topics.rb +1 -1
  145. data/lib/chef/knife/index_rebuild.rb +91 -7
  146. data/lib/chef/knife/list.rb +109 -0
  147. data/lib/chef/knife/raw.rb +108 -0
  148. data/lib/chef/knife/search.rb +40 -22
  149. data/lib/chef/knife/show.rb +32 -0
  150. data/lib/chef/knife/ssh.rb +6 -2
  151. data/lib/chef/knife/upload.rb +50 -0
  152. data/lib/chef/mixin/checksum.rb +3 -3
  153. data/lib/chef/mixin/deep_merge.rb +55 -197
  154. data/lib/chef/mixin/language.rb +9 -222
  155. data/lib/chef/mixin/language_include_attribute.rb +6 -38
  156. data/lib/chef/mixin/language_include_recipe.rb +3 -35
  157. data/lib/chef/mixin/params_validate.rb +6 -19
  158. data/lib/chef/mixin/recipe_definition_dsl_core.rb +8 -61
  159. data/lib/chef/mixin/securable.rb +32 -7
  160. data/lib/chef/mixin/template.rb +40 -0
  161. data/lib/chef/mixins.rb +0 -4
  162. data/lib/chef/monkey_patches/net_http.rb +0 -34
  163. data/lib/chef/node.rb +133 -309
  164. data/lib/chef/node/attribute.rb +333 -473
  165. data/lib/chef/node/attribute_collections.rb +199 -0
  166. data/lib/chef/node/immutable_collections.rb +186 -0
  167. data/lib/chef/platform.rb +7 -22
  168. data/lib/chef/provider.rb +2 -49
  169. data/lib/chef/provider/breakpoint.rb +6 -6
  170. data/lib/chef/provider/cookbook_file.rb +5 -33
  171. data/lib/chef/provider/deploy.rb +2 -1
  172. data/lib/chef/provider/directory.rb +14 -17
  173. data/lib/chef/provider/file.rb +19 -52
  174. data/lib/chef/provider/group.rb +31 -51
  175. data/lib/chef/provider/group/dscl.rb +13 -53
  176. data/lib/chef/provider/group/gpasswd.rb +19 -14
  177. data/lib/chef/provider/group/groupadd.rb +1 -41
  178. data/lib/chef/provider/group/groupmod.rb +36 -46
  179. data/lib/chef/provider/group/pw.rb +16 -59
  180. data/lib/chef/provider/group/suse.rb +13 -16
  181. data/lib/chef/provider/group/usermod.rb +18 -40
  182. data/lib/chef/provider/group/windows.rb +6 -13
  183. data/lib/chef/provider/http_request.rb +25 -42
  184. data/lib/chef/provider/link.rb +2 -0
  185. data/lib/chef/provider/lwrp_base.rb +150 -0
  186. data/lib/chef/provider/package/portage.rb +4 -9
  187. data/lib/chef/provider/package/rpm.rb +2 -2
  188. data/lib/chef/provider/package/rubygems.rb +9 -41
  189. data/lib/chef/provider/package/yum.rb +12 -19
  190. data/lib/chef/provider/registry_key.rb +156 -0
  191. data/lib/chef/provider/remote_directory.rb +2 -0
  192. data/lib/chef/provider/remote_file.rb +21 -12
  193. data/lib/chef/provider/ruby_block.rb +5 -2
  194. data/lib/chef/provider/service.rb +15 -0
  195. data/lib/chef/provider/service/init.rb +9 -7
  196. data/lib/chef/provider/service/macosx.rb +15 -73
  197. data/lib/chef/provider/service/simple.rb +1 -1
  198. data/lib/chef/provider/service/solaris.rb +3 -3
  199. data/lib/chef/provider/template.rb +22 -25
  200. data/lib/chef/provider/template_finder.rb +61 -0
  201. data/lib/chef/provider/user.rb +0 -1
  202. data/lib/chef/provider/user/dscl.rb +175 -568
  203. data/lib/chef/provider/user/useradd.rb +30 -47
  204. data/lib/chef/providers.rb +3 -2
  205. data/lib/chef/recipe.rb +14 -8
  206. data/lib/chef/resource.rb +13 -154
  207. data/lib/chef/resource/group.rb +1 -11
  208. data/lib/chef/resource/http_request.rb +2 -1
  209. data/lib/chef/resource/lwrp_base.rb +127 -0
  210. data/lib/chef/resource/mount.rb +10 -11
  211. data/lib/chef/resource/registry_key.rb +86 -0
  212. data/lib/chef/resource/remote_directory.rb +6 -5
  213. data/lib/chef/resource/remote_file.rb +22 -31
  214. data/lib/chef/resource/ruby_block.rb +2 -2
  215. data/lib/chef/resource/service.rb +14 -0
  216. data/lib/chef/resource/user.rb +0 -18
  217. data/lib/chef/resource_collection.rb +25 -21
  218. data/lib/chef/resources.rb +2 -1
  219. data/lib/chef/rest.rb +50 -131
  220. data/lib/chef/rest/auth_credentials.rb +4 -20
  221. data/lib/chef/rest/rest_request.rb +2 -7
  222. data/lib/chef/role.rb +1 -97
  223. data/lib/chef/run_context.rb +108 -130
  224. data/lib/chef/run_context/cookbook_compiler.rb +280 -0
  225. data/lib/chef/run_list.rb +0 -2
  226. data/lib/chef/run_list/run_list_expansion.rb +0 -15
  227. data/lib/chef/run_lock.rb +90 -0
  228. data/lib/chef/runner.rb +28 -5
  229. data/lib/chef/sandbox.rb +15 -148
  230. data/lib/chef/scan_access_control.rb +2 -4
  231. data/lib/chef/shef/ext.rb +3 -575
  232. data/lib/chef/{shef.rb → shell.rb} +35 -40
  233. data/lib/chef/shell/ext.rb +593 -0
  234. data/lib/chef/{shef → shell}/model_wrapper.rb +3 -3
  235. data/lib/chef/{shef/shef_rest.rb → shell/shell_rest.rb} +4 -4
  236. data/lib/chef/{shef/shef_session.rb → shell/shell_session.rb} +17 -15
  237. data/lib/chef/shell_out.rb +7 -0
  238. data/lib/chef/util/windows/net_group.rb +1 -5
  239. data/lib/chef/version.rb +3 -3
  240. data/lib/chef/win32/api/process.rb +0 -1
  241. data/lib/chef/win32/handle.rb +1 -8
  242. data/lib/chef/win32/registry.rb +371 -0
  243. data/spec/data/big_json.json +1 -2
  244. data/spec/data/big_json_plus_one.json +1 -2
  245. data/spec/data/cookbooks/openldap/attributes/default.rb +10 -9
  246. data/spec/data/cookbooks/openldap/attributes/smokey.rb +1 -1
  247. data/spec/data/lwrp/providers/inline_compiler.rb +26 -0
  248. data/spec/data/nodes/default.rb +3 -3
  249. data/spec/data/nodes/test.example.com.rb +3 -3
  250. data/spec/data/nodes/test.rb +3 -3
  251. data/spec/data/partial_one.erb +1 -0
  252. data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +4 -0
  253. data/spec/data/run_context/cookbooks/circular-dep1/definitions/circular_dep1_res.rb +1 -0
  254. data/spec/data/run_context/cookbooks/circular-dep1/libraries/lib.rb +2 -0
  255. data/spec/data/run_context/cookbooks/circular-dep1/metadata.rb +2 -0
  256. data/spec/data/run_context/cookbooks/circular-dep1/providers/provider.rb +1 -0
  257. data/spec/data/{knife-home/.chef/plugins/knife/example_home_subcommand.rb → run_context/cookbooks/circular-dep1/recipes/default.rb} +0 -0
  258. data/spec/data/run_context/cookbooks/circular-dep1/resources/resource.rb +1 -0
  259. data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +3 -0
  260. data/spec/data/run_context/cookbooks/circular-dep2/definitions/circular_dep2_res.rb +1 -0
  261. data/spec/data/run_context/cookbooks/circular-dep2/libraries/lib.rb +2 -0
  262. data/spec/data/run_context/cookbooks/circular-dep2/metadata.rb +2 -0
  263. data/spec/data/run_context/cookbooks/circular-dep2/providers/provider.rb +1 -0
  264. data/spec/data/{lwrp_const_scoping/resources/conflict.rb → run_context/cookbooks/circular-dep2/recipes/default.rb} +0 -0
  265. data/spec/data/run_context/cookbooks/circular-dep2/resources/resource.rb +1 -0
  266. data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -0
  267. data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -0
  268. data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +3 -0
  269. data/spec/data/run_context/cookbooks/dependency1/definitions/dependency1_res.rb +1 -0
  270. data/spec/data/run_context/cookbooks/dependency1/libraries/lib.rb +2 -0
  271. data/spec/data/run_context/cookbooks/dependency1/providers/provider.rb +1 -0
  272. data/spec/data/run_context/cookbooks/dependency1/recipes/default.rb +0 -0
  273. data/spec/data/run_context/cookbooks/dependency1/resources/resource.rb +1 -0
  274. data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +3 -0
  275. data/spec/data/run_context/cookbooks/dependency2/definitions/dependency2_res.rb +1 -0
  276. data/spec/data/run_context/cookbooks/dependency2/libraries/lib.rb +2 -0
  277. data/spec/data/run_context/cookbooks/dependency2/providers/provider.rb +1 -0
  278. data/spec/data/run_context/cookbooks/dependency2/recipes/default.rb +0 -0
  279. data/spec/data/run_context/cookbooks/dependency2/resources/resource.rb +1 -0
  280. data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +3 -0
  281. data/spec/data/run_context/cookbooks/no-default-attr/definitions/no_default-attr_res.rb +1 -0
  282. data/spec/data/run_context/cookbooks/no-default-attr/providers/provider.rb +1 -0
  283. data/spec/data/run_context/cookbooks/no-default-attr/recipes/default.rb +0 -0
  284. data/spec/data/run_context/cookbooks/no-default-attr/resources/resource.rb +1 -0
  285. data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +3 -0
  286. data/spec/data/run_context/cookbooks/test-with-circular-deps/definitions/test_with-circular-deps_res.rb +1 -0
  287. data/spec/data/run_context/cookbooks/test-with-circular-deps/libraries/lib.rb +2 -0
  288. data/spec/data/run_context/cookbooks/test-with-circular-deps/metadata.rb +2 -0
  289. data/spec/data/run_context/cookbooks/test-with-circular-deps/providers/provider.rb +1 -0
  290. data/spec/data/run_context/cookbooks/test-with-circular-deps/recipes/default.rb +0 -0
  291. data/spec/data/run_context/cookbooks/test-with-circular-deps/resources/resource.rb +1 -0
  292. data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +3 -0
  293. data/spec/data/run_context/cookbooks/test-with-deps/definitions/test_with-deps_res.rb +1 -0
  294. data/spec/data/run_context/cookbooks/test-with-deps/libraries/lib.rb +1 -0
  295. data/spec/data/run_context/cookbooks/test-with-deps/metadata.rb +3 -0
  296. data/spec/data/run_context/cookbooks/test-with-deps/providers/provider.rb +1 -0
  297. data/spec/data/run_context/cookbooks/test-with-deps/recipes/default.rb +0 -0
  298. data/spec/data/run_context/cookbooks/test-with-deps/recipes/server.rb +0 -0
  299. data/spec/data/run_context/cookbooks/test-with-deps/resources/resource.rb +1 -0
  300. data/spec/data/run_context/cookbooks/test/attributes/default.rb +0 -0
  301. data/spec/data/run_context/cookbooks/test/attributes/george.rb +1 -1
  302. data/spec/data/run_context/cookbooks/test/definitions/test_res.rb +1 -0
  303. data/spec/data/run_context/cookbooks/test/providers/provider.rb +1 -0
  304. data/spec/data/run_context/cookbooks/test/resources/resource.rb +1 -0
  305. data/spec/data/shef-config.rb +7 -0
  306. data/spec/functional/dsl/registry_helper_spec.rb +63 -0
  307. data/spec/functional/knife/cookbook_delete_spec.rb +1 -1
  308. data/spec/functional/knife/exec_spec.rb +2 -2
  309. data/spec/functional/knife/ssh_spec.rb +5 -1
  310. data/spec/functional/resource/cookbook_file_spec.rb +7 -19
  311. data/spec/functional/resource/directory_spec.rb +4 -0
  312. data/spec/functional/resource/file_spec.rb +56 -22
  313. data/spec/functional/resource/link_spec.rb +2 -0
  314. data/spec/functional/resource/registry_spec.rb +576 -0
  315. data/spec/functional/resource/remote_directory_spec.rb +142 -36
  316. data/spec/functional/resource/remote_file_spec.rb +18 -0
  317. data/spec/functional/resource/template_spec.rb +23 -2
  318. data/spec/functional/run_lock_spec.rb +106 -0
  319. data/spec/functional/shell_spec.rb +100 -0
  320. data/spec/functional/win32/registry_helper_spec.rb +632 -0
  321. data/spec/spec_helper.rb +5 -29
  322. data/spec/stress/win32/security_spec.rb +1 -1
  323. data/spec/support/chef_helpers.rb +0 -2
  324. data/spec/support/platform_helpers.rb +8 -15
  325. data/spec/support/shared/functional/directory_resource.rb +84 -22
  326. data/spec/support/shared/functional/file_resource.rb +169 -71
  327. data/spec/support/shared/functional/securable_resource.rb +143 -119
  328. data/spec/support/shared/functional/securable_resource_with_reporting.rb +375 -0
  329. data/spec/support/shared/unit/file_system_support.rb +110 -0
  330. data/spec/support/shared/unit/platform_introspector.rb +162 -0
  331. data/spec/unit/api_client/registration_spec.rb +175 -0
  332. data/spec/unit/api_client_spec.rb +78 -156
  333. data/spec/unit/application/apply.rb +84 -0
  334. data/spec/unit/application/client_spec.rb +1 -37
  335. data/spec/unit/application/knife_spec.rb +5 -0
  336. data/spec/unit/application_spec.rb +57 -2
  337. data/spec/unit/checksum/storage/filesystem_spec.rb +1 -1
  338. data/spec/unit/chef_fs/diff_spec.rb +328 -0
  339. data/spec/unit/chef_fs/file_pattern_spec.rb +526 -0
  340. data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +237 -0
  341. data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +568 -0
  342. data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +220 -0
  343. data/spec/unit/chef_fs/file_system_spec.rb +136 -0
  344. data/spec/unit/client_spec.rb +124 -33
  345. data/spec/unit/config_spec.rb +46 -13
  346. data/spec/unit/cookbook/synchronizer_spec.rb +1 -49
  347. data/spec/unit/cookbook/syntax_check_spec.rb +48 -109
  348. data/spec/unit/cookbook_loader_spec.rb +153 -91
  349. data/spec/unit/cookbook_manifest_spec.rb +81 -81
  350. data/spec/unit/cookbook_spec.rb +3 -20
  351. data/spec/unit/cookbook_version_spec.rb +23 -122
  352. data/spec/unit/daemon_spec.rb +3 -24
  353. data/spec/unit/data_bag_spec.rb +6 -4
  354. data/spec/unit/digester_spec.rb +50 -0
  355. data/spec/unit/dsl/data_query_spec.rb +66 -0
  356. data/spec/unit/dsl/platform_introspection_spec.rb +130 -0
  357. data/spec/unit/dsl/regsitry_helper_spec.rb +55 -0
  358. data/spec/unit/encrypted_data_bag_item_spec.rb +50 -105
  359. data/spec/unit/environment_spec.rb +0 -130
  360. data/spec/unit/exceptions_spec.rb +2 -3
  361. data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +3 -3
  362. data/spec/unit/json_compat_spec.rb +15 -7
  363. data/spec/unit/knife/bootstrap_spec.rb +2 -0
  364. data/spec/unit/knife/configure_spec.rb +20 -14
  365. data/spec/unit/knife/cookbook_metadata_spec.rb +11 -4
  366. data/spec/unit/knife/cookbook_test_spec.rb +1 -0
  367. data/spec/unit/knife/cookbook_upload_spec.rb +43 -8
  368. data/spec/unit/knife/core/bootstrap_context_spec.rb +1 -1
  369. data/spec/unit/knife/core/ui_spec.rb +156 -125
  370. data/spec/unit/knife/data_bag_create_spec.rb +9 -0
  371. data/spec/unit/knife/data_bag_edit_spec.rb +1 -4
  372. data/spec/unit/knife/data_bag_from_file_spec.rb +4 -6
  373. data/spec/unit/knife/data_bag_show_spec.rb +11 -4
  374. data/spec/unit/knife/index_rebuild_spec.rb +96 -33
  375. data/spec/unit/knife/knife_help.rb +7 -7
  376. data/spec/unit/knife/node_edit_spec.rb +6 -33
  377. data/spec/unit/knife/node_run_list_remove_spec.rb +2 -1
  378. data/spec/unit/knife/ssh_spec.rb +12 -15
  379. data/spec/unit/knife/status_spec.rb +2 -2
  380. data/spec/unit/knife_spec.rb +53 -0
  381. data/spec/unit/lwrp_spec.rb +59 -42
  382. data/spec/unit/mixin/checksum_spec.rb +2 -2
  383. data/spec/unit/mixin/deep_merge_spec.rb +101 -799
  384. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +6 -1
  385. data/spec/unit/mixin/params_validate_spec.rb +4 -37
  386. data/spec/unit/mixin/securable_spec.rb +5 -3
  387. data/spec/unit/mixin/template_spec.rb +119 -0
  388. data/spec/unit/node/attribute_spec.rb +195 -173
  389. data/spec/unit/node/immutable_collections_spec.rb +139 -0
  390. data/spec/unit/node_spec.rb +366 -370
  391. data/spec/unit/platform_spec.rb +9 -10
  392. data/spec/unit/provider/breakpoint_spec.rb +8 -8
  393. data/spec/unit/provider/cookbook_file_spec.rb +4 -8
  394. data/spec/unit/provider/directory_spec.rb +96 -64
  395. data/spec/unit/provider/env_spec.rb +2 -2
  396. data/spec/unit/provider/file_spec.rb +48 -39
  397. data/spec/unit/provider/group/dscl_spec.rb +0 -36
  398. data/spec/unit/provider/group/gpasswd_spec.rb +9 -16
  399. data/spec/unit/provider/group/groupadd_spec.rb +4 -3
  400. data/spec/unit/provider/group/groupmod_spec.rb +1 -0
  401. data/spec/unit/provider/group/pw_spec.rb +15 -12
  402. data/spec/unit/provider/group/usermod_spec.rb +6 -21
  403. data/spec/unit/provider/group/windows_spec.rb +8 -0
  404. data/spec/unit/provider/group_spec.rb +6 -28
  405. data/spec/unit/provider/http_request_spec.rb +28 -69
  406. data/spec/unit/provider/ifconfig_spec.rb +2 -2
  407. data/spec/unit/provider/ohai_spec.rb +4 -4
  408. data/spec/unit/provider/package/apt_spec.rb +0 -1
  409. data/spec/unit/provider/package/ips_spec.rb +0 -1
  410. data/spec/unit/provider/package/portage_spec.rb +0 -44
  411. data/spec/unit/provider/package/rpm_spec.rb +0 -12
  412. data/spec/unit/provider/package/rubygems_spec.rb +1 -44
  413. data/spec/unit/provider/package/yum_spec.rb +39 -36
  414. data/spec/unit/provider/package_spec.rb +7 -5
  415. data/spec/unit/provider/registry_key_spec.rb +269 -0
  416. data/spec/unit/provider/remote_directory_spec.rb +7 -3
  417. data/spec/unit/provider/remote_file_spec.rb +36 -0
  418. data/spec/unit/provider/route_spec.rb +4 -3
  419. data/spec/unit/provider/ruby_block_spec.rb +8 -0
  420. data/spec/unit/provider/service/arch_service_spec.rb +5 -5
  421. data/spec/unit/provider/service/debian_service_spec.rb +1 -1
  422. data/spec/unit/provider/service/freebsd_service_spec.rb +5 -5
  423. data/spec/unit/provider/service/init_service_spec.rb +27 -4
  424. data/spec/unit/provider/service/insserv_service_spec.rb +1 -1
  425. data/spec/unit/provider/service/invokercd_service_spec.rb +4 -4
  426. data/spec/unit/provider/service/macosx_spec.rb +11 -66
  427. data/spec/unit/provider/service/redhat_spec.rb +1 -1
  428. data/spec/unit/provider/service/simple_service_spec.rb +3 -3
  429. data/spec/unit/provider/service/upstart_service_spec.rb +9 -9
  430. data/spec/unit/provider/subversion_spec.rb +1 -1
  431. data/spec/unit/provider/template_spec.rb +35 -11
  432. data/spec/unit/provider/user/dscl_spec.rb +285 -681
  433. data/spec/unit/provider/user/useradd_spec.rb +1 -22
  434. data/spec/unit/provider/user_spec.rb +1 -1
  435. data/spec/unit/recipe_spec.rb +10 -8
  436. data/spec/unit/registry_helper_spec.rb +374 -0
  437. data/spec/unit/resource/mount_spec.rb +0 -11
  438. data/spec/unit/resource/registry_key_spec.rb +171 -0
  439. data/spec/unit/resource/remote_file_spec.rb +21 -23
  440. data/spec/unit/resource/ruby_block_spec.rb +7 -3
  441. data/spec/unit/resource/service_spec.rb +11 -0
  442. data/spec/unit/resource_spec.rb +4 -19
  443. data/spec/unit/rest/auth_credentials_spec.rb +2 -19
  444. data/spec/unit/rest_spec.rb +130 -284
  445. data/spec/unit/run_context/cookbook_compiler_spec.rb +181 -0
  446. data/spec/unit/run_context_spec.rb +18 -4
  447. data/spec/unit/run_list_spec.rb +0 -209
  448. data/spec/unit/run_lock_spec.rb +37 -0
  449. data/spec/unit/runner_spec.rb +101 -2
  450. data/spec/unit/scan_access_control_spec.rb +4 -4
  451. data/spec/unit/{shef → shell}/model_wrapper_spec.rb +5 -5
  452. data/spec/unit/{shef/shef_ext_spec.rb → shell/shell_ext_spec.rb} +21 -21
  453. data/spec/unit/{shef/shef_session_spec.rb → shell/shell_session_spec.rb} +14 -69
  454. data/spec/unit/shell_out_spec.rb +18 -0
  455. data/spec/unit/{shef_spec.rb → shell_spec.rb} +20 -20
  456. metadata +275 -234
  457. checksums.yaml +0 -15
  458. data/README.rdoc +0 -177
  459. data/distro/common/html/knife-recipe.1.html +0 -92
  460. data/lib/chef/certificate.rb +0 -161
  461. data/lib/chef/checksum.rb +0 -167
  462. data/lib/chef/checksum_cache.rb +0 -190
  463. data/lib/chef/cookbook_version_selector.rb +0 -168
  464. data/lib/chef/couchdb.rb +0 -246
  465. data/lib/chef/index_queue/amqp_client.rb +0 -116
  466. data/lib/chef/index_queue/consumer.rb +0 -76
  467. data/lib/chef/index_queue/indexable.rb +0 -109
  468. data/lib/chef/knife/bootstrap/ubuntu12.10-gems.erb +0 -60
  469. data/lib/chef/monkey_patches/moneta.rb +0 -50
  470. data/lib/chef/monkey_patches/uri.rb +0 -70
  471. data/lib/chef/openid_registration.rb +0 -187
  472. data/lib/chef/provider/user/solaris.rb +0 -90
  473. data/lib/chef/solr_query.rb +0 -187
  474. data/lib/chef/solr_query/lucene.treetop +0 -150
  475. data/lib/chef/solr_query/lucene_nodes.rb +0 -285
  476. data/lib/chef/solr_query/query_transform.rb +0 -65
  477. data/lib/chef/solr_query/solr_http_request.rb +0 -132
  478. data/lib/chef/webui_user.rb +0 -231
  479. data/spec/data/cookbooks/openldap/files/default/.dotfile +0 -1
  480. data/spec/data/cookbooks/openldap/files/default/.ssh/id_rsa +0 -1
  481. data/spec/data/cookbooks/openldap/files/default/remotedir/.a_dotdir/.a_dotfile_in_a_dotdir +0 -1
  482. data/spec/data/cookbooks/openldap/files/default/remotedir/remotesubdir/.a_dotfile +0 -1
  483. data/spec/data/mac_users/10.7-8.plist.xml +0 -559
  484. data/spec/data/mac_users/10.7-8.shadow.xml +0 -11
  485. data/spec/data/mac_users/10.7.plist.xml +0 -559
  486. data/spec/data/mac_users/10.7.shadow.xml +0 -11
  487. data/spec/data/mac_users/10.8.plist.xml +0 -559
  488. data/spec/data/mac_users/10.8.shadow.xml +0 -21
  489. data/spec/data/mac_users/10.9.plist.xml +0 -560
  490. data/spec/data/mac_users/10.9.shadow.xml +0 -21
  491. data/spec/functional/resource/base.rb +0 -40
  492. data/spec/functional/resource/group_spec.rb +0 -343
  493. data/spec/functional/resource/user/dscl_spec.rb +0 -199
  494. data/spec/unit/certificate_spec.rb +0 -76
  495. data/spec/unit/checksum_cache_spec.rb +0 -209
  496. data/spec/unit/checksum_spec.rb +0 -94
  497. data/spec/unit/couchdb_spec.rb +0 -274
  498. data/spec/unit/index_queue_spec.rb +0 -391
  499. data/spec/unit/mixin/language_spec.rb +0 -305
  500. data/spec/unit/openid_registration_spec.rb +0 -153
  501. data/spec/unit/provider/user/solaris_spec.rb +0 -414
  502. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +0 -47
  503. data/spec/unit/solr_query/query_transform_spec.rb +0 -454
  504. data/spec/unit/solr_query/solr_http_request_spec.rb +0 -244
  505. data/spec/unit/solr_query_spec.rb +0 -203
  506. data/spec/unit/webui_user_spec.rb +0 -238
@@ -18,25 +18,46 @@
18
18
  # limitations under the License.
19
19
 
20
20
  require 'chef/resource_collection'
21
+ require 'chef/cookbook_version'
21
22
  require 'chef/node'
22
23
  require 'chef/role'
23
24
  require 'chef/log'
24
- require 'chef/mixin/language_include_recipe'
25
+ require 'chef/recipe'
26
+ require 'chef/run_context/cookbook_compiler'
25
27
 
26
28
  class Chef
29
+
27
30
  # == Chef::RunContext
28
31
  # Value object that loads and tracks the context of a Chef run
29
32
  class RunContext
30
33
 
31
- # Used to load the node's recipes after expanding its run list
32
- include Chef::Mixin::LanguageIncludeRecipe
34
+ # Chef::Node object for this run
35
+ attr_reader :node
36
+
37
+ # Chef::CookbookCollection for this run
38
+ attr_reader :cookbook_collection
39
+
40
+ # Resource Definitions for this run. Populated when the files in
41
+ # +definitions/+ are evaluated (this is triggered by #load).
42
+ attr_reader :definitions
33
43
 
34
- attr_reader :node, :cookbook_collection, :definitions
44
+ ###
45
+ # These need to be settable so deploy can run a resource_collection
46
+ # independent of any cookbooks via +recipe_eval+
35
47
 
36
- # Needs to be settable so deploy can run a resource_collection independent
37
- # of any cookbooks.
38
- attr_accessor :resource_collection, :immediate_notification_collection, :delayed_notification_collection
48
+ # The Chef::ResourceCollection for this run. Populated by evaluating
49
+ # recipes, which is triggered by #load. (See also: CookbookCompiler)
50
+ attr_accessor :resource_collection
39
51
 
52
+ # A Hash containing the immediate notifications triggered by resources
53
+ # during the converge phase of the chef run.
54
+ attr_accessor :immediate_notification_collection
55
+
56
+ # A Hash containing the delayed (end of run) notifications triggered by
57
+ # resources during the converge phase of the chef run.
58
+ attr_accessor :delayed_notification_collection
59
+
60
+ # Event dispatcher for this run.
40
61
  attr_reader :events
41
62
 
42
63
  # Creates a new Chef::RunContext object and populates its fields. This object gets
@@ -51,50 +72,23 @@ class Chef
51
72
  @immediate_notification_collection = Hash.new {|h,k| h[k] = []}
52
73
  @delayed_notification_collection = Hash.new {|h,k| h[k] = []}
53
74
  @definitions = Hash.new
75
+ @loaded_recipes = {}
76
+ @loaded_attributes = {}
54
77
  @events = events
55
78
 
56
- # TODO: 5/18/2010 cw/timh - See note on Chef::Node's
57
- # cookbook_collection attr_accessor
58
- node.cookbook_collection = cookbook_collection
79
+ @node.run_context = self
59
80
  end
60
81
 
82
+ # Triggers the compile phase of the chef run. Implemented by
83
+ # Chef::RunContext::CookbookCompiler
61
84
  def load(run_list_expansion)
62
- load_libraries
63
-
64
- load_lwrps
65
- load_attributes
66
- load_resource_definitions
67
-
68
- # Precendence rules state that roles' attributes come after
69
- # cookbooks. Now we've loaded attributes from cookbooks with
70
- # load_attributes, apply the expansion attributes (loaded from
71
- # roles) to the node.
72
- @node.apply_expansion_attributes(run_list_expansion)
73
-
74
- @events.recipe_load_start(run_list_expansion.recipes.size)
75
- run_list_expansion.recipes.each do |recipe|
76
- begin
77
- # TODO: timh/cw, 5-14-2010: It's distasteful to be including
78
- # the DSL in a class outside the context of the DSL
79
- include_recipe(recipe)
80
- rescue Chef::Exceptions::RecipeNotFound => e
81
- @events.recipe_not_found(e)
82
- raise
83
- rescue Exception => e
84
- path = resolve_recipe(recipe)
85
- @events.recipe_file_load_failed(path, e)
86
- raise
87
- end
88
- end
89
- @events.recipe_load_complete
90
- end
91
-
92
- def resolve_recipe(recipe_name)
93
- cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name)
94
- cookbook = cookbook_collection[cookbook_name]
95
- cookbook.recipe_filenames_by_name[recipe_short_name]
85
+ compiler = CookbookCompiler.new(self, run_list_expansion, events)
86
+ compiler.compile
96
87
  end
97
88
 
89
+ # Adds an immediate notification to the
90
+ # +immediate_notification_collection+. The notification should be a
91
+ # Chef::Resource::Notification or duck type.
98
92
  def notifies_immediately(notification)
99
93
  nr = notification.notifying_resource
100
94
  if nr.instance_of?(Chef::Resource)
@@ -104,6 +98,8 @@ class Chef
104
98
  end
105
99
  end
106
100
 
101
+ # Adds a delayed notification to the +delayed_notification_collection+. The
102
+ # notification should be a Chef::Resource::Notification or duck type.
107
103
  def notifies_delayed(notification)
108
104
  nr = notification.notifying_resource
109
105
  if nr.instance_of?(Chef::Resource)
@@ -129,107 +125,89 @@ class Chef
129
125
  end
130
126
  end
131
127
 
132
- private
133
-
134
- def load_libraries
135
- @events.library_load_start(count_files_by_segment(:libraries))
136
-
137
- foreach_cookbook_load_segment(:libraries) do |cookbook_name, filename|
138
- begin
139
- Chef::Log.debug("Loading cookbook #{cookbook_name}'s library file: #{filename}")
140
- Kernel.load(filename)
141
- @events.library_file_loaded(filename)
142
- rescue Exception => e
143
- # TODO wrap/munge exception to highlight syntax/name/no method errors.
144
- @events.library_file_load_failed(filename, e)
145
- raise
128
+ # Evaluates the recipes +recipe_names+. Used by DSL::IncludeRecipe
129
+ def include_recipe(*recipe_names)
130
+ result_recipes = Array.new
131
+ recipe_names.flatten.each do |recipe_name|
132
+ if result = load_recipe(recipe_name)
133
+ result_recipes << result
146
134
  end
147
135
  end
136
+ result_recipes
137
+ end
138
+
139
+ # Evaluates the recipe +recipe_name+. Used by DSL::IncludeRecipe
140
+ def load_recipe(recipe_name)
141
+ Chef::Log.debug("Loading Recipe #{recipe_name} via include_recipe")
142
+
143
+ cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name)
144
+ if loaded_fully_qualified_recipe?(cookbook_name, recipe_short_name)
145
+ Chef::Log.debug("I am not loading #{recipe_name}, because I have already seen it.")
146
+ false
147
+ else
148
+ loaded_recipe(cookbook_name, recipe_short_name)
149
+
150
+ cookbook = cookbook_collection[cookbook_name]
151
+ cookbook.load_recipe(recipe_short_name, self)
152
+ end
153
+ end
148
154
 
149
- @events.library_load_complete
155
+ # Looks up an attribute file given the +cookbook_name+ and
156
+ # +attr_file_name+. Used by DSL::IncludeAttribute
157
+ def resolve_attribute(cookbook_name, attr_file_name)
158
+ cookbook = cookbook_collection[cookbook_name]
159
+ raise Chef::Exceptions::CookbookNotFound, "could not find cookbook #{cookbook_name} while loading attribute #{name}" unless cookbook
160
+
161
+ attribute_filename = cookbook.attribute_filenames_by_short_filename[attr_file_name]
162
+ raise Chef::Exceptions::AttributeNotFound, "could not find filename for attribute #{attr_file_name} in cookbook #{cookbook_name}" unless attribute_filename
163
+
164
+ attribute_filename
150
165
  end
151
166
 
152
- def load_lwrps
153
- lwrp_file_count = count_files_by_segment(:providers) + count_files_by_segment(:resources)
154
- @events.lwrp_load_start(lwrp_file_count)
155
- load_lwrp_providers
156
- load_lwrp_resources
157
- @events.lwrp_load_complete
167
+ # An Array of all recipes that have been loaded. This is stored internally
168
+ # as a Hash, so ordering is not preserved when using ruby 1.8.
169
+ #
170
+ # Recipe names are given in fully qualified form, e.g., the recipe "nginx"
171
+ # will be given as "nginx::default"
172
+ #
173
+ # To determine if a particular recipe has been loaded, use #loaded_recipe?
174
+ def loaded_recipes
175
+ @loaded_recipes.keys
158
176
  end
159
177
 
160
- def load_lwrp_providers
161
- foreach_cookbook_load_segment(:providers) do |cookbook_name, filename|
162
- begin
163
- Chef::Log.debug("Loading cookbook #{cookbook_name}'s providers from #{filename}")
164
- Chef::Provider.build_from_file(cookbook_name, filename, self)
165
- @events.lwrp_file_loaded(filename)
166
- rescue Exception => e
167
- # TODO: wrap exception with helpful info
168
- @events.lwrp_file_load_failed(filename, e)
169
- raise
170
- end
171
- end
178
+ # An Array of all attributes files that have been loaded. Stored internally
179
+ # using a Hash, so order is not preserved on ruby 1.8.
180
+ #
181
+ # Attribute file names are given in fully qualified form, e.g.,
182
+ # "nginx::default" instead of "nginx".
183
+ def loaded_attributes
184
+ @loaded_attributes.keys
172
185
  end
173
186
 
174
- def load_lwrp_resources
175
- foreach_cookbook_load_segment(:resources) do |cookbook_name, filename|
176
- begin
177
- Chef::Log.debug("Loading cookbook #{cookbook_name}'s resources from #{filename}")
178
- Chef::Resource.build_from_file(cookbook_name, filename, self)
179
- @events.lwrp_file_loaded(filename)
180
- rescue Exception => e
181
- @events.lwrp_file_load_failed(filename, e)
182
- raise
183
- end
184
- end
187
+ def loaded_fully_qualified_recipe?(cookbook, recipe)
188
+ @loaded_recipes.has_key?("#{cookbook}::#{recipe}")
185
189
  end
186
190
 
187
- def load_attributes
188
- @events.attribute_load_start(count_files_by_segment(:attributes))
189
- foreach_cookbook_load_segment(:attributes) do |cookbook_name, filename|
190
- begin
191
- Chef::Log.debug("Node #{@node.name} loading cookbook #{cookbook_name}'s attribute file #{filename}")
192
- @node.from_file(filename)
193
- rescue Exception => e
194
- @events.attribute_file_load_failed(filename, e)
195
- raise
196
- end
197
- end
198
- @events.attribute_load_complete
199
- end
200
-
201
- def load_resource_definitions
202
- @events.definition_load_start(count_files_by_segment(:definitions))
203
- foreach_cookbook_load_segment(:definitions) do |cookbook_name, filename|
204
- begin
205
- Chef::Log.debug("Loading cookbook #{cookbook_name}'s definitions from #{filename}")
206
- resourcelist = Chef::ResourceDefinitionList.new
207
- resourcelist.from_file(filename)
208
- definitions.merge!(resourcelist.defines) do |key, oldval, newval|
209
- Chef::Log.info("Overriding duplicate definition #{key}, new definition found in #{filename}")
210
- newval
211
- end
212
- @events.definition_file_loaded(filename)
213
- rescue Exception => e
214
- @events.definition_file_load_failed(filename, e)
215
- end
216
- end
217
- @events.definition_load_complete
191
+ # Returns true if +recipe+ has been loaded, false otherwise. Default recipe
192
+ # names are expanded, so `loaded_recipe?("nginx")` and
193
+ # `loaded_recipe?("nginx::default")` are valid and give identical results.
194
+ def loaded_recipe?(recipe)
195
+ cookbook, recipe_name = Chef::Recipe.parse_recipe_name(recipe)
196
+ loaded_fully_qualified_recipe?(cookbook, recipe_name)
218
197
  end
219
198
 
220
- def count_files_by_segment(segment)
221
- cookbook_collection.inject(0) do |count, ( cookbook_name, cookbook )|
222
- count + cookbook.segment_filenames(segment).size
223
- end
199
+ def loaded_fully_qualified_attribute?(cookbook, attribute_file)
200
+ @loaded_attributes.has_key?("#{cookbook}::#{attribute_file}")
224
201
  end
225
202
 
226
- def foreach_cookbook_load_segment(segment, &block)
227
- cookbook_collection.each do |cookbook_name, cookbook|
228
- segment_filenames = cookbook.segment_filenames(segment)
229
- segment_filenames.each do |segment_filename|
230
- block.call(cookbook_name, segment_filename)
231
- end
232
- end
203
+ def loaded_attribute(cookbook, attribute_file)
204
+ @loaded_attributes["#{cookbook}::#{attribute_file}"] = true
205
+ end
206
+
207
+ private
208
+
209
+ def loaded_recipe(cookbook, recipe)
210
+ @loaded_recipes["#{cookbook}::#{recipe}"] = true
233
211
  end
234
212
 
235
213
  end
@@ -0,0 +1,280 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
3
+ # Copyright:: Copyright (c) 2012 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/log'
20
+ require 'chef/recipe'
21
+ require 'chef/resource/lwrp_base'
22
+ require 'chef/provider/lwrp_base'
23
+ require 'chef/resource_definition_list'
24
+
25
+ class Chef
26
+ class RunContext
27
+
28
+ # Implements the compile phase of the chef run by loading/eval-ing files
29
+ # from cookbooks in the correct order and in the correct context.
30
+ class CookbookCompiler
31
+ attr_reader :events
32
+ attr_reader :run_list_expansion
33
+
34
+ def initialize(run_context, run_list_expansion, events)
35
+ @run_context = run_context
36
+ @events = events
37
+ @run_list_expansion = run_list_expansion
38
+ @cookbook_order = nil
39
+ end
40
+
41
+ # Chef::Node object for the current run.
42
+ def node
43
+ @run_context.node
44
+ end
45
+
46
+ # Chef::CookbookCollection object for the current run
47
+ def cookbook_collection
48
+ @run_context.cookbook_collection
49
+ end
50
+
51
+ # Resource Definitions from the compiled cookbooks. This is populated by
52
+ # calling #compile_resource_definitions (which is called by #compile)
53
+ def definitions
54
+ @run_context.definitions
55
+ end
56
+
57
+ # Run the compile phase of the chef run. Loads files in the following order:
58
+ # * Libraries
59
+ # * Attributes
60
+ # * LWRPs
61
+ # * Resource Definitions
62
+ # * Recipes
63
+ #
64
+ # Recipes are loaded in precisely the order specified by the expanded run_list.
65
+ #
66
+ # Other files are loaded in an order derived from the expanded run_list
67
+ # and the dependencies declared by cookbooks' metadata. See
68
+ # #cookbook_order for more information.
69
+ def compile
70
+ compile_libraries
71
+ compile_attributes
72
+ compile_lwrps
73
+ compile_resource_definitions
74
+ compile_recipes
75
+ end
76
+
77
+ # Extracts the cookbook names from the expanded run list, then iterates
78
+ # over the list, recursing through dependencies to give a run_list
79
+ # ordered array of cookbook names with no duplicates. Dependencies appear
80
+ # before the cookbook(s) that depend on them.
81
+ def cookbook_order
82
+ @cookbook_order ||= begin
83
+ ordered_cookbooks = []
84
+ seen_cookbooks = {}
85
+ run_list_expansion.recipes.each do |recipe|
86
+ cookbook = Chef::Recipe.parse_recipe_name(recipe).first
87
+ add_cookbook_with_deps(ordered_cookbooks, seen_cookbooks, cookbook)
88
+ end
89
+ Chef::Log.debug("Cookbooks to compile: #{ordered_cookbooks.inspect}")
90
+ ordered_cookbooks
91
+ end
92
+ end
93
+
94
+ # Loads library files from cookbooks according to #cookbook_order.
95
+ def compile_libraries
96
+ @events.library_load_start(count_files_by_segment(:libraries))
97
+ cookbook_order.each do |cookbook|
98
+ load_libraries_from_cookbook(cookbook)
99
+ end
100
+ @events.library_load_complete
101
+ end
102
+
103
+ # Loads attributes files from cookbooks. Attributes files are loaded
104
+ # according to #cookbook_order; within a cookbook, +default.rb+ is loaded
105
+ # first, then the remaining attributes files in lexical sort order.
106
+ def compile_attributes
107
+ @events.attribute_load_start(count_files_by_segment(:attributes))
108
+ cookbook_order.each do |cookbook|
109
+ load_attributes_from_cookbook(cookbook)
110
+ end
111
+ @events.attribute_load_complete
112
+ end
113
+
114
+ # Loads LWRPs according to #cookbook_order. Providers are loaded before
115
+ # resources on a cookbook-wise basis.
116
+ def compile_lwrps
117
+ lwrp_file_count = count_files_by_segment(:providers) + count_files_by_segment(:resources)
118
+ @events.lwrp_load_start(lwrp_file_count)
119
+ cookbook_order.each do |cookbook|
120
+ load_lwrps_from_cookbook(cookbook)
121
+ end
122
+ @events.lwrp_load_complete
123
+ end
124
+
125
+ # Loads resource definitions according to #cookbook_order
126
+ def compile_resource_definitions
127
+ @events.definition_load_start(count_files_by_segment(:definitions))
128
+ cookbook_order.each do |cookbook|
129
+ load_resource_definitions_from_cookbook(cookbook)
130
+ end
131
+ @events.definition_load_complete
132
+ end
133
+
134
+ # Iterates over the expanded run_list, loading each recipe in turn.
135
+ def compile_recipes
136
+ @events.recipe_load_start(run_list_expansion.recipes.size)
137
+ run_list_expansion.recipes.each do |recipe|
138
+ begin
139
+ @run_context.load_recipe(recipe)
140
+ rescue Chef::Exceptions::RecipeNotFound => e
141
+ @events.recipe_not_found(e)
142
+ raise
143
+ rescue Exception => e
144
+ path = resolve_recipe(recipe)
145
+ @events.recipe_file_load_failed(path, e)
146
+ raise
147
+ end
148
+ end
149
+ @events.recipe_load_complete
150
+ end
151
+
152
+ private
153
+
154
+ def load_attributes_from_cookbook(cookbook_name)
155
+ list_of_attr_files = files_in_cookbook_by_segment(cookbook_name, :attributes).dup
156
+ if default_file = list_of_attr_files.find {|path| File.basename(path) == "default.rb" }
157
+ list_of_attr_files.delete(default_file)
158
+ load_attribute_file(cookbook_name.to_s, default_file)
159
+ end
160
+
161
+ list_of_attr_files.each do |filename|
162
+ load_attribute_file(cookbook_name.to_s, filename)
163
+ end
164
+ end
165
+
166
+ def load_attribute_file(cookbook_name, filename)
167
+ Chef::Log.debug("Node #{node.name} loading cookbook #{cookbook_name}'s attribute file #{filename}")
168
+ attr_file_basename = ::File.basename(filename, ".rb")
169
+ node.include_attribute("#{cookbook_name}::#{attr_file_basename}")
170
+ rescue Exception => e
171
+ @events.attribute_file_load_failed(filename, e)
172
+ raise
173
+ end
174
+
175
+ def load_libraries_from_cookbook(cookbook_name)
176
+ files_in_cookbook_by_segment(cookbook_name, :libraries).each do |filename|
177
+ begin
178
+ Chef::Log.debug("Loading cookbook #{cookbook_name}'s library file: #{filename}")
179
+ Kernel.load(filename)
180
+ @events.library_file_loaded(filename)
181
+ rescue Exception => e
182
+ @events.library_file_load_failed(filename, e)
183
+ raise
184
+ end
185
+ end
186
+ end
187
+
188
+ def load_lwrps_from_cookbook(cookbook_name)
189
+ files_in_cookbook_by_segment(cookbook_name, :providers).each do |filename|
190
+ load_lwrp_provider(cookbook_name, filename)
191
+ end
192
+ files_in_cookbook_by_segment(cookbook_name, :resources).each do |filename|
193
+ load_lwrp_resource(cookbook_name, filename)
194
+ end
195
+ end
196
+
197
+ def load_lwrp_provider(cookbook_name, filename)
198
+ Chef::Log.debug("Loading cookbook #{cookbook_name}'s providers from #{filename}")
199
+ Chef::Provider::LWRPBase.build_from_file(cookbook_name, filename, self)
200
+ @events.lwrp_file_loaded(filename)
201
+ rescue Exception => e
202
+ @events.lwrp_file_load_failed(filename, e)
203
+ raise
204
+ end
205
+
206
+ def load_lwrp_resource(cookbook_name, filename)
207
+ Chef::Log.debug("Loading cookbook #{cookbook_name}'s resources from #{filename}")
208
+ Chef::Resource::LWRPBase.build_from_file(cookbook_name, filename, self)
209
+ @events.lwrp_file_loaded(filename)
210
+ rescue Exception => e
211
+ @events.lwrp_file_load_failed(filename, e)
212
+ raise
213
+ end
214
+
215
+
216
+ def load_resource_definitions_from_cookbook(cookbook_name)
217
+ files_in_cookbook_by_segment(cookbook_name, :definitions).each do |filename|
218
+ begin
219
+ Chef::Log.debug("Loading cookbook #{cookbook_name}'s definitions from #{filename}")
220
+ resourcelist = Chef::ResourceDefinitionList.new
221
+ resourcelist.from_file(filename)
222
+ definitions.merge!(resourcelist.defines) do |key, oldval, newval|
223
+ Chef::Log.info("Overriding duplicate definition #{key}, new definition found in #{filename}")
224
+ newval
225
+ end
226
+ @events.definition_file_loaded(filename)
227
+ rescue Exception => e
228
+ @events.definition_file_load_failed(filename, e)
229
+ raise
230
+ end
231
+ end
232
+ end
233
+
234
+ # Builds up the list of +ordered_cookbooks+ by first recursing through the
235
+ # dependencies of +cookbook+, and then adding +cookbook+ to the list of
236
+ # +ordered_cookbooks+. A cookbook is skipped if it appears in
237
+ # +seen_cookbooks+, otherwise it is added to the set of +seen_cookbooks+
238
+ # before its dependencies are processed.
239
+ def add_cookbook_with_deps(ordered_cookbooks, seen_cookbooks, cookbook)
240
+ return false if seen_cookbooks.key?(cookbook)
241
+
242
+ seen_cookbooks[cookbook] = true
243
+ each_cookbook_dep(cookbook) do |dependency|
244
+ add_cookbook_with_deps(ordered_cookbooks, seen_cookbooks, dependency)
245
+ end
246
+ ordered_cookbooks << cookbook
247
+ end
248
+
249
+
250
+ def count_files_by_segment(segment)
251
+ cookbook_collection.inject(0) do |count, cookbook_by_name|
252
+ count + cookbook_by_name[1].segment_filenames(segment).size
253
+ end
254
+ end
255
+
256
+ # Lists the local paths to files in +cookbook+ of type +segment+
257
+ # (attribute, recipe, etc.), sorted lexically.
258
+ def files_in_cookbook_by_segment(cookbook, segment)
259
+ cookbook_collection[cookbook].segment_filenames(segment).sort
260
+ end
261
+
262
+ # Yields the name of each cookbook depended on by +cookbook_name+ in
263
+ # lexical sort order.
264
+ def each_cookbook_dep(cookbook_name, &block)
265
+ cookbook = cookbook_collection[cookbook_name]
266
+ cookbook.metadata.dependencies.keys.sort.each(&block)
267
+ end
268
+
269
+ # Given a +recipe_name+, finds the file associated with the recipe.
270
+ def resolve_recipe(recipe_name)
271
+ cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name)
272
+ cookbook = cookbook_collection[cookbook_name]
273
+ cookbook.recipe_filenames_by_name[recipe_short_name]
274
+ end
275
+
276
+
277
+ end
278
+
279
+ end
280
+ end