neptune 0.1.1 → 0.1.2
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/README +7 -4
- data/doc/AppControllerClient.html +12 -4
- data/doc/CommonFunctions.html +55 -42
- data/doc/Kernel.html +187 -0
- data/doc/LICENSE.html +2 -0
- data/doc/Object.html +488 -198
- data/doc/README.html +26 -5
- data/doc/bin/neptune.html +1 -1
- data/doc/created.rid +6 -6
- data/doc/index.html +20 -2
- data/doc/lib/app_controller_client_rb.html +2 -2
- data/doc/lib/common_functions_rb.html +2 -2
- data/doc/lib/neptune_rb.html +3 -1
- data/lib/app_controller_client.rb +2 -2
- data/lib/common_functions.rb +50 -24
- data/lib/neptune.rb +224 -159
- data/samples/appscale/add_appserver.rb +10 -0
- data/samples/appscale/add_database.rb +9 -0
- data/samples/appscale/add_loadbalancer.rb +9 -0
- data/samples/appscale/add_slave.rb +9 -0
- data/samples/c/compile_helloworld.rb +10 -0
- data/samples/c/helloworld/helloworld.c +6 -0
- data/samples/erlang/compile_erlang_ring.rb +10 -0
- data/samples/erlang/get_erlang_output.rb +8 -0
- data/samples/erlang/ring/Makefile +3 -0
- data/samples/erlang/ring/ring.erl +90 -0
- data/samples/erlang/run_erlang_ring.rb +6 -0
- data/samples/go/compile_hello.rb +10 -0
- data/samples/go/get_hello_output.rb +6 -0
- data/samples/go/hello/hello.go +8 -0
- data/samples/go/put_input.rb +8 -0
- data/samples/go/run_hello.rb +9 -0
- data/samples/mapreduce/expected-output.txt +7078 -0
- data/samples/mapreduce/get_mapreduce_output.rb +4 -0
- data/samples/mapreduce/hadoop-0.20.0-examples.jar +0 -0
- data/samples/mapreduce/input-10 +64 -0
- data/samples/mapreduce/input-30 +64 -0
- data/samples/mapreduce/input-7 +4 -0
- data/samples/mapreduce/map.rb +48 -0
- data/samples/mapreduce/reduce.rb +48 -0
- data/samples/mapreduce/run_java_mr.rb +14 -0
- data/samples/mapreduce/run_mapreduce.rb +13 -0
- data/samples/mapreduce/the-end-of-time.txt +11256 -0
- data/samples/mpi/Makefile +22 -0
- data/samples/mpi/MpiQueen +0 -0
- data/samples/mpi/compile_mpi_ring.rb +10 -0
- data/samples/mpi/compile_x10_nqueens.rb +8 -0
- data/samples/mpi/cpi +0 -0
- data/samples/mpi/get_mpi_output.rb +5 -0
- data/samples/mpi/get_ring_output.rb +5 -0
- data/samples/mpi/hw2.c +205 -0
- data/samples/mpi/hw2harness.c +84 -0
- data/samples/mpi/hw2harness.h +45 -0
- data/samples/mpi/powermethod +0 -0
- data/samples/mpi/ring/Makefile +2 -0
- data/samples/mpi/ring/Ring.c +76 -0
- data/samples/mpi/run_mpi_cpi.rb +10 -0
- data/samples/mpi/run_mpi_nqueens.np +6 -0
- data/samples/mpi/run_mpi_powermethod.rb +8 -0
- data/samples/mpi/run_mpi_ring.rb +12 -0
- data/samples/r/compile_hello.rb +10 -0
- data/samples/r/get_hello_output.rb +6 -0
- data/samples/r/hello/hello.r +1 -0
- data/samples/r/put_input.rb +8 -0
- data/samples/r/run_hello.rb +9 -0
- data/samples/upc/compile_upc_helloworld.rb +10 -0
- data/samples/upc/compile_upc_ring.rb +11 -0
- data/samples/upc/get_mpi_output.rb +8 -0
- data/samples/upc/helloworld/HelloWorld.c +9 -0
- data/samples/upc/helloworld/Makefile +3 -0
- data/samples/upc/ring/Makefile +3 -0
- data/samples/upc/ring/Ring.c +116 -0
- data/samples/upc/run_upc_helloworld.rb +12 -0
- data/samples/upc/run_upc_ring.rb +12 -0
- data/samples/x10/MyPowerMethod +0 -0
- data/samples/x10/MyPowerMethod.x10 +236 -0
- data/samples/x10/NQueensDist +0 -0
- data/samples/x10/NQueensDist.x10 +112 -0
- data/samples/x10/compile_x10_nqueens.rb +7 -0
- data/samples/x10/compile_x10_ring.rb +12 -0
- data/samples/x10/get_x10_output.rb +8 -0
- data/samples/x10/ring/Makefile +3 -0
- data/samples/x10/ring/Ring.x10 +28 -0
- data/samples/x10/ring/RingOld.x10 +68 -0
- data/samples/x10/run_x10_nqueens.rb +6 -0
- data/samples/x10/run_x10_powermethod.rb +7 -0
- data/samples/x10/run_x10_ring.rb +6 -0
- data/test/{tc_c.rb → integration/tc_c.rb} +2 -2
- data/test/{tc_dfsp.rb → integration/tc_dfsp.rb} +0 -0
- data/test/{tc_dwssa.rb → integration/tc_dwssa.rb} +0 -0
- data/test/{tc_erlang.rb → integration/tc_erlang.rb} +0 -0
- data/test/{tc_mapreduce.rb → integration/tc_mapreduce.rb} +0 -0
- data/test/{tc_mpi.rb → integration/tc_mpi.rb} +0 -0
- data/test/{tc_storage.rb → integration/tc_storage.rb} +0 -0
- data/test/{tc_upc.rb → integration/tc_upc.rb} +0 -0
- data/test/{tc_x10.rb → integration/tc_x10.rb} +0 -0
- data/test/{test_helper.rb → integration/test_helper.rb} +0 -0
- data/test/{ts_neptune.rb → integration/ts_neptune.rb} +2 -2
- data/test/unit/test_app_controller_client.rb +106 -0
- data/test/unit/test_common_functions.rb +106 -0
- data/test/unit/test_neptune.rb +208 -0
- data/test/unit/ts_all.rb +6 -0
- metadata +91 -15
data/doc/LICENSE.html
CHANGED
data/doc/Object.html
CHANGED
@@ -72,18 +72,32 @@
|
|
72
72
|
<h3 class="section-header">Methods</h3>
|
73
73
|
<ul class="link-list">
|
74
74
|
|
75
|
+
<li><a href="#method-i-compile_code">#compile_code</a></li>
|
76
|
+
|
75
77
|
<li><a href="#method-i-do_preprocessing">#do_preprocessing</a></li>
|
76
78
|
|
79
|
+
<li><a href="#method-i-get_input">#get_input</a></li>
|
80
|
+
|
81
|
+
<li><a href="#method-i-get_job_data">#get_job_data</a></li>
|
82
|
+
|
83
|
+
<li><a href="#method-i-get_std_out_and_err">#get_std_out_and_err</a></li>
|
84
|
+
|
77
85
|
<li><a href="#method-i-neptune">#neptune</a></li>
|
78
86
|
|
79
87
|
<li><a href="#method-i-preprocess_compile">#preprocess_compile</a></li>
|
80
88
|
|
81
89
|
<li><a href="#method-i-preprocess_erlang">#preprocess_erlang</a></li>
|
82
90
|
|
83
|
-
<li><a href="#method-i-preprocess_mapreduce">#preprocess_mapreduce</a></li>
|
84
|
-
|
85
91
|
<li><a href="#method-i-preprocess_mpi">#preprocess_mpi</a></li>
|
86
92
|
|
93
|
+
<li><a href="#method-i-preprocess_ssa">#preprocess_ssa</a></li>
|
94
|
+
|
95
|
+
<li><a href="#method-i-run_job">#run_job</a></li>
|
96
|
+
|
97
|
+
<li><a href="#method-i-validate_storage_params">#validate_storage_params</a></li>
|
98
|
+
|
99
|
+
<li><a href="#method-i-wait_for_compilation_to_finish">#wait_for_compilation_to_finish</a></li>
|
100
|
+
|
87
101
|
</ul>
|
88
102
|
</div>
|
89
103
|
|
@@ -126,6 +140,8 @@
|
|
126
140
|
|
127
141
|
<li><a href="./CommonFunctions.html">CommonFunctions</a></li>
|
128
142
|
|
143
|
+
<li><a href="./Kernel.html">Kernel</a></li>
|
144
|
+
|
129
145
|
<li><a href="./Object.html">Object</a></li>
|
130
146
|
|
131
147
|
</ul>
|
@@ -145,7 +161,9 @@
|
|
145
161
|
Neptune support. In the future, it is likely that the only exposed /
|
146
162
|
monkey-patched method should be job, while the others could probably be
|
147
163
|
folded into either a Neptune-specific class or into <a
|
148
|
-
href="CommonFunctions.html">CommonFunctions</a
|
164
|
+
href="CommonFunctions.html">CommonFunctions</a>. TODO(cbunch): This
|
165
|
+
doesn’t look like it does anything - run the integration test and confirm
|
166
|
+
one way or the other.</p>
|
149
167
|
|
150
168
|
</div>
|
151
169
|
|
@@ -201,6 +219,65 @@ computation can be performed.</p></dd>
|
|
201
219
|
<h3 class="section-header">Public Instance Methods</h3>
|
202
220
|
|
203
221
|
|
222
|
+
<div id="compile_code-method" class="method-detail ">
|
223
|
+
<a name="method-i-compile_code"></a>
|
224
|
+
|
225
|
+
|
226
|
+
<div class="method-heading">
|
227
|
+
<span class="method-name">compile_code</span><span
|
228
|
+
class="method-args">(job_data, ssh_args, shadow_ip, shell=Kernel.method(:`))</span>
|
229
|
+
<span class="method-click-advice">click to toggle source</span>
|
230
|
+
</div>
|
231
|
+
|
232
|
+
|
233
|
+
<div class="method-description">
|
234
|
+
|
235
|
+
<p>This method sends out a request to compile code, waits for it to finish,
|
236
|
+
and gets the standard out and error returned from the compilation. This
|
237
|
+
method returns a hash containing the standard out, error, and a result that
|
238
|
+
indicates whether or not the compilation was successful.</p>
|
239
|
+
|
240
|
+
|
241
|
+
|
242
|
+
<div class="method-source-code"
|
243
|
+
id="compile_code-source">
|
244
|
+
<pre>
|
245
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 281</span>
|
246
|
+
def compile_code(job_data, ssh_args, shadow_ip, shell=<span class="ruby-constant">Kernel</span>.method(:`))
|
247
|
+
compiled_location = controller.compile_code(job_data)
|
248
|
+
|
249
|
+
copy_to = job_data[<span class="ruby-string">"@copy_to"</span>]
|
250
|
+
|
251
|
+
wait_for_compilation_to_finish(ssh_args, shadow_ip, compiled_location)
|
252
|
+
|
253
|
+
<span class="ruby-constant">FileUtils</span>.rm_rf(copy_to)
|
254
|
+
|
255
|
+
scp_command = "scp -r #{ssh_args} root@#{shadow_ip}:#{compiled_location} #{copy_to} 2>&1"
|
256
|
+
puts scp_command
|
257
|
+
shell.call(scp_command)
|
258
|
+
|
259
|
+
code = job_data[<span class="ruby-string">"@code"</span>]
|
260
|
+
dirs = code.split(<span class="ruby-regexp">/\//</span>)
|
261
|
+
remote_dir = <span class="ruby-string">"/tmp/"</span> + dirs[-1]
|
262
|
+
|
263
|
+
[remote_dir, compiled_location].each { |remote_files|
|
264
|
+
ssh_command = "ssh #{ssh_args} root@#{shadow_ip} 'rm -rf #{remote_files}' 2>&1"
|
265
|
+
puts ssh_command
|
266
|
+
shell.call(ssh_command)
|
267
|
+
}
|
268
|
+
|
269
|
+
return get_std_out_and_err(copy_to)
|
270
|
+
end</pre>
|
271
|
+
</div>
|
272
|
+
|
273
|
+
</div>
|
274
|
+
|
275
|
+
|
276
|
+
|
277
|
+
|
278
|
+
</div>
|
279
|
+
|
280
|
+
|
204
281
|
<div id="do_preprocessing-method" class="method-detail ">
|
205
282
|
<a name="method-i-do_preprocessing"></a>
|
206
283
|
|
@@ -223,10 +300,12 @@ method to use based on the type of the job that the user has asked to run.</p>
|
|
223
300
|
<div class="method-source-code"
|
224
301
|
id="do_preprocessing-source">
|
225
302
|
<pre>
|
226
|
-
<span class="ruby-comment"># File lib/neptune.rb, line
|
303
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 52</span>
|
227
304
|
def do_preprocessing(job_data)
|
228
305
|
job_type = job_data[<span class="ruby-string">"@type"</span>]
|
229
|
-
|
306
|
+
if !<span class="ruby-constant">NEED_PREPROCESSING</span>.include?(job_type)
|
307
|
+
return
|
308
|
+
end
|
230
309
|
|
231
310
|
preprocess = "preprocess_#{job_type}".to_sym
|
232
311
|
send(preprocess, job_data)
|
@@ -241,51 +320,101 @@ end</pre>
|
|
241
320
|
</div>
|
242
321
|
|
243
322
|
|
244
|
-
<div id="
|
245
|
-
<a name="method-i-
|
323
|
+
<div id="get_input-method" class="method-detail ">
|
324
|
+
<a name="method-i-get_input"></a>
|
246
325
|
|
247
326
|
|
248
327
|
<div class="method-heading">
|
249
|
-
<span class="method-name">
|
250
|
-
class="method-args">(
|
328
|
+
<span class="method-name">get_input</span><span
|
329
|
+
class="method-args">(job_data, ssh_args, shadow_ip, controller, file=File, shell=Kernel.method(:`))</span>
|
251
330
|
<span class="method-click-advice">click to toggle source</span>
|
252
331
|
</div>
|
253
332
|
|
254
333
|
|
255
334
|
<div class="method-description">
|
256
335
|
|
257
|
-
<p>This method
|
258
|
-
|
259
|
-
|
260
|
-
access policy (ACL) for the output of a job. By default, job data is
|
261
|
-
private, but a Neptune job can be used to set it to public later (and
|
262
|
-
vice-versa).</p>
|
336
|
+
<p>This method takes a file on the local user’s computer and stores it
|
337
|
+
remotely via AppScale. It returns a hash map indicating whether or not the
|
338
|
+
job succeeded and if it failed, the reason for it.</p>
|
263
339
|
|
264
340
|
|
265
341
|
|
266
342
|
<div class="method-source-code"
|
267
|
-
id="
|
343
|
+
id="get_input-source">
|
268
344
|
<pre>
|
269
|
-
<span class="ruby-comment"># File lib/neptune.rb, line
|
270
|
-
def
|
271
|
-
|
272
|
-
|
345
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 227</span>
|
346
|
+
def get_input(job_data, ssh_args, shadow_ip, controller, file=<span class="ruby-constant">File</span>,
|
347
|
+
shell=<span class="ruby-constant">Kernel</span>.method(:`))
|
348
|
+
result = {:result => :success}
|
273
349
|
|
274
|
-
|
350
|
+
if !job_data[<span class="ruby-string">"@local"</span>]
|
351
|
+
abort(<span class="ruby-string">"You failed to specify a file to copy over via the :local flag."</span>)
|
352
|
+
end
|
275
353
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
354
|
+
local_file = file.expand_path(job_data[<span class="ruby-string">"@local"</span>])
|
355
|
+
if !file.exists?(local_file)
|
356
|
+
reason = "the file you specified to copy, #{local_file}, doesn't exist." +
|
357
|
+
<span class="ruby-string">" Please specify a file that exists and try again."</span>
|
358
|
+
return {:result => :failure, :reason => reason}
|
359
|
+
end
|
360
|
+
|
361
|
+
remote = "/tmp/neptune-input-#{rand(100000)}"
|
362
|
+
scp_cmd = "scp -r #{ssh_args} #{local_file} root@#{shadow_ip}:#{remote}"
|
363
|
+
puts scp_cmd
|
364
|
+
shell.call(scp_cmd)
|
365
|
+
|
366
|
+
job_data[<span class="ruby-string">"@local"</span>] = remote
|
367
|
+
puts "job data = #{job_data.inspect}"
|
368
|
+
response = controller.put_input(job_data)
|
369
|
+
if response
|
370
|
+
return {:result => :success}
|
371
|
+
else
|
372
|
+
<span class="ruby-comment"># TODO - expand this to include the reason why it failed</span>
|
373
|
+
return {:result => :failure}
|
374
|
+
end
|
375
|
+
end</pre>
|
376
|
+
</div>
|
377
|
+
|
378
|
+
</div>
|
379
|
+
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
</div>
|
280
384
|
|
385
|
+
|
386
|
+
<div id="get_job_data-method" class="method-detail ">
|
387
|
+
<a name="method-i-get_job_data"></a>
|
388
|
+
|
389
|
+
|
390
|
+
<div class="method-heading">
|
391
|
+
<span class="method-name">get_job_data</span><span
|
392
|
+
class="method-args">(params)</span>
|
393
|
+
<span class="method-click-advice">click to toggle source</span>
|
394
|
+
</div>
|
395
|
+
|
396
|
+
|
397
|
+
<div class="method-description">
|
398
|
+
|
399
|
+
|
400
|
+
|
401
|
+
|
402
|
+
|
403
|
+
<div class="method-source-code"
|
404
|
+
id="get_job_data-source">
|
405
|
+
<pre>
|
406
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 151</span>
|
407
|
+
def get_job_data(params)
|
281
408
|
job_data = {}
|
282
409
|
params.each { |k, v|
|
283
410
|
key = "@#{k}"
|
284
411
|
job_data[key] = v
|
285
412
|
}
|
286
413
|
|
287
|
-
job_data
|
288
|
-
job_data[<span class="ruby-string">"@keyname"</span>] = keyname || <span class="ruby-string">"appscale"</span>
|
414
|
+
job_data.delete(<span class="ruby-string">"@job"</span>)
|
415
|
+
job_data[<span class="ruby-string">"@keyname"</span>] = params[:keyname] || <span class="ruby-string">"appscale"</span>
|
416
|
+
|
417
|
+
job_data[<span class="ruby-string">"@type"</span>] = job_data[<span class="ruby-string">"@type"</span>].to_s
|
289
418
|
type = job_data[<span class="ruby-string">"@type"</span>]
|
290
419
|
|
291
420
|
if type == <span class="ruby-string">"upc"</span> or type == <span class="ruby-string">"x10"</span>
|
@@ -307,115 +436,110 @@ def neptune(params)
|
|
307
436
|
end
|
308
437
|
end
|
309
438
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
abort(msg)
|
316
|
-
end
|
439
|
+
return job_data
|
440
|
+
end</pre>
|
441
|
+
</div>
|
442
|
+
|
443
|
+
</div>
|
317
444
|
|
318
|
-
|
319
|
-
<span class="ruby-comment"># the same library as we do for S3 - so just tell it that it's S3</span>
|
320
|
-
if storage == <span class="ruby-string">"gstorage"</span>
|
321
|
-
storage = <span class="ruby-string">"s3"</span>
|
322
|
-
job_data[<span class="ruby-string">"@storage"</span>] = <span class="ruby-string">"s3"</span>
|
323
|
-
end
|
445
|
+
|
324
446
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
447
|
+
|
448
|
+
</div>
|
449
|
+
|
450
|
+
|
451
|
+
<div id="get_std_out_and_err-method" class="method-detail ">
|
452
|
+
<a name="method-i-get_std_out_and_err"></a>
|
453
|
+
|
454
|
+
|
455
|
+
<div class="method-heading">
|
456
|
+
<span class="method-name">get_std_out_and_err</span><span
|
457
|
+
class="method-args">(location)</span>
|
458
|
+
<span class="method-click-advice">click to toggle source</span>
|
459
|
+
</div>
|
460
|
+
|
461
|
+
|
462
|
+
<div class="method-description">
|
463
|
+
|
464
|
+
<p>This method returns a hash containing the standard out and standard error
|
465
|
+
from a completed job, as well as a result field that indicates whether or
|
466
|
+
not the job completed successfully (success = no errors).</p>
|
467
|
+
|
468
|
+
|
469
|
+
|
470
|
+
<div class="method-source-code"
|
471
|
+
id="get_std_out_and_err-source">
|
472
|
+
<pre>
|
473
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 310</span>
|
474
|
+
def get_std_out_and_err(location)
|
475
|
+
result = {}
|
476
|
+
|
477
|
+
out = <span class="ruby-constant">File</span>.open("#{location}/compile_out") { |f| f.read.chomp! }
|
478
|
+
result[:out] = out
|
479
|
+
|
480
|
+
err = <span class="ruby-constant">File</span>.open("#{location}/compile_err") { |f| f.read.chomp! }
|
481
|
+
result[:err] = err
|
482
|
+
|
483
|
+
if result[:err]
|
484
|
+
result[:result] = :failure
|
339
485
|
else
|
340
|
-
|
341
|
-
end
|
486
|
+
result[:result] = :success
|
487
|
+
end
|
342
488
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
489
|
+
return result
|
490
|
+
end</pre>
|
491
|
+
</div>
|
492
|
+
|
493
|
+
</div>
|
348
494
|
|
349
|
-
|
495
|
+
|
350
496
|
|
351
|
-
|
497
|
+
|
498
|
+
</div>
|
352
499
|
|
353
|
-
|
500
|
+
|
501
|
+
<div id="neptune-method" class="method-detail ">
|
502
|
+
<a name="method-i-neptune"></a>
|
354
503
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
abort(msg)
|
363
|
-
end
|
504
|
+
|
505
|
+
<div class="method-heading">
|
506
|
+
<span class="method-name">neptune</span><span
|
507
|
+
class="method-args">(params)</span>
|
508
|
+
<span class="method-click-advice">click to toggle source</span>
|
509
|
+
</div>
|
510
|
+
|
364
511
|
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
return controller.get_output(job_data)
|
375
|
-
elsif type == <span class="ruby-string">"get-acl"</span>
|
376
|
-
job_data[<span class="ruby-string">"@type"</span>] = <span class="ruby-string">"acl"</span>
|
377
|
-
return controller.get_acl(job_data)
|
378
|
-
elsif type == <span class="ruby-string">"set-acl"</span>
|
379
|
-
job_data[<span class="ruby-string">"@type"</span>] = <span class="ruby-string">"acl"</span>
|
380
|
-
return controller.set_acl(job_data)
|
381
|
-
elsif type == <span class="ruby-string">"compile"</span>
|
382
|
-
compiled_location = controller.compile_code(job_data)
|
383
|
-
|
384
|
-
copy_to = job_data[<span class="ruby-string">"@copy_to"</span>]
|
385
|
-
|
386
|
-
loop {
|
387
|
-
ssh_command = "ssh #{ssh_args} root@#{shadow_ip} 'ls #{compiled_location}' 2>&1"
|
388
|
-
<span class="ruby-comment">#puts ssh_command</span>
|
389
|
-
result = `#{ssh_command}`
|
390
|
-
<span class="ruby-comment">#puts "result was [#{result}]"</span>
|
391
|
-
if result =~ <span class="ruby-regexp">/No such file or directory/</span>
|
392
|
-
puts <span class="ruby-string">"Still waiting for code to be compiled..."</span>
|
393
|
-
else
|
394
|
-
puts "compilation complete! Copying compiled code to #{copy_to}"
|
395
|
-
break
|
396
|
-
end
|
397
|
-
sleep(5)
|
398
|
-
}
|
512
|
+
<div class="method-description">
|
513
|
+
|
514
|
+
<p>This method is the heart of Neptune - here, we take blocks of code that the
|
515
|
+
user has written and convert them into HPC job requests. At a high level,
|
516
|
+
the user can request to run a job, retrieve a job’s output, or modify the
|
517
|
+
access policy (ACL) for the output of a job. By default, job data is
|
518
|
+
private, but a Neptune job can be used to set it to public later (and
|
519
|
+
vice-versa).</p>
|
520
|
+
|
399
521
|
|
400
|
-
|
401
|
-
|
402
|
-
|
522
|
+
|
523
|
+
<div class="method-source-code"
|
524
|
+
id="neptune-source">
|
525
|
+
<pre>
|
526
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 368</span>
|
527
|
+
def neptune(params)
|
528
|
+
puts <span class="ruby-string">"Received a request to run a job."</span>
|
529
|
+
puts params[:type]
|
403
530
|
|
404
|
-
|
405
|
-
|
406
|
-
|
531
|
+
job_data = get_job_data(params)
|
532
|
+
validate_storage_params(job_data)
|
533
|
+
puts "job data = #{job_data.inspect}"
|
534
|
+
do_preprocessing(job_data)
|
535
|
+
keyname = job_data[<span class="ruby-string">"@keyname"</span>]
|
407
536
|
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
return {:result => :success, :msg => result}
|
415
|
-
else
|
416
|
-
return {:result => :failure, :msg => result}
|
417
|
-
end
|
418
|
-
end
|
537
|
+
shadow_ip = <span class="ruby-constant">CommonFunctions</span>.get_from_yaml(keyname, :shadow)
|
538
|
+
secret = <span class="ruby-constant">CommonFunctions</span>.get_secret_key(keyname)
|
539
|
+
ssh_key = <span class="ruby-constant">File</span>.expand_path("~/.appscale/#{keyname}.key")
|
540
|
+
ssh_args = "-i ~/.appscale/#{keyname}.key -o StrictHostkeyChecking=no "
|
541
|
+
|
542
|
+
return run_job(job_data, ssh_args, shadow_ip, secret)
|
419
543
|
end</pre>
|
420
544
|
</div>
|
421
545
|
|
@@ -433,7 +557,7 @@ end</pre>
|
|
433
557
|
|
434
558
|
<div class="method-heading">
|
435
559
|
<span class="method-name">preprocess_compile</span><span
|
436
|
-
class="method-args">(job_data)</span>
|
560
|
+
class="method-args">(job_data, shell=Kernel.method(:`))</span>
|
437
561
|
<span class="method-click-advice">click to toggle source</span>
|
438
562
|
</div>
|
439
563
|
|
@@ -449,10 +573,10 @@ copy over libraries as well.</p>
|
|
449
573
|
<div class="method-source-code"
|
450
574
|
id="preprocess_compile-source">
|
451
575
|
<pre>
|
452
|
-
<span class="ruby-comment"># File lib/neptune.rb, line
|
453
|
-
def preprocess_compile(job_data)
|
576
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 65</span>
|
577
|
+
def preprocess_compile(job_data, shell=<span class="ruby-constant">Kernel</span>.method(:`))
|
454
578
|
code = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">"@code"</span>])
|
455
|
-
|
579
|
+
if !<span class="ruby-constant">File</span>.exists?(code)
|
456
580
|
abort("The source file #{code} does not exist.")
|
457
581
|
end
|
458
582
|
|
@@ -463,8 +587,8 @@ def preprocess_compile(job_data)
|
|
463
587
|
|
464
588
|
ssh_args = "-i ~/.appscale/#{keyname}.key -o StrictHostkeyChecking=no root@#{shadow_ip}"
|
465
589
|
remove_dir = "ssh #{ssh_args} 'rm -rf #{dest}' 2>&1"
|
466
|
-
|
467
|
-
|
590
|
+
puts remove_dir
|
591
|
+
shell.call(remove_dir)
|
468
592
|
|
469
593
|
<span class="ruby-constant">CommonFunctions</span>.scp_to_shadow(code, dest, keyname, is_dir=true)
|
470
594
|
|
@@ -486,7 +610,7 @@ end</pre>
|
|
486
610
|
|
487
611
|
<div class="method-heading">
|
488
612
|
<span class="method-name">preprocess_erlang</span><span
|
489
|
-
class="method-args">(job_data)</span>
|
613
|
+
class="method-args">(job_data, file=File, common_functions=CommonFunctions)</span>
|
490
614
|
<span class="method-click-advice">click to toggle source</span>
|
491
615
|
</div>
|
492
616
|
|
@@ -500,18 +624,21 @@ end</pre>
|
|
500
624
|
<div class="method-source-code"
|
501
625
|
id="preprocess_erlang-source">
|
502
626
|
<pre>
|
503
|
-
<span class="ruby-comment"># File lib/neptune.rb, line
|
504
|
-
def preprocess_erlang(job_data)
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
627
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 86</span>
|
628
|
+
def preprocess_erlang(job_data, file=<span class="ruby-constant">File</span>, common_functions=<span class="ruby-constant">CommonFunctions</span>)
|
629
|
+
if !job_data[<span class="ruby-string">"@code"</span>]
|
630
|
+
abort(<span class="ruby-string">"When running Erlang jobs, :code must be specified."</span>)
|
631
|
+
end
|
632
|
+
|
633
|
+
source_code = file.expand_path(job_data[<span class="ruby-string">"@code"</span>])
|
634
|
+
if !file.exists?(source_code)
|
635
|
+
abort("The specified code, #{job_data['@code']}," +
|
636
|
+
<span class="ruby-string">" didn't exist. Please specify one that exists and try again"</span>)
|
510
637
|
end
|
511
638
|
dest_code = <span class="ruby-string">"/tmp/"</span>
|
512
639
|
|
513
640
|
keyname = job_data[<span class="ruby-string">"@keyname"</span>]
|
514
|
-
|
641
|
+
common_functions.scp_to_shadow(source_code, dest_code, keyname)
|
515
642
|
end</pre>
|
516
643
|
</div>
|
517
644
|
|
@@ -523,12 +650,12 @@ end</pre>
|
|
523
650
|
</div>
|
524
651
|
|
525
652
|
|
526
|
-
<div id="
|
527
|
-
<a name="method-i-
|
653
|
+
<div id="preprocess_mpi-method" class="method-detail ">
|
654
|
+
<a name="method-i-preprocess_mpi"></a>
|
528
655
|
|
529
656
|
|
530
657
|
<div class="method-heading">
|
531
|
-
<span class="method-name">
|
658
|
+
<span class="method-name">preprocess_mpi</span><span
|
532
659
|
class="method-args">(job_data)</span>
|
533
660
|
<span class="method-click-advice">click to toggle source</span>
|
534
661
|
</div>
|
@@ -536,38 +663,89 @@ end</pre>
|
|
536
663
|
|
537
664
|
<div class="method-description">
|
538
665
|
|
539
|
-
<p>This preprocessing method
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
specified to us to copy over an input file, we do that as well: AppScale
|
544
|
-
will copy it into HDFS for us.</p>
|
666
|
+
<p>This preprocessing method verifies that the user specified the number of
|
667
|
+
nodes to use. If they also specified the number of processes to use, we
|
668
|
+
also verify that this value is at least as many as the number of nodes
|
669
|
+
(that is, nodes can’t be underprovisioned in MPI).</p>
|
545
670
|
|
546
671
|
|
547
672
|
|
548
673
|
<div class="method-source-code"
|
549
|
-
id="
|
674
|
+
id="preprocess_mpi-source">
|
550
675
|
<pre>
|
551
|
-
<span class="ruby-comment"># File lib/neptune.rb, line
|
552
|
-
def
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
676
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 106</span>
|
677
|
+
def preprocess_mpi(job_data)
|
678
|
+
if !job_data[<span class="ruby-string">"@nodes_to_use"</span>]
|
679
|
+
abort(<span class="ruby-string">"When running MPI jobs, :nodes_to_use must be specified."</span>)
|
680
|
+
end
|
681
|
+
|
682
|
+
if !job_data[<span class="ruby-string">"@procs_to_use"</span>]
|
683
|
+
abort(<span class="ruby-string">"When running MPI jobs, :procs_to_use must be specified."</span>)
|
684
|
+
end
|
685
|
+
|
686
|
+
if job_data[<span class="ruby-string">"@procs_to_use"</span>]
|
687
|
+
p = job_data[<span class="ruby-string">"@procs_to_use"</span>]
|
688
|
+
n = job_data[<span class="ruby-string">"@nodes_to_use"</span>]
|
689
|
+
if p < n
|
690
|
+
abort(<span class="ruby-string">"When specifying both :procs_to_use and :nodes_to_use"</span> +
|
691
|
+
<span class="ruby-string">", :procs_to_use must be at least as large as :nodes_to_use. Please "</span> +
|
692
|
+
"change this and try again. You specified :procs_to_use = #{p} and" +
|
693
|
+
":nodes_to_use = #{n}.")
|
561
694
|
end
|
695
|
+
end
|
696
|
+
|
697
|
+
return job_data
|
698
|
+
end</pre>
|
699
|
+
</div>
|
700
|
+
|
701
|
+
</div>
|
702
|
+
|
703
|
+
|
562
704
|
|
563
|
-
|
564
|
-
|
705
|
+
|
706
|
+
</div>
|
565
707
|
|
566
|
-
|
567
|
-
|
708
|
+
|
709
|
+
<div id="preprocess_ssa-method" class="method-detail ">
|
710
|
+
<a name="method-i-preprocess_ssa"></a>
|
568
711
|
|
569
|
-
|
570
|
-
|
712
|
+
|
713
|
+
<div class="method-heading">
|
714
|
+
<span class="method-name">preprocess_ssa</span><span
|
715
|
+
class="method-args">(job_data)</span>
|
716
|
+
<span class="method-click-advice">click to toggle source</span>
|
717
|
+
</div>
|
718
|
+
|
719
|
+
|
720
|
+
<div class="method-description">
|
721
|
+
|
722
|
+
<p>This preprocessing method verifies that the user specified the number of
|
723
|
+
trajectories to run, via either :trajectories or :simulations. Both should
|
724
|
+
not be specified - only one or the other, and regardless of which they
|
725
|
+
specify, convert it to be :trajectories.</p>
|
726
|
+
|
727
|
+
|
728
|
+
|
729
|
+
<div class="method-source-code"
|
730
|
+
id="preprocess_ssa-source">
|
731
|
+
<pre>
|
732
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 133</span>
|
733
|
+
def preprocess_ssa(job_data)
|
734
|
+
if job_data[<span class="ruby-string">"@simulations"</span>] and job_data[<span class="ruby-string">"@trajectories"</span>]
|
735
|
+
abort(<span class="ruby-string">"Both :simulations and :trajectories cannot be specified - use one"</span> +
|
736
|
+
<span class="ruby-string">" or the other."</span>)
|
737
|
+
end
|
738
|
+
|
739
|
+
if job_data[<span class="ruby-string">"@simulations"</span>]
|
740
|
+
job_data[<span class="ruby-string">"@trajectories"</span>] = job_data[<span class="ruby-string">"@simulations"</span>]
|
741
|
+
job_data.delete(<span class="ruby-string">"@simulations"</span>)
|
742
|
+
end
|
743
|
+
|
744
|
+
if !job_data[<span class="ruby-string">"@trajectories"</span>]
|
745
|
+
abort(<span class="ruby-string">":trajectories needs to be specified when running ssa jobs"</span>)
|
746
|
+
end
|
747
|
+
|
748
|
+
return job_data
|
571
749
|
end</pre>
|
572
750
|
</div>
|
573
751
|
|
@@ -579,12 +757,73 @@ end</pre>
|
|
579
757
|
</div>
|
580
758
|
|
581
759
|
|
582
|
-
<div id="
|
583
|
-
<a name="method-i-
|
760
|
+
<div id="run_job-method" class="method-detail ">
|
761
|
+
<a name="method-i-run_job"></a>
|
584
762
|
|
585
763
|
|
586
764
|
<div class="method-heading">
|
587
|
-
<span class="method-name">
|
765
|
+
<span class="method-name">run_job</span><span
|
766
|
+
class="method-args">(job_data, ssh_args, shadow_ip, secret, controller=AppControllerClient, file=File)</span>
|
767
|
+
<span class="method-click-advice">click to toggle source</span>
|
768
|
+
</div>
|
769
|
+
|
770
|
+
|
771
|
+
<div class="method-description">
|
772
|
+
|
773
|
+
<p>This method actually runs the Neptune job, given information about the job
|
774
|
+
as well as information about the node to send the request to.</p>
|
775
|
+
|
776
|
+
|
777
|
+
|
778
|
+
<div class="method-source-code"
|
779
|
+
id="run_job-source">
|
780
|
+
<pre>
|
781
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 330</span>
|
782
|
+
def run_job(job_data, ssh_args, shadow_ip, secret,
|
783
|
+
controller=<span class="ruby-constant">AppControllerClient</span>, file=<span class="ruby-constant">File</span>)
|
784
|
+
controller = controller.new(shadow_ip, secret)
|
785
|
+
|
786
|
+
<span class="ruby-comment"># TODO - right now the job is assumed to succeed in many cases</span>
|
787
|
+
<span class="ruby-comment"># need to investigate the various failure scenarios</span>
|
788
|
+
result = { :result => :success }
|
789
|
+
|
790
|
+
case job_data[<span class="ruby-string">"@type"</span>]
|
791
|
+
when <span class="ruby-string">"input"</span>
|
792
|
+
result = get_input(job_data, ssh_args, shadow_ip, controller, file)
|
793
|
+
when <span class="ruby-string">"output"</span>
|
794
|
+
result[:output] = controller.get_output(job_data)
|
795
|
+
when <span class="ruby-string">"get-acl"</span>
|
796
|
+
job_data[<span class="ruby-string">"@type"</span>] = <span class="ruby-string">"acl"</span>
|
797
|
+
result[:acl] = controller.get_acl(job_data)
|
798
|
+
when <span class="ruby-string">"set-acl"</span>
|
799
|
+
job_data[<span class="ruby-string">"@type"</span>] = <span class="ruby-string">"acl"</span>
|
800
|
+
result[:acl] = controller.set_acl(job_data)
|
801
|
+
when <span class="ruby-string">"compile"</span>
|
802
|
+
result = compile_code(job_data, ssh_args, shadow_ip)
|
803
|
+
else
|
804
|
+
msg = controller.start_neptune_job(job_data)
|
805
|
+
result[:msg] = msg
|
806
|
+
result[:result] = :failure if result[:msg] !~ <span class="ruby-regexp">/job is now running\Z/</span>
|
807
|
+
end
|
808
|
+
|
809
|
+
return result
|
810
|
+
end</pre>
|
811
|
+
</div>
|
812
|
+
|
813
|
+
</div>
|
814
|
+
|
815
|
+
|
816
|
+
|
817
|
+
|
818
|
+
</div>
|
819
|
+
|
820
|
+
|
821
|
+
<div id="validate_storage_params-method" class="method-detail ">
|
822
|
+
<a name="method-i-validate_storage_params"></a>
|
823
|
+
|
824
|
+
|
825
|
+
<div class="method-heading">
|
826
|
+
<span class="method-name">validate_storage_params</span><span
|
588
827
|
class="method-args">(job_data)</span>
|
589
828
|
<span class="method-click-advice">click to toggle source</span>
|
590
829
|
</div>
|
@@ -592,48 +831,99 @@ end</pre>
|
|
592
831
|
|
593
832
|
<div class="method-description">
|
594
833
|
|
595
|
-
|
596
|
-
node in AppScale - this node will then copy it to whoever will run the MPI
|
597
|
-
job.</p>
|
834
|
+
|
598
835
|
|
599
836
|
|
600
837
|
|
601
838
|
<div class="method-source-code"
|
602
|
-
id="
|
839
|
+
id="validate_storage_params-source">
|
603
840
|
<pre>
|
604
|
-
<span class="ruby-comment"># File lib/neptune.rb, line
|
605
|
-
def
|
606
|
-
if job_data[<span class="ruby-string">"@
|
607
|
-
|
608
|
-
n = job_data[<span class="ruby-string">"@nodes_to_use"</span>]
|
609
|
-
if p < n
|
610
|
-
not_enough_procs = <span class="ruby-string">"When specifying both :procs_to_use and :nodes_to_use"</span> +
|
611
|
-
<span class="ruby-string">", :procs_to_use must be at least as large as :nodes_to_use. Please "</span> +
|
612
|
-
"change this and try again. You specified :procs_to_use = #{p} and" +
|
613
|
-
":nodes_to_use = #{n}."
|
614
|
-
abort(not_enough_procs)
|
615
|
-
end
|
841
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 186</span>
|
842
|
+
def validate_storage_params(job_data)
|
843
|
+
if !job_data[<span class="ruby-string">"@storage"</span>]
|
844
|
+
job_data[<span class="ruby-string">"@storage"</span>] = <span class="ruby-string">"appdb"</span>
|
616
845
|
end
|
617
846
|
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
abort(file_not_found)
|
847
|
+
storage = job_data[<span class="ruby-string">"@storage"</span>]
|
848
|
+
if !<span class="ruby-constant">ALLOWED_STORAGE_TYPES</span>.include?(storage)
|
849
|
+
abort("Supported storage types are #{ALLOWED_STORAGE_TYPES.join(', ')}" +
|
850
|
+
" - we do not support #{storage}.")
|
623
851
|
end
|
624
852
|
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
853
|
+
<span class="ruby-comment"># Our implementation for storing / retrieving via Google Storage</span>
|
854
|
+
<span class="ruby-comment"># and Walrus uses</span>
|
855
|
+
<span class="ruby-comment"># the same library as we do for S3 - so just tell it that it's S3</span>
|
856
|
+
if storage == <span class="ruby-string">"gstorage"</span> or storage == <span class="ruby-string">"walrus"</span>
|
857
|
+
storage = <span class="ruby-string">"s3"</span>
|
858
|
+
job_data[<span class="ruby-string">"@storage"</span>] = <span class="ruby-string">"s3"</span>
|
859
|
+
end
|
860
|
+
|
861
|
+
if storage == <span class="ruby-string">"s3"</span>
|
862
|
+
[<span class="ruby-string">"EC2_ACCESS_KEY"</span>, <span class="ruby-string">"EC2_SECRET_KEY"</span>, <span class="ruby-string">"S3_URL"</span>].each { |item|
|
863
|
+
if job_data["@#{item}"]
|
864
|
+
puts "Using specified #{item}"
|
865
|
+
else
|
866
|
+
if <span class="ruby-constant">ENV</span>[item]
|
867
|
+
puts "Using #{item} from environment"
|
868
|
+
job_data["@#{item}"] = <span class="ruby-constant">ENV</span>[item]
|
869
|
+
else
|
870
|
+
abort("When storing data to S3, #{item} must be specified or be in " +
|
871
|
+
<span class="ruby-string">"your environment. Please do so and try again."</span>)
|
872
|
+
end
|
873
|
+
end
|
874
|
+
}
|
629
875
|
end
|
630
876
|
|
631
|
-
|
877
|
+
return job_data
|
878
|
+
end</pre>
|
879
|
+
</div>
|
880
|
+
|
881
|
+
</div>
|
882
|
+
|
883
|
+
|
632
884
|
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
885
|
+
|
886
|
+
</div>
|
887
|
+
|
888
|
+
|
889
|
+
<div id="wait_for_compilation_to_finish-method" class="method-detail ">
|
890
|
+
<a name="method-i-wait_for_compilation_to_finish"></a>
|
891
|
+
|
892
|
+
|
893
|
+
<div class="method-heading">
|
894
|
+
<span class="method-name">wait_for_compilation_to_finish</span><span
|
895
|
+
class="method-args">(ssh_args, shadow_ip, compiled_location, shell=Kernel.method(:`))</span>
|
896
|
+
<span class="method-click-advice">click to toggle source</span>
|
897
|
+
</div>
|
898
|
+
|
899
|
+
|
900
|
+
<div class="method-description">
|
901
|
+
|
902
|
+
<p>This method waits for AppScale to finish compiling the user’s code,
|
903
|
+
indicated by AppScale copying the finished code to a pre-determined
|
904
|
+
location.</p>
|
905
|
+
|
906
|
+
|
907
|
+
|
908
|
+
<div class="method-source-code"
|
909
|
+
id="wait_for_compilation_to_finish-source">
|
910
|
+
<pre>
|
911
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 260</span>
|
912
|
+
def wait_for_compilation_to_finish(ssh_args, shadow_ip, compiled_location,
|
913
|
+
shell=<span class="ruby-constant">Kernel</span>.method(:`))
|
914
|
+
loop {
|
915
|
+
ssh_command = "ssh #{ssh_args} root@#{shadow_ip} 'ls #{compiled_location}' 2>&1"
|
916
|
+
puts ssh_command
|
917
|
+
ssh_result = shell.call(ssh_command)
|
918
|
+
puts "result was [#{ssh_result}]"
|
919
|
+
if ssh_result =~ <span class="ruby-regexp">/No such file or directory/</span>
|
920
|
+
puts <span class="ruby-string">"Still waiting for code to be compiled..."</span>
|
921
|
+
else
|
922
|
+
puts "compilation complete! Copying compiled code to #{copy_to}"
|
923
|
+
return
|
924
|
+
end
|
925
|
+
sleep(5)
|
926
|
+
}
|
637
927
|
end</pre>
|
638
928
|
</div>
|
639
929
|
|