neptune 0.0.6 → 0.0.7
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 +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
|
|