chef 12.5.1-universal-mingw32 → 12.6.0-universal-mingw32

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 (221) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -1
  3. data/README.md +6 -4
  4. data/Rakefile +1 -4
  5. data/chef-windows.gemspec +21 -0
  6. data/chef.gemspec +58 -0
  7. data/lib/chef/api_client/registration.rb +9 -4
  8. data/lib/chef/application.rb +3 -84
  9. data/lib/chef/application/apply.rb +9 -2
  10. data/lib/chef/application/client.rb +8 -3
  11. data/lib/chef/application/solo.rb +7 -1
  12. data/lib/chef/application/windows_service.rb +21 -6
  13. data/lib/chef/application/windows_service_manager.rb +2 -3
  14. data/lib/chef/audit/runner.rb +1 -0
  15. data/lib/chef/chef_class.rb +1 -11
  16. data/lib/chef/chef_fs/chef_fs_data_store.rb +181 -2
  17. data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +5 -0
  18. data/lib/chef/chef_fs/file_system/file_system_entry.rb +11 -7
  19. data/lib/chef/client.rb +28 -1
  20. data/lib/chef/cookbook/cookbook_collection.rb +14 -1
  21. data/lib/chef/cookbook/cookbook_version_loader.rb +1 -1
  22. data/lib/chef/cookbook/metadata.rb +115 -9
  23. data/lib/chef/cookbook/remote_file_vendor.rb +1 -1
  24. data/lib/chef/cookbook_version.rb +6 -2
  25. data/lib/chef/data_bag.rb +1 -1
  26. data/lib/chef/data_bag_item.rb +1 -1
  27. data/lib/chef/digester.rb +5 -1
  28. data/lib/chef/dsl/chef_provisioning.rb +57 -0
  29. data/lib/chef/dsl/cheffish.rb +64 -0
  30. data/lib/chef/dsl/declare_resource.rb +108 -0
  31. data/lib/chef/dsl/platform_introspection.rb +3 -3
  32. data/lib/chef/dsl/recipe.rb +3 -73
  33. data/lib/chef/dsl/resources.rb +27 -1
  34. data/lib/chef/event_dispatch/base.rb +3 -0
  35. data/lib/chef/event_dispatch/dispatcher.rb +5 -0
  36. data/lib/chef/event_dispatch/events_output_stream.rb +8 -0
  37. data/lib/chef/exceptions.rb +21 -1
  38. data/lib/chef/file_access_control/unix.rb +12 -12
  39. data/lib/chef/file_content_management/deploy/cp.rb +2 -2
  40. data/lib/chef/file_content_management/deploy/mv_unix.rb +4 -4
  41. data/lib/chef/file_content_management/deploy/mv_windows.rb +1 -1
  42. data/lib/chef/formatters/base.rb +7 -0
  43. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +2 -2
  44. data/lib/chef/formatters/indentable_output_stream.rb +5 -0
  45. data/lib/chef/http.rb +19 -3
  46. data/lib/chef/http/decompressor.rb +2 -2
  47. data/lib/chef/json_compat.rb +1 -0
  48. data/lib/chef/knife.rb +16 -2
  49. data/lib/chef/knife/bootstrap.rb +55 -10
  50. data/lib/chef/knife/cookbook_site_install.rb +5 -1
  51. data/lib/chef/knife/core/bootstrap_context.rb +2 -1
  52. data/lib/chef/knife/core/node_presenter.rb +1 -1
  53. data/lib/chef/knife/ssh.rb +30 -16
  54. data/lib/chef/knife/ssl_check.rb +4 -2
  55. data/lib/chef/knife/ssl_fetch.rb +3 -2
  56. data/lib/chef/knife/status.rb +14 -1
  57. data/lib/chef/log.rb +14 -0
  58. data/lib/chef/mixin/get_source_from_package.rb +7 -2
  59. data/lib/chef/mixin/properties.rb +302 -0
  60. data/lib/chef/mixin/proxified_socket.rb +38 -0
  61. data/lib/chef/mixin/subclass_directive.rb +37 -0
  62. data/lib/chef/node.rb +13 -5
  63. data/lib/chef/platform/query_helpers.rb +14 -3
  64. data/lib/chef/platform/service_helpers.rb +20 -38
  65. data/lib/chef/policy_builder/expand_node_object.rb +3 -0
  66. data/lib/chef/policy_builder/policyfile.rb +1 -0
  67. data/lib/chef/property.rb +51 -12
  68. data/lib/chef/provider.rb +40 -35
  69. data/lib/chef/provider/deploy.rb +1 -1
  70. data/lib/chef/provider/dsc_resource.rb +54 -20
  71. data/lib/chef/provider/execute.rb +25 -4
  72. data/lib/chef/provider/group.rb +1 -1
  73. data/lib/chef/provider/lwrp_base.rb +1 -0
  74. data/lib/chef/provider/package.rb +76 -30
  75. data/lib/chef/provider/package/dpkg.rb +152 -69
  76. data/lib/chef/provider/package/openbsd.rb +6 -8
  77. data/lib/chef/provider/package/solaris.rb +2 -0
  78. data/lib/chef/provider/package/windows.rb +95 -14
  79. data/lib/chef/provider/package/windows/exe.rb +129 -0
  80. data/lib/chef/provider/package/windows/msi.rb +37 -13
  81. data/lib/chef/provider/package/windows/registry_uninstall_entry.rb +89 -0
  82. data/lib/chef/provider/package/yum.rb +13 -3
  83. data/lib/chef/provider/powershell_script.rb +3 -0
  84. data/lib/chef/provider/remote_file/cache_control_data.rb +37 -4
  85. data/lib/chef/provider/remote_file/http.rb +1 -1
  86. data/lib/chef/provider/script.rb +1 -0
  87. data/lib/chef/provider/service.rb +13 -10
  88. data/lib/chef/provider/service/solaris.rb +43 -17
  89. data/lib/chef/provider/service/upstart.rb +3 -3
  90. data/lib/chef/provider/user.rb +1 -1
  91. data/lib/chef/provider/user/dscl.rb +111 -100
  92. data/lib/chef/provider/user/windows.rb +5 -3
  93. data/lib/chef/recipe.rb +3 -5
  94. data/lib/chef/resource.rb +77 -320
  95. data/lib/chef/resource/action_class.rb +4 -0
  96. data/lib/chef/resource/dpkg_package.rb +4 -3
  97. data/lib/chef/resource/dsc_resource.rb +40 -2
  98. data/lib/chef/resource/execute.rb +9 -1
  99. data/lib/chef/resource/ksh.rb +32 -0
  100. data/lib/chef/resource/lwrp_base.rb +6 -10
  101. data/lib/chef/resource/package.rb +8 -9
  102. data/lib/chef/resource/registry_key.rb +1 -1
  103. data/lib/chef/resource/resource_notification.rb +14 -1
  104. data/lib/chef/resource/script.rb +1 -1
  105. data/lib/chef/resource/windows_package.rb +1 -1
  106. data/lib/chef/resource_builder.rb +14 -7
  107. data/lib/chef/resource_reporter.rb +6 -0
  108. data/lib/chef/resources.rb +1 -7
  109. data/lib/chef/rest.rb +1 -1
  110. data/lib/chef/run_context.rb +45 -2
  111. data/lib/chef/run_list/run_list_expansion.rb +47 -0
  112. data/lib/chef/runner.rb +25 -0
  113. data/lib/chef/search/query.rb +16 -2
  114. data/lib/chef/util/diff.rb +2 -2
  115. data/lib/chef/util/powershell/ps_credential.rb +2 -3
  116. data/lib/chef/version.rb +1 -1
  117. data/lib/chef/win32/api/file.rb +51 -1
  118. data/lib/chef/win32/file.rb +5 -0
  119. data/lib/chef/win32/file/version_info.rb +93 -0
  120. data/lib/chef/win32/mutex.rb +1 -1
  121. data/spec/data/apt/chef-integration-test2-1.0/debian/changelog +5 -0
  122. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.debhelper.log +45 -0
  123. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.substvars +1 -0
  124. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/conffiles +1 -0
  125. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/control +10 -0
  126. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/md5sums +1 -0
  127. data/spec/data/apt/chef-integration-test2-1.0/debian/compat +1 -0
  128. data/spec/data/apt/chef-integration-test2-1.0/debian/conffiles +1 -0
  129. data/spec/data/apt/chef-integration-test2-1.0/debian/control +13 -0
  130. data/spec/data/apt/chef-integration-test2-1.0/debian/copyright +34 -0
  131. data/spec/data/apt/chef-integration-test2-1.0/debian/files +1 -0
  132. data/spec/data/apt/chef-integration-test2-1.0/debian/rules +13 -0
  133. data/spec/data/apt/chef-integration-test2-1.0/debian/source/format +1 -0
  134. data/spec/data/apt/chef-integration-test2_1.0-1.debian.tar.gz +0 -0
  135. data/spec/data/apt/chef-integration-test2_1.0-1.dsc +18 -0
  136. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.build +91 -0
  137. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.changes +31 -0
  138. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.deb +0 -0
  139. data/spec/data/apt/chef-integration-test2_1.0.orig.tar.gz +0 -0
  140. data/spec/functional/application_spec.rb +1 -1
  141. data/spec/functional/audit/runner_spec.rb +4 -0
  142. data/spec/functional/knife/ssh_spec.rb +5 -5
  143. data/spec/functional/notifications_spec.rb +74 -4
  144. data/spec/functional/resource/aix_service_spec.rb +2 -2
  145. data/spec/functional/resource/dpkg_package_spec.rb +339 -0
  146. data/spec/functional/resource/ifconfig_spec.rb +3 -1
  147. data/spec/functional/resource/mount_spec.rb +5 -2
  148. data/spec/functional/resource/package_spec.rb +1 -1
  149. data/spec/functional/resource/user/windows_spec.rb +8 -0
  150. data/spec/functional/resource/windows_package_spec.rb +177 -0
  151. data/spec/functional/win32/version_info_spec.rb +50 -0
  152. data/spec/integration/client/client_spec.rb +80 -0
  153. data/spec/integration/knife/download_spec.rb +9 -0
  154. data/spec/integration/knife/upload_spec.rb +28 -1
  155. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +93 -23
  156. data/spec/integration/recipes/resource_action_spec.rb +211 -116
  157. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +72 -0
  158. data/spec/integration/solo/solo_spec.rb +34 -0
  159. data/spec/spec_helper.rb +11 -1
  160. data/spec/support/platform_helpers.rb +8 -0
  161. data/spec/support/shared/integration/integration_helper.rb +6 -0
  162. data/spec/support/shared/unit/execute_resource.rb +5 -0
  163. data/spec/support/shared/unit/platform_introspector.rb +7 -0
  164. data/spec/tiny_server.rb +6 -2
  165. data/spec/unit/api_client/registration_spec.rb +5 -4
  166. data/spec/unit/application_spec.rb +1 -181
  167. data/spec/unit/chef_fs/file_system/cookbook_subdir_spec.rb +34 -0
  168. data/spec/unit/cookbook/metadata_spec.rb +122 -2
  169. data/spec/unit/http_spec.rb +102 -0
  170. data/spec/unit/knife/bootstrap_spec.rb +55 -13
  171. data/spec/unit/knife/core/bootstrap_context_spec.rb +10 -3
  172. data/spec/unit/knife/ssl_check_spec.rb +7 -3
  173. data/spec/unit/knife/ssl_fetch_spec.rb +2 -2
  174. data/spec/unit/knife/status_spec.rb +13 -13
  175. data/spec/unit/knife_spec.rb +26 -2
  176. data/spec/unit/lwrp_spec.rb +1 -1
  177. data/spec/unit/mixin/properties_spec.rb +97 -0
  178. data/spec/unit/mixin/proxified_socket_spec.rb +94 -0
  179. data/spec/unit/mixin/subclass_directive_spec.rb +45 -0
  180. data/spec/unit/node_spec.rb +9 -1
  181. data/spec/unit/policy_builder/policyfile_spec.rb +2 -0
  182. data/spec/unit/property/validation_spec.rb +14 -12
  183. data/spec/unit/property_spec.rb +56 -0
  184. data/spec/unit/provider/deploy_spec.rb +1 -1
  185. data/spec/unit/provider/dsc_resource_spec.rb +63 -24
  186. data/spec/unit/provider/execute_spec.rb +95 -28
  187. data/spec/unit/provider/package/dpkg_spec.rb +185 -96
  188. data/spec/unit/provider/package/windows/exe_spec.rb +251 -0
  189. data/spec/unit/provider/package/windows/msi_spec.rb +94 -10
  190. data/spec/unit/provider/package/windows_spec.rb +227 -26
  191. data/spec/unit/provider/package/yum_spec.rb +6 -0
  192. data/spec/unit/provider/package_spec.rb +495 -366
  193. data/spec/unit/provider/remote_file/cache_control_data_spec.rb +62 -36
  194. data/spec/unit/provider/script_spec.rb +2 -2
  195. data/spec/unit/provider/service/solaris_smf_service_spec.rb +110 -39
  196. data/spec/unit/provider/service/upstart_service_spec.rb +19 -0
  197. data/spec/unit/provider/user/dscl_spec.rb +14 -0
  198. data/spec/unit/provider/user/windows_spec.rb +2 -2
  199. data/spec/unit/provider/user_spec.rb +9 -0
  200. data/spec/unit/provider_resolver_spec.rb +6 -30
  201. data/spec/unit/recipe_spec.rb +46 -20
  202. data/spec/unit/resource/chef_gem_spec.rb +1 -1
  203. data/spec/unit/resource/dsc_resource_spec.rb +14 -3
  204. data/spec/unit/resource/ksh_spec.rb +40 -0
  205. data/spec/unit/resource/registry_key_spec.rb +2 -2
  206. data/spec/unit/resource/resource_notification_spec.rb +44 -45
  207. data/spec/unit/resource_reporter_spec.rb +7 -0
  208. data/spec/unit/resource_spec.rb +268 -253
  209. data/spec/unit/rest_spec.rb +2 -2
  210. data/spec/unit/run_list/run_list_expansion_spec.rb +18 -3
  211. data/spec/unit/search/query_spec.rb +19 -1
  212. data/spec/unit/util/powershell/ps_credential_spec.rb +8 -1
  213. data/spec/unit/windows_service_spec.rb +83 -38
  214. data/tasks/external_tests.rb +19 -9
  215. data/tasks/rspec.rb +1 -1
  216. metadata +70 -21
  217. data/spec/support/pedant/Gemfile +0 -3
  218. data/spec/support/pedant/pedant_config.rb +0 -129
  219. data/spec/support/pedant/run_pedant.rb +0 -63
  220. data/spec/support/pedant/stickywicket.pem +0 -27
  221. data/spec/unit/provider/package_spec.rbe +0 -0
@@ -0,0 +1,129 @@
1
+ #
2
+ # Author:: Seth Chisamore (<schisamo@chef.io>)
3
+ # Author:: Matt Wrock <matt@mattwrock.com>
4
+ # Copyright:: Copyright (c) 2011, 2015 Chef Software, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'chef/mixin/shell_out'
21
+
22
+ class Chef
23
+ class Provider
24
+ class Package
25
+ class Windows
26
+ class Exe
27
+ include Chef::Mixin::ShellOut
28
+
29
+ def initialize(resource, installer_type, uninstall_entries)
30
+ @new_resource = resource
31
+ @installer_type = installer_type
32
+ @uninstall_entries = uninstall_entries
33
+ end
34
+
35
+ attr_reader :new_resource
36
+ attr_reader :installer_type
37
+ attr_reader :uninstall_entries
38
+
39
+ # From Chef::Provider::Package
40
+ def expand_options(options)
41
+ options ? " #{options}" : ""
42
+ end
43
+
44
+ # Returns a version if the package is installed or nil if it is not.
45
+ def installed_version
46
+ Chef::Log.debug("#{new_resource} checking package version")
47
+ current_installed_version
48
+ end
49
+
50
+ def package_version
51
+ new_resource.version || install_file_version
52
+ end
53
+
54
+ def install_package
55
+ Chef::Log.debug("#{new_resource} installing #{new_resource.installer_type} package '#{new_resource.source}'")
56
+ shell_out!(
57
+ [
58
+ "start",
59
+ "\"\"",
60
+ "/wait",
61
+ "\"#{new_resource.source}\"",
62
+ unattended_flags,
63
+ expand_options(new_resource.options),
64
+ "& exit %%%%ERRORLEVEL%%%%"
65
+ ].join(" "), timeout: new_resource.timeout, returns: new_resource.returns
66
+ )
67
+ end
68
+
69
+ def remove_package
70
+ uninstall_version = new_resource.version || current_installed_version
71
+ uninstall_entries.select { |entry| [uninstall_version].flatten.include?(entry.display_version) }
72
+ .map { |version| version.uninstall_string }.uniq.each do |uninstall_string|
73
+ Chef::Log.debug("Registry provided uninstall string for #{new_resource} is '#{uninstall_string}'")
74
+ shell_out!(uninstall_command(uninstall_string), { returns: new_resource.returns })
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def uninstall_command(uninstall_string)
81
+ uninstall_string.delete!('"')
82
+ uninstall_string = [
83
+ %q{/d"},
84
+ ::File.dirname(uninstall_string),
85
+ %q{" },
86
+ ::File.basename(uninstall_string),
87
+ expand_options(new_resource.options),
88
+ " ",
89
+ unattended_flags
90
+ ].join
91
+ %Q{start "" /wait #{uninstall_string} & exit %%%%ERRORLEVEL%%%%}
92
+ end
93
+
94
+ def current_installed_version
95
+ @current_installed_version ||= uninstall_entries.count == 0 ? nil : begin
96
+ uninstall_entries.map { |entry| entry.display_version }.uniq
97
+ end
98
+ end
99
+
100
+ def install_file_version
101
+ @install_file_version ||= begin
102
+ if ::File.exist?(@new_resource.source)
103
+ version_info = Chef::ReservedNames::Win32::File.version_info(new_resource.source)
104
+ file_version = version_info.FileVersion || version_info.ProductVersion
105
+ file_version == '' ? nil : file_version
106
+ else
107
+ nil
108
+ end
109
+ end
110
+ end
111
+
112
+ # http://unattended.sourceforge.net/installers.php
113
+ def unattended_flags
114
+ case installer_type
115
+ when :installshield
116
+ '/s /sms'
117
+ when :nsis
118
+ '/S /NCRC'
119
+ when :inno
120
+ '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART'
121
+ when :wise
122
+ '/s'
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -29,10 +29,14 @@ class Chef
29
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
- def initialize(resource)
32
+ def initialize(resource, uninstall_entries)
33
33
  @new_resource = resource
34
+ @uninstall_entries = uninstall_entries
34
35
  end
35
36
 
37
+ attr_reader :new_resource
38
+ attr_reader :uninstall_entries
39
+
36
40
  # From Chef::Provider::Package
37
41
  def expand_options(options)
38
42
  options ? " #{options}" : ""
@@ -40,27 +44,47 @@ class Chef
40
44
 
41
45
  # Returns a version if the package is installed or nil if it is not.
42
46
  def installed_version
43
- Chef::Log.debug("#{@new_resource} getting product code for package at #{@new_resource.source}")
44
- product_code = get_product_property(@new_resource.source, "ProductCode")
45
- Chef::Log.debug("#{@new_resource} checking package status and version for #{product_code}")
46
- get_installed_version(product_code)
47
+ if ::File.exist?(new_resource.source)
48
+ Chef::Log.debug("#{new_resource} getting product code for package at #{new_resource.source}")
49
+ product_code = get_product_property(new_resource.source, "ProductCode")
50
+ Chef::Log.debug("#{new_resource} checking package status and version for #{product_code}")
51
+ get_installed_version(product_code)
52
+ else
53
+ uninstall_entries.count == 0 ? nil : begin
54
+ uninstall_entries.map { |entry| entry.display_version }.uniq
55
+ end
56
+ end
47
57
  end
48
58
 
49
59
  def package_version
50
- Chef::Log.debug("#{@new_resource} getting product version for package at #{@new_resource.source}")
51
- get_product_property(@new_resource.source, "ProductVersion")
60
+ return new_resource.version if new_resource.version
61
+ if ::File.exist?(new_resource.source)
62
+ Chef::Log.debug("#{new_resource} getting product version for package at #{new_resource.source}")
63
+ get_product_property(new_resource.source, "ProductVersion")
64
+ end
52
65
  end
53
66
 
54
- def install_package(name, version)
67
+ def install_package
55
68
  # We could use MsiConfigureProduct here, but we'll start off with msiexec
56
- Chef::Log.debug("#{@new_resource} installing MSI package '#{@new_resource.source}'")
57
- shell_out!("msiexec /qn /i \"#{@new_resource.source}\" #{expand_options(@new_resource.options)}", {:timeout => @new_resource.timeout, :returns => @new_resource.returns})
69
+ Chef::Log.debug("#{new_resource} installing MSI package '#{new_resource.source}'")
70
+ shell_out!("msiexec /qn /i \"#{new_resource.source}\" #{expand_options(new_resource.options)}", {:timeout => new_resource.timeout, :returns => new_resource.returns})
58
71
  end
59
72
 
60
- def remove_package(name, version)
73
+ def remove_package
61
74
  # We could use MsiConfigureProduct here, but we'll start off with msiexec
62
- Chef::Log.debug("#{@new_resource} removing MSI package '#{@new_resource.source}'")
63
- shell_out!("msiexec /qn /x \"#{@new_resource.source}\" #{expand_options(@new_resource.options)}", {:timeout => @new_resource.timeout, :returns => @new_resource.returns})
75
+ if ::File.exist?(new_resource.source)
76
+ Chef::Log.debug("#{new_resource} removing MSI package '#{new_resource.source}'")
77
+ shell_out!("msiexec /qn /x \"#{new_resource.source}\" #{expand_options(new_resource.options)}", {:timeout => new_resource.timeout, :returns => new_resource.returns})
78
+ else
79
+ uninstall_version = new_resource.version || installed_version
80
+ uninstall_entries.select { |entry| [uninstall_version].flatten.include?(entry.display_version) }
81
+ .map { |version| version.uninstall_string }.uniq.each do |uninstall_string|
82
+ Chef::Log.debug("#{new_resource} removing MSI package version using '#{uninstall_string}'")
83
+ uninstall_string += expand_options(new_resource.options)
84
+ uninstall_string += " /Q" unless uninstall_string =~ / \/Q\b/
85
+ shell_out!(uninstall_string, {:timeout => new_resource.timeout, :returns => new_resource.returns})
86
+ end
87
+ end
64
88
  end
65
89
  end
66
90
  end
@@ -0,0 +1,89 @@
1
+ #
2
+ # Author:: Seth Chisamore (<schisamo@chef.io>)
3
+ # Author:: Matt Wrock <matt@mattwrock.com>
4
+ # Copyright:: Copyright (c) 2011, 2015 Chef Software, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'win32/registry' if (RUBY_PLATFORM =~ /mswin|mingw32|windows/)
21
+
22
+ class Chef
23
+ class Provider
24
+ class Package
25
+ class Windows
26
+ class RegistryUninstallEntry
27
+
28
+ def self.find_entries(package_name)
29
+ Chef::Log.debug("Finding uninstall entries for #{package_name}")
30
+ entries = []
31
+ [
32
+ [::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0100)],
33
+ [::Win32::Registry::HKEY_LOCAL_MACHINE, (::Win32::Registry::Constants::KEY_READ | 0x0200)],
34
+ [::Win32::Registry::HKEY_CURRENT_USER]
35
+ ].each do |hkey|
36
+ desired = hkey.length > 1 ? hkey[1] : ::Win32::Registry::Constants::KEY_READ
37
+ begin
38
+ ::Win32::Registry.open(hkey[0], UNINSTALL_SUBKEY, desired) do |reg|
39
+ reg.each_key do |key, _wtime|
40
+ begin
41
+ entry = reg.open(key, desired)
42
+ display_name = read_registry_property(entry, 'DisplayName')
43
+ if display_name == package_name
44
+ entries.push(RegistryUninstallEntry.new(hkey, key, entry))
45
+ end
46
+ rescue ::Win32::Registry::Error => ex
47
+ Chef::Log.debug("Registry error opening key '#{key}' on node #{desired}: #{ex}")
48
+ end
49
+ end
50
+ end
51
+ rescue ::Win32::Registry::Error => ex
52
+ Chef::Log.debug("Registry error opening hive '#{hkey[0]}' :: #{desired}: #{ex}")
53
+ end
54
+ end
55
+ entries
56
+ end
57
+
58
+ def self.read_registry_property(data, property)
59
+ data[property]
60
+ rescue ::Win32::Registry::Error => ex
61
+ Chef::Log.debug("Failure to read property '#{property}'")
62
+ nil
63
+ end
64
+
65
+ def initialize(hive, key, registry_data)
66
+ Chef::Log.debug("Creating uninstall entry for #{hive}::#{key}")
67
+ @hive = hive
68
+ @key = key
69
+ @data = registry_data
70
+ @display_name = RegistryUninstallEntry.read_registry_property(registry_data, 'DisplayName')
71
+ @display_version = RegistryUninstallEntry.read_registry_property(registry_data, 'DisplayVersion')
72
+ @uninstall_string = RegistryUninstallEntry.read_registry_property(registry_data, 'UninstallString')
73
+ end
74
+
75
+ attr_reader :hive
76
+ attr_reader :key
77
+ attr_reader :display_name
78
+ attr_reader :display_version
79
+ attr_reader :uninstall_string
80
+ attr_reader :data
81
+
82
+ private
83
+
84
+ UNINSTALL_SUBKEY = 'Software\Microsoft\Windows\CurrentVersion\Uninstall'.freeze
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -785,19 +785,29 @@ class Chef
785
785
  def python_bin
786
786
  yum_executable = which(yum_binary)
787
787
  if yum_executable && shabang?(yum_executable)
788
- extract_interpreter(yum_executable)
788
+ shabang_or_fallback(extract_interpreter(yum_executable))
789
789
  else
790
790
  Chef::Log.warn("Yum executable not found or doesn't start with #!. Using default python.")
791
791
  "/usr/bin/python"
792
792
  end
793
793
  rescue StandardError => e
794
- Chef::Log.warn("An error occured attempting to determine correct python executable. Using default.")
794
+ Chef::Log.warn("An error occurred attempting to determine correct python executable. Using default.")
795
795
  Chef::Log.debug(e)
796
796
  "/usr/bin/python"
797
797
  end
798
798
 
799
799
  def extract_interpreter(file)
800
- ::File.open(file, 'r', &:readline)[2..-1].chomp
800
+ ::File.open(file, 'r', &:readline)[2..-1].strip
801
+ end
802
+
803
+ # dnf based systems have a yum shim that has /bin/bash as the interpreter. Don't use this.
804
+ def shabang_or_fallback(interpreter)
805
+ if interpreter == '/bin/bash'
806
+ Chef::Log.warn("Yum executable interpreter is /bin/bash. Falling back to default python.")
807
+ "/usr/bin/python"
808
+ else
809
+ interpreter
810
+ end
801
811
  end
802
812
 
803
813
  def shabang?(file)
@@ -199,6 +199,9 @@ elseif ( $LASTEXITCODE -ne $null -and $LASTEXITCODE -ne 0 )
199
199
  $exitstatus = $LASTEXITCODE
200
200
  }
201
201
 
202
+ # Print STDOUT for the script execution
203
+ Write-Output $chefscriptresult
204
+
202
205
  # If this script is launched with -File, the process exit
203
206
  # status of PowerShell.exe will be $exitstatus. If it was
204
207
  # launched with -Command, it will be 0 if $exitstatus was 0,
@@ -145,18 +145,51 @@ class Chef
145
145
  end
146
146
 
147
147
  def load_json_data
148
- Chef::FileCache.load("remote_file/#{sanitized_cache_file_basename}")
148
+ path = sanitized_cache_file_path(sanitized_cache_file_basename)
149
+ if Chef::FileCache.has_key?(path)
150
+ Chef::FileCache.load(path)
151
+ else
152
+ old_path = sanitized_cache_file_path(sanitized_cache_file_basename_md5)
153
+ if Chef::FileCache.has_key?(old_path)
154
+ # We found an old cache control data file. We started using sha256 instead of md5
155
+ # to name these. Upgrade the file to the new name.
156
+ Chef::Log.debug("Found old cache control data file at #{old_path}. Moving to #{path}.")
157
+ Chef::FileCache.load(old_path).tap do |data|
158
+ Chef::FileCache.store(path, data)
159
+ Chef::FileCache.delete(old_path)
160
+ end
161
+ else
162
+ raise Chef::Exceptions::FileNotFound
163
+ end
164
+ end
149
165
  end
150
166
 
151
- def sanitized_cache_file_basename
167
+ def sanitized_cache_file_path(basename)
168
+ "remote_file/#{basename}"
169
+ end
170
+
171
+ def scrubbed_uri
152
172
  # Scrub and truncate in accordance with the goals of keeping the name
153
173
  # human-readable but within the bounds of local file system
154
174
  # path length limits
155
- scrubbed_uri = uri.gsub(/\W/, '_')[0..63]
175
+ uri.gsub(/\W/, '_')[0..63]
176
+ end
177
+
178
+ def sanitized_cache_file_basename
179
+ uri_sha2 = Chef::Digester.instance.generate_checksum(StringIO.new(uri))
180
+ cache_file_basename(uri_sha2[0,32])
181
+ end
182
+
183
+
184
+ def sanitized_cache_file_basename_md5
185
+ # Old way of creating the file basename
156
186
  uri_md5 = Chef::Digester.instance.generate_md5_checksum(StringIO.new(uri))
157
- "#{scrubbed_uri}-#{uri_md5}.json"
187
+ cache_file_basename(uri_md5)
158
188
  end
159
189
 
190
+ def cache_file_basename(checksum)
191
+ "#{scrubbed_uri}-#{checksum}.json"
192
+ end
160
193
  end
161
194
  end
162
195
  end
@@ -105,7 +105,7 @@ class Chef
105
105
  # case you'd end up with a tar archive (no gzip) named, e.g., foo.tgz,
106
106
  # which is not what you wanted.
107
107
  if uri.to_s =~ /gz$/
108
- Chef::Log.debug("turning gzip compression off due to filename ending in gz")
108
+ Chef::Log.debug("Turning gzip compression off due to filename ending in gz")
109
109
  opts[:disable_gzip] = true
110
110
  end
111
111
  opts
@@ -27,6 +27,7 @@ class Chef
27
27
 
28
28
  provides :bash
29
29
  provides :csh
30
+ provides :ksh
30
31
  provides :perl
31
32
  provides :python
32
33
  provides :ruby
@@ -44,16 +44,19 @@ class Chef
44
44
  supports[:restart] = false if supports[:restart].nil?
45
45
  end
46
46
 
47
- def load_new_resource_state
48
- # If the user didn't specify a change in enabled state,
49
- # it will be the same as the old resource
50
- if ( @new_resource.enabled.nil? )
51
- @new_resource.enabled(@current_resource.enabled)
52
- end
53
- if ( @new_resource.running.nil? )
54
- @new_resource.running(@current_resource.running)
55
- end
56
- end
47
+ # the new_resource#enabled and #running variables are not user input, but when we
48
+ # do (e.g.) action_enable we want to set new_resource.enabled so that the comparison
49
+ # between desired and current state produces the correct change in reporting.
50
+ # XXX?: the #nil? check below will likely fail if this is a cloned resource or if
51
+ # we just run multiple actions.
52
+ def load_new_resource_state
53
+ if ( @new_resource.enabled.nil? )
54
+ @new_resource.enabled(@current_resource.enabled)
55
+ end
56
+ if ( @new_resource.running.nil? )
57
+ @new_resource.running(@current_resource.running)
58
+ end
59
+ end
57
60
 
58
61
  def shared_resource_requirements
59
62
  end
@@ -30,35 +30,39 @@ class Chef
30
30
 
31
31
  def initialize(new_resource, run_context=nil)
32
32
  super
33
- @init_command = "/usr/sbin/svcadm"
34
- @status_command = "/bin/svcs -l"
33
+ @init_command = "/usr/sbin/svcadm"
34
+ @status_command = "/bin/svcs"
35
35
  @maintenace = false
36
36
  end
37
37
 
38
38
  def load_current_resource
39
39
  @current_resource = Chef::Resource::Service.new(@new_resource.name)
40
40
  @current_resource.service_name(@new_resource.service_name)
41
- unless ::File.exists? "/bin/svcs"
42
- raise Chef::Exceptions::Service, "/bin/svcs does not exist!"
41
+
42
+ [@init_command, @status_command].each do |cmd|
43
+ unless ::File.executable? cmd then
44
+ raise Chef::Exceptions::Service, "#{cmd} not executable!"
45
+ end
43
46
  end
44
47
  @status = service_status.enabled
48
+
45
49
  @current_resource
46
50
  end
47
51
 
48
52
  def enable_service
49
- shell_out!("#{default_init_command} clear #{@new_resource.service_name}") if @maintenance
50
- shell_out!("#{default_init_command} enable -s #{@new_resource.service_name}")
53
+ shell_out!(default_init_command, "clear", @new_resource.service_name) if @maintenance
54
+ shell_out!(default_init_command, "enable", "-s", @new_resource.service_name)
51
55
  end
52
56
 
53
57
  def disable_service
54
- shell_out!("#{default_init_command} disable -s #{@new_resource.service_name}")
58
+ shell_out!(default_init_command, "disable", "-s", @new_resource.service_name)
55
59
  end
56
60
 
57
61
  alias_method :stop_service, :disable_service
58
62
  alias_method :start_service, :enable_service
59
63
 
60
64
  def reload_service
61
- shell_out_with_systems_locale!("#{default_init_command} refresh #{@new_resource.service_name}")
65
+ shell_out!(default_init_command, "refresh", @new_resource.service_name)
62
66
  end
63
67
 
64
68
  def restart_service
@@ -68,16 +72,38 @@ class Chef
68
72
  end
69
73
 
70
74
  def service_status
71
- status = shell_out!("#{@status_command} #{@current_resource.service_name}", :returns => [0, 1])
72
- status.stdout.each_line do |line|
73
- case line
74
- when /state\s+online/
75
- @current_resource.enabled(true)
76
- @current_resource.running(true)
77
- when /state\s+maintenance/
78
- @maintenance = true
79
- end
75
+ cmd = shell_out!(@status_command, "-l", @current_resource.service_name, :returns => [0, 1])
76
+ # Example output
77
+ # $ svcs -l rsyslog
78
+ # fmri svc:/application/rsyslog:default
79
+ # name rsyslog logging utility
80
+ # enabled true
81
+ # state online
82
+ # next_state none
83
+ # state_time April 2, 2015 04:25:19 PM EDT
84
+ # logfile /var/svc/log/application-rsyslog:default.log
85
+ # restarter svc:/system/svc/restarter:default
86
+ # contract_id 1115271
87
+ # dependency require_all/error svc:/milestone/multi-user:default (online)
88
+ # $
89
+
90
+ # load output into hash
91
+ status = {}
92
+ cmd.stdout.each_line do |line|
93
+ key, value = line.strip.split(/\s+/, 2)
94
+ status[key] = value
95
+ end
96
+
97
+ # check service state
98
+ @maintenance = false
99
+ case status['state']
100
+ when 'online'
101
+ @current_resource.enabled(true)
102
+ @current_resource.running(true)
103
+ when 'maintenance'
104
+ @maintenance = true
80
105
  end
106
+
81
107
  unless @current_resource.enabled
82
108
  @current_resource.enabled(false)
83
109
  @current_resource.running(false)