rye 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.txt CHANGED
@@ -4,6 +4,12 @@ TODO
4
4
 
5
5
  * Fingerprints: ssh-keygen -l -f id_rsa_repos.pub
6
6
 
7
+ #### 0.6.1 (2009-04-29) #############################
8
+
9
+ * ADDED: Prints message to STDERR when passwordless login fails.
10
+ * ADDED: Highline 1.5.1 to vendor to fix the Ruby 1.9 issue (Highline
11
+ 1.5.1 is not released as a gem yet)
12
+ * CHANGE: Cleaned examples and links in README
7
13
 
8
14
  #### 0.6.0 (2009-04-28) #############################
9
15
 
data/README.rdoc CHANGED
@@ -4,7 +4,6 @@ Safely run SSH commands on a bunch of machines at the same time (from Ruby).
4
4
 
5
5
  Rye is similar to Rush[http://rush.heroku.com] but everything happens over SSH (no HTTP daemon) and the default settings are less powerful (for safety). For example, file globs and the "rm" command are disabled so unless otherwise specified, you can't do this: <tt>rbox.rm('-rf', '/etc/**/*')</tt>.
6
6
 
7
- See the examples below (which are taken from bin/try).
8
7
 
9
8
  == Installation
10
9
 
@@ -15,85 +14,35 @@ One of:
15
14
  $ git clone git://github.com/delano/rye.git
16
15
 
17
16
 
18
- == EXAMPLE 1 -- Basic Usage
19
-
20
- rbox = Rye::Box.new('localhost')
21
-
22
- # Commands are run as methods on the Rye::Box object
23
- puts rbox.uptime # => 11:02 up 16:01, 3 users
24
-
25
- # The response value for all commands is a Rye::Rap object. The rap is a
26
- # subclass of Array so you can treat it as an Array, but it can also act
27
- # like a String if there's only one element.
28
- puts rbox.ls('rye.test') # => ""
29
- puts rbox.ls('rye.test').stderr # => ls: rye.test: No such file or directory
30
-
31
- puts rbox.touch('rye.test') # => ""
32
- puts rbox.rm('rye.test') # => ""
33
-
34
- # You can change directories
35
- puts rbox.pwd # => /home/rye
36
- puts rbox['/usr/bin'].pwd # => /usr/bin
37
- puts rbox.pwd # => /usr/bin
38
- puts rbox.cd('/home/rye').pwd # => /home/rye
39
-
40
- # You can specify environment variables
41
- rbox.setenv(:RYE, "Forty Creek")
42
- rbox.env # => ['HOME=/home/rye', 'RYE=Forty Creek', ...]
43
-
44
- # The commands method returns an Array of available commands:
45
- puts rbox.commands.join(', ') # => pwd, touch, echo, wc, ...
46
-
47
- # When you're done you can disconnect explicitly.
48
- # (Although Rye does this automatically at exit.)
49
- rbox.disconnect
50
-
17
+ See bin/try for examples!
51
18
 
52
- == EXAMPLE 2 -- Disabling Safe-Mode
53
19
 
54
- rbox_safe = Rye::Box.new('localhost')
55
- rbox_wild = Rye::Box.new('localhost', :safe => false)
20
+ == EXAMPLE 1 -- SSH Authorization
56
21
 
57
- # Safe-mode is enabled by default. In safe-mode, all command
58
- # arguments are thoroughly escaped. This prevents access to
59
- # environment variables and file globs (among other things).
60
- p rbox_safe.echo('$HOME') # => "$HOME"
61
- p rbox_safe['/etc'].ls('host*') rescue Rye::CommandError # Doesn't exist
62
- p rbox_safe.ls('-l | wc -l') rescue Rye::CommandError # => '|' is not a valid ls arg
22
+ Does it annoy you to manually authorize remote SSH accounts? Rye can help!
63
23
 
64
- # Here's the same commands with safe-mode disabled:
65
- p rbox_wild.echo('$HOME') # => "/home/rye"
66
- p rbox_wild['/etc'].ls('host*') # => ["hostconfig", "hosts"]
67
- p rbox_wild.ls('-l | wc -l') # => 110
68
- p rbox_wild.echo('$HOME > /tmp/rye-home') # =>
69
- p rbox_wild.cat('/tmp/rye-home') # => "/home/rye"
24
+ Enable passwordless logins to HOST1 and HOST2:
70
25
 
26
+ $ rye authorize HOST1 HOST2
71
27
 
72
- == EXAMPLE 3 -- Custom Commands
28
+ This will copy your public SSH keys to the <tt>~/.ssh/authorized_keys</tt> and <tt>~/.ssh/authorized_keys2</tt> files on the remote machine(s).
73
29
 
74
- rbox = Rye::Box.new('localhost')
75
- rbox.add_keys('/private/key/path') # Specify additional private keys
30
+ See <tt>rye -h</tt> for more info
76
31
 
77
- # There's currently no rye900 command
78
- p rbox.commands.member?('rye9000') # => false
79
32
 
80
- # But we can add our own commands to the Rye::Cmd class. They
81
- # automatically become available to all Rye::Box objects.
82
- module Rye::Cmd
83
- def rye9000(*args)
84
- run_command("ls", args)
85
- end
86
- def somescript(*args)
87
- run_command("/path/to/my/script", args)
88
- end
89
- end
33
+ == EXAMPLE 2 -- Basic Usage
90
34
 
91
- # We can now run rye9000 (with arguments)
92
- p rbox.rye9000('-a') # => [".", "..", ".bashrc", ...]
93
- p rbox.commands.member?('rye9000') # => true
94
-
35
+ rbox = Rye::Box.new('localhost')
36
+ rbox.uptime # => 11:02 up 16:01, 3 users
37
+ rbox['/usr/bin'].pwd # => /usr/bin
38
+
39
+ You can specify environment variables
95
40
 
96
- == EXAMPLE 4 -- Accessing Multiple Machines
41
+ rbox.setenv(:RYE, "Forty Creek")
42
+ rbox.env # => ['HOME=/home/rye', 'RYE=Forty Creek', ...]
43
+
44
+
45
+ == EXAMPLE 3 -- Accessing Multiple Machines
97
46
 
98
47
  rset = Rye::Set.new
99
48
  rbox = Rye::Box.new
@@ -101,59 +50,13 @@ One of:
101
50
  rset.add_keys('/private/key/path') # For passwordless logins
102
51
  rset.add_boxes(rbox, 'localhost') # Add boxes as hostnames or objects
103
52
 
104
- # Calling methods on Rye::Set objects is very similar to calling them on
105
- # Rye::Box objects. In fact, it's identical:
53
+ Calling methods on Rye::Set objects is very similar to calling them on Rye::Box objects. In fact, it's identical:
54
+
106
55
  p rset.uptime # => [[14:19:02 up 32 days, 19:35 ...], [14:19:02 up 30 days, 01:35]]
107
56
  p rset['/etc'].ls # => [['file1', 'file2', ...], ['life1', 'life2', ...]]
108
57
 
109
- # Like Rye::Box, the response value is a Rye::Rap object containing the
110
- # responses from each box. Each response is itself a Rye::Rap object.
111
- unames = rset.uname
112
- p unames # => [["Darwin"], ["Darwin"]]
113
- puts unames.class # => Rye::Rap
114
-
115
- # The Rye::Rap object also keeps a reference to the object that called the
116
- # command. In this case, it will keep a reference to Rye::Set:
117
- puts unames.set.class # => Rye::Set
118
- puts unames.set == rset # => true
119
- puts unames.size # => 2
120
- puts unames.first # => Darwin
121
- puts unames.first.class # => Rye::Rap
122
- puts unames.first.box.class # => Rye::Box
123
- puts unames.first.box == rbox # => true
124
-
125
- # Envrionment variables can be set the same way as with Rye::Box
126
- rset.setenv(:RYE, "Forty Creek")
127
- p rset.env.first.select { |env| env =~ /RYE/ } # => ["RYE=Forty Creek"]
128
-
129
-
130
- == EXAMPLE 5 -- ERROR HANDLING
131
-
132
- rbox = Rye::Box.new('localhost', :safe => false)
133
-
134
- # Rye follows the standard convention of taking exception to a non-zero
135
- # exit code by raising a Rye::CommandError. In this case, rye9000.test
136
- # is not found by the ls command.
137
- begin
138
- rbox.ls('rye9000.test')
139
- rescue Rye::CommandError => ex
140
- puts ex.exit_code # => 1
141
- puts ex.stderr # => ls: rye.test: No such file or directory
142
- end
143
-
144
- # The Rye:Rap response objects also give you the STDOUT and STDERR
145
- # content separately. Here we redirect STDOUT to STDERR, so this
146
- # will return nothing:
147
- puts rbox.uname('-a 1>&2').stdout # =>
148
-
149
- # It all went to STDERR:
150
- puts rbox.uname('-a 1>&2').stderr # => Darwin ryehost 9.6.0 ...
151
-
152
- # There were no actual error so the exit code should be 0.
153
- puts rbox.uname('-a 1>&2').exit_code # => 0
154
-
155
58
 
156
- == EXAMPLE 6 -- FILE TRANSFERS
59
+ == EXAMPLE 4 -- FILE TRANSFERS
157
60
 
158
61
  rbox = Rye::Box.new("localhost", :info => true)
159
62
 
@@ -174,25 +77,6 @@ One of:
174
77
 
175
78
  p filecontent.read
176
79
 
177
- == EXAMPLE 7 -- rye
178
-
179
- Rye comes with a command-line utility called <tt>rye</tt>.
180
-
181
- # Prints the paths to your private keys
182
- $ rye keys
183
-
184
- # Prints the server host keys (suitable for ~/.ssh/known_hosts)
185
- $ rye hostkey HOST1 HOST2
186
-
187
- # Add your public keys to authorized_keys and authorized_keys2
188
- # on a remote machine
189
- $ rye authorize HOST1 HOST2
190
- More info:
191
-
192
- $ rye -h
193
- $ rye COMMAND -h
194
- $ rye show-commands
195
-
196
80
 
197
81
  == About Safe-Mode
198
82
 
@@ -221,6 +105,7 @@ Rye permits only a limited number of system commands to be run. This default whi
221
105
  * highline
222
106
  * drydock
223
107
 
108
+
224
109
  == Known Issues
225
110
 
226
111
  This list will grow. If you find one let me know!
@@ -229,20 +114,20 @@ This list will grow. If you find one let me know!
229
114
  * Highline 1.5 not working in Ruby 1.9 (password prompts hang)
230
115
  * Rye uses OpenSSL's ssh-agent (if it exists). Rye starts it up as a child process and shuts it down using at_exit. If you have code in an at_exit that rely's on Rye, make sure your code runs before Rye's at_exit block is called. For example, Drydock uses at_exit too which is why in bin/rye you can see that Drydock is called explicitly so that Rye's at_exit is executed after Drydock executes a command.
231
116
 
117
+
232
118
  == Thanks
233
119
 
234
120
  * Solutious Incorporated (http://solutious.com) for all the orange juice.
235
- * http://github.com/adamwiggins/rush
236
- * http://github.com/jamis/capistrano/blob/master/lib/capistrano/shell.rb
237
- * http://www.nofluffjuststuff.com/blog/david_bock/2008/10/ruby_s_closure_cleanup_idiom_and_net_ssh.html
238
- * http://groups.google.com/group/ruby-talk-google/browse_thread/thread/674a6f6de15ceb49?pli=1
239
- * http://paste.lisp.org/display/6912
121
+ * Kalin Harvey (http://rely.ca)
122
+ * Rush[http://github.com/adamwiggins/rush]
123
+ * Capistrano[http://github.com/jamis/capistrano/blob/master/lib/capistrano/shell.rb]
124
+
240
125
 
241
126
  == More Info
242
127
 
243
- * http://github.com/delano/rye
244
- * http://delano.github.com/rye
245
- * http://www.youtube.com/watch?v=_StUVh6ENuw
128
+ * GitHub[http://github.com/delano/rye]
129
+ * Rdocs[http://delano.github.com/rye]
130
+ * Inspiration[http://www.youtube.com/watch?v=_StUVh6ENuw]
246
131
 
247
132
  == Credits
248
133
 
data/bin/rye CHANGED
@@ -35,7 +35,8 @@ after do
35
35
 
36
36
  end
37
37
 
38
- desc "Add your public keys to one or more remote machines"
38
+ about "Add your public keys to one or more remote machines"
39
+ usage "rye authorize [-u username] host"
39
40
  option :u, :user, String, "Username"
40
41
  argv :hostname
41
42
  command :authorize do |obj|
@@ -56,7 +57,7 @@ command :authorize do |obj|
56
57
  end
57
58
  command_alias :authorize, :authorise
58
59
 
59
- desc "Add your public keys to your current account on this machine"
60
+ about "Add your public keys to your current account on this machine"
60
61
  command :authorize_local do |obj|
61
62
  user = Rye.sysinfo.user
62
63
  puts "Authorizing #{user}@localhost"
@@ -68,11 +69,11 @@ end
68
69
  command_alias :local_authorize, :local_authorise
69
70
 
70
71
 
71
- desc "Generate a public key from a private key"
72
+ about "Generate a public key from a private key"
72
73
 
73
74
 
74
75
 
75
- desc "Fetch the host keys for remote machines (suitable for your ~/.ssh/known_hosts file)"
76
+ about "Fetch the host keys for remote machines (suitable for your ~/.ssh/known_hosts file)"
76
77
  usage "rye hostkey HOSTNAME [HOSTNAME2 HOSTNAME3 ...]"
77
78
  argv :hostname
78
79
  command :hostkeys do |obj|
@@ -84,14 +85,14 @@ end
84
85
  command_alias :hostkeys, :hostkey
85
86
 
86
87
 
87
- desc "Display your private keys"
88
+ about "Display your private keys"
88
89
  command :keys do |obj|
89
90
  Rye.keys.each do |key|
90
91
  puts key.join(' ')
91
92
  end
92
93
  end
93
94
 
94
- desc "Display your public SSH keys"
95
+ about "Display your public SSH keys"
95
96
  usage "rye pubkeys [--pem] [KEYPATH]"
96
97
  option :p, :pem, "Output in PEM format"
97
98
  argv :keypath
data/lib/rye.rb CHANGED
@@ -1,5 +1,7 @@
1
1
 
2
- require 'rubygems' unless defined? Gem
2
+ # Temporary fix before Highline 1.5.1 is release. This fixes
3
+ # a the issue with Ruby 1.9 that causes the prompts to hang.
4
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'vendor', 'highline-1.5.1')
3
5
 
4
6
  require 'tempfile'
5
7
  require 'logger'
@@ -32,6 +34,12 @@ require 'sys'
32
34
  # * See +bin/try+ for a bunch of working examples.
33
35
  # * See Rye::Box#initialize for info about disabling safe-mode.
34
36
  #
37
+ #--
38
+ # The following posts were really helpful when I first wrote Rye:
39
+ # http://www.nofluffjuststuff.com/blog/david_bock/2008/10/ruby_s_closure_cleanup_idiom_and_net_ssh.html
40
+ # http://groups.google.com/group/ruby-talk-google/browse_thread/thread/674a6f6de15ceb49?pli=1
41
+ # http://paste.lisp.org/display/6912
42
+ #++
35
43
  module Rye
36
44
  extend self
37
45
 
data/lib/rye/box.rb CHANGED
@@ -182,6 +182,7 @@ module Rye
182
182
  print "\a" if retried == 0 && @info # Ring the bell once
183
183
  retried += 1
184
184
  if STDIN.tty? && retried <= 3
185
+ STDERR.puts "Passwordless login failed for #{@opts[:user]}"
185
186
  @opts[:password] = highline.ask("Password: ") { |q| q.echo = '' }
186
187
  @opts[:auth_methods] ||= []
187
188
  @opts[:auth_methods] << 'password'
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.6.0"
4
+ s.version = "0.6.1"
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.6.0
4
+ version: 0.6.1
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: 2009-04-28 00:00:00 -04:00
12
+ date: 2009-04-29 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency