net-ssh-simple 1.4.5 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,6 +8,7 @@ Net::SSH::Simple is a simple wrapper around Net::SSH and Net::SCP.
8
8
  * All results are returned as {Net::SSH::Simple::Result}[http://rubydoc.info/gems/net-ssh-simple/Net/SSH/Simple/Result]
9
9
  * All errors are raised as {Net::SSH::Simple::Error}[http://rubydoc.info/gems/net-ssh-simple/Net/SSH/Simple/Error]
10
10
  * Efficient by default; re-uses transport connections where possible
11
+ * Maintains Keep-Alive to prevent unexpected connection timeouts
11
12
  * Lots of documentation
12
13
  * {100%}[https://busyloop.net/oss/net-ssh-simple/coverage/] test coverage
13
14
 
@@ -451,6 +451,10 @@ module Net
451
451
  # maximum time before aborting an operation (0 = disable).
452
452
  # you may use this to guard against run-away processes.
453
453
  #
454
+ # @option opts [Integer] :keepalive_interval (60)
455
+ # send keep-alive probes at this interval to prevent connections
456
+ # from timing out unexpectedly.
457
+ #
454
458
  # @option opts [Integer] :close_timeout (5)
455
459
  # grace-period on close before the connection will be terminated forcefully
456
460
  # (0 = terminate immediately).
@@ -512,7 +516,7 @@ module Net
512
516
  block.call(:start, ch, nil) if block
513
517
  end
514
518
  end
515
- wait_for_channel session, channel, @result, opts[:timeout]
519
+ wait_for_channel session, channel, @result, opts
516
520
  @result[:finish_at] = Time.new
517
521
  block.call(:finish, channel, nil) if block
518
522
  @result
@@ -585,7 +589,7 @@ module Net
585
589
 
586
590
 
587
591
  private
588
- EXTRA_OPTS = [:operation_timeout, :close_timeout]
592
+ EXTRA_OPTS = [:operation_timeout, :close_timeout, :keepalive_interval]
589
593
 
590
594
  def with_session(host, opts={}, &block)
591
595
  opts[:timeout] ||= 60
@@ -593,6 +597,7 @@ module Net
593
597
  opts[:operation_timeout] ||= 3600
594
598
  opts[:operation_timeout] = 2**32 if opts[:operation_timeout] == 0
595
599
  opts[:close_timeout] ||= 5
600
+ opts[:keepalive_interval] ||= 60
596
601
  begin
597
602
  net_ssh_opts = opts.reject{|k,v| EXTRA_OPTS.include? k }
598
603
  Timeout.timeout(opts[:operation_timeout]) do
@@ -611,11 +616,17 @@ module Net
611
616
  end
612
617
  end
613
618
 
614
- def wait_for_channel(session, channel, result, timeout)
619
+ def wait_for_channel(session, channel, result, opts)
615
620
  session.loop(1) do
616
- if timeout < Time.now - result[:last_event_at]
621
+ if opts[:timeout] < Time.now - result[:last_event_at]
617
622
  raise Timeout::Error, 'idle timeout'
618
623
  end
624
+
625
+ # Send keep-alive probes at the configured interval.
626
+ if opts[:keepalive_interval] < Time.now.to_i - (@result[:last_keepalive_at]||0).to_i
627
+ session.send_global_request('keep-alive@openssh.com')
628
+ @result[:last_keepalive_at] = Time.now
629
+ end
619
630
  channel.active?
620
631
  end
621
632
  end
@@ -635,7 +646,7 @@ module Net
635
646
  @result[:last_event_at] = Time.new
636
647
  block.call(sent, total) unless block.nil?
637
648
  end
638
- wait_for_channel session, channel, @result, opts[:timeout]
649
+ wait_for_channel session, channel, @result, opts
639
650
  @result[:finish_at] = Time.new
640
651
  @result[:success] = @result[:sent] == @result[:total]
641
652
  @result
@@ -669,14 +680,15 @@ module Net
669
680
  # @attr [String] host Hostname/IP address
670
681
  # @attr [Symbol] op :ssh or :scp
671
682
  # @attr [String] cmd Shell command (SSH only)
672
- # @attr [Time] start_at Operation start timestamp
673
- # @attr [Time] finish_at Operation finish timestamp
683
+ # @attr [Time] start_at Timestamp of operation start
684
+ # @attr [Time] finish_at Timestamp of operation finish
685
+ # @attr [Time] last_keepalive_at Timestamp of last keepalive (if any)
674
686
  # @attr [Time] last_event_at Timestamp of last activity
675
- # @attr [Boolean] timed_out Set to true if the operation timed out
687
+ # @attr [Boolean] timed_out True if the operation timed out
676
688
  # @attr [String] stdout Output to stdout (SSH only)
677
689
  # @attr [String] stderr Output to stderr (SSH only)
678
690
  # @attr [boolean] success
679
- # @attr [String] exit_code UNIX exit code of the remote command (SSH only)
691
+ # @attr [String] exit_code UNIX exit code (SSH only)
680
692
  # @attr [Integer] total Size of requested file (in bytes, SCP only)
681
693
  # @attr [Integer] sent Number of bytes transferred (SCP only)
682
694
  # @attr [String] exit_signal
@@ -1,7 +1,7 @@
1
1
  module Net
2
2
  module SSH
3
3
  class Simple
4
- VERSION = "1.4.5"
4
+ VERSION = "1.5.0"
5
5
  end
6
6
  end
7
7
  end
@@ -45,7 +45,7 @@ describe Net::SSH::Simple do
45
45
  it "enforces idle timeout" do
46
46
  raised = false
47
47
  begin
48
- r = Net::SSH::Simple.ssh('localhost', 'sleep 60', {:timeout => 1})
48
+ r = Net::SSH::Simple.ssh('localhost', 'sleep 60', {:timeout => 5, :keepalive_interval => 1})
49
49
  rescue => e
50
50
  raised = true
51
51
  e.to_s.should match /^idle timeout @ .*/
@@ -126,6 +126,14 @@ describe Net::SSH::Simple do
126
126
  Net::SSH::Simple.ssh('localhost', 'true').success.should == true
127
127
  end
128
128
 
129
+ it "sends keep-alive" do
130
+ r = Net::SSH::Simple.ssh('localhost', 'sleep 3', {:keepalive_interval=>1})
131
+ (Time.now - r.last_keepalive_at).to_i.should < 3
132
+
133
+ r = Net::SSH::Simple.ssh('localhost', 'sleep 3', {:keepalive_interval=>5})
134
+ (Time.now - r.last_keepalive_at).to_i.should > 2
135
+ end
136
+
129
137
  it "recognizes exit-codes" do
130
138
  Net::SSH::Simple.ssh('localhost', 'true').exit_code.should == 0
131
139
  Net::SSH::Simple.ssh('localhost', 'false').exit_code.should == 1
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ssh-simple
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.5
4
+ version: 1.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-07 00:00:00.000000000Z
12
+ date: 2011-11-25 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-ssh
16
- requirement: &13039960 !ruby/object:Gem::Requirement
16
+ requirement: &19079780 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.1.4
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *13039960
24
+ version_requirements: *19079780
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: net-scp
27
- requirement: &13039140 !ruby/object:Gem::Requirement
27
+ requirement: &19079300 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.0.4
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *13039140
35
+ version_requirements: *19079300
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: blockenspiel
38
- requirement: &13038360 !ruby/object:Gem::Requirement
38
+ requirement: &19078800 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.4.3
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *13038360
46
+ version_requirements: *19078800
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: hashie
49
- requirement: &13037600 !ruby/object:Gem::Requirement
49
+ requirement: &19078340 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.1.0
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *13037600
57
+ version_requirements: *19078340
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &13036620 !ruby/object:Gem::Requirement
60
+ requirement: &19077840 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.9.2.2
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *13036620
68
+ version_requirements: *19077840
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &13036020 !ruby/object:Gem::Requirement
71
+ requirement: &19077460 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *13036020
79
+ version_requirements: *19077460
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: cover_me
82
- requirement: &13035440 !ruby/object:Gem::Requirement
82
+ requirement: &19076980 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *13035440
90
+ version_requirements: *19076980
91
91
  description: Net::SSH::Simple is a simple wrapper around Net::SSH and Net::SCP.
92
92
  email:
93
93
  - moe@busyloop.net
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  version: '0'
125
125
  segments:
126
126
  - 0
127
- hash: -3584124677711427707
127
+ hash: 2921598519931635186
128
128
  requirements: []
129
129
  rubyforge_project:
130
130
  rubygems_version: 1.8.10