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
@@ -276,7 +276,7 @@ class Chef
276
276
 
277
277
  def enforce_ownership
278
278
  converge_by("force ownership of #{@new_resource.deploy_to} to #{@new_resource.group}:#{@new_resource.user}") do
279
- FileUtils.chown_R(@new_resource.user, @new_resource.group, @new_resource.deploy_to)
279
+ FileUtils.chown_R(@new_resource.user, @new_resource.group, @new_resource.deploy_to, :force => true)
280
280
  Chef::Log.info("#{@new_resource} set user to #{@new_resource.user}") if @new_resource.user
281
281
  Chef::Log.info("#{@new_resource} set group to #{@new_resource.group}") if @new_resource.group
282
282
  end
@@ -15,7 +15,6 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
  #
18
-
19
18
  require 'chef/util/powershell/cmdlet'
20
19
  require 'chef/util/dsc/local_configuration_manager'
21
20
  require 'chef/mixin/powershell_type_coercions'
@@ -25,19 +24,19 @@ class Chef
25
24
  class Provider
26
25
  class DscResource < Chef::Provider
27
26
  include Chef::Mixin::PowershellTypeCoercions
28
-
29
27
  provides :dsc_resource, os: "windows"
30
-
31
28
  def initialize(new_resource, run_context)
32
29
  super
33
30
  @new_resource = new_resource
34
31
  @module_name = new_resource.module_name
32
+ @reboot_resource = nil
35
33
  end
36
34
 
37
35
  def action_run
38
36
  if ! test_resource
39
37
  converge_by(generate_description) do
40
38
  result = set_resource
39
+ reboot_if_required
41
40
  end
42
41
  end
43
42
  end
@@ -59,8 +58,9 @@ class Chef
59
58
  a.block_action!
60
59
  end
61
60
  requirements.assert(:run) do |a|
62
- a.assertion { dsc_refresh_mode_disabled? }
63
- err = ["The LCM must have its RefreshMode set to Disabled. "]
61
+ a.assertion { supports_refresh_mode_enabled? || dsc_refresh_mode_disabled? }
62
+ err = ["The LCM must have its RefreshMode set to Disabled for" \
63
+ " PowerShell versions before 5.0.10586.0."]
64
64
  a.failure_message Chef::Exceptions::ProviderNotFound, err.join(' ')
65
65
  a.whyrun err + ["Assuming a previous resource sets the RefreshMode."]
66
66
  a.block_action!
@@ -83,11 +83,15 @@ class Chef
83
83
  def supports_dsc_invoke_resource?
84
84
  run_context && Chef::Platform.supports_dsc_invoke_resource?(node)
85
85
  end
86
-
86
+
87
87
  def dsc_refresh_mode_disabled?
88
88
  Chef::Platform.dsc_refresh_mode_disabled?(node)
89
89
  end
90
90
 
91
+ def supports_refresh_mode_enabled?
92
+ Chef::Platform.supports_refresh_mode_enabled?(node)
93
+ end
94
+
91
95
  def generate_description
92
96
  @converge_description
93
97
  end
@@ -99,7 +103,6 @@ class Chef
99
103
  def module_name
100
104
  @module_name ||= begin
101
105
  found = resource_store.find(dsc_resource_name)
102
-
103
106
  r = case found.length
104
107
  when 0
105
108
  raise Chef::Exceptions::ResourceNotFound,
@@ -119,22 +122,23 @@ class Chef
119
122
 
120
123
  def test_resource
121
124
  result = invoke_resource(:test)
122
- # We really want this information from the verbose stream,
123
- # however Invoke-DscResource is not correctly writing to that
124
- # stream and instead just dumping to stdout
125
- @converge_description = result.stdout
125
+ @converge_description = result.stream(:verbose)
126
126
 
127
- if result.return_value.is_a?(Array)
128
- # WMF Feb 2015 Preview
129
- result.return_value[0]["InDesiredState"]
130
- else
131
- # WMF April 2015 Preview
132
- result.return_value["InDesiredState"]
127
+ # We really want this information from the verbose stream,
128
+ # however in some versions of WMF, Invoke-DscResource is not correctly
129
+ # writing to that stream and instead just dumping to stdout
130
+ if @converge_description.empty?
131
+ @converge_description = result.stdout
133
132
  end
133
+
134
+ return_dsc_resource_result(result, "InDesiredState")
134
135
  end
135
136
 
136
137
  def set_resource
137
138
  result = invoke_resource(:set)
139
+ if return_dsc_resource_result(result, 'RebootRequired')
140
+ create_reboot_resource
141
+ end
138
142
  result.return_value
139
143
  end
140
144
 
@@ -142,19 +146,49 @@ class Chef
142
146
  properties = translate_type(@new_resource.properties)
143
147
  switches = "-Method #{method.to_s} -Name #{@new_resource.resource}"\
144
148
  " -Property #{properties} -Verbose"
145
-
146
149
  if module_name != :none
147
150
  switches += " -Module #{module_name}"
148
151
  end
149
-
150
152
  cmdlet = Chef::Util::Powershell::Cmdlet.new(
151
153
  node,
152
154
  "Invoke-DscResource #{switches}",
153
155
  output_format
154
156
  )
155
- cmdlet.run!
157
+ cmdlet.run!({}, {:timeout => new_resource.timeout})
156
158
  end
157
159
 
160
+ def return_dsc_resource_result(result, property_name)
161
+ if result.return_value.is_a?(Array)
162
+ # WMF Feb 2015 Preview
163
+ result.return_value[0][property_name]
164
+ else
165
+ # WMF April 2015 Preview
166
+ result.return_value[property_name]
167
+ end
168
+ end
169
+
170
+ def create_reboot_resource
171
+ @reboot_resource = Chef::Resource::Reboot.new(
172
+ "Reboot for #{@new_resource.name}",
173
+ run_context
174
+ ).tap do |r|
175
+ r.reason("Reboot for #{@new_resource.resource}.")
176
+ end
177
+ end
178
+
179
+ def reboot_if_required
180
+ reboot_action = @new_resource.reboot_action
181
+ unless @reboot_resource.nil?
182
+ case reboot_action
183
+ when :nothing
184
+ Chef::Log.debug("A reboot was requested by the DSC resource, but reboot_action is :nothing.")
185
+ Chef::Log.debug("This dsc_resource will not reboot the node.")
186
+ else
187
+ Chef::Log.debug("Requesting node reboot with #{reboot_action}.")
188
+ @reboot_resource.run_action(reboot_action)
189
+ end
190
+ end
191
+ end
158
192
  end
159
193
  end
160
194
  end
@@ -41,7 +41,7 @@ class Chef
41
41
  def define_resource_requirements
42
42
  # @todo: this should change to raise in some appropriate major version bump.
43
43
  if creates && creates_relative? && !cwd
44
- Chef::Log.warn "Providing a relative path for the creates attribute without the cwd is deprecated and will be changed to fail (CHEF-3819)"
44
+ Chef::Log.warn "Providing a relative path for the creates attribute without the cwd is deprecated and will be changed to fail in the future (CHEF-3819)"
45
45
  end
46
46
  end
47
47
 
@@ -58,7 +58,16 @@ class Chef
58
58
  end
59
59
 
60
60
  converge_by("execute #{description}") do
61
- result = shell_out!(command, opts)
61
+ begin
62
+ shell_out!(command, opts)
63
+ rescue Mixlib::ShellOut::ShellCommandFailed
64
+ if sensitive?
65
+ raise Mixlib::ShellOut::ShellCommandFailed,
66
+ "Command execution failed. STDOUT/STDERR suppressed for sensitive resource"
67
+ else
68
+ raise
69
+ end
70
+ end
62
71
  Chef::Log.info("#{new_resource} ran successfully")
63
72
  end
64
73
  end
@@ -69,6 +78,14 @@ class Chef
69
78
  !!new_resource.sensitive
70
79
  end
71
80
 
81
+ def live_stream?
82
+ Chef::Config[:stream_execute_output] || !!new_resource.live_stream
83
+ end
84
+
85
+ def stream_to_stdout?
86
+ STDOUT.tty? && !Chef::Config[:daemon]
87
+ end
88
+
72
89
  def opts
73
90
  opts = {}
74
91
  opts[:timeout] = timeout
@@ -80,8 +97,12 @@ class Chef
80
97
  opts[:umask] = umask if umask
81
98
  opts[:log_level] = :info
82
99
  opts[:log_tag] = new_resource.to_s
83
- if STDOUT.tty? && !Chef::Config[:daemon] && Chef::Log.info? && !sensitive?
84
- opts[:live_stream] = STDOUT
100
+ if (Chef::Log.info? || live_stream?) && !sensitive?
101
+ if run_context.events.formatter?
102
+ opts[:live_stream] = Chef::EventDispatch::EventsOutputStream.new(run_context.events, :name => :execute)
103
+ elsif stream_to_stdout?
104
+ opts[:live_stream] = STDOUT
105
+ end
85
106
  end
86
107
  opts
87
108
  end
@@ -125,7 +125,7 @@ class Chef
125
125
  def action_create
126
126
  case @group_exists
127
127
  when false
128
- converge_by("create #{@new_resource.group_name}") do
128
+ converge_by("create group #{@new_resource.group_name}") do
129
129
  create_group
130
130
  Chef::Log.info("#{@new_resource} created")
131
131
  end
@@ -19,6 +19,7 @@
19
19
  #
20
20
 
21
21
  require 'chef/provider'
22
+ require 'chef/dsl/recipe'
22
23
  require 'chef/dsl/include_recipe'
23
24
 
24
25
  class Chef
@@ -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");
@@ -18,6 +18,7 @@
18
18
 
19
19
  require 'chef/mixin/shell_out'
20
20
  require 'chef/mixin/command'
21
+ require 'chef/mixin/subclass_directive'
21
22
  require 'chef/log'
22
23
  require 'chef/file_cache'
23
24
  require 'chef/platform'
@@ -27,6 +28,12 @@ class Chef
27
28
  class Package < Chef::Provider
28
29
  include Chef::Mixin::Command
29
30
  include Chef::Mixin::ShellOut
31
+ extend Chef::Mixin::SubclassDirective
32
+
33
+ # subclasses declare this if they want all their arguments as arrays of packages and names
34
+ subclass_directive :use_multipackage_api
35
+ # subclasses declare this if they want sources (filenames) pulled from their package names
36
+ subclass_directive :use_package_name_for_source
30
37
 
31
38
  #
32
39
  # Hook that subclasses use to populate the candidate_version(s)
@@ -44,6 +51,8 @@ class Chef
44
51
  end
45
52
 
46
53
  def check_resource_semantics!
54
+ # FIXME: this is not universally true and subclasses are needing to override this and no-ops it. It should be turned into
55
+ # another "subclass_directive" and the apt and yum providers should declare that they need this behavior.
47
56
  if new_resource.package_name.is_a?(Array) && new_resource.source != nil
48
57
  raise Chef::Exceptions::InvalidResourceSpecification, "You may not specify both multipackage and source"
49
58
  end
@@ -86,11 +95,10 @@ class Chef
86
95
  end
87
96
  end
88
97
 
89
- # XXX: mutating the new resource is generally bad
90
- @new_resource.version(versions_for_new_resource)
91
-
92
98
  converge_by(install_description) do
93
- install_package(package_names_for_targets, versions_for_targets)
99
+ multipackage_api_adapter(package_names_for_targets, versions_for_targets) do |name, version|
100
+ install_package(name, version)
101
+ end
94
102
  Chef::Log.info("#{@new_resource} installed #{package_names_for_targets} at #{versions_for_targets}")
95
103
  end
96
104
  end
@@ -113,11 +121,10 @@ class Chef
113
121
  return
114
122
  end
115
123
 
116
- # XXX: mutating the new resource is generally bad
117
- @new_resource.version(versions_for_new_resource)
118
-
119
124
  converge_by(upgrade_description) do
120
- upgrade_package(package_names_for_targets, versions_for_targets)
125
+ multipackage_api_adapter(package_names_for_targets, versions_for_targets) do |name, version|
126
+ upgrade_package(name, version)
127
+ end
121
128
  log_allow_downgrade = allow_downgrade ? '(allow_downgrade)' : ''
122
129
  Chef::Log.info("#{@new_resource} upgraded#{log_allow_downgrade} #{package_names_for_targets} to #{versions_for_targets}")
123
130
  end
@@ -138,12 +145,13 @@ class Chef
138
145
 
139
146
  private :upgrade_description
140
147
 
141
- # @todo: ability to remove an array of packages
142
148
  def action_remove
143
149
  if removing_package?
144
150
  description = @new_resource.version ? "version #{@new_resource.version} of " : ""
145
151
  converge_by("remove #{description}package #{@current_resource.package_name}") do
146
- remove_package(@current_resource.package_name, @new_resource.version)
152
+ multipackage_api_adapter(@current_resource.package_name, @new_resource.version) do |name, version|
153
+ remove_package(name, version)
154
+ end
147
155
  Chef::Log.info("#{@new_resource} removed")
148
156
  end
149
157
  else
@@ -172,18 +180,18 @@ class Chef
172
180
  end
173
181
  end
174
182
 
175
- # @todo: ability to purge an array of packages
176
183
  def action_purge
177
184
  if removing_package?
178
185
  description = @new_resource.version ? "version #{@new_resource.version} of" : ""
179
186
  converge_by("purge #{description} package #{@current_resource.package_name}") do
180
- purge_package(@current_resource.package_name, @new_resource.version)
187
+ multipackage_api_adapter(@current_resource.package_name, @new_resource.version) do |name, version|
188
+ purge_package(name, version)
189
+ end
181
190
  Chef::Log.info("#{@new_resource} purged")
182
191
  end
183
192
  end
184
193
  end
185
194
 
186
- # @todo: ability to reconfigure an array of packages
187
195
  def action_reconfig
188
196
  if @current_resource.version == nil then
189
197
  Chef::Log.debug("#{@new_resource} is NOT installed - nothing to do")
@@ -198,7 +206,10 @@ class Chef
198
206
  if preseed_file = get_preseed_file(@new_resource.package_name, @current_resource.version)
199
207
  converge_by("reconfigure package #{@new_resource.package_name}") do
200
208
  preseed_package(preseed_file)
201
- reconfig_package(@new_resource.package_name, @current_resource.version)
209
+ multipackage_api_adapter(@new_resource.package_name, @current_resource.version) do |name, version|
210
+ reconfig_package(name, version)
211
+
212
+ end
202
213
  Chef::Log.info("#{@new_resource} reconfigured")
203
214
  end
204
215
  else
@@ -207,6 +218,15 @@ class Chef
207
218
  end
208
219
 
209
220
  # @todo use composition rather than inheritance
221
+
222
+ def multipackage_api_adapter(name, version)
223
+ if use_multipackage_api?
224
+ yield [name].flatten, [version].flatten
225
+ else
226
+ yield name, version
227
+ end
228
+ end
229
+
210
230
  def install_package(name, version)
211
231
  raise Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :install"
212
232
  end
@@ -231,7 +251,7 @@ class Chef
231
251
  raise( Chef::Exceptions::UnsupportedAction, "#{self.to_s} does not support :reconfig" )
232
252
  end
233
253
 
234
- # this is heavily used by subclasses
254
+ # used by subclasses. deprecated. use #a_to_s instead.
235
255
  def expand_options(options)
236
256
  options ? " #{options}" : ""
237
257
  end
@@ -322,18 +342,6 @@ class Chef
322
342
  multipackage? ? versions_for_targets : versions_for_targets[0]
323
343
  end
324
344
 
325
- # We need to mutate @new_resource.version() for some reason and this is a helper so that we inject the right
326
- # class (String or Array) into that attribute based on if we're handling an array of package names or not.
327
- #
328
- # @return [String, Array<String>] target_versions coerced into the correct type for back-compat
329
- def versions_for_new_resource
330
- if multipackage?
331
- target_version_array
332
- else
333
- target_version_array[0]
334
- end
335
- end
336
-
337
345
  # Return an array indexed the same as *_version_array which contains either the target version to install/upgrade to
338
346
  # or else nil if the package is not being modified.
339
347
  #
@@ -473,6 +481,37 @@ class Chef
473
481
  [ new_resource.version ].flatten.map { |v| v.to_s.empty? ? nil : v }
474
482
  end
475
483
 
484
+ # TIP: less error prone to simply always call resolved_source_array, even if you
485
+ # don't think that you need to.
486
+ #
487
+ # @return [Array] new_resource.source as an array
488
+ def source_array
489
+ if new_resource.source.nil?
490
+ package_name_array.map { nil }
491
+ else
492
+ [ new_resource.source ].flatten
493
+ end
494
+ end
495
+
496
+ # Helper to handle use_package_name_for_source to convert names into local packages to install.
497
+ #
498
+ # @return [Array] Array of sources with package_names converted to sources
499
+ def resolved_source_array
500
+ @resolved_source_array ||=
501
+ begin
502
+ source_array.each_with_index.map do |source, i|
503
+ package_name = package_name_array[i]
504
+ # we require at least one '/' in the package_name to avoid [XXX_]package 'foo' breaking due to a random 'foo' file in cwd
505
+ if use_package_name_for_source? && source.nil? && package_name.match(/#{::File::SEPARATOR}/) && ::File.exist?(package_name)
506
+ Chef::Log.debug("No package source specified, but #{package_name} exists on filesystem, using #{package_name} as source.")
507
+ package_name
508
+ else
509
+ source
510
+ end
511
+ end
512
+ end
513
+ end
514
+
476
515
  # @todo: extract apt/dpkg specific preseeding to a helper class
477
516
  def template_available?(path)
478
517
  run_context.has_template_in_cookbook?(new_resource.cookbook_name, path)
@@ -491,8 +530,6 @@ class Chef
491
530
  end
492
531
  end
493
532
 
494
- private
495
-
496
533
  def shell_out_with_timeout(*command_args)
497
534
  shell_out(*add_timeout_option(command_args))
498
535
  end
@@ -514,6 +551,15 @@ class Chef
514
551
  args
515
552
  end
516
553
 
554
+ # Helper for sublcasses to convert an array of string args into a string. It
555
+ # will compact nil or empty strings in the array and will join the array elements
556
+ # with spaces, without introducing any double spaces for nil/empty elements.
557
+ #
558
+ # @param args [String] variable number of string arguments
559
+ # @return [String] nicely concatenated string or empty string
560
+ def a_to_s(*args)
561
+ args.reject {|i| i.nil? || i == "" }.join(" ")
562
+ end
517
563
  end
518
564
  end
519
565
  end