rush 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/bin/rush +7 -1
- data/bin/rushd +0 -0
- data/lib/rush.rb +1 -0
- data/lib/rush/box.rb +21 -8
- data/lib/rush/exceptions.rb +5 -3
- data/lib/rush/local.rb +57 -4
- data/lib/rush/process.rb +2 -1
- data/lib/rush/process_set.rb +62 -0
- data/lib/rush/remote.rb +5 -3
- data/lib/rush/shell.rb +31 -17
- data/spec/box_spec.rb +8 -2
- data/spec/dir_spec.rb +2 -2
- data/spec/local_spec.rb +32 -4
- data/spec/process_set_spec.rb +50 -0
- data/spec/process_spec.rb +1 -1
- data/spec/remote_spec.rb +4 -4
- metadata +34 -29
data/Rakefile
CHANGED
data/bin/rush
CHANGED
data/bin/rushd
CHANGED
File without changes
|
data/lib/rush.rb
CHANGED
data/lib/rush/box.rb
CHANGED
@@ -41,26 +41,39 @@ class Rush::Box
|
|
41
41
|
filesystem[key]
|
42
42
|
end
|
43
43
|
|
44
|
-
# Get the list of processes
|
45
|
-
#
|
44
|
+
# Get the list of processes running on the box, not unlike "ps aux" in bash.
|
45
|
+
# Returns a Rush::ProcessSet.
|
46
46
|
def processes
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
Rush::ProcessSet.new(
|
48
|
+
connection.processes.map do |ps|
|
49
|
+
Rush::Process.new(ps, self)
|
50
|
+
end
|
51
|
+
)
|
50
52
|
end
|
51
53
|
|
52
|
-
# Execute a command in the standard unix shell.
|
54
|
+
# Execute a command in the standard unix shell. Returns the contents of
|
55
|
+
# stdout if successful, or raises Rush::BashFailed with the output of stderr
|
56
|
+
# if the shell returned a non-zero value. Options:
|
53
57
|
#
|
54
58
|
# :user => unix username to become via sudo
|
55
59
|
# :env => hash of environment variables
|
60
|
+
# :background => run in the background (returns Rush::Process instead of stdout)
|
56
61
|
#
|
57
|
-
#
|
62
|
+
# Examples:
|
58
63
|
#
|
59
64
|
# box.bash '/etc/init.d/mysql restart', :user => 'root'
|
60
65
|
# box.bash 'rake db:migrate', :user => 'www', :env => { :RAILS_ENV => 'production' }
|
66
|
+
# box.bash 'mongrel_rails start', :background => true
|
61
67
|
#
|
62
68
|
def bash(command, options={})
|
63
|
-
|
69
|
+
cmd_with_env = command_with_environment(command, options[:env])
|
70
|
+
|
71
|
+
if options[:background]
|
72
|
+
pid = connection.bash(cmd_with_env, options[:user], true)
|
73
|
+
processes.find_by_pid(pid)
|
74
|
+
else
|
75
|
+
connection.bash(cmd_with_env, options[:user], false)
|
76
|
+
end
|
64
77
|
end
|
65
78
|
|
66
79
|
def command_with_environment(command, env) # :nodoc:
|
data/lib/rush/exceptions.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
module Rush
|
2
2
|
# Base class for all rush exceptions.
|
3
|
-
class Exception < ::
|
3
|
+
class Exception < ::RuntimeError; end
|
4
4
|
|
5
5
|
# Client was not authorized by remote server; check credentials.
|
6
6
|
class NotAuthorized < Exception; end
|
7
7
|
|
8
|
-
#
|
9
|
-
|
8
|
+
# rushd is not running on the remote box.
|
9
|
+
class RushdNotRunning < Exception; end
|
10
|
+
|
11
|
+
# An unrecognized status code was returned by rushd.
|
10
12
|
class FailedTransmit < Exception; end
|
11
13
|
|
12
14
|
# The entry (file or dir) referenced does not exist. Message is the entry's full path.
|
data/lib/rush/local.rb
CHANGED
@@ -133,7 +133,7 @@ class Rush::Connection::Local
|
|
133
133
|
# Get the list of processes as an array of hashes.
|
134
134
|
def processes
|
135
135
|
if ::File.directory? "/proc"
|
136
|
-
linux_processes
|
136
|
+
resolve_unix_uids(linux_processes)
|
137
137
|
elsif ::File.directory? "C:/WINDOWS"
|
138
138
|
windows_processes
|
139
139
|
else
|
@@ -154,6 +154,33 @@ class Rush::Connection::Local
|
|
154
154
|
list
|
155
155
|
end
|
156
156
|
|
157
|
+
def resolve_unix_uids(list)
|
158
|
+
@uid_map = {} # reset the cache between uid resolutions.
|
159
|
+
list.each do |process|
|
160
|
+
process[:user] = resolve_unix_uid_to_user(process[:uid])
|
161
|
+
end
|
162
|
+
list
|
163
|
+
end
|
164
|
+
|
165
|
+
# resolve uid to user
|
166
|
+
def resolve_unix_uid_to_user(uid)
|
167
|
+
require 'etc'
|
168
|
+
|
169
|
+
@uid_map ||= {}
|
170
|
+
uid = uid.to_i
|
171
|
+
|
172
|
+
return @uid_map[uid] if !@uid_map[uid].nil?
|
173
|
+
|
174
|
+
begin
|
175
|
+
record = Etc.getpwuid(uid)
|
176
|
+
rescue ArgumentError
|
177
|
+
return nil
|
178
|
+
end
|
179
|
+
|
180
|
+
@uid_map[uid] = record.name
|
181
|
+
@uid_map[uid]
|
182
|
+
end
|
183
|
+
|
157
184
|
# Read a single file in /proc and store the parsed values in a hash suitable
|
158
185
|
# for use in the Rush::Process#new.
|
159
186
|
def read_proc_file(file)
|
@@ -256,15 +283,20 @@ class Rush::Connection::Local
|
|
256
283
|
end
|
257
284
|
|
258
285
|
::Process.kill('KILL', pid) rescue nil
|
286
|
+
|
287
|
+
rescue Errno::ESRCH
|
288
|
+
# if it's dead, great - do nothing
|
259
289
|
end
|
260
290
|
|
261
|
-
def bash(command, user=nil)
|
291
|
+
def bash(command, user=nil, background=false)
|
292
|
+
return bash_background(command, user) if background
|
293
|
+
|
262
294
|
require 'session'
|
263
295
|
|
264
296
|
sh = Session::Bash.new
|
265
297
|
|
266
298
|
if user and user != ""
|
267
|
-
out, err = sh.execute "sudo -u #{user} bash", :stdin => command
|
299
|
+
out, err = sh.execute "cd /; sudo -H -u #{user} bash", :stdin => command
|
268
300
|
else
|
269
301
|
out, err = sh.execute command
|
270
302
|
end
|
@@ -277,6 +309,27 @@ class Rush::Connection::Local
|
|
277
309
|
out
|
278
310
|
end
|
279
311
|
|
312
|
+
def bash_background(command, user)
|
313
|
+
inpipe, outpipe = IO.pipe
|
314
|
+
|
315
|
+
pid = fork do
|
316
|
+
outpipe.write command
|
317
|
+
outpipe.close
|
318
|
+
STDIN.reopen(inpipe)
|
319
|
+
|
320
|
+
if user and user != ''
|
321
|
+
exec "cd /; sudo -H -u #{user} bash"
|
322
|
+
else
|
323
|
+
exec "bash"
|
324
|
+
end
|
325
|
+
end
|
326
|
+
outpipe.close
|
327
|
+
|
328
|
+
Process::detach pid
|
329
|
+
|
330
|
+
pid
|
331
|
+
end
|
332
|
+
|
280
333
|
####################################
|
281
334
|
|
282
335
|
# Raised when the action passed in by RushServer is not known.
|
@@ -304,7 +357,7 @@ class Rush::Connection::Local
|
|
304
357
|
when 'processes' then YAML.dump(processes)
|
305
358
|
when 'process_alive' then process_alive(params[:pid]) ? '1' : '0'
|
306
359
|
when 'kill_process' then kill_process(params[:pid].to_i)
|
307
|
-
when 'bash' then bash(params[:payload], params[:user])
|
360
|
+
when 'bash' then bash(params[:payload], params[:user], params[:background] == 'true')
|
308
361
|
else
|
309
362
|
raise UnknownAction
|
310
363
|
end
|
data/lib/rush/process.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# An array of these objects is returned by Rush::Box#processes.
|
2
2
|
class Rush::Process
|
3
|
-
attr_reader :box, :pid, :uid, :parent_pid, :command, :cmdline, :mem, :cpu
|
3
|
+
attr_reader :box, :pid, :uid, :parent_pid, :command, :cmdline, :mem, :cpu, :user
|
4
4
|
|
5
5
|
# params is a hash returned by the system-specific method of looking up the
|
6
6
|
# process list.
|
@@ -9,6 +9,7 @@ class Rush::Process
|
|
9
9
|
|
10
10
|
@pid = params[:pid].to_i
|
11
11
|
@uid = params[:uid].to_i
|
12
|
+
@user = params[:user]
|
12
13
|
@command = params[:command]
|
13
14
|
@cmdline = params[:cmdline]
|
14
15
|
@mem = params[:mem]
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# A container for processes that behaves like an array, and adds process-specific operations
|
2
|
+
# on the entire set, like kill.
|
3
|
+
#
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# processes.filter(:cmdline => /mongrel_rails/).kill
|
7
|
+
#
|
8
|
+
class Rush::ProcessSet
|
9
|
+
attr_reader :processes
|
10
|
+
|
11
|
+
def initialize(processes)
|
12
|
+
@processes = processes
|
13
|
+
end
|
14
|
+
|
15
|
+
# Filter by any field that the process responds to. Specify an exact value,
|
16
|
+
# or a regular expression. All conditions are put together as a boolean
|
17
|
+
# AND, so these two statements are equivalent:
|
18
|
+
#
|
19
|
+
# processes.filter(:uid => 501).filter(:cmdline => /ruby/)
|
20
|
+
# processes.filter(:uid => 501, :cmdline => /ruby/)
|
21
|
+
#
|
22
|
+
def filter(conditions)
|
23
|
+
Rush::ProcessSet.new(
|
24
|
+
processes.select do |p|
|
25
|
+
conditions.all? do |key, value|
|
26
|
+
value.class == Regexp ?
|
27
|
+
value.match(p.send(key)) :
|
28
|
+
p.send(key) == value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Kill all processes in the set.
|
35
|
+
def kill
|
36
|
+
processes.each { |p| p.kill }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Check status of all processes in the set, returns an array of booleans.
|
40
|
+
def alive?
|
41
|
+
processes.map { |p| p.alive? }
|
42
|
+
end
|
43
|
+
|
44
|
+
include Enumerable
|
45
|
+
|
46
|
+
def each
|
47
|
+
processes.each { |p| yield p }
|
48
|
+
end
|
49
|
+
|
50
|
+
def ==(other)
|
51
|
+
if other.class == self.class
|
52
|
+
other.processes == processes
|
53
|
+
else
|
54
|
+
to_a == other
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# All other messages (like size or first) are passed through to the array.
|
59
|
+
def method_missing(meth, *args)
|
60
|
+
processes.send(meth, *args)
|
61
|
+
end
|
62
|
+
end
|
data/lib/rush/remote.rb
CHANGED
@@ -63,7 +63,7 @@ class Rush::Connection::Remote
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def size(full_path)
|
66
|
-
transmit(:action => 'size', :full_path => full_path)
|
66
|
+
transmit(:action => 'size', :full_path => full_path).to_i
|
67
67
|
end
|
68
68
|
|
69
69
|
def processes
|
@@ -78,8 +78,8 @@ class Rush::Connection::Remote
|
|
78
78
|
transmit(:action => 'kill_process', :pid => pid)
|
79
79
|
end
|
80
80
|
|
81
|
-
def bash(command, user)
|
82
|
-
transmit(:action => 'bash', :payload => command, :user => user)
|
81
|
+
def bash(command, user, background)
|
82
|
+
transmit(:action => 'bash', :payload => command, :user => user, :background => background)
|
83
83
|
end
|
84
84
|
|
85
85
|
# Given a hash of parameters (converted by the method call on the connection
|
@@ -104,6 +104,8 @@ class Rush::Connection::Remote
|
|
104
104
|
res = http.request(req, payload)
|
105
105
|
process_result(res.code, res.body)
|
106
106
|
end
|
107
|
+
rescue EOFError
|
108
|
+
raise Rush::RushdNotRunning
|
107
109
|
end
|
108
110
|
|
109
111
|
# Take the http result of a transmit and raise an error, or return the body
|
data/lib/rush/shell.rb
CHANGED
@@ -31,6 +31,21 @@ module Rush
|
|
31
31
|
Array.class_eval commands
|
32
32
|
end
|
33
33
|
|
34
|
+
# Run a single command.
|
35
|
+
def execute(cmd)
|
36
|
+
res = eval(cmd, @pure_binding)
|
37
|
+
$last_res = res
|
38
|
+
eval("_ = $last_res", @pure_binding)
|
39
|
+
print_result res
|
40
|
+
rescue Rush::Exception => e
|
41
|
+
puts "Exception #{e.class} -> #{e.message}"
|
42
|
+
rescue ::Exception => e
|
43
|
+
puts "Exception #{e.class} -> #{e.message}"
|
44
|
+
e.backtrace.each do |t|
|
45
|
+
puts " #{::File.expand_path(t)}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
34
49
|
# Run the interactive shell using readline.
|
35
50
|
def run
|
36
51
|
loop do
|
@@ -40,19 +55,7 @@ module Rush
|
|
40
55
|
next if cmd == ""
|
41
56
|
Readline::HISTORY.push(cmd)
|
42
57
|
|
43
|
-
|
44
|
-
res = eval(cmd, @pure_binding)
|
45
|
-
$last_res = res
|
46
|
-
eval("_ = $last_res", @pure_binding)
|
47
|
-
print_result res
|
48
|
-
rescue Rush::Exception => e
|
49
|
-
puts "Exception #{e.class} -> #{e.message}"
|
50
|
-
rescue ::Exception => e
|
51
|
-
puts "Exception #{e.class} -> #{e.message}"
|
52
|
-
e.backtrace.each do |t|
|
53
|
-
puts " #{::File.expand_path(t)}"
|
54
|
-
end
|
55
|
-
end
|
58
|
+
execute(cmd)
|
56
59
|
end
|
57
60
|
end
|
58
61
|
|
@@ -67,10 +70,6 @@ module Rush
|
|
67
70
|
def print_result(res)
|
68
71
|
if res.kind_of? String
|
69
72
|
puts res
|
70
|
-
elsif res.kind_of? Array
|
71
|
-
res.each do |item|
|
72
|
-
puts item
|
73
|
-
end
|
74
73
|
elsif res.kind_of? Rush::SearchResults
|
75
74
|
widest = res.entries.map { |k| k.full_path.length }.max
|
76
75
|
res.entries_with_lines.each do |entry, lines|
|
@@ -85,6 +84,21 @@ module Rush
|
|
85
84
|
print "\n"
|
86
85
|
end
|
87
86
|
puts "#{res.entries.size} matching files with #{res.lines.size} matching lines"
|
87
|
+
elsif res.respond_to? :each
|
88
|
+
counts = {}
|
89
|
+
res.each do |item|
|
90
|
+
puts item
|
91
|
+
counts[item.class] ||= 0
|
92
|
+
counts[item.class] += 1
|
93
|
+
end
|
94
|
+
if counts == {}
|
95
|
+
puts "=> (empty set)"
|
96
|
+
else
|
97
|
+
count_s = counts.map do |klass, count|
|
98
|
+
"#{count} x #{klass}"
|
99
|
+
end.join(', ')
|
100
|
+
puts "=> #{count_s}"
|
101
|
+
end
|
88
102
|
else
|
89
103
|
puts "=> #{res.inspect}"
|
90
104
|
end
|
data/spec/box_spec.rb
CHANGED
@@ -22,15 +22,21 @@ describe Rush::Box do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it "executes bash commands" do
|
25
|
-
@box.connection.should_receive(:bash).with('cmd', nil).and_return('output')
|
25
|
+
@box.connection.should_receive(:bash).with('cmd', nil, false).and_return('output')
|
26
26
|
@box.bash('cmd').should == 'output'
|
27
27
|
end
|
28
28
|
|
29
29
|
it "executes bash commands with an optional user" do
|
30
|
-
@box.connection.should_receive(:bash).with('cmd', 'user')
|
30
|
+
@box.connection.should_receive(:bash).with('cmd', 'user', false)
|
31
31
|
@box.bash('cmd', :user => 'user')
|
32
32
|
end
|
33
33
|
|
34
|
+
it "executes bash commands in the background, returning a Rush::Process" do
|
35
|
+
@box.connection.should_receive(:bash).with('cmd', nil, true).and_return(123)
|
36
|
+
@box.stub!(:processes).and_return([ mock('ps', :pid => 123) ])
|
37
|
+
@box.bash('cmd', :background => true).pid.should == 123
|
38
|
+
end
|
39
|
+
|
34
40
|
it "builds a script of environment variables to prefix the bash command" do
|
35
41
|
@box.command_with_environment('cmd', { :a => 'b' }).should == "export a='b'\ncmd"
|
36
42
|
end
|
data/spec/dir_spec.rb
CHANGED
@@ -152,8 +152,8 @@ describe Rush::Dir do
|
|
152
152
|
end
|
153
153
|
|
154
154
|
it "passes bash options (e.g., :user) through to the box bash command" do
|
155
|
-
@box.should_receive(:bash).with('cmd',
|
156
|
-
@box.bash('cmd',
|
155
|
+
@box.should_receive(:bash).with('cmd', :opt1 => 1, :opt2 => 2)
|
156
|
+
@box.bash('cmd', :opt1 => 1, :opt2 => 2)
|
157
157
|
end
|
158
158
|
|
159
159
|
end
|
data/spec/local_spec.rb
CHANGED
@@ -95,9 +95,14 @@ describe Rush::Connection::Local do
|
|
95
95
|
@con.receive(:action => 'kill_process', :pid => '123')
|
96
96
|
end
|
97
97
|
|
98
|
-
it "receive -> bash" do
|
99
|
-
@con.should_receive(:bash).with('cmd', 'user').and_return('output')
|
100
|
-
@con.receive(:action => 'bash', :payload => 'cmd', :user => 'user').should == 'output'
|
98
|
+
it "receive -> bash (foreground)" do
|
99
|
+
@con.should_receive(:bash).with('cmd', 'user', false).and_return('output')
|
100
|
+
@con.receive(:action => 'bash', :payload => 'cmd', :user => 'user', :background => 'false').should == 'output'
|
101
|
+
end
|
102
|
+
|
103
|
+
it "receive -> bash (background)" do
|
104
|
+
@con.should_receive(:bash).with('cmd', 'user', true).and_return('output')
|
105
|
+
@con.receive(:action => 'bash', :payload => 'cmd', :user => 'user', :background => 'true').should == 'output'
|
101
106
|
end
|
102
107
|
|
103
108
|
it "receive -> unknown action exception" do
|
@@ -263,6 +268,11 @@ EOPS
|
|
263
268
|
@con.kill_process(123)
|
264
269
|
end
|
265
270
|
|
271
|
+
it "does not raise an error if the process is already dead" do
|
272
|
+
::Process.should_receive(:kill).and_raise(Errno::ESRCH)
|
273
|
+
lambda { @con.kill_process(123) }.should_not raise_error
|
274
|
+
end
|
275
|
+
|
266
276
|
it "executes a bash command, returning stdout when successful" do
|
267
277
|
@con.bash("echo test").should == "test\n"
|
268
278
|
end
|
@@ -272,7 +282,11 @@ EOPS
|
|
272
282
|
end
|
273
283
|
|
274
284
|
it "executes a bash command as another user using sudo" do
|
275
|
-
@con.bash("echo test2", ENV['
|
285
|
+
@con.bash("echo test2", ENV['USER']).should == "test2\n"
|
286
|
+
end
|
287
|
+
|
288
|
+
it "executes a bash command in the background, returning the pid" do
|
289
|
+
@con.bash("true", nil, true).should > 0
|
276
290
|
end
|
277
291
|
|
278
292
|
it "ensure_tunnel to match with remote connection" do
|
@@ -282,4 +296,18 @@ EOPS
|
|
282
296
|
it "always returns true on alive?" do
|
283
297
|
@con.should be_alive
|
284
298
|
end
|
299
|
+
|
300
|
+
it "resolves a unix uid to a user" do
|
301
|
+
@con.resolve_unix_uid_to_user(0).should == "root"
|
302
|
+
@con.resolve_unix_uid_to_user('0').should == "root"
|
303
|
+
end
|
304
|
+
|
305
|
+
it "returns nil if the unix uid does not exist" do
|
306
|
+
@con.resolve_unix_uid_to_user(9999).should be_nil
|
307
|
+
end
|
308
|
+
|
309
|
+
it "iterates through a process list and resolves the unix uid for each" do
|
310
|
+
list = [ { :uid => 0, :command => 'pureftpd' }, { :uid => 9999, :command => 'defunk' } ]
|
311
|
+
@con.resolve_unix_uids(list).should == [ { :uid => 0, :user => 'root', :command => 'pureftpd' }, { :uid => 9999, :command => 'defunk', :user => nil } ]
|
312
|
+
end
|
285
313
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::ProcessSet do
|
4
|
+
before do
|
5
|
+
@process = mock('process')
|
6
|
+
@set = Rush::ProcessSet.new([ @process ])
|
7
|
+
end
|
8
|
+
|
9
|
+
it "is Enumerable" do
|
10
|
+
@set.select { |s| s == @process }.should == [ @process ]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "defines size" do
|
14
|
+
@set.size.should == 1
|
15
|
+
end
|
16
|
+
|
17
|
+
it "defines first" do
|
18
|
+
@set.first.should == @process
|
19
|
+
end
|
20
|
+
|
21
|
+
it "is equal to sets with the same contents" do
|
22
|
+
@set.should == Rush::ProcessSet.new([ @process ])
|
23
|
+
end
|
24
|
+
|
25
|
+
it "is equal to arrays with the same contents" do
|
26
|
+
@set.should == [ @process ]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "kills all processes in the set" do
|
30
|
+
@process.should_receive(:kill)
|
31
|
+
@set.kill
|
32
|
+
end
|
33
|
+
|
34
|
+
it "checks the alive? state of all processes in the set" do
|
35
|
+
@process.should_receive(:alive?).and_return(true)
|
36
|
+
@set.alive?.should == [ true ]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "filters the set from a conditions hash and returns the filtered set" do
|
40
|
+
@process.stub!(:pid).and_return(123)
|
41
|
+
@set.filter(:pid => 123).first.should == @process
|
42
|
+
@set.filter(:pid => 456).size.should == 0
|
43
|
+
end
|
44
|
+
|
45
|
+
it "filters with regexps if provided in the conditions" do
|
46
|
+
@process.stub!(:command).and_return('foobaz')
|
47
|
+
@set.filter(:command => /baz/).first.should == @process
|
48
|
+
@set.filter(:command => /blerg/).size.should == 0
|
49
|
+
end
|
50
|
+
end
|
data/spec/process_spec.rb
CHANGED
data/spec/remote_spec.rb
CHANGED
@@ -73,8 +73,8 @@ describe Rush::Connection::Local do
|
|
73
73
|
end
|
74
74
|
|
75
75
|
it "transmits size" do
|
76
|
-
@con.should_receive(:transmit).with(:action => 'size', :full_path => 'full_path').and_return("")
|
77
|
-
@con.size('full_path')
|
76
|
+
@con.should_receive(:transmit).with(:action => 'size', :full_path => 'full_path').and_return("123")
|
77
|
+
@con.size('full_path').should == 123
|
78
78
|
end
|
79
79
|
|
80
80
|
it "transmits processes" do
|
@@ -93,8 +93,8 @@ describe Rush::Connection::Local do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
it "transmits bash" do
|
96
|
-
@con.should_receive(:transmit).with(:action => 'bash', :payload => 'cmd', :user => 'user').and_return('output')
|
97
|
-
@con.bash('cmd', 'user').should == 'output'
|
96
|
+
@con.should_receive(:transmit).with(:action => 'bash', :payload => 'cmd', :user => 'user', :background => 'bg').and_return('output')
|
97
|
+
@con.bash('cmd', 'user', 'bg').should == 'output'
|
98
98
|
end
|
99
99
|
|
100
100
|
it "an http result code of 401 raises NotAuthorized" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rush
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.4"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Wiggins
|
@@ -9,11 +9,12 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-07-14 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: mongrel
|
17
|
+
type: :runtime
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
@@ -23,6 +24,7 @@ dependencies:
|
|
23
24
|
version:
|
24
25
|
- !ruby/object:Gem::Dependency
|
25
26
|
name: rspec
|
27
|
+
type: :runtime
|
26
28
|
version_requirement:
|
27
29
|
version_requirements: !ruby/object:Gem::Requirement
|
28
30
|
requirements:
|
@@ -32,6 +34,7 @@ dependencies:
|
|
32
34
|
version:
|
33
35
|
- !ruby/object:Gem::Dependency
|
34
36
|
name: session
|
37
|
+
type: :runtime
|
35
38
|
version_requirement:
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
@@ -52,46 +55,48 @@ files:
|
|
52
55
|
- Rakefile
|
53
56
|
- bin/rush
|
54
57
|
- bin/rushd
|
58
|
+
- lib/rush.rb
|
55
59
|
- lib/rush
|
56
|
-
- lib/rush/access.rb
|
57
|
-
- lib/rush/array_ext.rb
|
58
|
-
- lib/rush/box.rb
|
59
|
-
- lib/rush/commands.rb
|
60
60
|
- lib/rush/config.rb
|
61
|
-
- lib/rush/
|
61
|
+
- lib/rush/head_tail.rb
|
62
|
+
- lib/rush/search_results.rb
|
62
63
|
- lib/rush/entry.rb
|
63
|
-
- lib/rush/exceptions.rb
|
64
|
-
- lib/rush/file.rb
|
65
64
|
- lib/rush/find_by.rb
|
66
|
-
- lib/rush/
|
67
|
-
- lib/rush/head_tail.rb
|
65
|
+
- lib/rush/file.rb
|
68
66
|
- lib/rush/local.rb
|
69
|
-
- lib/rush/process.rb
|
70
|
-
- lib/rush/remote.rb
|
71
|
-
- lib/rush/search_results.rb
|
72
|
-
- lib/rush/server.rb
|
73
|
-
- lib/rush/shell.rb
|
74
67
|
- lib/rush/ssh_tunnel.rb
|
68
|
+
- lib/rush/shell.rb
|
69
|
+
- lib/rush/server.rb
|
70
|
+
- lib/rush/process_set.rb
|
71
|
+
- lib/rush/array_ext.rb
|
72
|
+
- lib/rush/remote.rb
|
73
|
+
- lib/rush/fixnum_ext.rb
|
74
|
+
- lib/rush/commands.rb
|
75
|
+
- lib/rush/process.rb
|
76
|
+
- lib/rush/dir.rb
|
75
77
|
- lib/rush/string_ext.rb
|
76
|
-
- lib/rush.rb
|
78
|
+
- lib/rush/box.rb
|
79
|
+
- lib/rush/exceptions.rb
|
80
|
+
- lib/rush/access.rb
|
81
|
+
- spec/remote_spec.rb
|
82
|
+
- spec/base.rb
|
83
|
+
- spec/ssh_tunnel_spec.rb
|
84
|
+
- spec/local_spec.rb
|
77
85
|
- spec/access_spec.rb
|
86
|
+
- spec/file_spec.rb
|
87
|
+
- spec/string_ext_spec.rb
|
78
88
|
- spec/array_ext_spec.rb
|
79
|
-
- spec/base.rb
|
80
|
-
- spec/box_spec.rb
|
81
89
|
- spec/commands_spec.rb
|
82
90
|
- spec/config_spec.rb
|
83
|
-
- spec/dir_spec.rb
|
84
|
-
- spec/entry_spec.rb
|
85
|
-
- spec/file_spec.rb
|
86
|
-
- spec/find_by_spec.rb
|
87
91
|
- spec/fixnum_ext_spec.rb
|
88
|
-
- spec/local_spec.rb
|
89
|
-
- spec/process_spec.rb
|
90
|
-
- spec/remote_spec.rb
|
91
92
|
- spec/search_results_spec.rb
|
93
|
+
- spec/process_spec.rb
|
92
94
|
- spec/shell_spec.rb
|
93
|
-
- spec/
|
94
|
-
- spec/
|
95
|
+
- spec/dir_spec.rb
|
96
|
+
- spec/entry_spec.rb
|
97
|
+
- spec/find_by_spec.rb
|
98
|
+
- spec/box_spec.rb
|
99
|
+
- spec/process_set_spec.rb
|
95
100
|
has_rdoc: true
|
96
101
|
homepage: http://rush.heroku.com/
|
97
102
|
post_install_message:
|
@@ -114,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
119
|
requirements: []
|
115
120
|
|
116
121
|
rubyforge_project: ruby-shell
|
117
|
-
rubygems_version: 1.0
|
122
|
+
rubygems_version: 1.2.0
|
118
123
|
signing_key:
|
119
124
|
specification_version: 2
|
120
125
|
summary: A Ruby replacement for bash+ssh.
|