net-ssh-session 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -3,6 +3,7 @@ rvm:
3
3
  - 1.8.7
4
4
  - 1.9.2
5
5
  - 1.9.3
6
+ - 2.0.0
6
7
  - ruby-head
7
8
  - jruby-18mode
8
- - jruby-19mode
9
+ - jruby-19mode
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source :rubygems
2
- gemspec
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE CHANGED
@@ -1,7 +1,18 @@
1
1
  Copyright (c) 2012-2013 Dan Sosedoff.
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
4
9
 
5
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
6
12
 
7
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -118,6 +118,8 @@ session.run_multiple(commands, :break => true)
118
118
  To get each command result after execution, you can supply a block:
119
119
 
120
120
  ```ruby
121
+ commands = ["mkdir /tmp", "echo test > /tmp/file", "rm -rf /tmp"]
122
+
121
123
  session.run_multiple(commands) do |cmd|
122
124
  puts "Original command: #{cmd.command}"
123
125
  puts "Exit code: #{cmd.exit_code}"
@@ -174,12 +176,23 @@ s.run("bundler install --path .")
174
176
  s.close
175
177
  ```
176
178
 
177
- You can also disable histroy for the whole session:
179
+ You can also disable history for the whole session:
178
180
 
179
181
  ```ruby
180
182
  Net::SSH::Session.new(host, user, password, :history => false)
181
183
  ```
182
184
 
185
+ ## Execute any command with timeout
186
+
187
+ To enable session-wide command execution timeout, pass an extra option:
188
+
189
+ ```ruby
190
+ session = Net::SSH::Session.new(host, user, password, :timeout => 10)
191
+ ```
192
+
193
+ This will limit any command execution time to 10 seconds. Error `Timeout::Error`
194
+ will be raised when timeout is exceeded.
195
+
183
196
  ## Credits
184
197
 
185
198
  Library code was extracted and modified from multiple sources:
@@ -188,4 +201,8 @@ Library code was extracted and modified from multiple sources:
188
201
  - Mitchell Hashimoto (@mitchellh)
189
202
  - Michael Klishin (@michaelklishin)
190
203
  - Sven Fuchs (@svenfuchs)
191
- - Travis-CI (@travis-ci)
204
+ - Travis-CI (@travis-ci)
205
+
206
+ ## License
207
+
208
+ See LICENSE file for details
@@ -1,7 +1,7 @@
1
1
  module Net
2
2
  module SSH
3
3
  class Session
4
- VERSION = '0.1.4'
4
+ VERSION = '0.1.5'
5
5
  end
6
6
  end
7
7
  end
@@ -14,6 +14,7 @@ module Net
14
14
  attr_reader :options
15
15
  attr_reader :logger
16
16
  attr_reader :history
17
+ attr_reader :timeout
17
18
 
18
19
  # Initialize a new ssh session
19
20
  # @param [String] remote hostname or ip address
@@ -26,10 +27,15 @@ module Net
26
27
  @password = password
27
28
  @history = []
28
29
  @track_history = true
30
+ @timeout = options[:timeout]
29
31
 
30
32
  if options[:history] == false
31
33
  @track_history = false
32
34
  end
35
+
36
+ if @timeout && !@timeout.kind_of?(Integer)
37
+ raise ArgumentError, "Timeout value should be numeric"
38
+ end
33
39
  end
34
40
 
35
41
  # Establish connection with remote server
@@ -59,12 +65,17 @@ module Net
59
65
  # @return [Integer] command execution exit code
60
66
  def exec(command, &on_output)
61
67
  status = nil
62
- shell.execute(command) do |process|
63
- process.on_output(&on_output)
64
- process.on_error_output(&on_output)
65
- process.on_finish { |p| status = p.exit_status }
68
+
69
+ handle_timeout do
70
+ shell.execute(command) do |process|
71
+ process.on_output(&on_output)
72
+ process.on_error_output(&on_output)
73
+ process.on_finish { |p| status = p.exit_status }
74
+ end
75
+
76
+ shell.session.loop(1) { status.nil? }
66
77
  end
67
- shell.session.loop(1) { status.nil? }
78
+
68
79
  status
69
80
  end
70
81
 
@@ -133,6 +144,9 @@ module Net
133
144
  history.last
134
145
  end
135
146
 
147
+ # Execute a dynamic command
148
+ # @param [String] command name
149
+ # @params [Array] command arguments
136
150
  def method_missing(name, *args)
137
151
  run("#{name} #{args.join(' ')}".strip)
138
152
  end
@@ -143,6 +157,14 @@ module Net
143
157
  @connection = Net::SSH.start(host, user, :password => password)
144
158
  @shell = @connection.shell
145
159
  end
160
+
161
+ def handle_timeout(&block)
162
+ if timeout
163
+ Timeout.timeout(timeout) { block.call(self) }
164
+ else
165
+ block.call(self)
166
+ end
167
+ end
146
168
  end
147
169
  end
148
170
  end
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.email = ["dan.sosedoff@gmail.com"]
11
11
 
12
12
  s.add_development_dependency 'rake'
13
- s.add_development_dependency 'rspec', '~> 2.11'
13
+ s.add_development_dependency 'rspec', '~> 2.13'
14
14
  s.add_development_dependency 'simplecov', '~> 0.4'
15
15
 
16
16
  s.add_dependency 'net-ssh', '~> 2.6'
@@ -19,4 +19,4 @@ Gem::Specification.new do |s|
19
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
21
21
  s.require_paths = ["lib"]
22
- end
22
+ end
data/spec/session_spec.rb CHANGED
@@ -1,12 +1,47 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Net::SSH::Session do
4
+ describe '#initialize' do
5
+ context 'with :timeout option' do
6
+ it 'raises error if timeout value is not numeric' do
7
+ expect {
8
+ Net::SSH::Session.new('host', 'user', 'password', :timeout => 'data')
9
+ }.to raise_error ArgumentError, "Timeout value should be numeric"
10
+ end
11
+
12
+ it 'sets global session timeout value' do
13
+ session = Net::SSH::Session.new('host', 'user', 'password', :timeout => 1)
14
+ expect(session.timeout).to eq 1
15
+ end
16
+ end
17
+ end
18
+
4
19
  describe '#method_missing' do
5
20
  let(:session) { Net::SSH::Session.new('host', 'user', 'password') }
21
+ before { session.stub(:run).with("uname").and_return(fake_run("uname", "Linux")) }
6
22
 
7
23
  it 'runs a command based on missing method name' do
8
- session.stub(:run).with("uname").and_return(fake_run("uname", "Linux"))
9
- session.uname.output.should eq("Linux")
24
+ expect(session.uname.output).to eq "Linux"
25
+ end
26
+ end
27
+
28
+ describe '#run' do
29
+ context 'when session timeout is set' do
30
+ let(:process) do
31
+ proc { sleep 5 }
32
+ end
33
+
34
+ let(:session) do
35
+ Net::SSH::Session.new('host', 'user', 'password', :timeout => 1)
36
+ end
37
+
38
+ before do
39
+ session.stub_chain(:shell, :execute).with('foo') { process.call }
40
+ end
41
+
42
+ it 'raises error if operation timed out' do
43
+ expect { session.run('foo') }.to raise_error Timeout::Error
44
+ end
10
45
  end
11
46
  end
12
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ssh-session
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-11 00:00:00.000000000 Z
12
+ date: 2013-04-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: '2.11'
37
+ version: '2.13'
38
38
  type: :development
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: '2.11'
45
+ version: '2.13'
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: simplecov
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
123
  version: '0'
124
124
  requirements: []
125
125
  rubyforge_project:
126
- rubygems_version: 1.8.24
126
+ rubygems_version: 1.8.25
127
127
  signing_key:
128
128
  specification_version: 3
129
129
  summary: Shell session for Net::SSH connections
@@ -133,4 +133,3 @@ test_files:
133
133
  - spec/session_helpers_spec.rb
134
134
  - spec/session_spec.rb
135
135
  - spec/spec_helper.rb
136
- has_rdoc: