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
@@ -0,0 +1,41 @@
1
+ require 'support/shared/integration/integration_helper'
2
+ require 'chef/mixin/shell_out'
3
+
4
+ describe "chef-solo" do
5
+ extend IntegrationSupport
6
+ include Chef::Mixin::ShellOut
7
+
8
+ context "with a no-op recipe in the run_list" do
9
+
10
+ when_the_repository "has a cookbook with a no-op recipe" do
11
+ directory 'cookbooks'
12
+ directory 'cookbooks/x'
13
+ directory 'cookbooks/x/recipes'
14
+ file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
15
+ file 'cookbooks/x/recipes/default.rb', ''
16
+
17
+ before do
18
+ @chef_file_cache = Dir.mktmpdir('file_cache')
19
+ end
20
+
21
+ after do
22
+ FileUtils.rm_rf(@chef_file_cache) if @chef_file_cache
23
+ end
24
+
25
+ it "should complete with success" do
26
+ # prepare the solo config
27
+ directory 'config'
28
+ file 'config/solo.rb', <<EOM
29
+ cookbook_path "#{File.join(@repository_dir, 'cookbooks')}"
30
+ file_cache_path "#{@chef_file_cache}"
31
+ EOM
32
+ config_file = canonicalize_path(File.join(@repository_dir, 'config', 'solo.rb'))
33
+
34
+ chef_dir = File.join(File.dirname(__FILE__), "..", "..", "..", "bin")
35
+ result = shell_out("chef-solo -c \"#{config_file}\" -o 'x::default' -l debug", :cwd => chef_dir)
36
+ result.error!
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -40,9 +40,25 @@ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
40
40
  $:.unshift(File.expand_path("../lib", __FILE__))
41
41
  $:.unshift(File.dirname(__FILE__))
42
42
 
43
+ if ENV["COVERAGE"]
44
+ require 'simplecov'
45
+ SimpleCov.start do
46
+ add_filter "/spec/"
47
+ add_group "Remote File", "remote_file"
48
+ add_group "Resources", "/resource/"
49
+ add_group "Providers", "/provider/"
50
+ add_group "Knife", "knife"
51
+ end
52
+ end
53
+
43
54
  require 'chef'
44
55
  require 'chef/knife'
45
- Chef::Knife.load_commands
56
+
57
+ Dir['lib/chef/knife/**/*.rb'].
58
+ map {|f| f.gsub('lib/', '') }.
59
+ map {|f| f.gsub(%r[\.rb$], '') }.
60
+ each {|f| require f }
61
+
46
62
  require 'chef/mixins'
47
63
  require 'chef/dsl'
48
64
  require 'chef/application'
@@ -64,8 +80,16 @@ require 'spec/support/platform_helpers'
64
80
  Dir["spec/support/**/*.rb"].
65
81
  reject { |f| f =~ %r{^spec/support/platforms} }.
66
82
  map { |f| f.gsub(%r{.rb$}, '') }.
83
+ map { |f| f.gsub(%r[spec/], '')}.
67
84
  each { |f| require f }
68
85
 
86
+
87
+ OHAI_SYSTEM = Ohai::System.new
88
+ OHAI_SYSTEM.require_plugin("os")
89
+ OHAI_SYSTEM.require_plugin("platform")
90
+ TEST_PLATFORM = OHAI_SYSTEM["platform"].dup.freeze
91
+ TEST_PLATFORM_VERSION = OHAI_SYSTEM["platform_version"].dup.freeze
92
+
69
93
  RSpec.configure do |config|
70
94
  config.include(Matchers)
71
95
  config.filter_run :focus => true
@@ -77,15 +101,45 @@ RSpec.configure do |config|
77
101
  # Add jruby filters here
78
102
  config.filter_run_excluding :windows_only => true unless windows?
79
103
  config.filter_run_excluding :not_supported_on_win2k3 => true if windows_win2k3?
104
+ config.filter_run_excluding :not_supported_on_solaris => true if solaris?
105
+ config.filter_run_excluding :win2k3_only => true unless windows_win2k3?
80
106
  config.filter_run_excluding :windows64_only => true unless windows64?
81
107
  config.filter_run_excluding :windows32_only => true unless windows32?
108
+ config.filter_run_excluding :system_windows_service_gem_only => true unless system_windows_service_gem?
82
109
  config.filter_run_excluding :unix_only => true unless unix?
110
+ config.filter_run_excluding :supports_cloexec => true unless supports_cloexec?
111
+ config.filter_run_excluding :selinux_only => true unless selinux_enabled?
83
112
  config.filter_run_excluding :ruby_18_only => true unless ruby_18?
84
113
  config.filter_run_excluding :ruby_19_only => true unless ruby_19?
114
+ config.filter_run_excluding :ruby_gte_19_only => true unless ruby_gte_19?
115
+ config.filter_run_excluding :ruby_20_only => true unless ruby_20?
116
+ config.filter_run_excluding :ruby_gte_20_only => true unless ruby_gte_20?
85
117
  config.filter_run_excluding :requires_root => true unless ENV['USER'] == 'root'
86
118
  config.filter_run_excluding :requires_unprivileged_user => true if ENV['USER'] == 'root'
87
119
  config.filter_run_excluding :uses_diff => true unless has_diff?
88
120
 
121
+ running_platform_arch = `uname -m`.strip
122
+
123
+ config.filter_run_excluding :arch => lambda {|target_arch|
124
+ running_platform_arch != target_arch
125
+ }
126
+
127
+ # Functional Resource tests that are provider-specific:
128
+ # context "on platforms that use useradd", :provider => {:user => Chef::Provider::User::Useradd}} do #...
129
+ config.filter_run_excluding :provider => lambda {|criteria|
130
+ type, target_provider = criteria.first
131
+
132
+ platform = TEST_PLATFORM.dup
133
+ platform_version = TEST_PLATFORM_VERSION.dup
134
+
135
+ begin
136
+ provider_for_running_platform = Chef::Platform.find_provider(platform, platform_version, type)
137
+ provider_for_running_platform != target_provider
138
+ rescue ArgumentError # no provider for platform
139
+ true
140
+ end
141
+ }
142
+
89
143
  config.run_all_when_everything_filtered = true
90
144
  config.treat_symbols_as_metadata_keys_with_true_values = true
91
145
  end
@@ -61,3 +61,35 @@ def has_diff?
61
61
  false
62
62
  end
63
63
  end
64
+
65
+ # This is a helper to determine if the ruby in the PATH contains
66
+ # win32/service gem. windows_service_manager tests create a windows
67
+ # service that starts with the system ruby and requires this gem.
68
+ def system_windows_service_gem?
69
+ windows_service_gem_check_command = "ruby -e 'require \"win32/daemon\"' > /dev/null 2>&1"
70
+ if defined?(Bundler)
71
+ Bundler.with_clean_env do
72
+ # This returns true if the gem can be loaded
73
+ system windows_service_gem_check_command
74
+ end
75
+ else
76
+ # This returns true if the gem can be loaded
77
+ system windows_service_gem_check_command
78
+ end
79
+ end
80
+
81
+ # This is a helper to canonicalize paths that we're using in the file
82
+ # tests.
83
+ def canonicalize_path(path)
84
+ windows? ? path.gsub('/', '\\') : path
85
+ end
86
+
87
+ # Check if a cmd exists on the PATH
88
+ def which(cmd)
89
+ paths = ENV['PATH'].split(File::PATH_SEPARATOR) + [ '/bin', '/usr/bin', '/sbin', '/usr/sbin' ]
90
+ paths.each do |path|
91
+ filename = File.join(path, cmd)
92
+ return filename if File.executable?(filename)
93
+ end
94
+ false
95
+ end
@@ -1,3 +1,17 @@
1
+ require 'fcntl'
2
+
3
+ def ruby_gte_20?
4
+ RUBY_VERSION.to_f >= 2.0
5
+ end
6
+
7
+ def ruby_gte_19?
8
+ RUBY_VERSION.to_f >= 1.9
9
+ end
10
+
11
+ def ruby_20?
12
+ !!(RUBY_VERSION =~ /^2.0/)
13
+ end
14
+
1
15
  def ruby_19?
2
16
  !!(RUBY_VERSION =~ /^1.9/)
3
17
  end
@@ -46,4 +60,30 @@ def freebsd?
46
60
  !!(RUBY_PLATFORM =~ /freebsd/)
47
61
  end
48
62
 
63
+ def supports_cloexec?
64
+ Fcntl.const_defined?('F_SETFD') && Fcntl.const_defined?('FD_CLOEXEC')
65
+ end
66
+
49
67
  DEV_NULL = windows? ? 'NUL' : '/dev/null'
68
+
69
+ def selinux_enabled?
70
+ # This code is currently copied from lib/chef/util/selinux to make
71
+ # specs independent of product.
72
+ selinuxenabled_path = which("selinuxenabled")
73
+ if selinuxenabled_path
74
+ cmd = Mixlib::ShellOut.new(selinuxenabled_path, :returns => [0,1])
75
+ cmd_result = cmd.run_command
76
+ case cmd_result.exitstatus
77
+ when 1
78
+ return false
79
+ when 0
80
+ return true
81
+ else
82
+ raise RuntimeError, "Unknown exit code from command #{selinuxenabled_path}: #{cmd.exitstatus}"
83
+ end
84
+ else
85
+ # We assume selinux is not enabled if selinux utils are not
86
+ # installed.
87
+ return false
88
+ end
89
+ end
@@ -0,0 +1,59 @@
1
+ #
2
+ # Author:: Serdar Sutay (<serdar@lambda.local>)
3
+ # Copyright:: Copyright (c) 2013 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 'win32/daemon'
20
+
21
+ class SpecService < ::Win32::Daemon
22
+ def service_init
23
+ @test_service_file = "#{ENV['TMP']}/spec_service_file"
24
+ end
25
+
26
+ def service_main(*startup_parameters)
27
+ while running? do
28
+ if !File.exists?(@test_service_file)
29
+ File.open(@test_service_file, 'wb') do |f|
30
+ f.write("This file is created by SpecService")
31
+ end
32
+ end
33
+
34
+ sleep 1
35
+ end
36
+ end
37
+
38
+ ################################################################################
39
+ # Control Signal Callback Methods
40
+ ################################################################################
41
+
42
+ def service_stop
43
+ end
44
+
45
+ def service_pause
46
+ end
47
+
48
+ def service_resume
49
+ end
50
+
51
+ def service_shutdown
52
+ end
53
+ end
54
+
55
+ # To run this file as a service, it must be called as a script from within
56
+ # the Windows Service framework. In that case, kick off the main loop!
57
+ if __FILE__ == $0
58
+ SpecService.mainloop
59
+ end
@@ -63,6 +63,31 @@ shared_examples_for "a directory resource" do
63
63
  end
64
64
  end
65
65
  end
66
+
67
+ # Set up the context for security tests
68
+ def allowed_acl(sid, expected_perms)
69
+ [
70
+ ACE.access_allowed(sid, expected_perms[:specific]),
71
+ ACE.access_allowed(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::INHERIT_ONLY_ACE | Chef::ReservedNames::Win32::API::Security::CONTAINER_INHERIT_ACE | Chef::ReservedNames::Win32::API::Security::OBJECT_INHERIT_ACE))
72
+ ]
73
+ end
74
+
75
+ def denied_acl(sid, expected_perms)
76
+ [
77
+ ACE.access_denied(sid, expected_perms[:specific]),
78
+ ACE.access_denied(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::INHERIT_ONLY_ACE | Chef::ReservedNames::Win32::API::Security::CONTAINER_INHERIT_ACE | Chef::ReservedNames::Win32::API::Security::OBJECT_INHERIT_ACE))
79
+ ]
80
+ end
81
+
82
+ def parent_inheritable_acls
83
+ dummy_directory_path = File.join(test_file_dir, "dummy_directory")
84
+ dummy_directory = FileUtils.mkdir_p(dummy_directory_path)
85
+ dummy_desc = get_security_descriptor(dummy_directory_path)
86
+ FileUtils.rm_rf(dummy_directory_path)
87
+ dummy_desc
88
+ end
89
+
90
+ it_behaves_like "a securable resource without existing target"
66
91
  end
67
92
 
68
93
  context "when the target directory exists" do
@@ -120,27 +145,29 @@ shared_examples_for "a directory resource" do
120
145
  end
121
146
  end
122
147
 
123
- # Set up the context for security tests
124
- def allowed_acl(sid, expected_perms)
125
- [
126
- ACE.access_allowed(sid, expected_perms[:specific]),
127
- ACE.access_allowed(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::INHERIT_ONLY_ACE | Chef::ReservedNames::Win32::API::Security::CONTAINER_INHERIT_ACE | Chef::ReservedNames::Win32::API::Security::OBJECT_INHERIT_ACE))
128
- ]
148
+ end
149
+
150
+ shared_context Chef::Resource::Directory do
151
+ # We create the directory than tmp to exercise different file
152
+ # deployment strategies more completely.
153
+ let(:test_file_dir) do
154
+ if windows?
155
+ File.join(ENV['systemdrive'], "test-dir")
156
+ else
157
+ File.join(CHEF_SPEC_DATA, "test-dir")
158
+ end
129
159
  end
130
160
 
131
- def denied_acl(sid, expected_perms)
132
- [
133
- ACE.access_denied(sid, expected_perms[:specific]),
134
- ACE.access_denied(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::INHERIT_ONLY_ACE | Chef::ReservedNames::Win32::API::Security::CONTAINER_INHERIT_ACE | Chef::ReservedNames::Win32::API::Security::OBJECT_INHERIT_ACE))
135
- ]
161
+ let(:path) do
162
+ File.join(test_file_dir, make_tmpname(directory_base))
136
163
  end
137
164
 
138
- it_behaves_like "a securable resource"
139
- end
165
+ before do
166
+ FileUtils::mkdir_p(test_file_dir)
167
+ end
140
168
 
141
- shared_context Chef::Resource::Directory do
142
- let(:path) do
143
- File.join(Dir.tmpdir, make_tmpname(directory_base))
169
+ after do
170
+ FileUtils::rm_rf(test_file_dir)
144
171
  end
145
172
 
146
173
  after(:each) do
@@ -16,6 +16,51 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
+ shared_context "deploying with move" do
20
+ before do
21
+ @original_atomic_update = Chef::Config[:file_atomic_update]
22
+ Chef::Config[:file_atomic_update] = true
23
+ end
24
+
25
+ after do
26
+ Chef::Config[:file_atomic_update] = @original_atomic_update
27
+ end
28
+ end
29
+
30
+ shared_context "deploying with copy" do
31
+ before do
32
+ @original_atomic_update = Chef::Config[:file_atomic_update]
33
+ Chef::Config[:file_atomic_update] = false
34
+ end
35
+
36
+ after do
37
+ Chef::Config[:file_atomic_update] = @original_atomic_update
38
+ end
39
+ end
40
+
41
+ shared_context "deploying via tmpdir" do
42
+ before do
43
+ @original_stage_via = Chef::Config[:file_staging_uses_destdir]
44
+ Chef::Config[:file_staging_uses_destdir] = false
45
+ end
46
+
47
+ after do
48
+ Chef::Config[:file_staging_uses_destdir] = @original_stage_via
49
+ end
50
+ end
51
+
52
+ shared_context "deploying via destdir" do
53
+ before do
54
+ @original_stage_via = Chef::Config[:file_staging_uses_destdir]
55
+ Chef::Config[:file_staging_uses_destdir] = true
56
+ end
57
+
58
+ after do
59
+ Chef::Config[:file_staging_uses_destdir] = @original_stage_via
60
+ end
61
+ end
62
+
63
+
19
64
  shared_examples_for "a file with the wrong content" do
20
65
  before do
21
66
  # Assert starting state is as expected
@@ -46,6 +91,10 @@ shared_examples_for "a file with the wrong content" do
46
91
  it "is marked as updated by last action" do
47
92
  resource.should be_updated_by_last_action
48
93
  end
94
+
95
+ it "should restore the security contexts on selinux", :selinux_only do
96
+ selinux_security_context_restored?(path).should be_true
97
+ end
49
98
  end
50
99
 
51
100
  context "with backups disabled" do
@@ -58,6 +107,10 @@ shared_examples_for "a file with the wrong content" do
58
107
  it "should not attempt to backup the existing file if :backup == 0" do
59
108
  Dir.glob(backup_glob).size.should equal(0)
60
109
  end
110
+
111
+ it "should restore the security contexts on selinux", :selinux_only do
112
+ selinux_security_context_restored?(path).should be_true
113
+ end
61
114
  end
62
115
  end
63
116
 
@@ -74,6 +127,10 @@ shared_examples_for "a file with the wrong content" do
74
127
  it "is not marked as updated" do
75
128
  resource.should_not be_updated_by_last_action
76
129
  end
130
+
131
+ it "should restore the security contexts on selinux", :selinux_only do
132
+ selinux_security_context_restored?(path).should be_true
133
+ end
77
134
  end
78
135
 
79
136
  describe "when running action :delete" do
@@ -115,6 +172,10 @@ shared_examples_for "a file with the correct content" do
115
172
  it "is not marked as updated by last action" do
116
173
  resource.should_not be_updated_by_last_action
117
174
  end
175
+
176
+ it "should restore the security contexts on selinux", :selinux_only do
177
+ selinux_security_context_restored?(path).should be_true
178
+ end
118
179
  end
119
180
 
120
181
  describe "when running action :create_if_missing" do
@@ -129,6 +190,10 @@ shared_examples_for "a file with the correct content" do
129
190
  it "is not marked as updated by last action" do
130
191
  resource.should_not be_updated_by_last_action
131
192
  end
193
+
194
+ it "should restore the security contexts on selinux", :selinux_only do
195
+ selinux_security_context_restored?(path).should be_true
196
+ end
132
197
  end
133
198
 
134
199
  describe "when running action :delete" do
@@ -147,6 +212,122 @@ shared_examples_for "a file with the correct content" do
147
212
  end
148
213
 
149
214
  shared_examples_for "a file resource" do
215
+ describe "when deploying with :move" do
216
+
217
+ include_context "deploying with move"
218
+
219
+ describe "when deploying via tmpdir" do
220
+
221
+ include_context "deploying via tmpdir"
222
+
223
+ it_behaves_like "a configured file resource"
224
+ end
225
+
226
+ describe "when deploying via destdir" do
227
+
228
+ include_context "deploying via destdir"
229
+
230
+ it_behaves_like "a configured file resource"
231
+ end
232
+ end
233
+
234
+ describe "when deploying with :copy" do
235
+
236
+ include_context "deploying with copy"
237
+
238
+ describe "when deploying via tmpdir" do
239
+
240
+ include_context "deploying via tmpdir"
241
+
242
+ it_behaves_like "a configured file resource"
243
+ end
244
+
245
+ describe "when deploying via destdir" do
246
+
247
+ include_context "deploying via destdir"
248
+
249
+ it_behaves_like "a configured file resource"
250
+ end
251
+ end
252
+
253
+ describe "when running under why run" do
254
+
255
+ before do
256
+ Chef::Config[:why_run] = true
257
+ end
258
+
259
+ after do
260
+ Chef::Config[:why_run] = false
261
+ end
262
+
263
+ context "and the resource has a path with a missing intermediate directory" do
264
+ # CHEF-3978
265
+
266
+ let(:path) do
267
+ File.join(test_file_dir, "intermediate_dir", make_tmpname(file_base))
268
+ end
269
+
270
+ it "successfully doesn't create the file" do
271
+ resource.run_action(:create) # should not raise
272
+ File.should_not exist(path)
273
+ end
274
+ end
275
+
276
+ end
277
+
278
+ describe "when setting atomic_update" do
279
+ it "booleans should work" do
280
+ lambda {resource.atomic_update(true)}.should_not raise_error
281
+ lambda {resource.atomic_update(false)}.should_not raise_error
282
+ end
283
+
284
+ it "anything else should raise an error" do
285
+ lambda {resource.atomic_update(:copy)}.should raise_error(ArgumentError)
286
+ lambda {resource.atomic_update(:move)}.should raise_error(ArgumentError)
287
+ lambda {resource.atomic_update(958)}.should raise_error(ArgumentError)
288
+ end
289
+ end
290
+
291
+ end
292
+
293
+ shared_examples_for "file resource not pointing to a real file" do
294
+ def symlink?(file_path)
295
+ if windows?
296
+ Chef::ReservedNames::Win32::File.symlink?(file_path)
297
+ else
298
+ File.symlink?(file_path)
299
+ end
300
+ end
301
+
302
+ def real_file?(file_path)
303
+ !symlink?(file_path) && File.file?(file_path)
304
+ end
305
+
306
+ describe "when force_unlink is set to true" do
307
+ it ":create unlinks the target" do
308
+ real_file?(path).should be_false
309
+ resource.force_unlink(true)
310
+ resource.run_action(:create)
311
+ real_file?(path).should be_true
312
+ binread(path).should == expected_content
313
+ resource.should be_updated_by_last_action
314
+ end
315
+ end
316
+
317
+ describe "when force_unlink is set to false" do
318
+ it ":create raises an error" do
319
+ lambda {resource.run_action(:create) }.should raise_error(Chef::Exceptions::FileTypeMismatch)
320
+ end
321
+ end
322
+
323
+ describe "when force_unlink is not set (default)" do
324
+ it ":create raises an error" do
325
+ lambda {resource.run_action(:create) }.should raise_error(Chef::Exceptions::FileTypeMismatch)
326
+ end
327
+ end
328
+ end
329
+
330
+ shared_examples_for "a configured file resource" do
150
331
 
151
332
  include_context "diff disabled"
152
333
 
@@ -155,7 +336,7 @@ shared_examples_for "a file resource" do
155
336
  end
156
337
 
157
338
  # note the stripping of the drive letter from the tmpdir on windows
158
- let(:backup_glob) { File.join(CHEF_SPEC_BACKUP_PATH, Dir.tmpdir.sub(/^([A-Za-z]:)/, ""), "#{file_base}*") }
339
+ let(:backup_glob) { File.join(CHEF_SPEC_BACKUP_PATH, test_file_dir.sub(/^([A-Za-z]:)/, ""), "#{file_base}*") }
159
340
 
160
341
  # Most tests update the resource, but a few do not. We need to test that the
161
342
  # resource is marked updated or not correctly, but the test contexts are
@@ -164,6 +345,17 @@ shared_examples_for "a file resource" do
164
345
  # and permissions are correct.
165
346
  let(:expect_updated?) { true }
166
347
 
348
+ include Chef::Mixin::ShellOut
349
+
350
+ def selinux_security_context_restored?(path)
351
+ @restorecon_path = which("restorecon") if @restorecon_path.nil?
352
+ restorecon_test_command = "#{@restorecon_path} -n -v #{path}"
353
+ cmdresult = shell_out(restorecon_test_command)
354
+ # restorecon will print the required changes to stdout if any is
355
+ # needed
356
+ cmdresult.stdout.empty?
357
+ end
358
+
167
359
  def binread(file)
168
360
  content = File.open(file, "rb") do |f|
169
361
  f.read
@@ -172,6 +364,398 @@ shared_examples_for "a file resource" do
172
364
  content
173
365
  end
174
366
 
367
+ context "when the target file is a symlink", :not_supported_on_win2k3 do
368
+ let(:symlink_target) {
369
+ File.join(CHEF_SPEC_DATA, "file-test-target")
370
+ }
371
+
372
+
373
+ describe "when configured not to manage symlink's target" do
374
+ before(:each) do
375
+ # configure not to manage symlink source
376
+ resource.manage_symlink_source(false)
377
+
378
+ # create symlinks for test context
379
+ FileUtils.touch(symlink_target)
380
+
381
+ if windows?
382
+ Chef::ReservedNames::Win32::File.symlink(symlink_target, path)
383
+ else
384
+ File.symlink(symlink_target, path)
385
+ end
386
+ end
387
+
388
+ after(:each) do
389
+ FileUtils.rm_rf(symlink_target)
390
+ FileUtils.rm_rf(path)
391
+ end
392
+
393
+ describe "when symlink target has correct content" do
394
+ before(:each) do
395
+ File.open(symlink_target, "wb") { |f| f.print expected_content }
396
+ end
397
+
398
+ it_behaves_like "file resource not pointing to a real file"
399
+ end
400
+
401
+ describe "when symlink target has the wrong content" do
402
+ before(:each) do
403
+ File.open(symlink_target, "wb") { |f| f.print "This is so wrong!!!" }
404
+ end
405
+
406
+ after(:each) do
407
+ # symlink should never be followed
408
+ binread(symlink_target).should == "This is so wrong!!!"
409
+ end
410
+
411
+ it_behaves_like "file resource not pointing to a real file"
412
+ end
413
+ end
414
+
415
+ # Unix-only for now. Windows behavior may differ because of how ACL
416
+ # management handles symlinks. Since symlinks are rare on Windows and this
417
+ # feature primarily exists to support the case where a well-known file
418
+ # (e.g., resolv.conf) has been converted to a symlink, we're okay with the
419
+ # discrepancy.
420
+ context "when configured to manage the symlink source", :unix_only do
421
+
422
+ before do
423
+ resource.manage_symlink_source(true)
424
+ end
425
+
426
+ context "but the symlink is part of a loop" do
427
+ let(:link1_path) { File.join(CHEF_SPEC_DATA, "points-to-link2") }
428
+ let(:link2_path) { File.join(CHEF_SPEC_DATA, "points-to-link1") }
429
+
430
+ before do
431
+ # point resource at link1:
432
+ resource.path(link1_path)
433
+ # create symlinks for test context
434
+ File.symlink(link1_path, link2_path)
435
+ File.symlink(link2_path, link1_path)
436
+ end
437
+
438
+ after(:each) do
439
+ FileUtils.rm_rf(link1_path)
440
+ FileUtils.rm_rf(link2_path)
441
+ end
442
+
443
+ it "raises an InvalidSymlink error" do
444
+ lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::InvalidSymlink)
445
+ end
446
+
447
+ it "issues a warning/assumption in whyrun mode" do
448
+ begin
449
+ Chef::Config[:why_run] = true
450
+ resource.run_action(:create) # should not raise
451
+ ensure
452
+ Chef::Config[:why_run] = false
453
+ end
454
+ end
455
+ end
456
+
457
+ context "but the symlink points to a nonexistent file" do
458
+ let(:link_path) { File.join(CHEF_SPEC_DATA, "points-to-nothing") }
459
+ let(:not_existent_source) { File.join(CHEF_SPEC_DATA, "i-am-not-here") }
460
+
461
+ before do
462
+ resource.path(link_path)
463
+ # create symlinks for test context
464
+ File.symlink(not_existent_source, link_path)
465
+ FileUtils.rm_rf(not_existent_source)
466
+ end
467
+
468
+ after(:each) do
469
+ FileUtils.rm_rf(link_path)
470
+ end
471
+ it "raises an InvalidSymlink error" do
472
+ lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::InvalidSymlink)
473
+ end
474
+
475
+ it "issues a warning/assumption in whyrun mode" do
476
+ begin
477
+ Chef::Config[:why_run] = true
478
+ resource.run_action(:create) # should not raise
479
+ ensure
480
+ Chef::Config[:why_run] = false
481
+ end
482
+ end
483
+ end
484
+
485
+ context "but the symlink is points to a non-file fs entry" do
486
+ let(:link_path) { File.join(CHEF_SPEC_DATA, "points-to-dir") }
487
+ let(:not_a_file_path) { File.join(CHEF_SPEC_DATA, "dir-at-end-of-symlink") }
488
+
489
+ before do
490
+ # point resource at link1:
491
+ resource.path(link_path)
492
+ # create symlinks for test context
493
+ File.symlink(not_a_file_path, link_path)
494
+ Dir.mkdir(not_a_file_path)
495
+ end
496
+
497
+ after(:each) do
498
+ FileUtils.rm_rf(link_path)
499
+ FileUtils.rm_rf(not_a_file_path)
500
+ end
501
+
502
+ it "raises an InvalidSymlink error" do
503
+ lambda { resource.run_action(:create) }.should raise_error(Chef::Exceptions::FileTypeMismatch)
504
+ end
505
+
506
+ it "issues a warning/assumption in whyrun mode" do
507
+ begin
508
+ Chef::Config[:why_run] = true
509
+ resource.run_action(:create) # should not raise
510
+ ensure
511
+ Chef::Config[:why_run] = false
512
+ end
513
+ end
514
+ end
515
+
516
+ context "when the symlink source is a real file" do
517
+
518
+ let(:wrong_content) { "this is the wrong content" }
519
+ let(:link_path) { File.join(CHEF_SPEC_DATA, "points-to-real-file") }
520
+
521
+ before do
522
+ # point resource at link:
523
+ resource.path(link_path)
524
+ # create symlinks for test context
525
+ File.symlink(path, link_path)
526
+ end
527
+
528
+ after(:each) do
529
+ # shared examples should not change our test setup of a file resource
530
+ # pointing at a symlink:
531
+ resource.path.should == link_path
532
+ FileUtils.rm_rf(link_path)
533
+ end
534
+
535
+ context "and the permissions are incorrect" do
536
+ before do
537
+ # Create source (real) file
538
+ File.open(path, "wb") { |f| f.write(expected_content) }
539
+ end
540
+
541
+
542
+ include_context "setup broken permissions"
543
+
544
+ include_examples "a securable resource with existing target"
545
+
546
+ it "does not replace the symlink with a real file" do
547
+ resource.run_action(:create)
548
+ File.should be_symlink(link_path)
549
+ end
550
+
551
+ end
552
+
553
+ context "and the content is incorrect" do
554
+ before do
555
+ # Create source (real) file
556
+ File.open(path, "wb") { |f| f.write(wrong_content) }
557
+ end
558
+
559
+ it "updates the source file content" do
560
+ pending
561
+ end
562
+
563
+ it "marks the resource as updated" do
564
+ resource.run_action(:create)
565
+ resource.should be_updated_by_last_action
566
+ end
567
+
568
+ it "does not replace the symlink with a real file" do
569
+ resource.run_action(:create)
570
+ File.should be_symlink(link_path)
571
+ end
572
+ end
573
+
574
+ context "and the content and permissions are correct" do
575
+ let(:expect_updated?) { false }
576
+
577
+ before do
578
+ # Create source (real) file
579
+ File.open(path, "wb") { |f| f.write(expected_content) }
580
+ end
581
+ include_context "setup correct permissions"
582
+
583
+ include_examples "a securable resource with existing target"
584
+
585
+ end
586
+
587
+ end
588
+
589
+ context "when the symlink points to a symlink which points to a real file" do
590
+
591
+ let(:wrong_content) { "this is the wrong content" }
592
+ let(:link_to_file_path) { File.join(CHEF_SPEC_DATA, "points-to-real-file") }
593
+ let(:link_to_link_path) { File.join(CHEF_SPEC_DATA, "points-to-next-link") }
594
+
595
+ before do
596
+ # point resource at link:
597
+ resource.path(link_to_link_path)
598
+ # create symlinks for test context
599
+ File.symlink(path, link_to_file_path)
600
+ File.symlink(link_to_file_path, link_to_link_path)
601
+
602
+ # Create source (real) file
603
+ File.open(path, "wb") { |f| f.write(wrong_content) }
604
+ end
605
+
606
+ include_context "setup broken permissions"
607
+
608
+ include_examples "a securable resource with existing target"
609
+
610
+ after(:each) do
611
+ # shared examples should not change our test setup of a file resource
612
+ # pointing at a symlink:
613
+ resource.path.should == link_to_link_path
614
+ FileUtils.rm_rf(link_to_file_path)
615
+ FileUtils.rm_rf(link_to_link_path)
616
+ end
617
+
618
+ it "does not replace the symlink with a real file" do
619
+ resource.run_action(:create)
620
+ File.should be_symlink(link_to_link_path)
621
+ File.should be_symlink(link_to_file_path)
622
+ end
623
+
624
+ end
625
+ end
626
+ end
627
+
628
+ context "when the target file is a directory" do
629
+ before(:each) do
630
+ FileUtils.mkdir_p(path)
631
+ end
632
+
633
+ after(:each) do
634
+ FileUtils.rm_rf(path)
635
+ end
636
+
637
+ it_behaves_like "file resource not pointing to a real file"
638
+ end
639
+
640
+ context "when the target file is a blockdev",:unix_only, :requires_root, :not_supported_on_solaris do
641
+ include Chef::Mixin::ShellOut
642
+ let(:path) do
643
+ File.join(CHEF_SPEC_DATA, "testdev")
644
+ end
645
+
646
+ before(:each) do
647
+ result = shell_out("mknod #{path} b 1 2")
648
+ result.stderr.empty?
649
+ end
650
+
651
+ after(:each) do
652
+ FileUtils.rm_rf(path)
653
+ end
654
+
655
+ it_behaves_like "file resource not pointing to a real file"
656
+ end
657
+
658
+ context "when the target file is a chardev",:unix_only, :requires_root, :not_supported_on_solaris do
659
+ include Chef::Mixin::ShellOut
660
+ let(:path) do
661
+ File.join(CHEF_SPEC_DATA, "testdev")
662
+ end
663
+
664
+ before(:each) do
665
+ result = shell_out("mknod #{path} c 1 2")
666
+ result.stderr.empty?
667
+ end
668
+
669
+ after(:each) do
670
+ FileUtils.rm_rf(path)
671
+ end
672
+
673
+ it_behaves_like "file resource not pointing to a real file"
674
+ end
675
+
676
+ context "when the target file is a pipe",:unix_only do
677
+ include Chef::Mixin::ShellOut
678
+ let(:path) do
679
+ File.join(CHEF_SPEC_DATA, "testpipe")
680
+ end
681
+
682
+ before(:each) do
683
+ result = shell_out("mkfifo #{path}")
684
+ result.stderr.empty?
685
+ end
686
+
687
+ after(:each) do
688
+ FileUtils.rm_rf(path)
689
+ end
690
+
691
+ it_behaves_like "file resource not pointing to a real file"
692
+ end
693
+
694
+ context "when the target file is a socket",:unix_only do
695
+ require 'socket'
696
+
697
+ # It turns out that the path to a socket can have at most ~104
698
+ # bytes. Therefore we are creating our sockets in tmpdir so that
699
+ # they have a shorter path.
700
+ let(:test_socket_dir) { File.join(Dir.tmpdir, "sockets") }
701
+
702
+ before do
703
+ FileUtils::mkdir_p(test_socket_dir)
704
+ end
705
+
706
+ after do
707
+ FileUtils::rm_rf(test_socket_dir)
708
+ end
709
+
710
+ let(:path) do
711
+ File.join(test_socket_dir, "testsocket")
712
+ end
713
+
714
+ before(:each) do
715
+ path.bytesize.should <= 104
716
+ UNIXServer.new(path)
717
+ end
718
+
719
+ after(:each) do
720
+ FileUtils.rm_rf(path)
721
+ end
722
+
723
+ it_behaves_like "file resource not pointing to a real file"
724
+ end
725
+
726
+ # Regression test for http://tickets.opscode.com/browse/CHEF-4082
727
+ context "when notification is configured" do
728
+ describe "when path is specified with normal seperator" do
729
+ before do
730
+ @notified_resource = Chef::Resource.new("punk", resource.run_context)
731
+ resource.notifies(:run, @notified_resource, :immediately)
732
+ resource.run_action(:create)
733
+ end
734
+
735
+ it "should notify the other resources correctly" do
736
+ resource.should be_updated_by_last_action
737
+ resource.run_context.immediate_notifications(resource).length.should == 1
738
+ end
739
+ end
740
+
741
+ describe "when path is specified with windows seperator", :windows_only do
742
+ let(:path) {
743
+ File.join(test_file_dir, make_tmpname(file_base)).gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR)
744
+ }
745
+
746
+ before do
747
+ @notified_resource = Chef::Resource.new("punk", resource.run_context)
748
+ resource.notifies(:run, @notified_resource, :immediately)
749
+ resource.run_action(:create)
750
+ end
751
+
752
+ it "should notify the other resources correctly" do
753
+ resource.should be_updated_by_last_action
754
+ resource.run_context.immediate_notifications(resource).length.should == 1
755
+ end
756
+ end
757
+ end
758
+
175
759
  context "when the target file does not exist" do
176
760
  before do
177
761
  # Assert starting state is expected
@@ -194,6 +778,10 @@ shared_examples_for "a file resource" do
194
778
  it "is marked as updated by last action" do
195
779
  resource.should be_updated_by_last_action
196
780
  end
781
+
782
+ it "should restore the security contexts on selinux", :selinux_only do
783
+ selinux_security_context_restored?(path).should be_true
784
+ end
197
785
  end
198
786
 
199
787
  describe "when running action :create_if_missing" do
@@ -208,6 +796,10 @@ shared_examples_for "a file resource" do
208
796
  it "is marked as updated by last action" do
209
797
  resource.should be_updated_by_last_action
210
798
  end
799
+
800
+ it "should restore the security contexts on selinux", :selinux_only do
801
+ selinux_security_context_restored?(path).should be_true
802
+ end
211
803
  end
212
804
 
213
805
  describe "when running action :delete" do
@@ -234,6 +826,15 @@ shared_examples_for "a file resource" do
234
826
  [ ACE.access_denied(sid, expected_perms[:specific]) ]
235
827
  end
236
828
 
829
+ def parent_inheritable_acls
830
+ dummy_file_path = File.join(test_file_dir, "dummy_file")
831
+ FileUtils.touch(dummy_file_path)
832
+ dummy_desc = get_security_descriptor(dummy_file_path)
833
+ FileUtils.rm_rf(dummy_file_path)
834
+ dummy_desc
835
+ end
836
+
837
+ it_behaves_like "a securable resource without existing target"
237
838
 
238
839
  context "when the target file has the wrong content" do
239
840
  before(:each) do
@@ -250,7 +851,7 @@ shared_examples_for "a file resource" do
250
851
 
251
852
  it_behaves_like "a file with the wrong content"
252
853
 
253
- it_behaves_like "a securable resource"
854
+ it_behaves_like "a securable resource with existing target"
254
855
  end
255
856
 
256
857
  context "and the target file has incorrect permissions" do
@@ -258,7 +859,7 @@ shared_examples_for "a file resource" do
258
859
 
259
860
  it_behaves_like "a file with the wrong content"
260
861
 
261
- it_behaves_like "a securable resource"
862
+ it_behaves_like "a securable resource with existing target"
262
863
  end
263
864
  end
264
865
 
@@ -282,46 +883,86 @@ shared_examples_for "a file resource" do
282
883
 
283
884
  it_behaves_like "a file with the correct content"
284
885
 
285
- it_behaves_like "a securable resource"
886
+ it_behaves_like "a securable resource with existing target"
286
887
  end
287
888
 
288
889
  context "and the target file has incorrect permissions" do
289
890
  include_context "setup broken permissions"
290
891
 
291
892
  it_behaves_like "a file with the correct content"
292
-
293
- it_behaves_like "a securable resource"
893
+
894
+ it_behaves_like "a securable resource with existing target"
294
895
  end
295
896
  end
296
897
 
297
- it_behaves_like "a file that inherits permissions from a parent directory"
298
-
299
- end
898
+ # Regression test for http://tickets.opscode.com/browse/CHEF-4419
899
+ context "when the path starts with '/' and target file exists", :windows_only do
900
+ let(:path) do
901
+ File.join(test_file_dir[2..test_file_dir.length], make_tmpname(file_base))
902
+ end
300
903
 
301
- shared_examples_for "a file that inherits permissions from a parent directory" do
302
- include_context "diff disabled"
303
- include_context "use Windows permissions"
304
- context "on Windows", :windows_only do
305
- it "has only inherited aces if no explicit aces were specified" do
306
- File.exist?(path).should == false
904
+ before do
905
+ File.open(path, "wb") { |f| f.print expected_content }
906
+ now = Time.now.to_i
907
+ File.utime(now - 9000, now - 9000, path)
307
908
 
308
- resource.run_action(:create)
909
+ @expected_mtime = File.stat(path).mtime
910
+ @expected_checksum = sha256_checksum(path)
911
+ end
912
+
913
+ describe ":create action should run without any updates" do
914
+ before do
915
+ # Assert starting state is as expected
916
+ File.should exist(path)
917
+ sha256_checksum(path).should == @expected_checksum
918
+ resource.run_action(:create)
919
+ end
309
920
 
310
- descriptor.dacl_inherits?.should == true
311
- descriptor.dacl.each do | ace |
312
- ace.inherited?.should == true
921
+ it "does not overwrite the original when the :create action is run" do
922
+ sha256_checksum(path).should == @expected_checksum
923
+ end
924
+
925
+ it "does not update the mtime of the file when the :create action is run" do
926
+ File.stat(path).mtime.should == @expected_mtime
927
+ end
928
+
929
+ it "is not marked as updated by last action" do
930
+ resource.should_not be_updated_by_last_action
313
931
  end
314
932
  end
315
933
  end
934
+
316
935
  end
317
936
 
318
937
  shared_context Chef::Resource::File do
938
+ if windows?
939
+ require 'chef/win32/file'
940
+ end
941
+
942
+ # We create the files in a different directory than tmp to exercise
943
+ # different file deployment strategies more completely.
944
+ let(:test_file_dir) do
945
+ if windows?
946
+ File.join(ENV['systemdrive'], "test-dir")
947
+ else
948
+ File.join(CHEF_SPEC_DATA, "test-dir")
949
+ end
950
+ end
951
+
319
952
  let(:path) do
320
- File.join(Dir.tmpdir, make_tmpname(file_base))
953
+ File.join(test_file_dir, make_tmpname(file_base))
954
+ end
955
+
956
+ before do
957
+ FileUtils::mkdir_p(test_file_dir)
321
958
  end
322
959
 
323
960
  after(:each) do
324
961
  FileUtils.rm_r(path) if File.exists?(path)
325
962
  FileUtils.rm_r(CHEF_SPEC_BACKUP_PATH) if File.exists?(CHEF_SPEC_BACKUP_PATH)
326
963
  end
964
+
965
+ after do
966
+ FileUtils::rm_rf(test_file_dir)
967
+ end
327
968
  end