weave 1.0.2.beta1 → 1.1.0.pre.beta1
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.
- checksums.yaml +4 -4
- data/README.md +8 -3
- data/examples/basic.rb +2 -2
- data/lib/weave.rb +40 -59
- data/weave.gemspec +6 -9
- metadata +28 -28
- data/lib/weave/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa0ce3c6677178d9891d65239ab9982fe0e6038d
|
4
|
+
data.tar.gz: 892226999386cb1e0caf1a93b55fd4f72e362703
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c691d81f57e0d6ae599fea383ee7bd9b9b31341d17b6614719198a5de20989c9d87b7e07a91bb405b8824db4a36626bf2b3c9c81543bd4fa7d29cfed63778e9
|
7
|
+
data.tar.gz: 0fe3897f7c733b1228742bd76588f6b2cc831037d38013840fa434d5baecf96135ec7952aba7c76d94dbb48bc50f1fcf8918492f53c1cb1aaa7590ad572f0327
|
data/README.md
CHANGED
@@ -10,9 +10,8 @@ Put `weave` in your Gemfile or install directly:
|
|
10
10
|
|
11
11
|
## Documentation
|
12
12
|
|
13
|
-
[Method docs here](http://rubydoc.info/github/cespare/weave/master/frames).
|
14
|
-
|
15
|
-
|
13
|
+
[Method docs here](http://rubydoc.info/github/cespare/weave/master/frames). See the examples (in `examples/`)
|
14
|
+
to get started.
|
16
15
|
|
17
16
|
## Implemented features
|
18
17
|
|
@@ -22,3 +21,9 @@ examples (in `examples/`) to get started.
|
|
22
21
|
* Commands:
|
23
22
|
|
24
23
|
- `run`
|
24
|
+
|
25
|
+
## Tests
|
26
|
+
|
27
|
+
You need vagrant installed. `vagrant up` to get the machines running. Then:
|
28
|
+
|
29
|
+
$ bundle exec rake test
|
data/examples/basic.rb
CHANGED
data/lib/weave.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require "net/ssh"
|
2
2
|
require "thread"
|
3
|
-
require "timeout"
|
4
3
|
|
5
4
|
module Weave
|
6
5
|
DEFAULT_THREAD_POOL_SIZE = 10
|
@@ -12,16 +11,18 @@ module Weave
|
|
12
11
|
COLORS = { :red => 1, :green => 2 }
|
13
12
|
|
14
13
|
# Create a connection pool for an array of hosts. Each host must have a user specified (e.g.,
|
15
|
-
# root@example.com). If
|
16
|
-
#
|
17
|
-
#
|
14
|
+
# root@example.com). If the key :net_ssh_options is present in options, then the value is a hash of options
|
15
|
+
# that is passed directly to Net::SSH.start. If a block is given, then the options (except for
|
16
|
+
# :net_ssh_options) are passed through to the underlying ConnectionPool and the block is immediately run in
|
17
|
+
# the context of each connection. Otherwise, a pool is returned.
|
18
18
|
#
|
19
19
|
# @see ConnectionPool#execute
|
20
20
|
def self.connect(host_list, options = {}, &block)
|
21
21
|
unless host_list.is_a? Array
|
22
22
|
raise Weave::Error, "Must pass an array for host_list. Received: #{host_list.inspect}"
|
23
23
|
end
|
24
|
-
|
24
|
+
net_ssh_options = options.delete(:net_ssh_options)
|
25
|
+
pool = ConnectionPool.new(host_list, net_ssh_options)
|
25
26
|
if block_given?
|
26
27
|
pool.execute(options, &block)
|
27
28
|
pool.disconnect!
|
@@ -61,9 +62,12 @@ module Weave
|
|
61
62
|
class ConnectionPool
|
62
63
|
# @param [Array] host_list the array of hosts, of the form user@host. You may leave off this argument, and
|
63
64
|
# use #execute_with (instead of #execute) to specify the whole list of hosts each time.
|
64
|
-
def initialize(host_list = [])
|
65
|
+
def initialize(host_list = [], net_ssh_options = {})
|
65
66
|
@hosts = host_list
|
66
|
-
@
|
67
|
+
@net_ssh_options = net_ssh_options
|
68
|
+
@connections = host_list.reduce({}) do |pool, host|
|
69
|
+
pool.merge(host => LazyConnection.new(host, @net_ssh_options))
|
70
|
+
end
|
67
71
|
end
|
68
72
|
|
69
73
|
# Run a command over the connection pool. The block is evaluated in the context of LazyConnection.
|
@@ -82,7 +86,7 @@ module Weave
|
|
82
86
|
# This is the same as #execute, except that host_list overrides the list of connections with which this
|
83
87
|
# ConnectionPool was initialized. Any hosts in here that weren't already in the pool will be added.
|
84
88
|
def execute_with(host_list, options = {}, &block)
|
85
|
-
host_list.each { |host| @connections[host] ||= LazyConnection.new(host) }
|
89
|
+
host_list.each { |host| @connections[host] ||= LazyConnection.new(host, @net_ssh_options) }
|
86
90
|
args = options[:args] || []
|
87
91
|
num_threads = options[:num_threads] || DEFAULT_THREAD_POOL_SIZE
|
88
92
|
if options[:serial]
|
@@ -120,9 +124,10 @@ module Weave
|
|
120
124
|
attr_reader :host
|
121
125
|
|
122
126
|
# @param [String] host_string the host of the form user@host
|
123
|
-
def initialize(host_string)
|
127
|
+
def initialize(host_string, net_ssh_options = {})
|
124
128
|
@user, @host = self.class.user_and_host(host_string)
|
125
129
|
@connection = nil
|
130
|
+
@net_ssh_options = net_ssh_options || {}
|
126
131
|
@mutex = NilMutex
|
127
132
|
end
|
128
133
|
|
@@ -144,71 +149,47 @@ module Weave
|
|
144
149
|
# command terminated via a signal or with a non-zero exit status. Otherwise (the default), these will
|
145
150
|
# cause a `Weave::Error` to be raised.
|
146
151
|
#
|
147
|
-
# The option `:timeout`, if provided, specifies the number of seconds to allow the command to execute
|
148
|
-
# before timing it out. If this happens, the output is unchanged (but in most cases, this will be an error
|
149
|
-
# as your process was killed by a signal from the pseudo-tty Weave allocates for it on the remote host).
|
150
|
-
# If the command is timed out, the result hash also has `:timed_out => true` (is is `false` otherwise).
|
151
|
-
#
|
152
152
|
# @param [Hash] options the output options
|
153
153
|
# @option options [Symbol] :output the output format
|
154
|
-
# @option options [Symbol] :continue_on_failure whether to raise an exception if the command exits with a
|
155
|
-
# non-zero exit status or because of a signal
|
156
|
-
# @option options[Symbol] :timeout if given, how many seconds to give the command before timing it out
|
157
154
|
def run(command, options = {})
|
158
155
|
options[:output] ||= :pretty
|
159
|
-
@connection ||= Net::SSH.start(@host, @user)
|
156
|
+
@connection ||= Net::SSH.start(@host, @user, @net_ssh_options)
|
160
157
|
result = options[:output] == :capture ? { :stdout => "", :stderr => "" } : {}
|
161
|
-
result[:timed_out] = false
|
162
158
|
@connection.open_channel do |channel|
|
163
|
-
channel.
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
raise Error, "Could not run ssh command: #{command}"
|
168
|
-
end
|
159
|
+
channel.exec(command) do |_, success|
|
160
|
+
unless success
|
161
|
+
raise Error, "Could not run ssh command: #{command}"
|
162
|
+
end
|
169
163
|
|
170
|
-
|
171
|
-
|
172
|
-
|
164
|
+
channel.on_data do |_, data|
|
165
|
+
append_or_print_output(result, data, :stdout, options)
|
166
|
+
end
|
173
167
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
168
|
+
channel.on_extended_data do |_, type, data|
|
169
|
+
next unless type == 1
|
170
|
+
append_or_print_output(result, data, :stderr, options)
|
171
|
+
end
|
178
172
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
end
|
184
|
-
result[:exit_code] = code
|
173
|
+
channel.on_request("exit-status") do |_, data|
|
174
|
+
code = data.read_long
|
175
|
+
unless code.zero? || options[:continue_on_failure]
|
176
|
+
raise Error, "[#{@host}] command finished with exit status #{code}: #{command}"
|
185
177
|
end
|
178
|
+
result[:exit_code] = code
|
179
|
+
end
|
186
180
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end
|
194
|
-
result[:exit_signal] = signal
|
181
|
+
channel.on_request("exit-signal") do |_, data|
|
182
|
+
signal = data.read_long
|
183
|
+
unless options[:continue_on_failure]
|
184
|
+
signal_name = Signal.list.invert[signal]
|
185
|
+
signal_message = signal_name ? "#{signal} (#{signal_name})" : "#{signal}"
|
186
|
+
raise Error, "[#{@host}] command received signal #{signal_message}: #{command}"
|
195
187
|
end
|
188
|
+
result[:exit_signal] = signal
|
196
189
|
end
|
197
190
|
end
|
198
191
|
end
|
199
|
-
|
200
|
-
@connection.loop(0.05)
|
201
|
-
else
|
202
|
-
begin
|
203
|
-
Timeout.timeout(options[:timeout]) do
|
204
|
-
@connection.loop(0.05)
|
205
|
-
end
|
206
|
-
rescue Timeout::Error
|
207
|
-
@connection.close
|
208
|
-
@connection = nil
|
209
|
-
result[:timed_out] = true
|
210
|
-
end
|
211
|
-
end
|
192
|
+
@connection.loop(0.05)
|
212
193
|
result
|
213
194
|
end
|
214
195
|
|
data/weave.gemspec
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path('../lib/weave/version', __FILE__)
|
3
|
-
|
4
1
|
Gem::Specification.new do |gem|
|
5
2
|
gem.authors = ["Caleb Spare"]
|
6
3
|
gem.email = ["cespare@gmail.com"]
|
@@ -14,14 +11,14 @@ Gem::Specification.new do |gem|
|
|
14
11
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
12
|
gem.name = "weave"
|
16
13
|
gem.require_paths = ["lib"]
|
17
|
-
gem.version =
|
14
|
+
gem.version = "1.1.0-beta1"
|
18
15
|
|
19
|
-
gem.add_dependency "net-ssh", "
|
16
|
+
gem.add_dependency "net-ssh", "~> 2.9"
|
20
17
|
|
21
18
|
# For running integration tests.
|
22
|
-
gem.add_development_dependency "minitest"
|
23
|
-
gem.add_development_dependency "rake"
|
19
|
+
gem.add_development_dependency "minitest", "~> 5.0"
|
20
|
+
gem.add_development_dependency "rake", "~> 10.0"
|
24
21
|
# For generating the docs
|
25
|
-
gem.add_development_dependency "yard"
|
26
|
-
gem.add_development_dependency "redcarpet"
|
22
|
+
gem.add_development_dependency "yard", "~> 0.8"
|
23
|
+
gem.add_development_dependency "redcarpet", "~> 3.0"
|
27
24
|
end
|
metadata
CHANGED
@@ -1,85 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: weave
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.1.0.pre.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Caleb Spare
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-ssh
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
19
|
+
version: '2.9'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.
|
26
|
+
version: '2.9'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '5.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
40
|
+
version: '5.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
47
|
+
version: '10.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
54
|
+
version: '10.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: yard
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
61
|
+
version: '0.8'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
68
|
+
version: '0.8'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: redcarpet
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
75
|
+
version: '3.0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
82
|
+
version: '3.0'
|
83
83
|
description: Simple parallel ssh.
|
84
84
|
email:
|
85
85
|
- cespare@gmail.com
|
@@ -87,8 +87,8 @@ executables: []
|
|
87
87
|
extensions: []
|
88
88
|
extra_rdoc_files: []
|
89
89
|
files:
|
90
|
-
- .gitignore
|
91
|
-
- .yardopts
|
90
|
+
- ".gitignore"
|
91
|
+
- ".yardopts"
|
92
92
|
- Gemfile
|
93
93
|
- LICENSE
|
94
94
|
- README.md
|
@@ -97,7 +97,6 @@ files:
|
|
97
97
|
- examples/basic.rb
|
98
98
|
- examples/parallel-console.rb
|
99
99
|
- lib/weave.rb
|
100
|
-
- lib/weave/version.rb
|
101
100
|
- test/integrations/sanity_test.rb
|
102
101
|
- test/test_helper.rb
|
103
102
|
- weave.gemspec
|
@@ -111,20 +110,21 @@ require_paths:
|
|
111
110
|
- lib
|
112
111
|
required_ruby_version: !ruby/object:Gem::Requirement
|
113
112
|
requirements:
|
114
|
-
- -
|
113
|
+
- - ">="
|
115
114
|
- !ruby/object:Gem::Version
|
116
115
|
version: '0'
|
117
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
117
|
requirements:
|
119
|
-
- -
|
118
|
+
- - ">"
|
120
119
|
- !ruby/object:Gem::Version
|
121
120
|
version: 1.3.1
|
122
121
|
requirements: []
|
123
122
|
rubyforge_project:
|
124
|
-
rubygems_version: 2.
|
123
|
+
rubygems_version: 2.2.2
|
125
124
|
signing_key:
|
126
125
|
specification_version: 4
|
127
126
|
summary: Simple parallel ssh.
|
128
127
|
test_files:
|
129
128
|
- test/integrations/sanity_test.rb
|
130
129
|
- test/test_helper.rb
|
130
|
+
has_rdoc:
|
data/lib/weave/version.rb
DELETED