net-ssh-simple 1.4.5 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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