neptune 0.1.4 → 0.2.0

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.
@@ -0,0 +1,1102 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
7
+
8
+ <title>Module: NeptuneHelper</title>
9
+
10
+ <link rel="stylesheet" href="./rdoc.css" type="text/css" media="screen" />
11
+
12
+ <script src="./js/jquery.js" type="text/javascript"
13
+ charset="utf-8"></script>
14
+ <script src="./js/thickbox-compressed.js" type="text/javascript"
15
+ charset="utf-8"></script>
16
+ <script src="./js/quicksearch.js" type="text/javascript"
17
+ charset="utf-8"></script>
18
+ <script src="./js/darkfish.js" type="text/javascript"
19
+ charset="utf-8"></script>
20
+
21
+ </head>
22
+ <body class="module">
23
+
24
+ <div id="metadata">
25
+ <div id="home-metadata">
26
+ <div id="home-section" class="section">
27
+ <h3 class="section-header">
28
+ <a href="./index.html">Home</a>
29
+ <a href="./index.html#classes">Classes</a>
30
+ <a href="./index.html#methods">Methods</a>
31
+ </h3>
32
+ </div>
33
+ </div>
34
+
35
+ <div id="file-metadata">
36
+ <div id="file-list-section" class="section">
37
+ <h3 class="section-header">In Files</h3>
38
+ <div class="section-body">
39
+ <ul>
40
+
41
+ <li><a href="./lib/neptune_rb.html?TB_iframe=true&amp;height=550&amp;width=785"
42
+ class="thickbox" title="lib/neptune.rb">lib/neptune.rb</a></li>
43
+
44
+ </ul>
45
+ </div>
46
+ </div>
47
+
48
+
49
+ </div>
50
+
51
+ <div id="class-metadata">
52
+
53
+ <!-- Parent Class -->
54
+
55
+
56
+ <!-- Namespace Contents -->
57
+
58
+
59
+ <!-- Method Quickref -->
60
+
61
+ <div id="method-list-section" class="section">
62
+ <h3 class="section-header">Methods</h3>
63
+ <ul class="link-list">
64
+
65
+ <li><a href="#method-c-compile_code">::compile_code</a></li>
66
+
67
+ <li><a href="#method-c-do_preprocessing">::do_preprocessing</a></li>
68
+
69
+ <li><a href="#method-c-get_input">::get_input</a></li>
70
+
71
+ <li><a href="#method-c-get_job_data">::get_job_data</a></li>
72
+
73
+ <li><a href="#method-c-get_std_out_and_err">::get_std_out_and_err</a></li>
74
+
75
+ <li><a href="#method-c-preprocess_babel">::preprocess_babel</a></li>
76
+
77
+ <li><a href="#method-c-preprocess_compile">::preprocess_compile</a></li>
78
+
79
+ <li><a href="#method-c-preprocess_erlang">::preprocess_erlang</a></li>
80
+
81
+ <li><a href="#method-c-preprocess_mpi">::preprocess_mpi</a></li>
82
+
83
+ <li><a href="#method-c-preprocess_ssa">::preprocess_ssa</a></li>
84
+
85
+ <li><a href="#method-c-require_file_to_exist">::require_file_to_exist</a></li>
86
+
87
+ <li><a href="#method-c-require_file_to_not_exist">::require_file_to_not_exist</a></li>
88
+
89
+ <li><a href="#method-c-require_param">::require_param</a></li>
90
+
91
+ <li><a href="#method-c-run_job">::run_job</a></li>
92
+
93
+ <li><a href="#method-c-upload_app_for_cicero">::upload_app_for_cicero</a></li>
94
+
95
+ <li><a href="#method-c-validate_storage_params">::validate_storage_params</a></li>
96
+
97
+ <li><a href="#method-c-wait_for_compilation_to_finish">::wait_for_compilation_to_finish</a></li>
98
+
99
+ </ul>
100
+ </div>
101
+
102
+
103
+ <!-- Included Modules -->
104
+
105
+ </div>
106
+
107
+ <div id="project-metadata">
108
+
109
+
110
+
111
+ <div id="classindex-section" class="section project-section">
112
+ <h3 class="section-header">Class/Module Index
113
+ <span class="search-toggle"><img src="./images/find.png"
114
+ height="16" width="16" alt="[+]"
115
+ title="show/hide quicksearch" /></span></h3>
116
+ <form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
117
+ <fieldset>
118
+ <legend>Quicksearch</legend>
119
+ <input type="text" name="quicksearch" value=""
120
+ class="quicksearch-field" />
121
+ </fieldset>
122
+ </form>
123
+
124
+ <ul class="link-list">
125
+
126
+ <li><a href="./AppControllerClient.html">AppControllerClient</a></li>
127
+
128
+ <li><a href="./AppControllerException.html">AppControllerException</a></li>
129
+
130
+ <li><a href="./BabelHelper.html">BabelHelper</a></li>
131
+
132
+ <li><a href="./BadConfigurationException.html">BadConfigurationException</a></li>
133
+
134
+ <li><a href="./CommonFunctions.html">CommonFunctions</a></li>
135
+
136
+ <li><a href="./FileNotFoundException.html">FileNotFoundException</a></li>
137
+
138
+ <li><a href="./NeptuneHelper.html">NeptuneHelper</a></li>
139
+
140
+ <li><a href="./Object.html">Object</a></li>
141
+
142
+ </ul>
143
+ <div id="no-class-search-results" style="display: none;">No matching classes.</div>
144
+ </div>
145
+
146
+
147
+ </div>
148
+ </div>
149
+
150
+ <div id="documentation">
151
+ <h1 class="module">NeptuneHelper</h1>
152
+
153
+ <div id="description">
154
+
155
+ </div>
156
+
157
+ <!-- Constants -->
158
+
159
+
160
+ <!-- Attributes -->
161
+
162
+
163
+ <!-- Methods -->
164
+
165
+ <div id="public-class-method-details" class="method-section section">
166
+ <h3 class="section-header">Public Class Methods</h3>
167
+
168
+
169
+ <div id="compile_code-method" class="method-detail ">
170
+ <a name="method-c-compile_code"></a>
171
+
172
+
173
+ <div class="method-heading">
174
+ <span class="method-name">compile_code</span><span
175
+ class="method-args">(job_data, ssh_args, shadow_ip)</span>
176
+ <span class="method-click-advice">click to toggle source</span>
177
+ </div>
178
+
179
+
180
+ <div class="method-description">
181
+
182
+ <p>This method sends out a request to compile code, waits for it to finish,
183
+ and gets the standard out and error returned from the compilation. This
184
+ method returns a hash containing the standard out, error, and a result that
185
+ indicates whether or not the compilation was successful.</p>
186
+
187
+
188
+
189
+ <div class="method-source-code"
190
+ id="compile_code-source">
191
+ <pre>
192
+ <span class="ruby-comment"># File lib/neptune.rb, line 369</span>
193
+ def self.compile_code(job_data, ssh_args, shadow_ip)
194
+ compiled_location = controller.compile_code(job_data)
195
+ copy_to = job_data[<span class="ruby-string">&quot;@copy_to&quot;</span>]
196
+ self.wait_for_compilation_to_finish(ssh_args, shadow_ip, compiled_location)
197
+
198
+ <span class="ruby-constant">FileUtils</span>.rm_rf(copy_to)
199
+
200
+ scp_command = &quot;scp -r #{ssh_args} root@#{shadow_ip}:#{compiled_location} #{copy_to} 2&gt;&amp;1&quot;
201
+ <span class="ruby-constant">Kernel</span>.puts scp_command
202
+ <span class="ruby-constant">CommonFunctions</span>.shell(scp_command)
203
+
204
+ code = job_data[<span class="ruby-string">&quot;@code&quot;</span>]
205
+ dirs = code.split(<span class="ruby-regexp">/\//</span>)
206
+ remote_dir = <span class="ruby-string">&quot;/tmp/&quot;</span> + dirs[-1]
207
+
208
+ [remote_dir, compiled_location].each { |remote_files|
209
+ ssh_command = &quot;ssh #{ssh_args} root@#{shadow_ip} 'rm -rf #{remote_files}' 2&gt;&amp;1&quot;
210
+ <span class="ruby-constant">Kernel</span>.puts ssh_command
211
+ <span class="ruby-constant">CommonFunctions</span>.shell(ssh_command)
212
+ }
213
+
214
+ return get_std_out_and_err(copy_to)
215
+ end</pre>
216
+ </div>
217
+
218
+ </div>
219
+
220
+
221
+
222
+
223
+ </div>
224
+
225
+
226
+ <div id="do_preprocessing-method" class="method-detail ">
227
+ <a name="method-c-do_preprocessing"></a>
228
+
229
+
230
+ <div class="method-heading">
231
+ <span class="method-name">do_preprocessing</span><span
232
+ class="method-args">(job_data, controller)</span>
233
+ <span class="method-click-advice">click to toggle source</span>
234
+ </div>
235
+
236
+
237
+ <div class="method-description">
238
+
239
+ <p>Certain types of jobs need steps to be taken before they can be started
240
+ (e.g., copying input data or code over). This method dispatches the right
241
+ method to use based on the type of the job that the user has asked to run.</p>
242
+
243
+
244
+
245
+ <div class="method-source-code"
246
+ id="do_preprocessing-source">
247
+ <pre>
248
+ <span class="ruby-comment"># File lib/neptune.rb, line 60</span>
249
+ def self.do_preprocessing(job_data, controller)
250
+ job_type = job_data[<span class="ruby-string">&quot;@type&quot;</span>]
251
+ if !<span class="ruby-constant">NEED_PREPROCESSING</span>.include?(job_type)
252
+ return
253
+ end
254
+
255
+ <span class="ruby-comment"># Don't worry about adding on the self. prefix - send will resolve</span>
256
+ <span class="ruby-comment"># it the right way</span>
257
+ preprocess = &quot;preprocess_#{job_type}&quot;.to_sym
258
+ send(preprocess, job_data, controller)
259
+ end</pre>
260
+ </div>
261
+
262
+ </div>
263
+
264
+
265
+
266
+
267
+ </div>
268
+
269
+
270
+ <div id="get_input-method" class="method-detail ">
271
+ <a name="method-c-get_input"></a>
272
+
273
+
274
+ <div class="method-heading">
275
+ <span class="method-name">get_input</span><span
276
+ class="method-args">(job_data, ssh_args, shadow_ip, controller)</span>
277
+ <span class="method-click-advice">click to toggle source</span>
278
+ </div>
279
+
280
+
281
+ <div class="method-description">
282
+
283
+ <p>This method takes a file on the local user’s computer and stores it
284
+ remotely via AppScale. It returns a hash map indicating whether or not the
285
+ job succeeded and if it failed, the reason for it.</p>
286
+
287
+
288
+
289
+ <div class="method-source-code"
290
+ id="get_input-source">
291
+ <pre>
292
+ <span class="ruby-comment"># File lib/neptune.rb, line 319</span>
293
+ def self.get_input(job_data, ssh_args, shadow_ip, controller)
294
+ result = {:result =&gt; :success}
295
+
296
+ self.require_param(<span class="ruby-string">&quot;@local&quot;</span>, job_data)
297
+
298
+ local_file = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">&quot;@local&quot;</span>])
299
+ if !<span class="ruby-constant">File</span>.exists?(local_file)
300
+ reason = &quot;the file you specified to copy, #{local_file}, doesn't exist.&quot; +
301
+ <span class="ruby-string">&quot; Please specify a file that exists and try again.&quot;</span>
302
+ return {:result =&gt; :failure, :reason =&gt; reason}
303
+ end
304
+
305
+ remote = &quot;/tmp/neptune-input-#{rand(100000)}&quot;
306
+ scp_cmd = &quot;scp -r #{ssh_args} #{local_file} root@#{shadow_ip}:#{remote}&quot;
307
+ <span class="ruby-constant">Kernel</span>.puts scp_cmd
308
+ <span class="ruby-constant">CommonFunctions</span>.shell(scp_cmd)
309
+
310
+ job_data[<span class="ruby-string">&quot;@local&quot;</span>] = remote
311
+ <span class="ruby-constant">Kernel</span>.puts &quot;job data = #{job_data.inspect}&quot;
312
+ response = controller.put_input(job_data)
313
+ if response
314
+ return {:result =&gt; :success}
315
+ else
316
+ <span class="ruby-comment"># TODO - expand this to include the reason why it failed</span>
317
+ return {:result =&gt; :failure}
318
+ end
319
+ end</pre>
320
+ </div>
321
+
322
+ </div>
323
+
324
+
325
+
326
+
327
+ </div>
328
+
329
+
330
+ <div id="get_job_data-method" class="method-detail ">
331
+ <a name="method-c-get_job_data"></a>
332
+
333
+
334
+ <div class="method-heading">
335
+ <span class="method-name">get_job_data</span><span
336
+ class="method-args">(params)</span>
337
+ <span class="method-click-advice">click to toggle source</span>
338
+ </div>
339
+
340
+
341
+ <div class="method-description">
342
+
343
+
344
+
345
+
346
+
347
+ <div class="method-source-code"
348
+ id="get_job_data-source">
349
+ <pre>
350
+ <span class="ruby-comment"># File lib/neptune.rb, line 232</span>
351
+ def self.get_job_data(params)
352
+ job_data = {}
353
+ params.each { |k, v|
354
+ key = &quot;@#{k}&quot;
355
+ job_data[key] = v
356
+ }
357
+
358
+ job_data.delete(<span class="ruby-string">&quot;@job&quot;</span>)
359
+ job_data[<span class="ruby-string">&quot;@keyname&quot;</span>] = params[:keyname] || <span class="ruby-string">&quot;appscale&quot;</span>
360
+
361
+ job_data[<span class="ruby-string">&quot;@type&quot;</span>] = job_data[<span class="ruby-string">&quot;@type&quot;</span>].to_s
362
+ type = job_data[<span class="ruby-string">&quot;@type&quot;</span>]
363
+
364
+ if !<span class="ruby-constant">ALLOWED_JOB_TYPES</span>.include?(type)
365
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-constant">JOB_TYPE_NOT_ALLOWED</span>)
366
+ end
367
+
368
+ if type == <span class="ruby-string">&quot;upc&quot;</span> or type == <span class="ruby-string">&quot;x10&quot;</span>
369
+ job_data[<span class="ruby-string">&quot;@type&quot;</span>] = <span class="ruby-string">&quot;mpi&quot;</span>
370
+ type = <span class="ruby-string">&quot;mpi&quot;</span>
371
+ end
372
+
373
+ <span class="ruby-comment"># kdt jobs also run as mpi jobs, but need to pass along an executable</span>
374
+ <span class="ruby-comment"># parameter to let mpiexec know to use python to exec it</span>
375
+ if type == <span class="ruby-string">&quot;kdt&quot;</span>
376
+ job_data[<span class="ruby-string">&quot;@type&quot;</span>] = <span class="ruby-string">&quot;mpi&quot;</span>
377
+ type = <span class="ruby-string">&quot;mpi&quot;</span>
378
+
379
+ job_data[<span class="ruby-string">&quot;@executable&quot;</span>] = <span class="ruby-string">&quot;python&quot;</span>
380
+ end
381
+
382
+ if job_data[<span class="ruby-string">&quot;@nodes_to_use&quot;</span>].class == <span class="ruby-constant">Hash</span>
383
+ job_data[<span class="ruby-string">&quot;@nodes_to_use&quot;</span>] = job_data[<span class="ruby-string">&quot;@nodes_to_use&quot;</span>].to_a.flatten
384
+ end
385
+
386
+ if !<span class="ruby-constant">NO_OUTPUT_NEEDED</span>.include?(type)
387
+ if (job_data[<span class="ruby-string">&quot;@output&quot;</span>].nil? or job_data[<span class="ruby-string">&quot;@output&quot;</span>].empty?)
388
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-string">&quot;Job output must be specified&quot;</span>)
389
+ end
390
+
391
+ if job_data[<span class="ruby-string">&quot;@output&quot;</span>][0].chr != <span class="ruby-string">&quot;/&quot;</span>
392
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-string">&quot;Job output must begin with a slash ('/')&quot;</span>)
393
+ end
394
+ end
395
+
396
+ return job_data
397
+ end</pre>
398
+ </div>
399
+
400
+ </div>
401
+
402
+
403
+
404
+
405
+ </div>
406
+
407
+
408
+ <div id="get_std_out_and_err-method" class="method-detail ">
409
+ <a name="method-c-get_std_out_and_err"></a>
410
+
411
+
412
+ <div class="method-heading">
413
+ <span class="method-name">get_std_out_and_err</span><span
414
+ class="method-args">(location)</span>
415
+ <span class="method-click-advice">click to toggle source</span>
416
+ </div>
417
+
418
+
419
+ <div class="method-description">
420
+
421
+ <p>This method returns a hash containing the standard out and standard error
422
+ from a completed job, as well as a result field that indicates whether or
423
+ not the job completed successfully (success = no errors).</p>
424
+
425
+
426
+
427
+ <div class="method-source-code"
428
+ id="get_std_out_and_err-source">
429
+ <pre>
430
+ <span class="ruby-comment"># File lib/neptune.rb, line 396</span>
431
+ def self.get_std_out_and_err(location)
432
+ result = {}
433
+
434
+ out = <span class="ruby-constant">File</span>.open(&quot;#{location}/compile_out&quot;) { |f| f.read.chomp! }
435
+ result[:out] = out
436
+
437
+ err = <span class="ruby-constant">File</span>.open(&quot;#{location}/compile_err&quot;) { |f| f.read.chomp! }
438
+ result[:err] = err
439
+
440
+ if result[:err]
441
+ result[:result] = :failure
442
+ else
443
+ result[:result] = :success
444
+ end
445
+
446
+ return result
447
+ end</pre>
448
+ </div>
449
+
450
+ </div>
451
+
452
+
453
+
454
+
455
+ </div>
456
+
457
+
458
+ <div id="preprocess_babel-method" class="method-detail ">
459
+ <a name="method-c-preprocess_babel"></a>
460
+
461
+
462
+ <div class="method-heading">
463
+ <span class="method-name">preprocess_babel</span><span
464
+ class="method-args">(job_data, controller)</span>
465
+ <span class="method-click-advice">click to toggle source</span>
466
+ </div>
467
+
468
+
469
+ <div class="method-description">
470
+
471
+ <p>This preprocessing method verifies that the user specified code that should
472
+ be run, where the output should be placed, and an engine to run over. It
473
+ also verifies that all files to be used are actually reachable. Supported
474
+ engines can be found by contacting an AppScale node.</p>
475
+
476
+
477
+
478
+ <div class="method-source-code"
479
+ id="preprocess_babel-source">
480
+ <pre>
481
+ <span class="ruby-comment"># File lib/neptune.rb, line 188</span>
482
+ def self.preprocess_babel(job_data, controller)
483
+ self.require_param(<span class="ruby-string">&quot;@code&quot;</span>, job_data)
484
+ self.require_param(<span class="ruby-string">&quot;@engine&quot;</span>, job_data)
485
+ self.require_param(<span class="ruby-string">&quot;@output&quot;</span>, job_data)
486
+
487
+ <span class="ruby-comment"># For most code types, the file's name given is the thing to exec.</span>
488
+ <span class="ruby-comment"># For Java, the actual file to search for is whatever the user gives</span>
489
+ <span class="ruby-comment"># us, with a .class extension.</span>
490
+ code_file_name = job_data[<span class="ruby-string">&quot;@code&quot;</span>]
491
+ if !job_data[<span class="ruby-string">&quot;@executable&quot;</span>].nil? and job_data[<span class="ruby-string">&quot;@executable&quot;</span>] == <span class="ruby-string">&quot;java&quot;</span>
492
+ code_file_name += <span class="ruby-string">&quot;.class&quot;</span>
493
+ end
494
+
495
+ self.require_file_to_exist(code_file_name, job_data, controller)
496
+ self.require_file_to_not_exist(job_data[<span class="ruby-string">&quot;@output&quot;</span>], job_data, controller)
497
+
498
+ if job_data[<span class="ruby-string">&quot;@argv&quot;</span>]
499
+ argv = job_data[<span class="ruby-string">&quot;@argv&quot;</span>]
500
+ if argv.class != <span class="ruby-constant">Array</span>
501
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-string">&quot;argv must be an array&quot;</span>)
502
+ end
503
+
504
+ argv.each { |arg|
505
+ if arg =~ <span class="ruby-regexp">/\/.*\/.*/</span>
506
+ self.require_file_to_exist(arg, job_data, controller)
507
+ end
508
+ }
509
+ end
510
+
511
+ if job_data[<span class="ruby-string">&quot;@appcfg_cookies&quot;</span>]
512
+ self.require_file_to_exist(job_data[<span class="ruby-string">&quot;@appcfg_cookies&quot;</span>], job_data, controller)
513
+ end
514
+
515
+ user_specified_engine = job_data[<span class="ruby-string">&quot;@engine&quot;</span>]
516
+
517
+ <span class="ruby-comment"># validate the engine here</span>
518
+ engines = controller.get_supported_babel_engines(job_data)
519
+ if !engines.include?(user_specified_engine)
520
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-string">&quot;The engine you specified, &quot;</span> +
521
+ &quot;#{user_specified_engine}, is not a supported engine. Supported engines&quot; +
522
+ &quot; are: #{engines.join(', ')}&quot;)
523
+ end
524
+ end</pre>
525
+ </div>
526
+
527
+ </div>
528
+
529
+
530
+
531
+
532
+ </div>
533
+
534
+
535
+ <div id="preprocess_compile-method" class="method-detail ">
536
+ <a name="method-c-preprocess_compile"></a>
537
+
538
+
539
+ <div class="method-heading">
540
+ <span class="method-name">preprocess_compile</span><span
541
+ class="method-args">(job_data, controller)</span>
542
+ <span class="method-click-advice">click to toggle source</span>
543
+ </div>
544
+
545
+
546
+ <div class="method-description">
547
+
548
+ <p>This preprocessing method copies over the user’s code to the Shadow node
549
+ so that it can be compiled there. A future version of this method may also
550
+ copy over libraries as well.</p>
551
+
552
+
553
+
554
+ <div class="method-source-code"
555
+ id="preprocess_compile-source">
556
+ <pre>
557
+ <span class="ruby-comment"># File lib/neptune.rb, line 75</span>
558
+ def self.preprocess_compile(job_data, controller)
559
+ code = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">&quot;@code&quot;</span>])
560
+ if !<span class="ruby-constant">File</span>.exists?(code)
561
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(&quot;The source file #{code} does not exist.&quot;)
562
+ end
563
+
564
+ suffix = code.split(<span class="ruby-string">'/'</span>)[-1]
565
+ dest = &quot;/tmp/#{suffix}&quot;
566
+ keyname = job_data[<span class="ruby-string">&quot;@keyname&quot;</span>]
567
+ shadow_ip = <span class="ruby-constant">CommonFunctions</span>.get_from_yaml(keyname, :shadow)
568
+
569
+ ssh_args = &quot;-i ~/.appscale/#{keyname}.key -o StrictHostkeyChecking=no root@#{shadow_ip}&quot;
570
+ remove_dir = &quot;ssh #{ssh_args} 'rm -rf #{dest}' 2&gt;&amp;1&quot;
571
+ <span class="ruby-constant">Kernel</span>.puts remove_dir
572
+ <span class="ruby-constant">CommonFunctions</span>.shell(remove_dir)
573
+ <span class="ruby-constant">CommonFunctions</span>.scp_to_shadow(code, dest, keyname, is_dir=true)
574
+
575
+ job_data[<span class="ruby-string">&quot;@code&quot;</span>] = dest
576
+ end</pre>
577
+ </div>
578
+
579
+ </div>
580
+
581
+
582
+
583
+
584
+ </div>
585
+
586
+
587
+ <div id="preprocess_erlang-method" class="method-detail ">
588
+ <a name="method-c-preprocess_erlang"></a>
589
+
590
+
591
+ <div class="method-heading">
592
+ <span class="method-name">preprocess_erlang</span><span
593
+ class="method-args">(job_data, controller)</span>
594
+ <span class="method-click-advice">click to toggle source</span>
595
+ </div>
596
+
597
+
598
+ <div class="method-description">
599
+
600
+
601
+
602
+
603
+
604
+ <div class="method-source-code"
605
+ id="preprocess_erlang-source">
606
+ <pre>
607
+ <span class="ruby-comment"># File lib/neptune.rb, line 95</span>
608
+ def self.preprocess_erlang(job_data, controller)
609
+ self.require_param(<span class="ruby-string">&quot;@code&quot;</span>, job_data)
610
+
611
+ source_code = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">&quot;@code&quot;</span>])
612
+ if !<span class="ruby-constant">File</span>.exists?(source_code)
613
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(&quot;The specified code, #{job_data['@code']},&quot; +
614
+ <span class="ruby-string">&quot; didn't exist. Please specify one that exists and try again&quot;</span>)
615
+ end
616
+ dest_code = <span class="ruby-string">&quot;/tmp/&quot;</span>
617
+
618
+ keyname = job_data[<span class="ruby-string">&quot;@keyname&quot;</span>]
619
+ <span class="ruby-constant">CommonFunctions</span>.scp_to_shadow(source_code, dest_code, keyname)
620
+ end</pre>
621
+ </div>
622
+
623
+ </div>
624
+
625
+
626
+
627
+
628
+ </div>
629
+
630
+
631
+ <div id="preprocess_mpi-method" class="method-detail ">
632
+ <a name="method-c-preprocess_mpi"></a>
633
+
634
+
635
+ <div class="method-heading">
636
+ <span class="method-name">preprocess_mpi</span><span
637
+ class="method-args">(job_data, controller)</span>
638
+ <span class="method-click-advice">click to toggle source</span>
639
+ </div>
640
+
641
+
642
+ <div class="method-description">
643
+
644
+ <p>This preprocessing method verifies that the user specified the number of
645
+ nodes to use. If they also specified the number of processes to use, we
646
+ also verify that this value is at least as many as the number of nodes
647
+ (that is, nodes can’t be underprovisioned in MPI).</p>
648
+
649
+
650
+
651
+ <div class="method-source-code"
652
+ id="preprocess_mpi-source">
653
+ <pre>
654
+ <span class="ruby-comment"># File lib/neptune.rb, line 113</span>
655
+ def self.preprocess_mpi(job_data, controller)
656
+ self.require_param(<span class="ruby-string">&quot;@nodes_to_use&quot;</span>, job_data)
657
+ self.require_param(<span class="ruby-string">&quot;@procs_to_use&quot;</span>, job_data)
658
+
659
+ if job_data[<span class="ruby-string">&quot;@procs_to_use&quot;</span>]
660
+ p = job_data[<span class="ruby-string">&quot;@procs_to_use&quot;</span>]
661
+ n = job_data[<span class="ruby-string">&quot;@nodes_to_use&quot;</span>]
662
+ if p &lt; n
663
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-string">&quot;:procs_to_use must be at least as &quot;</span> +
664
+ <span class="ruby-string">&quot;large as :nodes_to_use.&quot;</span>)
665
+ end
666
+ end
667
+
668
+ if job_data[<span class="ruby-string">&quot;@argv&quot;</span>]
669
+ argv = job_data[<span class="ruby-string">&quot;@argv&quot;</span>]
670
+
671
+ if argv.class == <span class="ruby-constant">String</span>
672
+ job_data[<span class="ruby-string">&quot;@argv&quot;</span>] = argv
673
+ elsif argv.class == <span class="ruby-constant">Array</span>
674
+ job_data[<span class="ruby-string">&quot;@argv&quot;</span>] = argv.join(<span class="ruby-string">' '</span>)
675
+ else
676
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-string">&quot;:argv must be either a String or Array&quot;</span>)
677
+ end
678
+ end
679
+
680
+ return job_data
681
+ end</pre>
682
+ </div>
683
+
684
+ </div>
685
+
686
+
687
+
688
+
689
+ </div>
690
+
691
+
692
+ <div id="preprocess_ssa-method" class="method-detail ">
693
+ <a name="method-c-preprocess_ssa"></a>
694
+
695
+
696
+ <div class="method-heading">
697
+ <span class="method-name">preprocess_ssa</span><span
698
+ class="method-args">(job_data, controller)</span>
699
+ <span class="method-click-advice">click to toggle source</span>
700
+ </div>
701
+
702
+
703
+ <div class="method-description">
704
+
705
+ <p>This preprocessing method verifies that the user specified the number of
706
+ trajectories to run, via either :trajectories or :simulations. Both should
707
+ not be specified - only one or the other, and regardless of which they
708
+ specify, convert it to be :trajectories.</p>
709
+
710
+
711
+
712
+ <div class="method-source-code"
713
+ id="preprocess_ssa-source">
714
+ <pre>
715
+ <span class="ruby-comment"># File lib/neptune.rb, line 145</span>
716
+ def self.preprocess_ssa(job_data, controller)
717
+ if job_data[<span class="ruby-string">&quot;@simulations&quot;</span>] and job_data[<span class="ruby-string">&quot;@trajectories&quot;</span>]
718
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-string">&quot;:simulations and :trajectories &quot;</span> +
719
+ <span class="ruby-string">&quot;not both be specified.&quot;</span>)
720
+ end
721
+
722
+ if job_data[<span class="ruby-string">&quot;@simulations&quot;</span>]
723
+ job_data[<span class="ruby-string">&quot;@trajectories&quot;</span>] = job_data[<span class="ruby-string">&quot;@simulations&quot;</span>]
724
+ job_data.delete(<span class="ruby-string">&quot;@simulations&quot;</span>)
725
+ end
726
+
727
+ self.require_param(<span class="ruby-string">&quot;@trajectories&quot;</span>, job_data)
728
+ return job_data
729
+ end</pre>
730
+ </div>
731
+
732
+ </div>
733
+
734
+
735
+
736
+
737
+ </div>
738
+
739
+
740
+ <div id="require_file_to_exist-method" class="method-detail ">
741
+ <a name="method-c-require_file_to_exist"></a>
742
+
743
+
744
+ <div class="method-heading">
745
+ <span class="method-name">require_file_to_exist</span><span
746
+ class="method-args">(file, job_data, controller)</span>
747
+ <span class="method-click-advice">click to toggle source</span>
748
+ </div>
749
+
750
+
751
+ <div class="method-description">
752
+
753
+
754
+
755
+
756
+
757
+ <div class="method-source-code"
758
+ id="require_file_to_exist-source">
759
+ <pre>
760
+ <span class="ruby-comment"># File lib/neptune.rb, line 166</span>
761
+ def self.require_file_to_exist(file, job_data, controller)
762
+ if controller.does_file_exist?(file, job_data)
763
+ return
764
+ else
765
+ raise <span class="ruby-constant">FileNotFoundException</span>
766
+ end
767
+ end</pre>
768
+ </div>
769
+
770
+ </div>
771
+
772
+
773
+
774
+
775
+ </div>
776
+
777
+
778
+ <div id="require_file_to_not_exist-method" class="method-detail ">
779
+ <a name="method-c-require_file_to_not_exist"></a>
780
+
781
+
782
+ <div class="method-heading">
783
+ <span class="method-name">require_file_to_not_exist</span><span
784
+ class="method-args">(file, job_data, controller)</span>
785
+ <span class="method-click-advice">click to toggle source</span>
786
+ </div>
787
+
788
+
789
+ <div class="method-description">
790
+
791
+
792
+
793
+
794
+
795
+ <div class="method-source-code"
796
+ id="require_file_to_not_exist-source">
797
+ <pre>
798
+ <span class="ruby-comment"># File lib/neptune.rb, line 174</span>
799
+ def self.require_file_to_not_exist(file, job_data, controller)
800
+ begin
801
+ self.require_file_to_exist(file, job_data, controller)
802
+ <span class="ruby-comment"># no exception thrown previously means that the output file exists</span>
803
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-string">'Output specified already exists'</span>)
804
+ rescue <span class="ruby-constant">FileNotFoundException</span>
805
+ return
806
+ end
807
+ end</pre>
808
+ </div>
809
+
810
+ </div>
811
+
812
+
813
+
814
+
815
+ </div>
816
+
817
+
818
+ <div id="require_param-method" class="method-detail ">
819
+ <a name="method-c-require_param"></a>
820
+
821
+
822
+ <div class="method-heading">
823
+ <span class="method-name">require_param</span><span
824
+ class="method-args">(param, job_data)</span>
825
+ <span class="method-click-advice">click to toggle source</span>
826
+ </div>
827
+
828
+
829
+ <div class="method-description">
830
+
831
+
832
+
833
+
834
+
835
+ <div class="method-source-code"
836
+ id="require_param-source">
837
+ <pre>
838
+ <span class="ruby-comment"># File lib/neptune.rb, line 160</span>
839
+ def self.require_param(param, job_data)
840
+ if !job_data[param]
841
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(&quot;#{param} must be specified&quot;)
842
+ end
843
+ end</pre>
844
+ </div>
845
+
846
+ </div>
847
+
848
+
849
+
850
+
851
+ </div>
852
+
853
+
854
+ <div id="run_job-method" class="method-detail ">
855
+ <a name="method-c-run_job"></a>
856
+
857
+
858
+ <div class="method-heading">
859
+ <span class="method-name">run_job</span><span
860
+ class="method-args">(job_data, ssh_args, shadow_ip, secret)</span>
861
+ <span class="method-click-advice">click to toggle source</span>
862
+ </div>
863
+
864
+
865
+ <div class="method-description">
866
+
867
+ <p>This method actually runs the Neptune job, given information about the job
868
+ as well as information about the node to send the request to.</p>
869
+
870
+
871
+
872
+ <div class="method-source-code"
873
+ id="run_job-source">
874
+ <pre>
875
+ <span class="ruby-comment"># File lib/neptune.rb, line 442</span>
876
+ def self.run_job(job_data, ssh_args, shadow_ip, secret)
877
+ controller = <span class="ruby-constant">AppControllerClient</span>.new(shadow_ip, secret)
878
+
879
+ <span class="ruby-comment"># TODO - right now the job is assumed to succeed in many cases</span>
880
+ <span class="ruby-comment"># need to investigate the various failure scenarios</span>
881
+ result = { :result =&gt; :success }
882
+
883
+ case job_data[<span class="ruby-string">&quot;@type&quot;</span>]
884
+ when <span class="ruby-string">&quot;input&quot;</span>
885
+ result = self.get_input(job_data, ssh_args, shadow_ip, controller)
886
+ when <span class="ruby-string">&quot;output&quot;</span>
887
+ result[:output] = controller.get_output(job_data)
888
+ when <span class="ruby-string">&quot;get-acl&quot;</span>
889
+ job_data[<span class="ruby-string">&quot;@type&quot;</span>] = <span class="ruby-string">&quot;acl&quot;</span>
890
+ result[:acl] = controller.get_acl(job_data)
891
+ when <span class="ruby-string">&quot;set-acl&quot;</span>
892
+ job_data[<span class="ruby-string">&quot;@type&quot;</span>] = <span class="ruby-string">&quot;acl&quot;</span>
893
+ result[:acl] = controller.set_acl(job_data)
894
+ when <span class="ruby-string">&quot;compile&quot;</span>
895
+ result = self.compile_code(job_data, ssh_args, shadow_ip)
896
+ when <span class="ruby-string">&quot;cicero&quot;</span>
897
+ self.upload_app_for_cicero(job_data)
898
+ msg = controller.start_neptune_job(job_data)
899
+ result[:msg] = msg
900
+ result[:result] = :failure if result[:msg] !~ <span class="ruby-regexp">/job is now running\Z/</span>
901
+ else
902
+ msg = controller.start_neptune_job(job_data)
903
+ result[:msg] = msg
904
+ result[:result] = :failure if result[:msg] !~ <span class="ruby-regexp">/job is now running\Z/</span>
905
+ end
906
+
907
+ return result
908
+ end</pre>
909
+ </div>
910
+
911
+ </div>
912
+
913
+
914
+
915
+
916
+ </div>
917
+
918
+
919
+ <div id="upload_app_for_cicero-method" class="method-detail ">
920
+ <a name="method-c-upload_app_for_cicero"></a>
921
+
922
+
923
+ <div class="method-heading">
924
+ <span class="method-name">upload_app_for_cicero</span><span
925
+ class="method-args">(job_data)</span>
926
+ <span class="method-click-advice">click to toggle source</span>
927
+ </div>
928
+
929
+
930
+ <div class="method-description">
931
+
932
+
933
+
934
+
935
+
936
+ <div class="method-source-code"
937
+ id="upload_app_for_cicero-source">
938
+ <pre>
939
+ <span class="ruby-comment"># File lib/neptune.rb, line 414</span>
940
+ def self.upload_app_for_cicero(job_data)
941
+ if !job_data[<span class="ruby-string">&quot;@app&quot;</span>]
942
+ <span class="ruby-constant">Kernel</span>.puts <span class="ruby-string">&quot;No app specified, not uploading...&quot;</span>
943
+ return
944
+ end
945
+
946
+ app_location = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">&quot;@app&quot;</span>])
947
+ if !<span class="ruby-constant">File</span>.exists?(app_location)
948
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(&quot;The app you specified, #{app_location}, does not exist.&quot; +
949
+ <span class="ruby-string">&quot;Please specify one that does and try again.&quot;</span>)
950
+ end
951
+
952
+ keyname = job_data[<span class="ruby-string">&quot;@keyname&quot;</span>] || <span class="ruby-string">&quot;appscale&quot;</span>
953
+ if job_data[<span class="ruby-string">&quot;@appscale_tools&quot;</span>]
954
+ upload_app = <span class="ruby-constant">File</span>.expand_path(job_data[<span class="ruby-string">&quot;@appscale_tools&quot;</span>]) +
955
+ <span class="ruby-constant">File</span>::<span class="ruby-constant">SEPARATOR</span> + <span class="ruby-string">&quot;bin&quot;</span> + <span class="ruby-constant">File</span>::<span class="ruby-constant">SEPARATOR</span> + <span class="ruby-string">&quot;appscale-upload-app&quot;</span>
956
+ else
957
+ upload_app = <span class="ruby-string">&quot;appscale-upload-app&quot;</span>
958
+ end
959
+
960
+ <span class="ruby-constant">Kernel</span>.puts &quot;Uploading AppEngine app at #{app_location}&quot;
961
+ upload_command = &quot;#{upload_app} --file #{app_location} --test --keyname #{keyname}&quot;
962
+ <span class="ruby-constant">Kernel</span>.puts upload_command
963
+ <span class="ruby-constant">Kernel</span>.puts `#{upload_command}`
964
+ end</pre>
965
+ </div>
966
+
967
+ </div>
968
+
969
+
970
+
971
+
972
+ </div>
973
+
974
+
975
+ <div id="validate_storage_params-method" class="method-detail ">
976
+ <a name="method-c-validate_storage_params"></a>
977
+
978
+
979
+ <div class="method-heading">
980
+ <span class="method-name">validate_storage_params</span><span
981
+ class="method-args">(job_data)</span>
982
+ <span class="method-click-advice">click to toggle source</span>
983
+ </div>
984
+
985
+
986
+ <div class="method-description">
987
+
988
+
989
+
990
+
991
+
992
+ <div class="method-source-code"
993
+ id="validate_storage_params-source">
994
+ <pre>
995
+ <span class="ruby-comment"># File lib/neptune.rb, line 280</span>
996
+ def self.validate_storage_params(job_data)
997
+ job_data[<span class="ruby-string">&quot;@storage&quot;</span>] ||= <span class="ruby-string">&quot;appdb&quot;</span>
998
+
999
+ storage = job_data[<span class="ruby-string">&quot;@storage&quot;</span>]
1000
+ if !<span class="ruby-constant">ALLOWED_STORAGE_TYPES</span>.include?(storage)
1001
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(<span class="ruby-string">&quot;Supported storage types are &quot;</span> +
1002
+ &quot;#{ALLOWED_STORAGE_TYPES.join(', ')} - #{storage} is not supported.&quot;)
1003
+ end
1004
+
1005
+ <span class="ruby-comment"># Our implementation for storing / retrieving via Google Storage</span>
1006
+ <span class="ruby-comment"># and Walrus uses</span>
1007
+ <span class="ruby-comment"># the same library as we do for S3 - so just tell it that it's S3</span>
1008
+ if storage == <span class="ruby-string">&quot;gstorage&quot;</span> or storage == <span class="ruby-string">&quot;walrus&quot;</span>
1009
+ storage = <span class="ruby-string">&quot;s3&quot;</span>
1010
+ job_data[<span class="ruby-string">&quot;@storage&quot;</span>] = <span class="ruby-string">&quot;s3&quot;</span>
1011
+ end
1012
+
1013
+ if storage == <span class="ruby-string">&quot;s3&quot;</span>
1014
+ [<span class="ruby-string">&quot;EC2_ACCESS_KEY&quot;</span>, <span class="ruby-string">&quot;EC2_SECRET_KEY&quot;</span>, <span class="ruby-string">&quot;S3_URL&quot;</span>].each { |item|
1015
+ if job_data[&quot;@#{item}&quot;]
1016
+ <span class="ruby-constant">Kernel</span>.puts &quot;Using specified #{item}&quot;
1017
+ else
1018
+ if <span class="ruby-constant">ENV</span>[item]
1019
+ <span class="ruby-constant">Kernel</span>.puts &quot;Using #{item} from environment&quot;
1020
+ job_data[&quot;@#{item}&quot;] = <span class="ruby-constant">ENV</span>[item]
1021
+ else
1022
+ raise <span class="ruby-constant">BadConfigurationException</span>.new(&quot;When storing data to S3, #{item} must be specified or be in &quot; +
1023
+ <span class="ruby-string">&quot;your environment. Please do so and try again.&quot;</span>)
1024
+ end
1025
+ end
1026
+ }
1027
+ end
1028
+
1029
+ return job_data
1030
+ end</pre>
1031
+ </div>
1032
+
1033
+ </div>
1034
+
1035
+
1036
+
1037
+
1038
+ </div>
1039
+
1040
+
1041
+ <div id="wait_for_compilation_to_finish-method" class="method-detail ">
1042
+ <a name="method-c-wait_for_compilation_to_finish"></a>
1043
+
1044
+
1045
+ <div class="method-heading">
1046
+ <span class="method-name">wait_for_compilation_to_finish</span><span
1047
+ class="method-args">(ssh_args, shadow_ip, compiled_location)</span>
1048
+ <span class="method-click-advice">click to toggle source</span>
1049
+ </div>
1050
+
1051
+
1052
+ <div class="method-description">
1053
+
1054
+ <p>This method waits for AppScale to finish compiling the user’s code,
1055
+ indicated by AppScale copying the finished code to a pre-determined
1056
+ location.</p>
1057
+
1058
+
1059
+
1060
+ <div class="method-source-code"
1061
+ id="wait_for_compilation_to_finish-source">
1062
+ <pre>
1063
+ <span class="ruby-comment"># File lib/neptune.rb, line 349</span>
1064
+ def self.wait_for_compilation_to_finish(ssh_args, shadow_ip, compiled_location)
1065
+ loop {
1066
+ ssh_command = &quot;ssh #{ssh_args} root@#{shadow_ip} 'ls #{compiled_location}' 2&gt;&amp;1&quot;
1067
+ <span class="ruby-constant">Kernel</span>.puts ssh_command
1068
+ ssh_result = <span class="ruby-constant">CommonFunctions</span>.shell(ssh_command)
1069
+ <span class="ruby-constant">Kernel</span>.puts &quot;result was [#{ssh_result}]&quot;
1070
+ if ssh_result =~ <span class="ruby-regexp">/No such file or directory/</span>
1071
+ <span class="ruby-constant">Kernel</span>.puts <span class="ruby-string">&quot;Still waiting for code to be compiled...&quot;</span>
1072
+ else
1073
+ <span class="ruby-constant">Kernel</span>.puts &quot;compilation complete! Copying compiled code to #{copy_to}&quot;
1074
+ return
1075
+ end
1076
+ sleep(5)
1077
+ }
1078
+ end</pre>
1079
+ </div>
1080
+
1081
+ </div>
1082
+
1083
+
1084
+
1085
+
1086
+ </div>
1087
+
1088
+
1089
+ </div>
1090
+
1091
+
1092
+ </div>
1093
+
1094
+ <div id="validator-badges">
1095
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
1096
+ <p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
1097
+ Rdoc Generator</a> 2</small>.</p>
1098
+ </div>
1099
+
1100
+ </body>
1101
+ </html>
1102
+