chef 11.4.4 → 11.6.0.hotfix.1

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 (504) hide show
  1. data/README.md +1 -1
  2. data/Rakefile +18 -1
  3. data/bin/chef-service-manager +37 -0
  4. data/distro/common/html/chef-client.8.html +4 -4
  5. data/distro/common/html/chef-expander.8.html +4 -4
  6. data/distro/common/html/chef-expanderctl.8.html +4 -4
  7. data/distro/common/html/chef-server-webui.8.html +4 -4
  8. data/distro/common/html/chef-server.8.html +4 -4
  9. data/distro/common/html/chef-shell.1.html +4 -4
  10. data/distro/common/html/chef-solo.8.html +12 -18
  11. data/distro/common/html/chef-solr.8.html +4 -4
  12. data/distro/common/html/knife-bootstrap.1.html +4 -4
  13. data/distro/common/html/knife-client.1.html +4 -4
  14. data/distro/common/html/knife-configure.1.html +4 -4
  15. data/distro/common/html/knife-cookbook-site.1.html +4 -4
  16. data/distro/common/html/knife-cookbook.1.html +7 -10
  17. data/distro/common/html/knife-data-bag.1.html +7 -10
  18. data/distro/common/html/knife-environment.1.html +6 -8
  19. data/distro/common/html/knife-exec.1.html +4 -4
  20. data/distro/common/html/knife-index.1.html +4 -4
  21. data/distro/common/html/knife-node.1.html +4 -4
  22. data/distro/common/html/knife-role.1.html +4 -4
  23. data/distro/common/html/knife-search.1.html +4 -4
  24. data/distro/common/html/knife-ssh.1.html +4 -4
  25. data/distro/common/html/knife-status.1.html +4 -4
  26. data/distro/common/html/knife-tag.1.html +4 -4
  27. data/distro/common/html/knife.1.html +4 -4
  28. data/distro/common/man/man1/chef-shell.1 +1 -1
  29. data/distro/common/man/man1/knife-bootstrap.1 +1 -1
  30. data/distro/common/man/man1/knife-client.1 +1 -1
  31. data/distro/common/man/man1/knife-configure.1 +1 -1
  32. data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
  33. data/distro/common/man/man1/knife-cookbook.1 +2 -15
  34. data/distro/common/man/man1/knife-data-bag.1 +2 -15
  35. data/distro/common/man/man1/knife-environment.1 +2 -12
  36. data/distro/common/man/man1/knife-exec.1 +1 -1
  37. data/distro/common/man/man1/knife-index.1 +1 -1
  38. data/distro/common/man/man1/knife-node.1 +1 -1
  39. data/distro/common/man/man1/knife-role.1 +1 -1
  40. data/distro/common/man/man1/knife-search.1 +1 -1
  41. data/distro/common/man/man1/knife-ssh.1 +1 -1
  42. data/distro/common/man/man1/knife-status.1 +1 -1
  43. data/distro/common/man/man1/knife-tag.1 +1 -1
  44. data/distro/common/man/man1/knife.1 +1 -1
  45. data/distro/common/man/man8/chef-client.8 +1 -1
  46. data/distro/common/man/man8/chef-expander.8 +1 -1
  47. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  48. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  49. data/distro/common/man/man8/chef-server.8 +1 -1
  50. data/distro/common/man/man8/chef-solo.8 +4 -36
  51. data/distro/common/man/man8/chef-solr.8 +1 -1
  52. data/distro/debian/etc/init.d/chef-client +4 -2
  53. data/distro/windows/service_manager.rb +2 -146
  54. data/lib/chef.rb +1 -1
  55. data/lib/chef/application.rb +5 -12
  56. data/lib/chef/application/apply.rb +2 -0
  57. data/lib/chef/application/client.rb +12 -12
  58. data/lib/chef/application/knife.rb +2 -2
  59. data/lib/chef/application/solo.rb +4 -5
  60. data/lib/chef/application/windows_service.rb +113 -56
  61. data/lib/chef/application/windows_service_manager.rb +179 -0
  62. data/lib/chef/chef_fs.rb +2 -4
  63. data/lib/chef/chef_fs/chef_fs_data_store.rb +371 -0
  64. data/lib/chef/chef_fs/command_line.rb +145 -93
  65. data/lib/chef/chef_fs/config.rb +205 -0
  66. data/lib/chef/chef_fs/data_handler/acl_data_handler.rb +26 -0
  67. data/lib/chef/chef_fs/data_handler/client_data_handler.rb +38 -0
  68. data/lib/chef/chef_fs/data_handler/container_data_handler.rb +29 -0
  69. data/lib/chef/chef_fs/data_handler/cookbook_data_handler.rb +38 -0
  70. data/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +56 -0
  71. data/lib/chef/chef_fs/data_handler/data_handler_base.rb +128 -0
  72. data/lib/chef/chef_fs/data_handler/environment_data_handler.rb +40 -0
  73. data/lib/chef/chef_fs/data_handler/group_data_handler.rb +51 -0
  74. data/lib/chef/chef_fs/data_handler/node_data_handler.rb +36 -0
  75. data/lib/chef/chef_fs/data_handler/role_data_handler.rb +40 -0
  76. data/lib/chef/chef_fs/data_handler/user_data_handler.rb +27 -0
  77. data/lib/chef/chef_fs/file_system.rb +195 -127
  78. data/lib/chef/chef_fs/file_system/acl_dir.rb +64 -0
  79. data/lib/chef/chef_fs/file_system/acl_entry.rb +58 -0
  80. data/lib/chef/chef_fs/file_system/acls_dir.rb +68 -0
  81. data/lib/chef/chef_fs/file_system/already_exists_error.rb +31 -0
  82. data/lib/chef/chef_fs/file_system/base_fs_object.rb +98 -39
  83. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +85 -0
  84. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb +71 -0
  85. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +55 -0
  86. data/lib/chef/chef_fs/file_system/chef_repository_file_system_data_bags_dir.rb +36 -0
  87. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +14 -63
  88. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +93 -3
  89. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +35 -9
  90. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +67 -32
  91. data/lib/chef/chef_fs/file_system/cookbook_file.rb +13 -6
  92. data/lib/chef/chef_fs/file_system/cookbook_frozen_error.rb +31 -0
  93. data/lib/chef/chef_fs/file_system/cookbooks_acl_dir.rb +41 -0
  94. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +102 -21
  95. data/lib/chef/chef_fs/file_system/data_bag_dir.rb +12 -21
  96. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +14 -8
  97. data/lib/chef/chef_fs/file_system/default_environment_cannot_be_modified_error.rb +36 -0
  98. data/lib/chef/chef_fs/file_system/environments_dir.rb +60 -0
  99. data/lib/chef/chef_fs/file_system/file_system_entry.rb +8 -8
  100. data/lib/chef/chef_fs/file_system/file_system_error.rb +3 -1
  101. data/lib/chef/chef_fs/file_system/memory_dir.rb +52 -0
  102. data/lib/chef/chef_fs/file_system/memory_file.rb +17 -0
  103. data/lib/chef/chef_fs/file_system/memory_root.rb +21 -0
  104. data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +48 -0
  105. data/lib/chef/chef_fs/file_system/must_delete_recursively_error.rb +2 -2
  106. data/lib/chef/chef_fs/file_system/nodes_dir.rb +17 -9
  107. data/lib/chef/chef_fs/file_system/nonexistent_fs_object.rb +0 -4
  108. data/lib/chef/chef_fs/file_system/not_found_error.rb +2 -2
  109. data/lib/chef/chef_fs/file_system/operation_failed_error.rb +34 -0
  110. data/lib/chef/chef_fs/file_system/operation_not_allowed_error.rb +48 -0
  111. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +42 -13
  112. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +81 -27
  113. data/lib/chef/chef_fs/knife.rb +68 -29
  114. data/lib/chef/chef_fs/parallelizer.rb +129 -0
  115. data/lib/chef/chef_fs/path_utils.rb +29 -3
  116. data/lib/chef/chef_fs/raw_request.rb +79 -0
  117. data/lib/chef/client.rb +46 -20
  118. data/lib/chef/config.rb +59 -61
  119. data/lib/chef/cookbook/chefignore.rb +2 -1
  120. data/lib/chef/cookbook/synchronizer.rb +8 -6
  121. data/lib/chef/cookbook/syntax_check.rb +17 -2
  122. data/lib/chef/cookbook_uploader.rb +10 -1
  123. data/lib/chef/cookbook_version.rb +0 -109
  124. data/lib/chef/data_bag.rb +15 -6
  125. data/lib/chef/deprecation/mixin/template.rb +49 -0
  126. data/lib/chef/deprecation/provider/cookbook_file.rb +55 -0
  127. data/lib/chef/deprecation/provider/file.rb +197 -0
  128. data/lib/chef/deprecation/provider/remote_file.rb +86 -0
  129. data/lib/chef/deprecation/provider/template.rb +63 -0
  130. data/lib/chef/deprecation/warnings.rb +38 -0
  131. data/lib/chef/encrypted_data_bag_item.rb +153 -61
  132. data/lib/chef/environment.rb +34 -3
  133. data/lib/chef/event_dispatch/base.rb +3 -0
  134. data/lib/chef/exceptions.rb +27 -2
  135. data/lib/chef/file_access_control/unix.rb +64 -7
  136. data/lib/chef/file_access_control/windows.rb +22 -11
  137. data/lib/chef/file_content_management/content_base.rb +56 -0
  138. data/lib/chef/file_content_management/deploy.rb +38 -0
  139. data/lib/chef/file_content_management/deploy/cp.rb +48 -0
  140. data/lib/chef/file_content_management/deploy/mv_unix.rb +77 -0
  141. data/lib/chef/file_content_management/deploy/mv_windows.rb +95 -0
  142. data/lib/chef/file_content_management/tempfile.rb +61 -0
  143. data/lib/chef/formatters/doc.rb +1 -1
  144. data/lib/chef/formatters/error_descriptor.rb +5 -4
  145. data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +23 -3
  146. data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +4 -0
  147. data/lib/chef/json_compat.rb +3 -0
  148. data/lib/chef/knife.rb +12 -3
  149. data/lib/chef/knife/bootstrap.rb +46 -2
  150. data/lib/chef/knife/bootstrap/archlinux-gems.erb +3 -3
  151. data/lib/chef/knife/bootstrap/centos5-gems.erb +3 -3
  152. data/lib/chef/knife/bootstrap/chef-full.erb +4 -4
  153. data/lib/chef/knife/bootstrap/fedora13-gems.erb +3 -3
  154. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +3 -3
  155. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +3 -3
  156. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +3 -3
  157. data/lib/chef/knife/client_show.rb +2 -5
  158. data/lib/chef/knife/configure.rb +3 -3
  159. data/lib/chef/knife/cookbook_create.rb +6 -5
  160. data/lib/chef/knife/cookbook_download.rb +13 -5
  161. data/lib/chef/knife/cookbook_site_share.rb +1 -0
  162. data/lib/chef/knife/cookbook_test.rb +1 -0
  163. data/lib/chef/knife/cookbook_upload.rb +4 -9
  164. data/lib/chef/knife/core/bootstrap_context.rb +10 -4
  165. data/lib/chef/knife/core/generic_presenter.rb +16 -0
  166. data/lib/chef/knife/core/node_editor.rb +1 -1
  167. data/lib/chef/knife/core/subcommand_loader.rb +43 -12
  168. data/lib/chef/knife/core/ui.rb +19 -4
  169. data/lib/chef/knife/delete.rb +76 -9
  170. data/lib/chef/knife/deps.rb +139 -0
  171. data/lib/chef/knife/diff.rb +22 -5
  172. data/lib/chef/knife/download.rb +16 -3
  173. data/lib/chef/knife/edit.rb +76 -0
  174. data/lib/chef/knife/environment_show.rb +2 -7
  175. data/lib/chef/knife/list.rb +91 -47
  176. data/lib/chef/knife/node_run_list_set.rb +66 -0
  177. data/lib/chef/knife/node_show.rb +1 -7
  178. data/lib/chef/knife/raw.rb +20 -64
  179. data/lib/chef/knife/role_show.rb +2 -4
  180. data/lib/chef/knife/search.rb +5 -6
  181. data/lib/chef/knife/show.rb +34 -11
  182. data/lib/chef/knife/ssh.rb +8 -0
  183. data/lib/chef/knife/upload.rb +23 -4
  184. data/lib/chef/knife/user_show.rb +2 -5
  185. data/lib/chef/knife/xargs.rb +265 -0
  186. data/lib/chef/log.rb +2 -2
  187. data/lib/chef/mixin/file_class.rb +0 -9
  188. data/lib/chef/mixin/language_include_recipe.rb +1 -1
  189. data/lib/chef/mixin/params_validate.rb +19 -9
  190. data/lib/chef/mixin/template.rb +126 -36
  191. data/lib/chef/mixin/windows_architecture_helper.rb +91 -0
  192. data/lib/chef/monkey_patches/file.rb +26 -0
  193. data/lib/chef/monkey_patches/net-ssh-multi.rb +140 -0
  194. data/lib/chef/monkey_patches/securerandom.rb +44 -0
  195. data/lib/chef/monologger.rb +93 -0
  196. data/lib/chef/node.rb +4 -0
  197. data/lib/chef/platform.rb +4 -490
  198. data/lib/chef/platform/provider_mapping.rb +529 -0
  199. data/lib/chef/{monkey_patches/dir.rb → platform/query_helpers.rb} +25 -19
  200. data/lib/chef/provider.rb +12 -9
  201. data/lib/chef/provider/batch.rb +35 -0
  202. data/lib/chef/provider/cookbook_file.rb +9 -78
  203. data/lib/chef/provider/cookbook_file/content.rb +49 -0
  204. data/lib/chef/provider/deploy.rb +24 -20
  205. data/lib/chef/provider/deploy/revision.rb +27 -0
  206. data/lib/chef/provider/directory.rb +19 -22
  207. data/lib/chef/provider/execute.rb +22 -5
  208. data/lib/chef/provider/file.rb +299 -217
  209. data/lib/chef/provider/file/content.rb +39 -0
  210. data/lib/chef/provider/git.rb +76 -43
  211. data/lib/chef/provider/group/usermod.rb +2 -2
  212. data/lib/chef/provider/ifconfig.rb +25 -35
  213. data/lib/chef/provider/ifconfig/debian.rb +71 -0
  214. data/lib/chef/provider/ifconfig/redhat.rb +47 -0
  215. data/lib/chef/provider/link.rb +10 -3
  216. data/lib/chef/provider/mount.rb +1 -1
  217. data/lib/chef/provider/mount/mount.rb +8 -3
  218. data/lib/chef/provider/mount/windows.rb +4 -1
  219. data/lib/chef/provider/package/portage.rb +9 -4
  220. data/lib/chef/provider/package/rubygems.rb +45 -10
  221. data/lib/chef/provider/package/smartos.rb +47 -36
  222. data/lib/chef/provider/package/yum.rb +19 -12
  223. data/lib/chef/provider/package/zypper.rb +45 -55
  224. data/lib/chef/provider/powershell_script.rb +77 -0
  225. data/lib/chef/provider/remote_directory.rb +5 -6
  226. data/lib/chef/provider/remote_file.rb +12 -108
  227. data/lib/chef/provider/remote_file/cache_control_data.rb +165 -0
  228. data/lib/chef/provider/remote_file/content.rb +75 -0
  229. data/lib/chef/provider/remote_file/fetcher.rb +43 -0
  230. data/lib/chef/provider/remote_file/ftp.rb +183 -0
  231. data/lib/chef/provider/remote_file/http.rb +124 -0
  232. data/lib/chef/provider/remote_file/local_file.rb +47 -0
  233. data/lib/chef/provider/route.rb +6 -2
  234. data/lib/chef/provider/script.rb +14 -2
  235. data/lib/chef/provider/service/macosx.rb +16 -10
  236. data/lib/chef/provider/service/solaris.rb +6 -5
  237. data/lib/chef/provider/template.rb +16 -78
  238. data/lib/chef/provider/template/content.rb +61 -0
  239. data/lib/chef/provider/user/solaris.rb +90 -0
  240. data/lib/chef/provider/user/useradd.rb +76 -63
  241. data/lib/chef/provider/windows_script.rb +73 -0
  242. data/lib/chef/providers.rb +16 -0
  243. data/lib/chef/resource.rb +23 -2
  244. data/lib/chef/resource/batch.rb +31 -0
  245. data/lib/chef/resource/conditional.rb +4 -0
  246. data/lib/chef/resource/conditional_action_not_nothing.rb +48 -0
  247. data/lib/chef/resource/file.rb +31 -3
  248. data/lib/chef/resource/link.rb +17 -0
  249. data/lib/chef/resource/lwrp_base.rb +1 -1
  250. data/lib/chef/resource/mount.rb +29 -2
  251. data/lib/chef/resource/powershell_script.rb +31 -0
  252. data/lib/chef/resource/remote_file.rb +47 -1
  253. data/lib/chef/resource/route.rb +1 -1
  254. data/lib/chef/resource/template.rb +145 -0
  255. data/lib/chef/resource/windows_script.rb +62 -0
  256. data/lib/chef/resource_collection.rb +45 -11
  257. data/lib/chef/resource_reporter.rb +81 -52
  258. data/lib/chef/resources.rb +2 -0
  259. data/lib/chef/rest.rb +13 -4
  260. data/lib/chef/rest/rest_request.rb +5 -1
  261. data/lib/chef/run_context/cookbook_compiler.rb +3 -3
  262. data/lib/chef/run_list/run_list_expansion.rb +1 -1
  263. data/lib/chef/run_lock.rb +7 -1
  264. data/lib/chef/runner.rb +0 -1
  265. data/lib/chef/scan_access_control.rb +6 -1
  266. data/lib/chef/search/query.rb +2 -2
  267. data/lib/chef/shell/shell_session.rb +2 -2
  268. data/lib/chef/util/backup.rb +84 -0
  269. data/lib/chef/util/diff.rb +145 -0
  270. data/lib/chef/util/file_edit.rb +1 -1
  271. data/lib/chef/util/selinux.rb +100 -0
  272. data/lib/chef/util/windows/net_user.rb +14 -1
  273. data/lib/chef/util/windows/volume.rb +2 -2
  274. data/lib/chef/version.rb +1 -1
  275. data/lib/chef/version/platform.rb +42 -0
  276. data/lib/chef/version_class.rb +1 -1
  277. data/lib/chef/version_constraint.rb +6 -5
  278. data/lib/chef/version_constraint/platform.rb +26 -0
  279. data/lib/chef/win32/api/file.rb +8 -2
  280. data/lib/chef/win32/version.rb +25 -8
  281. data/spec/data/apt/chef-integration-test-1.0/debian/changelog +5 -0
  282. data/spec/data/apt/chef-integration-test-1.0/debian/compat +1 -0
  283. data/spec/data/apt/chef-integration-test-1.0/debian/control +13 -0
  284. data/spec/data/apt/chef-integration-test-1.0/debian/copyright +34 -0
  285. data/spec/data/apt/chef-integration-test-1.0/debian/files +1 -0
  286. data/spec/data/apt/chef-integration-test-1.0/debian/rules +13 -0
  287. data/spec/data/apt/chef-integration-test-1.0/debian/source/format +1 -0
  288. data/spec/data/apt/chef-integration-test-1.1/debian/changelog +11 -0
  289. data/spec/data/apt/chef-integration-test-1.1/debian/compat +1 -0
  290. data/spec/data/apt/chef-integration-test-1.1/debian/control +13 -0
  291. data/spec/data/apt/chef-integration-test-1.1/debian/copyright +34 -0
  292. data/spec/data/apt/chef-integration-test-1.1/debian/files +1 -0
  293. data/spec/data/apt/chef-integration-test-1.1/debian/rules +13 -0
  294. data/spec/data/apt/chef-integration-test-1.1/debian/source/format +1 -0
  295. data/spec/data/apt/chef-integration-test_1.0-1_amd64.changes +22 -0
  296. data/spec/data/apt/chef-integration-test_1.0-1_amd64.deb +0 -0
  297. data/spec/data/apt/chef-integration-test_1.0.orig.tar.gz +0 -0
  298. data/spec/data/apt/chef-integration-test_1.1-1_amd64.changes +22 -0
  299. data/spec/data/apt/chef-integration-test_1.1-1_amd64.deb +0 -0
  300. data/spec/data/apt/chef-integration-test_1.1.orig.tar.gz +0 -0
  301. data/spec/data/apt/var/www/apt/conf/distributions +7 -0
  302. data/spec/data/apt/var/www/apt/conf/incoming +4 -0
  303. data/spec/data/apt/var/www/apt/conf/pulls +3 -0
  304. data/spec/data/apt/var/www/apt/db/checksums.db +0 -0
  305. data/spec/data/apt/var/www/apt/db/contents.cache.db +0 -0
  306. data/spec/data/apt/var/www/apt/db/packages.db +0 -0
  307. data/spec/data/apt/var/www/apt/db/references.db +0 -0
  308. data/spec/data/apt/var/www/apt/db/release.caches.db +0 -0
  309. data/spec/data/apt/var/www/apt/db/version +4 -0
  310. data/spec/data/apt/var/www/apt/dists/sid/Release +19 -0
  311. data/spec/data/apt/var/www/apt/dists/sid/main/binary-amd64/Packages +16 -0
  312. data/spec/data/apt/var/www/apt/dists/sid/main/binary-amd64/Packages.gz +0 -0
  313. data/spec/data/apt/var/www/apt/dists/sid/main/binary-amd64/Release +5 -0
  314. data/spec/data/apt/var/www/apt/dists/sid/main/binary-i386/Packages +0 -0
  315. data/spec/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.0-1_amd64.deb +0 -0
  316. data/spec/data/apt/var/www/apt/pool/main/c/chef-integration-test/chef-integration-test_1.1-1_amd64.deb +0 -0
  317. data/spec/data/bootstrap/encrypted_data_bag_secret +1 -0
  318. data/spec/data/bootstrap/secret.erb +9 -0
  319. data/spec/data/cookbooks/ignorken/recipes/default.rb +1 -0
  320. data/spec/data/cookbooks/ignorken/recipes/ignoreme.rb +2 -0
  321. data/spec/data/cookbooks/openldap/files/default/.dotfile +1 -0
  322. data/spec/data/cookbooks/openldap/files/default/.ssh/id_rsa +1 -0
  323. data/spec/data/cookbooks/openldap/files/default/remotedir/.a_dotdir/.a_dotfile_in_a_dotdir +1 -0
  324. data/spec/data/cookbooks/openldap/files/default/remotedir/remotesubdir/.a_dotfile +1 -0
  325. data/spec/data/cookbooks/openldap/templates/default/all_windows_line_endings.erb +4 -0
  326. data/spec/data/cookbooks/openldap/templates/default/helper_test.erb +1 -0
  327. data/spec/data/cookbooks/openldap/templates/default/helpers_via_partial_test.erb +1 -0
  328. data/spec/data/cookbooks/openldap/templates/default/no_windows_line_endings.erb +4 -0
  329. data/spec/data/cookbooks/openldap/templates/default/some_windows_line_endings.erb +4 -0
  330. data/spec/data/cookbooks/preseed/files/default/preseed-file.seed +1 -0
  331. data/spec/data/cookbooks/preseed/templates/default/preseed-template.seed +1 -0
  332. data/spec/data/file-providers-method-snapshot-chef-11-4.json +127 -0
  333. data/spec/data/git_bundles/example-repo.gitbundle +0 -0
  334. data/spec/data/knife-home/.chef/plugins/knife/example_home_subcommand.rb +0 -0
  335. data/spec/data/knife_subcommand/test_yourself.rb +8 -0
  336. data/spec/data/null_config.rb +1 -0
  337. data/spec/data/partial_one.erb +1 -1
  338. data/spec/data/remote_file/nyan_cat.png.gz +0 -0
  339. data/spec/functional/file_content_management/deploy_strategies_spec.rb +238 -0
  340. data/spec/functional/knife/exec_spec.rb +2 -2
  341. data/spec/functional/provider/remote_file/cache_control_data_spec.rb +101 -0
  342. data/spec/functional/resource/batch_spec.rb +64 -0
  343. data/spec/functional/resource/cookbook_file_spec.rb +2 -3
  344. data/spec/functional/resource/deploy_revision_spec.rb +180 -0
  345. data/spec/functional/resource/directory_spec.rb +2 -2
  346. data/spec/functional/resource/file_spec.rb +17 -1
  347. data/spec/functional/resource/git_spec.rb +259 -0
  348. data/spec/functional/resource/link_spec.rb +422 -388
  349. data/spec/functional/resource/package_spec.rb +297 -0
  350. data/spec/functional/resource/powershell_spec.rb +188 -0
  351. data/spec/functional/resource/registry_spec.rb +8 -4
  352. data/spec/functional/resource/remote_directory_spec.rb +2 -2
  353. data/spec/functional/resource/remote_file_spec.rb +97 -29
  354. data/spec/functional/resource/template_spec.rb +173 -17
  355. data/spec/functional/resource/user_spec.rb +547 -0
  356. data/spec/functional/run_lock_spec.rb +5 -0
  357. data/spec/functional/shell_spec.rb +2 -1
  358. data/spec/functional/win32/service_manager_spec.rb +269 -0
  359. data/spec/functional/win32/versions_spec.rb +78 -0
  360. data/spec/integration/knife/chef_repo_path_spec.rb +805 -0
  361. data/spec/integration/knife/chef_repository_file_system_spec.rb +276 -0
  362. data/spec/integration/knife/chefignore_spec.rb +271 -0
  363. data/spec/integration/knife/delete_spec.rb +944 -0
  364. data/spec/integration/knife/deps_spec.rb +648 -0
  365. data/spec/integration/knife/diff_spec.rb +536 -0
  366. data/spec/integration/knife/download_spec.rb +962 -0
  367. data/spec/integration/knife/list_spec.rb +633 -0
  368. data/spec/integration/knife/raw_spec.rb +166 -0
  369. data/spec/integration/knife/redirection_spec.rb +57 -0
  370. data/spec/integration/knife/show_spec.rb +158 -0
  371. data/spec/integration/knife/upload_spec.rb +1060 -0
  372. data/spec/integration/solo/solo_spec.rb +41 -0
  373. data/spec/spec_helper.rb +55 -1
  374. data/spec/support/chef_helpers.rb +32 -0
  375. data/spec/support/platform_helpers.rb +40 -0
  376. data/spec/support/platforms/win32/spec_service.rb +59 -0
  377. data/spec/support/shared/functional/directory_resource.rb +43 -16
  378. data/spec/support/shared/functional/file_resource.rb +661 -20
  379. data/spec/support/shared/functional/securable_resource.rb +109 -8
  380. data/spec/support/shared/functional/securable_resource_with_reporting.rb +39 -31
  381. data/spec/support/shared/integration/integration_helper.rb +166 -0
  382. data/spec/support/shared/integration/knife_support.rb +171 -0
  383. data/spec/support/shared/unit/execute_resource.rb +125 -0
  384. data/spec/support/shared/unit/file_system_support.rb +8 -48
  385. data/spec/support/shared/unit/provider/file.rb +609 -0
  386. data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +407 -0
  387. data/spec/support/shared/unit/script_resource.rb +52 -0
  388. data/spec/support/shared/unit/windows_script_resource.rb +48 -0
  389. data/spec/tiny_server.rb +13 -11
  390. data/spec/unit/application/client_spec.rb +39 -1
  391. data/spec/unit/application/knife_spec.rb +12 -0
  392. data/spec/unit/application/solo_spec.rb +1 -1
  393. data/spec/unit/application_spec.rb +57 -2
  394. data/spec/unit/chef_fs/diff_spec.rb +30 -31
  395. data/spec/unit/chef_fs/file_pattern_spec.rb +2 -2
  396. data/spec/unit/chef_fs/file_system_spec.rb +2 -3
  397. data/spec/unit/client_spec.rb +20 -1
  398. data/spec/unit/config_spec.rb +70 -52
  399. data/spec/unit/cookbook/synchronizer_spec.rb +49 -1
  400. data/spec/unit/cookbook/syntax_check_spec.rb +28 -3
  401. data/spec/unit/cookbook_loader_spec.rb +3 -2
  402. data/spec/unit/daemon_spec.rb +7 -7
  403. data/spec/unit/data_bag_spec.rb +7 -0
  404. data/spec/unit/deprecation_spec.rb +86 -0
  405. data/spec/unit/encrypted_data_bag_item_spec.rb +183 -88
  406. data/spec/unit/environment_spec.rb +98 -0
  407. data/spec/unit/exceptions_spec.rb +6 -1
  408. data/spec/unit/file_access_control_spec.rb +21 -1
  409. data/spec/unit/file_content_management/deploy/cp_spec.rb +46 -0
  410. data/spec/unit/file_content_management/deploy/mv_unix_spec.rb +103 -0
  411. data/spec/unit/file_content_management/deploy/mv_windows_spec.rb +179 -0
  412. data/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb +38 -2
  413. data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +3 -2
  414. data/spec/unit/knife/bootstrap_spec.rb +128 -29
  415. data/spec/unit/knife/configure_spec.rb +42 -26
  416. data/spec/unit/knife/cookbook_download_spec.rb +24 -3
  417. data/spec/unit/knife/cookbook_upload_spec.rb +8 -4
  418. data/spec/unit/knife/core/bootstrap_context_spec.rb +78 -61
  419. data/spec/unit/knife/core/subcommand_loader_spec.rb +20 -0
  420. data/spec/unit/knife/core/ui_spec.rb +41 -0
  421. data/spec/unit/knife/node_run_list_set_spec.rb +140 -0
  422. data/spec/unit/knife_spec.rb +21 -0
  423. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +1 -0
  424. data/spec/unit/mixin/params_validate_spec.rb +35 -0
  425. data/spec/unit/mixin/template_spec.rb +69 -57
  426. data/spec/unit/mixin/windows_architecture_helper_spec.rb +83 -0
  427. data/spec/unit/node_spec.rb +7 -0
  428. data/spec/unit/platform_spec.rb +15 -1
  429. data/spec/unit/provider/cookbook_file/content_spec.rb +40 -0
  430. data/spec/unit/provider/cookbook_file_spec.rb +26 -183
  431. data/spec/unit/provider/cron/solaris_spec.rb +1 -1
  432. data/spec/unit/provider/deploy/revision_spec.rb +19 -11
  433. data/spec/unit/provider/deploy_spec.rb +2 -2
  434. data/spec/unit/provider/directory_spec.rb +23 -23
  435. data/spec/unit/provider/execute_spec.rb +27 -1
  436. data/spec/unit/provider/file/content_spec.rb +101 -0
  437. data/spec/unit/provider/file_spec.rb +25 -484
  438. data/spec/unit/provider/git_spec.rb +224 -28
  439. data/spec/unit/provider/group/usermod_spec.rb +3 -1
  440. data/spec/unit/provider/ifconfig/debian_spec.rb +89 -0
  441. data/spec/unit/provider/ifconfig/redhat_spec.rb +71 -0
  442. data/spec/unit/provider/ifconfig_spec.rb +0 -33
  443. data/spec/unit/provider/mount/mount_spec.rb +33 -2
  444. data/spec/unit/provider/mount/windows_spec.rb +4 -1
  445. data/spec/unit/provider/mount_spec.rb +16 -6
  446. data/spec/unit/provider/package/portage_spec.rb +44 -0
  447. data/spec/unit/provider/package/rubygems_spec.rb +44 -1
  448. data/spec/unit/provider/package/smartos_spec.rb +3 -2
  449. data/spec/unit/provider/package/yum_spec.rb +36 -39
  450. data/spec/unit/provider/package/zypper_spec.rb +84 -22
  451. data/spec/unit/provider/package_spec.rb +0 -4
  452. data/spec/unit/provider/powershell_spec.rb +38 -0
  453. data/spec/unit/provider/remote_directory_spec.rb +0 -4
  454. data/spec/unit/provider/remote_file/cache_control_data_spec.rb +211 -0
  455. data/spec/unit/provider/remote_file/content_spec.rb +230 -0
  456. data/spec/unit/provider/remote_file/fetcher_spec.rb +75 -0
  457. data/spec/unit/provider/remote_file/ftp_spec.rb +224 -0
  458. data/spec/unit/provider/remote_file/http_spec.rb +319 -0
  459. data/spec/unit/provider/remote_file/local_file_spec.rb +60 -0
  460. data/spec/unit/provider/remote_file_spec.rb +33 -295
  461. data/spec/unit/provider/route_spec.rb +25 -9
  462. data/spec/unit/provider/service/macosx_spec.rb +176 -152
  463. data/spec/unit/provider/service/solaris_smf_service_spec.rb +21 -18
  464. data/spec/unit/provider/service/systemd_service_spec.rb +2 -2
  465. data/spec/unit/provider/service/upstart_service_spec.rb +2 -2
  466. data/spec/unit/provider/service_spec.rb +3 -3
  467. data/spec/unit/provider/template/content_spec.rb +78 -0
  468. data/spec/unit/provider/template_spec.rb +52 -184
  469. data/spec/unit/provider/user/solaris_spec.rb +80 -0
  470. data/spec/unit/provider/user/useradd_spec.rb +12 -358
  471. data/spec/unit/resource/batch_spec.rb +48 -0
  472. data/spec/unit/resource/conditional_action_not_nothing_spec.rb +45 -0
  473. data/spec/unit/resource/execute_spec.rb +3 -101
  474. data/spec/unit/resource/file_spec.rb +0 -5
  475. data/spec/unit/resource/group_spec.rb +9 -0
  476. data/spec/unit/resource/ifconfig_spec.rb +60 -1
  477. data/spec/unit/resource/link_spec.rb +1 -0
  478. data/spec/unit/resource/mount_spec.rb +37 -0
  479. data/spec/unit/resource/powershell_spec.rb +48 -0
  480. data/spec/unit/resource/remote_file_spec.rb +44 -4
  481. data/spec/unit/resource/route_spec.rb +1 -1
  482. data/spec/unit/resource/script_spec.rb +13 -36
  483. data/spec/unit/resource/template_spec.rb +111 -8
  484. data/spec/unit/resource/user_spec.rb +7 -0
  485. data/spec/unit/resource_collection_spec.rb +61 -32
  486. data/spec/unit/resource_reporter_spec.rb +115 -102
  487. data/spec/unit/resource_spec.rb +170 -1
  488. data/spec/unit/rest/auth_credentials_spec.rb +2 -2
  489. data/spec/unit/rest_spec.rb +6 -2
  490. data/spec/unit/run_context/cookbook_compiler_spec.rb +9 -0
  491. data/spec/unit/runner_spec.rb +1 -1
  492. data/spec/unit/scan_access_control_spec.rb +4 -2
  493. data/spec/unit/shell/shell_session_spec.rb +15 -2
  494. data/spec/unit/util/backup_spec.rb +149 -0
  495. data/spec/unit/util/diff_spec.rb +596 -0
  496. data/spec/unit/util/selinux_spec.rb +172 -0
  497. data/spec/unit/version/platform_spec.rb +61 -0
  498. data/spec/unit/version_constraint/platform_spec.rb +46 -0
  499. data/spec/unit/version_constraint_spec.rb +5 -0
  500. metadata +233 -10
  501. data/lib/chef/chef_fs/file_system/data_bag_item.rb +0 -59
  502. data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +0 -237
  503. data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +0 -568
  504. data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +0 -220
@@ -27,8 +27,6 @@ class Chef
27
27
  class Provider
28
28
  class Directory < Chef::Provider::File
29
29
 
30
- include Chef::Mixin::EnforceOwnershipAndPermissions
31
-
32
30
  def whyrun_supported?
33
31
  true
34
32
  end
@@ -36,15 +34,13 @@ class Chef
36
34
  def load_current_resource
37
35
  @current_resource = Chef::Resource::Directory.new(@new_resource.name)
38
36
  @current_resource.path(@new_resource.path)
39
- setup_acl
40
-
37
+ if ::File.exists?(@current_resource.path) && @action != :create_if_missing
38
+ load_resource_attributes_from_file(@current_resource)
39
+ end
41
40
  @current_resource
42
41
  end
43
42
 
44
43
  def define_resource_requirements
45
- # this must be evaluated before whyrun messages are printed
46
- access_controls.requires_changes?
47
-
48
44
  requirements.assert(:create) do |a|
49
45
  # Make sure the parent dir exists, or else fail.
50
46
  # for why run, print a message explaining the potential error.
@@ -61,8 +57,8 @@ class Chef
61
57
  # find the lowest-level directory in @new_resource.path that already exists
62
58
  # make sure we have write permissions to that directory
63
59
  is_parent_writable = lambda do |base_dir|
64
- base_dir = ::File.dirname(base_dir)
65
- if ::File.exist?(base_dir)
60
+ base_dir = ::File.dirname(base_dir)
61
+ if ::File.exists?(base_dir)
66
62
  ::File.writable?(base_dir)
67
63
  else
68
64
  is_parent_writable.call(base_dir)
@@ -72,49 +68,50 @@ class Chef
72
68
  else
73
69
  # in why run mode & parent directory does not exist no permissions check is required
74
70
  # If not in why run, permissions must be valid and we rely on prior assertion that dir exists
75
- if !whyrun_mode? || ::File.exist?(parent_directory)
71
+ if !whyrun_mode? || ::File.exists?(parent_directory)
76
72
  ::File.writable?(parent_directory)
77
73
  else
78
74
  true
79
75
  end
80
76
  end
81
77
  end
82
- a.failure_message(Chef::Exceptions::InsufficientPermissions,
78
+ a.failure_message(Chef::Exceptions::InsufficientPermissions,
83
79
  "Cannot create #{@new_resource} at #{@new_resource.path} due to insufficient permissions")
84
80
  end
85
81
 
86
- requirements.assert(:delete) do |a|
87
- a.assertion do
88
- if ::File.exist?(@new_resource.path)
89
- ::File.directory?(@new_resource.path) && ::File.writable?(@new_resource.path)
82
+ requirements.assert(:delete) do |a|
83
+ a.assertion do
84
+ if ::File.exists?(@new_resource.path)
85
+ ::File.directory?(@new_resource.path) && ::File.writable?(@new_resource.path)
90
86
  else
91
87
  true
92
88
  end
93
89
  end
94
90
  a.failure_message(RuntimeError, "Cannot delete #{@new_resource} at #{@new_resource.path}!")
95
- # No why-run handling here:
91
+ # No why-run handling here:
96
92
  # * if we don't have permissions, this is unlikely to be changed earlier in the run
97
93
  # * if the target is a file (not a dir), there's no reasonable path by which this would have been changed
98
94
  end
99
95
  end
100
96
 
101
97
  def action_create
102
- unless ::File.exist?(@new_resource.path)
103
- converge_by("create new directory #{@new_resource.path}") do
98
+ unless ::File.exists?(@new_resource.path)
99
+ converge_by("create new directory #{@new_resource.path}") do
104
100
  if @new_resource.recursive == true
105
101
  ::FileUtils.mkdir_p(@new_resource.path)
106
102
  else
107
103
  ::Dir.mkdir(@new_resource.path)
108
104
  end
109
105
  Chef::Log.info("#{@new_resource} created directory #{@new_resource.path}")
110
- end
106
+ end
111
107
  end
112
- set_all_access_controls
113
- update_new_file_state
108
+ do_acl_changes
109
+ do_selinux(true)
110
+ load_resource_attributes_from_file(@new_resource)
114
111
  end
115
112
 
116
113
  def action_delete
117
- if ::File.exist?(@new_resource.path)
114
+ if ::File.exists?(@new_resource.path)
118
115
  converge_by("delete existing directory #{@new_resource.path}") do
119
116
  if @new_resource.recursive == true
120
117
  FileUtils.rm_rf(@new_resource.path)
@@ -37,11 +37,9 @@ class Chef
37
37
  def action_run
38
38
  opts = {}
39
39
 
40
- if sentinel_file = @new_resource.creates
41
- if ::File.exists?(sentinel_file)
42
- Chef::Log.debug("#{@new_resource} sentinel file #{sentinel_file} exists - nothing to do")
43
- return false
44
- end
40
+ if sentinel_file = sentinel_file_if_exists
41
+ Chef::Log.debug("#{@new_resource} sentinel file #{sentinel_file} exists - nothing to do")
42
+ return false
45
43
  end
46
44
 
47
45
  # original implementation did not specify a timeout, but ShellOut
@@ -63,6 +61,25 @@ class Chef
63
61
  Chef::Log.info("#{@new_resource} ran successfully")
64
62
  end
65
63
  end
64
+
65
+ private
66
+
67
+ def sentinel_file_if_exists
68
+ if sentinel_file = @new_resource.creates
69
+ relative = Pathname(sentinel_file).relative?
70
+ cwd = @new_resource.cwd
71
+ if relative && !cwd
72
+ Chef::Log.warn "You have provided relative path for execute#creates (#{sentinel_file}) without execute#cwd (see CHEF-3819)"
73
+ end
74
+
75
+ if ::File.exists?(sentinel_file)
76
+ sentinel_file
77
+ elsif cwd && relative
78
+ sentinel_file = ::File.join(cwd, sentinel_file)
79
+ sentinel_file if ::File.exists?(sentinel_file)
80
+ end
81
+ end
82
+ end
66
83
  end
67
84
  end
68
85
  end
@@ -1,6 +1,7 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
- # Copyright:: Copyright (c) 2008 Opscode, Inc.
3
+ # Author:: Lamont Granquist (<lamont@opscode.com>)
4
+ # Copyright:: Copyright (c) 2008-2013 Opscode, Inc.
4
5
  # License:: Apache License, Version 2.0
5
6
  #
6
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,230 +20,107 @@
19
20
  require 'chef/config'
20
21
  require 'chef/log'
21
22
  require 'chef/resource/file'
22
- require 'chef/mixin/checksum'
23
23
  require 'chef/provider'
24
24
  require 'etc'
25
25
  require 'fileutils'
26
26
  require 'chef/scan_access_control'
27
+ require 'chef/mixin/checksum'
27
28
  require 'chef/mixin/shell_out'
29
+ require 'chef/mixin/file_class'
30
+ require 'chef/util/backup'
31
+ require 'chef/util/diff'
32
+ require 'chef/deprecation/provider/file'
33
+ require 'chef/deprecation/warnings'
34
+ require 'chef/file_content_management/deploy'
35
+
36
+ # The Tao of File Providers:
37
+ # - the content provider must always return a tempfile that we can delete/mv
38
+ # - do_create_file shall always create the file first and obey umask when perms are not specified
39
+ # - do_contents_changes may assume the destination file exists (simplifies exception checking,
40
+ # and always gives us something to diff against)
41
+ # - do_contents_changes must restore the perms to the dest file and not obliterate them with
42
+ # random tempfile permissions
43
+ # - do_acl_changes may assume perms were not modified between lcr and when it runs (although the
44
+ # file may have been created)
28
45
 
29
46
  class Chef
30
-
31
47
  class Provider
32
48
  class File < Chef::Provider
33
49
  include Chef::Mixin::EnforceOwnershipAndPermissions
34
50
  include Chef::Mixin::Checksum
35
51
  include Chef::Mixin::ShellOut
52
+ include Chef::Util::Selinux
53
+ include Chef::Mixin::FileClass
36
54
 
37
- def negative_complement(big)
38
- if big > 1073741823 # Fixnum max
39
- big -= (2**32) # diminished radix wrap to negative
40
- end
41
- big
42
- end
55
+ extend Chef::Deprecation::Warnings
56
+ include Chef::Deprecation::Provider::File
57
+ add_deprecation_warnings_for(Chef::Deprecation::Provider::File.instance_methods)
43
58
 
44
- def octal_mode(mode)
45
- ((mode.respond_to?(:oct) ? mode.oct : mode.to_i) & 007777)
46
- end
47
-
48
- private :negative_complement, :octal_mode
59
+ attr_reader :deployment_strategy
49
60
 
50
- def diff_current_from_content(new_content)
51
- result = nil
52
- Tempfile.open("chef-diff") do |file|
53
- file.write new_content
54
- file.close
55
- result = diff_current file.path
61
+ def initialize(new_resource, run_context)
62
+ @content_class ||= Chef::Provider::File::Content
63
+ if new_resource.respond_to?(:atomic_update)
64
+ @deployment_strategy = Chef::FileContentManagement::Deploy.strategy(new_resource.atomic_update)
56
65
  end
57
- result
66
+ super
58
67
  end
59
68
 
60
- def is_binary?(path)
61
- ::File.open(path) do |file|
62
-
63
- buff = file.read(Chef::Config[:diff_filesize_threshold])
64
- buff = "" if buff.nil?
65
- return buff !~ /^[\r[:print:]]*$/
66
- end
67
- end
68
-
69
-
70
- def diff_current(temp_path)
71
- suppress_resource_reporting = false
72
-
73
- return [ "(diff output suppressed by config)" ] if Chef::Config[:diff_disabled]
74
- return [ "(no temp file with new content, diff output suppressed)" ] unless ::File.exists?(temp_path) # should never happen?
75
-
76
- # solaris does not support diff -N, so create tempfile to diff against if we are creating a new file
77
- target_path = if ::File.exists?(@current_resource.path)
78
- @current_resource.path
79
- else
80
- suppress_resource_reporting = true # suppress big diffs going to resource reporting service
81
- tempfile = Tempfile.new('chef-tempfile')
82
- tempfile.path
83
- end
84
-
85
- diff_filesize_threshold = Chef::Config[:diff_filesize_threshold]
86
- diff_output_threshold = Chef::Config[:diff_output_threshold]
87
-
88
- if ::File.size(target_path) > diff_filesize_threshold || ::File.size(temp_path) > diff_filesize_threshold
89
- return [ "(file sizes exceed #{diff_filesize_threshold} bytes, diff output suppressed)" ]
90
- end
91
-
92
- # MacOSX(BSD?) diff will *sometimes* happily spit out nasty binary diffs
93
- return [ "(current file is binary, diff output suppressed)"] if is_binary?(target_path)
94
- return [ "(new content is binary, diff output suppressed)"] if is_binary?(temp_path)
95
-
96
- begin
97
- # -u: Unified diff format
98
- result = shell_out("diff -u #{target_path} #{temp_path}" )
99
- rescue Exception => e
100
- # Should *not* receive this, but in some circumstances it seems that
101
- # an exception can be thrown even using shell_out instead of shell_out!
102
- return [ "Could not determine diff. Error: #{e.message}" ]
103
- end
104
-
105
- # diff will set a non-zero return code even when there's
106
- # valid stdout results, if it encounters something unexpected
107
- # So as long as we have output, we'll show it.
108
- if not result.stdout.empty?
109
- if result.stdout.length > diff_output_threshold
110
- [ "(long diff of over #{diff_output_threshold} characters, diff output suppressed)" ]
111
- else
112
- val = result.stdout.split("\n")
113
- val.delete("\")
114
- @new_resource.diff(val.join("\\n")) unless suppress_resource_reporting
115
- val
116
- end
117
- elsif not result.stderr.empty?
118
- [ "Could not determine diff. Error: #{result.stderr}" ]
119
- else
120
- [ "(no diff)" ]
121
- end
122
- end
123
-
124
69
  def whyrun_supported?
125
70
  true
126
71
  end
127
72
 
128
73
  def load_current_resource
129
- # Every child should be specifying their own constructor, so this
130
- # should only be run in the file case.
74
+ # Let children resources override constructing the @current_resource
131
75
  @current_resource ||= Chef::Resource::File.new(@new_resource.name)
132
- @new_resource.path.gsub!(/\\/, "/") # for Windows
133
76
  @current_resource.path(@new_resource.path)
134
- if !::File.directory?(@new_resource.path)
135
- if ::File.exist?(@new_resource.path)
136
- if @action != :create_if_missing
137
- @current_resource.checksum(checksum(@new_resource.path))
138
- end
77
+ if ::File.exists?(@current_resource.path) && ::File.file?(::File.realpath(@current_resource.path))
78
+ if @action != :create_if_missing && @current_resource.respond_to?(:checksum)
79
+ @current_resource.checksum(checksum(@current_resource.path))
139
80
  end
81
+ load_resource_attributes_from_file(@current_resource)
140
82
  end
141
- setup_acl
142
-
143
83
  @current_resource
144
84
  end
145
85
 
146
- def setup_acl
147
- return if Chef::Platform.windows?
148
- acl_scanner = ScanAccessControl.new(@new_resource, @current_resource)
149
- acl_scanner.set_all!
150
- end
151
-
152
86
  def define_resource_requirements
153
- # this must be evaluated before whyrun messages are printed
154
- access_controls.requires_changes?
155
-
87
+ # deep inside FAC we have to assert requirements, so call FACs hook to set that up
88
+ access_controls.define_resource_requirements
89
+ # Make sure the parent directory exists, otherwise fail. For why-run assume it would have been created.
156
90
  requirements.assert(:create, :create_if_missing, :touch) do |a|
157
- # Make sure the parent dir exists, or else fail.
158
- # for why run, print a message explaining the potential error.
159
91
  parent_directory = ::File.dirname(@new_resource.path)
160
-
161
92
  a.assertion { ::File.directory?(parent_directory) }
162
93
  a.failure_message(Chef::Exceptions::EnclosingDirectoryDoesNotExist, "Parent directory #{parent_directory} does not exist.")
163
94
  a.whyrun("Assuming directory #{parent_directory} would have been created")
164
95
  end
165
96
 
166
- # Make sure the file is deletable if it exists. Otherwise, fail.
167
- requirements.assert(:delete) do |a|
168
- a.assertion do
169
- if ::File.exists?(@new_resource.path)
170
- ::File.writable?(@new_resource.path)
171
- else
172
- true
173
- end
174
- end
175
- a.failure_message(Chef::Exceptions::InsufficientPermissions,"File #{@new_resource.path} exists but is not writable so it cannot be deleted")
176
- end
177
- end
178
-
179
- # Compare the content of a file. Returns true if they are the same, false if they are not.
180
- def compare_content
181
- checksum(@current_resource.path) == new_resource_content_checksum
182
- end
183
-
184
- # Set the content of the file, assuming it is not set correctly already.
185
- def set_content
186
- unless compare_content
187
- description = []
188
- description << "update content in file #{@new_resource.path} from #{short_cksum(@current_resource.checksum)} to #{short_cksum(new_resource_content_checksum)}"
189
- description << diff_current_from_content(@new_resource.content)
190
- converge_by(description) do
191
- backup @new_resource.path if ::File.exists?(@new_resource.path)
192
- ::File.open(@new_resource.path, "w") {|f| f.write @new_resource.content }
193
- Chef::Log.info("#{@new_resource} contents updated")
97
+ # Make sure the file is deletable if it exists, otherwise fail.
98
+ if ::File.exists?(@new_resource.path)
99
+ requirements.assert(:delete) do |a|
100
+ a.assertion { ::File.writable?(@new_resource.path) }
101
+ a.failure_message(Chef::Exceptions::InsufficientPermissions,"File #{@new_resource.path} exists but is not writable so it cannot be deleted")
194
102
  end
195
103
  end
196
- end
197
-
198
- # if you are using a tempfile before creating, you must
199
- # override the default with the tempfile, since the
200
- # file at @new_resource.path will not be updated on converge
201
- def update_new_file_state(path=@new_resource.path)
202
- if !::File.directory?(path)
203
- @new_resource.checksum(checksum(path))
204
- end
205
104
 
206
- if Chef::Platform.windows?
207
- # TODO: To work around CHEF-3554, add support for Windows
208
- # equivalent, or implicit resource reporting won't work for
209
- # Windows.
210
- return
105
+ error, reason, whyrun_message = inspect_existing_fs_entry
106
+ requirements.assert(:create) do |a|
107
+ a.assertion { error.nil? }
108
+ a.failure_message(error, reason)
109
+ a.whyrun(whyrun_message)
110
+ # Subsequent attempts to read the fs entry at the path (e.g., for
111
+ # calculating checksums) could blow up, so give up trying to continue
112
+ # why-running.
113
+ a.block_action!
211
114
  end
212
-
213
- acl_scanner = ScanAccessControl.new(@new_resource, @new_resource)
214
- acl_scanner.set_all!
215
115
  end
216
116
 
217
117
  def action_create
218
- if !::File.exists?(@new_resource.path)
219
- description = []
220
- desc = "create new file #{@new_resource.path}"
221
- desc << " with content checksum #{short_cksum(new_resource_content_checksum)}" if new_resource.content
222
- description << desc
223
- description << diff_current_from_content(@new_resource.content)
224
-
225
- converge_by(description) do
226
- Chef::Log.info("entered create")
227
- ::File.open(@new_resource.path, "w+") {|f| f.write @new_resource.content }
228
- access_controls.set_all
229
- Chef::Log.info("#{@new_resource} created file #{@new_resource.path}")
230
- update_new_file_state
231
- end
232
- else
233
- set_content unless @new_resource.content.nil?
234
- set_all_access_controls
235
- end
236
- end
237
-
238
- def set_all_access_controls
239
- if access_controls.requires_changes?
240
- converge_by(access_controls.describe_changes) do
241
- access_controls.set_all
242
- #Update file state with new access values
243
- update_new_file_state
244
- end
245
- end
118
+ do_unlink
119
+ do_create_file
120
+ do_contents_changes
121
+ do_acl_changes
122
+ do_selinux
123
+ load_resource_attributes_from_file(@new_resource)
246
124
  end
247
125
 
248
126
  def action_create_if_missing
@@ -255,8 +133,8 @@ class Chef
255
133
 
256
134
  def action_delete
257
135
  if ::File.exists?(@new_resource.path)
258
- converge_by("delete file #{@new_resource.path}") do
259
- backup unless ::File.symlink?(@new_resource.path)
136
+ converge_by("delete file #{@new_resource.path}") do
137
+ do_backup unless file_class.symlink?(@new_resource.path)
260
138
  ::File.delete(@new_resource.path)
261
139
  Chef::Log.info("#{@new_resource} deleted file at #{@new_resource.path}")
262
140
  end
@@ -272,57 +150,261 @@ class Chef
272
150
  end
273
151
  end
274
152
 
275
- def backup(file=nil)
276
- file ||= @new_resource.path
277
- if @new_resource.backup != false && @new_resource.backup > 0 && ::File.exist?(file)
278
- time = Time.now
279
- savetime = time.strftime("%Y%m%d%H%M%S")
280
- backup_filename = "#{@new_resource.path}.chef-#{savetime}"
281
- backup_filename = backup_filename.sub(/^([A-Za-z]:)/, "") #strip drive letter on Windows
282
- # if :file_backup_path is nil, we fallback to the old behavior of
283
- # keeping the backup in the same directory. We also need to to_s it
284
- # so we don't get a type error around implicit to_str conversions.
285
- prefix = Chef::Config[:file_backup_path].to_s
286
- backup_path = ::File.join(prefix, backup_filename)
287
- FileUtils.mkdir_p(::File.dirname(backup_path)) if Chef::Config[:file_backup_path]
288
- FileUtils.cp(file, backup_path, :preserve => true)
289
- Chef::Log.info("#{@new_resource} backed up to #{backup_path}")
290
-
291
- # Clean up after the number of backups
292
- slice_number = @new_resource.backup
293
- backup_files = Dir[::File.join(prefix, ".#{@new_resource.path}.chef-*")].sort { |a,b| b <=> a }
294
- if backup_files.length >= @new_resource.backup
295
- remainder = backup_files.slice(slice_number..-1)
296
- remainder.each do |backup_to_delete|
297
- FileUtils.rm(backup_to_delete)
298
- Chef::Log.info("#{@new_resource} removed backup at #{backup_to_delete}")
153
+ # Implementation components *should* follow symlinks when managing access
154
+ # control (e.g., use chmod instead of lchmod even if the path we're
155
+ # managing is a symlink).
156
+ def manage_symlink_access?
157
+ false
158
+ end
159
+
160
+ private
161
+
162
+ # Handles resource requirements for action :create when some fs entry
163
+ # already exists at the destination path. For actions other than create,
164
+ # we don't care what kind of thing is at the destination path because:
165
+ # * for :create_if_missing, we're assuming the user wanted to avoid blowing away the non-file here
166
+ # * for :touch, we can modify perms of whatever is at this path, regardless of its type
167
+ # * for :delete, we can blow away whatever is here, regardless of its type
168
+ #
169
+ # For the action :create case, we need to deal with user-selectable
170
+ # behavior to see if we're in an error condition.
171
+ # * If there's no file at the destination path currently, we're cool to
172
+ # create it.
173
+ # * If the fs entry that currently exists at the destination is a regular
174
+ # file, we're cool to update it with new content.
175
+ # * If the fs entry is a symlink AND the resource has
176
+ # `manage_symlink_source` enabled, we need to verify that the symlink is
177
+ # a valid pointer to a real file. If it is, we can manage content and
178
+ # permissions on the symlink source, otherwise, error.
179
+ # * If `manage_symlink_source` is not enabled, fall through.
180
+ # * If force_unlink is true, action :create will unlink whatever is in the way.
181
+ # * If force_unlink is false, we're in an exceptional situation, so we
182
+ # want to error.
183
+ #
184
+ # Note that this method returns values to be used with requirement
185
+ # assertions, which then decide whether or not to raise or issue a
186
+ # warning for whyrun mode.
187
+ def inspect_existing_fs_entry
188
+ path = @new_resource.path
189
+
190
+ if !l_exist?(path)
191
+ [nil, nil, nil]
192
+ elsif real_file?(path)
193
+ [nil, nil, nil]
194
+ elsif file_class.symlink?(path) && @new_resource.manage_symlink_source
195
+ verify_symlink_sanity(path)
196
+ elsif file_class.symlink?(@new_resource.path) && @new_resource.manage_symlink_source.nil?
197
+ Chef::Log.warn("File #{path} managed by #{@new_resource} is really a symlink. Managing the source file instead.")
198
+ Chef::Log.warn("Disable this warning by setting `manage_symlink_source true` on the resource")
199
+ Chef::Log.warn("In a future Chef release, 'manage_symlink_source' will not be enabled by default")
200
+ verify_symlink_sanity(path)
201
+ elsif @new_resource.force_unlink
202
+ [nil, nil, nil]
203
+ else
204
+ [ Chef::Exceptions::FileTypeMismatch,
205
+ "File #{path} exists, but is a #{file_type_string(@new_resource.path)}, set force_unlink to true to remove",
206
+ "Assuming #{file_type_string(@new_resource.path)} at #{@new_resource.path} would have been removed by a previous resource"
207
+ ]
208
+ end
209
+ end
210
+
211
+ # Returns values suitable for use in a requirements assertion statement
212
+ # when managing symlink source. If we're managing symlink source we can
213
+ # hit 3 error cases:
214
+ # 1. Symlink to nowhere: File.realpath(symlink) -> raise Errno::ENOENT
215
+ # 2. Symlink loop: File.realpath(symlink) -> raise Errno::ELOOP
216
+ # 3. Symlink to not-a-real-file: File.realpath(symlink) -> (directory|blockdev|etc.)
217
+ # If any of the above apply, returns a 3-tuple of Exception class,
218
+ # exception message, whyrun message; otherwise returns a 3-tuple of nil.
219
+ def verify_symlink_sanity(path)
220
+ real_path = ::File.realpath(path)
221
+ if real_file?(real_path)
222
+ [nil, nil, nil]
223
+ else
224
+ [ Chef::Exceptions::FileTypeMismatch,
225
+ "File #{path} exists, but is a symlink to #{real_path} which is a #{file_type_string(real_path)}. " +
226
+ "Disable manage_symlink_source and set force_unlink to remove it.",
227
+ "Assuming symlink #{path} or source file #{real_path} would have been fixed by a previous resource"
228
+ ]
229
+ end
230
+ rescue Errno::ELOOP
231
+ [ Chef::Exceptions::InvalidSymlink,
232
+ "Symlink at #{path} (pointing to #{::File.readlink(path)}) exists but attempting to resolve it creates a loop",
233
+ "Assuming symlink loop would be fixed by a previous resource" ]
234
+ rescue Errno::ENOENT
235
+ [ Chef::Exceptions::InvalidSymlink,
236
+ "Symlink at #{path} (pointing to #{::File.readlink(path)}) exists but attempting to resolve it leads to a nonexistent file",
237
+ "Assuming symlink source would be created by a previous resource" ]
238
+ end
239
+
240
+
241
+ def content
242
+ @content ||= begin
243
+ load_current_resource if @current_resource.nil?
244
+ @content_class.new(@new_resource, @current_resource, @run_context)
245
+ end
246
+ end
247
+
248
+ def file_type_string(path)
249
+ case
250
+ when ::File.blockdev?(path)
251
+ "block device"
252
+ when ::File.chardev?(path)
253
+ "char device"
254
+ when ::File.directory?(path)
255
+ "directory"
256
+ when ::File.pipe?(path)
257
+ "pipe"
258
+ when ::File.socket?(path)
259
+ "socket"
260
+ when file_class.symlink?(path)
261
+ "symlink"
262
+ else
263
+ "unknown filetype"
264
+ end
265
+ end
266
+
267
+ def real_file?(path)
268
+ !file_class.symlink?(path) && ::File.file?(path)
269
+ end
270
+
271
+ # Similar to File.exist?, but also returns true in the case that the
272
+ # named file is a broken symlink.
273
+ def l_exist?(path)
274
+ ::File.exist?(path) || file_class.symlink?(path)
275
+ end
276
+
277
+ def unlink(path)
278
+ # Directories can not be unlinked. Remove them using FileUtils.
279
+ if ::File.directory?(path)
280
+ FileUtils.rm_rf(path)
281
+ else
282
+ ::File.unlink(path)
283
+ end
284
+ end
285
+
286
+ def do_unlink
287
+ @file_unlinked = false
288
+ if @new_resource.force_unlink
289
+ if !real_file?(@new_resource.path)
290
+ # unlink things that aren't normal files
291
+ description = "unlink #{file_type_string(@new_resource.path)} at #{@new_resource.path}"
292
+ converge_by(description) do
293
+ unlink(@new_resource.path)
299
294
  end
295
+ @current_resource.checksum = nil
296
+ @file_unlinked = true
300
297
  end
301
298
  end
302
299
  end
303
300
 
304
- def deploy_tempfile
305
- Tempfile.open(::File.basename(@new_resource.name)) do |tempfile|
306
- yield tempfile
301
+ def file_unlinked?
302
+ @file_unlinked == true
303
+ end
307
304
 
308
- temp_res = Chef::Resource::CookbookFile.new(@new_resource.name)
309
- temp_res.path(tempfile.path)
310
- ac = Chef::FileAccessControl.new(temp_res, @new_resource, self)
311
- ac.set_all!
312
- FileUtils.mv(tempfile.path, @new_resource.path)
305
+ def do_create_file
306
+ @file_created = false
307
+ if !::File.exists?(@new_resource.path) || file_unlinked?
308
+ converge_by("create new file #{@new_resource.path}") do
309
+ deployment_strategy.create(@new_resource.path)
310
+ Chef::Log.info("#{@new_resource} created file #{@new_resource.path}")
311
+ end
312
+ @file_created = true
313
313
  end
314
314
  end
315
315
 
316
- private
316
+ # do_contents_changes needs to know if do_create_file created a file or not
317
+ def file_created?
318
+ @file_created == true
319
+ end
320
+
321
+ def do_backup(file = nil)
322
+ Chef::Util::Backup.new(@new_resource, file).backup!
323
+ end
324
+
325
+ def diff
326
+ @diff ||= Chef::Util::Diff.new
327
+ end
328
+
329
+ def update_file_contents
330
+ do_backup unless file_created?
331
+ deployment_strategy.deploy(tempfile.path, ::File.realpath(@new_resource.path))
332
+ Chef::Log.info("#{@new_resource} updated file contents #{@new_resource.path}")
333
+ @new_resource.checksum(checksum(@new_resource.path)) # for reporting
334
+ end
335
+
336
+ def do_contents_changes
337
+ # a nil tempfile is okay, means the resource has no content or no new content
338
+ return if tempfile.nil?
339
+ # but a tempfile that has no path or doesn't exist should not happen
340
+ if tempfile.path.nil? || !::File.exists?(tempfile.path)
341
+ raise "chef-client is confused, trying to deploy a file that has no path or does not exist..."
342
+ end
343
+ # the file? on the next line suppresses the case in why-run when we have a not-file here that would have otherwise been removed
344
+ if ::File.file?(@new_resource.path) && contents_changed?
345
+ diff.diff(@current_resource.path, tempfile.path)
346
+ @new_resource.diff( diff.for_reporting ) unless file_created?
347
+ description = [ "update content in file #{@new_resource.path} from #{short_cksum(@current_resource.checksum)} to #{short_cksum(checksum(tempfile.path))}" ]
348
+ description << diff.for_output
349
+ converge_by(description) do
350
+ update_file_contents
351
+ end
352
+ end
353
+ # unlink necessary to clean up in why-run mode
354
+ tempfile.unlink
355
+ end
356
+
357
+ # This logic ideally will be made into some kind of generic
358
+ # platform-dependent post-converge hook for file-like
359
+ # resources, but for now we only have the single selinux use
360
+ # case.
361
+ def do_selinux(recursive = false)
362
+ if resource_updated? && Chef::Config[:enable_selinux_file_permission_fixup]
363
+ if selinux_enabled?
364
+ converge_by("restore selinux security context") do
365
+ restore_security_context(::File.realpath(@new_resource.path), recursive)
366
+ end
367
+ else
368
+ Chef::Log.debug "selinux utilities can not be found. Skipping selinux permission fixup."
369
+ end
370
+ end
371
+ end
372
+
373
+ def do_acl_changes
374
+ if access_controls.requires_changes?
375
+ converge_by(access_controls.describe_changes) do
376
+ access_controls.set_all
377
+ end
378
+ end
379
+ end
380
+
381
+ def contents_changed?
382
+ checksum(tempfile.path) != @current_resource.checksum
383
+ end
384
+
385
+ def tempfile
386
+ content.tempfile
387
+ end
317
388
 
318
389
  def short_cksum(checksum)
319
390
  return "none" if checksum.nil?
320
391
  checksum.slice(0,6)
321
392
  end
322
393
 
323
- def new_resource_content_checksum
324
- @new_resource.content && Digest::SHA2.hexdigest(@new_resource.content)
394
+ def load_resource_attributes_from_file(resource)
395
+
396
+ if Chef::Platform.windows?
397
+ # This is a work around for CHEF-3554.
398
+ # OC-6534: is tracking the real fix for this workaround.
399
+ # Add support for Windows equivalent, or implicit resource
400
+ # reporting won't work for Windows.
401
+ return
402
+ end
403
+ acl_scanner = ScanAccessControl.new(@new_resource, resource)
404
+ acl_scanner.set_all!
325
405
  end
406
+
326
407
  end
327
408
  end
328
409
  end
410
+