rye 0.8.0 → 0.8.1
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 +8 -0
- data/Rudyfile +135 -0
- data/bin/try +202 -0
- data/lib/rye.rb +1 -1
- data/lib/rye/box.rb +46 -37
- data/lib/rye/cmd.rb +5 -0
- data/rye.gemspec +3 -1
- metadata +3 -1
data/CHANGES.txt
CHANGED
@@ -6,6 +6,14 @@ TODO
|
|
6
6
|
* Fingerprints: ssh-keygen -l -f id_rsa_repos.pub
|
7
7
|
* Add S3 support for Rye::Box.upload / download
|
8
8
|
|
9
|
+
#### 0.8.1 (2009-06-22) #############################
|
10
|
+
|
11
|
+
* FIXED: file_upload now handles globs like a champ
|
12
|
+
* FIXED: Handling of relative paths in Rye::Box#cd and Rye::Box#[]
|
13
|
+
* ADDED: file_upload now assumes uploading to home directory when only 1 arg
|
14
|
+
* ADDED: Rudyfile for remote 'clean-machine' tests
|
15
|
+
* CHANGE: guess_user_home, ostype, and getenv now run quietly
|
16
|
+
|
9
17
|
|
10
18
|
#### 0.8.0 (2009-06-21) #############################
|
11
19
|
|
data/Rudyfile
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# = Rudy configuration
|
2
|
+
#
|
3
|
+
|
4
|
+
# ----------------------------------------------------------- DEFAULTS --------
|
5
|
+
# These values are used as defaults for their respective global settings. All
|
6
|
+
# non-boolean values are expected to be Symbols.
|
7
|
+
#
|
8
|
+
defaults do
|
9
|
+
zone :'eu-west-1b'
|
10
|
+
environment :rye
|
11
|
+
color true # Terminal colors? true/false
|
12
|
+
yes false # Auto-confirm? true/false
|
13
|
+
end
|
14
|
+
|
15
|
+
# --------------------------------------------------------- MACHINES --------
|
16
|
+
# The machines block describes the 'physical' characteristics of your machines.
|
17
|
+
machines do
|
18
|
+
|
19
|
+
zone :'us-east-1b' do
|
20
|
+
ami 'ami-e348af8a' # Alestic Debian 5.0, 32-bit (US)
|
21
|
+
bucket 'rudy-ami-us'
|
22
|
+
end
|
23
|
+
zone :'eu-west-1b' do
|
24
|
+
ami 'ami-1dbd9569' # rudy-ami-eu/debian-5.0-32-ruby-r1
|
25
|
+
bucket 'rudy-ami-eu'
|
26
|
+
end
|
27
|
+
|
28
|
+
hostname :rudy # One of: :default, :rudy, 'your-name'
|
29
|
+
|
30
|
+
env :rye do
|
31
|
+
user :root # User to connect as
|
32
|
+
size 'm1.small' # EC2 machine type for all machines
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# ----------------------------------------------------------- COMMANDS --------
|
39
|
+
# The commands block defines shell commands that can be used in routines. The
|
40
|
+
# ones defined here are added to the default list defined by Rye::Cmd (Rudy
|
41
|
+
# executes all SSH commands via Rye).
|
42
|
+
#
|
43
|
+
# Usage:
|
44
|
+
#
|
45
|
+
# allow COMMAND-NAME
|
46
|
+
# allow COMMAND-NAME, '/path/2/COMMAND'
|
47
|
+
# allow COMMAND-NAME, '/path/2/COMMAND', 'default argument', 'another arg'
|
48
|
+
#
|
49
|
+
commands do
|
50
|
+
allow :apt_get, "apt-get", :y, :q
|
51
|
+
allow :gem18_install, "/usr/bin/gem1.8", "install", :n, '/usr/bin', :y, :V, "--no-rdoc", "--no-ri"
|
52
|
+
allow :gem18_sources, "/usr/bin/gem1.8", "sources"
|
53
|
+
allow :gem19_install, "/usr/local/bin/gem", "install", :n, '/usr/bin', :y, :V, "--no-rdoc", "--no-ri"
|
54
|
+
allow :gem19_sources, "/usr/local/bin/gem", "sources"
|
55
|
+
allow :update_rubygems
|
56
|
+
allow :ruby18, "/usr/bin/ruby1.8"
|
57
|
+
allow :ruby19, "/usr/local/bin/ruby"
|
58
|
+
allow :ssh_keygen, 'ssh-keygen'
|
59
|
+
allow :rm
|
60
|
+
end
|
61
|
+
|
62
|
+
# ----------------------------------------------------------- ROUTINES --------
|
63
|
+
# The routines block describes the repeatable processes for each machine group.
|
64
|
+
# To run a routine, specify its name on the command-line: rudy startup
|
65
|
+
routines do
|
66
|
+
|
67
|
+
env :rye do
|
68
|
+
startup do
|
69
|
+
after :installdeps, :authorize
|
70
|
+
after :runtest
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
runtest do
|
75
|
+
remote :root do
|
76
|
+
ruby18 :r, 'rubygems', 'rye/bin/try'
|
77
|
+
ruby19 'rye/bin/try'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
authorize do
|
82
|
+
remote :root do
|
83
|
+
rm :f, '/root/.ssh/id_rsa'
|
84
|
+
ssh_keygen :q, :f, '/root/.ssh/id_rsa', :N, ''
|
85
|
+
rye 'authorize_local'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
installdeps do
|
90
|
+
local do
|
91
|
+
rake 'package'
|
92
|
+
end
|
93
|
+
remote :root do
|
94
|
+
gem18_install "rye", "delano-rye"
|
95
|
+
gem19_install "rye", 'delano-rye'
|
96
|
+
disable_safe_mode
|
97
|
+
rm :r, :f, 'rye*'
|
98
|
+
file_upload 'pkg/rye-*gz'
|
99
|
+
tar :z, :x, :f, 'rye-*gz'
|
100
|
+
rm 'rye-*gz'
|
101
|
+
mv 'rye-*', 'rye'
|
102
|
+
cd 'rye'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# NOTE: sysupdate only needs to be run for the bare instances.
|
107
|
+
sysupdate do
|
108
|
+
remote :root do
|
109
|
+
apt_get "update"
|
110
|
+
apt_get "install", "build-essential", "git-core"
|
111
|
+
apt_get "install", "libssl-dev", "libreadline5-dev", "zlib1g-dev"
|
112
|
+
apt_get "install", "ruby1.8-dev", "rubygems"
|
113
|
+
gem18_install 'rubygems-update' # for 1.8
|
114
|
+
update_rubygems # for 1.8
|
115
|
+
gem18_sources :a, "http://gems.github.com"
|
116
|
+
end
|
117
|
+
after :install_ruby19
|
118
|
+
end
|
119
|
+
|
120
|
+
install_ruby19 do
|
121
|
+
remote :root do
|
122
|
+
wget :q, 'ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p129.tar.gz'
|
123
|
+
tar :z, :x, :f, 'ruby-1.9.1-p129.tar.gz'
|
124
|
+
cd 'ruby-1.9.1-p129'
|
125
|
+
configure
|
126
|
+
make
|
127
|
+
make 'install'
|
128
|
+
apt_get "install", "rubygems1.9"
|
129
|
+
gem19_sources :a, "http://gems.github.com"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
|
data/bin/try
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# Rye -- A working example
|
4
|
+
#
|
5
|
+
# If your reading this via the rdocs you won't be able to see the code
|
6
|
+
# See: http://github.com/delano/rye/blob/master/bin/try
|
7
|
+
#
|
8
|
+
# Usage: bin/try
|
9
|
+
#
|
10
|
+
|
11
|
+
RYE_HOME = File.join(File.dirname(__FILE__), '..')
|
12
|
+
$:.unshift File.join(RYE_HOME, 'lib')
|
13
|
+
%w{net-ssh sysinfo storable drydock}.each { |dir| $:.unshift File.join(File.dirname(__FILE__), '..', '..', dir, 'lib') }
|
14
|
+
|
15
|
+
require 'stringio'
|
16
|
+
require 'yaml'
|
17
|
+
require 'rye'
|
18
|
+
|
19
|
+
|
20
|
+
puts %Q(
|
21
|
+
# ------------------------------------------------------------------
|
22
|
+
# EXAMPLE 1 -- Basic Usage
|
23
|
+
#)
|
24
|
+
|
25
|
+
rbox = Rye::Box.new('localhost')
|
26
|
+
|
27
|
+
# Commands are run as methods on the Rye::Box object
|
28
|
+
puts rbox.uptime # => 11:02 up 16:01, 3 users
|
29
|
+
|
30
|
+
# The response value for all commands is a Rye::Rap object. The rap is a
|
31
|
+
# subclass of Array so you can treat it as an Array, but it can also act
|
32
|
+
# like a String if there's only one element.
|
33
|
+
p rbox.ls(:a, '/') # => ['.', '..', 'bin', 'etc', ...]
|
34
|
+
|
35
|
+
# You can change directories
|
36
|
+
puts rbox.pwd # => /home/rye
|
37
|
+
puts rbox['/usr/bin'].pwd # => /usr/bin
|
38
|
+
puts rbox.pwd # => /usr/bin
|
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
|
+
|
51
|
+
|
52
|
+
puts %Q(
|
53
|
+
# ------------------------------------------------------------------
|
54
|
+
# EXAMPLE 2 -- Disabling Safe-Mode
|
55
|
+
#)
|
56
|
+
|
57
|
+
rbox_safe = Rye::Box.new('localhost')
|
58
|
+
rbox_wild = Rye::Box.new('localhost', :safe => false)
|
59
|
+
|
60
|
+
# Safe-mode is enabled by default. In safe-mode, all command
|
61
|
+
# arguments are thoroughly escaped. This prevents access to
|
62
|
+
# environment variables and file globs (among other things).
|
63
|
+
p rbox_safe.echo('$HOME') # => "$HOME"
|
64
|
+
p rbox_safe['/etc'].ls('host*') rescue Rye::CommandError # Doesn't exist
|
65
|
+
p rbox_safe.ls('-l | wc -l') rescue Rye::CommandError # => '|' is not a valid ls arg
|
66
|
+
|
67
|
+
# Here's the same commands with safe-mode disabled:
|
68
|
+
p rbox_wild.echo('$HOME') # => "/home/rye"
|
69
|
+
p rbox_wild['/etc'].ls('host*') # => ["hostconfig", "hosts"]
|
70
|
+
p rbox_wild.ls('-l | wc -l') # => 110
|
71
|
+
p rbox_wild.echo('$HOME > /tmp/rye-home') # =>
|
72
|
+
p rbox_wild.cat('/tmp/rye-home') # => "/home/rye"
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
puts %Q(
|
77
|
+
# ------------------------------------------------------------------
|
78
|
+
# EXAMPLE 3 -- Custom Commands
|
79
|
+
#)
|
80
|
+
|
81
|
+
rbox = Rye::Box.new('localhost')
|
82
|
+
rbox.add_keys('/private/key/path') # Specify additional private keys
|
83
|
+
|
84
|
+
# There's currently no rye900 command
|
85
|
+
p rbox.commands.member?('rye9000') # => false
|
86
|
+
|
87
|
+
# But we can add our own commands to the Rye::Cmd class. They
|
88
|
+
# automatically become available to all Rye::Box objects.
|
89
|
+
module Rye::Cmd
|
90
|
+
def rye9000(*args)
|
91
|
+
run_command("ls", args)
|
92
|
+
end
|
93
|
+
def somescript(*args)
|
94
|
+
run_command("/path/to/my/script", args)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# We can now run rye9000 (with arguments)
|
99
|
+
p rbox.rye9000('-a') # => [".", "..", ".bashrc", ...]
|
100
|
+
p rbox.commands.member?('rye9000') # => true
|
101
|
+
|
102
|
+
|
103
|
+
puts %Q(
|
104
|
+
# ------------------------------------------------------------------
|
105
|
+
# EXAMPLE 4 -- Accessing Multiple Machines
|
106
|
+
#)
|
107
|
+
|
108
|
+
rset = Rye::Set.new('default', :parallel => true)
|
109
|
+
rbox = Rye::Box.new
|
110
|
+
p rbox
|
111
|
+
|
112
|
+
rset.add_keys('/private/key/path') # For passwordless logins
|
113
|
+
rset.add_boxes(rbox, '127.0.0.1') # Add boxes as hostnames or objects
|
114
|
+
|
115
|
+
# Calling methods on Rye::Set objects is very similar to calling them on
|
116
|
+
# Rye::Box objects. In fact, it's identical:
|
117
|
+
p rset.uptime # => [[14:19:02 up 32 days, 19:35 ...], [14:19:02 up 30 days, 01:35]]
|
118
|
+
p rset['/usr'].ls # => [['bin', 'etc', ...], ['bin', 'etc', ...]]
|
119
|
+
|
120
|
+
# Like Rye::Box, the response value is a Rye::Rap object containing the
|
121
|
+
# responses from each box. Each response is itself a Rye::Rap object.
|
122
|
+
unames = rset.uname
|
123
|
+
p unames # => [["Darwin"], ["Darwin"]]
|
124
|
+
puts unames.class # => Rye::Rap
|
125
|
+
|
126
|
+
# The Rye::Rap object also keeps a reference to the object that called the
|
127
|
+
# command. In this case, it will keep a reference to Rye::Set:
|
128
|
+
puts unames.set.class # => Rye::Set
|
129
|
+
puts unames.set == rset # => true
|
130
|
+
puts unames.size # => 2
|
131
|
+
puts unames.first # => Darwin
|
132
|
+
puts unames.first.class # => Rye::Rap
|
133
|
+
puts unames.first.box.class # => Rye::Box
|
134
|
+
puts unames.first.box == rbox # => true
|
135
|
+
|
136
|
+
# Envrionment variables can be set the same way as with Rye::Box
|
137
|
+
rset.setenv(:RYE, "Forty Creek")
|
138
|
+
p rset.env.first.select { |env| env =~ /RYE/ } # => ["RYE=Forty Creek"]
|
139
|
+
|
140
|
+
|
141
|
+
puts %Q(
|
142
|
+
# ------------------------------------------------------------------
|
143
|
+
# EXAMPLE 5 -- ERROR HANDLING
|
144
|
+
#)
|
145
|
+
|
146
|
+
rbox = Rye::Box.new('localhost', :safe => false) # Note: safe mode is off
|
147
|
+
|
148
|
+
# Rye follows the standard convention of taking exception to a non-zero
|
149
|
+
# exit code by raising a Rye::CommandError. In this case, rye9000.test
|
150
|
+
# is not found by the ls command.
|
151
|
+
begin
|
152
|
+
rbox.ls('rye.test')
|
153
|
+
rescue Rye::CommandError => ex
|
154
|
+
puts ex.exit_code # => 1
|
155
|
+
puts ex.stderr # => ls: rye.test: No such file or directory
|
156
|
+
end
|
157
|
+
|
158
|
+
# The Rye:Rap response objects also give you the STDOUT and STDERR
|
159
|
+
# content separately. Here we redirect STDOUT to STDERR, so this
|
160
|
+
# will return nothing:
|
161
|
+
puts rbox.uname('-a 1>&2').stdout # =>
|
162
|
+
|
163
|
+
# It all went to STDERR:
|
164
|
+
puts rbox.uname('-a 1>&2').stderr # => Darwin ryehost 9.6.0 ...
|
165
|
+
|
166
|
+
# There were no actual errors so the exit code should be 0.
|
167
|
+
puts rbox.uname('-a 1>&2').exit_code # => 0
|
168
|
+
|
169
|
+
|
170
|
+
puts %Q(
|
171
|
+
# ------------------------------------------------------------------
|
172
|
+
# EXAMPLE 6 -- FILE TRANSFERS
|
173
|
+
#)
|
174
|
+
|
175
|
+
dir_upload = "#{Rye.sysinfo.tmpdir}/rye-upload/"
|
176
|
+
dir_download = "#{Rye.sysinfo.tmpdir}/rye-download/"
|
177
|
+
|
178
|
+
rbox = Rye::Box.new("localhost", :info => false)
|
179
|
+
|
180
|
+
# Rye ships without an rm method (for safety!). Here
|
181
|
+
# we add the rm method only to this instance of rbox.
|
182
|
+
def rbox.rm(*args); cmd('rm', args); end
|
183
|
+
|
184
|
+
rbox.rm(:r, :f, dir_upload) # Silently delete test dirs
|
185
|
+
rbox.rm(:r, :f, dir_download)
|
186
|
+
|
187
|
+
rbox.file_upload("#{RYE_HOME}/README.rdoc",
|
188
|
+
"#{RYE_HOME}/LICENSE.txt", dir_upload)
|
189
|
+
|
190
|
+
applejack = StringIO.new("Some in-memory content")
|
191
|
+
rbox.file_upload(applejack, "#{dir_upload}/applejack.txt")
|
192
|
+
|
193
|
+
p rbox.ls(dir_upload) # => [README.rdoc, LICENSE.txt, applejack.txt]
|
194
|
+
p rbox.cat("#{dir_upload}/applejack.txt") # => "Some in-memory content"
|
195
|
+
|
196
|
+
filecontent = StringIO.new
|
197
|
+
rbox.file_download("#{dir_upload}/applejack.txt", filecontent)
|
198
|
+
filecontent.rewind
|
199
|
+
p filecontent.read
|
200
|
+
|
201
|
+
|
202
|
+
|
data/lib/rye.rb
CHANGED
data/lib/rye/box.rb
CHANGED
@@ -155,28 +155,26 @@ module Rye
|
|
155
155
|
# rbox['/usr/bin'].pwd # => /usr/bin ($ cd /usr/bin && pwd)
|
156
156
|
# rbox.pwd # => /usr/bin ($ cd /usr/bin && pwd)
|
157
157
|
#
|
158
|
-
def [](
|
159
|
-
if
|
160
|
-
@rye_current_working_directory =
|
158
|
+
def [](fpath=nil)
|
159
|
+
if fpath.nil? || fpath.index('/') == 0
|
160
|
+
@rye_current_working_directory = fpath
|
161
161
|
else
|
162
162
|
# Append to non-absolute paths
|
163
|
-
|
164
|
-
|
163
|
+
if @rye_current_working_directory
|
164
|
+
newpath = File.join(@rye_current_working_directory, fpath)
|
165
|
+
@rye_current_working_directory = newpath
|
166
|
+
else
|
167
|
+
@rye_current_working_directory = fpath
|
168
|
+
end
|
165
169
|
end
|
170
|
+
info "CWD: #{@rye_current_working_directory}"
|
166
171
|
self
|
167
172
|
end
|
168
173
|
# Like [] except it returns an empty Rye::Rap object to mimick
|
169
174
|
# a regular command method. Call with nil key (or no arg) to
|
170
175
|
# reset.
|
171
|
-
def cd(
|
172
|
-
|
173
|
-
@rye_current_working_directory = key
|
174
|
-
else
|
175
|
-
# Append to non-absolute paths
|
176
|
-
newpath = File.join(@rye_current_working_directory, key)
|
177
|
-
@rye_current_working_directory = File.expand_path(newpath)
|
178
|
-
end
|
179
|
-
ret = Rye::Rap.new(self)
|
176
|
+
def cd(fpath=nil)
|
177
|
+
Rye::Rap.new(self[fpath])
|
180
178
|
end
|
181
179
|
|
182
180
|
# Change the current umask (sort of -- works the same way as cd)
|
@@ -237,7 +235,7 @@ module Rye
|
|
237
235
|
# it, execute it directly, parse the output.
|
238
236
|
def ostype
|
239
237
|
return @rye_ostype if @rye_ostype # simple cache
|
240
|
-
os = self.uname.first rescue nil
|
238
|
+
os = self.quietly { uname.first } rescue nil
|
241
239
|
os ||= 'unknown'
|
242
240
|
os &&= os.downcase
|
243
241
|
@rye_ostype = os
|
@@ -256,11 +254,11 @@ module Rye
|
|
256
254
|
#
|
257
255
|
def getenv
|
258
256
|
if @rye_getenv && @rye_getenv.empty? && self.can?(:env)
|
259
|
-
|
260
|
-
|
257
|
+
vars = self.quietly { env } rescue []
|
258
|
+
vars.each do |nvpair|
|
261
259
|
# Parse "GLORIA_HOME=/gloria/lives/here" into a name/value
|
262
260
|
# pair. The regexp ensures we split only at the 1st = sign
|
263
|
-
n, v =
|
261
|
+
n, v = nvpair.scan(/\A([\w_-]+?)=(.+)\z/).flatten
|
264
262
|
@rye_getenv[n] = v
|
265
263
|
end
|
266
264
|
end
|
@@ -307,6 +305,7 @@ module Rye
|
|
307
305
|
# Uses the output of "useradd -D" to determine the default home
|
308
306
|
# directory. This returns a GUESS rather than the a user's real
|
309
307
|
# home directory. Currently used only by authorize_keys_remote.
|
308
|
+
# Only useful before you've logged in. Otherwise check $HOME
|
310
309
|
def guess_user_home(other_user=nil)
|
311
310
|
this_user = other_user || opts[:user]
|
312
311
|
@rye_guessed_homes ||= {}
|
@@ -321,7 +320,7 @@ module Rye
|
|
321
320
|
# /etc/default/useradd, HOME=/home OR useradd -D
|
322
321
|
# /etc/adduser.config, DHOME=/home OR ??
|
323
322
|
user_defaults = {}
|
324
|
-
raw = self.useradd(:D) rescue ["HOME=/home"]
|
323
|
+
raw = self.quietly { useradd(:D) } rescue ["HOME=/home"]
|
325
324
|
ostmp = self.ostype
|
326
325
|
raw.each do |nv|
|
327
326
|
|
@@ -697,8 +696,7 @@ module Rye
|
|
697
696
|
## raise Rye::CommandNotFound unless self.can?(cmd)
|
698
697
|
|
699
698
|
begin
|
700
|
-
info "COMMAND: #{
|
701
|
-
debug "Executing: #{cmd_internal}"
|
699
|
+
info "COMMAND: #{cmd_internal}"
|
702
700
|
|
703
701
|
if !@rye_quiet && @rye_pre_command_hook.is_a?(Proc)
|
704
702
|
@rye_pre_command_hook.call(cmd_clean, user, host, nickname)
|
@@ -870,15 +868,26 @@ module Rye
|
|
870
868
|
|
871
869
|
# We allow a single file to be downloaded into a StringIO object
|
872
870
|
# but only when no target has been specified.
|
873
|
-
if direction == :download
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
871
|
+
if direction == :download
|
872
|
+
if files.size == 1
|
873
|
+
debug "Created StringIO for download"
|
874
|
+
target = StringIO.new
|
875
|
+
else
|
876
|
+
target = files.pop # The last path is the download target.
|
877
|
+
end
|
878
|
+
|
879
|
+
elsif direction == :upload
|
880
|
+
raise "Cannot upload to a StringIO object" if target.is_a?(StringIO)
|
881
|
+
if files.size == 1
|
882
|
+
target = self.getenv['HOME'] || guess_user_home
|
883
|
+
debug "Assuming upload to #{target}"
|
884
|
+
else
|
885
|
+
target = files.pop
|
886
|
+
end
|
887
|
+
|
888
|
+
# Expand fileglobs (e.g. path/*.rb becomes [path/1.rb, path/2.rb]).
|
889
|
+
# This should happen after checking files.size to determine the target
|
890
|
+
files = files.collect { |file| Dir.glob file }.flatten unless @rye_safe
|
882
891
|
end
|
883
892
|
|
884
893
|
# Fail early. We check whether the StringIO object is available to read
|
@@ -891,21 +900,21 @@ module Rye
|
|
891
900
|
end
|
892
901
|
end
|
893
902
|
|
894
|
-
|
903
|
+
info "#{direction.to_s.upcase} TO: #{target}"
|
895
904
|
debug "FILES: " << files.join(', ')
|
896
905
|
|
897
906
|
# Make sure the remote directory exists. We can do this only when
|
898
|
-
# there's more than one file because "
|
899
|
-
if files.size > 1 && !
|
900
|
-
debug "CREATING TARGET DIRECTORY: #{
|
901
|
-
self.mkdir(:p,
|
907
|
+
# there's more than one file because "target" could be a file name
|
908
|
+
if files.size > 1 && !target.is_a?(StringIO)
|
909
|
+
debug "CREATING TARGET DIRECTORY: #{target}"
|
910
|
+
self.mkdir(:p, target) unless self.file_exists?(target)
|
902
911
|
end
|
903
912
|
|
904
913
|
Net::SCP.start(@rye_host, @rye_opts[:user], @rye_opts || {}) do |scp|
|
905
914
|
transfers = []
|
906
915
|
files.each do |file|
|
907
916
|
debug file.to_s
|
908
|
-
transfers << scp.send(direction, file,
|
917
|
+
transfers << scp.send(direction, file, target) do |ch, n, s, t|
|
909
918
|
pinfo "#{n}: #{s}/#{t}b\r" # update line: "file: sent/total"
|
910
919
|
@rye_info.flush if @rye_info # make sure every line is printed
|
911
920
|
end
|
@@ -914,7 +923,7 @@ module Rye
|
|
914
923
|
info $/
|
915
924
|
end
|
916
925
|
|
917
|
-
|
926
|
+
target.is_a?(StringIO) ? target : nil
|
918
927
|
end
|
919
928
|
|
920
929
|
|
data/lib/rye/cmd.rb
CHANGED
@@ -36,6 +36,7 @@ module Rye;
|
|
36
36
|
def du(*args); cmd('du', args); end
|
37
37
|
|
38
38
|
def env; cmd "env"; end
|
39
|
+
def rye(*args); cmd "rye", args; end
|
39
40
|
def pwd(*args); cmd "pwd", args; end
|
40
41
|
def svn(*args); cmd('svn', args); end
|
41
42
|
def cvs(*args); cmd('cvs', args); end
|
@@ -50,6 +51,7 @@ module Rye;
|
|
50
51
|
def grep(*args); cmd('grep', args); end
|
51
52
|
def date(*args); cmd('date', args); end
|
52
53
|
def ruby(*args); cmd('ruby', args); end
|
54
|
+
def rudy(*args); cmd('rudy', args); end
|
53
55
|
def perl(*args); cmd('perl', args); end
|
54
56
|
def bash(*args); cmd('bash', args); end
|
55
57
|
def echo(*args); cmd('echo', args); end
|
@@ -77,8 +79,11 @@ module Rye;
|
|
77
79
|
def bunzip2(*args); cmd('bunzip2', args); end
|
78
80
|
def getconf(*args); cmd('getconf', args); end
|
79
81
|
def history(*args); cmd('history', args); end
|
82
|
+
def rudy_s3(*args); cmd('rudy-s3', args); end
|
80
83
|
def printenv(*args); cmd('printenv', args); end
|
81
84
|
def hostname(*args); cmd('hostname', args); end
|
85
|
+
def rudy_ec2(*args); cmd('rudy-ec2', args); end
|
86
|
+
def rudy_edb(*args); cmd('rudy-sdb', args); end
|
82
87
|
def configure(*args); cmd('./configure', args); end
|
83
88
|
|
84
89
|
# Transfer files to a machine via Net::SCP.
|
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.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"
|
@@ -35,7 +35,9 @@
|
|
35
35
|
LICENSE.txt
|
36
36
|
README.rdoc
|
37
37
|
Rakefile
|
38
|
+
Rudyfile
|
38
39
|
bin/rye
|
40
|
+
bin/try
|
39
41
|
lib/esc.rb
|
40
42
|
lib/rye.rb
|
41
43
|
lib/rye/box.rb
|
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.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -86,7 +86,9 @@ files:
|
|
86
86
|
- LICENSE.txt
|
87
87
|
- README.rdoc
|
88
88
|
- Rakefile
|
89
|
+
- Rudyfile
|
89
90
|
- bin/rye
|
91
|
+
- bin/try
|
90
92
|
- lib/esc.rb
|
91
93
|
- lib/rye.rb
|
92
94
|
- lib/rye/box.rb
|