class WinRM::Shells::Base
Base
class for remote shell
Constants
- ERROR_OPERATION_ABORTED
- FAULTS_FOR_RESET
- SHELL_NOT_FOUND
- TOO_MANY_COMMANDS
Attributes
@return [ConnectionOpts] connection options of the shell
@return [Logger] logger used for diagnostic messages
@return [String] shell id of the currently opn shell or nil if shell is closed
@return [Hash] Options targeted for the created shell
@return [String] uri that SOAP calls use to identify shell type
@return [WinRM::HTTP::HttpTransport] transport used to talk with endpoint
Public Class Methods
Source
# File lib/winrm/shells/base.rb, line 97 def self.finalize(connection_opts, transport, shell_id) proc { Thread.new { close_shell(connection_opts, transport, shell_id) } } end
Source
# File lib/winrm/shells/base.rb, line 46 def initialize(connection_opts, transport, logger, shell_opts = {}) @connection_opts = connection_opts @transport = transport @logger = logger @shell_opts = shell_opts end
Create a new Cmd
shell @param connection_opts
[ConnectionOpts] The WinRM
connection options @param transport [HttpTransport] The WinRM
SOAP transport @param logger [Logger] The logger to log diagnostic messages to @param shell_opts
[Hash] Options targeted for the created shell
Public Instance Methods
Source
# File lib/winrm/shells/base.rb, line 85 def close return unless shell_id begin self.class.close_shell(connection_opts, transport, shell_id) rescue WinRMWSManFault => e raise unless [ERROR_OPERATION_ABORTED, SHELL_NOT_FOUND].include?(e.fault_code) end remove_finalizer @shell_id = nil end
Closes the shell if one is open
Source
# File lib/winrm/shells/base.rb, line 78 def run(command, arguments = [], &block) with_command_shell(command, arguments) do |shell, cmd| response_reader.read_output(command_output_message(shell, cmd), &block) end end
Runs the specified command with optional arguments @param command [String] The command or executable to run @param arguments [Array] The optional command arguments @param block [&block] The optional callback for any realtime output @yieldparam [string] standard out response text @yieldparam [string] standard error response text @yieldreturn [WinRM::Output] The command output
Protected Instance Methods
Source
# File lib/winrm/shells/base.rb, line 119 def command_output_message(shell_id, command_id) cmd_out_opts = { shell_id: shell_id, command_id: command_id, shell_uri: shell_uri, out_streams: out_streams } WinRM::WSMV::CommandOutput.new(connection_opts, cmd_out_opts) end
Source
# File lib/winrm/shells/base.rb, line 111 def open_shell raise NotImplementedError end
Source
# File lib/winrm/shells/base.rb, line 115 def out_streams raise NotImplementedError end
Source
# File lib/winrm/shells/base.rb, line 107 def response_reader raise NotImplementedError end
Source
# File lib/winrm/shells/base.rb, line 103 def send_command(_command, _arguments) raise NotImplementedError end
Source
# File lib/winrm/shells/base.rb, line 129 def with_command_shell(command, arguments = []) tries ||= 2 open unless shell_id command_id = send_command(command, arguments) logger.debug("[WinRM] creating command_id: #{command_id} on shell_id #{shell_id}") yield shell_id, command_id rescue WinRMWSManFault => e raise unless FAULTS_FOR_RESET.include?(e.fault_code) && (tries -= 1) > 0 reset_on_error(e) retry ensure cleanup_command(command_id) if command_id end
Private Instance Methods
Source
# File lib/winrm/shells/base.rb, line 180 def add_finalizer ObjectSpace.define_finalizer( self, self.class.finalize(connection_opts, transport, shell_id) ) end
Source
# File lib/winrm/shells/base.rb, line 153 def cleanup_command(command_id) return unless shell_id logger.debug("[WinRM] cleaning up command_id: #{command_id} on shell_id #{shell_id}") cleanup_msg = WinRM::WSMV::CleanupCommand.new( connection_opts, shell_uri: shell_uri, shell_id: shell_id, command_id: command_id ) transport.send_request(cleanup_msg.build) rescue WinRMWSManFault => e raise unless [ERROR_OPERATION_ABORTED, SHELL_NOT_FOUND].include?(e.fault_code) rescue WinRMHTTPTransportError => t # dont let the cleanup raise so we dont lose any errors from the command logger.info("[WinRM] #{t.status_code} returned in cleanup with error: #{t.message}") end
Source
# File lib/winrm/shells/base.rb, line 170 def open close retryable(connection_opts[:retry_limit], connection_opts[:retry_delay]) do logger.debug("[WinRM] opening remote shell on #{connection_opts[:endpoint]}") @shell_id = open_shell end logger.debug("[WinRM] remote shell created with shell_id: #{shell_id}") add_finalizer end
Source
# File lib/winrm/shells/base.rb, line 187 def remove_finalizer ObjectSpace.undefine_finalizer(self) end
Source
# File lib/winrm/shells/base.rb, line 147 def reset_on_error(error) close if error.fault_code == TOO_MANY_COMMANDS logger.debug('[WinRM] opening new shell since the current one was deleted') @shell_id = nil end