chef 12.16.42-universal-mingw32 → 12.17.44-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.
- checksums.yaml +4 -4
- data/Gemfile +2 -1
- data/README.md +20 -5
- data/Rakefile +17 -0
- data/VERSION +1 -1
- data/acceptance/Gemfile.lock +32 -23
- data/distro/common/markdown/man1/knife-configure.mkd +3 -2
- data/lib-backcompat/chef/chef_fs/file_system/already_exists_error.rb +1 -1
- data/lib-backcompat/chef/chef_fs/file_system/cookbook_frozen_error.rb +1 -1
- data/lib-backcompat/chef/chef_fs/file_system/default_environment_cannot_be_modified_error.rb +1 -1
- data/lib-backcompat/chef/chef_fs/file_system/file_system_error.rb +1 -1
- data/lib-backcompat/chef/chef_fs/file_system/must_delete_recursively_error.rb +1 -1
- data/lib-backcompat/chef/chef_fs/file_system/not_found_error.rb +1 -1
- data/lib-backcompat/chef/chef_fs/file_system/operation_failed_error.rb +1 -1
- data/lib-backcompat/chef/chef_fs/file_system/operation_not_allowed_error.rb +1 -1
- data/lib-backcompat/chef/chef_fs/file_system/repository/chef_repository_file_system_entry.rb +1 -1
- data/lib-backcompat/chef/chef_fs/file_system/repository/file_system_root_dir.rb +1 -1
- data/lib/chef/api_client.rb +1 -1
- data/lib/chef/application.rb +1 -1
- data/lib/chef/application/exit_code.rb +3 -3
- data/lib/chef/chef_class.rb +15 -5
- data/lib/chef/chef_fs/file_system/repository/chef_repository_file_system_root_dir.rb +12 -1
- data/lib/chef/chef_fs/file_system/repository/nodes_dir.rb +19 -0
- data/lib/chef/client.rb +1 -0
- data/lib/chef/cookbook/metadata.rb +2 -2
- data/lib/chef/cookbook_version.rb +4 -4
- data/lib/chef/data_bag.rb +1 -1
- data/lib/chef/data_bag_item.rb +1 -1
- data/lib/chef/data_collector.rb +20 -13
- data/lib/chef/data_collector/messages.rb +0 -1
- data/lib/chef/data_collector/messages/helpers.rb +2 -2
- data/lib/chef/decorator/unchain.rb +2 -2
- data/lib/chef/deprecated.rb +190 -0
- data/lib/chef/deprecation/provider/remote_directory.rb +1 -1
- data/lib/chef/deprecation/warnings.rb +3 -4
- data/lib/chef/dsl/method_missing.rb +2 -2
- data/lib/chef/dsl/resources.rb +2 -2
- data/lib/chef/environment.rb +1 -1
- data/lib/chef/exceptions.rb +1 -1
- data/lib/chef/formatters/base.rb +11 -1
- data/lib/chef/formatters/doc.rb +13 -4
- data/lib/chef/key.rb +1 -1
- data/lib/chef/knife/client_delete.rb +12 -9
- data/lib/chef/knife/configure.rb +1 -1
- data/lib/chef/knife/core/bootstrap_context.rb +25 -1
- data/lib/chef/knife/core/subcommand_loader.rb +3 -3
- data/lib/chef/knife/core/ui.rb +1 -1
- data/lib/chef/knife/node_delete.rb +6 -6
- data/lib/chef/log.rb +1 -1
- data/lib/chef/mixin/deprecation.rb +4 -10
- data/lib/chef/mixin/powershell_type_coercions.rb +19 -19
- data/lib/chef/mixin/shell_out.rb +1 -1
- data/lib/chef/node.rb +2 -2
- data/lib/chef/node/attribute.rb +3 -4
- data/lib/chef/node/common_api.rb +1 -1
- data/lib/chef/node/mixin/state_tracking.rb +5 -2
- data/lib/chef/node_map.rb +2 -2
- data/lib/chef/org.rb +1 -1
- data/lib/chef/platform/rebooter.rb +3 -1
- data/lib/chef/policy_builder/expand_node_object.rb +1 -1
- data/lib/chef/property.rb +5 -5
- data/lib/chef/provider.rb +4 -4
- data/lib/chef/provider/launchd.rb +1 -1
- data/lib/chef/provider/link.rb +6 -0
- data/lib/chef/provider/mount.rb +2 -0
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/ohai.rb +5 -3
- data/lib/chef/provider/package/cab.rb +1 -1
- data/lib/chef/provider/package/chocolatey.rb +2 -2
- data/lib/chef/provider/package/easy_install.rb +2 -2
- data/lib/chef/provider/package/msu.rb +162 -0
- data/lib/chef/provider/package/powershell.rb +114 -0
- data/lib/chef/provider/package/yum.rb +1 -1
- data/lib/chef/provider/yum_repository.rb +6 -7
- data/lib/chef/provider_resolver.rb +2 -2
- data/lib/chef/providers.rb +2 -0
- data/lib/chef/resource.rb +3 -5
- data/lib/chef/resource/apt_update.rb +1 -1
- data/lib/chef/resource/chef_gem.rb +2 -3
- data/lib/chef/resource/file/verification.rb +1 -1
- data/lib/chef/resource/launchd.rb +48 -8
- data/lib/chef/resource/mount.rb +1 -1
- data/lib/chef/resource/msu_package.rb +47 -0
- data/lib/chef/resource/ohai.rb +5 -25
- data/lib/chef/resource/powershell_package.rb +41 -0
- data/lib/chef/resource/reboot.rb +1 -1
- data/lib/chef/resource/user.rb +2 -2
- data/lib/chef/resource_builder.rb +4 -4
- data/lib/chef/resource_resolver.rb +2 -3
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/rest.rb +1 -1
- data/lib/chef/role.rb +1 -1
- data/lib/chef/run_context.rb +3 -3
- data/lib/chef/shell/ext.rb +2 -2
- data/lib/chef/user.rb +3 -3
- data/lib/chef/user_v1.rb +1 -1
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/api/security.rb +12 -12
- data/spec/data/sample_msu1.xml +10 -0
- data/spec/data/sample_msu2.xml +14 -0
- data/spec/data/sample_msu3.xml +16 -0
- data/spec/functional/rebooter_spec.rb +3 -3
- data/spec/functional/resource/link_spec.rb +62 -1
- data/spec/functional/resource/msu_package_spec.rb +84 -0
- data/spec/functional/resource/registry_spec.rb +3 -3
- data/spec/functional/resource/rpm_spec.rb +7 -10
- data/spec/integration/solo/solo_spec.rb +50 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/platform_helpers.rb +16 -8
- data/spec/unit/application/exit_code_spec.rb +3 -15
- data/spec/unit/data_collector_spec.rb +6 -16
- data/spec/unit/deprecated_spec.rb +59 -0
- data/spec/unit/deprecation_spec.rb +1 -8
- data/spec/unit/handler_spec.rb +2 -2
- data/spec/unit/knife/client_delete_spec.rb +16 -0
- data/spec/unit/knife/configure_spec.rb +1 -1
- data/spec/unit/knife/cookbook_metadata_spec.rb +116 -113
- data/spec/unit/knife/core/bootstrap_context_spec.rb +55 -5
- data/spec/unit/knife/node_delete_spec.rb +19 -10
- data/spec/unit/mixin/shell_out_spec.rb +0 -1
- data/spec/unit/node/immutable_collections_spec.rb +5 -0
- data/spec/unit/node/vivid_mash_spec.rb +11 -0
- data/spec/unit/node_spec.rb +2 -2
- data/spec/unit/provider/launchd_spec.rb +81 -3
- data/spec/unit/provider/mount/mount_spec.rb +1 -1
- data/spec/unit/provider/mount_spec.rb +7 -0
- data/spec/unit/provider/package/chocolatey_spec.rb +5 -5
- data/spec/unit/provider/package/easy_install_spec.rb +6 -6
- data/spec/unit/provider/package/msu_spec.rb +283 -0
- data/spec/unit/provider/package/powershell_spec.rb +337 -0
- data/spec/unit/provider/service/macosx_spec.rb +1 -1
- data/spec/unit/provider/subversion_spec.rb +9 -0
- data/spec/unit/provider/user/linux_spec.rb +7 -1
- data/spec/unit/recipe_spec.rb +43 -11
- data/spec/unit/resource/apt_update_spec.rb +17 -25
- data/spec/unit/resource/file/verification_spec.rb +1 -1
- data/spec/unit/resource/mount_spec.rb +2 -1
- data/spec/unit/resource/msu_package_spec.rb +49 -0
- data/spec/unit/resource/ohai_spec.rb +1 -1
- data/spec/unit/resource/powershell_package_spec.rb +68 -0
- data/spec/unit/resource_reporter_spec.rb +4 -4
- data/spec/unit/run_status_spec.rb +1 -1
- data/tasks/announce.rb +58 -0
- data/tasks/changelog.rb +26 -6
- data/tasks/templates/prerelease.md.erb +35 -0
- data/tasks/templates/release.md.erb +34 -0
- metadata +21 -4
data/lib/chef/node_map.rb
CHANGED
@@ -32,8 +32,8 @@ class Chef
|
|
32
32
|
# @return [NodeMap] Returns self for possible chaining
|
33
33
|
#
|
34
34
|
def set(key, value, platform: nil, platform_version: nil, platform_family: nil, os: nil, on_platform: nil, on_platforms: nil, canonical: nil, override: nil, &block)
|
35
|
-
Chef.
|
36
|
-
Chef.
|
35
|
+
Chef.deprecated(:internal_api, "The on_platform option to node_map has been deprecated") if on_platform
|
36
|
+
Chef.deprecated(:internal_api, "The on_platforms option to node_map has been deprecated") if on_platforms
|
37
37
|
platform ||= on_platform || on_platforms
|
38
38
|
filters = {}
|
39
39
|
filters[:platform] = platform if platform
|
data/lib/chef/org.rb
CHANGED
@@ -125,7 +125,7 @@ class Chef
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def self.json_create(json)
|
128
|
-
Chef.
|
128
|
+
Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Org#from_json or Chef::Org#load.")
|
129
129
|
Chef::Org.from_json(json)
|
130
130
|
end
|
131
131
|
|
@@ -35,7 +35,9 @@ class Chef
|
|
35
35
|
|
36
36
|
cmd = if Chef::Platform.windows?
|
37
37
|
# should this do /f as well? do we then need a minimum delay to let apps quit?
|
38
|
-
|
38
|
+
# Use explicit path to shutdown.exe, to protect against https://github.com/chef/chef/issues/5594
|
39
|
+
windows_shutdown_path = "#{ENV['SYSTEMROOT']}/System32/shutdown.exe"
|
40
|
+
"#{windows_shutdown_path} /r /t #{reboot_info[:delay_mins] * 60} /c \"#{reboot_info[:reason]}\""
|
39
41
|
else
|
40
42
|
# probably Linux-only.
|
41
43
|
"shutdown -r +#{reboot_info[:delay_mins]} \"#{reboot_info[:reason]}\""
|
@@ -112,7 +112,7 @@ class Chef
|
|
112
112
|
# to create a PolicyBuilder::Dynamc policy builder and allow it to select
|
113
113
|
# the proper implementation.
|
114
114
|
def load_node
|
115
|
-
Chef.
|
115
|
+
Chef.deprecated(:internal_api, "ExpandNodeObject#load_node is deprecated. Please use Chef::PolicyBuilder::Dynamic instead of using ExpandNodeObject directly")
|
116
116
|
|
117
117
|
events.node_load_start(node_name, config)
|
118
118
|
Chef::Log.debug("Building node object for #{node_name}")
|
data/lib/chef/property.rb
CHANGED
@@ -116,7 +116,7 @@ class Chef
|
|
116
116
|
options.delete(:name_property)
|
117
117
|
preferred_default = :default
|
118
118
|
end
|
119
|
-
Chef.
|
119
|
+
Chef.deprecated(:custom_resource, "Cannot specify both default and name_property together on property #{self}. Only one (#{preferred_default}) will be obeyed. In Chef 13, this will become an error. Please remove one or the other from the property.")
|
120
120
|
end
|
121
121
|
|
122
122
|
# Validate the default early, so the user gets a good error message, and
|
@@ -287,13 +287,13 @@ class Chef
|
|
287
287
|
input_to_stored_value(resource, value)
|
288
288
|
# If nil is valid, and it would change the value, warn that this will change to a set.
|
289
289
|
if !result.nil?
|
290
|
-
Chef.
|
290
|
+
Chef.deprecated(:custom_resource, "An attempt was made to change #{name} from #{result.inspect} to nil by calling #{name}(nil). In Chef 12, this does a get rather than a set. In Chef 13, this will change to set the value to nil.")
|
291
291
|
end
|
292
292
|
rescue Chef::Exceptions::DeprecatedFeatureError
|
293
293
|
raise
|
294
294
|
rescue
|
295
295
|
# If nil is invalid, warn that this will become an error.
|
296
|
-
Chef.
|
296
|
+
Chef.deprecated(:custom_resource, "nil is an invalid value for #{self}. In Chef 13, this warning will change to an error. Error: #{$!}")
|
297
297
|
end
|
298
298
|
|
299
299
|
result
|
@@ -677,9 +677,9 @@ class Chef
|
|
677
677
|
# warn and return the (possibly coerced) value to the user.
|
678
678
|
if is_default
|
679
679
|
if value.nil?
|
680
|
-
Chef.
|
680
|
+
Chef.deprecated(:custom_resource, "Default value nil is invalid for property #{self}. Possible fixes: 1. Remove 'default: nil' if nil means 'undefined'. 2. Set a valid default value if there is a reasonable one. 3. Allow nil as a valid value of your property (for example, 'property #{name.inspect}, [ String, nil ], default: nil'). Error: #{$!}")
|
681
681
|
else
|
682
|
-
Chef.
|
682
|
+
Chef.deprecated(:custom_resource, "Default value #{value.inspect} is invalid for property #{self}. In Chef 13 this will become an error: #{$!}.")
|
683
683
|
end
|
684
684
|
else
|
685
685
|
raise
|
data/lib/chef/provider.rb
CHANGED
@@ -205,7 +205,7 @@ class Chef
|
|
205
205
|
specified_properties = properties.select { |property| new_resource.property_is_set?(property) }
|
206
206
|
modified = specified_properties.select { |p| new_resource.send(p) != current_resource.send(p) }
|
207
207
|
if modified.empty?
|
208
|
-
properties_str = if sensitive
|
208
|
+
properties_str = if new_resource.sensitive
|
209
209
|
specified_properties.join(", ")
|
210
210
|
else
|
211
211
|
specified_properties.map { |p| "#{p}=#{new_resource.send(p).inspect}" }.join(", ")
|
@@ -217,7 +217,7 @@ class Chef
|
|
217
217
|
# Print the pretty green text and run the block
|
218
218
|
property_size = modified.map { |p| p.size }.max
|
219
219
|
modified.map! do |p|
|
220
|
-
properties_str = if sensitive
|
220
|
+
properties_str = if new_resource.sensitive
|
221
221
|
"(suppressed sensitive property)"
|
222
222
|
else
|
223
223
|
"#{new_resource.send(p).inspect} (was #{current_resource.send(p).inspect})"
|
@@ -232,7 +232,7 @@ class Chef
|
|
232
232
|
property_size = properties.map { |p| p.size }.max
|
233
233
|
created = properties.map do |property|
|
234
234
|
default = " (default value)" unless new_resource.property_is_set?(property)
|
235
|
-
properties_str = if sensitive
|
235
|
+
properties_str = if new_resource.sensitive
|
236
236
|
"(suppressed sensitive property)"
|
237
237
|
else
|
238
238
|
new_resource.send(property).inspect
|
@@ -424,7 +424,7 @@ class Chef
|
|
424
424
|
module DeprecatedLWRPClass
|
425
425
|
def const_missing(class_name)
|
426
426
|
if Chef::Provider.deprecated_constants[class_name.to_sym]
|
427
|
-
Chef.
|
427
|
+
Chef.deprecated(:custom_resource, "Using an LWRP provider by its name (#{class_name}) directly is no longer supported in Chef 12 and will be removed. Use Chef::ProviderResolver.new(node, resource, action) instead.")
|
428
428
|
Chef::Provider.deprecated_constants[class_name.to_sym]
|
429
429
|
else
|
430
430
|
raise NameError, "uninitialized constant Chef::Provider::#{class_name}"
|
@@ -115,7 +115,7 @@ class Chef
|
|
115
115
|
res = Chef::Resource::File.new(@path, run_context)
|
116
116
|
res.name(@path) if @path
|
117
117
|
res.backup(backup) if backup
|
118
|
-
res.content(content) if content
|
118
|
+
res.content(content) if content?
|
119
119
|
res.group(group) if group
|
120
120
|
res.mode(mode) if mode
|
121
121
|
res.owner(owner) if owner
|
data/lib/chef/provider/link.rb
CHANGED
@@ -121,6 +121,12 @@ class Chef
|
|
121
121
|
file_class.symlink(canonicalize(@new_resource.to), @new_resource.target_file)
|
122
122
|
Chef::Log.debug("#{@new_resource} created #{@new_resource.link_type} link from #{@new_resource.target_file} -> #{@new_resource.to}")
|
123
123
|
Chef::Log.info("#{@new_resource} created")
|
124
|
+
# file_class.symlink will create the link with default access controls.
|
125
|
+
# This means that the access controls of the file could be different
|
126
|
+
# than those captured during the initial evaluation of current_resource.
|
127
|
+
# We need to re-evaluate the current_resource to ensure that the desired
|
128
|
+
# access controls are applied.
|
129
|
+
ScanAccessControl.new(@new_resource, @current_resource).set_all!
|
124
130
|
end
|
125
131
|
elsif @new_resource.link_type == :hard
|
126
132
|
converge_by("create hard link at #{@new_resource.target_file} to #{@new_resource.to}") do
|
data/lib/chef/provider/mount.rb
CHANGED
@@ -193,7 +193,7 @@ class Chef
|
|
193
193
|
def device_should_exist?
|
194
194
|
( @new_resource.device != "none" ) &&
|
195
195
|
( not network_device? ) &&
|
196
|
-
( not %w{ cgroup tmpfs fuse vboxsf }.include? @new_resource.fstype )
|
196
|
+
( not %w{ cgroup tmpfs fuse vboxsf zfs }.include? @new_resource.fstype )
|
197
197
|
end
|
198
198
|
|
199
199
|
private
|
data/lib/chef/provider/ohai.rb
CHANGED
@@ -21,6 +21,8 @@ require "ohai"
|
|
21
21
|
class Chef
|
22
22
|
class Provider
|
23
23
|
class Ohai < Chef::Provider
|
24
|
+
use_inline_resources
|
25
|
+
|
24
26
|
provides :ohai
|
25
27
|
|
26
28
|
def whyrun_supported?
|
@@ -31,7 +33,7 @@ class Chef
|
|
31
33
|
true
|
32
34
|
end
|
33
35
|
|
34
|
-
|
36
|
+
action :reload do
|
35
37
|
converge_by("re-run ohai and merge results into node attributes") do
|
36
38
|
ohai = ::Ohai::System.new
|
37
39
|
|
@@ -39,9 +41,9 @@ class Chef
|
|
39
41
|
# Otherwise it will only reload the specified plugin
|
40
42
|
# Note that any changes to plugins, or new plugins placed on
|
41
43
|
# the path are picked up by ohai.
|
42
|
-
ohai.all_plugins
|
44
|
+
ohai.all_plugins new_resource.plugin
|
43
45
|
node.automatic_attrs.merge! ohai.data
|
44
|
-
Chef::Log.info("#{
|
46
|
+
Chef::Log.info("#{new_resource} reloaded")
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
@@ -45,7 +45,7 @@ class Chef
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def dism_command(command)
|
48
|
-
shellout = Mixlib::ShellOut.new("dism.exe /Online #{command} /NoRestart", { :timeout => @new_resource.timeout })
|
48
|
+
shellout = Mixlib::ShellOut.new("dism.exe /Online /English #{command} /NoRestart", { :timeout => @new_resource.timeout })
|
49
49
|
with_os_architecture(nil) do
|
50
50
|
shellout.run_command
|
51
51
|
end
|
@@ -84,7 +84,7 @@ EOS
|
|
84
84
|
|
85
85
|
# choco does not support installing multiple packages with version pins
|
86
86
|
name_has_versions.each do |name, version|
|
87
|
-
choco_command("install -y
|
87
|
+
choco_command("install -y --version", version, cmd_args, name)
|
88
88
|
end
|
89
89
|
|
90
90
|
# but we can do all the ones without version pins at once
|
@@ -106,7 +106,7 @@ EOS
|
|
106
106
|
|
107
107
|
# choco does not support installing multiple packages with version pins
|
108
108
|
name_has_versions.each do |name, version|
|
109
|
-
choco_command("upgrade -y
|
109
|
+
choco_command("upgrade -y --version", version, cmd_args, name)
|
110
110
|
end
|
111
111
|
|
112
112
|
# but we can do all the ones without version pins at once
|
@@ -112,7 +112,7 @@ class Chef
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def install_package(name, version)
|
115
|
-
Chef.
|
115
|
+
Chef.deprecated(:easy_install, "The easy_install package provider is deprecated and will be removed in Chef 13.")
|
116
116
|
run_command(:command => "#{easy_install_binary_path}#{expand_options(@new_resource.options)} \"#{name}==#{version}\"")
|
117
117
|
end
|
118
118
|
|
@@ -121,7 +121,7 @@ class Chef
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def remove_package(name, version)
|
124
|
-
Chef.
|
124
|
+
Chef.deprecated(:easy_install, "The easy_install package provider is deprecated and will be removed in Chef 13.")
|
125
125
|
run_command(:command => "#{easy_install_binary_path }#{expand_options(@new_resource.options)} -m #{name}")
|
126
126
|
end
|
127
127
|
|
@@ -0,0 +1,162 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Nimisha Sharad (<nimisha.sharad@msystechnologies.com>)
|
3
|
+
# Copyright:: Copyright 2015-2016, Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
# msu_package leverages cab_package
|
20
|
+
# The contents of msu file are extracted, which contains one or more cab files.
|
21
|
+
# The extracted cab files are installed using Chef::Resource::Package::CabPackage
|
22
|
+
# Reference: https://support.microsoft.com/en-in/kb/934307
|
23
|
+
require "chef/provider/package"
|
24
|
+
require "chef/resource/msu_package"
|
25
|
+
require "chef/mixin/shell_out"
|
26
|
+
require "chef/provider/package/cab"
|
27
|
+
require "chef/util/path_helper"
|
28
|
+
require "chef/mixin/uris"
|
29
|
+
require "chef/mixin/checksum"
|
30
|
+
|
31
|
+
class Chef
|
32
|
+
class Provider
|
33
|
+
class Package
|
34
|
+
class Msu < Chef::Provider::Package
|
35
|
+
use_inline_resources
|
36
|
+
include Chef::Mixin::ShellOut
|
37
|
+
include Chef::Mixin::Uris
|
38
|
+
include Chef::Mixin::Checksum
|
39
|
+
|
40
|
+
provides :msu_package, os: "windows"
|
41
|
+
|
42
|
+
def load_current_resource
|
43
|
+
@current_resource = Chef::Resource::MsuPackage.new(new_resource.name)
|
44
|
+
|
45
|
+
# download file if source is a url
|
46
|
+
msu_file = uri_scheme?(new_resource.source) ? download_source_file : @new_resource.source
|
47
|
+
|
48
|
+
# temp directory where the contents of msu file get extracted
|
49
|
+
@temp_directory = Dir.mktmpdir("chef")
|
50
|
+
extract_msu_contents(msu_file, @temp_directory)
|
51
|
+
@cab_files = read_cab_files_from_xml(@temp_directory)
|
52
|
+
|
53
|
+
unless @cab_files.empty?
|
54
|
+
current_resource.version(get_current_versions)
|
55
|
+
else
|
56
|
+
raise Chef::Exceptions::Package, "Corrupt MSU package: MSU package XML does not contain any cab file"
|
57
|
+
end
|
58
|
+
current_resource
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_current_versions
|
62
|
+
@cab_files.map do |cabfile|
|
63
|
+
cab_pkg = get_cab_package(cabfile)
|
64
|
+
cab_pkg.installed_version
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_candidate_versions
|
69
|
+
@cab_files.map do |cabfile|
|
70
|
+
cab_pkg = get_cab_package(cabfile)
|
71
|
+
cab_pkg.package_version
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def candidate_version
|
76
|
+
@candidate_version ||= get_candidate_versions
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_cab_package(cab_file)
|
80
|
+
cab_resource = @new_resource
|
81
|
+
cab_resource.source = cab_file
|
82
|
+
cab_pkg = Chef::Provider::Package::Cab.new(cab_resource, nil)
|
83
|
+
end
|
84
|
+
|
85
|
+
def download_source_file
|
86
|
+
source_resource.run_action(:create)
|
87
|
+
Chef::Log.debug("#{new_resource} fetched source file to #{source_resource.path}")
|
88
|
+
source_resource.path
|
89
|
+
end
|
90
|
+
|
91
|
+
def source_resource
|
92
|
+
@source_resource ||= declare_resource(:remote_file, new_resource.name) do
|
93
|
+
path default_download_cache_path
|
94
|
+
source new_resource.source
|
95
|
+
checksum new_resource.checksum
|
96
|
+
backup false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def default_download_cache_path
|
101
|
+
uri = ::URI.parse(new_resource.source)
|
102
|
+
filename = ::File.basename(::URI.unescape(uri.path))
|
103
|
+
file_cache_dir = Chef::FileCache.create_cache_path("package/")
|
104
|
+
Chef::Util::PathHelper.cleanpath("#{file_cache_dir}/#{filename}")
|
105
|
+
end
|
106
|
+
|
107
|
+
def install_package(name, version)
|
108
|
+
#use cab_package resource to install the extracted cab packages
|
109
|
+
@cab_files.each do |cab_file|
|
110
|
+
declare_resource(:cab_package, @new_resource.name) do
|
111
|
+
source cab_file
|
112
|
+
action :install
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def remove_package(name, version)
|
118
|
+
#use cab_package provider to remove the extracted cab packages
|
119
|
+
@cab_files.each do |cab_file|
|
120
|
+
declare_resource(:cab_package, @new_resource.name) do
|
121
|
+
source cab_file
|
122
|
+
action :remove
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def extract_msu_contents(msu_file, destination)
|
128
|
+
with_os_architecture(nil) do
|
129
|
+
shell_out_with_timeout!("#{ENV['SYSTEMROOT']}\\system32\\expand.exe -f:* #{msu_file} #{destination}")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# msu package can contain multiple cab files
|
134
|
+
# Reading cab files from xml to ensure the order of installation in case of multiple cab files
|
135
|
+
def read_cab_files_from_xml(msu_dir)
|
136
|
+
# get the file with .xml extension
|
137
|
+
xml_files = Dir.glob("#{msu_dir}/*.xml")
|
138
|
+
cab_files = []
|
139
|
+
|
140
|
+
if xml_files.empty?
|
141
|
+
raise Chef::Exceptions::Package, "Corrupt MSU package: MSU package doesn't contain any xml file"
|
142
|
+
else
|
143
|
+
# msu package contains only single xml file. So using xml_files.first is sufficient
|
144
|
+
doc = ::File.open("#{xml_files.first}") { |f| REXML::Document.new f }
|
145
|
+
locations = doc.elements.each("unattend/servicing/package/source") { |element| puts element.attributes["location"] }
|
146
|
+
locations.each do |loc|
|
147
|
+
cab_files << msu_dir + "/" + loc.attribute("location").value.split("\\")[1]
|
148
|
+
end
|
149
|
+
|
150
|
+
cab_files
|
151
|
+
end
|
152
|
+
cab_files
|
153
|
+
end
|
154
|
+
|
155
|
+
def cleanup_after_converge
|
156
|
+
# delete the temp directory where the contents of msu file are extracted
|
157
|
+
FileUtils.rm_rf(@temp_directory) if Dir.exists?(@temp_directory)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# Author:: Dheeraj Dubey(dheeraj.dubey@msystechnologies.com)
|
2
|
+
# Copyright:: Copyright 2015-2016, Chef Software, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "chef/provider/package"
|
19
|
+
require "chef/resource/powershell_package"
|
20
|
+
require "chef/mixin/powershell_out"
|
21
|
+
|
22
|
+
class Chef
|
23
|
+
class Provider
|
24
|
+
class Package
|
25
|
+
class Powershell < Chef::Provider::Package
|
26
|
+
include Chef::Mixin::PowershellOut
|
27
|
+
|
28
|
+
provides :powershell_package, os: "windows"
|
29
|
+
|
30
|
+
def load_current_resource
|
31
|
+
@current_resource = Chef::Resource::PowershellPackage.new(new_resource.name)
|
32
|
+
current_resource.package_name(new_resource.package_name)
|
33
|
+
current_resource.version(build_current_versions)
|
34
|
+
current_resource
|
35
|
+
end
|
36
|
+
|
37
|
+
def define_resource_requirements
|
38
|
+
super
|
39
|
+
if powershell_out("$PSVersionTable.PSVersion.Major").stdout.strip().to_i < 5
|
40
|
+
raise "Minimum installed Powershell Version required is 5"
|
41
|
+
end
|
42
|
+
requirements.assert(:install) do |a|
|
43
|
+
a.assertion { candidates_exist_for_all_uninstalled? }
|
44
|
+
a.failure_message(Chef::Exceptions::Package, "No candidate version available for #{packages_missing_candidates.join(", ")}")
|
45
|
+
a.whyrun("Assuming a repository that offers #{packages_missing_candidates.join(", ")} would have been configured")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def candidate_version
|
50
|
+
@candidate_version ||= build_candidate_versions
|
51
|
+
end
|
52
|
+
|
53
|
+
# Installs the package specified with the version passed else latest version will be installed
|
54
|
+
def install_package(names, versions)
|
55
|
+
names.each_with_index do |name, index|
|
56
|
+
powershell_out("Install-Package '#{name}' -Force -ForceBootstrap -RequiredVersion #{versions[index]}", { :timeout => @new_resource.timeout })
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Removes the package for the version passed and if no version is passed, then all installed versions of the package are removed
|
61
|
+
def remove_package(names, versions)
|
62
|
+
names.each_with_index do |name, index|
|
63
|
+
if versions && versions[index] != nil
|
64
|
+
powershell_out( "Uninstall-Package '#{name}' -Force -ForceBootstrap -RequiredVersion #{versions[index]}", { :timeout => @new_resource.timeout })
|
65
|
+
else
|
66
|
+
version = "0"
|
67
|
+
until version.empty?
|
68
|
+
version = powershell_out( "(Uninstall-Package '#{name}' -Force -ForceBootstrap | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
|
69
|
+
if !version.empty?
|
70
|
+
Chef::Log.info("Removed package '#{name}' with version #{version}")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns array of available available online
|
78
|
+
def build_candidate_versions
|
79
|
+
versions = []
|
80
|
+
new_resource.package_name.each_with_index do |name, index|
|
81
|
+
if new_resource.version && new_resource.version[index] != nil
|
82
|
+
version = powershell_out("(Find-Package '#{name}' -RequiredVersion #{new_resource.version[index]} -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
|
83
|
+
else
|
84
|
+
version = powershell_out("(Find-Package '#{name}' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
|
85
|
+
end
|
86
|
+
if version.empty?
|
87
|
+
version = nil
|
88
|
+
end
|
89
|
+
versions.push(version)
|
90
|
+
end
|
91
|
+
versions
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns version array of installed version on the system
|
95
|
+
def build_current_versions
|
96
|
+
version_list = []
|
97
|
+
new_resource.package_name.each_with_index do |name, index|
|
98
|
+
if new_resource.version && new_resource.version[index] != nil
|
99
|
+
version = powershell_out("(Get-Package -Name '#{name}' -RequiredVersion #{new_resource.version[index]} -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
|
100
|
+
else
|
101
|
+
version = powershell_out("(Get-Package -Name '#{name}' -ForceBootstrap -Force | select version | Format-Table -HideTableHeaders | Out-String).Trim()", { :timeout => @new_resource.timeout }).stdout.strip()
|
102
|
+
end
|
103
|
+
if version.empty?
|
104
|
+
version = nil
|
105
|
+
end
|
106
|
+
version_list.push(version)
|
107
|
+
end
|
108
|
+
version_list
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|