chef 12.5.0.alpha.1 → 12.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (275) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +21 -25
  3. data/Gemfile +46 -0
  4. data/README.md +4 -4
  5. data/Rakefile +5 -110
  6. data/distro/common/html/knife_cookbook_site.html +18 -18
  7. data/distro/common/man/man1/knife-cookbook-site.1 +11 -11
  8. data/lib/chef/application.rb +1 -1
  9. data/lib/chef/application/apply.rb +19 -1
  10. data/lib/chef/application/client.rb +11 -5
  11. data/lib/chef/application/knife.rb +2 -2
  12. data/lib/chef/application/windows_service_manager.rb +9 -7
  13. data/lib/chef/chef_class.rb +39 -0
  14. data/lib/chef/chef_fs/data_handler/client_data_handler.rb +3 -1
  15. data/lib/chef/chef_fs/file_system/acl_dir.rb +3 -4
  16. data/lib/chef/chef_fs/file_system/acls_dir.rb +5 -1
  17. data/lib/chef/chef_fs/file_system/base_fs_dir.rb +0 -5
  18. data/lib/chef/chef_fs/file_system/base_fs_object.rb +5 -2
  19. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +2 -9
  20. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb +2 -9
  21. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +10 -17
  22. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +1 -12
  23. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +15 -11
  24. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +8 -2
  25. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +3 -4
  26. data/lib/chef/chef_fs/file_system/cookbooks_acl_dir.rb +1 -1
  27. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +3 -11
  28. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +3 -5
  29. data/lib/chef/chef_fs/file_system/environments_dir.rb +1 -1
  30. data/lib/chef/chef_fs/file_system/file_system_entry.rb +7 -4
  31. data/lib/chef/chef_fs/file_system/memory_dir.rb +2 -3
  32. data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +15 -0
  33. data/lib/chef/chef_fs/file_system/nodes_dir.rb +1 -1
  34. data/lib/chef/chef_fs/file_system/organization_members_entry.rb +2 -2
  35. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +4 -9
  36. data/lib/chef/client.rb +2 -3
  37. data/lib/chef/config.rb +34 -2
  38. data/lib/chef/cookbook/metadata.rb +25 -3
  39. data/lib/chef/cookbook/synchronizer.rb +1 -1
  40. data/lib/chef/cookbook_site_streaming_uploader.rb +1 -1
  41. data/lib/chef/cookbook_version.rb +3 -3
  42. data/lib/chef/deprecation/mixin/template.rb +1 -2
  43. data/lib/chef/deprecation/provider/cookbook_file.rb +1 -1
  44. data/lib/chef/deprecation/provider/file.rb +1 -1
  45. data/lib/chef/deprecation/provider/remote_directory.rb +52 -0
  46. data/lib/chef/deprecation/provider/remote_file.rb +1 -2
  47. data/lib/chef/deprecation/provider/template.rb +1 -1
  48. data/lib/chef/deprecation/warnings.rb +3 -4
  49. data/lib/chef/dsl/reboot_pending.rb +3 -2
  50. data/lib/chef/dsl/recipe.rb +6 -5
  51. data/lib/chef/dsl/resources.rb +2 -2
  52. data/lib/chef/event_dispatch/base.rb +12 -7
  53. data/lib/chef/event_dispatch/dispatcher.rb +21 -6
  54. data/lib/chef/exceptions.rb +22 -0
  55. data/lib/chef/file_content_management/tempfile.rb +1 -1
  56. data/lib/chef/formatters/base.rb +3 -0
  57. data/lib/chef/formatters/doc.rb +53 -5
  58. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +36 -0
  59. data/lib/chef/formatters/minimal.rb +2 -2
  60. data/lib/chef/knife.rb +35 -55
  61. data/lib/chef/knife/bootstrap.rb +41 -0
  62. data/lib/chef/knife/bootstrap/chef_vault_handler.rb +1 -0
  63. data/lib/chef/knife/bootstrap/client_builder.rb +16 -0
  64. data/lib/chef/knife/bootstrap/templates/README.md +3 -4
  65. data/lib/chef/knife/cookbook_create.rb +1 -1
  66. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  67. data/lib/chef/knife/cookbook_site_install.rb +1 -1
  68. data/lib/chef/knife/cookbook_site_share.rb +6 -6
  69. data/lib/chef/knife/cookbook_site_unshare.rb +2 -2
  70. data/lib/chef/knife/core/bootstrap_context.rb +12 -4
  71. data/lib/chef/knife/core/custom_manifest_loader.rb +69 -0
  72. data/lib/chef/knife/core/gem_glob_loader.rb +138 -0
  73. data/lib/chef/knife/core/hashed_command_loader.rb +80 -0
  74. data/lib/chef/knife/core/node_presenter.rb +24 -1
  75. data/lib/chef/knife/core/object_loader.rb +1 -0
  76. data/lib/chef/knife/core/subcommand_loader.rb +131 -146
  77. data/lib/chef/knife/node_run_list_remove.rb +12 -1
  78. data/lib/chef/knife/null.rb +10 -0
  79. data/lib/chef/knife/rehash.rb +62 -0
  80. data/lib/chef/knife/search.rb +3 -3
  81. data/lib/chef/knife/ssh.rb +52 -30
  82. data/lib/chef/local_mode.rb +5 -0
  83. data/lib/chef/log.rb +5 -1
  84. data/lib/chef/mixin/deprecation.rb +8 -8
  85. data/lib/chef/mixin/params_validate.rb +2 -2
  86. data/lib/chef/mixin/template.rb +48 -0
  87. data/lib/chef/mixin/which.rb +1 -1
  88. data/lib/chef/mixin/wide_string.rb +72 -0
  89. data/lib/chef/mixin/windows_architecture_helper.rb +15 -39
  90. data/lib/chef/mixin/windows_env_helper.rb +4 -1
  91. data/lib/chef/monkey_patches/webrick-utils.rb +51 -0
  92. data/lib/chef/monkey_patches/win32/registry.rb +72 -0
  93. data/lib/chef/node.rb +97 -3
  94. data/lib/chef/node_map.rb +2 -2
  95. data/lib/chef/platform/provider_mapping.rb +5 -6
  96. data/lib/chef/platform/query_helpers.rb +46 -4
  97. data/lib/chef/platform/service_helpers.rb +30 -32
  98. data/lib/chef/policy_builder.rb +1 -8
  99. data/lib/chef/policy_builder/dynamic.rb +186 -0
  100. data/lib/chef/policy_builder/expand_node_object.rb +30 -15
  101. data/lib/chef/policy_builder/policyfile.rb +155 -18
  102. data/lib/chef/property.rb +38 -9
  103. data/lib/chef/provider.rb +104 -12
  104. data/lib/chef/provider/batch.rb +8 -0
  105. data/lib/chef/provider/deploy.rb +2 -2
  106. data/lib/chef/provider/directory.rb +14 -2
  107. data/lib/chef/provider/dsc_resource.rb +5 -9
  108. data/lib/chef/provider/group/pw.rb +1 -1
  109. data/lib/chef/provider/ifconfig.rb +2 -2
  110. data/lib/chef/provider/mount.rb +7 -3
  111. data/lib/chef/provider/package/dpkg.rb +5 -11
  112. data/lib/chef/provider/package/rpm.rb +2 -2
  113. data/lib/chef/provider/package/rubygems.rb +1 -1
  114. data/lib/chef/provider/package/windows/msi.rb +2 -2
  115. data/lib/chef/provider/package/yum.rb +17 -5
  116. data/lib/chef/provider/powershell_script.rb +27 -4
  117. data/lib/chef/provider/remote_directory.rb +190 -102
  118. data/lib/chef/provider/service.rb +12 -2
  119. data/lib/chef/provider/service/aix.rb +1 -1
  120. data/lib/chef/provider/service/debian.rb +3 -5
  121. data/lib/chef/provider/service/freebsd.rb +1 -1
  122. data/lib/chef/provider/service/gentoo.rb +3 -3
  123. data/lib/chef/provider/service/init.rb +3 -3
  124. data/lib/chef/provider/service/insserv.rb +2 -4
  125. data/lib/chef/provider/service/invokercd.rb +2 -4
  126. data/lib/chef/provider/service/openbsd.rb +2 -1
  127. data/lib/chef/provider/service/redhat.rb +52 -16
  128. data/lib/chef/provider/service/simple.rb +2 -2
  129. data/lib/chef/provider/service/systemd.rb +3 -5
  130. data/lib/chef/provider/service/upstart.rb +4 -6
  131. data/lib/chef/provider/subversion.rb +13 -7
  132. data/lib/chef/provider/template/content.rb +16 -6
  133. data/lib/chef/provider/user/solaris.rb +32 -4
  134. data/lib/chef/provider/windows_script.rb +3 -5
  135. data/lib/chef/provider_resolver.rb +2 -2
  136. data/lib/chef/resource.rb +85 -27
  137. data/lib/chef/resource/action_class.rb +83 -0
  138. data/lib/chef/resource/chef_gem.rb +3 -3
  139. data/lib/chef/resource/deploy.rb +8 -2
  140. data/lib/chef/resource/dsc_script.rb +2 -0
  141. data/lib/chef/resource/file/verification.rb +1 -1
  142. data/lib/chef/resource/registry_key.rb +1 -1
  143. data/lib/chef/resource/service.rb +10 -2
  144. data/lib/chef/resource/subversion.rb +5 -0
  145. data/lib/chef/resource/windows_script.rb +6 -2
  146. data/lib/chef/resource/yum_package.rb +10 -1
  147. data/lib/chef/resource_resolver.rb +3 -3
  148. data/lib/chef/run_context.rb +6 -8
  149. data/lib/chef/run_list/versioned_recipe_list.rb +15 -0
  150. data/lib/chef/run_lock.rb +30 -21
  151. data/lib/chef/util/powershell/ps_credential.rb +4 -0
  152. data/lib/chef/util/windows.rb +0 -32
  153. data/lib/chef/util/windows/net_group.rb +85 -106
  154. data/lib/chef/util/windows/net_use.rb +35 -71
  155. data/lib/chef/util/windows/net_user.rb +0 -1
  156. data/lib/chef/util/windows/volume.rb +19 -19
  157. data/lib/chef/version.rb +3 -3
  158. data/lib/chef/win32/api.rb +1 -0
  159. data/lib/chef/win32/api/file.rb +20 -0
  160. data/lib/chef/win32/api/net.rb +163 -43
  161. data/lib/chef/win32/api/registry.rb +51 -0
  162. data/lib/chef/win32/api/system.rb +23 -0
  163. data/lib/chef/win32/api/unicode.rb +0 -43
  164. data/lib/chef/win32/crypto.rb +2 -1
  165. data/lib/chef/win32/file.rb +28 -3
  166. data/lib/chef/win32/mutex.rb +1 -2
  167. data/lib/chef/win32/net.rb +162 -8
  168. data/lib/chef/win32/process.rb +13 -0
  169. data/lib/chef/win32/registry.rb +25 -28
  170. data/lib/chef/win32/security.rb +1 -1
  171. data/lib/chef/win32/security/token.rb +1 -1
  172. data/lib/chef/win32/system.rb +62 -0
  173. data/lib/chef/win32/unicode.rb +7 -2
  174. data/lib/chef/win32/version.rb +0 -4
  175. data/spec/data/cookbooks/openldap/templates/default/helpers.erb +14 -0
  176. data/spec/data/cookbooks/openldap/templates/default/nested_openldap_partials.erb +1 -0
  177. data/spec/data/cookbooks/openldap/templates/default/nested_partial.erb +1 -0
  178. data/spec/data/dsc_lcm.pfx +0 -0
  179. data/spec/functional/dsl/reboot_pending_spec.rb +33 -43
  180. data/spec/functional/knife/cookbook_delete_spec.rb +17 -7
  181. data/spec/functional/knife/ssh_spec.rb +16 -0
  182. data/spec/functional/resource/deploy_revision_spec.rb +1 -1
  183. data/spec/functional/resource/dsc_resource_spec.rb +2 -0
  184. data/spec/functional/resource/dsc_script_spec.rb +91 -2
  185. data/spec/functional/resource/group_spec.rb +67 -44
  186. data/spec/functional/resource/powershell_script_spec.rb +104 -15
  187. data/spec/functional/resource/windows_service_spec.rb +1 -1
  188. data/spec/functional/run_lock_spec.rb +368 -189
  189. data/spec/functional/win32/{registry_helper_spec.rb → registry_spec.rb} +4 -23
  190. data/spec/integration/client/client_spec.rb +51 -0
  191. data/spec/integration/knife/download_spec.rb +4 -0
  192. data/spec/integration/knife/list_spec.rb +8 -0
  193. data/spec/integration/knife/upload_spec.rb +1 -1
  194. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -1
  195. data/spec/integration/recipes/remote_directory.rb +74 -0
  196. data/spec/integration/recipes/resource_action_spec.rb +42 -22
  197. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +423 -0
  198. data/spec/integration/recipes/resource_load_spec.rb +206 -0
  199. data/spec/spec_helper.rb +8 -0
  200. data/spec/support/platform_helpers.rb +13 -0
  201. data/{lib/chef/mixin/wstring.rb → spec/support/shared/context/win32.rb} +15 -12
  202. data/spec/support/shared/functional/windows_script.rb +63 -26
  203. data/spec/support/shared/unit/mock_shellout.rb +46 -0
  204. data/spec/support/shared/unit/provider/file.rb +10 -4
  205. data/spec/unit/application/client_spec.rb +16 -3
  206. data/spec/unit/application/knife_spec.rb +2 -2
  207. data/spec/unit/chef_class_spec.rb +0 -4
  208. data/spec/unit/client_spec.rb +6 -1
  209. data/spec/unit/config_spec.rb +31 -0
  210. data/spec/unit/cookbook/metadata_spec.rb +23 -3
  211. data/spec/unit/cookbook/syntax_check_spec.rb +3 -0
  212. data/spec/unit/deprecation_spec.rb +3 -6
  213. data/spec/unit/dsl/reboot_pending_spec.rb +12 -6
  214. data/spec/unit/event_dispatch/dispatcher_spec.rb +65 -3
  215. data/spec/unit/event_dispatch/dsl_spec.rb +0 -4
  216. data/spec/unit/formatters/doc_spec.rb +32 -0
  217. data/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb +26 -0
  218. data/spec/unit/knife/bootstrap/client_builder_spec.rb +27 -0
  219. data/spec/unit/knife/bootstrap_spec.rb +55 -3
  220. data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
  221. data/spec/unit/knife/core/bootstrap_context_spec.rb +21 -4
  222. data/spec/unit/knife/core/custom_manifest_loader_spec.rb +41 -0
  223. data/spec/unit/knife/core/gem_glob_loader_spec.rb +210 -0
  224. data/spec/unit/knife/core/hashed_command_loader_spec.rb +93 -0
  225. data/spec/unit/knife/core/subcommand_loader_spec.rb +16 -192
  226. data/spec/unit/knife/node_run_list_remove_spec.rb +17 -0
  227. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +10 -10
  228. data/spec/unit/mixin/template_spec.rb +5 -1
  229. data/spec/unit/mixin/windows_architecture_helper_spec.rb +13 -8
  230. data/spec/unit/node_spec.rb +213 -0
  231. data/spec/unit/platform/query_helpers_spec.rb +146 -3
  232. data/spec/unit/policy_builder/dynamic_spec.rb +275 -0
  233. data/spec/unit/policy_builder/expand_node_object_spec.rb +37 -38
  234. data/spec/unit/policy_builder/policyfile_spec.rb +260 -46
  235. data/spec/unit/property/validation_spec.rb +5 -0
  236. data/spec/unit/property_spec.rb +152 -26
  237. data/spec/unit/provider/deploy_spec.rb +5 -5
  238. data/spec/unit/provider/directory_spec.rb +35 -0
  239. data/spec/unit/provider/dsc_resource_spec.rb +3 -10
  240. data/spec/unit/provider/ifconfig_spec.rb +22 -2
  241. data/spec/unit/provider/mount/aix_spec.rb +2 -1
  242. data/spec/unit/provider/mount/mount_spec.rb +6 -0
  243. data/spec/unit/provider/mount/windows_spec.rb +14 -0
  244. data/spec/unit/provider/mount_spec.rb +12 -1
  245. data/spec/unit/provider/package/dpkg_spec.rb +8 -1
  246. data/spec/unit/provider/package/rpm_spec.rb +18 -1
  247. data/spec/unit/provider/package/rubygems_spec.rb +18 -0
  248. data/spec/unit/provider/package/yum_spec.rb +97 -24
  249. data/spec/unit/provider/powershell_script_spec.rb +52 -26
  250. data/spec/unit/provider/remote_directory_spec.rb +1 -2
  251. data/spec/unit/provider/service/aix_service_spec.rb +3 -3
  252. data/spec/unit/provider/service/gentoo_service_spec.rb +4 -4
  253. data/spec/unit/provider/service/openbsd_service_spec.rb +10 -8
  254. data/spec/unit/provider/service/redhat_spec.rb +88 -8
  255. data/spec/unit/provider/service/upstart_service_spec.rb +11 -7
  256. data/spec/unit/provider/service/windows_spec.rb +211 -200
  257. data/spec/unit/provider/subversion_spec.rb +50 -31
  258. data/spec/unit/provider/template/content_spec.rb +93 -2
  259. data/spec/unit/provider/user/solaris_spec.rb +66 -9
  260. data/spec/unit/provider_resolver_spec.rb +707 -650
  261. data/spec/unit/resource/deploy_spec.rb +7 -1
  262. data/spec/unit/resource/dsc_script_spec.rb +4 -0
  263. data/spec/unit/resource/file/verification_spec.rb +1 -1
  264. data/spec/unit/resource/powershell_script_spec.rb +17 -13
  265. data/spec/unit/resource/service_spec.rb +4 -4
  266. data/spec/unit/resource/subversion_spec.rb +4 -0
  267. data/spec/unit/resource/yum_package_spec.rb +10 -1
  268. data/spec/unit/run_list/versioned_recipe_list_spec.rb +5 -0
  269. data/spec/unit/win32/registry_spec.rb +394 -0
  270. data/tasks/external_tests.rb +47 -23
  271. data/tasks/maintainers.rb +155 -14
  272. metadata +51 -26
  273. data/lib/chef/knife/bootstrap/templates/archlinux-gems.erb +0 -76
  274. data/lib/chef/knife/bootstrap/templates/chef-aix.erb +0 -72
  275. data/spec/unit/registry_helper_spec.rb +0 -390
@@ -18,7 +18,7 @@
18
18
 
19
19
  # TODO: Allow @new_resource.source to be a Product Code as a GUID for uninstall / network install
20
20
 
21
- require 'chef/win32/api/installer' if RUBY_PLATFORM =~ /mswin|mingw32|windows/
21
+ require 'chef/win32/api/installer' if (RUBY_PLATFORM =~ /mswin|mingw32|windows/) && Chef::Platform.supports_msi?
22
22
  require 'chef/mixin/shell_out'
23
23
 
24
24
  class Chef
@@ -26,7 +26,7 @@ class Chef
26
26
  class Package
27
27
  class Windows
28
28
  class MSI
29
- include Chef::ReservedNames::Win32::API::Installer if RUBY_PLATFORM =~ /mswin|mingw32|windows/
29
+ include Chef::ReservedNames::Win32::API::Installer if (RUBY_PLATFORM =~ /mswin|mingw32|windows/) && Chef::Platform.supports_msi?
30
30
  include Chef::Mixin::ShellOut
31
31
 
32
32
  def initialize(resource)
@@ -1,6 +1,6 @@
1
1
 
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
- # Copyright:: Copyright (c) 2008 Opscode, Inc.
3
+ # Copyright:: Copyright (c) 2008-2015 Chef Software, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -651,6 +651,8 @@ class Chef
651
651
  include Chef::Mixin::ShellOut
652
652
  include Singleton
653
653
 
654
+ attr_accessor :yum_binary
655
+
654
656
  def initialize
655
657
  @rpmdb = RPMDb.new
656
658
 
@@ -781,7 +783,7 @@ class Chef
781
783
  end
782
784
 
783
785
  def python_bin
784
- yum_executable = which("yum")
786
+ yum_executable = which(yum_binary)
785
787
  if yum_executable && shabang?(yum_executable)
786
788
  extract_interpreter(yum_executable)
787
789
  else
@@ -980,6 +982,15 @@ class Chef
980
982
  super
981
983
 
982
984
  @yum = YumCache.instance
985
+ @yum.yum_binary = yum_binary
986
+ end
987
+
988
+ def yum_binary
989
+ @yum_binary ||=
990
+ begin
991
+ yum_binary = new_resource.yum_binary if new_resource.is_a?(Chef::Resource::YumPackage)
992
+ yum_binary ||= ::File.exist?("/usr/bin/yum-deprecated") ? "yum-deprecated" : "yum"
993
+ end
983
994
  end
984
995
 
985
996
  # Extra attributes
@@ -1026,6 +1037,7 @@ class Chef
1026
1037
  end
1027
1038
 
1028
1039
  def yum_command(command)
1040
+ command = "#{yum_binary} #{command}"
1029
1041
  Chef::Log.debug("#{@new_resource}: yum command: \"#{command}\"")
1030
1042
  status = shell_out_with_timeout(command, {:timeout => Chef::Config[:yum_timeout]})
1031
1043
 
@@ -1233,7 +1245,7 @@ class Chef
1233
1245
  end
1234
1246
  pkg_string = pkg_string_bits.join(' ')
1235
1247
  Chef::Log.info("#{@new_resource} #{log_method} #{repos.join(' ')}")
1236
- yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} #{method} #{pkg_string}")
1248
+ yum_command("-d0 -e0 -y#{expand_options(@new_resource.options)} #{method} #{pkg_string}")
1237
1249
  else
1238
1250
  raise Chef::Exceptions::Package, "Version #{version} of #{name} not found. Did you specify both version " +
1239
1251
  "and release? (version-release, e.g. 1.84-10.fc6)"
@@ -1242,7 +1254,7 @@ class Chef
1242
1254
 
1243
1255
  def install_package(name, version)
1244
1256
  if @new_resource.source
1245
- yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} localinstall #{@new_resource.source}")
1257
+ yum_command("-d0 -e0 -y#{expand_options(@new_resource.options)} localinstall #{@new_resource.source}")
1246
1258
  else
1247
1259
  install_remote_package(name, version)
1248
1260
  end
@@ -1290,7 +1302,7 @@ class Chef
1290
1302
  "#{n}#{yum_arch(a)}"
1291
1303
  end.join(' ')
1292
1304
  end
1293
- yum_command("yum -d0 -e0 -y#{expand_options(@new_resource.options)} remove #{remove_str}")
1305
+ yum_command("-d0 -e0 -y#{expand_options(@new_resource.options)} remove #{remove_str}")
1294
1306
 
1295
1307
  if flush_cache[:after]
1296
1308
  @yum.reload
@@ -16,6 +16,7 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
+ require 'chef/platform/query_helpers'
19
20
  require 'chef/provider/windows_script'
20
21
 
21
22
  class Chef
@@ -34,13 +35,30 @@ class Chef
34
35
  super
35
36
  end
36
37
 
37
- def flags
38
+ def command
39
+ basepath = is_forced_32bit ? wow64_directory : run_context.node.kernel.os_info.system_directory
40
+
41
+ # Powershell.exe is always in "v1.0" folder (for backwards compatibility)
42
+ interpreter_path = Chef::Util::PathHelper.join(basepath, "WindowsPowerShell", "v1.0", interpreter)
43
+
38
44
  # Must use -File rather than -Command to launch the script
39
45
  # file created by the base class that contains the script
40
46
  # code -- otherwise, powershell.exe does not propagate the
41
47
  # error status of a failed Windows process that ran at the
42
48
  # end of the script, it gets changed to '1'.
43
- interpreter_flags = [default_interpreter_flags, '-File'].join(' ')
49
+ #
50
+ # Nano only supports -Command
51
+ cmd = "\"#{interpreter_path}\" #{flags}"
52
+ if Chef::Platform.windows_nano_server?
53
+ cmd << " -Command \". '#{script_file.path}'\""
54
+ else
55
+ cmd << " -File \"#{script_file.path}\""
56
+ end
57
+ cmd
58
+ end
59
+
60
+ def flags
61
+ interpreter_flags = [*default_interpreter_flags].join(' ')
44
62
 
45
63
  if ! (@new_resource.flags.nil?)
46
64
  interpreter_flags = [@new_resource.flags, interpreter_flags].join(' ')
@@ -78,7 +96,7 @@ EOH
78
96
  # written to the file system at this point, which is required since
79
97
  # the intent is to execute the code just written to it.
80
98
  user_script_file.close
81
- validation_command = "\"#{interpreter}\" #{interpreter_arguments} -Command #{user_script_file.path}"
99
+ validation_command = "\"#{interpreter}\" #{interpreter_arguments} -Command \". '#{user_script_file.path}'\""
82
100
 
83
101
  # Note that other script providers like bash allow syntax errors
84
102
  # to be suppressed by setting 'returns' to a value that the
@@ -90,11 +108,16 @@ EOH
90
108
  # Therefore, the only return value for a syntactically valid
91
109
  # script is 0. If an exception is raised by shellout, this
92
110
  # means a non-zero return and thus a syntactically invalid script.
93
- shell_out!(validation_command, {returns: [0]})
111
+
112
+ with_os_architecture(node, architecture: new_resource.architecture) do
113
+ shell_out!(validation_command, {returns: [0]})
114
+ end
94
115
  end
95
116
  end
96
117
 
97
118
  def default_interpreter_flags
119
+ return [] if Chef::Platform.windows_nano_server?
120
+
98
121
  # Execution policy 'Bypass' is preferable since it doesn't require
99
122
  # user input confirmation for files such as PowerShell modules
100
123
  # downloaded from the Internet. However, 'Bypass' is not supported
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@opscode.com>)
3
- # Copyright:: Copyright (c) 2008 Opscode, Inc.
3
+ # Copyright:: Copyright (c) 2008-2015 Chef Software, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,178 +16,266 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'chef/provider/file'
20
19
  require 'chef/provider/directory'
20
+ require 'chef/resource/file'
21
21
  require 'chef/resource/directory'
22
- require 'chef/resource/remote_file'
22
+ require 'chef/resource/cookbook_file'
23
23
  require 'chef/mixin/file_class'
24
- require 'chef/platform'
25
- require 'uri'
26
- require 'tempfile'
27
- require 'net/https'
28
- require 'set'
24
+ require 'chef/platform/query_helpers'
29
25
  require 'chef/util/path_helper'
26
+ require 'chef/deprecation/warnings'
27
+ require 'chef/deprecation/provider/remote_directory'
28
+
29
+ require 'forwardable'
30
30
 
31
31
  class Chef
32
32
  class Provider
33
33
  class RemoteDirectory < Chef::Provider::Directory
34
+ extend Forwardable
35
+ include Chef::Mixin::FileClass
34
36
 
35
37
  provides :remote_directory
36
38
 
37
- include Chef::Mixin::FileClass
39
+ def_delegators :@new_resource, :purge, :path, :source, :cookbook, :cookbook_name
40
+ def_delegators :@new_resource, :files_rights, :files_mode, :files_group, :files_owner, :files_backup
41
+ def_delegators :@new_resource, :rights, :mode, :group, :owner
42
+
43
+ # The overwrite property on the resource. Delegates to new_resource but can be mutated.
44
+ #
45
+ # @return [Boolean] if we are overwriting
46
+ #
47
+ def overwrite?
48
+ @overwrite = new_resource.overwrite if @overwrite.nil?
49
+ !!@overwrite
50
+ end
51
+
52
+ attr_accessor :managed_files
53
+
54
+ # Hash containing keys of the paths for all the files that we sync, plus all their
55
+ # parent directories.
56
+ #
57
+ # @return [Set] Ruby Set of the files that we manage
58
+ #
59
+ def managed_files
60
+ @managed_files ||= Set.new
61
+ end
38
62
 
63
+ # Handle action :create.
64
+ #
39
65
  def action_create
40
66
  super
41
- # Mark all files as needing to be purged
42
- files_to_purge = Set.new(ls(@new_resource.path)) # Make sure each path is clean
43
67
 
44
68
  # Transfer files
45
69
  files_to_transfer.each do |cookbook_file_relative_path|
46
70
  create_cookbook_file(cookbook_file_relative_path)
47
- # parent directories and file being transferred are removed from the purge list
48
- Pathname.new(Chef::Util::PathHelper.cleanpath(::File.join(@new_resource.path, cookbook_file_relative_path))).descend do |d|
49
- files_to_purge.delete(d.to_s)
50
- end
71
+ # parent directories and file being transferred need to not be removed in the purge
72
+ add_managed_file(cookbook_file_relative_path)
51
73
  end
52
74
 
53
- purge_unmanaged_files(files_to_purge)
75
+ purge_unmanaged_files
54
76
  end
55
77
 
78
+ # Handle action :create_if_missing.
79
+ #
56
80
  def action_create_if_missing
57
81
  # if this action is called, ignore the existing overwrite flag
58
- @new_resource.overwrite(false)
82
+ @overwrite = false
59
83
  action_create
60
84
  end
61
85
 
62
- protected
86
+ private
63
87
 
64
- # List all excluding . and ..
65
- def ls(path)
66
- files = Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob(path), '**', '*'),
67
- ::File::FNM_DOTMATCH)
68
-
69
- # Remove current directory and previous directory
70
- files.reject! do |name|
71
- basename = Pathname.new(name).basename().to_s
72
- ['.', '..'].include?(basename)
88
+ # Add a file and its parent directories to the managed_files Hash.
89
+ #
90
+ # @param [String] cookbook_file_relative_path relative path to the file
91
+ # @api private
92
+ #
93
+ def add_managed_file(cookbook_file_relative_path)
94
+ if purge
95
+ Pathname.new(Chef::Util::PathHelper.cleanpath(::File.join(path, cookbook_file_relative_path))).descend do |d|
96
+ managed_files.add(d.to_s)
97
+ end
73
98
  end
74
-
75
- # Clean all the paths... this is required because of the join
76
- files.map {|f| Chef::Util::PathHelper.cleanpath(f)}
77
99
  end
78
100
 
79
- def purge_unmanaged_files(unmanaged_files)
80
- if @new_resource.purge
81
- unmanaged_files.sort.reverse.each do |f|
82
- # file_class comes from Chef::Mixin::FileClass
83
- if ::File.directory?(f) && !Chef::Platform.windows? && !file_class.symlink?(f.dup)
84
- # Linux treats directory symlinks as files
85
- # Remove a directory as a directory when not on windows if it is not a symlink
86
- purge_directory(f)
87
- elsif ::File.directory?(f) && Chef::Platform.windows?
88
- # Windows treats directory symlinks as directories so we delete them here
89
- purge_directory(f)
90
- else
91
- converge_by("delete unmanaged file #{f}") do
92
- ::File.delete(f)
93
- Chef::Log.debug("#{@new_resource} deleted file #{f}")
101
+ # Remove all files not in the managed_files Set.
102
+ #
103
+ # @api private
104
+ #
105
+ def purge_unmanaged_files
106
+ if purge
107
+ Dir.glob(::File.join(Chef::Util::PathHelper.escape_glob(path), '**', '*'), ::File::FNM_DOTMATCH).sort!.reverse!.each do |file|
108
+ # skip '.' and '..'
109
+ next if ['.','..'].include?(Pathname.new(file).basename().to_s)
110
+
111
+ # Clean the path. This is required because of the ::File.join
112
+ file = Chef::Util::PathHelper.cleanpath(file)
113
+
114
+ # Skip files that we've sync'd and their parent dirs
115
+ next if managed_files.include?(file)
116
+
117
+ if ::File.directory?(file)
118
+ if !Chef::Platform.windows? && file_class.symlink?(file.dup)
119
+ # Unix treats dir symlinks as files
120
+ purge_file(file)
121
+ else
122
+ # Unix dirs are dirs, Windows dirs and dir symlinks are dirs
123
+ purge_directory(file)
94
124
  end
125
+ else
126
+ purge_file(file)
95
127
  end
96
128
  end
97
129
  end
98
130
  end
99
131
 
132
+ # Use a Chef directory sub-resource to remove a directory.
133
+ #
134
+ # @param [String] dir The path of the directory to remove
135
+ # @api private
136
+ #
100
137
  def purge_directory(dir)
101
- converge_by("delete unmanaged directory #{dir}") do
102
- Dir::rmdir(dir)
103
- Chef::Log.debug("#{@new_resource} removed directory #{dir}")
104
- end
138
+ res = Chef::Resource::Directory.new(dir, run_context)
139
+ res.run_action(:delete)
140
+ new_resource.updated_by_last_action(true) if res.updated?
105
141
  end
106
142
 
143
+ # Use a Chef file sub-resource to remove a file.
144
+ #
145
+ # @param [String] file The path of the file to remove
146
+ # @api private
147
+ #
148
+ def purge_file(file)
149
+ res = Chef::Resource::File.new(file, run_context)
150
+ res.run_action(:delete)
151
+ new_resource.updated_by_last_action(true) if res.updated?
152
+ end
153
+
154
+ # Get the files to tranfer. This returns files in lexicographical sort order.
155
+ #
156
+ # FIXME: it should do breadth-first, see CHEF-5080 (please use a performant sort)
157
+ #
158
+ # @return Array<String> The list of files to transfer
159
+ # @api private
160
+ #
107
161
  def files_to_transfer
108
162
  cookbook = run_context.cookbook_collection[resource_cookbook]
109
- files = cookbook.relative_filenames_in_preferred_directory(node, :files, @new_resource.source)
110
- files.sort.reverse
163
+ files = cookbook.relative_filenames_in_preferred_directory(node, :files, source)
164
+ files.sort_by! { |x| x.count(::File::SEPARATOR) }
111
165
  end
112
166
 
113
- def directory_root_in_cookbook_cache
114
- @directory_root_in_cookbook_cache ||= begin
115
- cookbook = run_context.cookbook_collection[resource_cookbook]
116
- cookbook.preferred_filename_on_disk_location(node, :files, @new_resource.source, @new_resource.path)
117
- end
167
+ # Either the explicit cookbook that the user sets on the resource, or the implicit
168
+ # cookbook_name that the resource was declared in.
169
+ #
170
+ # @return [String] Cookbook to get file from.
171
+ # @api private
172
+ #
173
+ def resource_cookbook
174
+ cookbook || cookbook_name
118
175
  end
119
176
 
120
- # Determine the cookbook to get the file from. If new resource sets an
121
- # explicit cookbook, use it, otherwise fall back to the implicit cookbook
122
- # i.e., the cookbook the resource was declared in.
123
- def resource_cookbook
124
- @new_resource.cookbook || @new_resource.cookbook_name
177
+ # If we are overwriting, then cookbook_file sub-resources should all be action :create,
178
+ # otherwise they should be :create_if_missing
179
+ #
180
+ # @return [Symbol] Action to take on cookbook_file sub-resources
181
+ # @api private
182
+ #
183
+ def action_for_cookbook_file
184
+ overwrite? ? :create : :create_if_missing
125
185
  end
126
186
 
187
+ # This creates and uses a cookbook_file resource to sync a single file from the cookbook.
188
+ #
189
+ # @param [String] cookbook_file_relative_path The relative path to the cookbook file
190
+ # @api private
191
+ #
127
192
  def create_cookbook_file(cookbook_file_relative_path)
128
- full_path = ::File.join(@new_resource.path, cookbook_file_relative_path)
193
+ full_path = ::File.join(path, cookbook_file_relative_path)
129
194
 
130
195
  ensure_directory_exists(::File.dirname(full_path))
131
196
 
132
- file_to_fetch = cookbook_file_resource(full_path, cookbook_file_relative_path)
133
- if @new_resource.overwrite
134
- file_to_fetch.run_action(:create)
135
- else
136
- file_to_fetch.run_action(:create_if_missing)
137
- end
138
- @new_resource.updated_by_last_action(true) if file_to_fetch.updated?
197
+ res = cookbook_file_resource(full_path, cookbook_file_relative_path)
198
+ res.run_action(action_for_cookbook_file)
199
+ new_resource.updated_by_last_action(true) if res.updated?
139
200
  end
140
201
 
202
+ # This creates the cookbook_file resource for use by create_cookbook_file.
203
+ #
204
+ # @param [String] target_path Path on the system to create
205
+ # @param [String] relative_source_path Relative path in the cookbook to the base source
206
+ # @return [Chef::Resource::CookbookFile] The built cookbook_file resource
207
+ # @api private
208
+ #
141
209
  def cookbook_file_resource(target_path, relative_source_path)
142
- cookbook_file = Chef::Resource::CookbookFile.new(target_path, run_context)
143
- cookbook_file.cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name
144
- cookbook_file.source(::File.join(@new_resource.source, relative_source_path))
145
- if Chef::Platform.windows? && @new_resource.files_rights
146
- @new_resource.files_rights.each_pair do |permission, *args|
147
- cookbook_file.rights(permission, *args)
210
+ res = Chef::Resource::CookbookFile.new(target_path, run_context)
211
+ res.cookbook_name = resource_cookbook
212
+ res.source(::File.join(source, relative_source_path))
213
+ if Chef::Platform.windows? && files_rights
214
+ files_rights.each_pair do |permission, *args|
215
+ res.rights(permission, *args)
148
216
  end
149
217
  end
150
- cookbook_file.mode(@new_resource.files_mode) if @new_resource.files_mode
151
- cookbook_file.group(@new_resource.files_group) if @new_resource.files_group
152
- cookbook_file.owner(@new_resource.files_owner) if @new_resource.files_owner
153
- cookbook_file.backup(@new_resource.files_backup) if @new_resource.files_backup
218
+ res.mode(files_mode) if files_mode
219
+ res.group(files_group) if files_group
220
+ res.owner(files_owner) if files_owner
221
+ res.backup(files_backup) if files_backup
154
222
 
155
- cookbook_file
223
+ res
156
224
  end
157
225
 
158
- def ensure_directory_exists(path)
159
- unless ::File.directory?(path)
160
- directory_to_create = resource_for_directory(path)
161
- directory_to_create.run_action(:create)
162
- @new_resource.updated_by_last_action(true) if directory_to_create.updated?
226
+ # This creates and uses a directory resource to create a directory if it is needed.
227
+ #
228
+ # @param [String] dir The path to the directory to create.
229
+ # @api private
230
+ #
231
+ def ensure_directory_exists(dir)
232
+ # doing the check here and skipping the resource should be more performant
233
+ unless ::File.directory?(dir)
234
+ res = directory_resource(dir)
235
+ res.run_action(:create)
236
+ new_resource.updated_by_last_action(true) if res.updated?
163
237
  end
164
238
  end
165
239
 
166
- def resource_for_directory(path)
167
- dir = Chef::Resource::Directory.new(path, run_context)
168
- dir.cookbook_name = @new_resource.cookbook || @new_resource.cookbook_name
169
- if Chef::Platform.windows? && @new_resource.rights
240
+ # This creates the directory resource for ensure_directory_exists.
241
+ #
242
+ # @param [String] dir Directory path on the system
243
+ # @return [Chef::Resource::Directory] The built directory resource
244
+ # @api private
245
+ #
246
+ def directory_resource(dir)
247
+ res = Chef::Resource::Directory.new(dir, run_context)
248
+ res.cookbook_name = resource_cookbook
249
+ if Chef::Platform.windows? && rights
170
250
  # rights are only meant to be applied to the toppest-level directory;
171
251
  # Windows will handle inheritance.
172
- if path == @new_resource.path
173
- @new_resource.rights.each do |rights| #rights is a hash
174
- permissions = rights.delete(:permissions) #delete will return the value or nil if not found
175
- principals = rights.delete(:principals)
176
- dir.rights(permissions, principals, rights)
252
+ if dir == path
253
+ rights.each do |r|
254
+ r = r.dup # do not update the new_resource
255
+ permissions = r.delete(:permissions)
256
+ principals = r.delete(:principals)
257
+ res.rights(permissions, principals, r)
177
258
  end
178
259
  end
179
260
  end
180
- dir.mode(@new_resource.mode) if @new_resource.mode
181
- dir.group(@new_resource.group)
182
- dir.owner(@new_resource.owner)
183
- dir.recursive(true)
184
- dir
185
- end
261
+ res.mode(mode) if mode
262
+ res.group(group) if group
263
+ res.owner(owner) if owner
264
+ res.recursive(true)
186
265
 
187
- def whyrun_supported?
188
- true
266
+ res
189
267
  end
190
268
 
269
+ #
270
+ # Add back deprecated methods and aliases that are internally unused and should be removed in Chef-13
271
+ #
272
+ extend Chef::Deprecation::Warnings
273
+ include Chef::Deprecation::Provider::RemoteDirectory
274
+ add_deprecation_warnings_for(Chef::Deprecation::Provider::RemoteDirectory.instance_methods)
275
+
276
+ alias_method :resource_for_directory, :directory_resource
277
+ add_deprecation_warnings_for([:resource_for_directory])
278
+
191
279
  end
192
280
  end
193
281
  end