source: branches/0.4/web/addons/job_monarch/libtoga.php @ 759

Last change on this file since 759 was 759, checked in by ramonb, 11 years ago

host_view.php,
templates/host_view.tpl:

graph.php:

  • set range as title if it's not job

libtoga.php:

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