Class: Proxy::RemoteExecution::Ssh::Session
- Inherits:
-
Dynflow::Actor
- Object
- Dynflow::Actor
- Proxy::RemoteExecution::Ssh::Session
- Defined in:
- lib/smart_proxy_remote_execution_ssh_core/session.rb
Overview
Service that handles running external commands for Actions::Command Dynflow action. It runs just one (actor) thread for all the commands running in the system and updates the Dynflow actions periodically.
Constant Summary collapse
- EXPECTED_POWER_ACTION_MESSAGES =
["restart host", "shutdown host"]
Instance Method Summary collapse
- #dispatcher ⇒ Object
- #finish_command ⇒ Object
-
#initialize(options = {}) ⇒ Session
constructor
A new instance of Session.
- #initialize_command ⇒ Object
- #kill ⇒ Object
- #refresh ⇒ Object
- #refresh_command_buffer ⇒ Object
- #start_termination(*args) ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Session
Returns a new instance of Session.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/smart_proxy_remote_execution_ssh_core/session.rb', line 10 def initialize( = {}) @clock = [:clock] || Dynflow::Clock.spawn('proxy-dispatcher-clock') @logger = [:logger] || Logger.new($stderr) @connector_class = [:connector_class] || Connector @local_working_dir = [:local_working_dir] || Settings.instance.local_working_dir @remote_working_dir = [:remote_working_dir] || Settings.instance.remote_working_dir @refresh_interval = [:refresh_interval] || 1 @client_private_key_file = Settings.instance.ssh_identity_key_file @command = [:command] @command_buffer = [] @refresh_planned = false reference.tell(:initialize_command) end |
Instance Method Details
#dispatcher ⇒ Object
105 106 107 |
# File 'lib/smart_proxy_remote_execution_ssh_core/session.rb', line 105 def dispatcher self.parent end |
#finish_command ⇒ Object
100 101 102 103 |
# File 'lib/smart_proxy_remote_execution_ssh_core/session.rb', line 100 def finish_command close dispatcher.tell([:finish_command, @command]) end |
#initialize_command ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/smart_proxy_remote_execution_ssh_core/session.rb', line 26 def initialize_command @logger.debug("initalizing command [#{@command}]") open_connector remote_script = cp_script_to_remote output_path = File.join(File.dirname(remote_script), 'output') # pipe the output to tee while capturing the exit code script = <<-SCRIPT exec 4>&1 exit_code=`((#{su_prefix}#{remote_script}; echo $?>&3 ) | /usr/bin/tee #{output_path} ) 3>&1 >&4` exec 4>&- exit $exit_code SCRIPT @logger.debug("executing script:\n#{script.lines.map { |line| " | #{line}" }.join}") @connector.async_run(script) do |data| @command_buffer << data end rescue => e @logger.error("error while initalizing command #{e.class} #{e.}:\n #{e.backtrace.join("\n")}") @command_buffer.concat(CommandUpdate.encode_exception("Error initializing command #{@command}", e)) refresh ensure plan_next_refresh end |
#kill ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/smart_proxy_remote_execution_ssh_core/session.rb', line 88 def kill @logger.debug("killing command [#{@command}]") if @connector @connector.run("pkill -f #{remote_command_file('script')}") else @logger.debug("connection closed") end rescue => e @command_buffer.concat(CommandUpdate.encode_exception("Failed to kill the command", e, false)) plan_next_refresh end |
#refresh ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/smart_proxy_remote_execution_ssh_core/session.rb', line 51 def refresh @connector.refresh if @connector unless @command_buffer.empty? status = refresh_command_buffer if status finish_command end end rescue Net::SSH::Disconnect => e check_expecting_disconnect if @expecting_disconnect @command_buffer << CommandUpdate::StatusData.new(0) else @command_buffer.concat(CommandUpdate.encode_exception("Failed to refresh the connector", e, true)) end refresh_command_buffer finish_command rescue => e @command_buffer.concat(CommandUpdate.encode_exception("Failed to refresh the connector", e, false)) ensure @refresh_planned = false plan_next_refresh end |
#refresh_command_buffer ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/smart_proxy_remote_execution_ssh_core/session.rb', line 76 def refresh_command_buffer @logger.debug("command #{@command} got new output: #{@command_buffer.inspect}") command_update = CommandUpdate.new(@command_buffer) check_expecting_disconnect @command.suspended_action << command_update @command_buffer = [] if command_update.exit_status @logger.debug("command [#{@command}] finished with status #{command_update.exit_status}") return command_update.exit_status end end |
#start_termination(*args) ⇒ Object
109 110 111 112 113 |
# File 'lib/smart_proxy_remote_execution_ssh_core/session.rb', line 109 def start_termination(*args) super close finish_termination end |