summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoradamedx <adamed@getchef.com>2015-05-22 23:07:16 -0700
committeradamedx <adamed@getchef.com>2015-05-23 14:20:19 -0700
commit9f242e2af3f32e413cf6fcfabe48d6ebdc03cd80 (patch)
treebb01bb11ede536824ff74be293d4d7fc394cad1b
parentac274bc53e30a09182ec4b13d4de9d6d639f422d (diff)
downloadchef-adamedx/x-powershell-exitstatus.tar.gz
Use executionpolicy Bypass in powershell_script provider for PS 3.0 and lateradamedx/x-powershell-exitstatus
-rw-r--r--lib/chef/platform/query_helpers.rb5
-rw-r--r--lib/chef/provider/powershell_script.rb12
-rw-r--r--spec/functional/resource/powershell_spec.rb2
-rw-r--r--spec/unit/provider/powershell_spec.rb64
4 files changed, 68 insertions, 15 deletions
diff --git a/lib/chef/platform/query_helpers.rb b/lib/chef/platform/query_helpers.rb
index 03b1c9ca1e..b3948eac21 100644
--- a/lib/chef/platform/query_helpers.rb
+++ b/lib/chef/platform/query_helpers.rb
@@ -39,6 +39,11 @@ class Chef
is_server_2003
end
+ def supports_powershell_execution_bypass?(node)
+ node[:languages] && node[:languages][:powershell] &&
+ node[:languages][:powershell][:version].to_i >= 3
+ end
+
def supports_dsc?(node)
node[:languages] && node[:languages][:powershell] &&
node[:languages][:powershell][:version].to_i >= 4
diff --git a/lib/chef/provider/powershell_script.rb b/lib/chef/provider/powershell_script.rb
index 3b86e2a5de..ed44dee6ae 100644
--- a/lib/chef/provider/powershell_script.rb
+++ b/lib/chef/provider/powershell_script.rb
@@ -26,7 +26,7 @@ class Chef
def initialize (new_resource, run_context)
super(new_resource, run_context, '.ps1')
- normalize_script_exit_status
+ add_exit_status_wrapper
end
def action_run
@@ -53,7 +53,7 @@ class Chef
# Process exit codes are strange with PowerShell and require
# special handling to cover common use cases.
- def normalize_script_exit_status
+ def add_exit_status_wrapper
self.code = wrapper_script
Chef::Log.debug("powershell_script provider called with script code:\n\n#{@new_resource.code}\n")
Chef::Log.debug("powershell_script provider will execute transformed code:\n\n#{self.code}\n")
@@ -82,11 +82,17 @@ class Chef
end
def default_interpreter_flags
+ # 'Bypass' is preferable since it doesn't require user input confirmation
+ # for files such as PowerShell modules downloaded from the
+ # Internet. However, 'Bypass' is not supported prior to
+ # PowerShell 3.0, so the fallback is 'Unrestricted'
+ execution_policy = Chef::Platform.supports_powershell_execution_bypass?(run_context.node) ? 'Bypass' : 'Unrestricted'
+
[
"-NoLogo",
"-NonInteractive",
"-NoProfile",
- "-ExecutionPolicy Unrestricted",
+ "-ExecutionPolicy #{execution_policy}",
# Powershell will hang if STDIN is redirected
# http://connect.microsoft.com/PowerShell/feedback/details/572313/powershell-exe-can-hang-if-stdin-is-redirected
"-InputFormat None"
diff --git a/spec/functional/resource/powershell_spec.rb b/spec/functional/resource/powershell_spec.rb
index b76e75782f..17ae8cbd2a 100644
--- a/spec/functional/resource/powershell_spec.rb
+++ b/spec/functional/resource/powershell_spec.rb
@@ -134,7 +134,7 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
it "returns 1 if the script provided to the code attribute is not syntactically correct" do
resource.code('if({)')
resource.returns(1)
- resource.run_action(:run)
+ expect { resource.run_action(:run) }.not_to raise_error
end
# This somewhat ambiguous case, two failures of different types,
diff --git a/spec/unit/provider/powershell_spec.rb b/spec/unit/provider/powershell_spec.rb
index 60dbcf80b0..855c18af9b 100644
--- a/spec/unit/provider/powershell_spec.rb
+++ b/spec/unit/provider/powershell_spec.rb
@@ -19,20 +19,62 @@
require 'spec_helper'
describe Chef::Provider::PowershellScript, "action_run" do
- before(:each) do
- @node = Chef::Node.new
+ let(:powershell_version) { nil }
+ let(:node) {
+ node = Chef::Node.new
+ node.default["kernel"] = Hash.new
+ node.default["kernel"][:machine] = :x86_64.to_s
+ if ! powershell_version.nil?
+ node.default[:languages] = { :powershell => { :version => powershell_version } }
+ end
+ node
+ }
- @node.default["kernel"] = Hash.new
- @node.default["kernel"][:machine] = :x86_64.to_s
+ let(:provider) {
+ empty_events = Chef::EventDispatch::Dispatcher.new
+ run_context = Chef::RunContext.new(node, {}, empty_events)
+ new_resource = Chef::Resource::PowershellScript.new('run some powershell code', run_context)
+ Chef::Provider::PowershellScript.new(new_resource, run_context)
+ }
- @run_context = Chef::RunContext.new(@node, {}, @events)
- @new_resource = Chef::Resource::PowershellScript.new('run some powershell code', @run_context)
+ context 'when setting interpreter flags' do
+ it "should set the -File flag as the last flag" do
+ expect(provider.flags.split(' ').pop).to eq("-File")
+ end
- @provider = Chef::Provider::PowershellScript.new(@new_resource, @run_context)
- end
+ let(:execution_policy_flag) do
+ execution_policy_index = 0
+ provider_flags = provider.flags.split(' ')
+ execution_policy_specified = false
- it "should set the -File flag as the last flag" do
- expect(@provider.flags.split(' ').pop).to eq("-File")
- end
+ provider_flags.find do | value |
+ execution_policy_index += 1
+ execution_policy_specified = value.downcase == '-ExecutionPolicy'.downcase
+ end
+
+ execution_policy = execution_policy_specified ? provider_flags[execution_policy_index] : nil
+ end
+ context 'when running with an unspecified PowerShell version' do
+ let(:powershell_version) { nil }
+ it "should set the -ExecutionPolicy flag to 'Unrestricted' by default" do
+ expect(execution_policy_flag.downcase).to eq('unrestricted'.downcase)
+ end
+ end
+
+ { '2.0' => 'Unrestricted',
+ '2.5' => 'Unrestricted',
+ '3.0' => 'Bypass',
+ '3.6' => 'Bypass',
+ '4.0' => 'Bypass',
+ '5.0' => 'Bypass' }.each do | version_policy |
+ let(:powershell_version) { version_policy[0].to_f }
+ context "when running PowerShell version #{version_policy[0]}" do
+ let(:powershell_version) { version_policy[0].to_f }
+ it "should set the -ExecutionPolicy flag to '#{version_policy[1]}'" do
+ expect(execution_policy_flag.downcase).to eq(version_policy[1].downcase)
+ end
+ end
+ end
+ end
end