Class: Bcome::Ssh::CommandExec

Inherits:
Object
  • Object
show all
Defined in:
lib/objects/ssh/command_exec.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(commands) ⇒ CommandExec

Returns a new instance of CommandExec.



5
6
7
# File 'lib/objects/ssh/command_exec.rb', line 5

def initialize(commands)
  @commands = commands
end

Instance Attribute Details

#commandsObject (readonly)

Returns the value of attribute commands.



3
4
5
# File 'lib/objects/ssh/command_exec.rb', line 3

def commands
  @commands
end

Instance Method Details

#execute!Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/objects/ssh/command_exec.rb', line 17

def execute!
  # TODO: - catch IOError: closed stream here and re-connect gracefully
  # to reproduce: open connections, and let them timeout then re-enter command (interactive mode)

  @commands.each do |command|
    node = command.node
    ssh = node.ssh_driver.ssh_connection

    begin
      ssh_exec!(ssh, command)
    rescue IOError # Typically occurs after a timeout if the session has been left idle
      node.open_ssh_connection
      ssh_exec!(ssh, command) # retry, once
    end

    output_append("\n(#{node.namespace})$".terminal_prompt + ">\s#{command.raw} (#{command.pretty_result})\n")
    output_append(command.output.to_s)
  end
  print_output unless ::Bcome::Orchestrator.instance.command_output_silenced?
end

#output_append(output_string) ⇒ Object



9
10
11
# File 'lib/objects/ssh/command_exec.rb', line 9

def output_append(output_string)
  @output_string = "#{@output_string}#{output_string}"
end


13
14
15
# File 'lib/objects/ssh/command_exec.rb', line 13

def print_output
  print "#{@output_string}\n\n"
end

#ssh_exec!(ssh, command) ⇒ Object

 NON PTY (i.e no pseudo-terminal)



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/objects/ssh/command_exec.rb', line 38

def ssh_exec!(ssh, command) #  NON PTY (i.e no pseudo-terminal)
  ssh.open_channel do |channel|
    channel.exec(command.raw) do |_cha, success|
      unless success
        abort "FAILED: couldn't execute command (ssh.channel.exec)"
      end

      channel.on_data do |_ch, data|
        command.stdout += data
      end

      channel.on_extended_data do |_ch, _type, data|
        command.stderr += data
      end

      channel.on_request('exit-status') do |_ch, data|
        command.exit_code = data.read_long
      end

      channel.on_request('exit-signal') do |_ch, data|
        command.exit_signal = data.read_long
      end
    end
  end
  ssh.loop
end