source: trunk/cleanup.php@ 36

Last change on this file since 36 was 35, checked in by gegorbet, 6 years ago

mods mostly for use of mysqli

File size: 32.7 KB
RevLine 
[1]1<?php
2/*
3 * cleanup.php
4 *
5 * functions relating to copying results and cleaning up the gfac DB
[10]6 * where the job used an Airavata interface.
[1]7 *
8 */
9
10$email_address = '';
11$queuestatus = '';
12$jobtype = '';
13$db = '';
14$editXMLFilename = '';
[4]15$status = '';
[1]16
[10]17function aira_cleanup( $us3_db, $reqID, $gfac_link )
[1]18{
[25]19 global $org_domain;
[1]20 global $dbhost;
21 global $user;
22 global $passwd;
23 global $db;
24 global $guser;
25 global $gpasswd;
26 global $gDB;
27 global $me;
28 global $work;
29 global $email_address;
30 global $queuestatus;
31 global $jobtype;
32 global $editXMLFilename;
33 global $submittime;
[4]34 global $status;
[10]35 global $stderr;
[5]36 global $stdout;
[10]37 global $tarfile;
[6]38 global $requestID;
[10]39 global $submit_dir;
40 $me = 'cleanup_aira.php';
[1]41
[6]42 $requestID = $reqID;
[1]43 $db = $us3_db;
44 write_log( "$me: debug db=$db; requestID=$requestID" );
45
[35]46 $us3_link = mysqli_connect( $dbhost, $user, $passwd, $db );
[1]47
48 if ( ! $us3_link )
49 {
[35]50 write_log( "$me: could not connect: $dbhost, $user, $passwd, $db" );
[1]51 mail_to_user( "fail", "Internal Error $requestID\nCould not connect to DB" );
52 return( -1 );
53 }
54
55 // First get basic info for email messages
56 $query = "SELECT email, investigatorGUID, editXMLFilename FROM HPCAnalysisRequest " .
57 "WHERE HPCAnalysisRequestID=$requestID";
[35]58 $result = mysqli_query( $us3_link, $query );
[1]59
60 if ( ! $result )
61 {
62 write_log( "$me: Bad query: $query" );
[35]63 mail_to_user( "fail", "Internal Error $requestID\n$query\n" . mysqli_error( $us3_link ) );
[1]64 return( -1 );
65 }
66
[35]67 list( $email_address, $investigatorGUID, $editXMLFilename ) = mysqli_fetch_array( $result );
[1]68
69 $query = "SELECT personID FROM people " .
70 "WHERE personGUID='$investigatorGUID'";
[35]71 $result = mysqli_query( $us3_link, $query );
[1]72
[35]73 list( $personID ) = mysqli_fetch_array( $result );
[1]74
75 $query = "SELECT clusterName, submitTime, queueStatus, method " .
76 "FROM HPCAnalysisRequest h, HPCAnalysisResult r " .
77 "WHERE h.HPCAnalysisRequestID=$requestID " .
78 "AND h.HPCAnalysisRequestID=r.HPCAnalysisRequestID";
79
[35]80 $result = mysqli_query( $us3_link, $query );
[1]81
82 if ( ! $result )
83 {
[35]84 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
[1]85 return( -1 );
86 }
87
[35]88 if ( mysqli_num_rows( $result ) == 0 )
[1]89 {
90 write_log( "$me: US3 Table error - No records for requestID: $requestID" );
91 return( -1 );
92 }
93
[35]94 list( $cluster, $submittime, $queuestatus, $jobtype ) = mysqli_fetch_array( $result );
[1]95
96 // Get the GFAC ID
97 $query = "SELECT HPCAnalysisResultID, gfacID FROM HPCAnalysisResult " .
98 "WHERE HPCAnalysisRequestID=$requestID";
99
[35]100 $result = mysqli_query( $us3_link, $query );
[1]101
102 if ( ! $result )
103 {
104 write_log( "$me: Bad query: $query" );
[35]105 mail_to_user( "fail", "Internal Error $requestID\n$query\n" . mysqli_error( $us3_link ) );
[1]106 return( -1 );
107 }
108
[35]109 list( $HPCAnalysisResultID, $gfacID ) = mysqli_fetch_array( $result );
[1]110
[10]111 // Get data from global GFAC DB then insert it into US3 DB
[1]112
[35]113/*
114 $result = mysqli_select_db( $gfac_link, $gDB );
[1]115
116 if ( ! $result )
117 {
118 write_log( "$me: Could not connect to DB $gDB" );
119 mail_to_user( "fail", "Internal Error $requestID\nCould not connect to DB $gDB" );
120 return( -1 );
121 }
[35]122 */
[1]123
124 $query = "SELECT status, cluster, id FROM analysis " .
125 "WHERE gfacID='$gfacID'";
126
[35]127 $result = mysqli_query( $gfac_link, $query );
[1]128 if ( ! $result )
129 {
130 write_log( "$me: Could not select GFAC status for $gfacID" );
131 mail_to_user( "fail", "Could not select GFAC status for $gfacID" );
132 return( -1 );
133 }
134
[35]135 list( $status, $cluster, $id ) = mysqli_fetch_array( $result );
[1]136
[25]137 $is_us3iab = preg_match( "/us3iab/", $cluster );
138 $is_local = preg_match( "/-local/", $cluster );
139
140 if ( $is_us3iab || $is_local )
[1]141 {
142 $clushost = $cluster;
143 $clushost = preg_replace( "/\-local/", "", $clushost );
144 get_local_files( $gfac_link, $clushost, $requestID, $id, $gfacID );
145 }
146
[10]147
148 $query = "SELECT id FROM analysis " .
[1]149 "WHERE gfacID='$gfacID'";
150
[35]151 $result = mysqli_query( $gfac_link, $query );
[1]152
153 if ( ! $result )
154 {
[35]155 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
156 mail_to_user( "fail", "Internal error " . mysqli_error( $gfac_link ) );
[1]157 return( -1 );
158 }
159
[35]160 list( $analysisID ) = mysqli_fetch_array( $result );
[1]161
[10]162 // Get the request guid (LIMS submit dir name)
163 $query = "SELECT HPCAnalysisRequestGUID FROM HPCAnalysisRequest " .
164 "WHERE HPCAnalysisRequestID = $requestID ";
[35]165 $result = mysqli_query( $us3_link, $query );
[10]166
167 if ( ! $result )
168 {
[35]169 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
[10]170 }
171
[35]172 list( $requestGUID ) = mysqli_fetch_array( $result );
[10]173 $output_dir = "$submit_dir/$requestGUID";
174
175 // Get stderr,stdout,tarfile from work directory
176 if ( ! is_dir( "$output_dir" ) ) mkdir( "$output_dir", 0770 );
177 chdir( "$output_dir" );
178//write_log( "$me: gfacID=$gfacID" );
179//write_log( "$me: submit_dir=$submit_dir" );
180//write_log( "$me: requestGUID=$requestGUID" );
181write_log( "$me: output_dir=$output_dir" );
182
183 $stderr = "";
184 $stdout = "";
185 $tarfile = "";
186 $fn_stderr = "Ultrascan.stderr";
187 $fn_stdout = "Ultrascan.stdout";
188 $fn_tarfile = "analysis-results.tar";
[27]189 $secwait = 10;
[10]190 $num_try = 0;
[26]191write_log( "$me: fn_tarfile=$fn_tarfile" );
[28]192 while ( ! file_exists( $fn_tarfile ) && $num_try < 3 )
[10]193 {
[27]194 sleep( $secwait );
[10]195 $num_try++;
[27]196 $secwait *= 2;
[25]197write_log( "$me: tar-exists: num_try=$num_try" );
[10]198 }
199
200 $ofiles = scandir( $output_dir );
201 foreach ( $ofiles as $ofile )
202 {
[27]203 if ( preg_match( "/^.*stderr$/", $ofile ) )
[10]204 $fn_stderr = $ofile;
[27]205 if ( preg_match( "/^.*stdout$/", $ofile ) )
[10]206 $fn_stdout = $ofile;
207//write_log( "$me: ofile=$ofile" );
208 }
209write_log( "$me: fn_stderr=$fn_stderr" );
210write_log( "$me: fn_stdout=$fn_stdout" );
211if (file_exists($fn_tarfile)) write_log( "$me: fn_tarfile=$fn_tarfile" );
212else write_log( "$me: NOT FOUND: $fn_tarfile" );
213
[26]214 $stderr = '';
215 $stdout = '';
216 $tarfile = '';
[10]217 if ( file_exists( $fn_stderr ) ) $stderr = file_get_contents( $fn_stderr );
218 if ( file_exists( $fn_stdout ) ) $stdout = file_get_contents( $fn_stdout );
219 if ( file_exists( $fn_tarfile ) ) $tarfile = file_get_contents( $fn_tarfile );
[31]220write_log( "$me(0): length contents stderr,stdout,tarfile -- "
221 . strlen($stderr) . "," . strlen($stdout) . "," . strlen($tarfile) );
[26]222 // If stdout,stderr have no content, retry after delay
223 if ( strlen( $stdout ) == 0 || strlen( $stderr ) == 0 )
224 {
225 sleep( 20 );
226 if ( file_exists( $fn_stderr ) )
227 $stderr = file_get_contents( $fn_stderr );
228 if ( file_exists( $fn_stdout ) )
229 $stdout = file_get_contents( $fn_stdout );
230 }
[10]231
[26]232write_log( "$me: length contents stderr,stdout,tarfile -- "
233 . strlen($stderr) . "," . strlen($stdout) . "," . strlen($tarfile) );
234
[10]235 if ( $cluster == 'alamo' || $cluster == 'alamo-local' )
236 { // Filter "ipath_userinit" lines out of alamo stdout lines
237 $prefln = strlen( $stdout );
238 $output = array();
239 exec( "grep -v 'ipath_userinit' $fn_stdout 2>&1", $output, $err );
240 $stdout = implode( "\n", $output );
241 $posfln = strlen( $stdout );
242write_log( "$me: fn_stdout : filtered. Length $prefln -> $posfln ." );
243 }
244
[1]245 // Save queue messages for post-mortem analysis
246 $query = "SELECT message, time FROM queue_messages " .
247 "WHERE analysisID = $analysisID " .
248 "ORDER BY time ";
[35]249 $result = mysqli_query( $gfac_link, $query );
[1]250
251 if ( ! $result )
252 {
253 // Just log it and continue
[35]254 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
[1]255 }
256
257 $now = date( 'Y-m-d H:i:s' );
258 $message_log = "US3 DB: $db\n" .
259 "RequestID: $requestID\n" .
260 "GFAC ID: $gfacID\n" .
261 "Processed: $now\n\n" .
262 "Queue Messages\n\n" ;
[35]263 if ( mysqli_num_rows( $result ) > 0 )
[1]264 {
[35]265 while ( list( $message, $time ) = mysqli_fetch_array( $result ) )
[1]266 $message_log .= "$time $message\n";
267 }
268
269 $query = "DELETE FROM queue_messages " .
270 "WHERE analysisID = $analysisID ";
271
[35]272 $result = mysqli_query( $gfac_link, $query );
[1]273
274 if ( ! $result )
275 {
276 // Just log it and continue
[35]277 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
[1]278 }
279
[10]280 $query = "SELECT queue_msg FROM analysis " .
281 "WHERE gfacID='$gfacID' ";
282
[35]283 $result = mysqli_query( $gfac_link, $query );
284 list( $queue_msg ) = mysqli_fetch_array( $result );
[1]285
286 // But let's allow for investigation of other large stdout and/or stderr
287 if ( strlen( $stdout ) > 20480000 ||
288 strlen( $stderr ) > 20480000 )
289 write_log( "$me: stdout + stderr larger than 20M - $gfacID\n" );
290
291 $message_log .= "\n\n\nStdout Contents\n\n" .
292 $stdout .
293 "\n\n\nStderr Contents\n\n" .
294 $stderr .
295 "\n\n\nGFAC Status: $status\n" .
296 "GFAC message field: $queue_msg\n";
297
298 // Delete data from GFAC DB
299 $query = "DELETE from analysis WHERE gfacID='$gfacID'";
300
[35]301 $result = mysqli_query( $gfac_link, $query );
[1]302
303 if ( ! $result )
304 {
305 // Just log it and continue
[35]306 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
[1]307 }
308
309
310 // Try to create it if necessary, and write the file
311 // Let's use FILE_APPEND, in case this is the second time around and the
312 // GFAC job status was INSERTed, rather than UPDATEd
313 if ( ! is_dir( $output_dir ) )
314 mkdir( $output_dir, 0775, true );
315 $message_filename = "$output_dir/$db-$requestID-messages.txt";
316 file_put_contents( $message_filename, $message_log, FILE_APPEND );
[35]317 // mysqli_close( $gfac_link );
[1]318
319 /////////
320 // Insert data into HPCAnalysis
321
322 $query = "UPDATE HPCAnalysisResult SET " .
[35]323 "stderr='" . mysqli_real_escape_string( $us3_link, $stderr ) . "', " .
324 "stdout='" . mysqli_real_escape_string( $us3_link, $stdout ) . "', " .
[10]325 "queueStatus='completed' " .
[1]326 "WHERE HPCAnalysisResultID=$HPCAnalysisResultID";
327
[35]328 $result = mysqli_query( $us3_link, $query );
[1]329
330 if ( ! $result )
331 {
[35]332 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
333 mail_to_user( "fail", "Bad query:\n$query\n" . mysqli_error( $us3_link ) );
[1]334 return( -1 );
335 }
336
[10]337 // Delete data from GFAC DB
338 $query = "DELETE from analysis WHERE gfacID='$gfacID'";
[1]339
[35]340 $result = mysqli_query( $gfac_link, $query );
[10]341
342 if ( ! $result )
343 {
344 // Just log it and continue
[35]345 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
[10]346 }
347
348 // Expand the tar file
349
[1]350 if ( strlen( $tarfile ) == 0 )
351 {
352 write_log( "$me: No tarfile" );
353 mail_to_user( "fail", "No results" );
354 return( -1 );
355 }
356
357 $tar_out = array();
[10]358 exec( "tar -xf analysis-results.tar 2>&1", $tar_out, $err );
[1]359
360 // Insert the model files and noise files
361 $files = file( "analysis_files.txt", FILE_IGNORE_NEW_LINES );
362 $noiseIDs = array();
363 $modelGUIDs = array();
[17]364 $mrecsIDs = array();
365 $fns_used = array();
[1]366
367 foreach ( $files as $file )
368 {
369 $split = explode( ";", $file );
370
371 if ( count( $split ) > 1 )
372 {
373 list( $fn, $meniscus, $mc_iteration, $variance ) = explode( ";", $file );
374
375 list( $other, $mc_iteration ) = explode( "=", $mc_iteration );
376 list( $other, $variance ) = explode( "=", $variance );
377 list( $other, $meniscus ) = explode( "=", $meniscus );
378 }
379 else
380 $fn = $file;
381
[10]382 if ( preg_match( "/mdl.tmp$/", $fn ) )
383 continue;
384
[17]385 if ( in_array( $fn, $fns_used ) )
386 continue;
387
388 $fns_used[] = $fn;
389
[1]390 if ( filesize( $fn ) < 100 )
391 {
[10]392 write_log( "$me:fn is invalid $fn size filesize($fn)" );
[1]393 mail_to_user( "fail", "Internal error\n$fn is invalid" );
394 return( -1 );
395 }
396
397 if ( preg_match( "/^job_statistics\.xml$/", $fn ) ) // Job statistics file
398 {
399 $xml = file_get_contents( $fn );
400 $statistics = parse_xml( $xml, 'statistics' );
[10]401// $ntries = 0;
402//
403// while ( $statistics['cpucount'] < 1 && $ntries < 3 )
404// { // job_statistics file not totally copied, so retry
405// sleep( 10 );
406// $xml = file_get_contents( $fn );
407// $statistics = parse_xml( $xml, 'statistics' );
408// $ntries++;
409//write_log( "$me:jobstats retry $ntries" );
410// }
411//write_log( "$me:cputime=$statistics['cputime']" );
412
[1]413 $otherdata = parse_xml( $xml, 'id' );
414
415 $query = "UPDATE HPCAnalysisResult SET " .
416 "wallTime = {$statistics['walltime']}, " .
417 "CPUTime = {$statistics['cputime']}, " .
418 "CPUCount = {$statistics['cpucount']}, " .
419 "max_rss = {$statistics['maxmemory']}, " .
420 "startTime = '{$otherdata['starttime']}', " .
421 "endTime = '{$otherdata['endtime']}', " .
422 "mgroupcount = {$otherdata['groupcount']} " .
423 "WHERE HPCAnalysisResultID=$HPCAnalysisResultID";
[35]424 $result = mysqli_query( $us3_link, $query );
[1]425
426 if ( ! $result )
427 {
[35]428 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
[1]429 }
430
431 file_put_contents( "$output_dir/$fn", $xml ); // Copy to submit dir
432
[24]433 $file_type = "job_stats";
434 $id = 1;
[1]435 }
436
437 else if ( preg_match( "/\.noise/", $fn ) > 0 ) // It's a noise file
438 {
439 $xml = file_get_contents( $fn );
440 $noise_data = parse_xml( $xml, "noise" );
441 $type = ( $noise_data[ 'type' ] == "ri" ) ? "ri_noise" : "ti_noise";
442 $desc = $noise_data[ 'description' ];
443 $modelGUID = $noise_data[ 'modelGUID' ];
444 $noiseGUID = $noise_data[ 'noiseGUID' ];
[35]445 $editGUID = '00000000-0000-0000-0000-000000000000';
446 if ( isset( $model_data[ 'editGUID' ] ) )
447 $editGUID = $model_data[ 'editGUID' ];
[1]448
449 $query = "INSERT INTO noise SET " .
450 "noiseGUID='$noiseGUID'," .
451 "modelGUID='$modelGUID'," .
[35]452 "editedDataID=" .
453 "(SELECT editedDataID FROM editedData WHERE editGUID='$editGUID')," .
[1]454 "modelID=1, " .
455 "noiseType='$type'," .
456 "description='$desc'," .
[35]457 "xml='" . mysqli_real_escape_string( $us3_link, $xml ) . "'";
[1]458
459 // Add later after all files are processed: editDataID, modelID
460
[35]461 $result = mysqli_query( $us3_link, $query );
[1]462
463 if ( ! $result )
464 {
[35]465 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
466 mail_to_user( "fail", "Internal error\n$query\n" . mysqli_error( $us3_link ) );
[1]467 return( -1 );
468 }
469
[35]470 $id = mysqli_insert_id( $us3_link );
[1]471 $file_type = "noise";
472 $noiseIDs[] = $id;
473
474 // Keep track of modelGUIDs for later, when we replace them
475 $modelGUIDs[ $id ] = $modelGUID;
476
477 }
[10]478
479 else if ( preg_match( "/\.mrecs/", $fn ) > 0 ) // It's an mrecs file
[1]480 {
481 $xml = file_get_contents( $fn );
[10]482 $mrecs_data = parse_xml( $xml, "modelrecords" );
483 $desc = $mrecs_data[ 'description' ];
484 $editGUID = $mrecs_data[ 'editGUID' ];
485write_log( "$me: mrecs file editGUID=$editGUID" );
486 if ( strlen( $editGUID ) < 36 )
487 $editGUID = "12345678-0123-5678-0123-567890123456";
488 $mrecGUID = $mrecs_data[ 'mrecGUID' ];
489 $modelGUID = $mrecs_data[ 'modelGUID' ];
490
491 $query = "INSERT INTO pcsa_modelrecs SET " .
492 "editedDataID=" .
493 "(SELECT editedDataID FROM editedData WHERE editGUID='$editGUID')," .
494 "modelID=0, " .
495 "mrecsGUID='$mrecGUID'," .
496 "description='$desc'," .
[35]497 "xml='" . mysqli_real_escape_string( $us3_link, $xml ) . "'";
[10]498
499 // Add later after all files are processed: editDataID, modelID
500
[35]501 $result = mysqli_query( $us3_link, $query );
[10]502
503 if ( ! $result )
504 {
[35]505 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
506 mail_to_user( "fail", "Internal error\n$query\n" . mysqli_error( $us3_link ) );
[10]507 return( -1 );
508 }
509
[35]510 $id = mysqli_insert_id( $us3_link );
[10]511 $file_type = "mrecs";
512 $mrecsIDs[] = $id;
513
514 // Keep track of modelGUIDs for later, when we replace them
515 $rmodlGUIDs[ $id ] = $modelGUID;
516//write_log( "$me: mrecs file inserted into DB : id=$id" );
517 }
518
[23]519 else if ( preg_match( "/\.model/", $fn ) > 0 ) // It's a model file
[10]520 {
521 $xml = file_get_contents( $fn );
[1]522 $model_data = parse_xml( $xml, "model" );
523 $description = $model_data[ 'description' ];
524 $modelGUID = $model_data[ 'modelGUID' ];
525 $editGUID = $model_data[ 'editGUID' ];
526
[10]527 if ( $mc_iteration > 1 )
528 {
529 $miter = sprintf( "_mcN%03d", $mc_iteration );
530 $description = preg_replace( "/_mc[0-9]+/", $miter, $description );
531write_log( "$me: MODELUpd: O:description=$description" );
532 }
533
[1]534 $query = "INSERT INTO model SET " .
535 "modelGUID='$modelGUID'," .
536 "editedDataID=" .
537 "(SELECT editedDataID FROM editedData WHERE editGUID='$editGUID')," .
538 "description='$description'," .
539 "MCIteration='$mc_iteration'," .
540 "meniscus='$meniscus'," .
541 "variance='$variance'," .
[35]542 "xml='" . mysqli_real_escape_string( $us3_link, $xml ) . "'";
[1]543
[35]544 $result = mysqli_query( $us3_link, $query );
[1]545
546 if ( ! $result )
547 {
[35]548 write_log( "$me: Bad query:\n$query " . mysqli_error( $us3_link ) );
549 mail_to_user( "fail", "Internal error\n$query\n" . mysqli_error( $us3_link ) );
[1]550 return( -1 );
551 }
552
[35]553 $modelID = mysqli_insert_id( $us3_link );
[1]554 $id = $modelID;
555 $file_type = "model";
556
557 $query = "INSERT INTO modelPerson SET " .
558 "modelID=$modelID, personID=$personID";
[35]559 $result = mysqli_query( $us3_link, $query );
[1]560 }
561
[24]562 else // Undetermined type: skip result data update
563 continue;
564
[1]565 $query = "INSERT INTO HPCAnalysisResultData SET " .
566 "HPCAnalysisResultID='$HPCAnalysisResultID', " .
567 "HPCAnalysisResultType='$file_type', " .
568 "resultID=$id";
569
[35]570 $result = mysqli_query( $us3_link, $query );
[1]571
572 if ( ! $result )
573 {
[35]574 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
575 mail_to_user( "fail", "Internal error\n$query\n" . mysqli_error( $us3_link ) );
[1]576 return( -1 );
577 }
578 }
579
580 // Now fix up noise entries
581 // For noise files, there is, at most two: ti_noise and ri_noise
582 // In this case there will only be one modelID
583
584 foreach ( $noiseIDs as $noiseID )
585 {
586 $modelGUID = $modelGUIDs[ $noiseID ];
587 $query = "UPDATE noise SET " .
588 "editedDataID=" .
[6]589 "(SELECT editedDataID FROM model WHERE modelGUID='$modelGUID')," .
[1]590 "modelID=" .
591 "(SELECT modelID FROM model WHERE modelGUID='$modelGUID')" .
592 "WHERE noiseID=$noiseID";
593
[35]594 $result = mysqli_query( $us3_link, $query );
[1]595
596 if ( ! $result )
597 {
[35]598 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
599 mail_to_user( "fail", "Bad query\n$query\n" . mysqli_error( $us3_link ) );
[1]600 return( -1 );
601 }
602 }
603
[13]604 // Now possibly fix up mrecs entries
605
606 foreach ( $mrecsIDs as $mrecsID )
607 {
608 $modelGUID = $rmodlGUIDs[ $mrecsID ];
609 $query = "UPDATE pcsa_modelrecs SET " .
610 "modelID=" .
611 "(SELECT modelID FROM model WHERE modelGUID='$modelGUID')" .
612 "WHERE mrecsID=$mrecsID";
613
[35]614 $result = mysqli_query( $us3_link, $query );
[13]615
616 if ( ! $result )
617 {
[35]618 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
619 mail_to_user( "fail", "Bad query\n$query\n" . mysqli_error( $us3_link ) );
[13]620 return( -1 );
621 }
622write_log( "$me: mrecs entry updated : mrecsID=$mrecsID" );
623 }
624//write_log( "$me: mrecs entries updated" );
625
[1]626 // Copy results to LIMS submit directory (files there are deleted after 7 days)
627 global $submit_dir; // LIMS submit files dir
628
629 // Get the request guid (LIMS submit dir name)
630 $query = "SELECT HPCAnalysisRequestGUID FROM HPCAnalysisRequest " .
631 "WHERE HPCAnalysisRequestID = $requestID ";
[35]632 $result = mysqli_query( $us3_link, $query );
[1]633
634 if ( ! $result )
635 {
[35]636 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
[1]637 }
638
[35]639// list( $requestGUID ) = mysqli_fetch_array( $result );
[10]640//
641// chdir( "$submit_dir/$requestGUID" );
642// $f = fopen( "analysis-results.tar", "w" );
643// fwrite( $f, $tarfile );
644// fclose( $f );
[1]645
646 // Clean up
[10]647// chdir ( $work );
[1]648 // exec( "rm -rf $gfacID" );
649
[35]650 mysqli_close( $us3_link );
[1]651
652 /////////
653 // Send email
654
655 mail_to_user( "success", "" );
656}
657
658function mail_to_user( $type, $msg )
659{
660 // Note to me. Just changed subject line to include a modified $status instead
661 // of the $type variable passed. More informative than just "fail" or "success."
662 // See how it works for awhile and then consider removing $type parameter from
663 // function.
664 global $email_address;
665 global $submittime;
666 global $queuestatus;
667 global $status;
668 global $cluster;
669 global $jobtype;
670 global $org_name;
671 global $admin_email;
[6]672 global $db;
[1]673 global $dbhost;
674 global $requestID;
675 global $gfacID;
676 global $editXMLFilename;
[5]677 global $stdout;
[25]678 global $org_domain;
[1]679
680global $me;
681write_log( "$me mail_to_user(): sending email to $email_address for $gfacID" );
682
683 // Get GFAC status and message
[4]684 // function get_gfac_message() also sets global $status
685 $gfac_message = get_gfac_message( $gfacID );
[10]686 if ( $gfac_message === false ) $gfac_message = "Job Finished";
[1]687
688 // Create a status to put in the subject line
689 switch ( $status )
690 {
691 case "COMPLETE":
692 $subj_status = 'completed';
693 break;
694
695 case "CANCELLED":
696 case "CANCELED":
697 $subj_status = 'canceled';
698 break;
699
700 case "FAILED":
701 $subj_status = 'failed';
[10]702 if ( preg_match( "/^US3-A/i", $gfacID ) )
703 { // For A/Thrift FAIL, get error message
704 $gfac_message = getExperimentErrors( $gfacID );
705//$gfac_message .= "Test ERROR MESSAGE";
706 }
[1]707 break;
708
709 case "ERROR":
710 $subj_status = 'unknown error';
711 break;
712
713 default:
714 $subj_status = $status; // For now
715 break;
716
717 }
718
[10]719 $queuestatus = $subj_status;
720 $limshost = $dbhost;
721 if ( $limshost == 'localhost' )
[25]722 {
[10]723 $limshost = gethostname();
[35]724 if ( preg_match( "/scyld/", $limshost ) )
725 $limshost = 'alamo.uthscsa.edu';
726 else if ( ! preg_match( "/\./", $limshost ) )
[25]727 $limshost = $limshost . $org_domain;
728 }
[10]729
[1]730 // Parse the editXMLFilename
731 list( $runID, $editID, $dataType, $cell, $channel, $wl, $ext ) =
732 explode( ".", $editXMLFilename );
733
734 $headers = "From: $org_name Admin<$admin_email>" . "\n";
735 $headers .= "Cc: $org_name Admin<$admin_email>" . "\n";
736
737 // Set the reply address
738 $headers .= "Reply-To: $org_name<$admin_email>" . "\n";
739 $headers .= "Return-Path: $org_name<$admin_email>" . "\n";
740
741 // Try to avoid spam filters
742 $now = time();
743 $headers .= "Message-ID: <" . $now . "cleanup@$dbhost>\n";
744 $headers .= "X-Mailer: PHP v" . phpversion() . "\n";
745 $headers .= "MIME-Version: 1.0" . "\n";
746 $headers .= "Content-Transfer-Encoding: 8bit" . "\n";
747
748 $subject = "UltraScan Job Notification - $subj_status - " . substr( $gfacID, 0, 16 );
749 $message = "
750 Your UltraScan job is complete:
751
752 Submission Time : $submittime
[10]753 LIMS Host : $limshost
[1]754 Analysis ID : $gfacID
[6]755 Request ID : $requestID ( $db )
[1]756 RunID : $runID
757 EditID : $editID
758 Data Type : $dataType
759 Cell/Channel/Wl : $cell / $channel / $wl
760 Status : $queuestatus
761 Cluster : $cluster
762 Job Type : $jobtype
763 GFAC Status : $status
[4]764 GFAC Message : $gfac_message
[5]765 Stdout : $stdout
[1]766 ";
767
[4]768 if ( $type != "success" ) $message .= "Grid Ctrl Error : $msg\n";
[1]769
770 // Handle the error case where an error occurs before fetching the
771 // user's email address
772 if ( $email_address == "" ) $email_address = $admin_email;
773
774 mail( $email_address, $subject, $message, $headers );
775}
776
777function parse_xml( $xml, $type )
778{
779 $parser = new XMLReader();
780 $parser->xml( $xml );
781
782 $results = array();
783
784 while ( $parser->read() )
785 {
786 if ( $parser->name == $type )
787 {
788 while ( $parser->moveToNextAttribute() )
789 {
790 $results[ $parser->name ] = $parser->value;
791 }
792
793 break;
794 }
795 }
796
797 $parser->close();
798 return $results;
799}
800
801// Function to get information about the current job GFAC
802function get_gfac_message( $gfacID )
803{
804 global $serviceURL;
805 global $me;
806
807 $hex = "[0-9a-fA-F]";
808 if ( ! preg_match( "/^US3-Experiment/i", $gfacID ) &&
809 ! preg_match( "/^US3-$hex{8}-$hex{4}-$hex{4}-$hex{4}-$hex{12}$/", $gfacID ) )
810 {
811 // Then it's not a GFAC job
812 return false;
813 }
814
815 $url = "$serviceURL/jobstatus/$gfacID";
816 try
817 {
818 $post = new HttpRequest( $url, HttpRequest::METH_GET );
819 $http = $post->send();
820 $xml = $post->getResponseBody();
821 }
822 catch ( HttpException $e )
823 {
824 write_log( "$me: Job status not available - $gfacID" );
825 return false;
826 }
827
828 // Parse the result
829 $gfac_message = parse_message( $xml );
830
831 return $gfac_message;
832}
833
834function parse_message( $xml )
835{
[4]836 global $status;
[1]837 $status = "";
838 $gfac_message = "";
839
840 $parser = new XMLReader();
841 $parser->xml( $xml );
842
843 $results = array();
844
845 while( $parser->read() )
846 {
847 $type = $parser->nodeType;
848
849 if ( $type == XMLReader::ELEMENT )
850 $name = $parser->name;
851
852 else if ( $type == XMLReader::TEXT )
853 {
854 if ( $name == "status" )
855 $status = $parser->value;
856 else
857 $gfac_message = $parser->value;
858 }
859 }
860
861 $parser->close();
862 return $gfac_message;
863}
864
865function get_local_files( $gfac_link, $cluster, $requestID, $id, $gfacID )
866{
867 global $work;
868 global $work_remote;
869 global $me;
870 global $db;
[35]871 global $dbhost;
[1]872 global $status;
[25]873 $is_us3iab = preg_match( "/us3iab/", $cluster );
[31]874 $is_jetstr = preg_match( "/jetstream/", $cluster );
[35]875 $limshost = $dbhost;
876 $stderr = '';
877 $stdout = '';
878 $tarfile = '';
[1]879
[35]880 if ( $limshost == 'localhost' )
881 { // If DB host is local host, get full LIMS host name
882 $limshost = gethostname();
883 if ( preg_match( "/scyld/", $limshost ) )
884 $limshost = 'alamo.uthscsa.edu';
885 else if ( ! preg_match( "/\./", $limshost ) )
886 $limshost = $limshost . $org_domain;
887 }
888
889 if ( preg_match( "/alamo/", $limshost ) &&
890 preg_match( "/alamo/", $cluster ) )
891 { // If both LIMS and cluster are alamo, set up local transfers
892 $is_us3iab = 1;
893 if ( ! preg_match( "/\/local/", $work_remote ) )
894 $work_remote = $work_remote . "/local";
895 }
896
897 // Figure out job's remote (or local) work directory
[1]898 $remoteDir = sprintf( "$work_remote/$db-%06d", $requestID );
[28]899//write_log( "$me: is_us3iab=$is_us3iab remoteDir=$remoteDir" );
[1]900
901 // Get stdout, stderr, output/analysis-results.tar
902 $output = array();
903
[25]904 if ( $is_us3iab == 0 )
905 {
[28]906 // For "-local", recompute remote work directory
[31]907 $clushost = "$cluster.uthscsa.edu";
908 $lworkdir = "~us3/lims/work/local";
909 if ( $is_jetstr )
910 {
[32]911 $clushost = "js-169-137.jetstream-cloud.org";
[31]912 $lworkdir = "/N/us3_cluster/work/local";
913 }
[35]914 $cmd = "ssh us3@$clushost 'ls -d $lworkdir' 2>/dev/null";
[28]915 exec( $cmd, $output, $stat );
916 $work_remote = $output[ 0 ];
917 $remoteDir = sprintf( "$work_remote/$db-%06d", $requestID );
918write_log( "$me: -LOCAL: remoteDir=$remoteDir" );
919
[25]920 // Figure out local working directory
921 if ( ! is_dir( "$work/$gfacID" ) ) mkdir( "$work/$gfacID", 0770 );
922 $pwd = chdir( "$work/$gfacID" );
[1]923
[31]924 $cmd = "scp us3@$clushost:$remoteDir/output/analysis-results.tar . 2>&1";
[25]925
[1]926 exec( $cmd, $output, $stat );
[25]927 if ( $stat != 0 )
[1]928 write_log( "$me: Bad exec:\n$cmd\n" . implode( "\n", $output ) );
[25]929
[31]930 $cmd = "scp us3@$clushost:$remoteDir/stdout . 2>&1";
[25]931
[1]932 exec( $cmd, $output, $stat );
[25]933 if ( $stat != 0 )
934 {
[1]935 write_log( "$me: Bad exec:\n$cmd\n" . implode( "\n", $output ) );
[25]936 sleep( 10 );
937 write_log( "$me: RETRY" );
938 exec( $cmd, $output, $stat );
939 if ( $stat != 0 )
940 write_log( "$me: Bad exec:\n$cmd\n" . implode( "\n", $output ) );
941 }
942
[31]943 $cmd = "scp us3@$clushost:$remoteDir/stderr . 2>&1";
[25]944
945 exec( $cmd, $output, $stat );
946 if ( $stat != 0 )
947 {
948 write_log( "$me: Bad exec:\n$cmd\n" . implode( "\n", $output ) );
949 sleep( 10 );
950 write_log( "$me: RETRY" );
951 exec( $cmd, $output, $stat );
952 if ( $stat != 0 )
953 write_log( "$me: Bad exec:\n$cmd\n" . implode( "\n", $output ) );
954 }
[1]955 }
[25]956 else
[35]957 { // Is US3IAB or alamo-to-alamo, so just change to local work directory
[25]958 $pwd = chdir( "$remoteDir" );
959write_log( "$me: IS US3IAB: pwd=$pwd $remoteDir");
960 }
[1]961
[25]962
[1]963 // Write the files to gfacDB
964
[35]965 $secwait = 10;
966 $num_try = 0;
967 while ( ! file_exists( "stderr" ) && $num_try < 3 )
968 { // Do waits and retries to let stderr appear
969 sleep( $secwait );
970 $num_try++;
971 $secwait *= 2;
972write_log( "$me: not-exist-stderr: num_try=$num_try" );
973 }
974
975 $lense = 0;
[25]976 if ( file_exists( "stderr" ) )
[35]977 {
978 $lense = filesize( "stderr" );
979 if ( $lense > 1000000 )
980 { // Replace exceptionally large stderr with smaller version
981 exec( "mv stderr stderr-orig", $output, $stat );
982 exec( "head -n 5000 stderr-orig >stderr-h", $output, $stat );
983 exec( "tail -n 5000 stderr-orig >stderr-t", $output, $stat );
984 exec( "cat stderr-h stderr-t >stderr", $output, $stat );
985 }
[25]986 $stderr = file_get_contents( "stderr" );
987 }
988 else
[35]989 {
[25]990 $stderr = "";
[35]991 }
992
[1]993 if ( file_exists( "stdout" ) ) $stdout = file_get_contents( "stdout" );
[35]994
[25]995 $fn1_tarfile = "analysis-results.tar";
996 $fn2_tarfile = "output/" . $fn1_tarfile;
997 if ( file_exists( $fn1_tarfile ) )
998 $tarfile = file_get_contents( $fn1_tarfile );
999 else if ( file_exists( $fn2_tarfile ) )
1000 $tarfile = file_get_contents( $fn2_tarfile );
[1]1001
[35]1002// $lense = strlen( $stderr );
1003// if ( $lense > 1000000 )
1004// { // Replace exceptionally large stderr with smaller version
1005// exec( "mv stderr stderr-orig", $output, $stat );
1006// exec( "head -n 5000 stderr-orig >stderr-h", $output, $stat );
1007// exec( "tail -n 5000 stderr-orig >stderr-t", $output, $stat );
1008// exec( "cat stderr-h stderr-t >stderr", $output, $stat );
1009// $stderr = file_get_contents( "stderr" );
1010// }
[25]1011$lene = strlen( $stderr );
1012write_log( "$me: stderr size: $lene (was $lense)");
1013$leno = strlen( $stdout );
1014write_log( "$me: stdout size: $leno");
[35]1015$lent = strlen( $tarfile );
1016write_log( "$me: tarfile size: $lent");
1017 $esstde = mysqli_real_escape_string( $gfac_link, $stderr );
1018 $esstdo = mysqli_real_escape_string( $gfac_link, $stdout );
1019 $estarf = mysqli_real_escape_string( $gfac_link, $tarfile );
1020$lene = strlen($esstde);
1021write_log( "$me: es-stderr size: $lene");
1022$leno = strlen($esstdo);
1023write_log( "$me: es-stdout size: $leno");
[25]1024$lenf = strlen($estarf);
[35]1025write_log( "$me: es-tarfile size: $lenf");
[1]1026 $query = "UPDATE analysis SET " .
[35]1027 "stderr='" . $esstde . "'," .
1028 "stdout='" . $esstdo . "'," .
1029 "tarfile='" . $estarf . "'";
[1]1030
[35]1031 $result = mysqli_query( $gfac_link, $query );
[1]1032
1033 if ( ! $result )
1034 {
[35]1035 write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
[1]1036 echo "Bad query\n";
1037 return( -1 );
1038 }
1039}
1040?>
Note: See TracBrowser for help on using the repository browser.