Class: Backup::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/backup/ssh_helpers.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server_name, command, callback, options, actor) ⇒ Command

:nodoc:



13
14
15
16
17
18
19
# File 'lib/backup/ssh_helpers.rb', line 13

def initialize(server_name, command, callback, options, actor) #:nodoc:
  @command  = command.strip.gsub(/\r?\n/, "\\\n")
  @callback = callback
  @options  = options
  @actor    = actor
  @channels = open_channels
end

Instance Attribute Details

#actorObject (readonly)

Returns the value of attribute actor.



11
12
13
# File 'lib/backup/ssh_helpers.rb', line 11

def actor
  @actor
end

#commandObject (readonly)

Returns the value of attribute command.



10
11
12
# File 'lib/backup/ssh_helpers.rb', line 10

def command
  @command
end

#optionsObject (readonly)

Returns the value of attribute options.



10
11
12
# File 'lib/backup/ssh_helpers.rb', line 10

def options
  @options
end

Instance Method Details

#open_channelsObject



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
# File 'lib/backup/ssh_helpers.rb', line 48

def open_channels
  channel = actor.session.open_channel do |channel|
       channel.request_pty do |ch, success|
         if success
           ch.exec command
           ch.send_data options[:data] if options[:data]
         else
           ch.close
         end
       end

       channel[:actor] = @actor

       channel.on_data do |ch, data|
         puts data
         @callback[ch, :out, data] if @callback
       end

       channel.on_request "exit-status" do |ch, data|
         ch[:status] = data.read_long
       end

       channel.on_close do |ch|
         ch[:closed] = true
       end
  end
  [channel]
end

#process!Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/backup/ssh_helpers.rb', line 21

def process!
  since = Time.now
  loop do
    active = 0
    @channels.each do |ch|
      next if ch[:closed]
      active += 1
      ch.connection.process(0)
    end

    break if active == 0
    if Time.now - since >= 1
      since = Time.now
      @channels.each { |ch| ch.connection.ping! }
    end
    sleep 0.01 # a brief respite, to keep the CPU from going crazy
  end

  #logger.trace "command finished"

  if failed = @channels.detect { |ch| ch[:status] != 0 }
    raise "command #{@command.inspect} failed"
  end

  self
end