|
1
|
|
|
<?php |
|
2
|
|
|
// This file is part of BOINC. |
|
3
|
|
|
// http://boinc.berkeley.edu |
|
4
|
|
|
// Copyright (C) 2020 University of California |
|
5
|
|
|
// |
|
6
|
|
|
// BOINC is free software; you can redistribute it and/or modify it |
|
7
|
|
|
// under the terms of the GNU Lesser General Public License |
|
8
|
|
|
// as published by the Free Software Foundation, |
|
9
|
|
|
// either version 3 of the License, or (at your option) any later version. |
|
10
|
|
|
// |
|
11
|
|
|
// BOINC is distributed in the hope that it will be useful, |
|
12
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
14
|
|
|
// See the GNU Lesser General Public License for more details. |
|
15
|
|
|
// |
|
16
|
|
|
// You should have received a copy of the GNU Lesser General Public License |
|
17
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>. |
|
18
|
|
|
|
|
19
|
|
|
// This file contains a PHP binding of a web-service interface |
|
20
|
|
|
// for submitting jobs to a BOINC server. |
|
21
|
|
|
// |
|
22
|
|
|
// Functions: |
|
23
|
|
|
// boinc_abort_batch(): abort a batch |
|
24
|
|
|
// boinc_estimate_batch(); estimate completion time of a batch |
|
25
|
|
|
// boinc_get_output_file(): get the URL for an output file |
|
26
|
|
|
// boinc_get_output_files(): get the URL for zipped batch output |
|
27
|
|
|
// boinc_query_batch(): get details of a batch |
|
28
|
|
|
// boinc_query_batches(): get list of batches |
|
29
|
|
|
// boinc_query_job(): get details of a job |
|
30
|
|
|
// boinc_retire_batch(): retire a batch; delete output files |
|
31
|
|
|
// boinc_submit_batch(): submit a batch |
|
32
|
|
|
// boinc_set_timeout($x): set RPC timeout to X seconds |
|
33
|
|
|
// |
|
34
|
|
|
// See https://github.com/BOINC/boinc/wiki/RemoteJobs#php-interface |
|
35
|
|
|
|
|
36
|
|
|
//// Implementation stuff follows |
|
37
|
|
|
|
|
38
|
|
|
// Convert a request message from PHP object to XML string |
|
39
|
|
|
// |
|
40
|
|
|
function req_to_xml($req, $op) { |
|
41
|
|
|
if (!isset($req->batch_name)) { |
|
42
|
|
|
$req->batch_name = "batch_".time(); |
|
43
|
|
|
} |
|
44
|
|
|
$x = "<$op> |
|
45
|
|
|
<authenticator>$req->authenticator</authenticator> |
|
46
|
|
|
<batch> |
|
47
|
|
|
<app_name>$req->app_name</app_name> |
|
48
|
|
|
<batch_name>$req->batch_name</batch_name> |
|
49
|
|
|
"; |
|
50
|
|
|
if ((isset($req->output_template_filename)) && ($req->output_template_filename)) { |
|
51
|
|
|
$x .= " <output_template_filename>$req->output_template_filename</output_template_filename> |
|
52
|
|
|
"; |
|
53
|
|
|
} |
|
54
|
|
|
if ((isset($req->input_template_filename)) && ($req->input_template_filename)) { |
|
55
|
|
|
$x .= " <input_template_filename>$req->input_template_filename</input_template_filename> |
|
56
|
|
|
"; |
|
57
|
|
|
} |
|
58
|
|
|
if ((isset($req->app_version_num)) && ($req->app_version_num)) { |
|
59
|
|
|
$x .= " <app_version_num>$req->app_version_num</app_version_num> |
|
60
|
|
|
"; |
|
61
|
|
|
} |
|
62
|
|
|
if (!empty($req->allocation_priority)) { |
|
63
|
|
|
$x .= " <allocation_priority/> |
|
64
|
|
|
"; |
|
65
|
|
|
} |
|
66
|
|
|
if (isset($req->priority)) { |
|
67
|
|
|
$x .= " <priority>$req->priority</priority> |
|
68
|
|
|
"; |
|
69
|
|
|
} |
|
70
|
|
|
foreach ($req->jobs as $job) { |
|
71
|
|
|
$x .= " <job> |
|
72
|
|
|
"; |
|
73
|
|
|
if (!empty($job->name)) { |
|
74
|
|
|
$x .= " <name>$job->name</name> |
|
75
|
|
|
"; |
|
76
|
|
|
} |
|
77
|
|
|
if (!empty($job->rsc_fpops_est)) { |
|
78
|
|
|
$x .= " <rsc_fpops_est>$job->rsc_fpops_est</rsc_fpops_est> |
|
79
|
|
|
"; |
|
80
|
|
|
} |
|
81
|
|
|
if (!empty($job->command_line)) { |
|
82
|
|
|
$x .= " <command_line>$job->command_line</command_line> |
|
83
|
|
|
"; |
|
84
|
|
|
} |
|
85
|
|
|
if (!empty($job->target_team)) { |
|
86
|
|
|
$x .= " <target_team>$job->target_team</target_team> |
|
87
|
|
|
"; |
|
88
|
|
|
} elseif (!empty($job->target_user)) { |
|
89
|
|
|
$x .= " <target_user>$job->target_user</target_user> |
|
90
|
|
|
"; |
|
91
|
|
|
} elseif (!empty($job->target_host)) { |
|
92
|
|
|
$x .= " <target_host>$job->target_host</target_host> |
|
93
|
|
|
"; |
|
94
|
|
|
} |
|
95
|
|
|
if (isset($job->priority)) { |
|
96
|
|
|
$x .= " <priority>$job->priority</priority> |
|
97
|
|
|
"; |
|
98
|
|
|
} |
|
99
|
|
|
foreach ($job->input_files as $file) { |
|
100
|
|
|
$x .= " <input_file>\n"; |
|
101
|
|
|
$x .= " <mode>$file->mode</mode>\n"; |
|
102
|
|
|
if ($file->mode == "remote") { |
|
103
|
|
|
$x .= " <url>$file->url</url>\n"; |
|
104
|
|
|
$x .= " <nbytes>$file->nbytes</nbytes>\n"; |
|
105
|
|
|
$x .= " <md5>$file->md5</md5>\n"; |
|
106
|
|
|
} else { |
|
107
|
|
|
$x .= " <source>$file->source</source>\n"; |
|
108
|
|
|
} |
|
109
|
|
|
$x .= " </input_file>\n"; |
|
110
|
|
|
} |
|
111
|
|
|
if (!empty($job->input_template)) { |
|
112
|
|
|
$x .= " $job->input_template\n"; |
|
113
|
|
|
} |
|
114
|
|
|
if (!empty($job->output_template)) { |
|
115
|
|
|
$x .= " $job->output_template\n"; |
|
116
|
|
|
} |
|
117
|
|
|
$x .= " </job> |
|
118
|
|
|
"; |
|
119
|
|
|
} |
|
120
|
|
|
$x .= " </batch> |
|
121
|
|
|
</$op> |
|
122
|
|
|
"; |
|
123
|
|
|
return $x; |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
// check whether the PHP structure looks like a batch request object |
|
127
|
|
|
// |
|
128
|
|
|
function validate_request($req) { |
|
129
|
|
|
if (!is_object($req)) return "req is not an object"; |
|
130
|
|
|
if (!property_exists($req, 'project')) return "missing req->project"; |
|
131
|
|
|
if (!property_exists($req, 'authenticator')) return "missing req->authenticator"; |
|
132
|
|
|
if (!property_exists($req, 'app_name')) return "missing req->app_name"; |
|
133
|
|
|
if (!property_exists($req, 'jobs')) return "missing req->jobs"; |
|
134
|
|
|
if (!is_array($req->jobs)) return "req->jobs is not an array"; |
|
135
|
|
|
foreach ($req->jobs as $job) { |
|
136
|
|
|
// other checks |
|
137
|
|
|
} |
|
138
|
|
|
return null; |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
$rpc_timeout = 0; |
|
142
|
|
|
|
|
143
|
|
|
// Given a request object and XML string, issue the HTTP POST request |
|
144
|
|
|
// |
|
145
|
|
|
function do_http_op($req, $xml, $op) { |
|
146
|
|
|
global $rpc_timeout; |
|
147
|
|
|
|
|
148
|
|
|
$ch = curl_init("$req->project/submit_rpc_handler.php"); |
|
149
|
|
|
curl_setopt($ch, CURLOPT_POST, 1); |
|
150
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
|
151
|
|
|
if ($rpc_timeout) { |
|
152
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, $rpc_timeout); |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
|
|
// see if we need to send any files |
|
156
|
|
|
// |
|
157
|
|
|
$nfiles = 0; |
|
158
|
|
|
$post = array(); |
|
159
|
|
|
$post["request"] = $xml; |
|
160
|
|
|
$cwd = getcwd(); |
|
161
|
|
|
if ($op == "submit_batch") { |
|
162
|
|
|
foreach ($req->jobs as $job) { |
|
163
|
|
|
foreach ($job->input_files as $file) { |
|
164
|
|
|
if ($file->mode == "inline") { |
|
165
|
|
|
$path = realpath("$cwd/$file->path"); |
|
166
|
|
|
$post["file$nfiles"] = $path; |
|
167
|
|
|
$nfiles++; |
|
168
|
|
|
} |
|
169
|
|
|
} |
|
170
|
|
|
} |
|
171
|
|
|
} |
|
172
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); |
|
173
|
|
|
$reply = curl_exec($ch); |
|
174
|
|
|
curl_close($ch); |
|
175
|
|
|
if (!$reply) return array(null, "HTTP error"); |
|
176
|
|
|
$r = @simplexml_load_string($reply); |
|
|
|
|
|
|
177
|
|
|
if (!$r) { |
|
178
|
|
|
return array(null, "Can't parse reply XML:\n$reply"); |
|
179
|
|
|
} |
|
180
|
|
|
$e = (string)$r->error_msg; |
|
181
|
|
|
if ($e) { |
|
182
|
|
|
return array(null, "BOINC server: $e"); |
|
183
|
|
|
} else { |
|
184
|
|
|
return array($r, null); |
|
185
|
|
|
} |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
// do a batch op (estimate or submit) |
|
189
|
|
|
// |
|
190
|
|
|
function do_batch_op($req, $op) { |
|
191
|
|
|
$retval = validate_request($req); |
|
192
|
|
|
if ($retval) return array(null, $retval); |
|
193
|
|
|
$xml = req_to_xml($req, $op); |
|
194
|
|
|
return do_http_op($req, $xml, $op); |
|
195
|
|
|
} |
|
196
|
|
|
|
|
197
|
|
|
// convert a batch description from XML string to object |
|
198
|
|
|
// |
|
199
|
|
|
function batch_xml_to_object($batch) { |
|
200
|
|
|
$b = new StdClass; |
|
201
|
|
|
$b->id = (int)($batch->id); |
|
202
|
|
|
$b->create_time = (double)($batch->create_time); |
|
203
|
|
|
$b->est_completion_time = (double)($batch->est_completion_time); |
|
204
|
|
|
$b->njobs = (int)($batch->njobs); |
|
205
|
|
|
$b->fraction_done = (double) $batch->fraction_done; |
|
206
|
|
|
$b->nerror_jobs = (int)($batch->nerror_jobs); |
|
207
|
|
|
$b->state = (int)($batch->state); |
|
208
|
|
|
$b->completion_time = (double)($batch->completion_time); |
|
209
|
|
|
$b->credit_estimate = (double)($batch->credit_estimate); |
|
210
|
|
|
$b->credit_canonical = (double)($batch->credit_canonical); |
|
211
|
|
|
$b->name = (string)($batch->name); |
|
212
|
|
|
$b->app_name = (string)($batch->app_name); |
|
213
|
|
|
$b->total_cpu_time = (double)($batch->total_cpu_time); |
|
214
|
|
|
return $b; |
|
215
|
|
|
} |
|
216
|
|
|
|
|
217
|
|
|
// if RPC had a fatal error, return the message |
|
218
|
|
|
// |
|
219
|
|
|
function get_error($reply, $outer_tag) { |
|
220
|
|
|
$name = $reply->getName(); |
|
221
|
|
|
if ($name != $outer_tag) { |
|
222
|
|
|
return "Bad reply outer tag"; |
|
223
|
|
|
} |
|
224
|
|
|
foreach ($reply->error as $error) { |
|
225
|
|
|
if (isset($error->error_num)) { |
|
226
|
|
|
return (string)$error->error_msg; |
|
227
|
|
|
} |
|
228
|
|
|
} |
|
229
|
|
|
return null; |
|
230
|
|
|
} |
|
231
|
|
|
|
|
232
|
|
|
//// API functions follow |
|
233
|
|
|
|
|
234
|
|
|
function boinc_set_timeout($x) { |
|
235
|
|
|
global $rpc_timeout; |
|
236
|
|
|
$rpc_timeout = $x; |
|
237
|
|
|
} |
|
238
|
|
|
|
|
239
|
|
|
function boinc_ping($req) { |
|
240
|
|
|
$req_xml = "<ping> |
|
241
|
|
|
<authenticator>$req->authenticator</authenticator> |
|
242
|
|
|
</ping> |
|
243
|
|
|
"; |
|
244
|
|
|
list($reply, $errmsg) = do_http_op($req, $req_xml, ""); |
|
245
|
|
|
if ($errmsg) return array(null, $errmsg); |
|
246
|
|
|
return array($reply, null); |
|
247
|
|
|
} |
|
248
|
|
|
|
|
249
|
|
|
function boinc_estimate_batch($req) { |
|
250
|
|
|
list($reply, $errmsg) = do_batch_op($req, "estimate_batch"); |
|
251
|
|
|
if ($errmsg) return array(0, $errmsg); |
|
252
|
|
|
if ($x = get_error($reply, "estimate_batch")) { |
|
253
|
|
|
return array(null, $x); |
|
254
|
|
|
} |
|
255
|
|
|
return array((string)$reply->seconds, null); |
|
256
|
|
|
} |
|
257
|
|
|
|
|
258
|
|
|
function boinc_submit_batch($req) { |
|
259
|
|
|
list($reply, $errmsg) = do_batch_op($req, "submit_batch"); |
|
260
|
|
|
if ($errmsg) return array(0, $errmsg); |
|
261
|
|
|
if ($x = get_error($reply, "submit_batch")) { |
|
262
|
|
|
return array(null, $x); |
|
263
|
|
|
} |
|
264
|
|
|
return array((int)$reply->batch_id, null); |
|
265
|
|
|
} |
|
266
|
|
|
|
|
267
|
|
|
function boinc_query_batches($req) { |
|
268
|
|
|
$req_xml = "<query_batches> |
|
269
|
|
|
<authenticator>$req->authenticator</authenticator> |
|
270
|
|
|
"; |
|
271
|
|
|
if (!empty($req->get_cpu_time)) { |
|
272
|
|
|
$req_xml .= " <get_cpu_time>1</get_cpu_time>\n"; |
|
273
|
|
|
} |
|
274
|
|
|
$req_xml .= "</query_batches>\n"; |
|
275
|
|
|
list($reply, $errmsg) = do_http_op($req, $req_xml, ""); |
|
276
|
|
|
if ($errmsg) return array(null, $errmsg); |
|
277
|
|
|
if ($x = get_error($reply, "query_batches")) { |
|
278
|
|
|
return array(null, $x); |
|
279
|
|
|
} |
|
280
|
|
|
$batches = array(); |
|
281
|
|
|
foreach ($reply->batch as $batch) { |
|
282
|
|
|
$b = batch_xml_to_object($batch); |
|
283
|
|
|
$batches[] = $b; |
|
284
|
|
|
} |
|
285
|
|
|
return array($batches, null); |
|
286
|
|
|
} |
|
287
|
|
|
|
|
288
|
|
|
function boinc_query_batch($req) { |
|
289
|
|
|
$req_xml = "<query_batch> |
|
290
|
|
|
<authenticator>$req->authenticator</authenticator> |
|
291
|
|
|
<batch_id>$req->batch_id</batch_id> |
|
292
|
|
|
"; |
|
293
|
|
|
if (!empty($req->get_cpu_time)) { |
|
294
|
|
|
$req_xml .= " <get_cpu_time>1</get_cpu_time>\n"; |
|
295
|
|
|
} |
|
296
|
|
|
if (!empty($req->get_job_details)) { |
|
297
|
|
|
$req_xml .= " <get_job_details>1</get_job_details>\n"; |
|
298
|
|
|
} |
|
299
|
|
|
$req_xml .= "</query_batch>\n"; |
|
300
|
|
|
list($reply, $errmsg) = do_http_op($req, $req_xml, ""); |
|
301
|
|
|
if ($errmsg) return array(null, $errmsg); |
|
302
|
|
|
if ($x = get_error($reply, "query_batch")) { |
|
303
|
|
|
return array(null, $x); |
|
304
|
|
|
} |
|
305
|
|
|
$jobs = array(); |
|
306
|
|
|
foreach ($reply->job as $job) { |
|
307
|
|
|
$j = new StdClass; |
|
308
|
|
|
$j->id = (int)($job->id); |
|
309
|
|
|
$j->canonical_instance_id = (int)($job->canonical_instance_id); |
|
310
|
|
|
$jobs[] = $j; |
|
311
|
|
|
} |
|
312
|
|
|
$r = batch_xml_to_object($reply); |
|
313
|
|
|
$r->jobs = $jobs; |
|
314
|
|
|
return array($r, null); |
|
315
|
|
|
} |
|
316
|
|
|
|
|
317
|
|
|
function boinc_query_job($req) { |
|
318
|
|
|
$req_xml = "<query_job> |
|
319
|
|
|
<authenticator>$req->authenticator</authenticator> |
|
320
|
|
|
<job_id>$req->job_id</job_id> |
|
321
|
|
|
</query_job> |
|
322
|
|
|
"; |
|
323
|
|
|
list($reply, $errmsg) = do_http_op($req, $req_xml, ""); |
|
324
|
|
|
if ($errmsg) return array(null, $errmsg); |
|
325
|
|
|
if ($x = get_error($reply, "query_job")) { |
|
326
|
|
|
return array(null, $x); |
|
327
|
|
|
} |
|
328
|
|
|
$instances = array(); |
|
329
|
|
|
foreach ($reply->instance as $instance) { |
|
330
|
|
|
$i = new StdClass; |
|
331
|
|
|
$i->name = (string)($instance->name); |
|
332
|
|
|
$i->id = (int)($instance->id); |
|
333
|
|
|
$i->state = (string)($instance->state); |
|
334
|
|
|
$i->outfiles = array(); |
|
335
|
|
|
foreach ($instance->outfile as $outfile) { |
|
336
|
|
|
$f = new StdClass; |
|
337
|
|
|
$f->size = (double)$outfile->size; |
|
338
|
|
|
$i->outfiles[] = $f; |
|
339
|
|
|
} |
|
340
|
|
|
$instances[] = $i; |
|
341
|
|
|
} |
|
342
|
|
|
$r = new StdClass; |
|
343
|
|
|
$r->instances = $instances; |
|
344
|
|
|
return array($r, null); |
|
345
|
|
|
} |
|
346
|
|
|
|
|
347
|
|
|
function boinc_abort_batch($req) { |
|
348
|
|
|
$req_xml = "<abort_batch> |
|
349
|
|
|
<authenticator>$req->authenticator</authenticator> |
|
350
|
|
|
<batch_id>$req->batch_id</batch_id> |
|
351
|
|
|
</abort_batch> |
|
352
|
|
|
"; |
|
353
|
|
|
list($reply, $errmsg) = do_http_op($req, $req_xml, ""); |
|
354
|
|
|
if ($errmsg) return $errmsg; |
|
355
|
|
|
if ($x = get_error($reply, "abort_batch")) { |
|
356
|
|
|
return array(null, $x); |
|
357
|
|
|
} |
|
358
|
|
|
return array(true, null); |
|
359
|
|
|
} |
|
360
|
|
|
|
|
361
|
|
|
function boinc_get_output_file($req) { |
|
362
|
|
|
$auth_str = md5($req->authenticator.$req->instance_name); |
|
363
|
|
|
$name = $req->instance_name; |
|
364
|
|
|
$file_num = $req->file_num; |
|
365
|
|
|
return $req->project."/get_output.php?cmd=result_file&result_name=$name&file_num=$file_num&auth_str=$auth_str"; |
|
366
|
|
|
} |
|
367
|
|
|
|
|
368
|
|
|
function boinc_get_output_files($req) { |
|
369
|
|
|
$auth_str = md5($req->authenticator.$req->batch_id); |
|
370
|
|
|
$batch_id = $req->batch_id; |
|
371
|
|
|
return $req->project."/get_output.php?cmd=batch_files&batch_id=$batch_id&auth_str=$auth_str"; |
|
372
|
|
|
} |
|
373
|
|
|
|
|
374
|
|
|
function boinc_retire_batch($req) { |
|
375
|
|
|
$req_xml = "<retire_batch> |
|
376
|
|
|
<authenticator>$req->authenticator</authenticator> |
|
377
|
|
|
<batch_id>$req->batch_id</batch_id> |
|
378
|
|
|
</retire_batch> |
|
379
|
|
|
"; |
|
380
|
|
|
list($reply, $errmsg) = do_http_op($req, $req_xml, ""); |
|
381
|
|
|
if ($errmsg) return $errmsg; |
|
382
|
|
|
if ($x = get_error($reply, "retire_batch")) { |
|
383
|
|
|
return array(null, $x); |
|
384
|
|
|
} |
|
385
|
|
|
return array(true, null); |
|
386
|
|
|
} |
|
387
|
|
|
|
|
388
|
|
|
//// example usage follows |
|
389
|
|
|
if (0) { |
|
390
|
|
|
$req = new StdClass; |
|
391
|
|
|
$req->project = "http://isaac.ssl.berkeley.edu/test/"; |
|
392
|
|
|
$req->authenticator = trim(file_get_contents("test_auth")); |
|
393
|
|
|
$req->app_name = "uppercase"; |
|
394
|
|
|
$req->batch_name = "batch_name_12"; |
|
395
|
|
|
$req->app_version_num = 710; |
|
396
|
|
|
$req->jobs = array(); |
|
397
|
|
|
|
|
398
|
|
|
|
|
399
|
|
|
$f = new StdClass; |
|
400
|
|
|
$f->mode = "remote"; |
|
401
|
|
|
$f->url = "http://isaac.ssl.berkeley.edu/validate_logic.txt"; |
|
402
|
|
|
$f->md5 = "eec5a142cea5202c9ab2e4575a8aaaa7"; |
|
403
|
|
|
$f->nbytes = 4250; |
|
404
|
|
|
|
|
405
|
|
|
if (0) { |
|
406
|
|
|
$f = new StdClass; |
|
407
|
|
|
$f->mode = "local"; |
|
408
|
|
|
$f->source = "foobar"; |
|
409
|
|
|
//$job->input_files[] = $f; |
|
410
|
|
|
} |
|
411
|
|
|
|
|
412
|
|
|
$it = " |
|
413
|
|
|
<input_template> |
|
414
|
|
|
<file_info> |
|
415
|
|
|
</file_info> |
|
416
|
|
|
<workunit> |
|
417
|
|
|
<file_ref> |
|
418
|
|
|
<open_name>in</open_name> |
|
419
|
|
|
</file_ref> |
|
420
|
|
|
<target_nresults>1</target_nresults> |
|
421
|
|
|
<min_quorum>1</min_quorum> |
|
422
|
|
|
<rsc_fpops_est> 60e9 </rsc_fpops_est> |
|
423
|
|
|
<rsc_fpops_bound> 60e12 </rsc_fpops_bound> |
|
424
|
|
|
<rsc_disk_bound>2e6</rsc_disk_bound> |
|
425
|
|
|
<rsc_memory_bound>1e6</rsc_memory_bound> |
|
426
|
|
|
<delay_bound>3600</delay_bound> |
|
427
|
|
|
<credit>1</credit> |
|
428
|
|
|
</workunit> |
|
429
|
|
|
</input_template> |
|
430
|
|
|
"; |
|
431
|
|
|
$ot = " |
|
432
|
|
|
<output_template> |
|
433
|
|
|
<file_info> |
|
434
|
|
|
<name><OUTFILE_0/></name> |
|
435
|
|
|
<generated_locally/> |
|
436
|
|
|
<upload_when_present/> |
|
437
|
|
|
<max_nbytes>6000000</max_nbytes> |
|
438
|
|
|
<url><UPLOAD_URL/></url> |
|
439
|
|
|
</file_info> |
|
440
|
|
|
<result> |
|
441
|
|
|
<file_ref> |
|
442
|
|
|
<file_name><OUTFILE_0/></file_name> |
|
443
|
|
|
<open_name>out</open_name> |
|
444
|
|
|
</file_ref> |
|
445
|
|
|
</result> |
|
446
|
|
|
</output_template> |
|
447
|
|
|
"; |
|
448
|
|
|
for ($i=0; $i<2; $i++) { |
|
449
|
|
|
$job = new StdClass; |
|
450
|
|
|
$job->input_files = array(); |
|
451
|
|
|
$job->input_files[] = $f; |
|
452
|
|
|
$job->name = $req->batch_name."_$i"; |
|
453
|
|
|
//$job->rsc_fpops_est = $i*1e9; |
|
454
|
|
|
$job->command_line = "--t $i"; |
|
455
|
|
|
$job->input_template = $it; |
|
456
|
|
|
$job->output_template = $ot; |
|
457
|
|
|
$req->jobs[] = $job; |
|
458
|
|
|
} |
|
459
|
|
|
|
|
460
|
|
|
if (0) { |
|
461
|
|
|
list($e, $errmsg) = boinc_estimate_batch($req); |
|
462
|
|
|
if ($errmsg) { |
|
463
|
|
|
echo "Error from server: $errmsg\n"; |
|
464
|
|
|
} else { |
|
465
|
|
|
echo "Batch completion estimate: $e seconds\n"; |
|
466
|
|
|
} |
|
467
|
|
|
} else { |
|
468
|
|
|
list($id, $errmsg) = boinc_submit_batch($req); |
|
469
|
|
|
if ($errmsg) { |
|
470
|
|
|
echo "Error from server: $errmsg\n"; |
|
471
|
|
|
} else { |
|
472
|
|
|
echo "Batch ID: $id\n"; |
|
473
|
|
|
} |
|
474
|
|
|
} |
|
475
|
|
|
} |
|
476
|
|
|
|
|
477
|
|
|
if (0) { |
|
478
|
|
|
list($batches, $errmsg) = boinc_query_batches($req); |
|
479
|
|
|
if ($errmsg) { |
|
480
|
|
|
echo "Error: $errmsg\n"; |
|
481
|
|
|
} else { |
|
482
|
|
|
print_r($batches); |
|
483
|
|
|
} |
|
484
|
|
|
} |
|
485
|
|
|
|
|
486
|
|
|
if (0) { |
|
487
|
|
|
$req->batch_id = 20; |
|
488
|
|
|
list($jobs, $errmsg) = boinc_query_batch($req); |
|
489
|
|
|
if ($errmsg) { |
|
490
|
|
|
echo "Error: $errmsg\n"; |
|
491
|
|
|
} else { |
|
492
|
|
|
print_r($jobs); |
|
493
|
|
|
} |
|
494
|
|
|
} |
|
495
|
|
|
?> |
|
496
|
|
|
|