rye 0.8.11 → 0.8.12
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.
- data/CHANGES.txt +12 -1
- data/README.rdoc +1 -0
- data/lib/rye.rb +3 -70
- data/lib/rye/box.rb +22 -11
- data/lib/rye/cmd.rb +4 -3
- data/rye.gemspec +1 -1
- metadata +2 -2
data/CHANGES.txt
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
RYE, CHANGES
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
#### 0.8.12 (2010-01-16) #############################
|
|
5
|
+
|
|
6
|
+
* FIXED: Removed dependency on ssh-agent. Also fixes starting
|
|
7
|
+
many instances of said executable.
|
|
8
|
+
* FIXED: file_append was overwriting when supplied a String (!)
|
|
9
|
+
* ADDED: Use SSH config file by default [Justin Case]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
#### 0.8.12 (2009-11-06) #############################
|
|
13
|
+
|
|
14
|
+
* ADDED: Use SSH config file by default
|
|
4
15
|
|
|
5
16
|
#### 0.8.11 (2009-10-30) #############################
|
|
6
17
|
|
data/README.rdoc
CHANGED
|
@@ -227,6 +227,7 @@ If you find one let me know!
|
|
|
227
227
|
* Kalin Harvey (http://rely.ca)
|
|
228
228
|
* Rush[http://github.com/adamwiggins/rush] and Capistrano[http://github.com/jamis/capistrano/blob/master/lib/capistrano/shell.rb] for the inspiration.
|
|
229
229
|
* Mike Cline for giving the okay to use the Rye name.
|
|
230
|
+
* Justin Case (http://github.com/justincase/) for fixes
|
|
230
231
|
|
|
231
232
|
|
|
232
233
|
== More Info
|
data/lib/rye.rb
CHANGED
|
@@ -42,7 +42,7 @@ require 'esc'
|
|
|
42
42
|
module Rye
|
|
43
43
|
extend self
|
|
44
44
|
|
|
45
|
-
VERSION = "0.8.
|
|
45
|
+
VERSION = "0.8.12".freeze unless defined?(VERSION)
|
|
46
46
|
|
|
47
47
|
@@sysinfo = nil
|
|
48
48
|
@@agent_env = Hash.new # holds ssh-agent env vars
|
|
@@ -94,7 +94,7 @@ module Rye
|
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
# Looks for private keys in +path+ and returns and Array of paths
|
|
97
|
-
# to the files it
|
|
97
|
+
# to the files it finds. Raises an Exception if path does not exist.
|
|
98
98
|
# If path is a file rather than a directory, it will check whether
|
|
99
99
|
# that single file is a private key.
|
|
100
100
|
def find_private_keys(path)
|
|
@@ -127,8 +127,7 @@ module Rye
|
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
# Returns an Array of info about the currently available
|
|
130
|
-
# SSH keys, as provided by the SSH Agent.
|
|
131
|
-
# Rye.start_sshagent_environment
|
|
130
|
+
# SSH keys, as provided by the SSH Agent.
|
|
132
131
|
#
|
|
133
132
|
# Returns: [[bits, finger-print, file-path], ...]
|
|
134
133
|
#
|
|
@@ -262,74 +261,8 @@ module Rye
|
|
|
262
261
|
|
|
263
262
|
private
|
|
264
263
|
|
|
265
|
-
# Start the SSH Agent locally. This is important
|
|
266
|
-
# primarily because Rye relies on it for SSH key
|
|
267
|
-
# management. If the agent doesn't start then
|
|
268
|
-
# passwordless logins won't work.
|
|
269
|
-
#
|
|
270
|
-
# This method starts an instances of ssh-agent
|
|
271
|
-
# and sets the appropriate environment so all
|
|
272
|
-
# local commands run by Rye will have access be aware
|
|
273
|
-
# of this instance of the agent too.
|
|
274
|
-
#
|
|
275
|
-
# The equivalent commands on the shell are:
|
|
276
|
-
#
|
|
277
|
-
# $ ssh-agent -s
|
|
278
|
-
# SSH_AUTH_SOCK=/tmp/ssh-tGvaOXIXSr/agent.12951; export SSH_AUTH_SOCK;
|
|
279
|
-
# SSH_AGENT_PID=12952; export SSH_AGENT_PID;
|
|
280
|
-
# $ SSH_AUTH_SOCK=/tmp/ssh-tGvaOXIXSr/agent.12951; export SSH_AUTH_SOCK;
|
|
281
|
-
# $ SSH_AGENT_PID=12952; export SSH_AGENT_PID;
|
|
282
|
-
#
|
|
283
|
-
# NOTE: The OpenSSH library must be installed for this to work.
|
|
284
|
-
#
|
|
285
|
-
def start_sshagent_environment
|
|
286
|
-
return if @@agent_env["SSH_AGENT_PID"]
|
|
287
|
-
lines = Rye.shell("ssh-agent", '-s') || []
|
|
288
|
-
lines.each do |line|
|
|
289
|
-
next unless line.index("echo").nil?
|
|
290
|
-
line = line.slice(0..(line.index(';')-1))
|
|
291
|
-
key, value = line.chomp.split( /=/ )
|
|
292
|
-
@@agent_env[key] = value
|
|
293
|
-
end
|
|
294
|
-
ENV["SSH_AUTH_SOCK"] = @@agent_env["SSH_AUTH_SOCK"]
|
|
295
|
-
ENV["SSH_AGENT_PID"] = @@agent_env["SSH_AGENT_PID"]
|
|
296
|
-
|
|
297
|
-
Rye.shell("ssh-add") # Add the user's default keys
|
|
298
|
-
nil
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
# Kill the local instance of the SSH Agent we started.
|
|
302
|
-
#
|
|
303
|
-
# Calls this command via the local shell:
|
|
304
|
-
#
|
|
305
|
-
# $ ssh-agent -k
|
|
306
|
-
#
|
|
307
|
-
# which uses the SSH_AUTH_SOCK and SSH_AGENT_PID environment variables
|
|
308
|
-
# to determine which ssh-agent to kill.
|
|
309
|
-
#
|
|
310
|
-
def end_sshagent_environment
|
|
311
|
-
pid = @@agent_env["SSH_AGENT_PID"]
|
|
312
|
-
Rye.shell("ssh-agent", '-k') || []
|
|
313
|
-
#Rye.shell("kill", ['-9', pid]) if pid
|
|
314
|
-
@@agent_env.clear
|
|
315
|
-
nil
|
|
316
|
-
end
|
|
317
|
-
|
|
318
264
|
Rye.reload
|
|
319
265
|
|
|
320
|
-
unless Rye.sysinfo.os == :windows
|
|
321
|
-
begin
|
|
322
|
-
@@mutex.synchronize { # One thread only
|
|
323
|
-
start_sshagent_environment # Run this now
|
|
324
|
-
at_exit { end_sshagent_environment } # Run this before Ruby exits
|
|
325
|
-
}
|
|
326
|
-
rescue => ex
|
|
327
|
-
STDERR.puts "Error initializing the SSH Agent (is OpenSSH installed?):"
|
|
328
|
-
STDERR.puts ex.message
|
|
329
|
-
STDERR.puts ex.backtrace
|
|
330
|
-
exit 1
|
|
331
|
-
end
|
|
332
|
-
end
|
|
333
266
|
end
|
|
334
267
|
|
|
335
268
|
|
data/lib/rye/box.rb
CHANGED
|
@@ -32,7 +32,7 @@ module Rye
|
|
|
32
32
|
def host; @rye_host; end
|
|
33
33
|
def opts; @rye_opts; end
|
|
34
34
|
def safe; @rye_safe; end
|
|
35
|
-
def user;
|
|
35
|
+
def user; @rye_user; end
|
|
36
36
|
|
|
37
37
|
# Returns the current value of the stash +@rye_stash+
|
|
38
38
|
def stash; @rye_stash; end
|
|
@@ -70,13 +70,14 @@ module Rye
|
|
|
70
70
|
# A Hash. The keys are exception classes, the values are Procs to execute
|
|
71
71
|
def exception_hook=(val); @rye_exception_hook = val; end
|
|
72
72
|
|
|
73
|
-
# * +host+ The hostname to connect to.
|
|
73
|
+
# * +host+ The hostname to connect to. Default: localhost.
|
|
74
|
+
# * +user+ The username to connect as. Default: SSH config file or current shell user.
|
|
74
75
|
# * +opts+ a hash of optional arguments.
|
|
75
76
|
#
|
|
76
77
|
# The +opts+ hash excepts the following keys:
|
|
77
78
|
#
|
|
78
|
-
# * :user => the username to connect as. Default: the current user.
|
|
79
79
|
# * :safe => should Rye be safe? Default: true
|
|
80
|
+
# * :port => remote server ssh port. Default: SSH config file or 22
|
|
80
81
|
# * :keys => one or more private key file paths (passwordless login)
|
|
81
82
|
# * :info => an IO object to print Rye::Box command info to. Default: nil
|
|
82
83
|
# * :debug => an IO object to print Rye::Box debugging info to. Default: nil
|
|
@@ -88,14 +89,20 @@ module Rye
|
|
|
88
89
|
# Net::SSH.start that is not already mentioned above.
|
|
89
90
|
#
|
|
90
91
|
def initialize(host='localhost', opts={})
|
|
92
|
+
ssh_opts = ssh_config_options(host)
|
|
91
93
|
@rye_exception_hook = {}
|
|
92
94
|
@rye_host = host
|
|
93
95
|
|
|
96
|
+
if opts[:user]
|
|
97
|
+
@rye_user = opts[:user]
|
|
98
|
+
else
|
|
99
|
+
@rye_user = ssh_opts[:user] || Rye.sysinfo.user
|
|
100
|
+
end
|
|
101
|
+
|
|
94
102
|
# These opts are use by Rye::Box and also passed to Net::SSH
|
|
95
103
|
@rye_opts = {
|
|
96
|
-
:user => Rye.sysinfo.user,
|
|
97
104
|
:safe => true,
|
|
98
|
-
:port =>
|
|
105
|
+
:port => ssh_opts[:port],
|
|
99
106
|
:keys => [],
|
|
100
107
|
:info => nil,
|
|
101
108
|
:debug => nil,
|
|
@@ -141,6 +148,10 @@ module Rye
|
|
|
141
148
|
|
|
142
149
|
end
|
|
143
150
|
|
|
151
|
+
# Parse SSH config files for use with Net::SSH
|
|
152
|
+
def ssh_config_options(host)
|
|
153
|
+
return Net::SSH::Config.for(host)
|
|
154
|
+
end
|
|
144
155
|
|
|
145
156
|
# Change the current working directory (sort of).
|
|
146
157
|
#
|
|
@@ -201,7 +212,7 @@ module Rye
|
|
|
201
212
|
def switch_user(newuser)
|
|
202
213
|
return if newuser.to_s == self.user.to_s
|
|
203
214
|
@rye_opts ||= {}
|
|
204
|
-
@
|
|
215
|
+
@rye_user = newuser
|
|
205
216
|
disconnect
|
|
206
217
|
end
|
|
207
218
|
|
|
@@ -215,7 +226,7 @@ module Rye
|
|
|
215
226
|
def interactive_ssh(run=true)
|
|
216
227
|
debug "interactive_ssh with keys: #{Rye.keys.inspect}"
|
|
217
228
|
run = false unless STDIN.tty?
|
|
218
|
-
cmd = Rye.prepare_command("ssh", "#{@
|
|
229
|
+
cmd = Rye.prepare_command("ssh", "#{@rye_user}@#{@rye_host}")
|
|
219
230
|
return cmd unless run
|
|
220
231
|
system(cmd)
|
|
221
232
|
end
|
|
@@ -613,12 +624,12 @@ module Rye
|
|
|
613
624
|
raise Rye::NoHost unless @rye_host
|
|
614
625
|
return if @rye_ssh && !reconnect
|
|
615
626
|
disconnect if @rye_ssh
|
|
616
|
-
debug "Opening connection to #{@rye_host} as #{@
|
|
627
|
+
debug "Opening connection to #{@rye_host} as #{@rye_user}"
|
|
617
628
|
highline = HighLine.new # Used for password prompt
|
|
618
629
|
retried = 0
|
|
619
630
|
@rye_opts[:keys].compact! # A quick fix in Windows. TODO: Why is there a nil?
|
|
620
631
|
begin
|
|
621
|
-
@rye_ssh = Net::SSH.start(@rye_host, @
|
|
632
|
+
@rye_ssh = Net::SSH.start(@rye_host, @rye_user, @rye_opts || {})
|
|
622
633
|
rescue Net::SSH::HostKeyMismatch => ex
|
|
623
634
|
STDERR.puts ex.message
|
|
624
635
|
print "\a" if @rye_info # Ring the bell
|
|
@@ -632,7 +643,7 @@ module Rye
|
|
|
632
643
|
print "\a" if retried == 0 && @rye_info # Ring the bell once
|
|
633
644
|
retried += 1
|
|
634
645
|
if STDIN.tty? && retried <= 3
|
|
635
|
-
STDERR.puts "Passwordless login failed for #{@
|
|
646
|
+
STDERR.puts "Passwordless login failed for #{@rye_user}"
|
|
636
647
|
@rye_opts[:password] = highline.ask("Password: ") { |q| q.echo = '' }
|
|
637
648
|
@rye_opts[:auth_methods] ||= []
|
|
638
649
|
@rye_opts[:auth_methods] << 'password'
|
|
@@ -967,7 +978,7 @@ module Rye
|
|
|
967
978
|
self.mkdir(:p, target) unless self.file_exists?(target)
|
|
968
979
|
end
|
|
969
980
|
|
|
970
|
-
Net::SCP.start(@rye_host, @
|
|
981
|
+
Net::SCP.start(@rye_host, @rye_user, @rye_opts || {}) do |scp|
|
|
971
982
|
transfers = []
|
|
972
983
|
prev = ""
|
|
973
984
|
files.each do |file|
|
data/lib/rye/cmd.rb
CHANGED
|
@@ -150,12 +150,13 @@ module Rye;
|
|
|
150
150
|
# it will be created. If +backup+ is specified, +filepath+ will be
|
|
151
151
|
# copied to +filepath-previous+ before appending.
|
|
152
152
|
def file_append(filepath, newcontent, backup=false)
|
|
153
|
+
content = StringIO.new
|
|
154
|
+
|
|
153
155
|
if self.file_exists?(filepath)
|
|
154
156
|
self.cp filepath, "#{filepath}-previous" if backup
|
|
155
|
-
|
|
157
|
+
content = self.file_download filepath
|
|
156
158
|
end
|
|
157
|
-
|
|
158
|
-
content = StringIO.new
|
|
159
|
+
|
|
159
160
|
if newcontent.is_a?(StringIO)
|
|
160
161
|
newcontent.rewind
|
|
161
162
|
content.puts newcontent.read
|
data/rye.gemspec
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
|
2
2
|
s.name = "rye"
|
|
3
3
|
s.rubyforge_project = "rye"
|
|
4
|
-
s.version = "0.8.
|
|
4
|
+
s.version = "0.8.12"
|
|
5
5
|
s.summary = "Rye: Safely run SSH commands on a bunch of machines at the same time (from Ruby)."
|
|
6
6
|
s.description = s.summary
|
|
7
7
|
s.author = "Delano Mandelbaum"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rye
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Delano Mandelbaum
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date:
|
|
12
|
+
date: 2010-01-16 00:00:00 -05:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|