rye 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGES.txt +44 -38
- data/README.rdoc +44 -30
- data/Rakefile +41 -82
- data/VERSION +1 -0
- data/gem-public_cert.pem +20 -0
- data/lib/rye.rb +74 -52
- data/lib/rye/box.rb +7 -4
- data/lib/rye/dsl.rb +100 -0
- data/rye.gemspec +95 -55
- data/try/10_basic_tryouts.rb +44 -0
- data/try/12_batch_tryouts.rb +26 -0
- data/try/13_set_tryouts.rb +42 -0
- data/try/14_auth_methods_tryouts.rb +28 -0
- data/try/15_file_tryouts.rb +12 -0
- data/try/20_file_transfer_tryouts.rb +46 -0
- data/try/25_template_upload.rb +37 -0
- data/try/30_safemode_tryouts.rb +85 -0
- data/try/35_basics_with_hop.rb +36 -0
- data/try/70_rye_cli_tryouts.rb +0 -0
- data/try/copying.rb +18 -0
- data/try/keys.rb +141 -0
- data/tst/10-key1 +27 -0
- data/tst/10-key1.pub +1 -0
- data/tst/10-key2 +30 -0
- data/tst/10-key2.pub +1 -0
- data/tst/10_keys_test.rb +88 -0
- data/tst/50_rset_test.rb +54 -0
- data/tst/60-file.mp3 +0 -0
- data/tst/60_rbox_transfer_test.rb +53 -0
- data/tst/65_rbox_file_append_test.rb +53 -0
- data/tst/70_rbox_env_test.rb +19 -0
- data/tst/dsl_example.rb +80 -0
- data/tst/rye.rb +13 -0
- data/tst/shell.rb +280 -0
- data/tst/shell2.rb +278 -0
- data/tst/shell3.rb +280 -0
- data/tst/test_hop.rb +25 -0
- metadata +86 -25
- metadata.gz.sig +0 -0
- data/bin/try +0 -246
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.9.8
|
data/gem-public_cert.pem
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMQ8wDQYDVQQDDAZkZWxh
|
3
|
+
bm8xGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
|
4
|
+
b20wHhcNMTMwMjA2MTE1NzQ1WhcNMTQwMjA2MTE1NzQ1WjBBMQ8wDQYDVQQDDAZk
|
5
|
+
ZWxhbm8xGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
|
6
|
+
FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDg1hMtl0XsMuUK
|
7
|
+
AKTgYWv3gjj7vuEsE2EjT+vyBg8/LpqVVwZziiaebJT9IZiQ+sCFqbiakj0b53pI
|
8
|
+
hg1yOaBEmH6/W0L7rwzqaRV9sW1eJs9JxFYQCnd67zUnzj8nnRlOjG+hhIG+Vsij
|
9
|
+
npsGbt28pefuNZJjO5q2clAlfSniIIHfIsU7/StEYu6FUGOjnwryZ0r5yJlr9RrE
|
10
|
+
Gs+q0DW8QnZ9UpAfuDFQZuIqeKQFFLE7nMmCGaA+0BN1nLl3fVHNbLHq7Avk8+Z+
|
11
|
+
ZuuvkdscbHlO/l+3xCNQ5nUnHwq0ADAbMLOlmiYYzqXoWLjmeI6me/clktJCfN2R
|
12
|
+
oZG3UQvvAgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFMSJOEtHzE4l0azv
|
13
|
+
M0JK0kKNToK1MAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAtOdE73qx
|
14
|
+
OH2ydi9oT2hS5f9G0y1Z70Tlwh+VGExyfxzVE9XwC+iPpJxNraiHYgF/9/oky7ZZ
|
15
|
+
R9q0/tJneuhAenZdiQkX7oi4O3v9wRS6YHoWBxMPFKVRLNTzvVJsbmfpCAlp5/5g
|
16
|
+
ps4wQFy5mibElGVlOobf/ghqZ25HS9J6kd0/C/ry0AUtTogsL7TxGwT4kbCx63ub
|
17
|
+
3vywEEhsJUzfd97GCABmtQfRTldX/j7F1z/5wd8p+hfdox1iibds9ZtfaZA3KzKn
|
18
|
+
kchWN9B6zg9r1XMQ8BM2Jz0XoPanPe354+lWwjpkRKbFow/ZbQHcCLCq24+N6b6g
|
19
|
+
dgKfNDzwiDpqCA==
|
20
|
+
-----END CERTIFICATE-----
|
data/lib/rye.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# vim: set sw=2 ts=2 :
|
2
2
|
|
3
|
+
module Rye
|
4
|
+
unless defined?(Rye::HOME)
|
5
|
+
HOME = File.expand_path( File.join(File.dirname(__FILE__), '..') )
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
require 'logger'
|
4
10
|
require 'thread'
|
5
11
|
require 'base64'
|
@@ -19,11 +25,11 @@ require 'esc'
|
|
19
25
|
#
|
20
26
|
# Safely run remote commands via SSH in Ruby.
|
21
27
|
#
|
22
|
-
# Rye is similar to Rush[http://rush.heroku.com] but everything
|
28
|
+
# Rye is similar to Rush[http://rush.heroku.com] but everything
|
23
29
|
# happens over SSH (no HTTP daemon) and the default settings are
|
24
30
|
# less dangerous (for safety). For example, file globs and the
|
25
|
-
# "rm" command are disabled so unless otherwise specified, you
|
26
|
-
# can't do this: <tt>rbox.rm('/etc/**/*')</tt>.
|
31
|
+
# "rm" command are disabled so unless otherwise specified, you
|
32
|
+
# can't do this: <tt>rbox.rm('/etc/**/*')</tt>.
|
27
33
|
#
|
28
34
|
# However, you can do this:
|
29
35
|
#
|
@@ -31,7 +37,7 @@ require 'esc'
|
|
31
37
|
# rset.add_boxes('host1', 'host2', 'host3', 'host4')
|
32
38
|
# rset.ps('aux')
|
33
39
|
#
|
34
|
-
# * See +bin/try+ for a bunch of working examples.
|
40
|
+
# * See +bin/try+ for a bunch of working examples.
|
35
41
|
# * See Rye::Box#initialize for info about disabling safe-mode.
|
36
42
|
#
|
37
43
|
#--
|
@@ -42,22 +48,38 @@ require 'esc'
|
|
42
48
|
#++
|
43
49
|
module Rye
|
44
50
|
extend self
|
45
|
-
|
46
|
-
|
47
|
-
|
51
|
+
|
52
|
+
module VERSION
|
53
|
+
@path = File.join(Rye::HOME, 'VERSION')
|
54
|
+
class << self
|
55
|
+
attr_reader :version, :path
|
56
|
+
def version
|
57
|
+
@version || read_version
|
58
|
+
end
|
59
|
+
def read_version
|
60
|
+
return if @version
|
61
|
+
@version = File.read(path).strip!
|
62
|
+
end
|
63
|
+
def prerelease?() false end
|
64
|
+
def to_a() version.split('.') end
|
65
|
+
def to_s() version end
|
66
|
+
def inspect() version end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
48
70
|
@@sysinfo = nil
|
49
71
|
@@agent_env = Hash.new # holds ssh-agent env vars
|
50
72
|
@@mutex = Mutex.new # for synchronizing threads
|
51
|
-
|
73
|
+
|
52
74
|
# Accessor for an instance of SystemInfo
|
53
75
|
def Rye.sysinfo
|
54
76
|
@@sysinfo = SysInfo.new if @@sysinfo.nil?
|
55
77
|
@@sysinfo
|
56
78
|
end
|
57
|
-
|
79
|
+
|
58
80
|
# Accessor for an instance of SystemInfo
|
59
81
|
def sysinfo; Rye.sysinfo end
|
60
|
-
|
82
|
+
|
61
83
|
class RyeError < RuntimeError; end
|
62
84
|
class NoBoxes < RyeError; end
|
63
85
|
class NoPassword < RyeError
|
@@ -82,19 +104,19 @@ module Rye
|
|
82
104
|
def stdout; @rap.stdout if @rap; end
|
83
105
|
def exit_status; @rap.exit_status if @rap; end
|
84
106
|
end
|
85
|
-
|
86
|
-
# Reload Rye dynamically. Useful with irb.
|
87
|
-
# NOTE: does not reload rye.rb.
|
107
|
+
|
108
|
+
# Reload Rye dynamically. Useful with irb.
|
109
|
+
# NOTE: does not reload rye.rb.
|
88
110
|
def reload
|
89
111
|
pat = File.join(File.dirname(__FILE__), 'rye')
|
90
112
|
%w{key rap cmd box set hop}.each {|lib| load File.join(pat, "#{lib}.rb") }
|
91
113
|
end
|
92
|
-
|
114
|
+
|
93
115
|
def mutex
|
94
116
|
@@mutex
|
95
117
|
end
|
96
|
-
|
97
|
-
# Looks for private keys in +path+ and returns
|
118
|
+
|
119
|
+
# Looks for private keys in +path+ and returns an Array of paths
|
98
120
|
# to the files it finds. Raises an Exception if path does not exist.
|
99
121
|
# If path is a file rather than a directory, it will check whether
|
100
122
|
# that single file is a private key.
|
@@ -105,12 +127,12 @@ module Rye
|
|
105
127
|
else
|
106
128
|
files = [path]
|
107
129
|
end
|
108
|
-
|
130
|
+
|
109
131
|
files = files.select do |file|
|
110
132
|
next if File.directory?(file)
|
111
133
|
pk = nil
|
112
134
|
begin
|
113
|
-
tmp = Rye::Key.from_file(file)
|
135
|
+
tmp = Rye::Key.from_file(file)
|
114
136
|
pk = tmp if tmp.private?
|
115
137
|
rescue OpenSSL::PKey::PKeyError
|
116
138
|
end
|
@@ -118,15 +140,15 @@ module Rye
|
|
118
140
|
end
|
119
141
|
files || []
|
120
142
|
end
|
121
|
-
|
122
|
-
# Add one or more private keys to the SSH Agent.
|
123
|
-
# * +keys+ one or more file paths to private keys used for passwordless logins.
|
143
|
+
|
144
|
+
# Add one or more private keys to the SSH Agent.
|
145
|
+
# * +keys+ one or more file paths to private keys used for passwordless logins.
|
124
146
|
def add_keys(*keys)
|
125
147
|
keys = keys.flatten.compact || []
|
126
148
|
return if keys.empty?
|
127
149
|
Rye.shell("ssh-add", keys)
|
128
150
|
end
|
129
|
-
|
151
|
+
|
130
152
|
# Returns an Array of info about the currently available
|
131
153
|
# SSH keys, as provided by the SSH Agent.
|
132
154
|
#
|
@@ -142,25 +164,25 @@ module Rye
|
|
142
164
|
#end
|
143
165
|
Dir.glob(File.join(Rye.sysinfo.home, '.ssh', 'id_*sa'))
|
144
166
|
end
|
145
|
-
|
167
|
+
|
146
168
|
def remote_host_keys(*hostnames)
|
147
169
|
hostnames = hostnames.flatten.compact || []
|
148
170
|
return if hostnames.empty?
|
149
171
|
Rye.shell("ssh-keyscan", hostnames)
|
150
172
|
end
|
151
|
-
|
152
|
-
# Takes a command with arguments and returns it in a
|
153
|
-
# single String with escaped args and some other stuff.
|
154
|
-
#
|
173
|
+
|
174
|
+
# Takes a command with arguments and returns it in a
|
175
|
+
# single String with escaped args and some other stuff.
|
176
|
+
#
|
155
177
|
# * +cmd+ The shell command name or absolute path.
|
156
|
-
# * +args+ an Array of command arguments.
|
178
|
+
# * +args+ an Array of command arguments.
|
157
179
|
#
|
158
180
|
# The command is searched for in the local PATH (where
|
159
181
|
# Rye is running). An exception is raised if it's not
|
160
182
|
# found. NOTE: Because this happens locally, you won't
|
161
183
|
# want to use this method if the environment is quite
|
162
184
|
# different from the remote machine it will be executed
|
163
|
-
# on.
|
185
|
+
# on.
|
164
186
|
#
|
165
187
|
# The command arguments are passed through Escape.shell_command
|
166
188
|
# (that means you can't use environment variables or asterisks).
|
@@ -177,32 +199,32 @@ module Rye
|
|
177
199
|
end
|
178
200
|
Rye.escape(@safe, found_cmd, *args)
|
179
201
|
end
|
180
|
-
|
181
|
-
# An all ruby implementation of unix "which" command.
|
202
|
+
|
203
|
+
# An all ruby implementation of unix "which" command.
|
182
204
|
#
|
183
205
|
# * +executable+ the name of the executable
|
184
|
-
#
|
206
|
+
#
|
185
207
|
# Returns the absolute path if found in PATH otherwise nil.
|
186
208
|
def which(executable)
|
187
209
|
return unless executable.is_a?(String)
|
188
210
|
return executable if Rye.sysinfo.os == :windows
|
189
211
|
#return executable if File.exists?(executable) # SHOULD WORK, MUST TEST
|
190
212
|
shortname = File.basename(executable)
|
191
|
-
dir = Rye.sysinfo.paths.select do |path| # dir contains all of the
|
192
|
-
next unless File.exists? path # occurrences of shortname
|
193
|
-
Dir.new(path).entries.member?(shortname) # found in the paths.
|
213
|
+
dir = Rye.sysinfo.paths.select do |path| # dir contains all of the
|
214
|
+
next unless File.exists? path # occurrences of shortname
|
215
|
+
Dir.new(path).entries.member?(shortname) # found in the paths.
|
194
216
|
end
|
195
217
|
File.join(dir.first, shortname) unless dir.empty? # Return just the first
|
196
218
|
end
|
197
|
-
|
219
|
+
|
198
220
|
# Execute a local system command (via the shell, not SSH)
|
199
|
-
#
|
221
|
+
#
|
200
222
|
# * +cmd+ the executable path (relative or absolute)
|
201
223
|
# * +args+ Array of arguments to be sent to the command. Each element
|
202
224
|
# is one argument:. i.e. <tt>['-l', 'some/path']</tt>
|
203
225
|
#
|
204
226
|
# NOTE: shell is a bit paranoid so it escapes every argument. This means
|
205
|
-
# you can only use literal values. That means no asterisks too.
|
227
|
+
# you can only use literal values. That means no asterisks too.
|
206
228
|
#
|
207
229
|
# Returns a Rye::Rap object.
|
208
230
|
#
|
@@ -227,27 +249,27 @@ module Rye
|
|
227
249
|
rap.add_exit_status($?)
|
228
250
|
rap
|
229
251
|
end
|
230
|
-
|
252
|
+
|
231
253
|
# Creates a string from +cmd+ and +args+. If +safe+ is true
|
232
|
-
# it will send them through Escape.shell_command otherwise
|
233
|
-
# it will return them joined by a space character.
|
254
|
+
# it will send them through Escape.shell_command otherwise
|
255
|
+
# it will return them joined by a space character.
|
234
256
|
def escape(safe, cmd, *args)
|
235
257
|
args = args.flatten.compact || []
|
236
258
|
safe ? Escape.shell_command(cmd, *args).to_s : [cmd, args].flatten.compact.join(' ')
|
237
259
|
end
|
238
|
-
|
260
|
+
|
239
261
|
def sshagent_info
|
240
262
|
@@agent_env
|
241
263
|
end
|
242
|
-
|
243
|
-
# Returns +str+ with the leading indentation removed.
|
264
|
+
|
265
|
+
# Returns +str+ with the leading indentation removed.
|
244
266
|
# Stolen from http://github.com/mynyml/unindent/ because it was better.
|
245
267
|
def without_indent(str)
|
246
268
|
indent = str.split($/).each {|line| !line.strip.empty? }.map {|line| line.index(/[^\s]/) }.compact.min
|
247
269
|
str.gsub(/^[[:blank:]]{#{indent}}/, '')
|
248
270
|
end
|
249
|
-
|
250
|
-
#
|
271
|
+
|
272
|
+
#
|
251
273
|
# Generates a string of random alphanumeric characters.
|
252
274
|
# * +len+ is the length, an Integer. Default: 8
|
253
275
|
# * +safe+ in safe-mode, ambiguous characters are removed (default: true):
|
@@ -259,7 +281,7 @@ module Rye
|
|
259
281
|
1.upto(len) { |i| str << chars[rand(chars.size-1)] }
|
260
282
|
str
|
261
283
|
end
|
262
|
-
|
284
|
+
|
263
285
|
class Tpl
|
264
286
|
attr_reader :src, :result, :basename
|
265
287
|
def initialize(src, basename='rye-template')
|
@@ -286,13 +308,13 @@ module Rye
|
|
286
308
|
end
|
287
309
|
def to_s() src end
|
288
310
|
end
|
289
|
-
|
290
|
-
private
|
291
|
-
|
311
|
+
|
312
|
+
private
|
313
|
+
|
292
314
|
Rye.reload
|
293
|
-
|
315
|
+
|
294
316
|
end
|
295
317
|
|
296
318
|
|
297
319
|
|
298
|
-
|
320
|
+
|
data/lib/rye/box.rb
CHANGED
@@ -106,6 +106,7 @@ module Rye
|
|
106
106
|
# * :password => the user's password (ignored if there's a valid private key)
|
107
107
|
# * :templates => the template engine to use for uploaded files. One of: :erb (default)
|
108
108
|
# * :sudo => Run all commands via sudo (default: false)
|
109
|
+
# * :password_prompt => Show a password prompt on auth failure (default: true)
|
109
110
|
#
|
110
111
|
# NOTE: +opts+ can also contain any parameter supported by
|
111
112
|
# Net::SSH.start that is not already mentioned above.
|
@@ -132,7 +133,8 @@ module Rye
|
|
132
133
|
:error => STDERR,
|
133
134
|
:getenv => true,
|
134
135
|
:templates => :erb,
|
135
|
-
:quiet => false
|
136
|
+
:quiet => false,
|
137
|
+
:password_prompt => true
|
136
138
|
}.merge(opts)
|
137
139
|
|
138
140
|
# Close the SSH session before Ruby exits. This will do nothing
|
@@ -150,8 +152,9 @@ module Rye
|
|
150
152
|
@rye_ostype, @rye_impltype = @rye_opts.delete(:ostype), @rye_opts.delete(:impltype)
|
151
153
|
@rye_quiet, @rye_sudo = @rye_opts.delete(:quiet), @rye_opts.delete(:sudo)
|
152
154
|
@rye_templates = @rye_opts.delete(:templates)
|
153
|
-
|
154
|
-
|
155
|
+
@rye_password_prompt = @rye_opts.delete(:password_prompt)
|
156
|
+
|
157
|
+
# Store the state of the terminal
|
155
158
|
@rye_stty_save = `stty -g`.chomp rescue nil
|
156
159
|
|
157
160
|
unless @rye_templates.nil?
|
@@ -684,7 +687,7 @@ module Rye
|
|
684
687
|
# only auth method
|
685
688
|
if @rye_opts[:auth_methods] == ["publickey"]
|
686
689
|
raise Net::SSH::AuthenticationFailed
|
687
|
-
elsif STDIN.tty? && retried <= 3
|
690
|
+
elsif @rye_password_prompt && (STDIN.tty? && retried <= 3)
|
688
691
|
STDERR.puts "Passwordless login failed for #{@rye_user}"
|
689
692
|
@rye_opts[:password] = highline.ask("Password: ") { |q| q.echo = '' }.strip
|
690
693
|
@rye_opts[:auth_methods].push *['keyboard-interactive', 'password']
|
data/lib/rye/dsl.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'docile'
|
2
|
+
|
3
|
+
module Rye
|
4
|
+
class Set
|
5
|
+
def run cmd
|
6
|
+
instance_eval &@@command[cmd]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
@hosts, @hostsets, @contexts = {}, {}, {}
|
12
|
+
@parallel = nil
|
13
|
+
|
14
|
+
@@colors = false || ENV['COLORS'] || ENV['TERM'].match(/.*color.*/)
|
15
|
+
@@command = {}
|
16
|
+
|
17
|
+
def parallel state; @parallel = state; end
|
18
|
+
def colors state; @@colors = state; end
|
19
|
+
|
20
|
+
def host(hostname, *args, &block)
|
21
|
+
@hosts[hostname] = Rye::Box.new(hostname, *args) unless @hosts.key? hostname
|
22
|
+
Docile.dsl_eval(Rye::Set.new.add_box(@hosts[hostname]), &block) if block_given?
|
23
|
+
end
|
24
|
+
|
25
|
+
def hostset(setname, *args, &block)
|
26
|
+
@hostsets[setname] = Rye::Set.new(setname) unless @hostsets.key? setname
|
27
|
+
args.each do |host|
|
28
|
+
@hosts[host] = Rye::Box.new(host) unless @hosts.key? host
|
29
|
+
@hostsets[setname].add_box @hosts[host] unless @hostsets[setname].boxes.include? @hosts[host]
|
30
|
+
end
|
31
|
+
if @parallel
|
32
|
+
@hostsets[setname].parallel = true
|
33
|
+
Docile.dsl_eval(@hostsets[setname], &block) if block_given?
|
34
|
+
else
|
35
|
+
@hostsets[setname].boxes.each do |host|
|
36
|
+
Docile.dsl_eval(Rye::Set.new.add_box(host), &block) if block_given?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def command_group(name, &block)
|
42
|
+
@@command[name] = Proc.new &block
|
43
|
+
end
|
44
|
+
|
45
|
+
def exit_status_check(cmd, opts={})
|
46
|
+
enable_quiet_mode
|
47
|
+
@pass = opts[:pass_str] || cmd.to_s + ' Passed Status Check'
|
48
|
+
@fail = opts[:fail_str] || cmd.to_s + ' Failed Status Check'
|
49
|
+
def results(obj, out)
|
50
|
+
if obj.exit_status == 0
|
51
|
+
info out, :altstring => @pass
|
52
|
+
else
|
53
|
+
err out, :altstring => @fail
|
54
|
+
end
|
55
|
+
end
|
56
|
+
out = execute cmd
|
57
|
+
if out[0].class == Rye::Rap
|
58
|
+
out.each do |rap|
|
59
|
+
results(rap, out)
|
60
|
+
end
|
61
|
+
elsif out.exit_status == 0
|
62
|
+
results(out, out)
|
63
|
+
end
|
64
|
+
disable_quiet_mode
|
65
|
+
end
|
66
|
+
|
67
|
+
def strwrap(msg, opts={})
|
68
|
+
out = ''
|
69
|
+
unless @@colors
|
70
|
+
msg.each do |str|
|
71
|
+
unless opts.key? :altstring
|
72
|
+
out += str.to_s.gsub!(/^/, "[#{str.obj.hostname}] ") + "\n"
|
73
|
+
else
|
74
|
+
out += "[#{str.obj.hostname}] #{opts[:altstring]}\n"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
else
|
78
|
+
msg.each do |str|
|
79
|
+
unless opts.key? :altstring
|
80
|
+
out += str.to_s.gsub!(/^(.*)$/, str.obj.hostname)
|
81
|
+
else
|
82
|
+
out += "#{str.obj.hostname} " + opts[:altstring]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
out
|
87
|
+
end
|
88
|
+
|
89
|
+
def info msg, *opts
|
90
|
+
STDOUT.puts strwrap(msg, *opts)
|
91
|
+
end
|
92
|
+
|
93
|
+
def err msg, *opts
|
94
|
+
STDOUT.puts strwrap(msg, *opts)
|
95
|
+
end
|
96
|
+
|
97
|
+
def debug msg, *opts
|
98
|
+
STDOUT.puts strwrap(msg, *opts)
|
99
|
+
end
|
100
|
+
|
data/rye.gemspec
CHANGED
@@ -1,61 +1,101 @@
|
|
1
|
-
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
2
7
|
s.name = "rye"
|
3
|
-
s.
|
4
|
-
|
5
|
-
s.
|
6
|
-
s.
|
7
|
-
s.
|
8
|
+
s.version = "0.9.8"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Delano Mandelbaum"]
|
12
|
+
s.cert_chain = ["gem-public_cert.pem"]
|
13
|
+
s.date = "2013-02-06"
|
14
|
+
s.description = "Run SSH commands on a bunch of machines at the same time (from Ruby)."
|
8
15
|
s.email = "delano@solutious.com"
|
9
|
-
s.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
s.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"LICENSE.txt",
|
18
|
+
"README.rdoc"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
"CHANGES.txt",
|
22
|
+
"LICENSE.txt",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"Rudyfile",
|
26
|
+
"VERSION",
|
27
|
+
"gem-public_cert.pem",
|
28
|
+
"lib/esc.rb",
|
29
|
+
"lib/rye.rb",
|
30
|
+
"lib/rye/box.rb",
|
31
|
+
"lib/rye/cmd.rb",
|
32
|
+
"lib/rye/dsl.rb",
|
33
|
+
"lib/rye/hop.rb",
|
34
|
+
"lib/rye/key.rb",
|
35
|
+
"lib/rye/rap.rb",
|
36
|
+
"lib/rye/set.rb",
|
37
|
+
"rye.gemspec",
|
38
|
+
"try/10_basic_tryouts.rb",
|
39
|
+
"try/12_batch_tryouts.rb",
|
40
|
+
"try/13_set_tryouts.rb",
|
41
|
+
"try/14_auth_methods_tryouts.rb",
|
42
|
+
"try/15_file_tryouts.rb",
|
43
|
+
"try/20_file_transfer_tryouts.rb",
|
44
|
+
"try/25_template_upload.rb",
|
45
|
+
"try/30_safemode_tryouts.rb",
|
46
|
+
"try/35_basics_with_hop.rb",
|
47
|
+
"try/70_rye_cli_tryouts.rb",
|
48
|
+
"try/copying.rb",
|
49
|
+
"try/keys.rb",
|
50
|
+
"tst/10-key1",
|
51
|
+
"tst/10-key1.pub",
|
52
|
+
"tst/10-key2",
|
53
|
+
"tst/10-key2.pub",
|
54
|
+
"tst/10_keys_test.rb",
|
55
|
+
"tst/50_rset_test.rb",
|
56
|
+
"tst/60-file.mp3",
|
57
|
+
"tst/60_rbox_transfer_test.rb",
|
58
|
+
"tst/65_rbox_file_append_test.rb",
|
59
|
+
"tst/70_rbox_env_test.rb",
|
60
|
+
"tst/dsl_example.rb",
|
61
|
+
"tst/rye.rb",
|
62
|
+
"tst/shell.rb",
|
63
|
+
"tst/shell2.rb",
|
64
|
+
"tst/shell3.rb",
|
65
|
+
"tst/test_hop.rb"
|
66
|
+
]
|
67
|
+
s.homepage = "https://github.com/delano/rye"
|
68
|
+
s.require_paths = ["lib"]
|
69
|
+
s.rubyforge_project = "rye"
|
70
|
+
s.rubygems_version = "1.8.25"
|
71
|
+
s.signing_key = "/mnt/gem/gem-private_key.pem"
|
72
|
+
s.summary = "Run SSH commands on a bunch of machines at the same time (from Ruby)."
|
55
73
|
|
56
74
|
if s.respond_to? :specification_version then
|
57
|
-
|
58
|
-
|
75
|
+
s.specification_version = 3
|
76
|
+
|
77
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
78
|
+
s.add_runtime_dependency(%q<annoy>, [">= 0"])
|
79
|
+
s.add_runtime_dependency(%q<sysinfo>, [">= 0.7.3"])
|
80
|
+
s.add_runtime_dependency(%q<highline>, [">= 1.5.1"])
|
81
|
+
s.add_runtime_dependency(%q<net-ssh>, [">= 2.0.13"])
|
82
|
+
s.add_runtime_dependency(%q<net-scp>, [">= 1.0.2"])
|
83
|
+
s.add_runtime_dependency(%q<docile>, [">= 1.0.1"])
|
84
|
+
else
|
85
|
+
s.add_dependency(%q<annoy>, [">= 0"])
|
86
|
+
s.add_dependency(%q<sysinfo>, [">= 0.7.3"])
|
87
|
+
s.add_dependency(%q<highline>, [">= 1.5.1"])
|
88
|
+
s.add_dependency(%q<net-ssh>, [">= 2.0.13"])
|
89
|
+
s.add_dependency(%q<net-scp>, [">= 1.0.2"])
|
90
|
+
s.add_dependency(%q<docile>, [">= 1.0.1"])
|
91
|
+
end
|
92
|
+
else
|
93
|
+
s.add_dependency(%q<annoy>, [">= 0"])
|
94
|
+
s.add_dependency(%q<sysinfo>, [">= 0.7.3"])
|
95
|
+
s.add_dependency(%q<highline>, [">= 1.5.1"])
|
96
|
+
s.add_dependency(%q<net-ssh>, [">= 2.0.13"])
|
97
|
+
s.add_dependency(%q<net-scp>, [">= 1.0.2"])
|
98
|
+
s.add_dependency(%q<docile>, [">= 1.0.1"])
|
59
99
|
end
|
60
|
-
|
61
100
|
end
|
101
|
+
|