diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index b456bed0..befd5389 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,19 +1,20 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2019-10-18 11:01:56 -0500 using RuboCop version 0.49.1. +# on 2019-10-29 17:24:12 -0500 using RuboCop version 0.49.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 4 +# Offense count: 6 GetText/DecorateFunctionMessage: Exclude: - 'lib/puppet/provider/exec/powershell.rb' - 'lib/puppet/provider/exec/pwsh.rb' - 'spec/spec_helper_acceptance.rb' -# Offense count: 1 +# Offense count: 3 GetText/DecorateString: Exclude: - 'lib/puppet/provider/exec/powershell.rb' + - 'lib/puppet/provider/exec/pwsh.rb' diff --git a/lib/puppet/provider/exec/powershell.rb b/lib/puppet/provider/exec/powershell.rb index 6eeb2b4a..0eae38e7 100644 --- a/lib/puppet/provider/exec/powershell.rb +++ b/lib/puppet/provider/exec/powershell.rb @@ -1,11 +1,13 @@ require 'puppet/provider/exec' -require 'ruby-pwsh' +begin + require 'ruby-pwsh' +rescue LoadError + raise 'Could not load the "ruby-pwsh" library; is the module puppetlabs-pwshlib installed in this environment?' +end Puppet::Type.type(:exec).provide :powershell, :parent => Puppet::Provider::Exec do confine :operatingsystem => :windows - commands :powershell => Pwsh::Manager.powershell_path - desc <<-EOT Executes Powershell commands. One of the `onlyif`, `unless`, or `creates` parameters should be specified to ensure the command is idempotent. @@ -42,19 +44,24 @@ have .NET Framework 3.5 installed. UPGRADE - def self.upgrade_message + def get_powershell_command + defined?(Pwsh::Manager.powershell_path) ? Pwsh::Manager.powershell_path : nil + end + + def upgrade_message Puppet.warning POWERSHELL_MODULE_UPGRADE_MSG if !@upgrade_warning_issued @upgrade_warning_issued = true end def ps_manager debug_output = Puppet::Util::Log.level == :debug - Pwsh::Manager.instance(command(:powershell), Pwsh::Manager.powershell_args, debug: debug_output) + Pwsh::Manager.instance(@powershell_command, Pwsh::Manager.powershell_args, debug: debug_output) end def run(command, check = false) + @powershell_command ||= get_powershell_command unless Pwsh::Manager.windows_powershell_supported? - self.class.upgrade_message + upgrade_message write_script(command) do |native_path| # Ideally, we could keep a handle open on the temp file in this # process (to prevent TOCTOU attacks), and execute powershell @@ -64,7 +71,7 @@ def run(command, check = false) # we redirect powershell's stdin to read from the file. Current # versions of Windows use per-user temp directories with strong # permissions, but I'd rather not make (poor) assumptions. - return super("cmd.exe /c \"\"#{native_path(command(:powershell))}\" #{legacy_args} -Command - < \"#{native_path}\"\"", check) + return super("cmd.exe /c \"\"#{native_path(@powershell_command)}\" #{legacy_args} -Command - < \"#{native_path}\"\"", check) end else return execute_resource(command, resource) diff --git a/lib/puppet/provider/exec/pwsh.rb b/lib/puppet/provider/exec/pwsh.rb index 395f5b6a..1156d690 100644 --- a/lib/puppet/provider/exec/pwsh.rb +++ b/lib/puppet/provider/exec/pwsh.rb @@ -1,5 +1,9 @@ require 'puppet/provider/exec' -require 'ruby-pwsh' +begin + require 'ruby-pwsh' +rescue LoadError + raise 'Could not load the "ruby-pwsh" library; is the module puppetlabs-pwshlib installed in this environment?' +end Puppet::Type.type(:exec).provide :pwsh, :parent => Puppet::Provider::Exec do desc <<-EOT diff --git a/spec/unit/provider/exec/powershell_spec.rb b/spec/unit/provider/exec/powershell_spec.rb index 41d67622..1c431476 100644 --- a/spec/unit/provider/exec/powershell_spec.rb +++ b/spec/unit/provider/exec/powershell_spec.rb @@ -48,6 +48,12 @@ provider.run_spec_override(command) end + it "should raise an upgrade message warning" do + Puppet::Type::Exec::ProviderPowershell.any_instance.expects(:upgrade_message).once + + provider.run_spec_override(command) + end + context "on windows", :if => Puppet.features.microsoft_windows? do it "should call cmd.exe /c" do Puppet::Type::Exec::ProviderPowershell.any_instance.expects(:run) @@ -84,6 +90,7 @@ context "actual runs" do context "on Windows", :if => Puppet.features.microsoft_windows? do + it "returns the output and status" do output, status = provider.run(command) @@ -156,80 +163,4 @@ end end end - - describe 'when applying a catalog' do - let(:manifest) { <<-MANIFEST - exec { 'PS': - command => 'exit 0', - provider => powershell, - } - MANIFEST - } - let(:tmpdir) { Dir.mktmpdir('statetmp').encode!(Encoding::UTF_8) } - - before :each do - skip('Not on Windows platform') unless Puppet.features.microsoft_windows? - # a statedir setting must now exist per the new transactionstore code - # introduced in Puppet 4.6 for corrective changes, as a new YAML file - # called transactionstore.yaml will be written under this path - # which defaults to c:\dev\null when not set on Windows - Puppet[:statedir] = tmpdir - end - - after :each do - FileUtils.rm_rf(tmpdir) - end - - def compile_to_catalog(string, node = Puppet::Node.new('foonode')) - Puppet[:code] = string - - # see lib/puppet/indirector/catalog/compiler.rb#filter - Puppet::Parser::Compiler.compile(node).filter { |r| r.virtual? } - end - - def compile_to_ral(manifest) - catalog = compile_to_catalog(manifest) - ral = catalog.to_ral - ral.finalize - ral - end - - def apply_compiled_manifest(manifest) - catalog = compile_to_ral(manifest) - - # ensure compilation works from Puppet 3.0.0 forward - args = [catalog, Puppet::Transaction::Report.new('apply')] - args << Puppet::Graph::SequentialPrioritizer.new if defined?(Puppet::Graph) - transaction = Puppet::Transaction.new(*args) - transaction.evaluate - transaction.report.finalize_report - - transaction - end - - it 'does not emit a warning message when PowerShellManager is usable in a Windows environment' do - - Pwsh::Manager.stubs(:win32console_enabled?).returns(false) - - expect(Pwsh::Manager.windows_powershell_supported?).to eq(true) - - # given PowerShellManager is supported, never emit an upgrade message - Puppet::Type::Exec::ProviderPowershell.expects(:upgrade_message).never - - apply_compiled_manifest(manifest) - end - - it 'emits a warning message when PowerShellManager cannot be used in a Windows environment' do - - # pretend we're Ruby 1.9.3 / Puppet 3.x x86 - Pwsh::Manager.stubs(:win32console_enabled?).returns(true) - - expect(Pwsh::Manager.windows_powershell_supported?).to eq(false) - - # given PowerShellManager is NOT supported, emit an upgrade message - Puppet::Type::Exec::ProviderPowershell.expects(:upgrade_message).once - - apply_compiled_manifest(manifest) - end - end end