Module: ChefPowerShell::PowerShell::PowerMod

Extended by:
FFI::Library
Defined in:
lib/chef-powershell/powershell.rb

Constant Summary collapse

StoreResultCallback =
FFI::Function.new(:bool, %i{pointer size_t}) do |data, size|
  # try parsing the result *first* before returning from the function, and if it fails,
  # return false so that the function can be retried from the C++ side.
  @result_string = data.get_bytes(0, size).force_encoding("UTF-16LE").encode("UTF-8")
  @hashed_outcome = FFI_Yajl::Parser.parse(@result_string)
  @result = FFI_Yajl::Parser.parse(@hashed_outcome["result"])
  @errors = @hashed_outcome["errors"]
  @verbose = @hashed_outcome["verbose"]
  true
rescue NoMethodError, FFI_Yajl::ParseError => e
  @retry_count += 1
  # capture exception so that it can be raised later, since otherwise
  # we will be raising back to C++.
  @exception = e
  return true if @retry_count > 3

  puts "Retrying PowerShell command execution #{@retry_count}"
  sleep 1
  false
rescue => e
  # no retry for other exceptions
  @exception = e
  true
end
@@powershell_dll =

FFI requires attaching to modules, not classes, so we need to have a module here. The module level variables could be refactored out here, but still 100% of the work still goes through the module. @@powershell_dll = Gem.loaded_specs.full_gem_path + “/bin/ruby_bin_folder/#"PROCESSOR_ARCHITECTURE"/Chef.PowerShell.Wrapper.dll” NOTE: Previously this line called self.resolve_wrapper_dll at class definition time, but no such method exists inside this module (it’s defined on the outer PowerShell class), leading to NoMethodError during require. We now lazy-resolve through a delegator.

nil
@@ps_command =
""
@@ps_timeout =
-1

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.errorsObject

Returns the value of attribute errors.



103
104
105
# File 'lib/chef-powershell/powershell.rb', line 103

def errors
  @errors
end

.exceptionObject

Returns the value of attribute exception.



103
104
105
# File 'lib/chef-powershell/powershell.rb', line 103

def exception
  @exception
end

.hashed_outcomeObject

Returns the value of attribute hashed_outcome.



103
104
105
# File 'lib/chef-powershell/powershell.rb', line 103

def hashed_outcome
  @hashed_outcome
end

.resultObject

Returns the value of attribute result.



103
104
105
# File 'lib/chef-powershell/powershell.rb', line 103

def result
  @result
end

.result_stringObject

Returns the value of attribute result_string.



103
104
105
# File 'lib/chef-powershell/powershell.rb', line 103

def result_string
  @result_string
end

.retry_countObject

Returns the value of attribute retry_count.



103
104
105
# File 'lib/chef-powershell/powershell.rb', line 103

def retry_count
  @retry_count
end

.verboseObject

Returns the value of attribute verbose.



103
104
105
# File 'lib/chef-powershell/powershell.rb', line 103

def verbose
  @verbose
end

Class Method Details

.do_workObject



160
161
162
163
164
165
166
167
168
# File 'lib/chef-powershell/powershell.rb', line 160

def self.do_work
  @exception = nil
  @retry_count = 0
  ensure_ps_dll unless @@powershell_dll
  ffi_lib @@powershell_dll
  attach_function :execute_powershell, :ExecuteScript, %i{string int pointer}, :pointer

  execute_powershell(@@ps_command, @@ps_timeout, StoreResultCallback)
end

.ensure_ps_dllObject

Resolve DLL via outer class method; cache the result



148
149
150
# File 'lib/chef-powershell/powershell.rb', line 148

def self.ensure_ps_dll
  @@powershell_dll ||= ChefPowerShell::PowerShell.resolve_wrapper_dll
end

.set_ps_command(value) ⇒ Object



152
153
154
# File 'lib/chef-powershell/powershell.rb', line 152

def self.set_ps_command(value)
  @@ps_command = value
end

.set_ps_dll(value) ⇒ Object



143
144
145
# File 'lib/chef-powershell/powershell.rb', line 143

def self.set_ps_dll(value)
  @@powershell_dll = value
end

.set_ps_timeout(value) ⇒ Object



156
157
158
# File 'lib/chef-powershell/powershell.rb', line 156

def self.set_ps_timeout(value)
  @@ps_timeout = value
end