Class: Command::Runner::Backends::SSH

Inherits:
Fake
  • Object
show all
Defined in:
lib/command/runner/backends/ssh.rb

Overview

Note:

The message that is returned by this may not be entirely filled with data, since some of it may not be able to be accessible.

SSHs into a remote and runs commands there.

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Fake

#ran?, #unsafe?

Constructor Details

#initialize(host, user, options = {}) ⇒ SSH

Initializes the backend.

Parameters:

  • host (String)

    the host to connect to.

  • user (String)

    the user to log in as.

  • options (Hash) (defaults to: {})

    the options to pass to Net::SSH.


39
40
41
42
# File 'lib/command/runner/backends/ssh.rb', line 39

def initialize(host, user, options = {})
  super()
  @net_ssh = Net::SSH.start(host, user, options)
end

Class Method Details

.available?(force_unsafe = false) ⇒ Object

This method is abstract.

Returns whether or not this backend is avialable on this platform.

Parameters:

  • force_unsafe (Boolean) (defaults to: false)

    if the backend needs to be able to handle unsafe execution, then this will be true.


13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/command/runner/backends/ssh.rb', line 13

def self.available?(force_unsafe = false)
  begin
    require 'net/ssh'
    if force_unsafe
      false
    else
      true
    end
  rescue LoadError
    false
  end
end

.unsafe?Boolean

Returns:

  • (Boolean)

26
27
28
# File 'lib/command/runner/backends/ssh.rb', line 26

def self.unsafe?
  true
end

.unsafe_execution?Boolean

Returns:

  • (Boolean)

30
31
32
# File 'lib/command/runner/backends/ssh.rb', line 30

def self.unsafe_execution?
  false
end

Instance Method Details

#call(command, arguments, env = {}, options = {}) {|Message| ... } ⇒ Message, Object

Note:

The block is called in another thread, so in ruby versions other than MRI, make sure your code is thread-safe.

Run the given command and arguments, in the given environment.

Parameters:

  • command (String)

    the command to run.

  • arguments (String)

    the arguments to pass to the command.

  • env (Hash) (defaults to: {})

    the enviornment to run the command under.

  • options (Hash) (defaults to: {})

    the options to run the command under.

Yields:

  • (Message)

    when the command finishes.

Returns:

  • (Message, Object)

    message if no block is given, the result of the block call otherwise.

Raises:

  • (Errno::ENOENT)

    if the command doesn't exist.


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/command/runner/backends/ssh.rb', line 45

def call(command, arguments, env = {}, options = {}, &block)
  super
  mdata   = { :stdout => "", :stderr => "", :env => env, :options => {} }
  channel = @net_ssh.open_channel do |ch|


    ch.exec "#{command} " \
      "#{arguments.join(" ")}" do |sch, success|
      raise Errno::ENOENT unless success

      env.each do |k, v|
        sch.env k.to_s, v
      end

      sch.on_data do |_, data|
        mdata[:stdout] << data
      end

      sch.on_extended_data do |_, type, data|
        mdata[:stderr] << data if type == 1
      end

      sch.on_request "exit-status" do |_, data|
        mdata[:exit_code] = data.read_long
      end

      sch.on_close do
        mdata[:executed] = true
        mdata[:finished] = true
      end

    end
  end

  future do
    start_time = Time.now
    channel.wait
    end_time   = Time.now
    channel.close

    mdata[:time] = (end_time - start_time).abs

    message = Message.new mdata

    if block_given?
      block.call(message)
    else
      message
    end
  end
end