~ubuntu-branches/ubuntu/lucid/boinc/lucid

« back to all changes in this revision

Viewing changes to tools/boinc_submit

  • Committer: Bazaar Package Importer
  • Author(s): Frank S. Thomas, Frank S. Thomas
  • Date: 2008-05-31 08:02:47 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20080531080247-4ce890lp2rc768cr
Tags: 6.2.7-1
[ Frank S. Thomas ]
* New upstream release.
  - BOINC Manager: Redraw disk usage charts immediately after connecting to
    a (different) client. (closes: 463823)
* debian/copyright:
  - Added the instructions from debian/README.Debian-source about how
    repackaged BOINC tarballs can be reproduced because DevRef now
    recommends to put this here instead of in the afore-mentioned file.
  - Updated for the new release.
* Removed the obsolete debian/README.Debian-source.
* For consistency upstream renamed the core client and the command tool
  ("boinc_client" to "boinc" and "boinc_cmd" to "boinccmd"). Done the same
  in all packages and created symlinks with the old names for the binaries
  and man pages. Also added an entry in debian/boinc-client.NEWS explaining
  this change.
* debian/rules: Do not list Makefile.ins in the clean target individually,
  just remove all that can be found.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env php
 
2
 
 
3
<?php
 
4
 
 
5
// Submit a single job.
 
6
// Implementation notes:
 
7
// - The jobs use the app "single_job_PLATFORM".
 
8
//   This app has a single app_version containing the wrapper for that platform
 
9
// - the executable is part of the WU, and has the sticky bit set,
 
10
//   and has a signature
 
11
// - The logical and physical name of the executable
 
12
//   (as stored in the download directory) is "program_platform_cksum"
 
13
//   where cksum is the last 8 chars of the MD5
 
14
// - The physical name of the job file is job_WUID.xml
 
15
// - The physical names of the input/output files are name_WUID
 
16
// - a file containing the job directory is stored in
 
17
//   sj_WUID in the upload hierarchy
 
18
// - a workunit template sj_WUID is created in templates/
 
19
// - the single_job_assimilator copies the output files to the job dir,
 
20
//   and cleans up the sj_WUID and WU template files
 
21
 
 
22
ini_set('error_reporting', E_ALL);
 
23
 
 
24
// global vars
 
25
//
 
26
$project_dir = null;
 
27
$job_dir = getcwd();
 
28
$platform = 'i686-pc-linux-gnu';
 
29
$infiles = array();
 
30
$infiles_phys = array();
 
31
    // input filename with _WUID appended
 
32
$outfiles = array();
 
33
$stdin_file = null;
 
34
$stdout_file = null;
 
35
$program = null;
 
36
$program_phys = null;
 
37
    // the physical name of the program
 
38
$cmdline_args = null;
 
39
$app_name = null;
 
40
$wu_template_filename = null;
 
41
    // relative to project dir
 
42
$result_template_filename = null;
 
43
    // relative to project dir
 
44
$wrapper_job_filename = null;
 
45
$verbose = false;
 
46
$wuid = null;
 
47
 
 
48
function get_project_dir() {
 
49
    global $project_dir;
 
50
    $project_dir = getenv('BOINC_PROJECT_DIR');
 
51
    if (!$project_dir) {
 
52
        echo "You must set the environment variable BOINC_PROJECT_DIR
 
53
to the path of a BOINC project, e.g.:
 
54
 
 
55
> setenv BOINC_PROJECT_DIR ~/projects/my_project
 
56
 
 
57
";
 
58
        exit(1);
 
59
    }
 
60
}
 
61
 
 
62
function usage() {
 
63
    echo "Usage: boinc_job [boinc-options] program [program-options]
 
64
 
 
65
boinc-options:
 
66
 
 
67
--platform p
 
68
    Run the program on platform p
 
69
--infile f
 
70
    The program will use f as an input file
 
71
--outfile f
 
72
    The program will use f as an output file
 
73
--stdin f
 
74
    Direct f to the program's stdin
 
75
--stdout f
 
76
    Direct the program's stdout to f
 
77
--help
 
78
    Print this
 
79
";
 
80
    exit(1);
 
81
}
 
82
 
 
83
function error($msg) {
 
84
    echo "$msg\n";
 
85
    exit(1);
 
86
}
 
87
 
 
88
function download_path($filename) {
 
89
    global $project_dir;
 
90
    return dir_hier_path($filename, "$project_dir/download", 1024);
 
91
}
 
92
 
 
93
function upload_path($filename) {
 
94
    global $project_dir;
 
95
    return dir_hier_path($filename, "$project_dir/upload", 1024);
 
96
}
 
97
 
 
98
function do_includes() {
 
99
    global $project_dir;
 
100
    chdir("$project_dir/html/ops");
 
101
    require_once("../inc/boinc_db.inc");
 
102
    require_once("../inc/dir_hier.inc");
 
103
    BoincDb::get();
 
104
}
 
105
 
 
106
function check_app_version() {
 
107
    global $platform, $app_name;
 
108
    $app_name = "single_job_$platform";
 
109
    $app = BoincApp::lookup("name='$app_name'");
 
110
    if (!$app) {
 
111
        error("This project isn't configured to run single jobs.");
 
112
    }
 
113
}
 
114
 
 
115
// make the job.xml file used by the wrapper
 
116
//
 
117
function make_wrapper_job_file() {
 
118
    global $program_phys, $stdin_file, $stdout_file, $cmdline_args, $wuid;
 
119
    global $project_dir, $wrapper_job_filename;
 
120
 
 
121
    chdir($project_dir);
 
122
    $wrapper_job_filename = "sj_$wuid.xml";
 
123
    $path = download_path($wrapper_job_filename);
 
124
    $f = fopen($path, "w");
 
125
    if (!$f) {
 
126
        error("Can't open $path");
 
127
    }
 
128
    fwrite($f,
 
129
"<job_desc>
 
130
    <task>
 
131
        <application>$program_phys</application>
 
132
");
 
133
    if ($stdin_file) {
 
134
        fwrite($f, "        <stdin_filename>$stdin_file</stdin_filename>\n");
 
135
    }
 
136
    if ($stdout_file) {
 
137
        fwrite($f, "        <stdout_filename>$stdout_file</stdout_filename>\n");
 
138
    }
 
139
    if ($cmdline_args) {
 
140
        fwrite($f, "        <command_line>$cmdline_args</command_line>\n");
 
141
    }
 
142
    fwrite($f, "    </task>\n</job_desc>\n");
 
143
    fclose($f);
 
144
}
 
145
 
 
146
function make_wu_template() {
 
147
    global $wuid, $infiles, $stdin_file, $program_phys, $wu_template_filename;
 
148
    global $project_dir;
 
149
 
 
150
    chdir($project_dir);
 
151
    $wu_template_filename = "templates/sj_wu_template_$wuid";
 
152
    $f = fopen($wu_template_filename, "w");
 
153
    if (!$f) {
 
154
        error("Can't open $wu_template_filename");
 
155
    }
 
156
    $n = count($infiles);
 
157
    $n++;   // for job file
 
158
    if ($stdin_file) {
 
159
        $n++;
 
160
    }
 
161
    for ($i=0; $i<$n; $i++) {
 
162
        fwrite($f,
 
163
"<file_info>
 
164
    <number>$i</number>
 
165
</file_info>
 
166
");
 
167
    }
 
168
 
 
169
    // The program file needs to be executable.
 
170
    // Make it sticky too.
 
171
    //
 
172
    fwrite($f,
 
173
"<file_info>
 
174
    <number>$i</number>
 
175
    <executable/>
 
176
    <sticky/>
 
177
</file_info>
 
178
");
 
179
 
 
180
    fwrite($f, "<workunit>\n");
 
181
    $i = 0;
 
182
    foreach($infiles as $infile) {
 
183
        fwrite($f,
 
184
"    <file_ref>
 
185
        <file_number>$i</file_number>
 
186
        <open_name>$infile</open_name>
 
187
        <copy_file/>
 
188
    </file_ref>
 
189
");
 
190
        $i++;
 
191
    }
 
192
    if ($stdin_file) {
 
193
        fwrite($f,
 
194
"    <file_ref>
 
195
        <file_number>$i</file_number>
 
196
        <open_name>$stdin_file</open_name>
 
197
    </file_ref>
 
198
");
 
199
        $i++;
 
200
    }
 
201
    fwrite($f,
 
202
"    <file_ref>
 
203
        <file_number>$i</file_number>
 
204
        <open_name>job.xml</open_name>
 
205
    </file_ref>
 
206
");
 
207
    $i++;
 
208
    fwrite($f,
 
209
"    <file_ref>
 
210
        <file_number>$i</file_number>
 
211
        <open_name>$program_phys</open_name>
 
212
    </file_ref>
 
213
");
 
214
    fwrite($f,
 
215
"    <rsc_fpops_bound>1e18</rsc_fpops_bound>
 
216
    <rsc_fpops_est>1e15</rsc_fpops_est>
 
217
</workunit>
 
218
");
 
219
    fclose($f);
 
220
}
 
221
 
 
222
function make_result_template() {
 
223
    global $wuid, $outfiles, $stdout_file, $project_dir;
 
224
    global $result_template_filename;
 
225
 
 
226
    chdir($project_dir);
 
227
    $result_template_filename = "templates/sj_result_template_$wuid";
 
228
    $f = fopen($result_template_filename, "w");
 
229
    if (!$f) {
 
230
        error("Can't open $result_template_filename");
 
231
    }
 
232
    $i = 0;
 
233
    foreach($outfiles as $outfile) {
 
234
        fwrite($f,
 
235
"<file_info>
 
236
    <name><OUTFILE_$i/></name>
 
237
    <generated_locally/>
 
238
    <upload_when_present/>
 
239
    <max_nbytes>1e12</max_nbytes>
 
240
    <url><UPLOAD_URL/></url>
 
241
</file_info>
 
242
");
 
243
        $i++;
 
244
    }
 
245
    if ($stdout_file) {
 
246
        fwrite($f,
 
247
"<file_info>
 
248
    <name><OUTFILE_$i/></name>
 
249
    <generated_locally/>
 
250
    <upload_when_present/>
 
251
    <max_nbytes>1e12</max_nbytes>
 
252
    <url><UPLOAD_URL/></url>
 
253
</file_info>
 
254
");
 
255
    }
 
256
 
 
257
    fwrite($f, "<result>\n");
 
258
 
 
259
    $i = 0;
 
260
    foreach($outfiles as $outfile) {
 
261
        fwrite($f,
 
262
"    <file_ref>
 
263
        <file_name><OUTFILE_$i/></file_name>
 
264
        <open_name>$outfile</open_name>
 
265
        <copy_file/>
 
266
    </file_ref>
 
267
");
 
268
        $i++;
 
269
    }
 
270
 
 
271
    if ($stdout_file) {
 
272
        fwrite($f,
 
273
"    <file_ref>
 
274
        <file_name><OUTFILE_$i/></file_name>
 
275
        <open_name>$stdout_file</open_name>
 
276
    </file_ref>
 
277
");
 
278
    }
 
279
    fwrite($f, "</result>\n");
 
280
    fclose($f);
 
281
}
 
282
 
 
283
// make the sj_WUID file
 
284
//
 
285
function make_job_file() {
 
286
    global $wuid, $job_dir, $project_dir;
 
287
 
 
288
    chdir($project_dir);
 
289
    $filename = "sj_$wuid";
 
290
    $path = upload_path($filename);
 
291
 
 
292
    $f = fopen($path, "w");
 
293
    if (!$f) {
 
294
        error("Can't open $path");
 
295
    }
 
296
    fwrite($f,
 
297
"<job_dir>$job_dir</job_dir>
 
298
");
 
299
    fclose($f);
 
300
}
 
301
 
 
302
function create_wu() {
 
303
    global $wuid;
 
304
    $name = md5(uniqid(rand(), true));
 
305
    $wuid = BoincWorkunit::insert("(name, transition_time) values ('$name', ".PHP_INT_MAX.")");
 
306
}
 
307
 
 
308
function create_job() {
 
309
    global $wuid, $app_name, $infiles_phys, $program_phys, $project_dir;
 
310
    global $result_template_filename, $wu_template_filename;
 
311
    global $wrapper_job_filename, $verbose;
 
312
 
 
313
    chdir($project_dir);
 
314
    $cmd = "bin/create_work --min_quorum 1 --target_nresults 1 --appname $app_name --wu_name sj_$wuid --wu_id $wuid --wu_template $wu_template_filename --result_template $result_template_filename";
 
315
    foreach ($infiles_phys as $infile) {
 
316
        $cmd .= " $infile";
 
317
    }
 
318
    $cmd .= " $wrapper_job_filename";
 
319
    $cmd .= " $program_phys";
 
320
 
 
321
    if ($verbose) {
 
322
        echo "Executing command: $cmd\n";
 
323
    }
 
324
    system($cmd);
 
325
}
 
326
 
 
327
// copy input files and program file to the download hierarchy
 
328
//
 
329
function copy_files() {
 
330
    global $infiles, $infiles_phys, $wuid, $job_dir, $program, $program_phys;
 
331
    global $verbose;
 
332
 
 
333
    chdir($job_dir);
 
334
    foreach ($infiles as $infile) {
 
335
        $filename = $infile.'_'.$wuid;
 
336
        $infiles_phys[] = $filename;
 
337
        $path = download_path($filename);
 
338
        if ($verbose) {
 
339
            echo "copying $infile to $path\n";
 
340
        }
 
341
        copy($infile, $path);
 
342
    }
 
343
    $path = download_path($program_phys);
 
344
    if ($verbose) {
 
345
        echo "copying $program to $path\n";
 
346
    }
 
347
    copy($program, $path);
 
348
 
 
349
}
 
350
 
 
351
// make sure the program is there, MD5 it, and get physical name
 
352
//
 
353
function check_program() {
 
354
    global $program, $job_dir, $program_phys, $platform;
 
355
 
 
356
    chdir($job_dir);
 
357
    if (!is_file($program)) {
 
358
        error("Program file $program not found");
 
359
    }
 
360
    $m = md5_file($program);
 
361
    $m = substr($m, 0, 8);
 
362
    $program_phys = $program.'_'.$platform.'_'.$m;
 
363
}
 
364
 
 
365
function parse_args($argc, $argv) {
 
366
    global $platform, $infiles, $outfiles, $stdin_file, $stdout_file;
 
367
    global $program, $cmdline_args, $wuid;
 
368
 
 
369
    for ($i=1; $i<$argc; $i++) {
 
370
        switch ($argv[$i]) {
 
371
        case '--help':
 
372
            usage();
 
373
        case '--platform':
 
374
            $platform = $argv[++$i];
 
375
            break;
 
376
        case '--infile':
 
377
            $infiles[] = $argv[++$i];
 
378
            break;
 
379
        case '--outfile':
 
380
            $outfiles[] = $argv[++$i];
 
381
            break;
 
382
        case '--stdin':
 
383
            $stdin_file = $argv[++$i];
 
384
            break;
 
385
        case '--stdout':
 
386
            $stdout_file = $argv[++$i];
 
387
            break;
 
388
        case '--verbose':
 
389
            $verbose = true;
 
390
            break;
 
391
        case '--wait':
 
392
            $wuid = $argv[++$i];
 
393
            wait();
 
394
        default:
 
395
            if ($program) {
 
396
                $cmdline_args .= ''.$argv[$i];
 
397
            } else {
 
398
                $program = $argv[$i];
 
399
            }
 
400
            break;
 
401
        }
 
402
    }
 
403
    if (!$program) usage();
 
404
}
 
405
 
 
406
function show_result($result, $i) {
 
407
    switch ($result->server_state) {
 
408
    case 2:
 
409
        echo "  Instance $i: unsent\n";
 
410
        break;
 
411
    case 4:
 
412
        echo "  Instance $i: in progress on host $result->hostid\n";
 
413
        break;
 
414
    case 5:
 
415
        echo "  Instance $i: completed on host $result->hostid\n";
 
416
        break;
 
417
    }
 
418
}
 
419
 
 
420
function show_wu_status($wu) {
 
421
    $now = date("F j, Y, g:i a e");
 
422
    switch ($wu->assimilate_state) {
 
423
    case 0:
 
424
        echo "$now: job $wu->id is in progress\n";
 
425
        $results = BoincResult::enum("workunitid=$wu->id");
 
426
        $n = count($results);
 
427
        if ($n) {
 
428
            $i = 0;
 
429
            foreach ($results as $result) {
 
430
                show_result($result, $i);
 
431
                $i++;
 
432
            }
 
433
        } else {
 
434
            echo "  (no instances yet)\n";
 
435
        }
 
436
        break;
 
437
    case 1:
 
438
        echo "$now: job $wu->id is being assimilated\n";
 
439
        break;
 
440
    case 2:
 
441
        echo "$now: job $wu->id completed\n";
 
442
        exit;
 
443
    }
 
444
}
 
445
 
 
446
function wait() {
 
447
    global $wuid;
 
448
 
 
449
    while (1) {
 
450
        $wu = BoincWorkunit::lookup_id($wuid);
 
451
        if (!$wu) {
 
452
            echo "Job $wuid is not in the database\n";
 
453
            exit;
 
454
        }
 
455
        show_wu_status($wu);
 
456
        sleep(10);
 
457
    }
 
458
}
 
459
 
 
460
get_project_dir();
 
461
do_includes();
 
462
parse_args($argc, $argv);
 
463
check_app_version();
 
464
check_program();
 
465
create_wu();
 
466
make_wrapper_job_file();
 
467
make_job_file();
 
468
make_wu_template();
 
469
make_result_template();
 
470
copy_files();
 
471
create_job();
 
472
wait();
 
473
 
 
474
?>