source: branches/1.0/web/addons/job_monarch/libtoga.php @ 934

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

libtoga.php:

  • allow searchDbase query to include running jobs

templates/search.tpl:

  • added "include running jobs" checkbox

search.php:

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