neptune 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README +19 -3
- data/doc/AppControllerClient.html +53 -7
- data/doc/CommonFunctions.html +16 -12
- data/doc/Object.html +200 -39
- data/doc/README.html +55 -17
- data/doc/bin/neptune.html +2 -6
- data/doc/created.rid +6 -6
- data/doc/index.html +6 -2
- data/doc/lib/app_controller_client_rb.html +1 -1
- data/doc/lib/common_functions_rb.html +1 -1
- data/doc/lib/neptune_rb.html +56 -0
- data/lib/common_functions.rb +0 -1
- data/lib/neptune.rb +17 -18
- data/test/tc_c.rb +57 -0
- data/test/tc_dfsp.rb +37 -0
- data/test/tc_dwssa.rb +38 -0
- data/test/tc_erlang.rb +157 -0
- data/test/tc_mapreduce.rb +207 -0
- data/test/tc_mpi.rb +124 -0
- data/test/tc_storage.rb +45 -0
- data/test/tc_upc.rb +75 -0
- data/test/tc_x10.rb +94 -0
- data/test/test_helper.rb +137 -0
- data/test/ts_neptune.rb +41 -0
- metadata +16 -4
data/README
CHANGED
@@ -32,8 +32,13 @@ By default, Neptune jobs store their outputs in the underlying database
|
|
32
32
|
that AppScale is running over. As of Neptune 0.0.5, job outputs can
|
33
33
|
also be stored in Amazon S3, Eucalyptus Walrus, and Google Storage.
|
34
34
|
|
35
|
-
Sample Neptune job scripts can be found in samples. Test
|
36
|
-
be
|
35
|
+
Sample Neptune job scripts can be found in samples. Test cases can
|
36
|
+
be found in the test folder, with the standard naming convention
|
37
|
+
- ts_neptune is the test suite runner, with tc_* containing test
|
38
|
+
cases for each type of job that Neptune offers. Before running
|
39
|
+
ts_neptune, you should export the environment variable APPSCALE_HEAD_NODE,
|
40
|
+
which should be set to the IP address of the AppScale machine that runs
|
41
|
+
the Shadow daemon (a.k.a. the Master AppController).
|
37
42
|
|
38
43
|
Developed by Chris Bunch as part of the AppScale project.
|
39
44
|
See LICENSE for the specifics of the New BSD License
|
@@ -41,8 +46,9 @@ by which Neptune is released.
|
|
41
46
|
|
42
47
|
Check us out on the web:
|
43
48
|
|
44
|
-
http://
|
49
|
+
http://neptune-lang.org
|
45
50
|
|
51
|
+
http://code.google.com/p/appscale
|
46
52
|
http://appscale.cs.ucsb.edu
|
47
53
|
|
48
54
|
Contributors welcome! We would love to add support for other
|
@@ -57,6 +63,16 @@ in for a link to that as it becomes available.
|
|
57
63
|
|
58
64
|
Version History:
|
59
65
|
|
66
|
+
April 2, 2001 - 0.0.7 released, adding automatic test suite
|
67
|
+
and many bug fixes for all scenarios. rcov can also be used
|
68
|
+
to generate test coverage information: current coverage stats
|
69
|
+
can be found in coverage directory. mapreduce broken at the
|
70
|
+
moment - will fix in next release
|
71
|
+
|
72
|
+
March 28, 2011 - 0.0.6 released, adding support for input jobs,
|
73
|
+
so users can place data in the datastore without having to run
|
74
|
+
any computation
|
75
|
+
|
60
76
|
March 18, 2011 - 0.0.5 released, adding support for storage outside
|
61
77
|
of AppScale to be used. Tested and working with Amazon S3 and Google
|
62
78
|
Storage
|
@@ -79,6 +79,8 @@
|
|
79
79
|
|
80
80
|
<li><a href="#method-i-make_call">#make_call</a></li>
|
81
81
|
|
82
|
+
<li><a href="#method-i-put_input">#put_input</a></li>
|
83
|
+
|
82
84
|
<li><a href="#method-i-set_acl">#set_acl</a></li>
|
83
85
|
|
84
86
|
<li><a href="#method-i-start_neptune_job">#start_neptune_job</a></li>
|
@@ -241,6 +243,7 @@ def initialize(ip, secret)
|
|
241
243
|
|
242
244
|
<span class="ruby-ivar">@conn</span> = <span class="ruby-constant">SOAP</span>::<span class="ruby-constant">RPC</span>::<span class="ruby-constant">Driver</span>.new("https://#{@ip}:17443")
|
243
245
|
<span class="ruby-ivar">@conn</span>.add_method(<span class="ruby-string">"neptune_start_job"</span>, <span class="ruby-string">"job_data"</span>, <span class="ruby-string">"secret"</span>)
|
246
|
+
<span class="ruby-ivar">@conn</span>.add_method(<span class="ruby-string">"neptune_put_input"</span>, <span class="ruby-string">"job_data"</span>, <span class="ruby-string">"secret"</span>)
|
244
247
|
<span class="ruby-ivar">@conn</span>.add_method(<span class="ruby-string">"neptune_get_output"</span>, <span class="ruby-string">"job_data"</span>, <span class="ruby-string">"secret"</span>)
|
245
248
|
<span class="ruby-ivar">@conn</span>.add_method(<span class="ruby-string">"neptune_get_acl"</span>, <span class="ruby-string">"job_data"</span>, <span class="ruby-string">"secret"</span>)
|
246
249
|
<span class="ruby-ivar">@conn</span>.add_method(<span class="ruby-string">"neptune_set_acl"</span>, <span class="ruby-string">"job_data"</span>, <span class="ruby-string">"secret"</span>)
|
@@ -282,7 +285,7 @@ end</pre>
|
|
282
285
|
<div class="method-source-code"
|
283
286
|
id="compile_code-source">
|
284
287
|
<pre>
|
285
|
-
<span class="ruby-comment"># File lib/app_controller_client.rb, line
|
288
|
+
<span class="ruby-comment"># File lib/app_controller_client.rb, line 152</span>
|
286
289
|
def compile_code(job_data)
|
287
290
|
result = <span class="ruby-string">""</span>
|
288
291
|
make_call(<span class="ruby-constant">NO_TIMEOUT</span>, false) {
|
@@ -324,7 +327,7 @@ exceptions mirror that of start_neptune_job.</p>
|
|
324
327
|
<div class="method-source-code"
|
325
328
|
id="get_acl-source">
|
326
329
|
<pre>
|
327
|
-
<span class="ruby-comment"># File lib/app_controller_client.rb, line
|
330
|
+
<span class="ruby-comment"># File lib/app_controller_client.rb, line 129</span>
|
328
331
|
def get_acl(job_data)
|
329
332
|
result = <span class="ruby-string">""</span>
|
330
333
|
make_call(<span class="ruby-constant">NO_TIMEOUT</span>, false) {
|
@@ -361,7 +364,7 @@ Within AppScale, a special application runs, referred to as the Repository,
|
|
361
364
|
which provides a key-value interface to Neptune job data. Data is stored as
|
362
365
|
though it were on a file system, therefore output be of the usual form
|
363
366
|
/folder/filename . Currently the contents of the file is returned as a
|
364
|
-
string to the caller, but as this
|
367
|
+
string to the caller, but as this may be inefficient for non-trivial output
|
365
368
|
jobs, the next version of Neptune will add an additional call to directly
|
366
369
|
copy the output to a file on the local filesystem. See <a
|
367
370
|
href="AppControllerClient.html#method-i-start_neptune_job">start_neptune_job</a>
|
@@ -373,7 +376,7 @@ used for job_data.</p>
|
|
373
376
|
<div class="method-source-code"
|
374
377
|
id="get_output-source">
|
375
378
|
<pre>
|
376
|
-
<span class="ruby-comment"># File lib/app_controller_client.rb, line
|
379
|
+
<span class="ruby-comment"># File lib/app_controller_client.rb, line 115</span>
|
377
380
|
def get_output(job_data)
|
378
381
|
result = <span class="ruby-string">""</span>
|
379
382
|
make_call(<span class="ruby-constant">NO_TIMEOUT</span>, false) {
|
@@ -423,7 +426,7 @@ The result of the block is returned to the caller.</p>
|
|
423
426
|
<div class="method-source-code"
|
424
427
|
id="make_call-source">
|
425
428
|
<pre>
|
426
|
-
<span class="ruby-comment"># File lib/app_controller_client.rb, line
|
429
|
+
<span class="ruby-comment"># File lib/app_controller_client.rb, line 52</span>
|
427
430
|
def make_call(time, retry_on_except)
|
428
431
|
begin
|
429
432
|
<span class="ruby-constant">Timeout</span>::timeout(time) {
|
@@ -452,6 +455,49 @@ end</pre>
|
|
452
455
|
|
453
456
|
|
454
457
|
|
458
|
+
</div>
|
459
|
+
|
460
|
+
|
461
|
+
<div id="put_input-method" class="method-detail ">
|
462
|
+
<a name="method-i-put_input"></a>
|
463
|
+
|
464
|
+
|
465
|
+
<div class="method-heading">
|
466
|
+
<span class="method-name">put_input</span><span
|
467
|
+
class="method-args">(job_data)</span>
|
468
|
+
<span class="method-click-advice">click to toggle source</span>
|
469
|
+
</div>
|
470
|
+
|
471
|
+
|
472
|
+
<div class="method-description">
|
473
|
+
|
474
|
+
<p>Stores a file stored on the user’s local file system in the underlying
|
475
|
+
database. The user can specify to use either the underlying database that
|
476
|
+
AppScale is using, or alternative storage mechanisms (as of writing, Google
|
477
|
+
Storage, Amazon S3, and Eucalyptus Walrus are supported) via the storage
|
478
|
+
parameter.</p>
|
479
|
+
|
480
|
+
|
481
|
+
|
482
|
+
<div class="method-source-code"
|
483
|
+
id="put_input-source">
|
484
|
+
<pre>
|
485
|
+
<span class="ruby-comment"># File lib/app_controller_client.rb, line 96</span>
|
486
|
+
def put_input(job_data)
|
487
|
+
result = <span class="ruby-string">""</span>
|
488
|
+
make_call(<span class="ruby-constant">NO_TIMEOUT</span>, false) {
|
489
|
+
result = conn.neptune_put_input(job_data, <span class="ruby-ivar">@secret</span>)
|
490
|
+
}
|
491
|
+
abort(result) if result =~ <span class="ruby-regexp">/Error:/</span>
|
492
|
+
return result
|
493
|
+
end</pre>
|
494
|
+
</div>
|
495
|
+
|
496
|
+
</div>
|
497
|
+
|
498
|
+
|
499
|
+
|
500
|
+
|
455
501
|
</div>
|
456
502
|
|
457
503
|
|
@@ -480,7 +526,7 @@ that of start_neptune_job.</p>
|
|
480
526
|
<div class="method-source-code"
|
481
527
|
id="set_acl-source">
|
482
528
|
<pre>
|
483
|
-
<span class="ruby-comment"># File lib/app_controller_client.rb, line
|
529
|
+
<span class="ruby-comment"># File lib/app_controller_client.rb, line 143</span>
|
484
530
|
def set_acl(job_data)
|
485
531
|
result = <span class="ruby-string">""</span>
|
486
532
|
make_call(<span class="ruby-constant">NO_TIMEOUT</span>, false) {
|
@@ -526,7 +572,7 @@ is the result returned from the AppController.</p>
|
|
526
572
|
<div class="method-source-code"
|
527
573
|
id="start_neptune_job-source">
|
528
574
|
<pre>
|
529
|
-
<span class="ruby-comment"># File lib/app_controller_client.rb, line
|
575
|
+
<span class="ruby-comment"># File lib/app_controller_client.rb, line 82</span>
|
530
576
|
def start_neptune_job(job_data)
|
531
577
|
result = <span class="ruby-string">""</span>
|
532
578
|
make_call(<span class="ruby-constant">NO_TIMEOUT</span>, false) {
|
data/doc/CommonFunctions.html
CHANGED
@@ -172,7 +172,7 @@ instead.</p>
|
|
172
172
|
<div class="method-source-code"
|
173
173
|
id="get_from_yaml-source">
|
174
174
|
<pre>
|
175
|
-
<span class="ruby-comment"># File lib/common_functions.rb, line
|
175
|
+
<span class="ruby-comment"># File lib/common_functions.rb, line 82</span>
|
176
176
|
def self.get_from_yaml(keyname, tag, required=true)
|
177
177
|
location_file = <span class="ruby-constant">File</span>.expand_path("~/.appscale/locations-#{keyname}.yaml")
|
178
178
|
|
@@ -227,7 +227,7 @@ function, as the secret is stored in a YAML file.</p>
|
|
227
227
|
<div class="method-source-code"
|
228
228
|
id="get_secret_key-source">
|
229
229
|
<pre>
|
230
|
-
<span class="ruby-comment"># File lib/common_functions.rb, line
|
230
|
+
<span class="ruby-comment"># File lib/common_functions.rb, line 107</span>
|
231
231
|
def self.get_secret_key(keyname, required=true)
|
232
232
|
return <span class="ruby-constant">CommonFunctions</span>.get_from_yaml(keyname, :secret)
|
233
233
|
end</pre>
|
@@ -247,7 +247,7 @@ end</pre>
|
|
247
247
|
|
248
248
|
<div class="method-heading">
|
249
249
|
<span class="method-name">scp_file</span><span
|
250
|
-
class="method-args">(local_file_loc, remote_file_loc, target_ip, public_key_loc)</span>
|
250
|
+
class="method-args">(local_file_loc, remote_file_loc, target_ip, public_key_loc, is_dir=false)</span>
|
251
251
|
<span class="method-click-advice">click to toggle source</span>
|
252
252
|
</div>
|
253
253
|
|
@@ -259,7 +259,8 @@ information from <a
|
|
259
259
|
href="CommonFunctions.html#method-c-scp_to_shadow">scp_to_shadow</a>,
|
260
260
|
attempts to use scp to copy the file over. Aborts if the scp fails, which
|
261
261
|
can occur if the network is down, if a bad keyname is provided, or if the
|
262
|
-
wrong IP is given
|
262
|
+
wrong IP is given. If the user specifies that the file to copy is actually
|
263
|
+
a directory, we append the -r flag to scp as well.</p>
|
263
264
|
|
264
265
|
|
265
266
|
|
@@ -267,19 +268,22 @@ wrong IP is given.</p>
|
|
267
268
|
id="scp_file-source">
|
268
269
|
<pre>
|
269
270
|
<span class="ruby-comment"># File lib/common_functions.rb, line 37</span>
|
270
|
-
def self.scp_file(local_file_loc, remote_file_loc, target_ip, public_key_loc)
|
271
|
+
def self.scp_file(local_file_loc, remote_file_loc, target_ip, public_key_loc, is_dir=false)
|
271
272
|
cmd = <span class="ruby-string">""</span>
|
272
273
|
local_file_loc = <span class="ruby-constant">File</span>.expand_path(local_file_loc)
|
273
|
-
|
274
|
+
|
275
|
+
ssh_args = <span class="ruby-string">"-o StrictHostkeyChecking=no 2>&1"</span>
|
276
|
+
ssh_args << <span class="ruby-string">" -r "</span> if is_dir
|
277
|
+
|
274
278
|
if public_key_loc.class == <span class="ruby-constant">Array</span>
|
275
279
|
public_key_loc.each { |key|
|
276
280
|
key = <span class="ruby-constant">File</span>.expand_path(key)
|
277
281
|
}
|
278
282
|
|
279
|
-
cmd = "scp -i #{public_key_loc.join(' -i ')}
|
283
|
+
cmd = "scp -i #{public_key_loc.join(' -i ')} #{ssh_args} #{local_file_loc} root@#{target_ip}:#{remote_file_loc}"
|
280
284
|
else
|
281
285
|
public_key_loc = <span class="ruby-constant">File</span>.expand_path(public_key_loc)
|
282
|
-
cmd = "scp -i #{public_key_loc}
|
286
|
+
cmd = "scp -i #{public_key_loc} #{ssh_args} #{local_file_loc} root@#{target_ip}:#{remote_file_loc}"
|
283
287
|
end
|
284
288
|
|
285
289
|
cmd << <span class="ruby-string">"; echo $? >> ~/.appscale/retval"</span>
|
@@ -318,7 +322,7 @@ end</pre>
|
|
318
322
|
|
319
323
|
<div class="method-heading">
|
320
324
|
<span class="method-name">scp_to_shadow</span><span
|
321
|
-
class="method-args">(local_file_loc, remote_file_loc, keyname)</span>
|
325
|
+
class="method-args">(local_file_loc, remote_file_loc, keyname, is_dir=false)</span>
|
322
326
|
<span class="method-click-advice">click to toggle source</span>
|
323
327
|
</div>
|
324
328
|
|
@@ -335,12 +339,12 @@ by the Neptune job given, but defaults to ”appscale” if not provided.</p>
|
|
335
339
|
<div class="method-source-code"
|
336
340
|
id="scp_to_shadow-source">
|
337
341
|
<pre>
|
338
|
-
<span class="ruby-comment"># File lib/common_functions.rb, line
|
339
|
-
def self.scp_to_shadow(local_file_loc, remote_file_loc, keyname)
|
342
|
+
<span class="ruby-comment"># File lib/common_functions.rb, line 24</span>
|
343
|
+
def self.scp_to_shadow(local_file_loc, remote_file_loc, keyname, is_dir=false)
|
340
344
|
shadow_ip = <span class="ruby-constant">CommonFunctions</span>.get_from_yaml(keyname, :shadow)
|
341
345
|
ssh_key = <span class="ruby-constant">File</span>.expand_path("~/.appscale/#{keyname}.key")
|
342
346
|
|
343
|
-
self.scp_file(local_file_loc, remote_file_loc, shadow_ip, ssh_key)
|
347
|
+
self.scp_file(local_file_loc, remote_file_loc, shadow_ip, ssh_key, is_dir)
|
344
348
|
end</pre>
|
345
349
|
</div>
|
346
350
|
|
data/doc/Object.html
CHANGED
@@ -41,8 +41,8 @@
|
|
41
41
|
<li><a href="./lib/app_controller_client_rb.html?TB_iframe=true&height=550&width=785"
|
42
42
|
class="thickbox" title="lib/app_controller_client.rb">lib/app_controller_client.rb</a></li>
|
43
43
|
|
44
|
-
<li><a href="./lib/
|
45
|
-
class="thickbox" title="lib/
|
44
|
+
<li><a href="./lib/neptune_rb.html?TB_iframe=true&height=550&width=785"
|
45
|
+
class="thickbox" title="lib/neptune.rb">lib/neptune.rb</a></li>
|
46
46
|
|
47
47
|
</ul>
|
48
48
|
</div>
|
@@ -74,10 +74,12 @@
|
|
74
74
|
|
75
75
|
<li><a href="#method-i-do_preprocessing">#do_preprocessing</a></li>
|
76
76
|
|
77
|
-
<li><a href="#method-i-
|
77
|
+
<li><a href="#method-i-neptune">#neptune</a></li>
|
78
78
|
|
79
79
|
<li><a href="#method-i-preprocess_compile">#preprocess_compile</a></li>
|
80
80
|
|
81
|
+
<li><a href="#method-i-preprocess_erlang">#preprocess_erlang</a></li>
|
82
|
+
|
81
83
|
<li><a href="#method-i-preprocess_mapreduce">#preprocess_mapreduce</a></li>
|
82
84
|
|
83
85
|
<li><a href="#method-i-preprocess_mpi">#preprocess_mpi</a></li>
|
@@ -162,6 +164,24 @@ timeout. The next version should replace this and properly timeout and not
|
|
162
164
|
use long calls unless necessary.</p></dd>
|
163
165
|
|
164
166
|
|
167
|
+
<dt><a name="NO_NODES_NEEDED">NO_NODES_NEEDED</a></dt>
|
168
|
+
|
169
|
+
<dd class="description"><p>A list of Neptune jobs that do not require nodes to be spawned up for
|
170
|
+
computation</p></dd>
|
171
|
+
|
172
|
+
|
173
|
+
<dt><a name="NO_OUTPUT_NEEDED">NO_OUTPUT_NEEDED</a></dt>
|
174
|
+
|
175
|
+
<dd class="description"><p>A list of Neptune jobs that do not require the output to be specified
|
176
|
+
beforehand</p></dd>
|
177
|
+
|
178
|
+
|
179
|
+
<dt><a name="ALLOWED_STORAGE_TYPES">ALLOWED_STORAGE_TYPES</a></dt>
|
180
|
+
|
181
|
+
<dd class="description"><p>A list of storage mechanisms that we can use to store and retrieve data to
|
182
|
+
for Neptune jobs.</p></dd>
|
183
|
+
|
184
|
+
|
165
185
|
<dt><a name="NEED_PREPROCESSING">NEED_PREPROCESSING</a></dt>
|
166
186
|
|
167
187
|
<dd class="description"><p>A list of jobs that require some kind of work to be done before the actual
|
@@ -203,7 +223,7 @@ method to use based on the type of the job that the user has asked to run.</p>
|
|
203
223
|
<div class="method-source-code"
|
204
224
|
id="do_preprocessing-source">
|
205
225
|
<pre>
|
206
|
-
<span class="ruby-comment"># File lib/
|
226
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 49</span>
|
207
227
|
def do_preprocessing(job_data)
|
208
228
|
job_type = job_data[<span class="ruby-string">"@type"</span>]
|
209
229
|
return unless <span class="ruby-constant">NEED_PREPROCESSING</span>.include?(job_type)
|
@@ -221,13 +241,13 @@ end</pre>
|
|
221
241
|
</div>
|
222
242
|
|
223
243
|
|
224
|
-
<div id="
|
225
|
-
<a name="method-i-
|
244
|
+
<div id="neptune-method" class="method-detail ">
|
245
|
+
<a name="method-i-neptune"></a>
|
226
246
|
|
227
247
|
|
228
248
|
<div class="method-heading">
|
229
|
-
<span class="method-name">
|
230
|
-
class="method-args">(
|
249
|
+
<span class="method-name">neptune</span><span
|
250
|
+
class="method-args">(params)</span>
|
231
251
|
<span class="method-click-advice">click to toggle source</span>
|
232
252
|
</div>
|
233
253
|
|
@@ -244,15 +264,14 @@ vice-versa).</p>
|
|
244
264
|
|
245
265
|
|
246
266
|
<div class="method-source-code"
|
247
|
-
id="
|
267
|
+
id="neptune-source">
|
248
268
|
<pre>
|
249
|
-
<span class="ruby-comment"># File lib/
|
250
|
-
def
|
269
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 175</span>
|
270
|
+
def neptune(params)
|
251
271
|
puts <span class="ruby-string">"Received a request to run a job."</span>
|
252
|
-
puts
|
253
|
-
block.call()
|
272
|
+
puts params[:type]
|
254
273
|
|
255
|
-
keyname =
|
274
|
+
keyname = params[:keyname] || <span class="ruby-string">"appscale"</span>
|
256
275
|
|
257
276
|
shadow_ip = <span class="ruby-constant">CommonFunctions</span>.get_from_yaml(keyname, :shadow)
|
258
277
|
secret = <span class="ruby-constant">CommonFunctions</span>.get_secret_key(keyname)
|
@@ -260,20 +279,65 @@ def job(name, &block)
|
|
260
279
|
ssh_key = <span class="ruby-constant">File</span>.expand_path("~/.appscale/#{keyname}.key")
|
261
280
|
|
262
281
|
job_data = {}
|
263
|
-
|
264
|
-
|
282
|
+
params.each { |k, v|
|
283
|
+
key = "@#{k}"
|
284
|
+
job_data[key] = v
|
265
285
|
}
|
266
286
|
|
267
287
|
job_data[<span class="ruby-string">"@job"</span>] = nil
|
268
|
-
job_data[<span class="ruby-string">"@
|
269
|
-
job_data[<span class="ruby-string">"@
|
288
|
+
job_data[<span class="ruby-string">"@keyname"</span>] = keyname || <span class="ruby-string">"appscale"</span>
|
289
|
+
type = job_data[<span class="ruby-string">"@type"</span>]
|
290
|
+
|
291
|
+
if type == <span class="ruby-string">"upc"</span> or type == <span class="ruby-string">"x10"</span>
|
292
|
+
job_data[<span class="ruby-string">"@type"</span>] = <span class="ruby-string">"mpi"</span>
|
293
|
+
type = <span class="ruby-string">"mpi"</span>
|
294
|
+
end
|
270
295
|
|
271
|
-
if
|
272
|
-
|
296
|
+
if job_data[<span class="ruby-string">"@nodes_to_use"</span>].class == <span class="ruby-constant">Hash</span>
|
297
|
+
job_data[<span class="ruby-string">"@nodes_to_use"</span>] = job_data[<span class="ruby-string">"@nodes_to_use"</span>].to_a.flatten
|
273
298
|
end
|
274
299
|
|
275
|
-
if
|
276
|
-
|
300
|
+
if !<span class="ruby-constant">NO_OUTPUT_NEEDED</span>.include?(type)
|
301
|
+
if (job_data[<span class="ruby-string">"@output"</span>].nil? or job_data[<span class="ruby-string">"@output"</span>] == <span class="ruby-string">""</span>)
|
302
|
+
abort(<span class="ruby-string">"Job output must be specified"</span>)
|
303
|
+
end
|
304
|
+
|
305
|
+
if job_data[<span class="ruby-string">"@output"</span>][0].chr != <span class="ruby-string">"/"</span>
|
306
|
+
abort(<span class="ruby-string">"Job output must begin with a slash ('/')"</span>)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
if job_data[<span class="ruby-string">"@storage"</span>]
|
311
|
+
storage = job_data[<span class="ruby-string">"@storage"</span>]
|
312
|
+
unless <span class="ruby-constant">ALLOWED_STORAGE_TYPES</span>.include?(storage)
|
313
|
+
msg = "Supported storage types are #{ALLOWED_STORAGE_TYPES.join(', ')}" +
|
314
|
+
" - we do not support #{storage}."
|
315
|
+
abort(msg)
|
316
|
+
end
|
317
|
+
|
318
|
+
<span class="ruby-comment"># Our implementation for storing / retrieving via Google Storage uses</span>
|
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
|
324
|
+
|
325
|
+
if storage == <span class="ruby-string">"s3"</span>
|
326
|
+
[<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|
|
327
|
+
unless job_data["@#{item}"]
|
328
|
+
if <span class="ruby-constant">ENV</span>[item]
|
329
|
+
puts "Using #{item} from environment"
|
330
|
+
job_data["@#{item}"] = <span class="ruby-constant">ENV</span>[item]
|
331
|
+
else
|
332
|
+
msg = "When storing data to S3, #{item} must be specified or be in " +
|
333
|
+
<span class="ruby-string">"your environment. Please do so and try again."</span>
|
334
|
+
abort(msg)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
}
|
338
|
+
end
|
339
|
+
else
|
340
|
+
job_data[<span class="ruby-string">"@storage"</span>] = <span class="ruby-string">"appdb"</span>
|
277
341
|
end
|
278
342
|
|
279
343
|
<span class="ruby-comment">#if job_data["@can_run_on"].class == Range</span>
|
@@ -286,8 +350,27 @@ def job(name, &block)
|
|
286
350
|
|
287
351
|
do_preprocessing(job_data)
|
288
352
|
|
289
|
-
|
290
|
-
|
353
|
+
ssh_args = "-i ~/.appscale/#{keyname}.key -o StrictHostkeyChecking=no "
|
354
|
+
|
355
|
+
if type == <span class="ruby-string">"input"</span>
|
356
|
+
<span class="ruby-comment"># copy file to remote</span>
|
357
|
+
<span class="ruby-comment"># set location</span>
|
358
|
+
local_file = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">"@local"</span>])
|
359
|
+
if !<span class="ruby-constant">File</span>.exists?(local_file)
|
360
|
+
msg = "the file you specified to copy, #{local_file}, doesn't exist." +
|
361
|
+
<span class="ruby-string">" Please specify a file that exists and try again."</span>
|
362
|
+
abort(msg)
|
363
|
+
end
|
364
|
+
|
365
|
+
remote = "/tmp/neptune-input-#{rand(100000)}"
|
366
|
+
scp_cmd = "scp #{ssh_args} #{local_file} root@#{shadow_ip}:#{remote}"
|
367
|
+
puts scp_cmd
|
368
|
+
`#{scp_cmd}`
|
369
|
+
|
370
|
+
job_data[<span class="ruby-string">"@local"</span>] = remote
|
371
|
+
puts "job data = #{job_data.inspect}"
|
372
|
+
return controller.put_input(job_data)
|
373
|
+
elsif type == <span class="ruby-string">"output"</span>
|
291
374
|
return controller.get_output(job_data)
|
292
375
|
elsif type == <span class="ruby-string">"get-acl"</span>
|
293
376
|
job_data[<span class="ruby-string">"@type"</span>] = <span class="ruby-string">"acl"</span>
|
@@ -298,14 +381,13 @@ def job(name, &block)
|
|
298
381
|
elsif type == <span class="ruby-string">"compile"</span>
|
299
382
|
compiled_location = controller.compile_code(job_data)
|
300
383
|
|
301
|
-
ssh_args = "-i ~/.appscale/#{keyname}.key -o StrictHostkeyChecking=no 2>&1 root@#{shadow_ip}"
|
302
384
|
copy_to = job_data[<span class="ruby-string">"@copy_to"</span>]
|
303
385
|
|
304
386
|
loop {
|
305
|
-
ssh_command = "ssh #{ssh_args} 'ls #{compiled_location}'"
|
306
|
-
puts ssh_command
|
387
|
+
ssh_command = "ssh #{ssh_args} root@#{shadow_ip} 'ls #{compiled_location}' 2>&1"
|
388
|
+
<span class="ruby-comment">#puts ssh_command</span>
|
307
389
|
result = `#{ssh_command}`
|
308
|
-
puts "result was [#{result}]"
|
390
|
+
<span class="ruby-comment">#puts "result was [#{result}]"</span>
|
309
391
|
if result =~ <span class="ruby-regexp">/No such file or directory/</span>
|
310
392
|
puts <span class="ruby-string">"Still waiting for code to be compiled..."</span>
|
311
393
|
else
|
@@ -315,15 +397,23 @@ def job(name, &block)
|
|
315
397
|
sleep(5)
|
316
398
|
}
|
317
399
|
|
318
|
-
|
400
|
+
rm_local = "rm -rf #{copy_to}"
|
401
|
+
<span class="ruby-comment">#puts rm_local</span>
|
402
|
+
`#{rm_local}`
|
403
|
+
|
404
|
+
scp_command = "scp -r #{ssh_args} root@#{shadow_ip}:#{compiled_location} #{copy_to} 2>&1"
|
319
405
|
puts scp_command
|
320
406
|
`#{scp_command}`
|
407
|
+
|
408
|
+
out = <span class="ruby-constant">File</span>.open("#{copy_to}/compile_out") { |f| f.read.chomp! }
|
409
|
+
err = <span class="ruby-constant">File</span>.open("#{copy_to}/compile_err") { |f| f.read.chomp! }
|
410
|
+
return {:out => out, :err => err }
|
321
411
|
else
|
322
412
|
result = controller.start_neptune_job(job_data)
|
323
413
|
if result =~ <span class="ruby-regexp">/job is now running\Z/</span>
|
324
|
-
return :success
|
414
|
+
return {:result => :success, :msg => result}
|
325
415
|
else
|
326
|
-
return :failure
|
416
|
+
return {:result => :failure, :msg => result}
|
327
417
|
end
|
328
418
|
end
|
329
419
|
end</pre>
|
@@ -359,7 +449,7 @@ copy over libraries as well.</p>
|
|
359
449
|
<div class="method-source-code"
|
360
450
|
id="preprocess_compile-source">
|
361
451
|
<pre>
|
362
|
-
<span class="ruby-comment"># File lib/
|
452
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 60</span>
|
363
453
|
def preprocess_compile(job_data)
|
364
454
|
code = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">"@code"</span>])
|
365
455
|
unless <span class="ruby-constant">File</span>.exists?(code)
|
@@ -368,9 +458,15 @@ def preprocess_compile(job_data)
|
|
368
458
|
|
369
459
|
suffix = code.split(<span class="ruby-string">'/'</span>)[-1]
|
370
460
|
dest = "/tmp/#{suffix}"
|
371
|
-
|
372
461
|
keyname = job_data[<span class="ruby-string">"@keyname"</span>]
|
373
|
-
<span class="ruby-constant">CommonFunctions</span>.
|
462
|
+
shadow_ip = <span class="ruby-constant">CommonFunctions</span>.get_from_yaml(keyname, :shadow)
|
463
|
+
|
464
|
+
ssh_args = "-i ~/.appscale/#{keyname}.key -o StrictHostkeyChecking=no root@#{shadow_ip}"
|
465
|
+
remove_dir = "ssh #{ssh_args} 'rm -rf #{dest}' 2>&1"
|
466
|
+
<span class="ruby-comment">#puts remove_dir</span>
|
467
|
+
`#{remove_dir}`
|
468
|
+
|
469
|
+
<span class="ruby-constant">CommonFunctions</span>.scp_to_shadow(code, dest, keyname, is_dir=true)
|
374
470
|
|
375
471
|
job_data[<span class="ruby-string">"@code"</span>] = dest
|
376
472
|
end</pre>
|
@@ -381,6 +477,49 @@ end</pre>
|
|
381
477
|
|
382
478
|
|
383
479
|
|
480
|
+
</div>
|
481
|
+
|
482
|
+
|
483
|
+
<div id="preprocess_erlang-method" class="method-detail ">
|
484
|
+
<a name="method-i-preprocess_erlang"></a>
|
485
|
+
|
486
|
+
|
487
|
+
<div class="method-heading">
|
488
|
+
<span class="method-name">preprocess_erlang</span><span
|
489
|
+
class="method-args">(job_data)</span>
|
490
|
+
<span class="method-click-advice">click to toggle source</span>
|
491
|
+
</div>
|
492
|
+
|
493
|
+
|
494
|
+
<div class="method-description">
|
495
|
+
|
496
|
+
|
497
|
+
|
498
|
+
|
499
|
+
|
500
|
+
<div class="method-source-code"
|
501
|
+
id="preprocess_erlang-source">
|
502
|
+
<pre>
|
503
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 81</span>
|
504
|
+
def preprocess_erlang(job_data)
|
505
|
+
source_code = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">"@code"</span>])
|
506
|
+
unless <span class="ruby-constant">File</span>.exists?(source_code)
|
507
|
+
file_not_found = "The specified code, #{job_data['@code']}," +
|
508
|
+
<span class="ruby-string">" didn't exist. Please specify one that exists and try again"</span>
|
509
|
+
abort(file_not_found)
|
510
|
+
end
|
511
|
+
dest_code = <span class="ruby-string">"/tmp/"</span>
|
512
|
+
|
513
|
+
keyname = job_data[<span class="ruby-string">"@keyname"</span>]
|
514
|
+
<span class="ruby-constant">CommonFunctions</span>.scp_to_shadow(source_code, dest_code, keyname)
|
515
|
+
end</pre>
|
516
|
+
</div>
|
517
|
+
|
518
|
+
</div>
|
519
|
+
|
520
|
+
|
521
|
+
|
522
|
+
|
384
523
|
</div>
|
385
524
|
|
386
525
|
|
@@ -409,11 +548,12 @@ will copy it into HDFS for us.</p>
|
|
409
548
|
<div class="method-source-code"
|
410
549
|
id="preprocess_mapreduce-source">
|
411
550
|
<pre>
|
412
|
-
<span class="ruby-comment"># File lib/
|
551
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 101</span>
|
413
552
|
def preprocess_mapreduce(job_data)
|
414
|
-
|
553
|
+
return
|
554
|
+
<span class="ruby-comment">#items_to_copy = ["@map", "@reduce"] if job_data["@map"] and job_data["@reduce"]</span>
|
415
555
|
items_to_copy = [<span class="ruby-string">"@mapreducejar"</span>] if job_data[<span class="ruby-string">"@mapreducejar"</span>]
|
416
|
-
|
556
|
+
<span class="ruby-comment">#items_to_copy << "@input" if job_data["@copy_input"]</span>
|
417
557
|
items_to_copy.each { |item|
|
418
558
|
source = <span class="ruby-constant">File</span>.expand_path(job_data[item])
|
419
559
|
unless <span class="ruby-constant">File</span>.exists?(source)
|
@@ -461,18 +601,39 @@ job.</p>
|
|
461
601
|
<div class="method-source-code"
|
462
602
|
id="preprocess_mpi-source">
|
463
603
|
<pre>
|
464
|
-
<span class="ruby-comment"># File lib/
|
604
|
+
<span class="ruby-comment"># File lib/neptune.rb, line 125</span>
|
465
605
|
def preprocess_mpi(job_data)
|
606
|
+
if job_data[<span class="ruby-string">"@procs_to_use"</span>]
|
607
|
+
p = job_data[<span class="ruby-string">"@procs_to_use"</span>]
|
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
|
616
|
+
end
|
617
|
+
|
466
618
|
source_code = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">"@code"</span>])
|
467
619
|
unless <span class="ruby-constant">File</span>.exists?(source_code)
|
468
|
-
file_not_found = "The specified code, #{
|
620
|
+
file_not_found = "The specified code, #{source_code}," +
|
469
621
|
<span class="ruby-string">" didn't exist. Please specify one that exists and try again"</span>
|
470
622
|
abort(file_not_found)
|
471
623
|
end
|
624
|
+
|
625
|
+
unless <span class="ruby-constant">File</span>.file?(source_code)
|
626
|
+
should_be_file = "The specified code, #{source_code}, was not a file - " +
|
627
|
+
<span class="ruby-string">" it was a directory or symbolic link. Please specify a file and try again."</span>
|
628
|
+
abort(should_be_file)
|
629
|
+
end
|
630
|
+
|
472
631
|
dest_code = <span class="ruby-string">"/tmp/thempicode"</span>
|
473
632
|
|
474
633
|
keyname = job_data[<span class="ruby-string">"@keyname"</span>]
|
634
|
+
puts <span class="ruby-string">"Copying over code..."</span>
|
475
635
|
<span class="ruby-constant">CommonFunctions</span>.scp_to_shadow(source_code, dest_code, keyname)
|
636
|
+
puts <span class="ruby-string">"Done copying code!"</span>
|
476
637
|
end</pre>
|
477
638
|
</div>
|
478
639
|
|