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,259 @@
1
+ #
2
+ # Author:: Seth Falcon (<seth@opscode.com>)
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 'spec_helper'
20
+ require 'chef/mixin/shell_out'
21
+ require 'tmpdir'
22
+ require 'shellwords'
23
+
24
+ # Deploy relies heavily on symlinks, so it doesn't work on windows.
25
+ describe Chef::Resource::Git do
26
+ include Chef::Mixin::ShellOut
27
+ let(:file_cache_path) { Dir.mktmpdir }
28
+ # Some versions of git complains when the deploy directory is
29
+ # already created. Here we intentionally don't create the deploy
30
+ # directory beforehand.
31
+ let(:base_dir_path) { Dir.mktmpdir }
32
+ let(:deploy_directory) { File.join(base_dir_path, make_tmpname("git_base")) }
33
+
34
+ let(:node) do
35
+ Chef::Node.new.tap do |n|
36
+ n.name "rspec-test"
37
+ n.consume_external_attrs(@ohai.data, {})
38
+ end
39
+ end
40
+
41
+ let(:event_dispatch) { Chef::EventDispatch::Dispatcher.new }
42
+ let(:run_context) { Chef::RunContext.new(node, {}, event_dispatch) }
43
+
44
+ # These tests use git's bundle feature, which is a way to export an entire
45
+ # git repo (or subset of commits) as a single file.
46
+ #
47
+ # Generally you can treat a git bundle as a regular git remote.
48
+ #
49
+ # See also: http://git-scm.com/2010/03/10/bundles.html
50
+ #
51
+ # Beware that git bundles don't behave exactly the same as real
52
+ # remotes. To get closer to real remotes, we'll create a local clone
53
+ # of the bundle to use as a remote for the tests. This at least
54
+ # gives the expected responses for ls-remote using git version
55
+ # 1.7.12.4
56
+ let(:git_bundle_repo) { File.expand_path("git_bundles/example-repo.gitbundle", CHEF_SPEC_DATA) }
57
+ let(:origin_repo_dir) { Dir.mktmpdir }
58
+ let(:origin_repo) { "#{origin_repo_dir}/example" }
59
+
60
+ # This is the fourth version
61
+ let(:v1_commit) { "bc5ec79931ae74089aeadca6edc173527613e6d9" }
62
+ let(:v1_tag) { "9b73fb5e316bfaff7b822b0ccb3e1e08f9885085" }
63
+ let(:rev_foo) { "ed181b3419b6f489bedab282348162a110d6d3a1" }
64
+ let(:rev_testing) { "972d153654503bccec29f630c5dd369854a561e8" }
65
+ let(:rev_head) { "d294fbfd05aa7709ad9a9b8ef6343b17d355bf5f"}
66
+
67
+ let(:git_user_config) do
68
+ <<-E
69
+ [user]
70
+ name = frodoTbaggins
71
+ email = frodo@shire.org
72
+ E
73
+ end
74
+
75
+ before(:each) do
76
+ Chef::Log.level = :warn # silence git command live streams
77
+ @old_file_cache_path = Chef::Config[:file_cache_path]
78
+ shell_out!("git clone \"#{git_bundle_repo}\" example", :cwd => origin_repo_dir)
79
+ File.open("#{origin_repo}/.git/config", "a+") {|f| f.print(git_user_config) }
80
+ Chef::Config[:file_cache_path] = file_cache_path
81
+ end
82
+
83
+ after(:each) do
84
+ Chef::Config[:file_cache_path] = @old_file_cache_path
85
+ FileUtils.remove_entry_secure deploy_directory if File.exist?(deploy_directory)
86
+ FileUtils.remove_entry_secure file_cache_path
87
+ end
88
+
89
+ after(:all) do
90
+ FileUtils.remove_entry_secure origin_repo_dir
91
+ end
92
+
93
+ before(:all) do
94
+ @ohai = Ohai::System.new
95
+ @ohai.require_plugin("os")
96
+ end
97
+
98
+ context "working with pathes with special characters" do
99
+ let(:path_with_spaces) { "#{origin_repo_dir}/path with spaces" }
100
+
101
+ before(:each) do
102
+ FileUtils.mkdir(path_with_spaces)
103
+ FileUtils.cp(git_bundle_repo, path_with_spaces)
104
+ end
105
+
106
+ it "clones a repository with a space in the path" do
107
+ Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
108
+ r.repository "#{path_with_spaces}/example-repo.gitbundle"
109
+ end.run_action(:sync)
110
+ end
111
+ end
112
+
113
+ context "when deploying from an annotated tag" do
114
+ let(:basic_git_resource) do
115
+ Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
116
+ r.repository origin_repo
117
+ r.revision "v1.0.0"
118
+ end
119
+ end
120
+
121
+ # We create a copy of the basic_git_resource so that we can run
122
+ # the resource again and verify that it doesn't update.
123
+ let(:copy_git_resource) do
124
+ Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
125
+ r.repository origin_repo
126
+ r.revision "v1.0.0"
127
+ end
128
+ end
129
+
130
+ it "checks out the revision pointed to by the tag commit, not the tag commit itself" do
131
+ basic_git_resource.run_action(:sync)
132
+ head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
133
+ head_rev.should == v1_commit
134
+ # also verify the tag commit itself is what we expect as an extra sanity check
135
+ rev = shell_out!('git rev-parse v1.0.0', :cwd => deploy_directory, :returns => [0]).stdout.strip
136
+ rev.should == v1_tag
137
+ end
138
+
139
+ it "doesn't update if up-to-date" do
140
+ # this used to fail because we didn't resolve the annotated tag
141
+ # properly to the pointed to commit.
142
+ basic_git_resource.run_action(:sync)
143
+ head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
144
+ head_rev.should == v1_commit
145
+
146
+ copy_git_resource.run_action(:sync)
147
+ copy_git_resource.should_not be_updated
148
+ end
149
+ end
150
+
151
+ context "when deploying from a SHA revision" do
152
+ let(:basic_git_resource) do
153
+ Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
154
+ r.repository git_bundle_repo
155
+ end
156
+ end
157
+
158
+ # We create a copy of the basic_git_resource so that we can run
159
+ # the resource again and verify that it doesn't update.
160
+ let(:copy_git_resource) do
161
+ Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
162
+ r.repository origin_repo
163
+ end
164
+ end
165
+
166
+ it "checks out the expected revision ed18" do
167
+ basic_git_resource.revision rev_foo
168
+ basic_git_resource.run_action(:sync)
169
+ head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
170
+ head_rev.should == rev_foo
171
+ end
172
+
173
+ it "doesn't update if up-to-date" do
174
+ basic_git_resource.revision rev_foo
175
+ basic_git_resource.run_action(:sync)
176
+ head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
177
+ head_rev.should == rev_foo
178
+
179
+ copy_git_resource.revision rev_foo
180
+ copy_git_resource.run_action(:sync)
181
+ copy_git_resource.should_not be_updated
182
+ end
183
+
184
+ it "checks out the expected revision 972d" do
185
+ basic_git_resource.revision rev_testing
186
+ basic_git_resource.run_action(:sync)
187
+ head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
188
+ head_rev.should == rev_testing
189
+ end
190
+ end
191
+
192
+ context "when deploying from a revision named 'HEAD'" do
193
+ let(:basic_git_resource) do
194
+ Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
195
+ r.repository origin_repo
196
+ r.revision 'HEAD'
197
+ end
198
+ end
199
+
200
+ it "checks out the expected revision" do
201
+ basic_git_resource.run_action(:sync)
202
+ head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
203
+ head_rev.should == rev_head
204
+ end
205
+ end
206
+
207
+ context "when deploying from the default revision" do
208
+ let(:basic_git_resource) do
209
+ Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
210
+ r.repository origin_repo
211
+ # use default
212
+ end
213
+ end
214
+
215
+ it "checks out HEAD as the default revision" do
216
+ basic_git_resource.run_action(:sync)
217
+ head_rev = shell_out!('git rev-parse HEAD', :cwd => deploy_directory, :returns => [0]).stdout.strip
218
+ head_rev.should == rev_head
219
+ end
220
+ end
221
+
222
+ context "when dealing with a repo with a degenerate tag named 'HEAD'" do
223
+ before do
224
+ shell_out!("git tag -m\"degenerate tag\" HEAD ed181b3419b6f489bedab282348162a110d6d3a1",
225
+ :cwd => origin_repo)
226
+ end
227
+
228
+ let(:basic_git_resource) do
229
+ Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
230
+ r.repository origin_repo
231
+ r.revision 'HEAD'
232
+ end
233
+ end
234
+
235
+ let(:git_resource_default_rev) do
236
+ Chef::Resource::Git.new(deploy_directory, run_context).tap do |r|
237
+ r.repository origin_repo
238
+ # use default of revision
239
+ end
240
+ end
241
+
242
+ it "checks out the (master) HEAD revision and ignores the tag" do
243
+ basic_git_resource.run_action(:sync)
244
+ head_rev = shell_out!('git rev-parse HEAD',
245
+ :cwd => deploy_directory,
246
+ :returns => [0]).stdout.strip
247
+ head_rev.should == rev_head
248
+ end
249
+
250
+ it "checks out the (master) HEAD revision when no revision is specified (ignores tag)" do
251
+ git_resource_default_rev.run_action(:sync)
252
+ head_rev = shell_out!('git rev-parse HEAD',
253
+ :cwd => deploy_directory,
254
+ :returns => [0]).stdout.strip
255
+ head_rev.should == rev_head
256
+ end
257
+
258
+ end
259
+ end
@@ -22,37 +22,56 @@ if windows?
22
22
  require 'chef/win32/file' #probably need this in spec_helper
23
23
  end
24
24
 
25
- describe Chef::Resource::Link, :not_supported_on_win2k3 do
25
+ describe Chef::Resource::Link do
26
26
  let(:file_base) { "file_spec" }
27
27
 
28
28
  let(:expect_updated?) {true}
29
29
 
30
- let(:base_dir) do
30
+ # We create the files in a different directory than tmp to exercise
31
+ # different file deployment strategies more completely.
32
+ let(:test_file_dir) do
31
33
  if windows?
32
- Chef::ReservedNames::Win32::File.get_long_path_name(Dir.tmpdir.gsub('/', '\\'))
34
+ File.join(ENV['systemdrive'], "test-dir")
33
35
  else
34
- Dir.tmpdir
36
+ File.join(CHEF_SPEC_DATA, "test-dir")
35
37
  end
36
38
  end
37
39
 
40
+ before do
41
+ FileUtils::mkdir_p(test_file_dir)
42
+ end
43
+
44
+ after do
45
+ FileUtils::rm_rf(test_file_dir)
46
+ end
47
+
38
48
  let(:to) do
39
- File.join(base_dir, make_tmpname("to_spec"))
49
+ File.join(test_file_dir, make_tmpname("to_spec"))
40
50
  end
41
51
  let(:target_file) do
42
- File.join(base_dir, make_tmpname("from_spec"))
52
+ File.join(test_file_dir, make_tmpname("from_spec"))
43
53
  end
44
54
 
45
55
  after(:each) do
46
- # TODO Windows fails to clean up some symlinks.
47
56
  begin
48
- FileUtils.rm_r(to) if File.exists?(to)
49
- FileUtils.rm_r(target_file) if File.exists?(target_file)
50
- FileUtils.rm_r(CHEF_SPEC_BACKUP_PATH) if File.exists?(CHEF_SPEC_BACKUP_PATH)
57
+ cleanup_link(to) if File.exists?(to)
58
+ cleanup_link(target_file) if File.exists?(target_file)
59
+ cleanup_link(CHEF_SPEC_BACKUP_PATH) if File.exists?(CHEF_SPEC_BACKUP_PATH)
51
60
  rescue
52
61
  puts "Could not remove a file: #{$!}"
53
62
  end
54
63
  end
55
64
 
65
+ def cleanup_link(path)
66
+ if windows? && File.directory?(path)
67
+ # If the link target is a directory rm_rf doesn't work all the
68
+ # time on windows.
69
+ system "rmdir '#{path}'"
70
+ else
71
+ FileUtils.rm_rf(path)
72
+ end
73
+ end
74
+
56
75
  def canonicalize(path)
57
76
  windows? ? path.gsub('/', '\\') : path
58
77
  end
@@ -97,478 +116,493 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do
97
116
  resource
98
117
  end
99
118
 
100
- let!(:resource) do
119
+ let(:resource) do
101
120
  create_resource
102
121
  end
103
122
 
104
- shared_examples_for 'delete errors out' do
105
- it 'delete errors out' do
106
- lambda { resource.run_action(:delete) }.should raise_error(Chef::Exceptions::Link)
107
- (File.exist?(target_file) || symlink?(target_file)).should be_true
123
+ describe "when supported on platform", :not_supported_on_win2k3 do
124
+ shared_examples_for 'delete errors out' do
125
+ it 'delete errors out' do
126
+ lambda { resource.run_action(:delete) }.should raise_error(Chef::Exceptions::Link)
127
+ (File.exist?(target_file) || symlink?(target_file)).should be_true
128
+ end
108
129
  end
109
- end
110
130
 
111
- shared_context 'delete is noop' do
112
- describe 'the :delete action' do
113
- before(:each) do
114
- @info = []
115
- Chef::Log.stub!(:info) { |msg| @info << msg }
116
- resource.run_action(:delete)
117
- end
131
+ shared_context 'delete is noop' do
132
+ describe 'the :delete action' do
133
+ before(:each) do
134
+ @info = []
135
+ Chef::Log.stub!(:info) { |msg| @info << msg }
136
+ resource.run_action(:delete)
137
+ end
118
138
 
119
- it 'leaves the file deleted' do
120
- File.exist?(target_file).should be_false
121
- symlink?(target_file).should be_false
122
- end
123
- it 'does not mark the resource updated' do
124
- resource.should_not be_updated
125
- end
126
- it 'does not log that it deleted' do
127
- @info.include?("link[#{target_file}] deleted").should be_false
139
+ it 'leaves the file deleted' do
140
+ File.exist?(target_file).should be_false
141
+ symlink?(target_file).should be_false
142
+ end
143
+ it 'does not mark the resource updated' do
144
+ resource.should_not be_updated
145
+ end
146
+ it 'does not log that it deleted' do
147
+ @info.include?("link[#{target_file}] deleted").should be_false
148
+ end
128
149
  end
129
150
  end
130
- end
131
151
 
132
- shared_context 'delete succeeds' do
133
- describe 'the :delete action' do
134
- before(:each) do
135
- @info = []
136
- Chef::Log.stub!(:info) { |msg| @info << msg }
137
- resource.run_action(:delete)
138
- end
152
+ shared_context 'delete succeeds' do
153
+ describe 'the :delete action' do
154
+ before(:each) do
155
+ @info = []
156
+ Chef::Log.stub!(:info) { |msg| @info << msg }
157
+ resource.run_action(:delete)
158
+ end
139
159
 
140
- it 'deletes the file' do
141
- File.exist?(target_file).should be_false
142
- symlink?(target_file).should be_false
143
- end
144
- it 'marks the resource updated' do
145
- resource.should be_updated
146
- end
147
- it 'logs that it deleted' do
148
- @info.include?("link[#{target_file}] deleted").should be_true
160
+ it 'deletes the file' do
161
+ File.exist?(target_file).should be_false
162
+ symlink?(target_file).should be_false
163
+ end
164
+ it 'marks the resource updated' do
165
+ resource.should be_updated
166
+ end
167
+ it 'logs that it deleted' do
168
+ @info.include?("link[#{target_file}] deleted").should be_true
169
+ end
149
170
  end
150
171
  end
151
- end
152
172
 
153
- shared_context 'create symbolic link succeeds' do
154
- describe 'the :create action' do
155
- before(:each) do
156
- @info = []
157
- Chef::Log.stub!(:info) { |msg| @info << msg }
158
- resource.run_action(:create)
159
- end
173
+ shared_context 'create symbolic link succeeds' do
174
+ describe 'the :create action' do
175
+ before(:each) do
176
+ @info = []
177
+ Chef::Log.stub!(:info) { |msg| @info << msg }
178
+ resource.run_action(:create)
179
+ end
160
180
 
161
- it 'links to the target file' do
162
- symlink?(target_file).should be_true
163
- readlink(target_file).should == canonicalize(to)
164
- end
165
- it 'marks the resource updated' do
166
- resource.should be_updated
167
- end
168
- it 'logs that it created' do
169
- @info.include?("link[#{target_file}] created").should be_true
181
+ it 'links to the target file' do
182
+ symlink?(target_file).should be_true
183
+ readlink(target_file).should == canonicalize(to)
184
+ end
185
+ it 'marks the resource updated' do
186
+ resource.should be_updated
187
+ end
188
+ it 'logs that it created' do
189
+ @info.include?("link[#{target_file}] created").should be_true
190
+ end
170
191
  end
171
192
  end
172
- end
173
193
 
174
- shared_context 'create symbolic link is noop' do
175
- describe 'the :create action' do
176
- before(:each) do
177
- @info = []
178
- Chef::Log.stub!(:info) { |msg| @info << msg }
179
- resource.run_action(:create)
180
- end
194
+ shared_context 'create symbolic link is noop' do
195
+ describe 'the :create action' do
196
+ before(:each) do
197
+ @info = []
198
+ Chef::Log.stub!(:info) { |msg| @info << msg }
199
+ resource.run_action(:create)
200
+ end
181
201
 
182
- it 'leaves the file linked' do
183
- symlink?(target_file).should be_true
184
- readlink(target_file).should == canonicalize(to)
185
- end
186
- it 'does not mark the resource updated' do
187
- resource.should_not be_updated
188
- end
189
- it 'does not log that it created' do
190
- @info.include?("link[#{target_file}] created").should be_false
202
+ it 'leaves the file linked' do
203
+ symlink?(target_file).should be_true
204
+ readlink(target_file).should == canonicalize(to)
205
+ end
206
+ it 'does not mark the resource updated' do
207
+ resource.should_not be_updated
208
+ end
209
+ it 'does not log that it created' do
210
+ @info.include?("link[#{target_file}] created").should be_false
211
+ end
191
212
  end
192
213
  end
193
- end
194
214
 
195
- shared_context 'create hard link succeeds' do
196
- describe 'the :create action' do
197
- before(:each) do
198
- @info = []
199
- Chef::Log.stub!(:info) { |msg| @info << msg }
200
- resource.run_action(:create)
201
- end
202
- it 'preserves the hard link' do
203
- File.exists?(target_file).should be_true
204
- symlink?(target_file).should be_false
205
- # Writing to one hardlinked file should cause both
206
- # to have the new value.
207
- IO.read(to).should == IO.read(target_file)
208
- File.open(to, "w") { |file| file.write('wowzers') }
209
- IO.read(target_file).should == 'wowzers'
210
- end
211
- it 'marks the resource updated' do
212
- resource.should be_updated
213
- end
214
- it 'logs that it created' do
215
- @info.include?("link[#{target_file}] created").should be_true
215
+ shared_context 'create hard link succeeds' do
216
+ describe 'the :create action' do
217
+ before(:each) do
218
+ @info = []
219
+ Chef::Log.stub!(:info) { |msg| @info << msg }
220
+ resource.run_action(:create)
221
+ end
222
+ it 'preserves the hard link' do
223
+ File.exists?(target_file).should be_true
224
+ symlink?(target_file).should be_false
225
+ # Writing to one hardlinked file should cause both
226
+ # to have the new value.
227
+ IO.read(to).should == IO.read(target_file)
228
+ File.open(to, "w") { |file| file.write('wowzers') }
229
+ IO.read(target_file).should == 'wowzers'
230
+ end
231
+ it 'marks the resource updated' do
232
+ resource.should be_updated
233
+ end
234
+ it 'logs that it created' do
235
+ @info.include?("link[#{target_file}] created").should be_true
236
+ end
216
237
  end
217
238
  end
218
- end
219
239
 
220
- shared_context 'create hard link is noop' do
221
- describe 'the :create action' do
222
- before(:each) do
223
- @info = []
224
- Chef::Log.stub!(:info) { |msg| @info << msg }
225
- resource.run_action(:create)
226
- end
227
- it 'links to the target file' do
228
- File.exists?(target_file).should be_true
229
- symlink?(target_file).should be_false
230
- # Writing to one hardlinked file should cause both
231
- # to have the new value.
232
- IO.read(to).should == IO.read(target_file)
233
- File.open(to, "w") { |file| file.write('wowzers') }
234
- IO.read(target_file).should == 'wowzers'
235
- end
236
- it 'does not mark the resource updated' do
237
- resource.should_not be_updated
238
- end
239
- it 'does not log that it created' do
240
- @info.include?("link[#{target_file}] created").should be_false
240
+ shared_context 'create hard link is noop' do
241
+ describe 'the :create action' do
242
+ before(:each) do
243
+ @info = []
244
+ Chef::Log.stub!(:info) { |msg| @info << msg }
245
+ resource.run_action(:create)
246
+ end
247
+ it 'links to the target file' do
248
+ File.exists?(target_file).should be_true
249
+ symlink?(target_file).should be_false
250
+ # Writing to one hardlinked file should cause both
251
+ # to have the new value.
252
+ IO.read(to).should == IO.read(target_file)
253
+ File.open(to, "w") { |file| file.write('wowzers') }
254
+ IO.read(target_file).should == 'wowzers'
255
+ end
256
+ it 'does not mark the resource updated' do
257
+ resource.should_not be_updated
258
+ end
259
+ it 'does not log that it created' do
260
+ @info.include?("link[#{target_file}] created").should be_false
261
+ end
241
262
  end
242
263
  end
243
- end
244
264
 
245
- context "is symbolic" do
265
+ context "is symbolic" do
246
266
 
247
- context 'when the link destination is a file' do
248
- before(:each) do
249
- File.open(to, "w") do |file|
250
- file.write('woohoo')
267
+ context 'when the link destination is a file' do
268
+ before(:each) do
269
+ File.open(to, "w") do |file|
270
+ file.write('woohoo')
271
+ end
251
272
  end
252
- end
253
- context 'and the link does not yet exist' do
254
- include_context 'create symbolic link succeeds'
255
- include_context 'delete is noop'
256
- end
257
- context 'and the link already exists and is a symbolic link' do
258
- context 'pointing at the target' do
259
- before(:each) do
260
- symlink(to, target_file)
261
- symlink?(target_file).should be_true
262
- readlink(target_file).should == canonicalize(to)
273
+ context 'and the link does not yet exist' do
274
+ include_context 'create symbolic link succeeds'
275
+ include_context 'delete is noop'
276
+ end
277
+ context 'and the link already exists and is a symbolic link' do
278
+ context 'pointing at the target' do
279
+ before(:each) do
280
+ symlink(to, target_file)
281
+ symlink?(target_file).should be_true
282
+ readlink(target_file).should == canonicalize(to)
283
+ end
284
+ include_context 'create symbolic link is noop'
285
+ include_context 'delete succeeds'
286
+ it 'the :delete action does not delete the target file' do
287
+ resource.run_action(:delete)
288
+ File.exists?(to).should be_true
289
+ end
263
290
  end
264
- include_context 'create symbolic link is noop'
265
- include_context 'delete succeeds'
266
- it 'the :delete action does not delete the target file' do
267
- resource.run_action(:delete)
268
- File.exists?(to).should be_true
291
+ context 'pointing somewhere else' do
292
+ before(:each) do
293
+ @other_target = File.join(test_file_dir, make_tmpname('other_spec'))
294
+ File.open(@other_target, 'w') { |file| file.write('eek') }
295
+ symlink(@other_target, target_file)
296
+ symlink?(target_file).should be_true
297
+ readlink(target_file).should == canonicalize(@other_target)
298
+ end
299
+ after(:each) do
300
+ File.delete(@other_target)
301
+ end
302
+ include_context 'create symbolic link succeeds'
303
+ include_context 'delete succeeds'
304
+ it 'the :delete action does not delete the target file' do
305
+ resource.run_action(:delete)
306
+ File.exists?(to).should be_true
307
+ end
308
+ end
309
+ context 'pointing nowhere' do
310
+ before(:each) do
311
+ nonexistent = File.join(test_file_dir, make_tmpname('nonexistent_spec'))
312
+ symlink(nonexistent, target_file)
313
+ symlink?(target_file).should be_true
314
+ readlink(target_file).should == canonicalize(nonexistent)
315
+ end
316
+ include_context 'create symbolic link succeeds'
317
+ include_context 'delete succeeds'
269
318
  end
270
319
  end
271
- context 'pointing somewhere else' do
320
+ context 'and the link already exists and is a hard link to the file' do
272
321
  before(:each) do
273
- @other_target = File.join(base_dir, make_tmpname('other_spec'))
274
- File.open(@other_target, 'w') { |file| file.write('eek') }
275
- symlink(@other_target, target_file)
276
- symlink?(target_file).should be_true
277
- readlink(target_file).should == @other_target
278
- end
279
- after(:each) do
280
- File.delete(@other_target)
322
+ link(to, target_file)
323
+ File.exists?(target_file).should be_true
324
+ symlink?(target_file).should be_false
281
325
  end
282
326
  include_context 'create symbolic link succeeds'
283
- include_context 'delete succeeds'
284
- it 'the :delete action does not delete the target file' do
285
- resource.run_action(:delete)
286
- File.exists?(to).should be_true
287
- end
327
+ it_behaves_like 'delete errors out'
288
328
  end
289
- context 'pointing nowhere' do
329
+ context 'and the link already exists and is a file' do
290
330
  before(:each) do
291
- nonexistent = File.join(base_dir, make_tmpname('nonexistent_spec'))
292
- symlink(nonexistent, target_file)
293
- symlink?(target_file).should be_true
294
- readlink(target_file).should == nonexistent
331
+ File.open(target_file, 'w') { |file| file.write('eek') }
295
332
  end
296
333
  include_context 'create symbolic link succeeds'
297
- include_context 'delete succeeds'
334
+ it_behaves_like 'delete errors out'
298
335
  end
299
- end
300
- context 'and the link already exists and is a hard link to the file' do
301
- before(:each) do
302
- link(to, target_file)
303
- File.exists?(target_file).should be_true
304
- symlink?(target_file).should be_false
336
+ context 'and the link already exists and is a directory' do
337
+ before(:each) do
338
+ Dir.mkdir(target_file)
339
+ end
340
+ it 'create errors out' do
341
+ if windows?
342
+ lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
343
+ elsif os_x? or solaris? or freebsd?
344
+ lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
345
+ else
346
+ lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
347
+ end
348
+ end
349
+ it_behaves_like 'delete errors out'
305
350
  end
306
- include_context 'create symbolic link succeeds'
307
- it_behaves_like 'delete errors out'
308
- end
309
- context 'and the link already exists and is a file' do
310
- before(:each) do
311
- File.open(target_file, 'w') { |file| file.write('eek') }
351
+ context 'and the link already exists and is not writeable to this user', :pending do
352
+ end
353
+ it_behaves_like 'a securable resource without existing target' do
354
+ let(:path) { target_file }
355
+ def allowed_acl(sid, expected_perms)
356
+ [ ACE.access_allowed(sid, expected_perms[:specific]) ]
357
+ end
358
+ def denied_acl(sid, expected_perms)
359
+ [ ACE.access_denied(sid, expected_perms[:specific]) ]
360
+ end
361
+ def parent_inheritable_acls
362
+ dummy_file_path = File.join(test_file_dir, "dummy_file")
363
+ dummy_file = FileUtils.touch(dummy_file_path)
364
+ dummy_desc = get_security_descriptor(dummy_file_path)
365
+ FileUtils.rm_rf(dummy_file_path)
366
+ dummy_desc
367
+ end
312
368
  end
313
- include_context 'create symbolic link succeeds'
314
- it_behaves_like 'delete errors out'
315
369
  end
316
- context 'and the link already exists and is a directory' do
370
+ context 'when the link destination is a directory' do
317
371
  before(:each) do
318
- Dir.mkdir(target_file)
372
+ Dir.mkdir(to)
319
373
  end
320
- it 'create errors out' do
321
- if windows?
322
- lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
323
- elsif os_x? or solaris? or freebsd?
324
- lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
325
- else
326
- lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
327
- end
374
+ # On Windows, readlink fails to open the link. FILE_FLAG_OPEN_REPARSE_POINT
375
+ # might help, from http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
376
+ context 'and the link does not yet exist' do
377
+ include_context 'create symbolic link succeeds'
378
+ include_context 'delete is noop'
328
379
  end
329
- it_behaves_like 'delete errors out'
330
- end
331
- context 'and the link already exists and is not writeable to this user', :pending do
332
380
  end
333
- it_behaves_like 'a securable resource' do
334
- let(:path) { target_file }
335
- def allowed_acl(sid, expected_perms)
336
- [ ACE.access_allowed(sid, expected_perms[:specific]) ]
381
+ context "when the link destination is a symbolic link" do
382
+ context 'to a file that exists' do
383
+ before(:each) do
384
+ @other_target = File.join(test_file_dir, make_tmpname("other_spec"))
385
+ File.open(@other_target, "w") { |file| file.write("eek") }
386
+ symlink(@other_target, to)
387
+ symlink?(to).should be_true
388
+ readlink(to).should == canonicalize(@other_target)
389
+ end
390
+ after(:each) do
391
+ File.delete(@other_target)
392
+ end
393
+ context 'and the link does not yet exist' do
394
+ include_context 'create symbolic link succeeds'
395
+ include_context 'delete is noop'
396
+ end
337
397
  end
338
- def denied_acl(sid, expected_perms)
339
- [ ACE.access_denied(sid, expected_perms[:specific]) ]
398
+ context 'to a file that does not exist' do
399
+ before(:each) do
400
+ @other_target = File.join(test_file_dir, make_tmpname("other_spec"))
401
+ symlink(@other_target, to)
402
+ symlink?(to).should be_true
403
+ readlink(to).should == canonicalize(@other_target)
404
+ end
405
+ context 'and the link does not yet exist' do
406
+ include_context 'create symbolic link succeeds'
407
+ include_context 'delete is noop'
408
+ end
340
409
  end
341
410
  end
342
- end
343
- context 'when the link destination is a directory' do
344
- before(:each) do
345
- Dir.mkdir(to)
411
+ context "when the link destination is not readable to this user", :pending do
346
412
  end
347
- # On Windows, readlink fails to open the link. FILE_FLAG_OPEN_REPARSE_POINT
348
- # might help, from http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
349
- context 'and the link does not yet exist' do
413
+ context "when the link destination does not exist" do
350
414
  include_context 'create symbolic link succeeds'
351
415
  include_context 'delete is noop'
352
416
  end
353
- end
354
- context "when the link destination is a symbolic link" do
355
- context 'to a file that exists' do
356
- before(:each) do
357
- @other_target = File.join(base_dir, make_tmpname("other_spec"))
358
- File.open(@other_target, "w") { |file| file.write("eek") }
359
- symlink(@other_target, to)
360
- symlink?(to).should be_true
361
- readlink(to).should == @other_target
362
- end
363
- after(:each) do
364
- File.delete(@other_target)
365
- end
366
- context 'and the link does not yet exist' do
367
- include_context 'create symbolic link succeeds'
368
- include_context 'delete is noop'
369
- end
370
- end
371
- context 'to a file that does not exist' do
372
- before(:each) do
373
- @other_target = File.join(base_dir, make_tmpname("other_spec"))
374
- symlink(@other_target, to)
375
- symlink?(to).should be_true
376
- readlink(to).should == @other_target
377
- end
378
- context 'and the link does not yet exist' do
379
- include_context 'create symbolic link succeeds'
380
- include_context 'delete is noop'
417
+
418
+ {
419
+ '../' => 'with a relative link destination',
420
+ '' => 'with a bare filename for the link destination'
421
+ }.each do |prefix, desc|
422
+ context desc do
423
+ let(:to) { "#{prefix}#{File.basename(absolute_to)}" }
424
+ let(:absolute_to) { File.join(test_file_dir, make_tmpname("to_spec")) }
425
+ before(:each) do
426
+ resource.to(to)
427
+ end
428
+ context 'when the link does not yet exist' do
429
+ include_context 'create symbolic link succeeds'
430
+ include_context 'delete is noop'
431
+ end
432
+ context 'when the link already exists and points at the target' do
433
+ before(:each) do
434
+ symlink(to, target_file)
435
+ symlink?(target_file).should be_true
436
+ readlink(target_file).should == canonicalize(to)
437
+ end
438
+ include_context 'create symbolic link is noop'
439
+ include_context 'delete succeeds'
440
+ end
441
+ context 'when the link already exists and points at the target with an absolute path' do
442
+ before(:each) do
443
+ symlink(absolute_to, target_file)
444
+ symlink?(target_file).should be_true
445
+ readlink(target_file).should == canonicalize(absolute_to)
446
+ end
447
+ include_context 'create symbolic link succeeds'
448
+ include_context 'delete succeeds'
449
+ end
381
450
  end
382
451
  end
383
452
  end
384
- context "when the link destination is not readable to this user", :pending do
385
- end
386
- context "when the link destination does not exist" do
387
- include_context 'create symbolic link succeeds'
388
- include_context 'delete is noop'
389
- end
390
453
 
391
- {
392
- '../' => 'with a relative link destination',
393
- '' => 'with a bare filename for the link destination'
394
- }.each do |prefix, desc|
395
- context desc do
396
- let(:to) { "#{prefix}#{File.basename(absolute_to)}" }
397
- let(:absolute_to) { File.join(base_dir, make_tmpname("to_spec")) }
454
+ context "is a hard link" do
455
+ before(:each) do
456
+ resource.link_type(:hard)
457
+ end
458
+
459
+ context "when the link destination is a file" do
398
460
  before(:each) do
399
- resource.to(to)
461
+ File.open(to, "w") do |file|
462
+ file.write('woohoo')
463
+ end
400
464
  end
401
- context 'when the link does not yet exist' do
402
- include_context 'create symbolic link succeeds'
465
+ context "and the link does not yet exist" do
466
+ include_context 'create hard link succeeds'
403
467
  include_context 'delete is noop'
404
468
  end
405
- context 'when the link already exists and points at the target' do
469
+ context "and the link already exists and is a symbolic link pointing at the same file" do
406
470
  before(:each) do
407
471
  symlink(to, target_file)
408
472
  symlink?(target_file).should be_true
409
473
  readlink(target_file).should == canonicalize(to)
410
474
  end
411
- include_context 'create symbolic link is noop'
412
- include_context 'delete succeeds'
475
+ include_context 'create hard link succeeds'
476
+ it_behaves_like 'delete errors out'
413
477
  end
414
- context 'when the link already exists and points at the target with an absolute path' do
478
+ context 'and the link already exists and is a hard link to the file' do
415
479
  before(:each) do
416
- symlink(absolute_to, target_file)
417
- symlink?(target_file).should be_true
418
- readlink(target_file).should == canonicalize(absolute_to)
480
+ link(to, target_file)
481
+ File.exists?(target_file).should be_true
482
+ symlink?(target_file).should be_false
419
483
  end
420
- include_context 'create symbolic link succeeds'
484
+ include_context 'create hard link is noop'
421
485
  include_context 'delete succeeds'
486
+ it 'the :delete action does not delete the target file' do
487
+ resource.run_action(:delete)
488
+ File.exists?(to).should be_true
489
+ end
422
490
  end
423
- end
424
- end
425
- end
426
-
427
- context "is a hard link" do
428
- before(:each) do
429
- resource.link_type(:hard)
430
- end
431
-
432
- context "when the link destination is a file" do
433
- before(:each) do
434
- File.open(to, "w") do |file|
435
- file.write('woohoo')
436
- end
437
- end
438
- context "and the link does not yet exist" do
439
- include_context 'create hard link succeeds'
440
- include_context 'delete is noop'
441
- end
442
- context "and the link already exists and is a symbolic link pointing at the same file" do
443
- before(:each) do
444
- symlink(to, target_file)
445
- symlink?(target_file).should be_true
446
- readlink(target_file).should == to
447
- end
448
- include_context 'create hard link succeeds'
449
- it_behaves_like 'delete errors out'
450
- end
451
- context 'and the link already exists and is a hard link to the file' do
452
- before(:each) do
453
- link(to, target_file)
454
- File.exists?(target_file).should be_true
455
- symlink?(target_file).should be_false
456
- end
457
- include_context 'create hard link is noop'
458
- include_context 'delete succeeds'
459
- it 'the :delete action does not delete the target file' do
460
- resource.run_action(:delete)
461
- File.exists?(to).should be_true
462
- end
463
- end
464
- context "and the link already exists and is a file" do
465
- before(:each) do
466
- File.open(target_file, 'w') { |file| file.write('tomfoolery') }
467
- end
468
- include_context 'create hard link succeeds'
469
- it_behaves_like 'delete errors out'
470
- end
471
- context "and the link already exists and is a directory" do
472
- before(:each) do
473
- Dir.mkdir(target_file)
491
+ context "and the link already exists and is a file" do
492
+ before(:each) do
493
+ File.open(target_file, 'w') { |file| file.write('tomfoolery') }
494
+ end
495
+ include_context 'create hard link succeeds'
496
+ it_behaves_like 'delete errors out'
474
497
  end
475
- it 'errors out' do
476
- if windows?
477
- lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
478
- elsif os_x? or solaris? or freebsd?
479
- lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
480
- else
481
- lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
498
+ context "and the link already exists and is a directory" do
499
+ before(:each) do
500
+ Dir.mkdir(target_file)
501
+ end
502
+ it 'errors out' do
503
+ if windows?
504
+ lambda { resource.run_action(:create) }.should raise_error(Errno::EACCES)
505
+ elsif os_x? or solaris? or freebsd?
506
+ lambda { resource.run_action(:create) }.should raise_error(Errno::EPERM)
507
+ else
508
+ lambda { resource.run_action(:create) }.should raise_error(Errno::EISDIR)
509
+ end
482
510
  end
511
+ it_behaves_like 'delete errors out'
483
512
  end
484
- it_behaves_like 'delete errors out'
485
- end
486
- context "and the link already exists and is not writeable to this user", :pending do
487
- end
488
- context "and specifies security attributes" do
489
- before(:each) do
490
- resource.owner(windows? ? 'Guest' : 'nobody')
513
+ context "and the link already exists and is not writeable to this user", :pending do
491
514
  end
492
- it 'ignores them' do
493
- resource.run_action(:create)
494
- if windows?
495
- Chef::ReservedNames::Win32::Security.get_named_security_info(target_file).owner.should_not == SID.Guest
496
- else
497
- File.lstat(target_file).uid.should_not == Etc.getpwnam('nobody').uid
515
+ context "and specifies security attributes" do
516
+ before(:each) do
517
+ resource.owner(windows? ? 'Guest' : 'nobody')
518
+ end
519
+ it 'ignores them' do
520
+ resource.run_action(:create)
521
+ if windows?
522
+ Chef::ReservedNames::Win32::Security.get_named_security_info(target_file).owner.should_not == SID.Guest
523
+ else
524
+ File.lstat(target_file).uid.should_not == Etc.getpwnam('nobody').uid
525
+ end
498
526
  end
499
527
  end
500
528
  end
501
- end
502
- context "when the link destination is a directory" do
503
- before(:each) do
504
- Dir.mkdir(to)
505
- end
506
- context 'and the link does not yet exist' do
507
- it 'create errors out' do
508
- lambda { resource.run_action(:create) }.should raise_error(windows? ? Chef::Exceptions::Win32APIError : Errno::EPERM)
509
- end
510
- include_context 'delete is noop'
511
- end
512
- end
513
- context "when the link destination is a symbolic link" do
514
- context 'to a real file' do
529
+ context "when the link destination is a directory" do
515
530
  before(:each) do
516
- @other_target = File.join(base_dir, make_tmpname("other_spec"))
517
- File.open(@other_target, "w") { |file| file.write("eek") }
518
- symlink(@other_target, to)
519
- symlink?(to).should be_true
520
- readlink(to).should == @other_target
521
- end
522
- after(:each) do
523
- File.delete(@other_target)
531
+ Dir.mkdir(to)
524
532
  end
525
533
  context 'and the link does not yet exist' do
526
- it 'links to the target file' do
527
- resource.run_action(:create)
528
- File.exists?(target_file).should be_true
529
- # OS X gets angry about this sort of link. Bug in OS X, IMO.
530
- pending('OS X/FreeBSD symlink? and readlink working on hard links to symlinks', :if => (os_x? or freebsd?)) do
531
- symlink?(target_file).should be_true
532
- readlink(target_file).should == @other_target
533
- end
534
+ it 'create errors out' do
535
+ lambda { resource.run_action(:create) }.should raise_error(windows? ? Chef::Exceptions::Win32APIError : Errno::EPERM)
534
536
  end
535
537
  include_context 'delete is noop'
536
538
  end
537
539
  end
538
- context 'to a nonexistent file' do
539
- before(:each) do
540
- @other_target = File.join(base_dir, make_tmpname("other_spec"))
541
- symlink(@other_target, to)
542
- symlink?(to).should be_true
543
- readlink(to).should == @other_target
544
- end
545
- context 'and the link does not yet exist' do
546
- it 'links to the target file' do
547
- pending('OS X/FreeBSD fails to create hardlinks to broken symlinks', :if => (os_x? or freebsd?)) do
540
+ context "when the link destination is a symbolic link" do
541
+ context 'to a real file' do
542
+ before(:each) do
543
+ @other_target = File.join(test_file_dir, make_tmpname("other_spec"))
544
+ File.open(@other_target, "w") { |file| file.write("eek") }
545
+ symlink(@other_target, to)
546
+ symlink?(to).should be_true
547
+ readlink(to).should == canonicalize(@other_target)
548
+ end
549
+ after(:each) do
550
+ File.delete(@other_target)
551
+ end
552
+ context 'and the link does not yet exist' do
553
+ it 'links to the target file' do
548
554
  resource.run_action(:create)
549
- # Windows and Unix have different definitions of exists? here, and that's OK.
550
- if windows?
551
- File.exists?(target_file).should be_true
552
- else
553
- File.exists?(target_file).should be_false
555
+ File.exists?(target_file).should be_true
556
+ # OS X gets angry about this sort of link. Bug in OS X, IMO.
557
+ pending('OS X/FreeBSD symlink? and readlink working on hard links to symlinks', :if => (os_x? or freebsd?)) do
558
+ symlink?(target_file).should be_true
559
+ readlink(target_file).should == canonicalize(@other_target)
554
560
  end
555
- symlink?(target_file).should be_true
556
- readlink(target_file).should == @other_target
557
561
  end
562
+ include_context 'delete is noop'
563
+ end
564
+ end
565
+ context 'to a nonexistent file' do
566
+ before(:each) do
567
+ @other_target = File.join(test_file_dir, make_tmpname("other_spec"))
568
+ symlink(@other_target, to)
569
+ symlink?(to).should be_true
570
+ readlink(to).should == canonicalize(@other_target)
571
+ end
572
+ context 'and the link does not yet exist' do
573
+ it 'links to the target file' do
574
+ pending('OS X/FreeBSD fails to create hardlinks to broken symlinks', :if => (os_x? or freebsd?)) do
575
+ resource.run_action(:create)
576
+ # Windows and Unix have different definitions of exists? here, and that's OK.
577
+ if windows?
578
+ File.exists?(target_file).should be_true
579
+ else
580
+ File.exists?(target_file).should be_false
581
+ end
582
+ symlink?(target_file).should be_true
583
+ readlink(target_file).should == canonicalize(@other_target)
584
+ end
585
+ end
586
+ include_context 'delete is noop'
558
587
  end
559
- include_context 'delete is noop'
560
588
  end
561
589
  end
562
- end
563
- context "when the link destination is not readable to this user", :pending do
564
- end
565
- context "when the link destination does not exist" do
566
- context 'and the link does not yet exist' do
567
- it 'create errors out' do
568
- lambda { resource.run_action(:create) }.should raise_error(Errno::ENOENT)
590
+ context "when the link destination is not readable to this user", :pending do
591
+ end
592
+ context "when the link destination does not exist" do
593
+ context 'and the link does not yet exist' do
594
+ it 'create errors out' do
595
+ lambda { resource.run_action(:create) }.should raise_error(Errno::ENOENT)
596
+ end
597
+ include_context 'delete is noop'
569
598
  end
570
- include_context 'delete is noop'
571
599
  end
572
600
  end
573
601
  end
602
+
603
+ describe "when not supported on platform", :win2k3_only do
604
+ it "raises error" do
605
+ lambda {resource}.should raise_error(Chef::Exceptions::Win32APIFunctionNotImplemented)
606
+ end
607
+ end
574
608
  end