diff options
author | adamedx <adamed@getchef.com> | 2015-05-22 23:07:16 -0700 |
---|---|---|
committer | adamedx <adamed@getchef.com> | 2015-05-23 14:20:19 -0700 |
commit | 9f242e2af3f32e413cf6fcfabe48d6ebdc03cd80 (patch) | |
tree | bb01bb11ede536824ff74be293d4d7fc394cad1b | |
parent | ac274bc53e30a09182ec4b13d4de9d6d639f422d (diff) | |
download | chef-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.rb | 5 | ||||
-rw-r--r-- | lib/chef/provider/powershell_script.rb | 12 | ||||
-rw-r--r-- | spec/functional/resource/powershell_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/provider/powershell_spec.rb | 64 |
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 |