<?php // Author: oxana.smirnova@hep.lu.se /** THIS IS THE TOP MONITOR WINDOW * Retrieves the Grid load information from the NorduGrid domain * Uses LDAP functions of PHP * * Author: O.Smirnova (May 2002) * inspired by the LDAPExplorer by T.Miao * and curses-based monitor by A.Waananen * * input: * debug level (default 0) * display range (default all) * * output: * an HTML table, containing: * - list of available clusters * per each cluster: * - total running jobs * - relative load of the cluster (ratio "running jobs"/"CPUs") * - queued jobs */ set_include_path(get_include_path().":".getcwd()."/includes".":".getcwd()."/lang"); require_once('headfoot.inc'); require_once('lmtable.inc'); require_once('comfun.inc'); require_once('toreload.inc'); require_once('ldap_purge.inc'); require_once('recursive_giis_info.inc'); require_once('emirs_info.inc'); require_once('archery.inc'); require_once('postcode.inc'); require_once('cache.inc'); // getting parameters $order = @$_GET["order"]; $display = @$_GET["display"]; $debug = @$_GET["debug"]; $lang = @$_GET["lang"]; $schema = @$_GET["schema"]; if ( !$order ) $order = "country"; if ( !$display ) $display = "all"; if ( !$debug ) $debug = 0; if ( !$lang ) $lang = "default"; // browser language if ( !$schema ) $schema = "NG"; define("FORCE_LANG",$lang); // Setting up the page itself $toppage = new LmDoc("loadmon"); $module = &$toppage->module; $strings = &$toppage->strings; $errors = &$toppage->errors; $giislist = &$toppage->giislist; $emirslist= &$toppage->emirslist; $cert = &$toppage->cert; $yazyk = &$toppage->language; $archery_list = &$toppage->archery_list; // Header table $toptit = date("Y-m-d T H:i:s"); $toppage->tabletop("<font face=\"Verdana,Geneva,Arial,Helvetica,sans-serif\">".EXTRA_TITLE." ".$toppage->title."<br><br></font>","<i>$toptit</i>"); //********************* Schema changing ****************************** $other_schema = "GLUE2"; if ( $schema == "GLUE2" ) $other_schema = "NG"; $_GET["schema"] = $other_schema; $get_options = ""; $keys = array_keys($_GET); foreach ($_GET as $key => $value) { if ( $key == $keys[0] ) { $get_options = "?"; } else { $get_options = $get_options."&"; } $get_options = $get_options."$key=$value"; } //TODO: use translate messages echo "</center>Current data rendered according to <b> $schema </b> schema.<br>"; echo "<b>Schema switching to: <a href=".$_SERVER['PHP_SELF']."$get_options>$other_schema</a></b><p><center>"; //********************** Legend - only needed for this module ********************* echo "<table width=\"100%\" border=\"0\"><tr><td>\n"; echo "<font size=\"-1\" face=\"Verdana,Geneva,Arial,Helvetica,Sans-serif,lucida\">".$errors["401"].":\n"; echo "<img src=\"./mon-icons/icon_led.php?c1=97&c2=144&c3=0\" vspace=\"1\" hspace=\"3\" border=\"0\" title=\"".$errors["305"]."\" alt=\"".$errors["305"]."\" width=\"14\" height=\"6\">".$errors["402"]." <img src=\"./mon-icons/icon_led.php?c1=176&c2=176&c3=176\" vspace=\"1\" hspace=\"3\" border=\"0\" title=\"".$errors["306"]."\" alt=\"".$errors["306"]."\">".$errors["403"]."</font>\n"; echo "</td><td>"; $sewin = popup("sestat.php",650,200,8,$lang,$debug); $discwin = popup("discover.php",700,400,9,$lang,$debug); $vostring = popup("volist.php",440,330,11,$lang,$debug); $usstring = popup("allusers.php",650,700,12,$lang,$debug); $acstring = popup("allusers.php?limit=1",500,600,12,$lang,$debug); echo "<div align=\"right\"><nobr>\n"; //******** Authorised users echo "<a href=\"$usstring\"><img src=\"./mon-icons/icon-folks.png\" width=\"24\" height=\"24\" border=\"0\" title=\"".$errors["307"]."\" alt=\"".$errors["307"]."\"></a> \n"; //******** Active users echo "<a href=\"$acstring\"><img src=\"./mon-icons/icon-run.png\" width=\"24\" height=\"24\" border=\"0\" title=\"".$errors["308"]."\" alt=\"".$errors["308"]."\"></a> \n"; //******** Search echo "<a href=\"$discwin\"><img src=\"./mon-icons/icon-look.png\" width=\"24\" height=\"24\" border=\"0\" title=\"".$errors["309"]."\" alt=\"".$errors["309"]."\"></a> \n"; //******** Storage echo "<a href=\"$sewin\"><img src=\"./mon-icons/icon-disk.png\" width=\"24\" height=\"24\" border=\"0\" title=\"".$errors["310"]."\" alt=\"".$errors["310"]."\"></a> \n"; //******** Virtual Organisations echo "<a href=\"$vostring\"><img src=\"./mon-icons/icon-vo.png\" width=\"24\" height=\"24\" border=\"0\" title=\"".$errors["311"]."\" alt=\"".$errors["311"]."\"></a>\n"; echo "</nobr></div>\n"; echo "</td></tr></table>\n"; //****************************** End of legend **************************************** // Some debug output if ( $debug ) { ob_end_flush(); ob_implicit_flush(); dbgmsg("<div align=\"left\"><b>ARC ".$toppage->getVersion()."</b></div>"); } $tcont = array(); // array with rows, to be sorted $cachefile = CACHE_LOCATION."/loadmon-$schema-".$yazyk; $tcont = get_from_cache($cachefile,120); // If cache exists, skip ldapsearch if ( !$tcont || $debug || $display != "all" ) { // Do LDAP search $tcont = array(); // Setting time limits for ldapsearch $tlim = 10; $tout = 11; if($debug) dbgmsg("<div align=\"left\"><i>:::> ".$errors["101"].$tlim.$errors["102"].$tout.$errors["103"]." <:::</i></div>"); // ldapsearch filter different for NG and GLUE2 if ( $schema == "NG" ) { $filter="(|(objectClass=".OBJ_CLUS.")(objectClass=".OBJ_QUEU."))"; } else { $filter="(|(objectclass=".GOBJ_CLUS.")(objectclass=".GOBJ_QUEU.")(objectClass=".GOBJ_MAN.")(objectClass=".GOBJ_LOC.")(objectClass=".GOBJ_CON.")(objectClass=".GOBJ_ADMD."))"; } // Array defining the attributes to be returned $lim = array( "dn", GCLU_ANAM, GCLU_ZIPC, GCLU_TCPU, GCLU_GCPU, GCLU_LCPU, GCLU_TJOB, GCLU_PQUE, GCLU_SUPP, GCLU_OWNR, GQUE_NAME, GQUE_MAPQ, GQUE_STAT, GQUE_QUED, GQUE_LQUE, GQUE_PQUE, GQUE_RUNG, GQUE_LRUN, CLU_ANAM, CLU_ZIPC, CLU_TCPU, CLU_UCPU, CLU_TJOB, CLU_QJOB, CLU_PQUE, QUE_STAT, QUE_GQUE, QUE_QUED, QUE_LQUE, QUE_PQUE, QUE_RUNG, QUE_GRUN ); // Adjusting cluster display filter $showvo = ""; if ( substr($display,0,2) == "vo" ) { $showvo = substr(strrchr($display,"="),1); if ($debug) dbgmsg("<b> ::: ".$errors["105"]."$showvo</b>"); } if ( $display != "all" && !$showvo ) $filter = "(&".$filstr."(".$display."))"; //========================= GET CLUSTER LIST ============================ $gentries = array(); // EGIIS if ( ! empty($giislist) ) { $ngiis = count($giislist); $ts1 = time(); $gentries = recursive_giis_info($giislist,"cluster",$errors,$debug,1); $ts2 = time(); if($debug) dbgmsg("<br><b>".$errors["106"].$ngiis." (".($ts2-$ts1).$errors["104"].")</b><br>"); } // EMIR if ( ! empty($emirslist)) $gentries = emirs_info($emirslist,"cluster",$errors,$gentries,$debug,$cert); // ARCHERY if ( ! empty($archery_list) ) $gentries = array_merge($gentries, archery_info($archery_list, $schema, $errors, $debug)); //======================================================================= $nc = count($gentries); if ( !$nc ) { // NO SITES FOUND! $errno = "1"; echo "<br><font color=\"red\"><b>".$errors[$errno]."</b></font>\n"; return $errno; } else { if ( $debug == 2 ) { dbgmsg("<div align=\"center\"><br><u>".$errors["119"]."cluster: ".$nc."</u><br></div>"); foreach ( $gentries as $num=>$val ) dbgmsg($val["host"].":".$val["base"]."<br>"); } } $dsarray = array (); $hnarray = array (); $pnarray = array (); $dnarray = array (); $sitetag = array (); /* a tag to skip duplicated entries */ // Purging cluster entries for ( $k = 0; $k < $nc; $k++ ) { $clhost = $gentries[$k]["host"]; $clport = $gentries[$k]["port"]; //$basedn = $gentries[$k]["base"]; // Force basedn to the selected schema if ( $schema == "GLUE2" ) { $basedn = DN_GLUE; } else { $basedn = DN_LOCAL; } $fp = @fsockopen($clhost, $clport, $errno, $errstr, 2); $ldapuri = "ldap://".$clhost.":".$clport; $clconn = ldap_connect($ldapuri); if ( $fp && $clconn && !@$sitetag[$clhost] ) { fclose($fp); array_push($dsarray,$clconn); array_push($hnarray,$clhost); array_push($pnarray,$clport); array_push($dnarray,$basedn); @ldap_set_option($clconn, LDAP_OPT_NETWORK_TIMEOUT, $tout); $sitetag[$clhost] = 1; /* filtering tag */ if ($debug==2) dbgmsg("Adding $k - <i>$clhost:$clport $basedn</i></br>"); } elseif ( $fp && $clconn && @$sitetag[$clhost] ) { if ($debug==2) dbgmsg("Skipping duplicate host entry $k - <i>$clhost:$clport $basedn</i></br>"); fclose($fp); } } $nhosts = count($dsarray); if( $debug == 2 ) dbgmsg("<BR>".$nhosts.$errors["108"]."<br>"); if ( !$nhosts ) { // NO SITES REPLY... $errno = "2"; echo "<BR><font color=\"red\"><B>".$errors[$errno]."</B></font>\n"; return $errno; } // Search all clusters and queues $ts1 = time(); $srarray = @ldap_search($dsarray,$dnarray,$filter,$lim,0,0,$tlim,LDAP_DEREF_NEVER); // If using the patched LDAP //$srarray = @ldap_search($dsarray,DN_LOCAL,$filter,$lim,0,0,$tlim,LDAP_DEREF_NEVER,$tout); $ts2 = time(); if($debug) dbgmsg("<br><b>".$errors["109"]." (".($ts2-$ts1).$errors["104"].")</b><br>"); /* * $ts1 = time(); * $qsarray = @ldap_search($dsarray,DN_LOCAL,$qfilstr,$qlim,0,0,$tlim,LDAP_DEREF_NEVER); * // Fall back to a conventional LDAP * // if ( !count($qsrarray)) $qsarray = @ldap_search($dsarray,DN_LOCAL,$qfilstr,$qlim,0,0,$tlim,LDAP_DEREF_NEVER); * $ts2 = time(); if($debug) dbgmsg("<br><b>".$errors["110"]." (".($ts2-$ts1).$errors["104"].")</b><br>"); */ // Loop on clusters for ( $ids = 0; $ids < $nhosts; $ids++ ) { $entries = array(); $jentries = array(); $gentries = array(); $rowcont = array(); $sr = $srarray[$ids]; $hn = $hnarray[$ids]; $pn = $pnarray[$ids]; $ds = $dsarray[$ids]; $nr = @ldap_count_entries($ds,$sr); if ( !$sr || !$ds || !$nr ) { $error = ldap_error($ds); if ( $error == "Success" ) $error = $errors["3"]; if ( $debug ) dbgmsg("<b><font color=\"red\">".$errors["111"]."$hn ($error)</font></b><br>"); $sr = FALSE; } if ($ds && $sr) { $entries = @ldap_get_entries($ds,$sr); // Number of LDAP objects retrieved for a given cluster // NG: nordugrid-cluster and nordugrid-queue(s) , 2+ // GLUE2: Service,Manager,Shares,Location,Contact,AdminDomain, 6+ $nobjects = $entries["count"]; if ( !$nobjects ) { if ( $debug ) dbgmsg("<b>$hn</b>:".$errors["3"]."<br>"); continue; } $nclu = 0; $nqueues = 0; $allqrun = 0; $lrmsrun = 0; $gridjobs = 0; $allqueued = 0; $gridqueued = 0; $lrmsqueued = 0; $prequeued = 0; $totgridq = 0; $toflag2 = FALSE; $stopflag = FALSE; for ($i=0; $i<$nobjects; $i++) { $curdn = $entries[$i]["dn"]; $preflength = strrpos($curdn,","); $basedn = substr($curdn,$preflength+1); $allbasedn = strtolower(substr($curdn,$preflength-17)); if ( ($schema == "GLUE2") && ($basedn == DN_GLUE ) ) { // extract objectclass name from DN -- shouldn't this be easier? $preflength = strpos($curdn,":"); $preflength = strpos($curdn,":",$preflength+1); $object = substr($curdn,$preflength+1,strpos($curdn,":",$preflength+1)-$preflength-1); if ($object=="ComputingService") { $dnparts = ldap_explode_dn($curdn,0); $endpointArray=explode(":",$dnparts[0]); $curname = $endpointArray[3]; $curport = $pn; $curalias = $entries[$i][GCLU_ANAM][0]; // Manipulate alias: replace the string if necessary and cut off at 22 characters; strip HTML tags if (file_exists("cnvalias.inc")) include('cnvalias.inc'); $curalias = strip_tags($curalias); //if alias empty (common in GLUE2 due to no real place for it in the schema), use endpoint FQDN if ( empty($curalias) ) { $curalias = $curname." Undefined)"; } if ( strlen($curalias) > 22 ) $curalias = substr($curalias,0,21) . ">"; $gmqueued = @($entries[$i][GCLU_PQUE][0]) ? $entries[$i][GCLU_PQUE][0] : 0; /* new since 0.5.38 */ // use computingmanager info instead, For some reason this number is incorrect in the rendering. Needs to be checked on infosys side. //$curtotjobs = @($entries[$i][GCLU_TJOB][0]) ? $entries[$i][GCLU_TJOB][0] : 0; $clstring = popup("clusdes.php?host=$curname&port=$curport&schema=$schema",700,620,1,$lang,$debug); $nclu++; } elseif ($object=="ComputingManager") { // All the numbers here are actually "JobSlots" and not CPUs or cores. // But I am keeping the variable names for consistency with NG. // Assumption: 1 core - 1 job slot $curtotcpu = @($entries[$i][GCLU_TCPU][0]) ? $entries[$i][GCLU_TCPU][0] : 0; if ( !$curtotcpu && $debug ) dbgmsg("<font color=\"red\"><b>$curname</b>".$errors["113"]."</font><br>"); $gridjobs = @($entries[$i][GCLU_GCPU][0]) ? $entries[$i][GCLU_GCPU][0] : 0; $lrmsrun = @($entries[$i][GCLU_LCPU][0]) ? $entries[$i][GCLU_LCPU][0] : 0; $curusedcpu = $gridjobs + $lrmsrun; if ( $curusedcpu < 0 ) $curusedcpu = -1; // I think this is not actually used anywhere, even in NG. Probably can be removed. $curtotjobs = $curusedcpu; } elseif ($object=="ComputingShare") { // GLUE2 publishes a Share for the bare queue, and as many shares as the VOs. // So here we only take the Share that holds the bare info, which is what we publish in the monitor. // TODO: find a better solution for this. Unfortunately some sites // seem to have hacked the queue EntityName or the LRMS returns a longer name that // is not being shortened by infosys. $shname = $entries[$i][GQUE_NAME][0]; $shmapq = $entries[$i][GQUE_MAPQ][0]; if ( $shname == $shmapq ) { $qstatus = $entries[$i][GQUE_STAT][0]; if ( $qstatus != "production" ) $stopflag = TRUE; // curallqueued: all queued jobs in the queue (grid + local) $curallqueued = @($entries[$i][GQUE_QUED][0]) ? ($entries[$i][GQUE_QUED][0]) : 0; $curlrmsqueued = @($entries[$i][GQUE_LQUE][0]) ? ($entries[$i][GQUE_LQUE][0]) : 0; // There is no info in GLUE2 Shares about Grid jobs, must be extracted $curgridqueued = $curallqueued - $curlrmsqueued; if ($curgridqueued < 0) $curgridqueued = 0; $gridqueued += $curgridqueued; $lrmsqueued += $curlrmsqueued; $prequeued += @($entries[$i][GQUE_PQUE][0]) ? ($entries[$i][GQUE_PQUE][0]) : 0; // Updating the total number of queued jobs $allqueued += $curallqueued; $nqueues++; }; } elseif ($object=="Location") { if ( !empty($entries[$i][GCLU_ZIPC][0]) ) $curzip = $entries[$i][GCLU_ZIPC][0]; } elseif ( $object == "AdminDomain" ) { // here we may extract the site name and add it to the cluster line as in NG but funkyer } elseif ( $object == "Contact" ) { // here we may extract the support string (usually an email) }; // This part of the code is for aggregating values from all the above GLUE2 objects if ( ($schema == "GLUE2") && ($basedn == DN_GLUE ) && ($i == ($nobjects-1))) { // Calculate country based on gathered data $dnparts = ldap_explode_dn($curdn,0); $endpointArray=explode(":",$dnparts[0]); $curname = $endpointArray[3]; $curport = $pn; // This could have been set by the Location object parsing, so we check it first if (!isset($$curzip)) $curzip=""; $vo = guess_country($curname,$curzip); if ($debug==2) dbgmsg("<i>$ids: <b>$curname</b>".$errors["112"]."$vo</i><br>"); $vostring = $_SERVER['PHP_SELF']."?display=vo=$vo"; if ( $lang != "default") $vostring .= "&lang=".$lang; if ( $debug ) $vostring .= "&debug=".$debug; $country = $vo; if ( $yazyk !== "en" ) $country = $strings["tlconvert"][$vo]; $country_content = "<a href=\"$vostring\"><img src=\"./mon-icons/$vo.png\" title=\"".$errors["312"]."$country \" alt=\"".$errors["312"]."\" height=\"10\" width=\"16\" border=\"0\"> <i><b>".$country."</b></i></a> "; if (!in_array($country_content,$rowcont)) { $rowcont[] = $country_content; } //blank $curzip for the next cluster $curzip=""; }; } elseif ( ($schema == "NG") && ( $allbasedn == DN_LOCAL) ) { // check if it is a site or a job; count $preflength = strpos($curdn,"-"); $object = substr($curdn,$preflength+1,strpos($curdn,"-",$preflength+1)-$preflength-1); if ($object=="cluster") { $dnparts = ldap_explode_dn($curdn,0); $curname = substr(strstr($dnparts[0],"="),1); $curport = $pn; // Country name massaging $zip = ""; if ( !empty($entries[$i][CLU_ZIPC][0]) ) $zip = $entries[$i][CLU_ZIPC][0]; $vo = guess_country($curname,$zip); if ($debug==2) dbgmsg("<i>$ids: <b>$curname</b>".$errors["112"]."$vo</i><br>"); $vostring = $_SERVER['PHP_SELF']."?display=vo=$vo"; if ( $lang != "default") $vostring .= "&lang=".$lang; if ( $debug ) $vostring .= "&debug=".$debug; $country = $vo; if ( $yazyk !== "en" ) $country = $strings["tlconvert"][$vo]; $rowcont[] = "<a href=\"$vostring\"><img src=\"./mon-icons/$vo.png\" title=\"".$errors["312"]."$country \" alt=\"".$errors["312"]."\" height=\"10\" width=\"16\" border=\"0\"> <i><b>".$country."</b></i></a> "; $curtotcpu = @($entries[$i][CLU_TCPU][0]) ? $entries[$i][CLU_TCPU][0] : 0; if ( !$curtotcpu && $debug ) dbgmsg("<font color=\"red\"><b>$curname</b>".$errors["113"]."</font><br>"); $curalias = $entries[$i][CLU_ANAM][0]; // Manipulate alias: replace the string if necessary and cut off at 22 characters; strip HTML tags if (file_exists("cnvalias.inc")) include('cnvalias.inc'); $curalias = strip_tags($curalias); if ( strlen($curalias) > 22 ) $curalias = substr($curalias,0,21) . ">"; $curtotjobs = @($entries[$i][CLU_TJOB][0]) ? $entries[$i][CLU_TJOB][0] : 0; $curusedcpu = @($entries[$i][CLU_UCPU][0]) ? $entries[$i][CLU_UCPU][0] : -1; $totqueued = @($entries[$i][CLU_QJOB][0]) ? $entries[$i][CLU_QJOB][0] : 0; /* deprecated since 0.5.38 */ $gmqueued = @($entries[$i][CLU_PQUE][0]) ? $entries[$i][CLU_PQUE][0] : 0; /* new since 0.5.38 */ $clstring = popup("clusdes.php?host=$curname&port=$curport",700,620,1,$lang,$debug); $nclu++; } elseif ($object=="queue") { $qstatus = $entries[$i][QUE_STAT][0]; if ( $qstatus != "active" ) $stopflag = TRUE; $allqrun += @($entries[$i][QUE_RUNG][0]) ? ($entries[$i][QUE_RUNG][0]) : 0; $gridjobs += @($entries[$i][QUE_GRUN][0]) ? ($entries[$i][QUE_GRUN][0]) : 0; $gridqueued += @($entries[$i][QUE_GQUE][0]) ? ($entries[$i][QUE_GQUE][0]) : 0; $allqueued += @($entries[$i][QUE_QUED][0]) ? ($entries[$i][QUE_QUED][0]) : 0; /* deprecated since 0.5.38 */ $lrmsqueued += @($entries[$i][QUE_LQUE][0]) ? ($entries[$i][QUE_LQUE][0]) : 0; /* new since 0.5.38 */ $prequeued += @($entries[$i][QUE_PQUE][0]) ? ($entries[$i][QUE_PQUE][0]) : 0; /* new since 0.5.38 */ $nqueues++; } } } if ( !$nclu && $nqueues ) { if ( $debug ) dbgmsg("<b>$hn</b>:".$errors["3"].": ".$errors["111"].$errors["410"]."<br>"); continue; } if ( $nclu > 1 && $debug ) dbgmsg("<b><font color=\"blue\">$hn</font></b>:".$errors["3"].": $nclu ".$errors["406"]."<br>"); if (!$nqueues) $toflag2 = TRUE; if ($debug==2 && $prequeued != $gmqueued) dbgmsg("<i><font color=\"blue\">$curname:</font></i> cluster-prelrmsqueued != sum(queue-prelrmsqueued)"); $allrun = ($curusedcpu < 0) ? $allqrun : $curusedcpu; if ($gridjobs > $allrun) $gridjobs = $allrun; /* For versions < 0.5.38: * Some Grid jobs are counted towards $totqueued and not towards $allqueued * (those in GM), so $totqueued - $allqueued = $gmqueued, * and $truegridq = $gmqueued + $gridqueued * and $nongridq = $totqueued - $truegridq == $allqueued - $gridqueued * hence $truegridq = $totqueued - $nongridq */ $nongridq = ($totqueued) ? $allqueued - $gridqueued : $lrmsqueued; $truegridq = ($totqueued) ? $totqueued - $nongridq : $gridqueued + $prequeued; // temporary hack: // $truegridq = $gridqueued; // $formtgq = sprintf(" s",$truegridq); $formngq = sprintf("\ \;s",$nongridq); $localrun = $allrun - $gridjobs; $gridload = ($curtotcpu > 0) ? $gridjobs/$curtotcpu : 0; $clusload = ($curtotcpu > 0) ? $allrun/$curtotcpu : 0; $tstring = urlencode("$gridjobs+$localrun"); $jrstring = popup("jobstat.php?host=$curname&port=$curport&status=Running&jobdn=all",600,500,2,$lang,$debug); $jqstring = popup("jobstat.php?host=$curname&port=$curport&status=Queueing&jobdn=all",600,500,2,$lang,$debug); if ( $schema == "GLUE2"){ $jrstring = popup("jobstat.php?host=$curname&port=$curport&status=Running&jobdn=all&schema=$schema",600,500,2,$lang,$debug); $jqstring = popup("jobstat.php?host=$curname&port=$curport&status=Queueing&jobdn=all&schema=$schema",600,500,2,$lang,$debug); } if ( $toflag2 ) { $tstring .= " (no queue info)"; // not sure if this is localizeable at all } elseif ( $stopflag ) { $tstring .= " (queue inactive)"; // not sure if this is localizeable at all } // Add a cluster row $rowcont[] = "<a href=\"$clstring\"> <b>$curalias</b></a>"; $rowcont[] = "$curtotcpu"; if ( $curtotcpu ) { $rowcont[] = "<a href=\"$jrstring\"><img src=\"./mon-icons/icon_bar.php?x=".$clusload."&xg=".$gridload."&y=13&text=".$tstring."\" vspace=\"2\" hspace=\"3\" border=\"0\" title=\"$gridjobs".$errors["313"]."$localrun".$errors["314"]."\" alt=\"$gridjobs+$localrun\" width=\"200\" height=\"13\"></a>"; } else { $rowcont[] = "<a href=\"$jrstring\"><img src=\"./mon-icons/spacer.gif\" vspace=\"2\" hspace=\"3\" border=\"0\" title=\"$gridjobs".$errors["313"]."$localrun".$errors["314"]."\" alt=\"$gridjobs+$localrun\" width=\"200\" height=\"13\"></a>"; } // $rowcont[] = "<a href=\"$jqstring\">$totqueued</a>"; $rowcont[] = "<a href=\"$jqstring\"><b>$truegridq</b></a>+$nongridq"; // Not adding anymore, cache instead // $ctable->addrow($rowcont); $tcont[] = $rowcont; $rowcont = array (); } } // Dump the collected table cache_table($cachefile,$tcont); } // HTML table initialization $ctable = new LmTableSp($module,$toppage->$module); // Sort /** possible ordering keywords: * country - sort by country, default * cpu - sort by advertised CPU number * grun - sort by number of running Grid jobs */ $ostring = "comp_by_".$order; usort($tcont,$ostring); $nrows = count($tcont); $votolink = array(); $affiliation = array(); foreach ( $tcont as $trow ) { $vo = $trow[0]; $vo = substr(stristr($vo,"./mon-icons/"),12); $vo = substr($vo,0,strpos($vo,".")); if ( !in_array($vo,$votolink) ) $votolink[]=$vo; array_push($affiliation,$vo); } $affcnt = array_count_values($affiliation); $prevvo = "boo"; $sumcpu = 0; $sumgridjobs = 0; $sumlocljobs = 0; $sumclusters = 0; $sumgridqueued = 0; $sumloclqueued = 0; //$sumqueued = 0; // actual loop foreach ( $tcont as $trow ) { $gridjobs = $trow[3]; $gridjobs = substr(stristr($gridjobs,"alt=\""),5); $gridjobs = substr($gridjobs,0,strpos($gridjobs,"+")); $localrun = $trow[3]; $localrun = substr(stristr($localrun,"+"),1); $localrun = substr($localrun,0,strpos($localrun,"\" w")); $truegridq = $trow[4]; $truegridq = substr(stristr($truegridq,"<b>"),3); $truegridq = substr($truegridq,0,strpos($truegridq,"</b>")); $nongridq = $trow[4]; $nongridq = substr(stristr($nongridq,"+"),1); $vo = $trow[0]; $vo = substr(stristr($vo,"./mon-icons/"),12); $vo = substr($vo,0,strpos($vo,".")); if ( @$showvo && $showvo != $vo ) continue; $sumcpu += $trow[2]; $sumgridjobs += $gridjobs; $sumlocljobs += $localrun; $sumgridqueued += $truegridq; $sumloclqueued += $nongridq; // $sumqueued += $totqueued; $sumclusters ++; if ( $vo != $prevvo && $order == "country" ) { // start new country rowspan $prevvo = $vo; $vostring = $trow[0]; $ctable->addspacer("#000099"); $ctable->rowspan( $affcnt[$vo], $vostring, "#FFF2DF" ); $tcrow = array_shift($trow); $ctable->addrow($trow); } else { if ( $order == "country" ) $tcrow = array_shift($trow); $ctable->addrow($trow); } } $tcont = array(); $ctable->addspacer("#990000"); $rowcont[] = "<b><i>".$errors["405"]."</i></b>"; $rowcont[] = "<b><i>$sumclusters".$errors["406"]."</i></b>"; $rowcont[] = "<b><i>$sumcpu</i></b>"; $rowcont[] = "<b><i>$sumgridjobs + $sumlocljobs</i></b>"; $rowcont[] = "<b><i>$sumgridqueued + $sumloclqueued</i></b>"; // $rowcont[] = "<b><i>$sumqueued</i></b>"; $ctable->addrow($rowcont, "#ffffff"); $ctable->close(); // To change language, link back to ALL $linkback = $_SERVER['PHP_SELF']; if ( $debug ) { $linkback .= "?debug=".$debug; $separator = "&"; } else { $separator = "?"; } // Show flags if only one country is chosen if ( @$showvo ) { echo "<br><nobr>\n"; foreach ( $votolink as $volink ) { $vostring = $_SERVER['PHP_SELF']."?display=vo=$volink"; if ( $lang != "default" ) $vostring .= "&lang=".$lang; if ( $debug ) $vostring .= "&debug=".$debug; $voimage = "<img src=\"./mon-icons/$volink.png\" title=\"".$errors["312"]."$volink\" alt=\"".$errors["312"]."\" height=\"10\" width=\"16\" border=\"0\">"; echo "<a href=\"$vostring\">$voimage</a> "; } if ( $lang != "default") $linkall = $linkback.$separator."lang=".$lang; echo "<a href=\"".$linkall."\"><b>".$errors["409"]."</b></a><BR>\n"; // Show ALL echo "</nobr>\n"; } else { // Show languages $translations = scandir(getcwd()."/lang"); echo "<center><br><nobr>\n"; foreach ( $translations as $transfile ) { $twoletcod = substr($transfile,0,2); if ( stristr($transfile,".") == ".inc" && $twoletcod != "us" ) { $linklang = $linkback.$separator."lang=".$twoletcod; echo "<a href=\"".$linklang."\">$twoletcod</a> "; } } echo "</nobr><br></center>\n"; } return 0; // Done $toppage->close(); ?>