source: trunk/cleanup.php @ 35

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

mods mostly for use of mysqli

File size: 32.7 KB
Line 
1<?php
2/*
3 * cleanup.php
4 *
5 * functions relating to copying results and cleaning up the gfac DB
6 *  where the job used an Airavata interface.
7 *
8 */
9
10$email_address   = '';
11$queuestatus     = '';
12$jobtype         = '';
13$db              = '';
14$editXMLFilename = '';
15$status          = '';
16
17function aira_cleanup( $us3_db, $reqID, $gfac_link )
18{
19   global $org_domain;
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;
34   global $status;
35   global $stderr;
36   global $stdout;
37   global $tarfile;
38   global $requestID;
39   global $submit_dir;
40   $me        = 'cleanup_aira.php';
41
42   $requestID = $reqID;
43   $db = $us3_db;
44   write_log( "$me: debug db=$db; requestID=$requestID" );
45
46   $us3_link = mysqli_connect( $dbhost, $user, $passwd, $db );
47
48   if ( ! $us3_link )
49   {
50      write_log( "$me: could not connect: $dbhost, $user, $passwd, $db" );
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";
58   $result = mysqli_query( $us3_link, $query );
59
60   if ( ! $result )
61   {
62      write_log( "$me: Bad query: $query" );
63      mail_to_user( "fail", "Internal Error $requestID\n$query\n" . mysqli_error( $us3_link ) );
64      return( -1 );
65   }
66
67   list( $email_address, $investigatorGUID, $editXMLFilename ) =  mysqli_fetch_array( $result );
68
69   $query  = "SELECT personID FROM people " .
70             "WHERE personGUID='$investigatorGUID'";
71   $result = mysqli_query( $us3_link, $query );
72
73   list( $personID ) = mysqli_fetch_array( $result );
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
80   $result = mysqli_query( $us3_link, $query );
81
82   if ( ! $result )
83   {
84      write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
85      return( -1 );
86   }
87
88   if ( mysqli_num_rows( $result ) == 0 )
89   {
90      write_log( "$me: US3 Table error - No records for requestID: $requestID" );
91      return( -1 );
92   }
93
94   list( $cluster, $submittime, $queuestatus, $jobtype ) = mysqli_fetch_array( $result );
95
96   // Get the GFAC ID
97   $query = "SELECT HPCAnalysisResultID, gfacID FROM HPCAnalysisResult " .
98            "WHERE HPCAnalysisRequestID=$requestID";
99
100   $result = mysqli_query( $us3_link, $query );
101
102   if ( ! $result )
103   {
104      write_log( "$me: Bad query: $query" );
105      mail_to_user( "fail", "Internal Error $requestID\n$query\n" . mysqli_error( $us3_link ) );
106      return( -1 );
107   }
108
109   list( $HPCAnalysisResultID, $gfacID ) = mysqli_fetch_array( $result ); 
110
111   // Get data from global GFAC DB then insert it into US3 DB
112
113/*
114   $result = mysqli_select_db( $gfac_link, $gDB );
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   }
122 */
123
124   $query = "SELECT status, cluster, id FROM analysis " .
125            "WHERE gfacID='$gfacID'";
126
127   $result = mysqli_query( $gfac_link, $query );
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   
135   list( $status, $cluster, $id ) = mysqli_fetch_array( $result );
136
137   $is_us3iab  = preg_match( "/us3iab/", $cluster );
138   $is_local   = preg_match( "/-local/", $cluster );
139
140   if ( $is_us3iab  ||  $is_local )
141   {
142         $clushost = $cluster;
143         $clushost = preg_replace( "/\-local/", "", $clushost );
144         get_local_files( $gfac_link, $clushost, $requestID, $id, $gfacID );
145   }
146
147
148   $query = "SELECT id FROM analysis " .
149            "WHERE gfacID='$gfacID'";
150
151   $result = mysqli_query( $gfac_link, $query );
152
153   if ( ! $result )
154   {
155      write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
156      mail_to_user( "fail", "Internal error " . mysqli_error( $gfac_link ) );
157      return( -1 );
158   }
159
160   list( $analysisID ) = mysqli_fetch_array( $result );
161
162   // Get the request guid (LIMS submit dir name)
163   $query  = "SELECT HPCAnalysisRequestGUID FROM HPCAnalysisRequest " .
164             "WHERE HPCAnalysisRequestID = $requestID ";
165   $result = mysqli_query( $us3_link, $query );
166   
167   if ( ! $result )
168   {
169      write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
170   }
171
172   list( $requestGUID ) = mysqli_fetch_array( $result );
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";
189   $secwait    = 10;
190   $num_try    = 0;
191write_log( "$me: fn_tarfile=$fn_tarfile" );
192   while ( ! file_exists( $fn_tarfile )  &&  $num_try < 3 )
193   {
194      sleep( $secwait );
195      $num_try++;
196      $secwait   *= 2;
197write_log( "$me:  tar-exists: num_try=$num_try" );
198   }
199
200   $ofiles     = scandir( $output_dir );
201   foreach ( $ofiles as $ofile )
202   {
203      if ( preg_match( "/^.*stderr$/", $ofile ) )
204         $fn_stderr  = $ofile;
205      if ( preg_match( "/^.*stdout$/", $ofile ) )
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
214   $stderr   = '';
215   $stdout   = '';
216   $tarfile  = '';
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 );
220write_log( "$me(0):  length contents stderr,stdout,tarfile -- "
221 . strlen($stderr) . "," . strlen($stdout) . "," . strlen($tarfile) );
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   }
231
232write_log( "$me:  length contents stderr,stdout,tarfile -- "
233 . strlen($stderr) . "," . strlen($stdout) . "," . strlen($tarfile) );
234
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
245   // Save queue messages for post-mortem analysis
246   $query = "SELECT message, time FROM queue_messages " .
247            "WHERE analysisID = $analysisID " .
248            "ORDER BY time ";
249   $result = mysqli_query( $gfac_link, $query );
250
251   if ( ! $result )
252   {
253      // Just log it and continue
254      write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
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" ;
263   if ( mysqli_num_rows( $result ) > 0 )
264   {
265      while ( list( $message, $time ) = mysqli_fetch_array( $result ) )
266         $message_log .= "$time $message\n";
267   }
268
269   $query = "DELETE FROM queue_messages " .
270            "WHERE analysisID = $analysisID ";
271
272   $result = mysqli_query( $gfac_link, $query );
273
274   if ( ! $result )
275   {
276      // Just log it and continue
277      write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
278   }
279
280   $query = "SELECT queue_msg FROM analysis " .
281            "WHERE gfacID='$gfacID' ";
282
283   $result = mysqli_query( $gfac_link, $query );
284   list( $queue_msg ) = mysqli_fetch_array( $result );
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
301   $result = mysqli_query( $gfac_link, $query );
302
303   if ( ! $result )
304   {
305      // Just log it and continue
306      write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
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 );
317  // mysqli_close( $gfac_link );
318
319   /////////
320   // Insert data into HPCAnalysis
321
322   $query = "UPDATE HPCAnalysisResult SET "                              .
323            "stderr='" . mysqli_real_escape_string( $us3_link, $stderr ) . "', " .
324            "stdout='" . mysqli_real_escape_string( $us3_link, $stdout ) . "', " .
325            "queueStatus='completed' " .
326            "WHERE HPCAnalysisResultID=$HPCAnalysisResultID";
327
328   $result = mysqli_query( $us3_link, $query );
329
330   if ( ! $result )
331   {
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 ) );
334      return( -1 );
335   }
336
337   // Delete data from GFAC DB
338   $query = "DELETE from analysis WHERE gfacID='$gfacID'";
339
340   $result = mysqli_query( $gfac_link, $query );
341
342   if ( ! $result )
343   {
344      // Just log it and continue
345      write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
346   }
347
348   // Expand the tar file
349
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();
358   exec( "tar -xf analysis-results.tar 2>&1", $tar_out, $err );
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();
364   $mrecsIDs   = array();
365   $fns_used   = array();
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
382      if ( preg_match( "/mdl.tmp$/", $fn ) )
383         continue;
384
385      if ( in_array( $fn, $fns_used ) )
386         continue;
387
388      $fns_used[] = $fn;
389
390      if ( filesize( $fn ) < 100 )
391      {
392         write_log( "$me:fn is invalid $fn size filesize($fn)" );
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' );
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
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";
424         $result = mysqli_query( $us3_link, $query );
425
426         if ( ! $result )
427         {
428            write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
429         }
430
431         file_put_contents( "$output_dir/$fn", $xml );    // Copy to submit dir
432
433         $file_type = "job_stats";
434         $id        = 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' ];
445         $editGUID   = '00000000-0000-0000-0000-000000000000';
446         if ( isset( $model_data[ 'editGUID' ] ) )
447            $editGUID   = $model_data[ 'editGUID' ];
448
449         $query = "INSERT INTO noise SET "  .
450                  "noiseGUID='$noiseGUID'," .
451                  "modelGUID='$modelGUID'," .
452                  "editedDataID="                .
453                  "(SELECT editedDataID FROM editedData WHERE editGUID='$editGUID')," .
454                  "modelID=1, "             .
455                  "noiseType='$type',"      .
456                  "description='$desc',"    .
457                  "xml='" . mysqli_real_escape_string( $us3_link, $xml ) . "'";
458
459         // Add later after all files are processed: editDataID, modelID
460
461         $result = mysqli_query( $us3_link, $query );
462
463         if ( ! $result )
464         {
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 ) );
467            return( -1 );
468         }
469
470         $id        = mysqli_insert_id( $us3_link );
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      }
478
479      else if ( preg_match( "/\.mrecs/", $fn ) > 0 )  // It's an mrecs file
480      {
481         $xml         = file_get_contents( $fn );
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',"    .
497                  "xml='" . mysqli_real_escape_string( $us3_link, $xml ) . "'";
498
499         // Add later after all files are processed: editDataID, modelID
500
501         $result = mysqli_query( $us3_link, $query );
502
503         if ( ! $result )
504         {
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 ) );
507            return( -1 );
508         }
509
510         $id         = mysqli_insert_id( $us3_link );
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
519      else if ( preg_match( "/\.model/", $fn ) > 0 ) // It's a model file
520      {
521         $xml         = file_get_contents( $fn );
522         $model_data  = parse_xml( $xml, "model" );
523         $description = $model_data[ 'description' ];
524         $modelGUID   = $model_data[ 'modelGUID' ];
525         $editGUID    = $model_data[ 'editGUID' ];
526
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
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'," .
542                  "xml='" . mysqli_real_escape_string( $us3_link, $xml ) . "'";
543
544         $result = mysqli_query( $us3_link, $query );
545
546         if ( ! $result )
547         {
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 ) );
550            return( -1 );
551         }
552
553         $modelID   = mysqli_insert_id( $us3_link );
554         $id        = $modelID;
555         $file_type = "model";
556
557         $query = "INSERT INTO modelPerson SET " .
558                  "modelID=$modelID, personID=$personID";
559         $result = mysqli_query( $us3_link, $query );
560      }
561
562      else      // Undetermined type:  skip result data update
563         continue;
564
565      $query = "INSERT INTO HPCAnalysisResultData SET "       .
566               "HPCAnalysisResultID='$HPCAnalysisResultID', " .
567               "HPCAnalysisResultType='$file_type', "         .
568               "resultID=$id";
569
570      $result = mysqli_query( $us3_link, $query );
571
572      if ( ! $result )
573      {
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 ) );
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="                                                     .
589               "(SELECT editedDataID FROM model WHERE modelGUID='$modelGUID'),"    .
590               "modelID="                                                          .
591               "(SELECT modelID FROM model WHERE modelGUID='$modelGUID')"          .
592               "WHERE noiseID=$noiseID";
593
594      $result = mysqli_query( $us3_link, $query );
595
596      if ( ! $result )
597      {
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 ) );
600         return( -1 );
601      }
602   }
603
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
614      $result = mysqli_query( $us3_link, $query );
615
616      if ( ! $result )
617      {
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 ) );
620         return( -1 );
621      }
622write_log( "$me:     mrecs entry updated : mrecsID=$mrecsID" );
623   }
624//write_log( "$me:     mrecs entries updated" );
625
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 ";
632   $result = mysqli_query( $us3_link, $query );
633   
634   if ( ! $result )
635   {
636      write_log( "$me: Bad query:\n$query\n" . mysqli_error( $us3_link ) );
637   }
638   
639//   list( $requestGUID ) = mysqli_fetch_array( $result );
640//   
641//   chdir( "$submit_dir/$requestGUID" );
642//   $f = fopen( "analysis-results.tar", "w" );
643//   fwrite( $f, $tarfile );
644//   fclose( $f );
645
646   // Clean up
647//   chdir ( $work );
648   // exec( "rm -rf $gfacID" );
649
650   mysqli_close( $us3_link );
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;
672   global $db;
673   global $dbhost;
674   global $requestID;
675   global $gfacID;
676   global $editXMLFilename;
677   global $stdout;
678   global $org_domain;
679
680global $me;
681write_log( "$me mail_to_user(): sending email to $email_address for $gfacID" );
682
683   // Get GFAC status and message
684   // function get_gfac_message() also sets global $status
685   $gfac_message = get_gfac_message( $gfacID );
686   if ( $gfac_message === false ) $gfac_message = "Job Finished";
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';
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         }
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
719   $queuestatus = $subj_status;
720   $limshost    = $dbhost;
721   if ( $limshost == 'localhost' )
722   {
723      $limshost    = gethostname();
724      if ( preg_match( "/scyld/", $limshost ) )
725         $limshost    = 'alamo.uthscsa.edu';
726      else if ( ! preg_match( "/\./", $limshost ) )
727         $limshost    = $limshost . $org_domain;
728   }
729
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
753   LIMS Host       : $limshost
754   Analysis ID     : $gfacID
755   Request ID      : $requestID  ( $db )
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
764   GFAC Message    : $gfac_message
765   Stdout          : $stdout
766   ";
767
768   if ( $type != "success" ) $message .= "Grid Ctrl Error :  $msg\n";
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{
836   global $status;
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;
871   global $dbhost;
872   global $status;
873   $is_us3iab  = preg_match( "/us3iab/", $cluster );
874   $is_jetstr  = preg_match( "/jetstream/", $cluster );
875   $limshost   = $dbhost;
876   $stderr     = '';
877   $stdout     = '';
878   $tarfile    = '';
879
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
898   $remoteDir = sprintf( "$work_remote/$db-%06d", $requestID );
899//write_log( "$me: is_us3iab=$is_us3iab  remoteDir=$remoteDir" );
900
901   // Get stdout, stderr, output/analysis-results.tar
902   $output = array();
903
904   if ( $is_us3iab == 0 )
905   {
906      // For "-local", recompute remote work directory
907      $clushost = "$cluster.uthscsa.edu";
908      $lworkdir = "~us3/lims/work/local";
909      if ( $is_jetstr )
910      {
911         $clushost = "js-169-137.jetstream-cloud.org";
912         $lworkdir = "/N/us3_cluster/work/local";
913      }
914      $cmd         = "ssh us3@$clushost 'ls -d $lworkdir' 2>/dev/null";
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
920      // Figure out local working directory
921      if ( ! is_dir( "$work/$gfacID" ) ) mkdir( "$work/$gfacID", 0770 );
922      $pwd = chdir( "$work/$gfacID" );
923
924      $cmd = "scp us3@$clushost:$remoteDir/output/analysis-results.tar . 2>&1";
925
926      exec( $cmd, $output, $stat );
927      if ( $stat != 0 )
928         write_log( "$me: Bad exec:\n$cmd\n" . implode( "\n", $output ) );
929
930      $cmd = "scp us3@$clushost:$remoteDir/stdout . 2>&1";
931
932      exec( $cmd, $output, $stat );
933      if ( $stat != 0 )
934      {
935         write_log( "$me: Bad exec:\n$cmd\n" . implode( "\n", $output ) );
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
943      $cmd = "scp us3@$clushost:$remoteDir/stderr . 2>&1";
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      }
955   }
956   else
957   { // Is US3IAB or alamo-to-alamo, so just change to local work directory
958      $pwd = chdir( "$remoteDir" );
959write_log( "$me: IS US3IAB: pwd=$pwd $remoteDir");
960   }
961
962
963   // Write the files to gfacDB
964
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;
976   if ( file_exists( "stderr"  ) )
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      }
986      $stderr  = file_get_contents( "stderr" );
987   }
988   else
989   {
990      $stderr  = "";
991   }
992
993   if ( file_exists( "stdout" ) ) $stdout  = file_get_contents( "stdout" );
994
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 );
1001
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//   }
1011$lene = strlen( $stderr );
1012write_log( "$me: stderr size: $lene  (was $lense)");
1013$leno = strlen( $stdout );
1014write_log( "$me: stdout size: $leno");
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");
1024$lenf = strlen($estarf);
1025write_log( "$me:  es-tarfile size: $lenf");
1026   $query = "UPDATE analysis SET " .
1027            "stderr='"  . $esstde . "'," .
1028            "stdout='"  . $esstdo . "'," .
1029            "tarfile='" . $estarf . "'";
1030
1031   $result = mysqli_query( $gfac_link, $query );
1032
1033   if ( ! $result )
1034   {
1035      write_log( "$me: Bad query:\n$query\n" . mysqli_error( $gfac_link ) );
1036      echo "Bad query\n";
1037      return( -1 );
1038   }
1039}
1040?>
Note: See TracBrowser for help on using the repository browser.