function handle_submit($r, $user, $app) { global $app_name, $log; $timestamp = date("Y-m-d H:i", time()); // read the list of template filenames // $files = file("../../tree_threader_template_files"); if ($files === false) { fwrite($log, "{$timestamp}\ttemplate file tree_threader_template_files\n"); error("no templates file"); } $njobs = sizeof($files); $now = time(); $batch_id = BoincBatch::insert("(user_id, create_time, njobs, name, app_id, state) values ({$user->id}, {$now}, {$njobs}, 'tree_threader batch', {$app->id}, " . BATCH_STATE_IN_PROGRESS . ")"); if (!$batch_id) { $log_msg = "{$timestamp}\tfailed to create batch for user {$user->id}\n"; fwrite($log, $log_msg); die("couldn't create batch\n"); } else { $log_msg = "{$timestamp}\tcreated batch {$batch_id} for user {$user->id}\n"; fwrite($log, $log_msg); } // move the sequence file to the download hier // $config = simplexml_load_string(file_get_contents("../../config.xml")); $fanout = (int) $config->config->uldl_dir_fanout; $download_dir = trim((string) $config->config->download_dir); $seq_fname = "treeThreader_sequence_{$batch_id}.tar.gz"; $seq_path = dir_hier_path($seq_fname, $download_dir, $fanout); $tmp_name = $_FILES['seq_file']['tmp_name']; $ret = rename($tmp_name, $seq_path); if ($ret === false) { error("couldn't rename sequence file"); } $i = 1; foreach ($files as $file) { $file = trim($file); $wu_name = "ICT_" . $batch_id . "_{$i}"; $cmd = "cd ../..; ./bin/create_work --appname {$app_name} --batch {$batch_id} --wu_name {$wu_name} --wu_template templates/ICT_in --result_template templates/ICT_out {$seq_fname} {$file}"; fwrite($log, "{$timestamp}\t{$cmd}\n"); system($cmd, $ret); if ($ret != 0) { fwrite($log, "can not creat job {$wu_name}\n"); error("can't create job"); } $i++; } echo "<tt_reply>\n<batch_id>{$batch_id}</batch_id>\n</tt_reply>\n"; }
function get_wu_output_files($wu_id, $auth_str) { $wu = BoincWorkunit::lookup_id($wu_id); if (!$wu) { die("no workunit {$wu_id}"); } $batch = BoincBatch::lookup_id($wu->batch); if (!$batch) { die("no batch {$wu->batch}"); } $user = BoincUser::lookup_id($batch->user_id); if (!$user) { die("no user {$batch->user_id}"); } $x = md5($user->authenticator . $wu_id); echo "user authenticator= {$user->authenticator}, wu_id={$wu_id}<br/>"; if ($x != $auth_str) { die("bad auth str: x={$x}, auth_str={$auth_str}"); } $zip_basename = tempnam("/tmp", "boinc_wu_" . $wu->name . "_"); $zip_filename = $zip_basename . ".zip"; $fanout = parse_config(get_config(), "<uldl_dir_fanout>"); $upload_dir = parse_config(get_config(), "<upload_dir>"); if (!$wu->canonical_resultid) { die("no canonical result for wu {$wu->name}"); } $result = BoincResult::lookup_id($wu->canonical_resultid); $names = get_outfile_names($result); foreach ($names as $name) { $path = dir_hier_path($name, $upload_dir, $fanout); if (is_file($path)) { system("nice -9 zip -jq {$zip_basename} {$path}"); } } do_download($zip_filename); unlink($zip_filename); unlink($zip_basename); }
function stage_file($file) { global $fanout; $download_dir = parse_config(get_config(), "<download_dir>"); switch ($file->mode) { case "semilocal": case "local": // read the file (from disk or network) to get MD5. // Copy to download hier, using a physical name based on MD5 // $md5 = md5_file($file->source); if (!$md5) { xml_error(-1, "BOINC server: Can't get MD5 of file {$file->source}"); } $name = "jf_{$md5}"; $path = dir_hier_path($name, $download_dir, $fanout); if (file_exists($path)) { return $name; } if (!copy($file->source, $path)) { xml_error(-1, "BOINC server: can't copy file from {$file->source} to {$path}"); } return $name; case "local_staged": return $file->source; case "inline": $md5 = md5($file->source); if (!$md5) { xml_error(-1, "BOINC server: Can't get MD5 of inline data"); } $name = "jf_{$md5}"; $path = dir_hier_path($name, $download_dir, $fanout); if (file_exists($path)) { return $name; } if (!file_put_contents($path, $file->source)) { xml_error(-1, "BOINC server: can't write to file {$path}"); } return $name; } xml_error(-1, "BOINC server: unsupported file mode: {$file->mode}"); }
function upload_files($r) { xml_start_tag("upload_files"); list($user, $user_submit) = authenticate_user($r, null); $fanout = parse_config(get_config(), "<uldl_dir_fanout>"); $delete_time = (int) $r->delete_time; $batch_id = (int) $r->batch_id; //print_r($_FILES); $i = 0; foreach ($r->md5 as $f) { $md5 = (string) $f; $name = "file_{$i}"; $tmp_name = $_FILES[$name]['tmp_name']; if (!is_uploaded_file($tmp_name)) { xml_error(-1, "{$tmp_name} is not an uploaded file"); } $fname = job_file_name($md5); $path = dir_hier_path($fname, project_dir() . "/download", $fanout); rename($tmp_name, $path); $now = time(); $jf_id = BoincJobFile::insert("(md5, create_time, delete_time) values ('{$md5}', {$now}, {$delete_time})"); if (!$jf_id) { xml_error(-1, "upload_files(): BoincJobFile::insert({$md5}) failed: " . BoincDb::error()); } if ($batch_id) { BoincBatchFileAssoc::insert("(batch_id, job_file_id) values ({$batch_id}, {$jf_id})"); } $i++; } echo "<success/>\n </upload_files>\n "; }
function handle_query_job($user) { $wuid = get_int('wuid'); $wu = BoincWorkunit::lookup_id($wuid); if (!$wu) { error_page("no such job"); } page_head("Job {$wuid}"); echo "\n <a href=workunit.php?wuid={$wuid}>Workunit details</a> ·\n <a href=submit.php?action=query_batch&batch_id={$wu->batch}>Batch {$wu->batch}</a>\n "; // show input files // echo "<h2>Input files</h2>\n"; $x = "<in>" . $wu->xml_doc . "</in>"; $x = simplexml_load_string($x); start_table(); table_header("Logical name<br><p class=\"text-muted\">(click to view)</p>", "Size (bytes)", "MD5"); foreach ($x->workunit->file_ref as $fr) { $pname = (string) $fr->file_name; $lname = (string) $fr->open_name; foreach ($x->file_info as $fi) { if ((string) $fi->name == $pname) { table_row("<a href={$fi->url}>{$lname}</a>", $fi->nbytes, $fi->md5_cksum); break; } } } end_table(); echo "<h2>Instances</h2>\n"; start_table(); table_header("Instance ID<br><p class=\"text-muted\">click for result page</p>", "State", "Output files<br><p class=\"text-muted\">click to view the file</p>"); $results = BoincResult::enum("workunitid={$wuid}"); $upload_dir = parse_config(get_config(), "<upload_dir>"); $fanout = parse_config(get_config(), "<uldl_dir_fanout>"); foreach ($results as $result) { echo "<tr>\n <td><a href=result.php?resultid={$result->id}>{$result->id} · {$result->name} </a></td>\n <td>" . state_string($result) . "</td>\n <td>\n"; $i = 0; if ($result->server_state == 5) { $names = get_outfile_names($result); $i = 0; foreach ($names as $name) { $url = boinc_get_output_file_url($user, $result, $i++); $path = dir_hier_path($name, $upload_dir, $fanout); $s = stat($path); $size = $s['size']; echo "<a href={$url}>{$name} </a> (" . number_format($size) . " bytes)<br/>"; } $i++; } echo "</td></tr>\n"; } end_table(); echo "<p><a href=submit.php>Return to job control page</a>\n"; page_tail(); }
function handle_query_job($user) { $wuid = get_int('wuid'); page_head("Job {$wuid}"); echo "<a href=workunit.php?wuid={$wuid}>View workunit page</a>\n"; // show input files // echo "<h2>Input files</h2>\n"; $wu = BoincWorkunit::lookup_id($wuid); $x = "<in>" . $wu->xml_doc . "</in>"; $x = simplexml_load_string($x); start_table(); table_header("Logical name<br><span class=note>(click to view)</span>", "Size (bytes)", "MD5"); $fanout = parse_config(get_config(), "<uldl_dir_fanout>"); foreach ($x->workunit->file_ref as $fr) { $pname = (string) $fr->file_name; $lname = (string) $fr->open_name; $dir = filename_hash($pname, $fanout); $path = "../../download/{$dir}/{$pname}"; $md5 = md5_file($path); $s = stat($path); $size = $s['size']; table_row("<a href=/download/{$dir}/{$pname}>{$lname}</a>", $size, $md5); } end_table(); echo "<h2>Instances</h2>\n"; start_table(); table_header("Instance ID<br><span class=note>click for result page</span>", "State", "Output files<br><span class=note>click to view the file</span>"); $results = BoincResult::enum("workunitid={$wuid}"); foreach ($results as $result) { echo "<tr>\n <td><a href=result.php?resultid={$result->id}>{$result->id} | {$result->name} </a></td>\n <td>" . state_string($result) . "</td>\n <td>\n"; $i = 0; if ($result->server_state == 5) { $names = get_outfile_names($result); $fanout = parse_config(get_config(), "<uldl_dir_fanout>"); $i = 0; foreach ($names as $name) { $url = boinc_get_output_file_url($user, $result, $i++); $path = dir_hier_path($name, "../../upload", $fanout); $s = stat($path); $size = $s['size']; echo "<a href={$url}>{$name} </a> (" . number_format($size) . " bytes)<br/>"; } $i++; } echo "</td></tr>\n"; } end_table(); echo "<p><a href=submit.php>Return to job control page</a>\n"; page_tail(); }
function stage_file($file) { global $fanout; $md5 = md5_file($file->source); if (!$md5) { error("Can't get MD5 of file {$source}"); } $name = "batch_{$md5}"; $path = dir_hier_path($name, "../../download", $fanout); if (file_exists($path)) { return $name; } if (!copy($file->source, $path)) { error("can't copy file from {$file->source} to {$path}"); } return $name; }