source: trunk/web/addons/job_monarch/libtoga.php @ 651

Last change on this file since 651 was 651, checked in by ramonb, 14 years ago
  • PHP4 fixes
File size: 57.6 KB
Line 
1<?php
2/*
3 *
4 * This file is part of Jobmonarch
5 *
6 * Copyright (C) 2006  Ramon Bastiaans
7 *
8 * Jobmonarch is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * Jobmonarch is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21 *
22 * SVN $Id: libtoga.php 531 2008-07-08 09:04:51Z ramonb $
23 *
24 */
25
26
27class HTTPVariables
28{
29        var $clustername, $metricname;
30        var $restvars, $httpvars;
31
32        function HTTPVariables( $httpvars, $getvars )
33        {
34                $this->restvars         = array();
35
36                $this->clustername      = isset( $httpvars['c'] ) ? $httpvars['c'] : $getvars['c'];
37                $this->metricname       = isset( $httpvars['m'] ) ? $httpvars['m'] : $getvars['m'];
38
39                if( count( $httpvars ) > 0 )
40                {
41                        foreach( $httpvars as $httpvar => $httpval )
42                        {
43                                if( $httpval )
44                                {
45                                        $this->restvars[$httpvar] = $httpval;
46                                }
47                        }
48                }
49
50                if( count( $getvars ) > 0 )
51                {
52                        foreach( $getvars as $getvar => $getval )
53                        {
54                                if( $getval )
55                                {
56                                        $this->restvars[$getvar] = $getval;
57                                }
58                        }
59                }
60        }
61
62        function getClusterName()
63        {
64                return $this->clustername;
65        }
66
67        function getMetricName()
68        {
69                return $this->metricname;
70        }
71
72        function getHttpVar( $var )
73        {
74                if( isset( $this->restvars[$var] ) )
75                {
76                        return $this->restvars[$var];
77                }
78                else
79                {
80                        return null;
81                }
82        }
83}
84
85$CLUSTER_CONFS  = array();
86
87ini_set("memory_limit","1024000000");
88set_time_limit(0);
89
90// Monarch's conf
91//
92include_once "./conf.php";
93include_once "./version.php";
94
95global $GANGLIA_PATH;
96global $RRDTOOL;
97global $JOB_ARCHIVE_DIR;
98global $JOB_ARCHIVE_DBASE;
99global $skan_str;
100global $x_first, $y_first;
101global $CLUSTER_CONFS;
102
103$my_dir = getcwd();
104
105// Load Ganglia's PHP
106chdir( $GANGLIA_PATH );
107
108include_once "./conf.php";
109include_once "./functions.php";
110include_once "./ganglia.php";
111include_once "./get_context.php";
112
113$context = 'cluster';
114include_once "./get_ganglia.php";
115
116// Back to our PHP
117chdir( $my_dir );
118
119global $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH, $DATA_SOURCE, $HTTP_GET_VARS, $_GET;
120$httpvars = new HTTPVariables( $HTTP_GET_VARS, $_GET );
121
122// Set cluster context so that Ganglia will
123// provide us with the correct metrics array
124//
125global $context, $clustername, $reports, $always_timestamp, $always_constant;
126
127global $default_metric;
128
129// Ganglia's array of host metrics
130//
131global $metrics, $hosts_up;
132global $range, $start;
133
134global $DATETIME_FORMAT;
135
136function makeDate( $time )
137{
138        global $DATETIME_FORMAT;
139        return strftime( $DATETIME_FORMAT, $time );
140}
141
142class SessionHandler
143{
144        var $cluster, $poll_stored;
145
146        function SessionHandler( $cluster )
147        {
148                $this->cluster          = $cluster;
149                $this->ds               = new DataSource( $this->cluster );
150
151                //ob_start();
152                session_start();
153        }
154
155        function refreshSession()
156        {
157                $ds                     = &$this->ds;
158                $myxml_data             = $ds->getData();
159
160                $_SESSION['data']               = &$myxml_data;
161                $_SESSION['gather_time']        = time();
162        }
163
164        function hasSession()
165        {
166                return ( $this->have_session );
167        }
168
169        function getSession()
170        {
171                return $_SESSION;
172
173        }
174
175        function endSession()
176        {
177                session_write_close();
178                //ob_end_flush();
179                //session_unlock();
180                //session_destroy();
181        }
182
183        function updatePollInterval( $poll_interval )
184        {
185                //if( ! isset( $_SESSION['poll_interval'] ) )
186                //{
187                        $_SESSION['poll_interval']      = $poll_interval;
188                //}
189        }
190
191        function checkSession()
192        {
193                // I got nothing; create session
194                //
195                //if( ! $this->have_session )
196                //{
197                //      $this->refreshSession();
198                //
199                //      return 0;
200                //}
201
202                //if( $this->poll_stored )
203                //{
204                //      session_start();
205
206                        if( isset( $_SESSION['gather_time'] ) && isset( $_SESSION['poll_interval'] ) )
207                        {
208
209                                $gather_time    = $_SESSION['gather_time'];
210                                $poll_interval  = $_SESSION['poll_interval'];
211
212                                // If poll_interval time elapsed since last update; recreate session
213                                //
214                                if( (time() - $gather_time) >= $poll_interval )
215                                {
216                                        $this->refreshSession();
217                                }
218                        }
219                        else
220                        {
221                                $this->refreshSession();
222                        }
223                //}
224        }
225}
226
227class TarchDbase
228{
229        var $ip, $dbase, $conn;
230
231        function TarchDbase( $ip = null, $dbase = null )
232        {
233                global $CLUSTER_CONFS, $clustername;
234                global $JOB_ARCHIVE_DBASE;
235
236                // Import cluster specific settings
237                //
238                foreach( $CLUSTER_CONFS as $confcluster => $conffile )
239                {
240                        if( strtolower( trim($this->clustername) ) == strtolower(trim($confcluster)) )
241                        {
242                                include_once $conffile;
243                        }
244                }
245
246                $db_fields = explode( '/', $JOB_ARCHIVE_DBASE );
247
248                $this->ip       = $db_fields[0];
249                $this->dbase    = $db_fields[1];
250                $this->conn     = null;
251        }
252
253        function connect()
254        {
255                if( $this->ip == null )
256                        $this->conn = pg_connect( "dbname=".$this->dbase );
257                else
258                        $this->conn = pg_connect( "host=".$this->ip." dbname=".$this->dbase );
259        }
260
261        function searchDbase( $id = null, $queue = null, $user = null, $name = null, $start_from_time = null, $start_to_time = null, $end_from_time = null, $end_to_time = null )
262        {
263                global $SEARCH_RESULT_LIMIT;
264
265                if( $id )
266                {
267                        $select_query = "SELECT job_id FROM jobs WHERE job_id = '$id' AND job_status = 'F'";
268                        $this->resultcount = 1;
269                }
270                else
271                {
272                        $query_args = array();
273                       
274                        if( $queue )
275                        {
276                                $query_args[] = "job_queue ='$queue'";
277                        }
278                        if( $user )
279                        {
280                                $query_args[] = "job_owner ='$user'";
281                        }
282                        if( $name )
283                        {
284                                $query_args[] = "job_name = '$name'";
285                        }
286                        if( $start_from_time )
287                        {
288                                $query_args[] = "job_start_timestamp >= $start_from_time";
289                        }
290                        if( $start_to_time )
291                        {
292                                $query_args[] = "job_start_timestamp <= $start_to_time";
293                        }
294                        if( $end_from_time )
295                        {
296                                $query_args[] = "job_stop_timestamp >= $end_from_time";
297                        }
298                        if( $end_to_time )
299                        {
300                                $query_args[] = "job_stop_timestamp <= $end_to_time";
301                        }
302
303                        $query = "FROM jobs WHERE job_status = 'F' AND ";
304                        $extra_query_args = '';
305
306                        foreach( $query_args as $myquery )
307                        {
308                                if( $extra_query_args == '' )
309                                {
310                                        $extra_query_args = $myquery;
311                                }
312                                else
313                                {
314                                        $extra_query_args .= " AND ".$myquery;
315                                }
316                        }
317                        $query .= $extra_query_args;
318
319                        $count_result_idname = "COUNT(job_id)";
320                        $select_result_idname = "job_id";
321
322                        $count_query = "SELECT " . $count_result_idname . " " . $query;
323
324                        $count_result = $this->queryDbase( $count_query );
325                        $this->resultcount = (int) $count_result[0]['count'];
326
327                        $select_query = "SELECT " . $select_result_idname . " " . $query . " ORDER BY job_id DESC LIMIT " . $SEARCH_RESULT_LIMIT;
328                }
329
330                $ids = $this->queryDbase( $select_query );
331
332                $ret = array();
333
334                foreach( $ids as $crow)
335                {
336                        $ret[] = $crow['job_id'];
337                }
338
339                return $ret;
340        }
341
342        function getNodesForJob( $jobid )
343        {
344                $result = $this->queryDbase( "SELECT node_id FROM job_nodes WHERE job_id = '$jobid'" );
345
346                $nodes = array();
347
348                foreach( $result as $result_row ) 
349                {
350                        $nodes[] = $this->getNodeArray( $result_row['node_id'] );
351                }
352
353                return $nodes;
354        }
355
356        function getJobsForNode( $nodeid )
357        {
358                $result = $this->queryDbase( "SELECT job_id FROM job_nodes WHERE node_id = '$nodeid'" );
359
360                $jobs = array();
361
362                foreach( $result as $result_row )
363                {
364                        $jobs[] = $this->getJobArray( $result_row['job_id'] );
365                }
366                return $jobs;
367        }
368
369        function getJobArray( $id )
370        {
371                $result = $this->queryDbase( "SELECT * FROM jobs WHERE job_id = '$id'" );
372
373                return ( $this->makeArray( $result[0] ) );
374        }
375
376        function getNodeArray( $id )
377        {
378                $result = $this->queryDbase( "SELECT * FROM nodes WHERE node_id = '$id'" );
379
380                return ( $this->makeArray( $result[0] ) );
381        }
382
383        function makeArray( $result_row )
384        {
385                $myar = array();
386
387                foreach( $result_row as $mykey => $myval )
388                {
389                        $map_key = explode( '_', $mykey );
390
391                        $rmap_key = array_reverse( $map_key );
392                        array_pop( $rmap_key );
393                        $map_key = array_reverse( $rmap_key );
394                       
395                        $newkey = implode( '_', $map_key );
396                       
397                        $myar[$newkey] = $result_row[$mykey];
398                }
399
400                return $myar;
401        }
402
403        function queryDbase( $query )
404        {
405                $result_rows = array();
406       
407                if( !$this->conn )
408                {
409                        $this->connect();
410                }
411
412                $result = pg_query( $this->conn, $query );
413
414                while ($row = pg_fetch_assoc($result))
415                {
416                        $result_rows[] = $row;
417                }
418
419                return $result_rows;
420        }
421}
422
423class TarchRrdGraph
424{
425        var $rrdbin, $rrdvalues, $clustername, $hostname, $tempdir, $tarchdir, $metrics;
426
427        function TarchRrdGraph( $clustername, $hostname )
428        {
429                global $RRDTOOL;
430                global $JOB_ARCHIVE_DIR;
431
432                $this->rrdbin           = $RRDTOOL;
433                $this->rrdvalues        = array();
434                $this->tarchdir         = $JOB_ARCHIVE_DIR;
435                $this->clustername      = $clustername;
436                $this->hostname         = $hostname;
437        }
438
439        function doCmd( $command )
440        {
441                $pipe = popen( $command . ' 2>&1', 'r' );
442
443                if (!$pipe)
444                {
445                        print "pipe failed.";
446                        return "";
447                }
448
449                $output = '';
450
451                while(!feof($pipe))
452                {
453                        $output .= fread($pipe, 1024);
454                }
455
456                pclose($pipe);
457
458                $output = explode( "\n", $output );
459
460                return $output;
461        }
462
463        function dirList( $dir )
464        {
465                $dirlist = array();
466
467                if ($handle = opendir( $dir ))
468                {
469                        while (false !== ($file = readdir($handle)))
470                        {
471                                if ($file != "." && $file != "..")
472                                {
473                                        $dirlist[] = $file;
474                                }
475                        }
476                        closedir($handle);
477                }
478
479                return $dirlist;
480        }
481
482        function getTimePeriods( $start, $end )
483        {
484                $times = array();
485                $dirlist = $this->dirList( $this->tarchdir . '/' . $this->clustername . '/' . $this->hostname );
486
487                $first = 0;
488                $last = 9999999999999;
489
490                foreach( $dirlist as $dir )
491                {
492                        if( $dir > $first and $dir <= $start )
493                        {
494                                $first = $dir;
495                        }
496                        if( $dir < $last and $dir >= $end )
497                        {
498                                $last = $dir;
499                        }
500                }
501
502                foreach( $dirlist as $dir )
503                {
504                        if( $dir >= $first and $dir <= $last and !array_key_exists( $dir, $times ) )
505                        {
506                                $times[] = $dir;
507                        }
508                }
509
510                sort( $times );
511
512                return $times;
513        }
514
515        function getRrdDirs( $start, $stop )
516        {
517                $timess = $this->getTimePeriods( $start, $stop );
518
519                $rrd_files = array();
520
521                foreach( $timess as $time )
522                {
523                        $rrd_files[] = $this->tarchdir . '/' . $this->clustername . '/' . $this->hostname. '/'.$time;
524                }
525
526                return $rrd_files;
527        }
528
529        function getRrdFiles( $metric, $start, $stop )
530        {
531                $times = $this->getTimePeriods( $start, $stop );
532
533                $rrd_files = array();
534
535                foreach( $times as $time )
536                {
537                        $rrd_files[] = $this->tarchdir . '/' . $this->clustername . '/' . $this->hostname . '/' .$time. '/' . $metric. '.rrd';
538                }
539
540                return $rrd_files;
541        }
542}
543
544class DataSource
545{
546        var $data, $ip, $port;
547
548        function DataSource( $cluster )
549        {
550                global $DATA_SOURCE;
551
552                $ds_fields      = explode( ':', $DATA_SOURCE );
553
554                $ds_ip          = $ds_fields[0];
555                $ds_port        = $ds_fields[1];
556
557                $this->ip       = $ds_ip;
558                $this->port     = $ds_port;
559                $this->cluster  = $cluster;
560        }
561
562        function getData()
563        {
564                $errstr         = '';
565                $errno          = 0;
566                $timeout        = 3;
567
568                $fp = fsockopen( $this->ip, $this->port, $errno, $errstr, $timeout );
569
570                if( !$fp )
571                {
572                        echo 'Unable to connect to '.$this->ip.':'.$this->port; // printf( 'Unable to connect to [%s:%.0f]', $this->ip, $this->port );
573                        return;
574                }
575
576                $clustername    = $this->cluster;
577
578                $rc = fputs($fp, "/$clustername"."\n" );
579
580                if (!$rc)
581                {
582                        echo "Could not sent request to gmetad: $errstr";
583                        return;
584                }
585
586                stream_set_timeout( $fp, 30 );
587
588                $data   = '';
589
590                while ( !feof( $fp ) )
591                {
592                        $data .= fread( $fp, 16384 );
593                }
594
595                fclose( $fp );
596
597                return $data;
598        }
599}
600
601class DataGatherer
602{
603        var $xmlhandler, $data, $httpvars;
604
605        function DataGatherer( $cluster )
606        {
607                $this->cluster  = $cluster;
608                //$this->httpvars = $httpvars;
609        }
610
611        function parseXML( $data )
612        {
613                //$this->parser                 = xml_parser_create();
614                $this->xmlhandler       = new TorqueXMLHandler( $this->cluster );
615
616                preg_match_all( '/<HOST (.*)?>/', $data, $hosts );
617                unset( $hosts[1] );
618                preg_match_all( '/<METRIC NAME="MONARCH-(.*)?\>/', $data, $metrics );
619                unset( $metrics[1] );
620
621                //print_r( $metrics );
622                //print_r( $hosts );
623
624                $togas  = $metrics[0];
625
626                //print_r( $togas );
627
628                foreach( $togas as $mid=>$metric )
629                {
630                //      printf( "%s\n", $metric );
631                        preg_match( '/<METRIC NAME="MONARCH-(.*?)" VAL="(?<toga>\d+)" /', $metric, $toga );
632                        //print_r( $toga );
633                }
634
635                //xml_parser_set_option( $this->parser, XML_OPTION_CASE_FOLDING, 0 );
636                //xml_parser_set_option( $this->parser, XML_OPTION_SKIP_WHITE, 1 );
637                //xml_set_element_handler( $this->parser, array( &$this->xmlhandler, 'startElement' ), array( &$this->xmlhandler, 'stopElement' ) );
638
639                //if ( !xml_parse( $this->parser, $data ) )
640                //{
641                //      $error = sprintf( 'XML error: %s at %d', xml_error_string( xml_get_error_code( $this->parser ) ), xml_get_current_line_number( $this->parser ) );
642                //}
643                //xml_parser_free( $this->parser );
644        }
645
646        function getPollInterval()
647        {
648                $handler = $this->xmlhandler;
649                //printf("d i %s\n", $handler->getPollInterval() );
650
651                return $handler->getPollInterval();
652        }
653
654        function printInfo()
655        {
656                $handler = $this->xmlhandler;
657                $handler->printInfo();
658        }
659
660        function getUsingFQDN()
661        {
662                $handler = $this->xmlhandler;
663                return $handler->getUsingFQDN();
664        }
665
666        function getNodes()
667        {
668                $handler = $this->xmlhandler;
669                return $handler->getNodes();
670        }
671
672        function getNode( $node )
673        {
674                $handler = $this->xmlhandler;
675                return $handler->getNode( $node );
676        }
677
678        function getCpus()
679        {
680                $handler = $this->xmlhandler;
681                return $handler->getCpus();
682        }
683
684        function getJobs()
685        {
686                $handler = &$this->xmlhandler;
687                return ( $handler->getJobs() );
688        }
689
690        function getJob( $job )
691        {
692                $handler = $this->xmlhandler;
693                return $handler->getJob( $job );
694        }
695
696        function getHeartbeat()
697        {
698                $handler = $this->xmlhandler;
699                return $handler->getHeartbeat();
700        }
701
702        function isJobmonRunning()
703        {
704                $handler = $this->xmlhandler;
705                return $handler->isJobmonRunning();
706        }
707}
708
709class TorqueXMLHandler
710{
711        var $clusters, $heartbeat, $nodes, $jobs, $clustername, $proc_cluster;
712
713        function TorqueXMLHandler( $clustername )
714        {
715                $jobs                   = array();
716                $clusters               = array();
717                $this->nodes            = array();
718                $heartbeat              = array();
719                $down_nodes             = array();
720                $offline_nodes          = array();
721                $this->clustername      = $clustername;
722                $this->fqdn             = 0;
723                $this->fqdnFound        = 0;
724                $this->pollinterval     = 0;
725        }
726
727        function getPollInterval()
728        {
729                //printf( "t pi %s\n", $this->pollinterval );
730                return ( $this->pollinterval );
731        }
732
733        function getUsingFQDN()
734        {
735                return $this->fqdn;
736        }
737
738        function getCpus()
739        {
740                $cpus = 0;
741
742                if( isset( $this->jobs ) && count( $this->jobs ) > 0 )
743                {
744                        foreach( $this->jobs as $jobid=>$jobattrs )
745                        {
746                                $nodes  = count( $jobattrs['nodes'] );
747                                $ppn    = (int) $jobattrs['ppn'] ? $jobattrs['ppn'] : 1;
748                                $mycpus = $nodes * $ppn;
749
750                                $cpus   = $cpus + $mycpus;
751                        }
752                }
753        }
754
755        function isJobmonRunning()
756        {
757                if (isset( $this->heartbeat['time'] ))
758                {
759                        return true;
760                }
761                else
762                {
763                        return false;
764                }
765        }
766
767        function makeHostname( $thostname, $tdomain=null )
768        {
769                // Should hostname be FQDN or short w/o domain
770                //
771                //$nodes = &$this->nodes;
772
773                $domain_len     = 0 - strlen( $tdomain );
774       
775                if( $tdomain && $this->fqdn )
776                {
777                        if( substr( $thostname, $domain_len ) != $tdomain )
778                        //if( strpos( $thostname, $tdomain ) !== false )
779                        {
780                                $thostname = $thostname . '.'.$tdomain;
781                        } 
782                }
783
784                return $thostname;
785        }
786
787        function startElement( $parser, $name, $attrs )
788        {
789                $jobs   = $this->jobs;
790                $nodes  = $this->nodes;
791
792                if ( $attrs['TN'] )
793                {
794                        // Ignore dead metrics. Detect and mask failures.
795                        if ( $attrs['TN'] > $attrs['TMAX'] * 4 )
796                        {
797                                return;
798                        }
799                }
800
801                $jobid = null;
802
803                //if( $name == 'CLUSTER' )
804                //{
805                //      $this->proc_cluster = $attrs['NAME'];
806                //}
807                //else if( $name == 'HOST' and $this->proc_cluster == $this->clustername)
808                if( $name == 'HOST' )
809                {
810                        $hostname = $attrs['NAME'];
811
812                        // Assume to use FQDN if we find a '.' in the hostname
813                        //
814                        if( strpos( $hostname, '.' ) !== false )
815                        {
816                                if( !$this->fqdnFound )
817                                {
818                                        $this->fqdn             = 1;
819                                        $this->fqdnFound        = 1;
820                                }
821                        }
822                        else
823                        {
824                                if( !$this->fqdnFound )
825                                {
826                                        $this->fqdn             = 0;
827                                        $this->fqdnFound        = 1;
828                                }
829                        }
830
831                        $location = $attrs['LOCATION'];
832
833                        if( !isset( $nodes[$hostname] ) )
834                        {
835                                $nodes[$hostname] = new NodeImage( $this->proc_cluster, $hostname );
836                        }
837                }
838                //else if( $name == 'METRIC' and strstr( $attrs['NAME'], 'MONARCH' ) and $this->proc_cluster == $this->clustername )
839                else if( ($name == 'METRIC') && (strpos( $attrs['NAME'], 'MONARCH' ) !== false) )
840                {
841                        if( strpos( $attrs['NAME'], 'MONARCH-HEARTBEAT' ) !== false )
842                        {
843                                $this->heartbeat['time'] = $attrs['VAL'];
844                        }
845                        else if( strpos( $attrs['NAME'], 'MONARCH-DOWN' ) !== false)
846                        {
847                                $fields         = explode( ' ', $attrs['VAL'] );
848
849                                $nodes_down     = array();
850                                $down_domain    = null;
851
852                                foreach( $fields as $f )
853                                {
854                                        $togavalues     = explode( '=', $f );
855
856                                        $toganame       = $togavalues[0];
857                                        $togavalue      = $togavalues[1];
858
859
860                                        if( $toganame == 'nodes' )
861                                        {
862                                                $mynodes = explode( ';', $togavalue );
863
864                                                foreach( $mynodes as $node )
865                                                {
866                                                        $nodes_down[] = $node;
867                                                }
868                                        }
869                                        else if( $toganame == 'domain' )
870                                        {
871                                                $down_domain = $togavalue;
872                                        }
873                                        else if( $toganame == 'reported' )
874                                        {
875                                                if( !isset( $this->down_nodes['heartbeat'] ) )
876                                                {
877                                                        $this->down_nodes[$togavalue]   = array( $nodes_down, $down_domain );
878                                                }
879                                        }
880                                }
881                                $down_nodes     = $nodes_down;
882
883                                foreach( $down_nodes as $node )
884                                {
885                                        $nodes_down[] = $this->makeHostname( $node, $down_domain );
886                                }
887                        }
888                        else if( strpos( $attrs['NAME'], 'MONARCH-OFFLINE' ) !== false )
889                        {
890                                $fields         = explode( ' ', $attrs['VAL'] );
891
892                                $nodes_offline  = array();
893                                $offline_domain = null;
894
895                                foreach( $fields as $f )
896                                {
897                                        $togavalues     = explode( '=', $f );
898
899                                        $toganame       = $togavalues[0];
900                                        $togavalue      = $togavalues[1];
901
902                                        if( $toganame == 'nodes' )
903                                        {
904                                                $mynodes = explode( ';', $togavalue );
905
906                                                foreach( $mynodes as $node )
907                                                {
908                                                        $nodes_offline[] = $node;
909                                                }
910                                        }
911                                        else if( $toganame == 'domain' )
912                                        {
913                                                $offline_domain = $togavalue;
914                                        }
915                                        else if( $toganame == 'reported' )
916                                        {
917                                                if( !isset( $this->offline_nodes['heartbeat'] ) )
918                                                {
919                                                        $this->offline_nodes[$togavalue] = array( $nodes_offline, $offline_domain );
920                                                }
921                                        }
922                                }
923                                $offline_nodes  = $nodes_offline;
924
925                                foreach( $offline_nodes as $node )
926                                {
927                                        $nodes_offline[] = $this->makeHostname( $node, $offline_domain );
928                                }
929                        }
930                        else if( strpos( $attrs['NAME'], 'MONARCH-JOB' ) !== false )
931                        {
932                                sscanf( $attrs['NAME'], 'MONARCH-JOB-%d-%d', $jobid, $monincr );
933
934                                if( !isset( $jobs[$jobid] ) )
935                                {
936                                        $jobs[$jobid] = array();
937                                }
938
939                                $fields = explode( ' ', $attrs['VAL'] );
940
941                                foreach( $fields as $f )
942                                {
943                                        $togavalues = explode( '=', $f );
944
945                                        $toganame = $togavalues[0];
946                                        $togavalue = $togavalues[1];
947
948                                        //printf( "tn %s\n", $toganame );
949
950                                        if( $toganame == 'nodes' )
951                                        {
952                                                if( $jobs[$jobid]['status'] == 'R' )
953                                                {
954                                                        if( !isset( $jobs[$jobid][$toganame] ) )
955                                                        {
956                                                                $jobs[$jobid][$toganame] = array();
957                                                        }
958
959                                                        $mynodes = explode( ';', $togavalue );
960
961                                                        foreach( $mynodes as $node )
962                                                        {
963                                                                if( !in_array( $node, $jobs[$jobid][$toganame] ) )
964                                                                {
965                                                                        $jobs[$jobid][$toganame][] = $node;
966                                                                }
967                                                        }
968
969                                                }
970                                                else if( $jobs[$jobid]['status'] == 'Q' )
971                                                {
972                                                        $jobs[$jobid][$toganame] = $togavalue;
973                                                }
974                                        }
975                                        else if( $toganame == 'poll_interval' )
976                                        {
977                                                $this->pollinterval     = $togavalue;
978                                                //printf("u pi %s\n", $togavalue );
979                                        }
980                                        else
981                                        {
982                                                $jobs[$jobid][$toganame] = $togavalue;
983                                        }
984                                }
985
986                                if( isset( $jobs[$jobid]['nodes'] ) )
987                                {
988                                        $nr_nodes = count( $jobs[$jobid]['nodes'] );
989               
990                                        if( $jobs[$jobid]['status'] == 'R' )
991                                        {
992                                                if( isset( $jobs[$jobid]['domain'] ) )
993                                                {
994                                                        $domain         = $jobs[$jobid]['domain'];
995                                                }
996                                                $job_nodes      = array();
997
998                                                foreach( $jobs[$jobid]['nodes'] as $node )
999                                                {
1000                                                        // Only add domain name to the hostname if Ganglia is doing that too
1001                                                        //
1002                                                        $host   = $this->makeHostname( $node, $domain );
1003
1004                                                        if( !isset( $nodes[$host] ) )
1005                                                        {
1006                                                                $my_node = new NodeImage( $this->proc_cluster, $host );
1007                                                        }
1008                                                        else
1009                                                        {
1010                                                                $my_node = $nodes[$host];
1011                                                        }
1012
1013                                                        if( !$my_node->hasJob( $jobid ) )
1014                                                        {
1015                                                                if( isset( $jobs[$jobid]['ppn'] ) )
1016                                                                {
1017                                                                        $my_node->addJob( $jobid, ((int) $jobs[$jobid]['ppn']) );
1018                                                                }
1019                                                                else
1020                                                                {
1021                                                                        $my_node->addJob( $jobid, 1 );
1022                                                                }
1023                                                        }
1024
1025                                                        $nodes[$host]   = $my_node;
1026                                                        $job_nodes[]    = $host;
1027                                                }
1028                                                $jobs[$jobid]['nodes']  = $job_nodes;
1029                                        }
1030                                }
1031                        }
1032                }
1033                $this->jobs     = $jobs;
1034                $this->nodes    = $nodes;
1035        }
1036
1037        function stopElement( $parser, $name )
1038        {
1039                $nodes  = $this->nodes;
1040
1041                if( $name == "GANGLIA_XML" )
1042                {
1043                        if( sizeof( $this->down_nodes ) > 0 )
1044                        {
1045                                foreach( $this->down_nodes as $reported => $dnodes )
1046                                {
1047                                        if( $reported == $this->heartbeat['time'] )
1048                                        {
1049                                                $domain = $dnodes[1];
1050
1051                                                foreach( $dnodes[0] as $downhost )
1052                                                {
1053                                                        $downhost = $this->makeHostname( $downhost, $domain );
1054
1055                                                        if( isset( $nodes[$downhost] ) )
1056                                                        {
1057                                                                // OMG PHP4 is fking stupid!
1058                                                                // $nodes[$downhost]->setDown( 1 ) won't work here..
1059                                                                //
1060                                                                $mynode = $nodes[$downhost];
1061                                                                $mynode->setDown( 1 );
1062                                                                $nodes[$downhost] = $mynode;
1063                                                        }
1064                                                }
1065                                        }
1066                                }
1067                        }
1068
1069                        if( sizeof( $this->offline_nodes ) > 0 )
1070                        {
1071                                foreach( $this->offline_nodes as $reported => $onodes )
1072                                {
1073                                        if( $reported == $this->heartbeat['time'] )
1074                                        {
1075                                                $domain = $onodes[1];
1076
1077                                                foreach( $onodes[0] as $offlinehost )
1078                                                {
1079                                                        $offlinehost = $this->makeHostname( $offlinehost, $domain );
1080
1081                                                        if( isset( $nodes[$offlinehost] ) )
1082                                                        {
1083                                                                // OMG PHP4 is fking stupid!
1084                                                                // $nodes[$offlinehost]->setDown( 1 ) won't work here..
1085                                                                //
1086                                                                $mynode = $nodes[$offlinehost];
1087                                                                $mynode->setOffline( 1 );
1088                                                                $nodes[$offlinehost] = $mynode;
1089                                                        }
1090                                                }
1091                                        }
1092                                }
1093                        }
1094                }
1095
1096                $this->nodes = $nodes;
1097        }
1098
1099        function printInfo()
1100        {
1101                $jobs = &$this->jobs;
1102
1103                printf( "---jobs---\n" );
1104
1105                foreach( $jobs as $jobid => $job )
1106                {
1107                        printf( "job %s\n", $jobid );
1108
1109                        if( isset( $job['nodes'] ) )
1110                        {
1111                                foreach( $job['nodes'] as $node )
1112                                {
1113                                        $mynode = $this->nodes[$node];
1114                                        $hostname = $mynode->getHostname();
1115                                        $location = $mynode->getLocation();
1116
1117                                        printf( "\t- node %s\tlocation %s\n", $hostname, $location );
1118                                }
1119                        }
1120                }
1121
1122                printf( "---nodes---\n" );
1123
1124                $nodes = &$this->nodes;
1125
1126                foreach( $nodes as $node )
1127                {
1128                        $hostname = $node->getHostname();
1129                        $location = $node->getLocation();
1130                        $jobs = implode( ' ', $node->getJobs() );
1131                        printf( "* node %s\tlocation %s\tjobs %s\n", $hostname, $location, $jobs );
1132                }
1133        }
1134
1135        function getNodes()
1136        {
1137                return $this->nodes;
1138        }
1139
1140        function getNode( $node )
1141        {
1142                $nodes = &$this->nodes;
1143
1144                if( isset( $nodes[$node] ) )
1145                {
1146                        return $nodes[$node];
1147                }
1148                else
1149                {
1150                        return NULL;
1151                }
1152        }
1153
1154        function getJobs()
1155        {
1156                return $this->jobs;
1157        }
1158
1159        function getJob( $job )
1160        {
1161                $jobs = &$this->jobs;
1162
1163                if( isset( $jobs[$job] ) )
1164                {
1165                        return $jobs[$job];
1166                }
1167                else
1168                {
1169                        return NULL;
1170                }
1171        }
1172
1173        function getHeartbeat()
1174        {
1175                return $this->heartbeat['time'];
1176        }
1177}
1178
1179class NodeImage
1180{
1181        var $image, $x, $y, $hostname, $jobs, $tasks, $showinfo;
1182
1183        function NodeImage( $cluster, $hostname )
1184        {
1185                global $SMALL_CLUSTERIMAGE_NODEWIDTH;
1186
1187                $this->jobs             = array();
1188                $this->tasks            = 0;
1189                $this->hostname         = $hostname;
1190                $this->cpus             = $this->determineCpus();
1191                $this->clustername      = $cluster;
1192                $this->showinfo         = 1;
1193                $this->size             = $SMALL_CLUSTERIMAGE_NODEWIDTH;
1194                $this->down             = 0;
1195                $this->offline          = 0;
1196                $this->small            = false;
1197                $this->big              = false;
1198                $this->selected         = false;
1199        }
1200
1201        function addJob( $jobid, $cpus )
1202        {
1203                $jobs           = &$this->jobs;
1204                $jobs[]         = $jobid;
1205                $this->jobs     = $jobs;
1206
1207                $this->addTask( $cpus );
1208        }
1209
1210        function hasJob( $jobid )
1211        {
1212                $jobfound = 0;
1213
1214                if( count( $this->jobs ) > 0 )
1215                {
1216                        foreach( $this->jobs as $job )
1217                        {
1218                                if( $job == $jobid )
1219                                {
1220                                        $jobfound = 1;
1221                                }
1222                        }
1223                }
1224
1225                return $jobfound;
1226        }
1227
1228        function addTask( $cpus )
1229        {
1230                $this->tasks = $this->tasks + $cpus;
1231        }
1232        function setDown( $down )
1233        {
1234                $this->down = $down;
1235        }
1236        function isDown()
1237        {
1238                return $this->down;
1239        }
1240        function setOffline( $offline )
1241        {
1242                $this->offline = $offline;
1243        }
1244        function isOffline()
1245        {
1246                return $this->offline;
1247        }
1248        function setImage( $image )
1249        {
1250                $this->image = $image;
1251        }
1252        function setCoords( $x, $y )
1253        {
1254                $this->x = $x;
1255                $this->y = $y;
1256        }
1257        function getX()
1258        {
1259                return $this->x;
1260        }
1261        function getY()
1262        {
1263                return $this->y;
1264        }
1265
1266        function getImagemapArea()
1267        {
1268                $area_topleft           = $this->x . "," . $this->y;
1269                $area_bottomright       = ($this->x + $this->size) . "," . ($this->y + $this->size);
1270                $area_coords            = $area_topleft . "," . $area_bottomright;
1271
1272                $area_href              = "./?c=" . $this->clustername . "&h=" . $this->hostname;
1273
1274                $area_tooltip           = $this->hostname;
1275                $area_onclick           = "return ClusterImageSelectHost( '" . $this->hostname . "' )";
1276
1277                if( $this->down)
1278                {
1279                        $area_tooltip           = $area_tooltip . ": DOWN";
1280                }
1281                else if( $this->offline )
1282                {
1283                        $area_tooltip           = $area_tooltip . ": OFFLINE";
1284                }
1285
1286                $area_tooltip           = $area_tooltip . ": " . implode( " ", $this->jobs );
1287
1288                $tag_onclick            = "ONCLICK=\"" . $area_onclick . "\"";
1289                $tag_href               = "HREF=\"" . $area_href . "\"";
1290                $tag_coords             = "COORDS=\"" . $area_coords . "\"";
1291                $tag_tooltip1           = "ALT=\"" . $area_tooltip . "\"";
1292                $tag_tooltip2           = "TITLE=\"" . $area_tooltip . "\"";
1293
1294                return ("<AREA SHAPE=\"RECT\" " . $tag_coords . " " . $tag_onclick . " " . $tag_href . " " . $tag_tooltip1 . " " . $tag_tooltip2 . ">");
1295        }
1296
1297        function colorHex( $color )
1298        {
1299                $my_color = imageColorAllocate( $this->image, hexdec( substr( $color, 0, 2 )), hexdec( substr( $color, 2, 2 )), hexdec( substr( $color, 4, 2 )) );
1300
1301                return $my_color;
1302        }
1303
1304        function setLoad( $load )
1305        {
1306                $this->load = $load;
1307        }
1308
1309        function setHostname( $hostname )
1310        {
1311                $this->hostname = $hostname;
1312        }
1313
1314        function getHostname()
1315        {
1316                return $this->hostname;
1317        }
1318
1319        function getJobs()
1320        {
1321                return $this->jobs;
1322        }
1323
1324        function setShowinfo( $showinfo )
1325        {
1326                $this->showinfo = $showinfo;
1327        }
1328
1329        function setSelected()
1330        {
1331                $this->selected = true;
1332        }
1333
1334        function drawSmall()
1335        {
1336                global $SMALL_CLUSTERIMAGE_NODEWIDTH;
1337
1338                $this->size     = $SMALL_CLUSTERIMAGE_NODEWIDTH;
1339                $this->small    = true;
1340                $this->big      = false;
1341
1342                $this->draw();
1343        }
1344
1345        function drawBig()
1346        {
1347                global $BIG_CLUSTERIMAGE_NODEWIDTH;
1348
1349                $this->size     = $BIG_CLUSTERIMAGE_NODEWIDTH;
1350                $this->small    = false;
1351                $this->big      = true;
1352
1353                $this->drawShadow();
1354                $this->draw();
1355        }
1356
1357        function drawShadow()
1358        {
1359                // offset of drop shadow from top left
1360                //
1361                $ds_offset      = 5;
1362 
1363                // number of steps from black to background color
1364                //
1365                $ds_steps       = 15;
1366
1367                // distance between steps
1368                //
1369                $ds_spread = 1;
1370
1371                // define the background color
1372                //
1373                $background = array("r" => 255, "g" => 255, "b" => 255);
1374
1375                // create a new canvas.  New canvas dimensions should be larger than the original's
1376                //
1377                $width  = $this->size + $ds_offset;
1378                $height = $this->size + $ds_offset;
1379
1380                // determine the offset between colors
1381                //
1382                $step_offset = array("r" => ($background['r'] / $ds_steps), "g" => ($background['g'] / $ds_steps), "b" => ($background['b'] / $ds_steps));
1383
1384                // calculate and allocate the needed colors
1385                //
1386                $current_color = $background;
1387
1388                for ($i = 0; $i <= $ds_steps ; $i++)
1389                {
1390                        $colors[$i] = imagecolorallocate($this->image, round($current_color['r']), round($current_color['g']), round($current_color['b']));
1391
1392                        $current_color['r'] -= $step_offset['r'];
1393                        $current_color['g'] -= $step_offset['g'];
1394                        $current_color['b'] -= $step_offset['b'];
1395                }
1396
1397                // draw overlapping rectangles to create a drop shadow effect
1398                //
1399                for ($i = 3; $i < count($colors); $i++)
1400                {
1401                        imagefilledrectangle( $this->image, ($this->x + $ds_offset), ($this->y + $ds_offset), ($this->x + $width), ($this->y + $height), $colors[$i] );
1402                        $width -= $ds_spread;
1403                        $height -= $ds_spread;
1404                }
1405        }
1406
1407        function draw()
1408        {
1409                global $JOB_NODE_MARKING, $NODE_DOWN_MARKING, $NODE_OFFLINE_MARKING;
1410
1411                $black_color = imageColorAllocate( $this->image, 0, 0, 0 );
1412                $size = $this->size;
1413
1414                // seperator pixel row
1415                //
1416                $sep    = 0;
1417
1418                if( $this->big )
1419                {
1420                        $sep    = 2;
1421                }
1422
1423                $select_color   = imageColorAllocate( $this->image, 91, 255, 41 );
1424
1425                if( $this->selected )
1426                {
1427                        imageFilledRectangle( $this->image, $this->x, $this->y, $this->x+($size), $this->y+($size), $select_color );
1428                }
1429                else
1430                {
1431                        imageFilledRectangle( $this->image, $this->x, $this->y, $this->x+($size-$sep), $this->y+($size-$sep), $black_color );
1432                }
1433
1434                if( $this->showinfo)
1435                {
1436                        $this->load = $this->determineLoad();
1437
1438                        if( !isset( $this->image ) or !isset( $this->x ) or !isset( $this->y ) )
1439                        {
1440                                printf( "aborting\n" );
1441                                printf( "x %d y %d load %f\n", $this->x, $this->y, $load );
1442                                return;
1443                        }
1444
1445                        // Convert Ganglias Hexadecimal load color to a Decimal one
1446                        //
1447                        $load = $this->determineLoad(); 
1448                        $usecolor = $this->colorHex( load_color($load) );
1449                        imageFilledRectangle( $this->image, $this->x+1, $this->y+1, $this->x+($size-(1+$sep)), $this->y+($size-(1+$sep)), $usecolor );
1450                        if( $this->down )
1451                        {
1452                                imageString( $this->image, 1, $this->x+(($size/2)-1), $this->y+(($size/2)-4), $NODE_DOWN_MARKING, $black_color );
1453                        }
1454                        else if( $this->offline )
1455                        {
1456                                imageString( $this->image, 1, $this->x+(($size/2)-1), $this->y+(($size/2)-4), $NODE_OFFLINE_MARKING, $black_color );
1457                        }
1458                        else if( count( $this->jobs ) > 0 )
1459                        {
1460                                imageString( $this->image, 1, $this->x+(($size/2)-1), $this->y+(($size/2)-4), $JOB_NODE_MARKING, $black_color );
1461                        }
1462                }
1463                else
1464                {
1465                        // White
1466                        $usecolor = imageColorAllocate( $this->image, 255, 255, 255 );
1467                        imageFilledRectangle( $this->image, $this->x+1, $this->y+1, $this->x+($size-1), $this->y+($size-1), $usecolor );
1468                }
1469        }
1470
1471        function determineCpus()
1472        {
1473                global $metrics;
1474
1475                $cpus = $metrics[$this->hostname][cpu_num]['VAL'];
1476
1477                if (!$cpus)
1478                {
1479                        $cpus=1;
1480                }
1481
1482                return $cpus;
1483        }
1484
1485        function determineLoad()
1486        {
1487                global $metrics;
1488
1489                $load_one       = $metrics[$this->hostname][load_one]['VAL'];
1490                $load           = ((float) $load_one)/$this->cpus;
1491
1492                return $load;
1493        }
1494}
1495
1496class ClusterImage
1497{
1498        var $dataget, $image, $clustername;
1499        var $filtername, $filters;
1500
1501        function ClusterImage( $datag, $clustername )
1502        {
1503                //$this->dataget                = new DataGatherer( $clustername );
1504                $this->dataget          = $datag;
1505                //$this->data           = $data;
1506                $this->clustername      = $clustername;
1507                $this->filters          = array();
1508                $this->size             = 's';
1509                $this->width            = 0;
1510                $this->height           = 0;
1511                $this->output           = 1;
1512                $this->selected         = '';
1513        }
1514
1515        function getWidth()
1516        {
1517                return $this->width;
1518        }
1519        function getHeight()
1520        {
1521                return $this->height;
1522        }
1523        function setSmall()
1524        {
1525                $this->size     = 's';
1526        }
1527        function setBig()
1528        {
1529                $this->size     = 'b';
1530        }
1531        function setNoimage()
1532        {
1533                $this->output   = 0;
1534        }
1535        function isSmall()
1536        {
1537                return ($this->size == 's');
1538        }
1539        function isBig()
1540        {
1541                return ($this->size == 'b');
1542        }
1543        function setFilter( $filtername, $filtervalue )
1544        {
1545                $this->filters[$filtername] = $filtervalue;
1546        }
1547
1548        function filterNodes( $jobs, $nodes )
1549        {
1550                $filtered_nodes = array();
1551
1552                $filter_checks  = array();
1553
1554                foreach( $nodes as $node )
1555                {
1556                        $hostname       = $node->getHostname();
1557                        $mynjobs        = $node->getJobs();
1558
1559                        foreach( $this->filters as $filtername => $filtervalue )
1560                        {
1561                                $filter_checks[$filtername] = false;
1562                        }
1563
1564                        if( array_key_exists( 'host', $this->filters ) )
1565                        {
1566                                if( $hostname == $this->filters['host'] )
1567                                {
1568                                        $this->selected         = $hostname;
1569                                        $filtered_nodes[]       = $hostname;
1570                                }
1571                        }
1572
1573                        foreach( $mynjobs as $myjob )
1574                        {
1575                                foreach( $this->filters as $filtername => $filtervalue )
1576                                {
1577                                        if( $filtername == 'jid' )
1578                                        {
1579                                                if( $myjob == $filtervalue )
1580                                                {
1581                                                        $filter_checks['jid'] = true;
1582                                                }
1583                                        }
1584                                        if( $filtername == 'query' )
1585                                        {
1586                                                foreach( $jobs[$myjob] as $myj_attr => $myj_val )
1587                                                {
1588                                                        if( is_array( $myj_val ) )
1589                                                        {
1590                                                                foreach( $myj_val as $myj_v )
1591                                                                {
1592                                                                        if( strpos( $myj_v, $filtervalue ) !== false )
1593                                                                        {
1594                                                                                $filter_checks['query'] = true;
1595                                                                        }
1596                                                                }
1597                                                        }
1598                                                        else
1599                                                        {
1600                                                                if( strpos( $myj_val, $filtervalue ) !== false )
1601                                                                {
1602                                                                        $filter_checks['query'] = true;
1603                                                                }
1604                                                        }
1605                                                }
1606                                        }
1607                                        if( $filtername != 'host' )
1608                                        {
1609                                                if( $jobs[$myjob][$filtername] == $filtervalue )
1610                                                {
1611                                                        $filter_checks[$filtername] = true;
1612                                                }
1613                                        }
1614                                }
1615                        }
1616
1617                        $addhost        = true;
1618
1619                        foreach( $filter_checks as $c_filtername => $c_filterfound )
1620                        {
1621                                if( ! $c_filterfound )
1622                                {
1623                                        $addhost        = false;
1624                                }
1625                        }
1626
1627                        if( $addhost == true )
1628                        {
1629                                $filtered_nodes[] = $hostname;
1630                        }
1631                }
1632
1633                return $filtered_nodes;
1634        }
1635
1636        function draw()
1637        {
1638                global $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH;
1639                global $BIG_CLUSTERIMAGE_MAXWIDTH, $BIG_CLUSTERIMAGE_NODEWIDTH;
1640                global $CLUSTER_CONFS, $confcluster, $SHOW_EMPTY_COLUMN, $SHOW_EMPTY_ROW;
1641
1642                global $SORTBY_HOSTNAME, $SORT_ORDER, $skan_str;
1643                global $x_first, $y_first;
1644
1645                foreach( $CLUSTER_CONFS as $confcluster => $conffile )
1646                {
1647                        if( strtolower( trim($this->clustername) ) == strtolower(trim($confcluster)) )
1648                        {
1649                                include_once $conffile;
1650                        }
1651                }
1652
1653                $mydatag                = &$this->dataget;
1654                //$mydatag->parseXML( $this->data );
1655
1656                if( $this->isSmall() )
1657                {
1658                        $max_width      = $SMALL_CLUSTERIMAGE_MAXWIDTH;
1659                        $node_width     = $SMALL_CLUSTERIMAGE_NODEWIDTH;
1660                }
1661                else if( $this->isBig() )
1662                {
1663                        $max_width      = $BIG_CLUSTERIMAGE_MAXWIDTH;
1664                        $node_width     = $BIG_CLUSTERIMAGE_NODEWIDTH;
1665                }
1666
1667                $nodes          = $mydatag->getNodes();
1668                //print_r( $nodes);
1669                $nodes_hosts    = array_keys( $nodes );
1670
1671                $nodes_nr       = count( $nodes );
1672
1673                $nodes_size     = $nodes_nr*$node_width;
1674                $node_rows      = 0;
1675
1676                if( $nodes_size > $max_width )
1677                {
1678                        $nodes_per_row = ( (int) ($max_width/$node_width) );
1679                }
1680                else
1681                {
1682                        $nodes_per_row = $nodes_size;
1683                        $node_rows = 1;
1684                }
1685
1686                if( $nodes_per_row < $nodes_nr )
1687                {
1688                        $node_rows = ( (int) ($nodes_nr/$nodes_per_row) );
1689                        $node_rest = fmod( $nodes_nr, $nodes_per_row );
1690
1691                        if( $node_rest > 0 )
1692                        {
1693                                $node_rows++;
1694                        }
1695                }
1696
1697                $y_offset       = 0;
1698                $font           = 2;
1699                $fontwidth      = ImageFontWidth( $font );
1700                $fontheight     = ImageFontHeight( $font );
1701                $fontspaceing   = 2;
1702                $y_offset       = $fontheight + (2 * $fontspaceing);
1703
1704                $this->width    = $max_width;
1705                $this->height   = ($y_offset + (($node_rows*$node_width)+1) );
1706
1707                $jobs           = $mydatag->getJobs();
1708                $filtered_nodes = $this->filterNodes( $jobs, $nodes );
1709                $selected_host  = $this->selected;
1710
1711                if( $SORTBY_HOSTNAME != "" )
1712                {
1713                        $sorted         = array();
1714
1715                        $x_first        = 0;
1716                        $y_first        = 0;
1717
1718                        $skan_str       = $SORTBY_HOSTNAME;
1719
1720                        global $x_present, $y_present;
1721                        $x_present      = false;
1722                        $y_present      = false;
1723
1724                        // Should we scan by X, Y or both
1725                        //
1726                        if(strpos( $SORTBY_HOSTNAME, "{x}" ) != false )
1727                        {
1728                                $x_str          = "{x}";
1729                                $x_present      = true;
1730                        }
1731                        else if(strpos( $SORTBY_HOSTNAME, "{X}" ) != false )
1732                        {
1733                                $x_str          = "{X}";
1734                                $x_present      = true;
1735                        }
1736                        if(strpos( $SORTBY_HOSTNAME, "{y}" ) != false )
1737                        {
1738                                $y_str          = "{y}";
1739                                $y_present      = true;
1740                        }
1741                        else if(strpos( $SORTBY_HOSTNAME, "{Y}" ) != false )
1742                        {
1743                                $y_str          = "{Y}";
1744                                $y_present      = true;
1745                        }
1746
1747                        // If we should scan for both X and Y: see which one is first
1748                        //
1749                        if(( strpos( $SORTBY_HOSTNAME, $x_str ) < strpos( $SORTBY_HOSTNAME, $y_str ) ) && ( $x_present && $y_present ))
1750                        {
1751                                $x_first        = 1;
1752                        }
1753                        else if(( strpos( $SORTBY_HOSTNAME, $x_str ) > strpos( $SORTBY_HOSTNAME, $y_str ) ) && ( $x_present && $y_present ))
1754                        {
1755                                $y_first        = 1;
1756               
1757                        }
1758                        else if( $x_present )
1759                        {
1760                                $x_first        = 1;
1761                        }
1762                        else if( $y_present )
1763                        {
1764                                $y_first        = 1;
1765                        }
1766
1767                        // Turn it into a regexp /something/ search pattern
1768                        //
1769                        $skan_str       = '/' . $skan_str . '/';
1770
1771                        // Now replace our {x} and {y} with %d for sscanf parsing
1772                        //
1773                        if(( $x_first ) && ( $x_present && $y_present ) )
1774                        {
1775                                $skan_str       = str_replace( $x_str, "(?<x>\d+)", $skan_str );
1776                                $skan_str       = str_replace( $y_str, "(?<y>\d+)", $skan_str );
1777                        } 
1778                        else if( $x_present)
1779                        {
1780                                $skan_str       = str_replace( $x_str, "(?<x>\d+)", $skan_str );
1781                        }
1782                        else if( $y_present)
1783                        {
1784                                $skan_str       = str_replace( $y_str, "(?<y>\d+)", $skan_str );
1785                        }
1786
1787                        $x_min          = null;
1788                        $x_max          = null;
1789                        $y_min          = null;
1790                        $y_max          = null;
1791
1792                        $x_columns      = array();
1793                        $y_rows         = array();
1794
1795                        // Now let's walk through all our nodes and see which one are valid for our scan pattern
1796                        //
1797                        foreach( $nodes as $hostname => $node )
1798                        {
1799                                $x      = null;
1800                                $y      = null;
1801
1802                                if( $x_present && $y_present )
1803                                {
1804                                        preg_match( $skan_str, $hostname, $matches );
1805
1806                                        // Remove nodes that don't match
1807                                        //
1808                                        if( !array_key_exists( 'x', $matches ) && !array_key_exists( 'y', $matches ) )
1809                                        {
1810                                                // This node hostname has no match for: {x} and {y}
1811                                                //
1812                                                unset( $nodes[$hostname] );
1813                                        }
1814                                        else
1815                                        {
1816                                                $x      = $matches['x'];
1817                                                $y      = $matches['y'];
1818                                        }
1819                                }
1820                                else if( $x_present && !$y_present )
1821                                {
1822                                        preg_match( $skan_str, $hostname, $matches );
1823
1824                                        // Remove nodes that don't match
1825                                        //
1826                                        if( !array_key_exists( 'x', $matches ) )
1827                                        {
1828                                                // This node hostname has no match for: {x}
1829                                                //
1830                                                unset( $nodes[$hostname] );
1831                                        }
1832                                        else
1833                                        {
1834                                                $x      = $matches['x'];
1835                                                $y      = 1;
1836                                        }
1837                                }
1838                                else if( $y_present && !$x_present )
1839                                {
1840                                        preg_match( $skan_str, $hostname, $matches );
1841
1842                                        // Remove nodes that don't match
1843                                        //
1844                                        if( !array_key_exists( 'y', $matches ) )
1845                                        {
1846                                                // This node hostname has no match for: {y}
1847                                                //
1848                                                unset( $nodes[$hostname] );
1849                                        }
1850                                        else
1851                                        {
1852                                                $y      = $matches['y'];
1853                                                $x      = 1;
1854                                        }
1855                                }
1856
1857                                // Determine the lowest value of {x} that exists in all node hostnames
1858                                //
1859                                if( !$x_min && $x != null )
1860                                {
1861                                        $x_min  = $x;
1862                                }
1863                                else if( $x < $x_min && $x != null )
1864                                {
1865                                        $x_min  = $x;
1866                                }
1867
1868                                // Determine the highest value of {x} that exists in all node hostnames
1869                                //
1870                                if( !$x_max && $x != null )
1871                                {
1872                                        $x_max  = $x;
1873                                }
1874                                else if( $x > $x_max && $x != null )
1875                                {
1876                                        $x_max  = $x;
1877                                }
1878
1879                                // Determine the lowest value of {y} that exists in all node hostnames
1880                                //
1881                                if( !$y_min && $y != null )
1882                                {
1883                                        $y_min  = $y;
1884                                }
1885                                else if( $y < $y_min && $y != null )
1886                                {
1887                                        $y_min  = $y;
1888                                }
1889
1890                                // Determine the highest value of {y} that exists in all node hostnames
1891                                //
1892                                if( !$y_max && $y != null )
1893                                {
1894                                        $y_max  = $y;
1895                                }
1896                                else if( $y > $y_max && $y != null )
1897                                {
1898                                        $y_max  = $y;
1899                                }
1900
1901                                // Store which non-empty columns and rows we found
1902                                //
1903                                if( !in_array( $x, $x_columns ) )
1904                                {
1905                                        $x_columns[] = $x;
1906                                }
1907                                if( !in_array( $y, $y_rows ) )
1908                                {
1909                                        $y_rows[] = $y;
1910                                }
1911                        }
1912
1913                        // Sort all the nodes (alpha and numerically)
1914                        // 1: gb-r1n1, 2: gb-r1n2, 3: gb-r2n1, etc
1915                        //
1916                        $sorted_nodes   = usort( $nodes, "cmp" );
1917
1918                        //print_r( $x_columns ) ;
1919
1920                        $cur_node       = 0;
1921
1922                        $x_offset       = 0;
1923                        $y_offset       = 0;
1924                        $font           = 2;
1925                        $fontwidth      = ImageFontWidth( $font );
1926                        $fontheight     = ImageFontHeight( $font );
1927                        $fontspaceing   = 2;
1928
1929                        if( $this->isSmall() ) 
1930                        {
1931                                $y_offset       = $y_offset + (2 * $fontspaceing) + $fontheight;
1932                        }
1933
1934                        if( $this->isBig() ) 
1935                        {
1936                                $y_offset       = ($fontheight * (1 + strlen( $x_max) ) ) + ((2 + strlen( $x_max)) * $fontspaceing);
1937                                $x_offset       = ($fontwidth * (1 + strlen( $y_max) ) ) + ((2 + strlen( $y_max)) * $fontspaceing);
1938                        }
1939
1940                        //$image_width  = $x_offset + ($node_width * ($x_max-$x_min+2));
1941                        $image_width    = $x_offset + ($node_width * (count($x_columns)));
1942
1943                        if( $this->isSmall() ) 
1944                        {
1945                                $image_width    = $max_width;
1946                        }
1947                        else if( $this->isBig() ) 
1948                        {
1949                                $image_width    = ($image_width < $max_width) ? $image_width : $max_width;
1950                        }
1951                        $image_height   = $y_offset + ($node_width * ($y_max-$y_min+2));
1952
1953                        $this->width    = $image_width;
1954                        $this->heigth   = $image_heigth;
1955
1956                        $image          = imageCreateTrueColor( $image_width, $image_height );
1957                        $colorwhite     = imageColorAllocate( $image, 255, 255, 255 );
1958
1959                        imageFill( $image, 0, 0, $colorwhite );
1960
1961                        if( $this->isSmall() )
1962                        {
1963                                // Draw a fancy little header text to explain what it is
1964                                //
1965                                $colorblue      = imageColorAllocate( $image, 0, 0, 255 );
1966
1967                                imageString( $image, $font, 2, 2, "Monarch Joblist - cluster: ".$this->clustername, $colorblue );
1968                        }
1969
1970                        if( $this->isBig() && ( isset( $SORT_XLABEL ) || isset( $SORT_YLABEL ) ) )
1971                        {
1972                                $colorblue      = imageColorAllocate( $image, 0, 0, 255 );
1973
1974                                if( isset( $SORT_XLABEL ) )
1975                                {
1976                                        // Print the {x} label: rack
1977                                        //
1978                                        imageString( $image, $font, $x_offset, $fontspaceing, $SORT_XLABEL, $colorblue );
1979                                }
1980
1981                                if( isset( $SORT_YLABEL ) )
1982                                {
1983                                        // Stupid php without imageStringDown function... we'll make one ourself
1984                                        //
1985
1986                                        // Print the {y} label: node
1987                                        //
1988                                        imageStringDown( $image, $font, $fontspaceing, $y_offset, $SORT_YLABEL, $colorblue );
1989                                }
1990                        }
1991
1992                        $previous_n     = 0;
1993                        $previous_m     = 0;
1994                        $x_empty_count  = 0;
1995                        $y_empty_count  = 0;
1996
1997                        // Let's start assigning x,y coordinates now
1998                        //
1999                        for( $n = $x_min; $n <= $x_max; $n++ )
2000                        {
2001                                for( $m = $y_min; $m <= $y_max; $m++ )
2002                                {
2003                                        if( $x_min > 0 )
2004                                        {
2005                                                $x      = $x_offset + ( ($n-$x_min) * $node_width ) - ($x_empty_count * $node_width);
2006                                        }
2007                                        if( $y_min > 0 )
2008                                        {
2009                                                $y      = $y_offset + ( ($m-$y_min) * $node_width ) - ($y_empty_count * $node_width);
2010                                        }
2011
2012                                        // Don't show empty rows/columns if option enabled
2013                                        //
2014                                        if( !in_array( $n, $x_columns ) && !$SHOW_EMPTY_COLUMN )
2015                                        {
2016                                                // Skip to next iteration: we don't want a empty column
2017                                                //
2018                                                if( $n > $previous_n )
2019                                                {
2020                                                        $previous_n = $n;
2021                                                        $x_empty_count++;
2022                                                }
2023                                                continue;
2024                                        }
2025                                        if( !in_array( $m, $y_rows ) && !$SHOW_EMPTY_ROW )
2026
2027                                        {
2028                                                // Skip to next iteration: we don't want a empty column
2029                                                //
2030                                                if( $m > $previous_m )
2031                                                {
2032                                                        $previous_m = $m;
2033                                                        $y_empty_count++;
2034                                                }
2035                                                continue;
2036                                        }
2037
2038                                        if( $this->isBig() ) 
2039                                        {
2040                                                // Draw y(node) column number header
2041                                                //
2042                                                if(( $n == $x_min ) && ( isset($SORT_YLABEL) ) )
2043                                                {
2044                                                        $mfontspacing   = 1;
2045
2046                                                        $ylabel_x       = $x - ( $fontwidth * strlen( $y_max ) ) - $mfontspacing;
2047                                                        $ylabel_y       = $y;
2048
2049                                                        imageString( $image, $font, $ylabel_x, $ylabel_y, strval( $m ), $colorblue );
2050
2051                                                        $xmin_hit[$n]   = true;
2052                                                }
2053
2054                                                // Draw x(rack) column number header
2055                                                //
2056                                                if(( $m == $y_min ) && ( isset($SORT_XLABEL) ) )
2057                                                {
2058                                                        $mfontspacing   = 2;
2059                                                        $xlabel_y       = $y - ( $fontheight * strlen( $x_max ) );
2060                                                        $xlabel_x       = $x + $mfontspacing; 
2061
2062                                                        imageStringDown( $image, $font, $xlabel_x, $xlabel_y, strval( $n ), $colorblue );
2063                                                }
2064                                        }
2065
2066                                        if( isset( $nodes[$cur_node] ) ) 
2067                                        {
2068                                                $host   = $nodes[$cur_node]->getHostname();
2069
2070                                                if( $x_present && $y_present )
2071                                                {
2072                                                        //if( $x_first )
2073                                                        //{
2074                                                        //      $nn = sscanf( $host, $skan_str, $rx, $ry );
2075                                                        //}
2076                                                        //else if( $y_first )
2077                                                        //{
2078                                                        //      $nn = sscanf( $host, $skan_str, $ry, $rx );
2079                                                        //}
2080                                                        //if ( $nn < 2 )
2081                                                        //{
2082                                                        //      //printf( "skipping node %s - y present & x present + <2 x,y matchs\n", $host);
2083                                                        //      continue;
2084                                                        //}
2085
2086                                                        preg_match( $skan_str, $host, $matches );
2087                                                        $rx = $matches['x'];
2088                                                        $ry = $matches['y'];
2089
2090                                                        if( !array_key_exists( 'x', $matches ) && !array_key_exists( 'y', $matches ) )
2091                                                        {
2092                                                                //printf( "skipping node %s - y present & x present + <2 x,y matchs\n", $host);
2093                                                                continue;
2094                                                        }
2095
2096                                                        if( intval( $rx ) > $n )
2097                                                        {
2098                                                                // If x(rack) is higher than current x, skip to next x(rack)
2099                                                                //
2100                                                                $m              = $y_max + 1;
2101
2102                                                                continue;
2103                                                        }
2104                                                        if( intval( $ry ) > $m )
2105                                                        {
2106                                                                // If y(node) is higher than current y, skip to next y(node)
2107                                                                //
2108                                                                continue;
2109                                                        }
2110                                                }
2111                                                else if( $x_present )
2112                                                {
2113                                                        //$nn = sscanf( $host, $skan_str, $rx );
2114                                                        preg_match( $skan_str, $host, $matches );
2115                                                        $rx = $matches['x'];
2116                                                }
2117                                                else if( $y_present )
2118                                                {
2119                                                        //$nn = sscanf( $host, $skan_str, $ry );
2120                                                        preg_match( $skan_str, $host, $matches );
2121                                                        $ry = $matches['y'];
2122                                                }
2123
2124                                                if( !in_array( $host, $filtered_nodes ) )
2125                                                {
2126                                                        // This node has been filtered out: we only want to see certain nodes
2127                                                        //
2128                                                        $nodes[$cur_node]->setShowinfo( 0 );
2129                                                }
2130                                                else
2131                                                {
2132                                                        if( $selected_host != '' && $host == $selected_host )
2133                                                        {
2134                                                                $nodes[$cur_node]->setSelected();
2135                                                        }
2136                                                }
2137
2138                                                $nodes[$cur_node]->setCoords( $x, $y );
2139                                                $nodes[$cur_node]->setImage( $image );
2140
2141                                                if( $this->isSmall() )
2142                                                {
2143                                                        $nodes[$cur_node]->drawSmall();
2144                                                }
2145                                                else if( $this->isBig() )
2146                                                {
2147                                                        $nodes[$cur_node]->drawBig();
2148                                                }
2149
2150                                                $cur_node++;
2151                                        }
2152                                }
2153                        }
2154
2155                }
2156                else
2157                {
2158                        if( $this->isSmall() )
2159                        {
2160                                $image          = imageCreateTrueColor( $max_width, ($y_offset + (($node_rows*$node_width)+1) ) );
2161                        }
2162                        else if( $this->isBig() )
2163                        {
2164                                $image_width    = ($node_width * $nodes_nr) + 2;
2165                                $image_width    = ($image_width < $max_width) ? $image_width : $max_width;
2166                                $image          = imageCreateTrueColor( $image_width, ($y_offset + (($node_rows*$node_width)+1) ) );
2167                        }
2168                        $colorwhite     = imageColorAllocate( $image, 255, 255, 255 );
2169
2170                        imageFill( $image, 0, 0, $colorwhite );
2171
2172                        if( $this->isSmall() )
2173                        {
2174                                $colorblue      = imageColorAllocate( $image, 0, 0, 255 );
2175
2176                                imageString( $image, $font, 2, 2, "Monarch Joblist - cluster: ".$this->clustername, $colorblue );
2177                        }
2178
2179                        for( $n = 0; $n < $node_rows; $n++ )
2180                        {
2181                                for( $m = 0; $m < $nodes_per_row; $m++ )
2182                                {
2183                                        $x = ($m * $node_width);
2184                                        $y = $y_offset + ($n * $node_width);
2185
2186                                        $cur_node = ($n * $nodes_per_row) + ($m);
2187                                        $host = $nodes_hosts[$cur_node];
2188
2189                                        if( isset( $nodes[$host] ) )
2190                                        {
2191                                                $nodes[$host]->setCoords( $x, $y );
2192                                                $nodes[$host]->setImage( $image );
2193
2194                                                if( !in_array( $host, $filtered_nodes ) )
2195                                                {
2196                                                        $nodes[$host]->setShowinfo( 0 );
2197                                                }
2198
2199                                                if( $this->isSmall() )
2200                                                {
2201                                                        $nodes[$host]->drawSmall();
2202                                                }
2203                                                else if( $this->isBig() )
2204                                                {
2205                                                        $nodes[$host]->drawBig();
2206                                                }
2207                                        }
2208                                }
2209                        }
2210                }
2211       
2212                $this->nodes    = &$nodes;
2213
2214                imageColorTransparent( $image, $colorwhite );
2215
2216                if ($this->output)
2217                {
2218                        header( 'Content-type: image/png' );
2219                        imagePNG( $image );
2220                        imageDestroy( $image );
2221                }
2222        }
2223
2224        function getImagemapArea()
2225        {
2226                $clusterimage_map       = "";
2227
2228                foreach( $this->nodes as $hostname => $node )
2229                {
2230                        $node_map               = $node->getImagemapArea();
2231                        $clusterimage_map       .= $node_map;
2232                }
2233
2234                return $clusterimage_map;
2235        }
2236}
2237
2238class EmptyImage
2239{
2240        function draw()
2241        {
2242                $image          = imageCreateTrueColor( 1, 1 );
2243                $colorwhite     = imageColorAllocate( $image, 255, 255, 255 );
2244                imageFill( $image, 0, 0, $colorwhite );                         
2245
2246                header( 'Content-type: image/png' );
2247                imagePNG( $image );
2248                imageDestroy( $image );
2249        }
2250}
2251
2252class HostImage
2253{
2254        var $data_gather, $cluster, $host, $node, $image;
2255        var $headerstrlen;
2256
2257        function HostImage( $data_gather, $cluster, $host )
2258        {
2259                $this->data_gather      = $data_gather;
2260                $this->cluster          = $cluster;
2261                $this->host             = $host;
2262                $this->y_offset         = 0;
2263                $this->font             = 2;
2264                $this->fontspaceing     = 2;
2265                $this->headerstrlen     = array();
2266
2267                $this->fontheight       = ImageFontHeight( $this->font );
2268                $this->fontwidth        = ImageFontWidth( $this->font );
2269
2270                $dg                     = &$this->data_gather;
2271                $this->node             = &$dg->getNode( $this->host );
2272                $n                      = &$this->node;
2273                $this->njobs            = $n->getJobs();
2274        }
2275
2276        function drawJobs()
2277        {
2278                $dg                     = &$this->data_gather;
2279                $colorblack             = imageColorAllocate( $this->image, 0, 0, 0 );
2280
2281                for( $n = 0; $n < count( $this->njobs ); $n++ )
2282                {
2283                        $jobid                  = $this->njobs[$n];
2284                        $jobinfo                = $dg->getJob( $jobid );
2285
2286                        $xoffset                = 5;
2287                        imageString( $this->image, $this->font, $xoffset, $this->y_offset, strval( $jobid ), $colorblack );
2288
2289                        foreach( $this->headerstrlen as $headername => $headerlen )
2290                        {
2291                                if( $headername == 'nodes' )
2292                                {
2293                                        $attrval        = strval( count( $jobinfo['nodes'] ) );
2294                                }
2295                                else if( $headername == 'cpus' )
2296                                {
2297                                        if( !isset( $jobinfo['ppn'] ) )
2298                                        {
2299                                                $jobinfo['ppn'] = 1;
2300                                        }
2301
2302                                        $attrval        = strval( count( $jobinfo['nodes'] ) * intval( $jobinfo['ppn'] ) );
2303                                }
2304                                else if( $headername == 'runningtime' )
2305                                {
2306                                        $attrval        = makeTime( intval( $jobinfo['reported'] ) - intval( $jobinfo['start_timestamp'] ) );
2307                                }
2308                                else
2309                                {
2310                                        $attrval        = strval( $jobinfo[$headername] );
2311                                }
2312
2313                                imageString( $this->image, $this->font, $xoffset, $this->y_offset, $attrval, $colorblack );
2314               
2315                                $xoffset        = $xoffset + ($this->fontwidth * ( $headerlen + 1 ) );
2316                        }
2317                       
2318                        $this->newLineOffset();
2319                }
2320        }
2321
2322        function drawHeader()
2323        {
2324                $dg                     = &$this->data_gather;
2325
2326                for( $n = 0; $n < count( $this->njobs ); $n++ )
2327                {
2328                        $jobid                  = $this->njobs[$n];
2329                        $jobinfo                = $dg->getJob( $jobid );
2330
2331                        if( !isset( $this->headerstrlen['id'] ) )
2332                        {
2333                                $this->headerstrlen['id']       = strlen( strval( $jobid ) );
2334                        }
2335                        else if( strlen( strval( $jobid ) ) > $this->headerstrlen['id'] )
2336                        {
2337                                $this->headerstrlen['id']       = strlen( strval( $jobid ) );
2338                        }
2339
2340                        if( !isset( $this->headerstrlen['owner'] ) )
2341                        {
2342                                $this->headerstrlen['owner']    = strlen( strval( $jobinfo['owner'] ) );
2343                        }
2344                        else if( strlen( strval( $jobinfo['owner'] ) ) > $this->headerstrlen['owner'] )
2345                        {
2346                                $this->headerstrlen['owner']    = strlen( strval( $jobinfo['owner'] ) );
2347                        }
2348
2349                        if( !isset( $this->headerstrlen['queue'] ) )
2350                        {
2351                                $this->headerstrlen['queue']    = strlen( strval( $jobinfo['queue'] ) );
2352                        }
2353                        else if( strlen( strval( $jobinfo['queue'] ) ) > $this->headerstrlen['queue'] )
2354                        {
2355                                $this->headerstrlen['queue']    = strlen( strval( $jobinfo['queue'] ) );
2356                        }
2357
2358                        if( !isset( $jobinfo['ppn'] ) )
2359                        {
2360                                $jobinfo['ppn'] = 1;
2361                        }
2362
2363                        $cpus                   = count( $jobinfo['nodes'] ) * intval( $jobinfo['ppn'] );
2364
2365                        if( !isset( $this->headerstrlen['cpus'] ) )
2366                        {
2367                                $this->headerstrlen['cpus']     = strlen( strval( $cpus ) );
2368                        }
2369                        else if( strlen( strval( $cpus ) ) > $this->headerstrlen['cpus'] )
2370                        {
2371                                $this->headerstrlen['cpus']     = strlen( strval( $cpus ) );
2372                        }
2373
2374                        $nodes                  = count( $jobinfo['nodes'] );
2375
2376                        if( !isset( $this->headerstrlen['nodes'] ) )
2377                        {
2378                                $this->headerstrlen['nodes']    = strlen( strval( $nodes ) );
2379                        }
2380                        else if( strlen( strval( $nodes) ) > $this->headerstrlen['nodes'] )
2381                        {
2382                                $this->headerstrlen['nodes']    = strlen( strval( $nodes ) );
2383                        }
2384
2385                        $runningtime            = makeTime( intval( $jobinfo['reported'] ) - intval( $jobinfo['start_timestamp'] ) );
2386
2387                        if( !isset( $this->headerstrlen['runningtime'] ) )
2388                        {
2389                                $this->headerstrlen['runningtime']      = strlen( strval( $runningtime) );
2390                        }
2391                        else if( strlen( strval( $runningtime) ) > $this->headerstrlen['runningtime'] )
2392                        {
2393                                $this->headerstrlen['runningtime']      = strlen( strval( $runningtime) );
2394                        }
2395
2396                        if( !isset( $this->headerstrlen['name'] ) )
2397                        {
2398                                $this->headerstrlen['name']     = strlen( strval( $jobinfo['name'] ) );
2399                        }
2400                        else if( strlen( strval( $jobinfo['name'] ) ) > $this->headerstrlen['name'] )
2401                        {
2402                                $this->headerstrlen['name']     = strlen( strval( $jobinfo['name'] ) );
2403                        }
2404                }
2405
2406                $xoffset        = 5;
2407
2408                foreach( $this->headerstrlen as $headername => $headerlen )
2409                {
2410                        $colorgreen     = imageColorAllocate( $this->image, 0, 200, 0 );
2411
2412                        if( $headerlen < strlen( $headername ) )
2413                        {
2414                                $this->headerstrlen[$headername]        = strlen( $headername );
2415                        }
2416
2417                        imageString( $this->image, $this->font, $xoffset, $this->y_offset, ucfirst( $headername ), $colorgreen );
2418
2419                        $xoffset        = $xoffset + ($this->fontwidth * ( $this->headerstrlen[$headername] + 1 ) );
2420                }
2421                $this->newLineOffset();
2422        }
2423
2424        function newLineOffset()
2425        {
2426                $this->y_offset         = $this->y_offset + $this->fontheight + $this->fontspaceing;
2427        }
2428
2429        function draw()
2430        {
2431                $xlen           = 450;
2432                $ylen           = ( count( $this->njobs ) * ( $this->fontheight + $this->fontspaceing ) ) + (3 * $this->fontheight);
2433
2434                $this->image    = imageCreateTrueColor( $xlen, $ylen );
2435                $colorwhite     = imageColorAllocate( $this->image, 255, 255, 255 );
2436                imageFill( $this->image, 0, 0, $colorwhite );                         
2437
2438                $colorblue      = imageColorAllocate( $this->image, 0, 0, 255 );
2439
2440                imageString( $this->image, $this->font, 1, $this->y_offset, "Monarch Joblist - host: ".$this->host, $colorblue );
2441                $this->newLineOffset();
2442
2443                $this->drawHeader();
2444                $this->drawJobs();
2445
2446                header("Cache-Control: no-cache, must-revalidate");
2447                header("Pragma: no-cache");
2448                header( 'Content-type: image/png' );
2449                imagePNG( $this->image );
2450                imageDestroy( $this->image );
2451        }
2452}
2453
2454function imageStringDown( &$image, $font, $x, $y, &$s, &$col )
2455{
2456        $fw     = imagefontwidth( $font);
2457        $fh     = imagefontheight( $font);
2458       
2459        $fontspacing = 0;
2460
2461        $fx     = $x;
2462        $fy     = $y;
2463
2464        for( $n=0; $n<strlen( $s ); $n++ )
2465        {
2466                $myc    = $s{$n};
2467
2468                imagestring( $image, $font, $fx, $fy, $myc, $col );
2469
2470                $fy     += ($fontspacing + $fh );
2471        }
2472}
2473
2474function array_rem( $val, &$arr )
2475{
2476        // Delete val from arr
2477        //
2478        $i      = array_search( $val, $arr );
2479
2480        if( $i == false ) return false;
2481
2482        $arr    = array_merge( array_slice( $arr, 0, $i ), array_slice( $arr, $i+1, count( $arr ) ) );
2483
2484        return true;
2485}
2486
2487function cmp( $a, $b ) 
2488{
2489        global $SORT_ORDER;
2490        global $skan_str;
2491        global $x_first, $y_first;
2492        global $x_present, $y_present;
2493
2494        $a_node         = $a;
2495        $b_node         = $b;
2496        $a              = $a_node->getHostname();
2497        $b              = $b_node->getHostname();
2498
2499        if( $a == $b ) return 0;
2500
2501        $a_x            = 0;
2502        $b_x            = 0;
2503        $a_y            = 0;
2504        $b_y            = 0;
2505
2506        if( $x_present && $y_present )
2507        {
2508                //if( $x_first )
2509                //{
2510                //      $n = sscanf( $a, $skan_str, $a_x, $a_y );
2511                //      $n = sscanf( $b, $skan_str, $b_x, $b_y );
2512                //}
2513                //else if( $y_first )
2514                //{
2515                //      $n = sscanf( $a, $skan_str, $a_y, $a_x );
2516                //      $n = sscanf( $b, $skan_str, $b_y, $b_x );
2517                //}
2518
2519                preg_match( $skan_str, $a, $matches );
2520                $a_x = $matches['x'];
2521                $a_y = $matches['y'];
2522                preg_match( $skan_str, $b, $matches );
2523                $b_x = $matches['x'];
2524                $b_y = $matches['y'];
2525        } 
2526        else if( $x_present && !$y_present )
2527        {
2528                //$n = sscanf( $a, $skan_str, $a_x );
2529                //$n = sscanf( $b, $skan_str, $b_x );
2530
2531                preg_match( $skan_str, $a, $matches );
2532                $a_x = $matches['x'];
2533                preg_match( $skan_str, $b, $matches );
2534                $b_x = $matches['x'];
2535        }
2536        else if( $y_present && !$x_present )
2537        {
2538                //$n = sscanf( $a, $skan_str, $a_y );
2539                //$n = sscanf( $b, $skan_str, $b_y );
2540
2541                preg_match( $skan_str, $a, $matches );
2542                $a_y = $matches['y'];
2543                preg_match( $skan_str, $b, $matches );
2544                $b_y = $matches['y'];
2545        }
2546
2547        if ( $SORT_ORDER=="desc" )
2548        {
2549
2550                if( $x_present && $y_present )
2551                {
2552                        // 1  = a < b
2553                        // -1 = a > b
2554                        //
2555                        if ($a_x == $b_x)
2556                        {
2557                                if ($a_y < $b_y)
2558                                {
2559                                        return 1;
2560                                }
2561                                else if ($a_y > $b_y)
2562                                {
2563                                        return -1;
2564                                }
2565                        }
2566                        else if ($a_x < $b_x)
2567                        {
2568                                return 1;
2569                        }
2570                        else if ($a_x > $b_x)
2571                        {
2572                                return -1;
2573                        }
2574                } 
2575                else if( $x_present && !$y_present )
2576                {
2577                        if ($a_x < $b_x)
2578                        {
2579                                return 1;
2580                        }
2581                        else if ($a_x > $b_x)
2582                        {
2583                                return -1;
2584                        }
2585                }
2586                else if( $y_present && !$x_present )
2587                {
2588                        if ($a_y < $b_y)
2589                        {
2590                                return 1;
2591                        }
2592                        else if ($a_y > $b_y)
2593                        {
2594                                return -1;
2595                        }
2596                }
2597                else if( !$y_present && !$x_present )
2598                {
2599                        if ($a < $b)
2600                        {
2601                                return 1;
2602                        }
2603                        else if ($a > $b)
2604                        {
2605                                return -1;
2606                        }
2607                }
2608        }
2609        else if ( $SORT_ORDER == "asc" )
2610        {
2611
2612                if( $x_present && $y_present )
2613                {
2614                        // 1  = a > b
2615                        // -1 = a < b
2616                        //
2617                        if ($a_x == $b_x)
2618                        {
2619                                if ($a_y > $b_y)
2620                                {
2621                                        return 1;
2622                                }
2623                                else if ($a_y < $b_y)
2624                                {
2625                                        return -1;
2626                                }
2627                        }
2628                        else if ($a_x > $b_x)
2629                        {
2630                                return 1;
2631                        }
2632                        else if ($a_x < $b_x)
2633                        {
2634                                return -1;
2635                        }
2636                }
2637                else if( $x_present && !$y_present )
2638                {
2639                        if ($a_x > $b_x)
2640                        {
2641                                return 1;
2642                        }
2643                        else if ($a_x < $b_x)
2644                        {
2645                                return -1;
2646                        }
2647                }
2648                else if( $y_present && !$x_present )
2649                {
2650                        if ($a_y > $b_y)
2651                        {
2652                                return 1;
2653                        }
2654                        else if ($a_y < $b_y)
2655                        {
2656                                return -1;
2657                        }
2658                }
2659                else if( !$y_present && !$x_present )
2660                {
2661                        if ($a > $b)
2662                        {
2663                                return 1;
2664                        }
2665                        else if ($a < $b)
2666                        {
2667                                return -1;
2668                        }
2669                }
2670        }
2671}
2672
2673function timeToEpoch( $time )
2674{
2675        $time_fields    = explode( ':', $time );
2676
2677        if( count( $time_fields ) == 3 )
2678        {
2679                $hours          = $time_fields[0];
2680                $minutes        = $time_fields[1];
2681                $seconds        = $time_fields[2];
2682
2683        }
2684        else if( count( $time_fields ) == 2 )
2685        {
2686                $hours          = 0;
2687                $minutes        = $time_fields[0];
2688                $seconds        = $time_fields[1];
2689
2690        }
2691        else if( count( $time_fields ) == 1 )
2692        {
2693                $hours          = 0;
2694                $minutes        = 0;
2695                $seconds        = $time_fields[0];
2696        }
2697
2698        $myepoch        = intval( $seconds + (intval( $minutes * 60 )) + (intval( $hours * 3600 )) );
2699
2700        return $myepoch;
2701}
2702
2703function makeTime( $time )
2704{
2705        $days = intval( $time / 86400 );
2706        $time = ($days>0) ? $time % ($days * 86400) : $time;
2707
2708        $date_str = '';
2709        $day_str = '';
2710
2711        if( $days > 0 )
2712        {
2713                if( $days > 1 )
2714                {
2715                        $date_str .= $days . ' days';
2716                }
2717                else
2718                {
2719                        $date_str .= $days . ' day';
2720                }
2721        }
2722
2723        $hours = intval( $time / 3600 );
2724        $time = $hours ? $time % ($hours * 3600) : $time;
2725
2726        if( $hours > 0 )
2727        {
2728                if( $hours > 1 )
2729                {
2730                        $date_unit      = 'hours';
2731                }
2732                else
2733                {
2734                        $date_unit      = 'hour';
2735                }
2736
2737                if( $date_str != '' )
2738                {
2739                        $date_str .= ' ' . $hours . ' ' . $date_unit;
2740                }
2741                else
2742                {
2743                        $date_str .= $hours . ' ' . $date_unit;
2744                }
2745        }
2746
2747        $minutes = intval( $time / 60 );
2748        $seconds = $minutes ? $time % ($minutes * 60) : $time;
2749
2750        if( $minutes > 0 )
2751        {
2752                if( $minutes > 1 )
2753                {
2754                        $date_unit      = 'minutes';
2755                }
2756                else
2757                {
2758                        $date_unit      = 'minute';
2759                }
2760
2761                if( $date_str != '' )
2762                {
2763                        $date_str .= ' ' . $minutes . ' ' . $date_unit;
2764                }
2765                else
2766                {
2767                        $date_str .= $minutes . ' ' . $date_unit;
2768                }
2769        }
2770
2771        if( $seconds > 0 )
2772        {
2773                if( $seconds > 1 )
2774                {
2775                        $date_unit      = 'seconds';
2776                }
2777                else
2778                {
2779                        $date_unit      = 'second';
2780                }
2781
2782                if( $date_str != '' )
2783                {
2784                        $date_str .= ' ' . $seconds . ' ' . $date_unit;
2785                }
2786                else
2787                {
2788                        $date_str .= $seconds . ' ' . $date_unit;
2789                }
2790        }
2791
2792        return $date_str;
2793}
2794?>
Note: See TracBrowser for help on using the repository browser.