quorum 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|