11require 'puppet/provider/exec'
2+ require 'ruby-pwsh'
23
34Puppet ::Type . type ( :exec ) . provide :pwsh , :parent => Puppet ::Provider ::Exec do
45 desc <<-EOT
1718 def run ( command , check = false )
1819 @pwsh ||= get_pwsh_command
1920 self . fail 'pwsh could not be found' if @pwsh . nil?
20- if PuppetX :: PowerShell :: PowerShellManager . supported_on_pwsh ?
21- return ps_manager . execute_resource ( command , resource )
21+ if Pwsh :: Manager . pwsh_supported ?
22+ return execute_resource ( command , resource )
2223 else
2324 write_script ( command ) do |native_path |
2425 # Ideally, we could keep a handle open on the temp file in this
@@ -49,35 +50,11 @@ def validatecmd(command)
4950 #
5051 # @return [String] the absolute path to the found pwsh executable. Returns nil when it does not exist
5152 def get_pwsh_command
52- if Puppet ::Util ::Platform . windows?
53- # Environment variables on Windows are not case sensitive however ruby hash keys are.
54- # Convert all the key names to upcase so we can be sure to find PATH etc.
55- # Also while ruby can have difficulty changing the case of some UTF8 characters, we're
56- # only going to use plain ASCII names so this is safe.
57- current_env = Hash [ Puppet ::Util . get_environment . map { |k , v | [ k . upcase , v ] } ]
58- else
59- # We don't force a case change on non-Windows platforms because it is perfectly
60- # ok to have 'Path' and 'PATH'
61- current_env = Puppet ::Util . get_environment
62- end
6353 # If the resource specifies a search path use that. Otherwise use the default
6454 # PATH from the environment.
65- search_paths = @resource . nil? || @resource [ 'path' ] . nil? ?
66- current_env [ 'PATH' ] :
67- resource [ :path ] . join ( File ::PATH_SEPARATOR )
68-
69- # If we're on Windows, try the default installation locations as a last resort.
70- # https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows?view=powershell-6#msi
71- if Puppet ::Util ::Platform . windows?
72- search_paths += ";#{ current_env [ 'PROGRAMFILES' ] } \\ PowerShell\\ 6" +
73- ";#{ current_env [ 'PROGRAMFILES(X86)' ] } \\ PowerShell\\ 6"
74- end
75-
76- # Note that just like when we run the command in Puppet::Provider::Exec, the
77- # resource[:path] replaces the PATH, it doesn't add to it.
78- Puppet ::Util . withenv ( { 'PATH' => search_paths } , Puppet ::Util . default_env ) do
79- return Puppet ::Util . which ( 'pwsh' )
80- end
55+ @resource . nil? || @resource [ 'path' ] . nil? ?
56+ Pwsh ::Manager . pwsh_path :
57+ Pwsh ::Manager . pwsh_path ( resource [ :path ] )
8158 end
8259
8360 def pwsh_args
@@ -89,10 +66,35 @@ def pwsh_args
8966 # Retrieves the PowerShell manager specific to our pwsh binary in this resource
9067 #
9168 # @api private
92- # @return [PuppetX::PowerShell::PowerShellManager ] The PowerShell manager for this resource
69+ # @return [Pwsh::Manager ] The PowerShell manager for this resource
9370 def ps_manager
9471 debug_output = Puppet ::Util ::Log . level == :debug
95- PuppetX ::PowerShell ::PowerShellManager . instance ( @pwsh , pwsh_args , debug : debug_output )
72+ Pwsh ::Manager . instance ( @pwsh , pwsh_args , debug : debug_output )
73+ end
74+
75+ def execute_resource ( powershell_code , resource )
76+ working_dir = resource [ :cwd ]
77+ if ( !working_dir . nil? )
78+ fail "Working directory '#{ working_dir } ' does not exist" unless File . directory? ( working_dir )
79+ end
80+ timeout_ms = resource [ :timeout ] . nil? ? nil : resource [ :timeout ] * 1000
81+ environment_variables = resource [ :environment ] . nil? ? [ ] : resource [ :environment ]
82+
83+ result = ps_manager . execute ( powershell_code , timeout_ms , working_dir , environment_variables )
84+ stdout = result [ :stdout ]
85+ native_out = result [ :native_stdout ]
86+ stderr = result [ :stderr ]
87+ exit_code = result [ :exitcode ]
88+
89+ unless stderr . nil?
90+ stderr . each { |e | Puppet . debug "STDERR: #{ e . chop } " unless e . empty? }
91+ end
92+
93+ Puppet . debug "STDERR: #{ result [ :errormessage ] } " unless result [ :errormessage ] . nil?
94+
95+ output = Puppet ::Util ::Execution ::ProcessOutput . new ( stdout . to_s + native_out . to_s , exit_code )
96+
97+ return output , output
9698 end
9799
98100 def write_script ( content , &block )
0 commit comments