chef 12.1.2-x86-mingw32 → 12.2.0.rc.1-x86-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 +7 -0
- data/lib/chef/application/client.rb +2 -2
- data/lib/chef/audit/audit_reporter.rb +1 -1
- data/lib/chef/audit/runner.rb +15 -2
- data/lib/chef/client.rb +1 -1
- data/lib/chef/config.rb +6 -4
- data/lib/chef/dsl/powershell.rb +29 -0
- data/lib/chef/exceptions.rb +18 -3
- data/lib/chef/formatters/doc.rb +2 -2
- data/lib/chef/knife/bootstrap.rb +2 -1
- data/lib/chef/knife/bootstrap/templates/chef-full.erb +1 -1
- data/lib/chef/knife/core/subcommand_loader.rb +13 -5
- data/lib/chef/knife/exec.rb +2 -1
- data/lib/chef/knife/ssh.rb +12 -2
- data/lib/chef/mixin/params_validate.rb +42 -19
- data/lib/chef/mixin/powershell_type_coercions.rb +82 -0
- data/lib/chef/mixin/windows_architecture_helper.rb +8 -0
- data/lib/chef/node.rb +1 -1
- data/lib/chef/platform/provider_mapping.rb +0 -107
- data/lib/chef/platform/query_helpers.rb +7 -0
- data/lib/chef/provider/batch.rb +2 -0
- data/lib/chef/provider/cron.rb +2 -0
- data/lib/chef/provider/cron/aix.rb +2 -0
- data/lib/chef/provider/cron/unix.rb +2 -0
- data/lib/chef/provider/deploy.rb +104 -87
- data/lib/chef/provider/dsc_resource.rb +157 -0
- data/lib/chef/provider/env.rb +2 -0
- data/lib/chef/provider/env/windows.rb +2 -0
- data/lib/chef/provider/git.rb +4 -0
- data/lib/chef/provider/group.rb +5 -5
- data/lib/chef/provider/group/dscl.rb +2 -0
- data/lib/chef/provider/group/groupmod.rb +2 -0
- data/lib/chef/provider/group/usermod.rb +2 -0
- data/lib/chef/provider/group/windows.rb +2 -0
- data/lib/chef/provider/mdadm.rb +2 -0
- data/lib/chef/provider/mount/windows.rb +2 -0
- data/lib/chef/provider/package/homebrew.rb +1 -1
- data/lib/chef/provider/package/openbsd.rb +49 -18
- data/lib/chef/provider/package/rubygems.rb +7 -2
- data/lib/chef/provider/powershell_script.rb +2 -0
- data/lib/chef/provider/service/macosx.rb +1 -2
- data/lib/chef/provider/user/dscl.rb +7 -1
- data/lib/chef/provider/user/windows.rb +2 -0
- data/lib/chef/providers.rb +1 -0
- data/lib/chef/recipe.rb +2 -0
- data/lib/chef/resource.rb +9 -0
- data/lib/chef/resource/batch.rb +2 -0
- data/lib/chef/resource/cron.rb +3 -3
- data/lib/chef/resource/deploy.rb +52 -217
- data/lib/chef/resource/dsc_resource.rb +83 -0
- data/lib/chef/resource/env.rb +2 -0
- data/lib/chef/resource/git.rb +1 -1
- data/lib/chef/resource/group.rb +2 -0
- data/lib/chef/resource/homebrew_package.rb +1 -1
- data/lib/chef/resource/lwrp_base.rb +0 -8
- data/lib/chef/resource/mdadm.rb +2 -0
- data/lib/chef/resource/mount.rb +2 -0
- data/lib/chef/resource/powershell_script.rb +2 -0
- data/lib/chef/resource/user.rb +2 -0
- data/lib/chef/resources.rb +1 -0
- data/lib/chef/run_context.rb +1 -1
- data/lib/chef/shell.rb +7 -5
- data/lib/chef/util/dsc/resource_store.rb +110 -0
- data/lib/chef/util/path_helper.rb +76 -0
- data/lib/chef/util/powershell/cmdlet.rb +41 -7
- data/lib/chef/util/powershell/cmdlet_result.rb +18 -3
- data/lib/chef/util/powershell/ps_credential.rb +38 -0
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/api.rb +2 -0
- data/lib/chef/win32/api/crypto.rb +63 -0
- data/lib/chef/win32/api/installer.rb +1 -1
- data/lib/chef/win32/crypto.rb +49 -0
- data/lib/chef/workstation_config_loader.rb +4 -3
- data/spec/functional/file_content_management/deploy_strategies_spec.rb +1 -1
- data/spec/functional/resource/cookbook_file_spec.rb +1 -1
- data/spec/functional/resource/deploy_revision_spec.rb +35 -0
- data/spec/functional/resource/directory_spec.rb +1 -1
- data/spec/functional/resource/dsc_resource_spec.rb +93 -0
- data/spec/functional/resource/env_spec.rb +4 -3
- data/spec/functional/resource/file_spec.rb +1 -1
- data/spec/functional/resource/powershell_spec.rb +2 -1
- data/spec/functional/resource/remote_directory_spec.rb +1 -1
- data/spec/functional/resource/remote_file_spec.rb +1 -1
- data/spec/functional/resource/template_spec.rb +1 -1
- data/spec/functional/resource/user/dscl_spec.rb +1 -2
- data/spec/functional/resource/user/useradd_spec.rb +27 -13
- data/spec/functional/util/powershell/cmdlet_spec.rb +3 -3
- data/spec/functional/win32/crypto_spec.rb +57 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/platform_helpers.rb +14 -0
- data/spec/support/shared/functional/securable_resource_with_reporting.rb +5 -5
- data/spec/unit/application/client_spec.rb +4 -4
- data/spec/unit/audit/audit_reporter_spec.rb +1 -1
- data/spec/unit/audit/runner_spec.rb +10 -0
- data/spec/unit/config_spec.rb +2 -8
- data/spec/unit/knife/bootstrap_spec.rb +20 -8
- data/spec/unit/knife/core/subcommand_loader_spec.rb +29 -29
- data/spec/unit/mixin/params_validate_spec.rb +75 -61
- data/spec/unit/mixin/powershell_type_coercions_spec.rb +72 -0
- data/spec/unit/platform/query_helpers_spec.rb +22 -0
- data/spec/unit/platform_spec.rb +0 -5
- data/spec/unit/provider/dsc_resource_spec.rb +84 -0
- data/spec/unit/provider/package/openbsd_spec.rb +105 -17
- data/spec/unit/provider/service/macosx_spec.rb +3 -3
- data/spec/unit/provider_resolver_spec.rb +132 -0
- data/spec/unit/recipe_spec.rb +4 -0
- data/spec/unit/resource/deploy_spec.rb +27 -0
- data/spec/unit/resource/dsc_resource_spec.rb +85 -0
- data/spec/unit/shell_spec.rb +1 -1
- data/spec/unit/util/dsc/resource_store.rb +76 -0
- data/spec/unit/util/powershell/ps_credential_spec.rb +37 -0
- data/spec/unit/workstation_config_loader_spec.rb +1 -1
- metadata +175 -226
@@ -0,0 +1,83 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Adam Edwards (<adamed@getchef.com>)
|
3
|
+
#
|
4
|
+
# Copyright:: 2014, Opscode, Inc.
|
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
|
+
require 'chef/dsl/powershell'
|
19
|
+
|
20
|
+
class Chef
|
21
|
+
class Resource
|
22
|
+
class DscResource < Chef::Resource
|
23
|
+
|
24
|
+
provides :dsc_resource, os: "windows"
|
25
|
+
|
26
|
+
include Chef::DSL::Powershell
|
27
|
+
|
28
|
+
def initialize(name, run_context)
|
29
|
+
super
|
30
|
+
@properties = {}
|
31
|
+
@resource_name = :dsc_resource
|
32
|
+
@resource = nil
|
33
|
+
@allowed_actions.push(:run)
|
34
|
+
@action = :run
|
35
|
+
end
|
36
|
+
|
37
|
+
def resource(value=nil)
|
38
|
+
if value
|
39
|
+
@resource = value
|
40
|
+
else
|
41
|
+
@resource
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def module_name(value=nil)
|
46
|
+
if value
|
47
|
+
@module_name = value
|
48
|
+
else
|
49
|
+
@module_name
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def property(property_name, value=nil)
|
54
|
+
if not property_name.is_a?(Symbol)
|
55
|
+
raise TypeError, "A property name of type Symbol must be specified, '#{property_name.to_s}' of type #{property_name.class.to_s} was given"
|
56
|
+
end
|
57
|
+
|
58
|
+
if value.nil?
|
59
|
+
value_of(@properties[property_name])
|
60
|
+
else
|
61
|
+
@properties[property_name] = value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def properties
|
66
|
+
@properties.reduce({}) do |memo, (k, v)|
|
67
|
+
memo[k] = value_of(v)
|
68
|
+
memo
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def value_of(value)
|
75
|
+
if value.is_a?(DelayedEvaluator)
|
76
|
+
value.call
|
77
|
+
else
|
78
|
+
value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/chef/resource/env.rb
CHANGED
data/lib/chef/resource/git.rb
CHANGED
data/lib/chef/resource/group.rb
CHANGED
@@ -70,14 +70,6 @@ class Chef
|
|
70
70
|
alias_method :resource_name=, :resource_name
|
71
71
|
end
|
72
72
|
|
73
|
-
# Define an attribute on this resource, including optional validation
|
74
|
-
# parameters.
|
75
|
-
def self.attribute(attr_name, validation_opts={})
|
76
|
-
define_method(attr_name) do |arg=nil|
|
77
|
-
set_or_return(attr_name.to_sym, arg, validation_opts)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
73
|
# Sets the default action
|
82
74
|
def self.default_action(action_name=NULL_ARG)
|
83
75
|
unless action_name.equal?(NULL_ARG)
|
data/lib/chef/resource/mdadm.rb
CHANGED
data/lib/chef/resource/mount.rb
CHANGED
@@ -21,6 +21,8 @@ class Chef
|
|
21
21
|
class Resource
|
22
22
|
class PowershellScript < Chef::Resource::WindowsScript
|
23
23
|
|
24
|
+
provides :powershell_script, os: "windows"
|
25
|
+
|
24
26
|
def initialize(name, run_context=nil)
|
25
27
|
super(name, run_context, :powershell_script, "powershell.exe")
|
26
28
|
@convert_boolean_return = false
|
data/lib/chef/resource/user.rb
CHANGED
data/lib/chef/resources.rb
CHANGED
@@ -29,6 +29,7 @@ require 'chef/resource/deploy_revision'
|
|
29
29
|
require 'chef/resource/directory'
|
30
30
|
require 'chef/resource/dpkg_package'
|
31
31
|
require 'chef/resource/dsc_script'
|
32
|
+
require 'chef/resource/dsc_resource'
|
32
33
|
require 'chef/resource/easy_install_package'
|
33
34
|
require 'chef/resource/env'
|
34
35
|
require 'chef/resource/erl_call'
|
data/lib/chef/run_context.rb
CHANGED
@@ -50,7 +50,7 @@ class Chef
|
|
50
50
|
# recipes, which is triggered by #load. (See also: CookbookCompiler)
|
51
51
|
attr_accessor :resource_collection
|
52
52
|
|
53
|
-
# The list of
|
53
|
+
# The list of control groups to execute during the audit phase
|
54
54
|
attr_accessor :audits
|
55
55
|
|
56
56
|
# A Hash containing the immediate notifications triggered by resources
|
data/lib/chef/shell.rb
CHANGED
@@ -29,6 +29,7 @@ require 'chef/config_fetcher'
|
|
29
29
|
require 'chef/shell/shell_session'
|
30
30
|
require 'chef/shell/ext'
|
31
31
|
require 'chef/json_compat'
|
32
|
+
require 'chef/util/path_helper'
|
32
33
|
|
33
34
|
# = Shell
|
34
35
|
# Shell is Chef in an IRB session. Shell can interact with a Chef server via the
|
@@ -101,7 +102,7 @@ module Shell
|
|
101
102
|
end
|
102
103
|
|
103
104
|
def self.configure_irb
|
104
|
-
irb_conf[:HISTORY_FILE] = "
|
105
|
+
irb_conf[:HISTORY_FILE] = Chef::Util::PathHelper.home(".chef", "chef_shell_history")
|
105
106
|
irb_conf[:SAVE_HISTORY] = 1000
|
106
107
|
|
107
108
|
irb_conf[:IRB_RC] = lambda do |conf|
|
@@ -295,18 +296,19 @@ FOOTER
|
|
295
296
|
private
|
296
297
|
|
297
298
|
def config_file_for_shell_mode(environment)
|
299
|
+
dot_chef_dir = Chef::Util::PathHelper.home('.chef')
|
298
300
|
if config[:config_file]
|
299
301
|
config[:config_file]
|
300
|
-
elsif environment
|
302
|
+
elsif environment
|
301
303
|
Shell.env = environment
|
302
|
-
config_file_to_try = ::File.join(
|
304
|
+
config_file_to_try = ::File.join(dot_chef_dir, environment, 'chef_shell.rb')
|
303
305
|
unless ::File.exist?(config_file_to_try)
|
304
306
|
puts "could not find chef-shell config for environment #{environment} at #{config_file_to_try}"
|
305
307
|
exit 1
|
306
308
|
end
|
307
309
|
config_file_to_try
|
308
|
-
elsif
|
309
|
-
File.join(
|
310
|
+
elsif dot_chef_dir && ::File.exist?(File.join(dot_chef_dir, 'chef_shell.rb'))
|
311
|
+
File.join(dot_chef_dir, 'chef_shell.rb')
|
310
312
|
elsif config[:solo]
|
311
313
|
Chef::Config.platform_specific_path("/etc/chef/solo.rb")
|
312
314
|
elsif config[:client]
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Jay Mundrawala (<jdm@chef.io>)
|
3
|
+
#
|
4
|
+
# Copyright:: Copyright (c) 2015 Chef Software, Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/util/powershell/cmdlet'
|
20
|
+
require 'chef/util/powershell/cmdlet_result'
|
21
|
+
require 'chef/exceptions'
|
22
|
+
|
23
|
+
class Chef
|
24
|
+
class Util
|
25
|
+
class DSC
|
26
|
+
class ResourceStore
|
27
|
+
|
28
|
+
def self.instance
|
29
|
+
@@instance ||= ResourceStore.new.tap do |store|
|
30
|
+
store.send(:populate_cache)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def resources
|
35
|
+
@resources ||= []
|
36
|
+
end
|
37
|
+
|
38
|
+
def find(name, module_name=nil)
|
39
|
+
found = find_resources(name, module_name, resources)
|
40
|
+
|
41
|
+
# We don't have it, query for the resource...it might
|
42
|
+
# have been added since we last queried
|
43
|
+
if found.length == 0
|
44
|
+
rs = query_resource(name)
|
45
|
+
add_resources(rs)
|
46
|
+
found = find_resources(name, module_name, rs)
|
47
|
+
end
|
48
|
+
|
49
|
+
found
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def add_resource(new_r)
|
55
|
+
count = resources.count do |r|
|
56
|
+
r['ResourceType'].casecmp(new_r['ResourceType']) == 0
|
57
|
+
end
|
58
|
+
if count == 0
|
59
|
+
resources << new_r
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_resources(rs)
|
64
|
+
rs.each do |r|
|
65
|
+
add_resource(r)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def populate_cache
|
70
|
+
@resources = query_resources
|
71
|
+
end
|
72
|
+
|
73
|
+
def find_resources(name, module_name, rs)
|
74
|
+
found = rs.find_all do |r|
|
75
|
+
name_matches = r['Name'].casecmp(name) == 0
|
76
|
+
if name_matches
|
77
|
+
module_name == nil || (r['Module'] and r['Module']['Name'].casecmp(module_name) == 0)
|
78
|
+
else
|
79
|
+
false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# Returns a list of dsc resources
|
86
|
+
def query_resources
|
87
|
+
cmdlet = Chef::Util::Powershell::Cmdlet.new(nil, 'get-dscresource',
|
88
|
+
:object)
|
89
|
+
result = cmdlet.run
|
90
|
+
result.return_value
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns a list of dsc resources matching the provided name
|
94
|
+
def query_resource(resource_name)
|
95
|
+
cmdlet = Chef::Util::Powershell::Cmdlet.new(nil, "get-dscresource #{resource_name}",
|
96
|
+
:object)
|
97
|
+
result = cmdlet.run
|
98
|
+
ret_val = result.return_value
|
99
|
+
if ret_val.nil?
|
100
|
+
[]
|
101
|
+
elsif ret_val.is_a? Array
|
102
|
+
ret_val
|
103
|
+
else
|
104
|
+
[ret_val]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -142,6 +142,82 @@ class Chef
|
|
142
142
|
def self.relative_path_from(from, to)
|
143
143
|
pathname = Pathname.new(Chef::Util::PathHelper.cleanpath(to)).relative_path_from(Pathname.new(Chef::Util::PathHelper.cleanpath(from)))
|
144
144
|
end
|
145
|
+
|
146
|
+
# Retrieves the "home directory" of the current user while trying to ascertain the existence
|
147
|
+
# of said directory. The path returned uses / for all separators (the ruby standard format).
|
148
|
+
# If the home directory doesn't exist or an error is otherwise encountered, nil is returned.
|
149
|
+
#
|
150
|
+
# If a set of path elements is provided, they are appended as-is to the home path if the
|
151
|
+
# homepath exists.
|
152
|
+
#
|
153
|
+
# If an optional block is provided, the joined path is passed to that block if the home path is
|
154
|
+
# valid and the result of the block is returned instead.
|
155
|
+
#
|
156
|
+
# Home-path discovery is performed once. If a path is discovered, that value is memoized so
|
157
|
+
# that subsequent calls to home_dir don't bounce around.
|
158
|
+
#
|
159
|
+
# See self.all_homes.
|
160
|
+
def self.home(*args)
|
161
|
+
@@home_dir ||= self.all_homes { |p| break p }
|
162
|
+
if @@home_dir
|
163
|
+
path = File.join(@@home_dir, *args)
|
164
|
+
block_given? ? (yield path) : path
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# See self.home. This method performs a similar operation except that it yields all the different
|
169
|
+
# possible values of 'HOME' that one could have on this platform. Hence, on windows, if
|
170
|
+
# HOMEDRIVE\HOMEPATH and USERPROFILE are different, the provided block will be called twice.
|
171
|
+
# This method goes out and checks the existence of each location at the time of the call.
|
172
|
+
#
|
173
|
+
# The return is a list of all the returned values from each block invocation or a list of paths
|
174
|
+
# if no block is provided.
|
175
|
+
def self.all_homes(*args)
|
176
|
+
paths = []
|
177
|
+
if Chef::Platform.windows?
|
178
|
+
# By default, Ruby uses the the following environment variables to determine Dir.home:
|
179
|
+
# HOME
|
180
|
+
# HOMEDRIVE HOMEPATH
|
181
|
+
# USERPROFILE
|
182
|
+
# Ruby only checks to see if the variable is specified - not if the directory actually exists.
|
183
|
+
# On Windows, HOMEDRIVE HOMEPATH can point to a different location (such as an unavailable network mounted drive)
|
184
|
+
# while USERPROFILE points to the location where the user application settings and profile are stored. HOME
|
185
|
+
# is not defined as an environment variable (usually). If the home path actually uses UNC, then the prefix is
|
186
|
+
# HOMESHARE instead of HOMEDRIVE.
|
187
|
+
#
|
188
|
+
# We instead walk down the following and only include paths that actually exist.
|
189
|
+
# HOME
|
190
|
+
# HOMEDRIVE HOMEPATH
|
191
|
+
# HOMESHARE HOMEPATH
|
192
|
+
# USERPROFILE
|
193
|
+
|
194
|
+
paths << ENV['HOME']
|
195
|
+
paths << ENV['HOMEDRIVE'] + ENV['HOMEPATH'] if ENV['HOMEDRIVE'] && ENV['HOMEPATH']
|
196
|
+
paths << ENV['HOMESHARE'] + ENV['HOMEPATH'] if ENV['HOMESHARE'] && ENV['HOMEPATH']
|
197
|
+
paths << ENV['USERPROFILE']
|
198
|
+
end
|
199
|
+
paths << Dir.home
|
200
|
+
|
201
|
+
# Depending on what environment variables we're using, the slashes can go in any which way.
|
202
|
+
# Just change them all to / to keep things consistent.
|
203
|
+
# Note: Maybe this is a bad idea on some unixy systems where \ might be a valid character depending on
|
204
|
+
# the particular brand of kool-aid you consume. This code assumes that \ and / are both
|
205
|
+
# path separators on any system being used.
|
206
|
+
paths = paths.map { |home_path| home_path.gsub(path_separator, ::File::SEPARATOR) if home_path }
|
207
|
+
|
208
|
+
# Filter out duplicate paths and paths that don't exist.
|
209
|
+
valid_paths = paths.select { |home_path| home_path && Dir.exists?(home_path) }
|
210
|
+
valid_paths = valid_paths.uniq
|
211
|
+
|
212
|
+
# Join all optional path elements at the end.
|
213
|
+
# If a block is provided, invoke it - otherwise just return what we've got.
|
214
|
+
joined_paths = valid_paths.map { |home_path| File.join(home_path, *args) }
|
215
|
+
if block_given?
|
216
|
+
joined_paths.each { |p| yield p }
|
217
|
+
else
|
218
|
+
joined_paths
|
219
|
+
end
|
220
|
+
end
|
145
221
|
end
|
146
222
|
end
|
147
223
|
end
|
@@ -20,7 +20,9 @@ require 'mixlib/shellout'
|
|
20
20
|
require 'chef/mixin/windows_architecture_helper'
|
21
21
|
require 'chef/util/powershell/cmdlet_result'
|
22
22
|
|
23
|
-
class Chef
|
23
|
+
class Chef
|
24
|
+
class Util
|
25
|
+
class Powershell
|
24
26
|
class Cmdlet
|
25
27
|
def initialize(node, cmdlet, output_format=nil, output_format_options={})
|
26
28
|
@output_format = output_format
|
@@ -46,6 +48,10 @@ class Chef::Util::Powershell
|
|
46
48
|
attr_reader :output_format
|
47
49
|
|
48
50
|
def run(switches={}, execution_options={}, *arguments)
|
51
|
+
streams = { :json => CmdletStream.new('json'),
|
52
|
+
:verbose => CmdletStream.new('verbose'),
|
53
|
+
}
|
54
|
+
|
49
55
|
arguments_string = arguments.join(' ')
|
50
56
|
|
51
57
|
switches_string = command_switches_string(switches)
|
@@ -56,21 +62,25 @@ class Chef::Util::Powershell
|
|
56
62
|
json_depth = @output_format_options[:depth]
|
57
63
|
end
|
58
64
|
|
59
|
-
json_command = @json_format ? " | convertto-json -compress -depth #{json_depth}
|
60
|
-
|
65
|
+
json_command = @json_format ? " | convertto-json -compress -depth #{json_depth} "\
|
66
|
+
"> #{streams[:json].path}" : ""
|
67
|
+
redirections = "4> '#{streams[:verbose].path}'"
|
68
|
+
command_string = "powershell.exe -executionpolicy bypass -noprofile -noninteractive "\
|
69
|
+
"-command \"trap [Exception] {write-error -exception "\
|
70
|
+
"($_.Exception.Message);exit 1};#{@cmdlet} #{switches_string} "\
|
71
|
+
"#{arguments_string} #{redirections}"\
|
72
|
+
"#{json_command}\";if ( ! $? ) { exit 1 }"
|
61
73
|
|
62
74
|
augmented_options = {:returns => [0], :live_stream => false}.merge(execution_options)
|
63
75
|
command = Mixlib::ShellOut.new(command_string, augmented_options)
|
64
76
|
|
65
|
-
os_architecture = "#{ENV['PROCESSOR_ARCHITEW6432']}" == 'AMD64' ? :x86_64 : :i386
|
66
|
-
|
67
77
|
status = nil
|
68
78
|
|
69
79
|
with_os_architecture(@node) do
|
70
80
|
status = command.run_command
|
71
81
|
end
|
72
82
|
|
73
|
-
CmdletResult.new(status, @output_format)
|
83
|
+
CmdletResult.new(status, streams, @output_format)
|
74
84
|
end
|
75
85
|
|
76
86
|
def run!(switches={}, execution_options={}, *arguments)
|
@@ -131,6 +141,30 @@ class Chef::Util::Powershell
|
|
131
141
|
|
132
142
|
command_switches.join(' ')
|
133
143
|
end
|
144
|
+
|
145
|
+
class CmdletStream
|
146
|
+
def initialize(name)
|
147
|
+
@filename = Dir::Tmpname.create(name) {}
|
148
|
+
ObjectSpace.define_finalizer(self, self.class.destroy(@filename))
|
149
|
+
end
|
150
|
+
|
151
|
+
def path
|
152
|
+
@filename
|
153
|
+
end
|
154
|
+
|
155
|
+
def read
|
156
|
+
if File.exist? @filename
|
157
|
+
File.open(@filename, 'rb:bom|UTF-16LE') do |f|
|
158
|
+
f.read.encode('UTF-8')
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.destroy(name)
|
164
|
+
proc { File.delete(name) if File.exists? name }
|
165
|
+
end
|
166
|
+
end
|
134
167
|
end
|
135
168
|
end
|
136
|
-
|
169
|
+
end
|
170
|
+
end
|