quorum 0.7.0 → 0.7.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/Gemfile.lock +11 -11
- data/HISTORY.md +5 -0
- data/README.rdoc +3 -0
- data/app/controllers/quorum/jobs_controller.rb +3 -7
- data/app/models/quorum/job.rb +21 -46
- data/app/views/quorum/jobs/form/_blastp_form.html.erb +2 -2
- data/app/views/quorum/jobs/form/_blastx_form.html.erb +2 -2
- data/app/views/quorum/jobs/form/_tblastn_form.html.erb +2 -2
- data/lib/quorum/version.rb +1 -1
- data/lib/quorum.rb +1 -1
- data/lib/tasks/{quorum_tasks.rake → quorum_blastdb_build.rake} +1 -1
- data/lib/tasks/quorum_delete_jobs.rake +11 -0
- data/lib/workers/system.rb +116 -0
- data/spec/models/job_spec.rb +18 -0
- metadata +7 -6
- data/lib/workers/quorum.rb +0 -55
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
quorum (0.7.
|
4
|
+
quorum (0.7.1)
|
5
5
|
bio-blastxmlparser (~> 1.1.0)
|
6
6
|
jquery-rails
|
7
7
|
net-ssh (~> 2.3.0)
|
@@ -46,17 +46,17 @@ GEM
|
|
46
46
|
nokogiri (>= 1.5.0)
|
47
47
|
bio-logger (1.0.1)
|
48
48
|
log4r (>= 1.1.9)
|
49
|
-
builder (3.0.
|
50
|
-
capybara (1.1.
|
49
|
+
builder (3.0.4)
|
50
|
+
capybara (1.1.3)
|
51
51
|
mime-types (>= 1.16)
|
52
52
|
nokogiri (>= 1.3.3)
|
53
53
|
rack (>= 1.0.0)
|
54
54
|
rack-test (>= 0.5.4)
|
55
55
|
selenium-webdriver (~> 2.0)
|
56
56
|
xpath (~> 0.1.4)
|
57
|
-
childprocess (0.3.
|
57
|
+
childprocess (0.3.6)
|
58
58
|
ffi (~> 1.0, >= 1.0.6)
|
59
|
-
database_cleaner (0.
|
59
|
+
database_cleaner (0.9.1)
|
60
60
|
diff-lcs (1.1.3)
|
61
61
|
erubis (2.7.0)
|
62
62
|
ffi (1.1.5)
|
@@ -81,7 +81,7 @@ GEM
|
|
81
81
|
mime-types (~> 1.16)
|
82
82
|
treetop (~> 1.4.8)
|
83
83
|
mime-types (1.19)
|
84
|
-
multi_json (1.3.
|
84
|
+
multi_json (1.3.7)
|
85
85
|
mysql2 (0.3.11)
|
86
86
|
net-ssh (2.3.0)
|
87
87
|
nokogiri (1.5.5)
|
@@ -126,7 +126,7 @@ GEM
|
|
126
126
|
resque-result (1.0.1)
|
127
127
|
resque (~> 1.9)
|
128
128
|
resque-meta (~> 1.0)
|
129
|
-
resque_spec (0.12.
|
129
|
+
resque_spec (0.12.5)
|
130
130
|
resque (>= 1.19.0)
|
131
131
|
rspec (>= 2.5.0)
|
132
132
|
rspec (2.11.0)
|
@@ -137,13 +137,13 @@ GEM
|
|
137
137
|
rspec-expectations (2.11.3)
|
138
138
|
diff-lcs (~> 1.1.3)
|
139
139
|
rspec-mocks (2.11.3)
|
140
|
-
rspec-rails (2.11.
|
140
|
+
rspec-rails (2.11.4)
|
141
141
|
actionpack (>= 3.0)
|
142
142
|
activesupport (>= 3.0)
|
143
143
|
railties (>= 3.0)
|
144
144
|
rspec (~> 2.11.0)
|
145
145
|
rubyzip (0.9.9)
|
146
|
-
selenium-webdriver (2.
|
146
|
+
selenium-webdriver (2.26.0)
|
147
147
|
childprocess (>= 0.2.5)
|
148
148
|
libwebsocket (~> 0.1.3)
|
149
149
|
multi_json (~> 1.0)
|
@@ -158,10 +158,10 @@ GEM
|
|
158
158
|
tilt (~> 1.1, != 1.3.0)
|
159
159
|
thor (0.16.0)
|
160
160
|
tilt (1.3.3)
|
161
|
-
treetop (1.4.
|
161
|
+
treetop (1.4.12)
|
162
162
|
polyglot
|
163
163
|
polyglot (>= 0.3.1)
|
164
|
-
tzinfo (0.3.
|
164
|
+
tzinfo (0.3.35)
|
165
165
|
vegas (0.1.11)
|
166
166
|
rack (>= 1.0.0)
|
167
167
|
xpath (0.1.4)
|
data/HISTORY.md
CHANGED
data/README.rdoc
CHANGED
@@ -316,6 +316,9 @@ Override Quorum's views and specify your own JavaScript callback function!
|
|
316
316
|
|
317
317
|
See "app/views/quorum/show.html.erb" for more details.
|
318
318
|
|
319
|
+
For an example using d3.js (https://github.com/mbostock/d3) see:
|
320
|
+
https://github.com/ncgr/lis_sequence_search
|
321
|
+
|
319
322
|
=== Redis
|
320
323
|
|
321
324
|
For detailed Redis installation instructions, follow the links below.
|
@@ -53,9 +53,7 @@ module Quorum
|
|
53
53
|
# Returns Resque worker results.
|
54
54
|
#
|
55
55
|
def get_quorum_search_results
|
56
|
-
|
57
|
-
|
58
|
-
json = empty
|
56
|
+
json = [{ :results => false }].to_json
|
59
57
|
|
60
58
|
if Quorum::BLAST_ALGORITHMS.include?(params[:algo])
|
61
59
|
queued = "#{params[:algo]}_job".to_sym
|
@@ -64,7 +62,7 @@ module Quorum
|
|
64
62
|
begin
|
65
63
|
job = Job.find(params[:id])
|
66
64
|
rescue ActiveRecord::RecordNotFound => e
|
67
|
-
json
|
65
|
+
json
|
68
66
|
else
|
69
67
|
if job.method(queued).call.present?
|
70
68
|
if job.method(report).call.present?
|
@@ -88,8 +86,6 @@ module Quorum
|
|
88
86
|
# for lookup.
|
89
87
|
#
|
90
88
|
def get_quorum_blast_hit_sequence
|
91
|
-
json = []
|
92
|
-
|
93
89
|
if Quorum::BLAST_ALGORITHMS.include?(params[:algo])
|
94
90
|
begin
|
95
91
|
job = Job.find(params[:id])
|
@@ -103,7 +99,7 @@ module Quorum
|
|
103
99
|
end
|
104
100
|
end
|
105
101
|
|
106
|
-
respond_with json
|
102
|
+
respond_with json || []
|
107
103
|
end
|
108
104
|
|
109
105
|
#
|
data/app/models/quorum/job.rb
CHANGED
@@ -38,19 +38,21 @@ module Quorum
|
|
38
38
|
# return worker's meta_id.
|
39
39
|
#
|
40
40
|
def fetch_quorum_blast_sequence(algo, algo_id)
|
41
|
-
job
|
42
|
-
|
41
|
+
job = "#{algo}_job".to_sym
|
42
|
+
job_reports = "#{algo}_job_reports".to_sym
|
43
43
|
|
44
44
|
blast_dbs = self.method(job).call.blast_dbs
|
45
45
|
|
46
|
-
job_report = self.method(
|
46
|
+
job_report = self.method(job_reports).call.where(
|
47
47
|
"quorum_#{algo}_job_reports.id = ?", algo_id
|
48
48
|
).first
|
49
49
|
|
50
50
|
hit_id = job_report.hit_id
|
51
51
|
hit_display_id = job_report.hit_display_id
|
52
52
|
|
53
|
-
cmd = create_blast_fetch_command(
|
53
|
+
cmd = Workers::System.create_blast_fetch_command(
|
54
|
+
blast_dbs, hit_id, hit_display_id, algo
|
55
|
+
)
|
54
56
|
|
55
57
|
data = Workers::System.enqueue(
|
56
58
|
cmd, Quorum.blast_remote,
|
@@ -61,6 +63,17 @@ module Quorum
|
|
61
63
|
Workers::System.get_meta(data.meta_id)
|
62
64
|
end
|
63
65
|
|
66
|
+
#
|
67
|
+
# Delete submitted jobs.
|
68
|
+
#
|
69
|
+
def self.delete_jobs(time = 1.week)
|
70
|
+
if time.is_a?(String)
|
71
|
+
time = time.split.inject { |count, unit| count.to_i.send(unit) }
|
72
|
+
end
|
73
|
+
|
74
|
+
self.where("created_at < '#{time.ago.to_s(:db)}'").destroy_all
|
75
|
+
end
|
76
|
+
|
64
77
|
private
|
65
78
|
|
66
79
|
#
|
@@ -157,16 +170,16 @@ module Quorum
|
|
157
170
|
def queue_workers
|
158
171
|
jobs = []
|
159
172
|
if self.blastn_job && self.blastn_job.queue
|
160
|
-
jobs << create_search_command("blastn")
|
173
|
+
jobs << Workers::System.create_search_command("blastn", self.id)
|
161
174
|
end
|
162
175
|
if self.blastx_job && self.blastx_job.queue
|
163
|
-
jobs << create_search_command("blastx")
|
176
|
+
jobs << Workers::System.create_search_command("blastx", self.id)
|
164
177
|
end
|
165
178
|
if self.tblastn_job && self.tblastn_job.queue
|
166
|
-
jobs << create_search_command("tblastn")
|
179
|
+
jobs << Workers::System.create_search_command("tblastn", self.id)
|
167
180
|
end
|
168
181
|
if self.blastp_job && self.blastp_job.queue
|
169
|
-
jobs << create_search_command("blastp")
|
182
|
+
jobs << Workers::System.create_search_command("blastp", self.id)
|
170
183
|
end
|
171
184
|
|
172
185
|
unless jobs.blank?
|
@@ -180,43 +193,5 @@ module Quorum
|
|
180
193
|
end
|
181
194
|
end
|
182
195
|
|
183
|
-
#
|
184
|
-
# Create fetch command based on config/quorum_settings.yml
|
185
|
-
#
|
186
|
-
def create_blast_fetch_command(db_names, hit_id, hit_display_id, algo)
|
187
|
-
# System command
|
188
|
-
cmd = ""
|
189
|
-
|
190
|
-
fetch = File.join(Quorum.blast_bin, "fetch")
|
191
|
-
cmd << "#{fetch} -f blastdbcmd -l #{Quorum.blast_log_dir} " <<
|
192
|
-
"-m #{Quorum.blast_tmp_dir} -d #{Quorum.blast_db} " <<
|
193
|
-
"-n '#{db_names}' -b '#{hit_id}' -s '#{hit_display_id}' " <<
|
194
|
-
"-a #{algo}"
|
195
|
-
end
|
196
|
-
|
197
|
-
#
|
198
|
-
# Create search command based on config/quorum_settings.yml
|
199
|
-
#
|
200
|
-
def create_search_command(algorithm)
|
201
|
-
# System command
|
202
|
-
cmd = ""
|
203
|
-
|
204
|
-
if Quorum::BLAST_ALGORITHMS.include?(algorithm)
|
205
|
-
search = File.join(Quorum.blast_bin, "search")
|
206
|
-
cmd << "#{search} -l #{Quorum.blast_log_dir} " <<
|
207
|
-
"-m #{Quorum.blast_tmp_dir} -b #{Quorum.blast_db} " <<
|
208
|
-
"-t #{Quorum.blast_threads} "
|
209
|
-
else
|
210
|
-
return cmd
|
211
|
-
end
|
212
|
-
|
213
|
-
cmd << "-s #{algorithm} -i #{self.id} " <<
|
214
|
-
"-d #{ActiveRecord::Base.configurations[::Rails.env.to_s]['database']} " <<
|
215
|
-
"-a #{ActiveRecord::Base.configurations[::Rails.env.to_s]['adapter']} " <<
|
216
|
-
"-k #{ActiveRecord::Base.configurations[::Rails.env.to_s]['host']} " <<
|
217
|
-
"-u #{ActiveRecord::Base.configurations[::Rails.env.to_s]['username']} " <<
|
218
|
-
"-p '#{ActiveRecord::Base.configurations[::Rails.env.to_s]['password']}' "
|
219
|
-
end
|
220
|
-
|
221
196
|
end
|
222
197
|
end
|
@@ -58,8 +58,8 @@
|
|
58
58
|
<%=
|
59
59
|
n.select :gap_opening_extension,
|
60
60
|
options_for_select(
|
61
|
-
@job.
|
62
|
-
@job.
|
61
|
+
@job.blastp_job.gap_opening_extension_values,
|
62
|
+
@job.blastp_job.gap_opening_extension
|
63
63
|
)
|
64
64
|
%>
|
65
65
|
</td>
|
@@ -58,8 +58,8 @@
|
|
58
58
|
<%=
|
59
59
|
n.select :gap_opening_extension,
|
60
60
|
options_for_select(
|
61
|
-
@job.
|
62
|
-
@job.
|
61
|
+
@job.blastx_job.gap_opening_extension_values,
|
62
|
+
@job.blastx_job.gap_opening_extension
|
63
63
|
)
|
64
64
|
%>
|
65
65
|
</td>
|
@@ -58,8 +58,8 @@
|
|
58
58
|
<%=
|
59
59
|
n.select :gap_opening_extension,
|
60
60
|
options_for_select(
|
61
|
-
@job.
|
62
|
-
@job.
|
61
|
+
@job.tblastn_job.gap_opening_extension_values,
|
62
|
+
@job.tblastn_job.gap_opening_extension
|
63
63
|
)
|
64
64
|
%>
|
65
65
|
</td>
|
data/lib/quorum/version.rb
CHANGED
data/lib/quorum.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
#
|
2
|
+
# Remove submitted jobs
|
3
|
+
#
|
4
|
+
|
5
|
+
namespace :quorum do
|
6
|
+
desc "Remove submitted jobs (options: TIME=\"6 weeks\" -- Default 1 week)."
|
7
|
+
task :delete_jobs => :environment do
|
8
|
+
time = ENV['TIME'] || '1 week'
|
9
|
+
puts "Jobs deleted: #{Quorum::Job.delete_jobs(time).count}"
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Workers
|
2
|
+
class System
|
3
|
+
|
4
|
+
extend Resque::Plugins::Result
|
5
|
+
|
6
|
+
@queue = :system_queue
|
7
|
+
|
8
|
+
#
|
9
|
+
# Resque worker method.
|
10
|
+
#
|
11
|
+
def self.perform(meta_id, cmd, remote, ssh_host, ssh_user, ssh_options = {}, stdout = false)
|
12
|
+
@meta_id = meta_id
|
13
|
+
@cmd = cmd
|
14
|
+
@remote = remote
|
15
|
+
@ssh_host = ssh_host
|
16
|
+
@ssh_user = ssh_user
|
17
|
+
@ssh_options = ssh_options
|
18
|
+
@stdout = stdout
|
19
|
+
@exit_status = 1
|
20
|
+
@out = ""
|
21
|
+
|
22
|
+
self.set_ssh_options
|
23
|
+
|
24
|
+
if remote
|
25
|
+
self.execute_ssh
|
26
|
+
else
|
27
|
+
@out = `#{@cmd}`
|
28
|
+
@exit_status = $?.exitstatus
|
29
|
+
end
|
30
|
+
|
31
|
+
if @exit_status > 0
|
32
|
+
raise "Worker failed :'(. See quorum/log/quorum.log for more information."
|
33
|
+
end
|
34
|
+
|
35
|
+
@out if stdout
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Convert each key in ssh_options to a symbol.
|
40
|
+
#
|
41
|
+
def self.set_ssh_options
|
42
|
+
unless @ssh_options.empty?
|
43
|
+
@ssh_options = @ssh_options.inject({}) do |memo, (k, v)|
|
44
|
+
memo[k.to_sym] = v
|
45
|
+
memo
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Execute command on remote machine.
|
52
|
+
#
|
53
|
+
def self.execute_ssh
|
54
|
+
Net::SSH.start(@ssh_host, @ssh_user, @ssh_options) do |ssh|
|
55
|
+
ssh.open_channel do |ch|
|
56
|
+
ch.exec(cmd) do |ch, success|
|
57
|
+
if success
|
58
|
+
# Capture STDOUT from ch.exec()
|
59
|
+
if @stdout
|
60
|
+
ch.on_data do |ch, data|
|
61
|
+
@out = data
|
62
|
+
end
|
63
|
+
end
|
64
|
+
# Read the exit status of the remote process.
|
65
|
+
ch.on_request("exit-status") do |ch, data|
|
66
|
+
@exit_status = data.read_long
|
67
|
+
end
|
68
|
+
else
|
69
|
+
Rails.logger.warn "Channel Net::SSH exec() failed. :'("
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
ssh.loop
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Create fetch command based on config/quorum_settings.yml
|
79
|
+
#
|
80
|
+
def self.create_blast_fetch_command(db_names, hit_id, hit_display_id, algo)
|
81
|
+
# System command
|
82
|
+
cmd = ""
|
83
|
+
|
84
|
+
fetch = File.join(Quorum.blast_bin, "fetch")
|
85
|
+
cmd << "#{fetch} -f blastdbcmd -l #{Quorum.blast_log_dir} " <<
|
86
|
+
"-m #{Quorum.blast_tmp_dir} -d #{Quorum.blast_db} " <<
|
87
|
+
"-n '#{db_names}' -b '#{hit_id}' -s '#{hit_display_id}' " <<
|
88
|
+
"-a #{algo}"
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Create search command based on config/quorum_settings.yml
|
93
|
+
#
|
94
|
+
def self.create_search_command(algo, id)
|
95
|
+
# System command
|
96
|
+
cmd = ""
|
97
|
+
|
98
|
+
if Quorum::BLAST_ALGORITHMS.include?(algo)
|
99
|
+
search = File.join(Quorum.blast_bin, "search")
|
100
|
+
cmd << "#{search} -l #{Quorum.blast_log_dir} " <<
|
101
|
+
"-m #{Quorum.blast_tmp_dir} -b #{Quorum.blast_db} " <<
|
102
|
+
"-t #{Quorum.blast_threads} "
|
103
|
+
else
|
104
|
+
return cmd
|
105
|
+
end
|
106
|
+
|
107
|
+
cmd << "-s #{algo} -i #{id} " <<
|
108
|
+
"-d #{ActiveRecord::Base.configurations[::Rails.env.to_s]['database']} " <<
|
109
|
+
"-a #{ActiveRecord::Base.configurations[::Rails.env.to_s]['adapter']} " <<
|
110
|
+
"-k #{ActiveRecord::Base.configurations[::Rails.env.to_s]['host']} " <<
|
111
|
+
"-u #{ActiveRecord::Base.configurations[::Rails.env.to_s]['username']} " <<
|
112
|
+
"-p '#{ActiveRecord::Base.configurations[::Rails.env.to_s]['password']}' "
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
data/spec/models/job_spec.rb
CHANGED
@@ -38,6 +38,24 @@ describe Quorum::Job do
|
|
38
38
|
@job.should have(0).errors_on(:algorithm)
|
39
39
|
end
|
40
40
|
|
41
|
+
it "deletes submitted jobs" do
|
42
|
+
1.upto(5) do |i|
|
43
|
+
job = Quorum::Job.new()
|
44
|
+
job.sequence = File.open(
|
45
|
+
File.expand_path("../../data/nucl_prot_seqs.txt", __FILE__)
|
46
|
+
).read
|
47
|
+
|
48
|
+
job.build_blastn_job
|
49
|
+
job.blastn_job.queue = true
|
50
|
+
job.blastn_job.blast_dbs = ["test"]
|
51
|
+
|
52
|
+
job.created_at = i.weeks.ago
|
53
|
+
job.save!
|
54
|
+
end
|
55
|
+
Quorum::Job.delete_jobs("25 days").count.should eq(2)
|
56
|
+
Quorum::BlastnJob.count.should eq(3)
|
57
|
+
end
|
58
|
+
|
41
59
|
it "queues workers after save" do
|
42
60
|
@job.sequence = File.open(
|
43
61
|
File.expand_path("../../data/nucl_prot_seqs.txt", __FILE__)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quorum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -303,9 +303,10 @@ files:
|
|
303
303
|
- lib/tasks/blastdb/README
|
304
304
|
- lib/tasks/blastdb/build_blast_db.rb
|
305
305
|
- lib/tasks/jasmine.rake
|
306
|
+
- lib/tasks/quorum_blastdb_build.rake
|
307
|
+
- lib/tasks/quorum_delete_jobs.rake
|
306
308
|
- lib/tasks/quorum_resque.rake
|
307
|
-
- lib/
|
308
|
-
- lib/workers/quorum.rb
|
309
|
+
- lib/workers/system.rb
|
309
310
|
- quorum.gemspec
|
310
311
|
- script/rails
|
311
312
|
- spec/config/quorum_settings.yml
|
@@ -402,7 +403,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
402
403
|
version: '0'
|
403
404
|
segments:
|
404
405
|
- 0
|
405
|
-
hash:
|
406
|
+
hash: 1003819355082357991
|
406
407
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
407
408
|
none: false
|
408
409
|
requirements:
|
@@ -411,7 +412,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
411
412
|
version: '0'
|
412
413
|
segments:
|
413
414
|
- 0
|
414
|
-
hash:
|
415
|
+
hash: 1003819355082357991
|
415
416
|
requirements: []
|
416
417
|
rubyforge_project:
|
417
418
|
rubygems_version: 1.8.24
|
data/lib/workers/quorum.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
module Workers
|
2
|
-
class System
|
3
|
-
extend Resque::Plugins::Result
|
4
|
-
|
5
|
-
@queue = :system_queue
|
6
|
-
|
7
|
-
#
|
8
|
-
# Resque worker method.
|
9
|
-
#
|
10
|
-
def self.perform(meta_id, cmd, remote, ssh_host, ssh_user, ssh_options = {}, stdout = false)
|
11
|
-
unless ssh_options.empty?
|
12
|
-
# Convert each key in ssh_options to a symbol.
|
13
|
-
ssh_options = ssh_options.inject({}) do |memo, (k, v)|
|
14
|
-
memo[k.to_sym] = v
|
15
|
-
memo
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
exit_status = 1
|
20
|
-
out = ""
|
21
|
-
|
22
|
-
if remote
|
23
|
-
# Execute command on remote machine.
|
24
|
-
Net::SSH.start(ssh_host, ssh_user, ssh_options) do |ssh|
|
25
|
-
ssh.open_channel do |ch|
|
26
|
-
ch.exec(cmd) do |ch, success|
|
27
|
-
if success
|
28
|
-
# Capture STDOUT from ch.exec()
|
29
|
-
if stdout
|
30
|
-
ch.on_data do |ch, data|
|
31
|
-
out = data
|
32
|
-
end
|
33
|
-
end
|
34
|
-
# Read the exit status of the remote process.
|
35
|
-
ch.on_request("exit-status") do |ch, data|
|
36
|
-
exit_status = data.read_long
|
37
|
-
end
|
38
|
-
else
|
39
|
-
Rails.logger.warn "Channel Net::SSH exec() failed. :'("
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
ssh.loop
|
44
|
-
end
|
45
|
-
else
|
46
|
-
out = `#{cmd}`
|
47
|
-
exit_status = $?.exitstatus
|
48
|
-
end
|
49
|
-
if exit_status > 0
|
50
|
-
raise "Worker failed :'(. See quorum/log/quorum.log for more information."
|
51
|
-
end
|
52
|
-
out if stdout
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|