<?php session_start(); function getTabNames() { $xml = docmd('tabdump','',NULL); $tabs = array(); foreach ($xml->children() as $response) foreach ($response->children() as $t) { $tabs[] = (string) $t; } return $tabs; } function docmd($cmd, $nr, $args){ // If for some reason we are not logged in yet, do not even try to communicate w/xcatd if (!is_logged()) { echo "<p>Docmd: not logged in yet - can not run command.</p>\n"; return simplexml_load_string('<xcat></xcat>','SimpleXMLElement', LIBXML_NOCDATA); } $request = simplexml_load_string('<xcatrequest></xcatrequest>'); $request->addChild('command',$cmd); if(!empty($nr)) { $request->addChild('noderange',$nr); } if (!empty($args)) { foreach ($args as $a) { $request->addChild('arg',$a); } } $usernode=$request->addChild('becomeuser'); $usernode->addChild('username',$_SESSION["username"]); $usernode->addChild('password',getpassword()); #echo $request->asXML(); $xml = submit_request($request,0); return $xml; } //----------------------------------------------------------------------------- // Used by docmd() // req is a tree of SimpleXML objects // Returns a tree of SimpleXML objects. See perl-xCAT/xCAT/Client.pm for the format. function submit_request($req, $skipVerify){ #global $cert,$port,$xcathost; //$apachehome = '/var/www'; # for sles this should be /var/lib/wwwrun //$cert = "$apachehome/.xcat/client-cred.pem"; $xcathost = "localhost"; $port = "3001"; $rsp = FALSE; $response = ''; $cleanexit=0; // Open a socket to xcatd $context = stream_context_create(); // do not need certificate anymore: array('ssl'=>array('local_cert' => $cert)) if($fp = stream_socket_client('ssl://'.$xcathost.':'.$port,$errno,$errstr,30,STREAM_CLIENT_CONNECT,$context)){ fwrite($fp,$req->asXML()); // send the xml to xcatd while(!feof($fp)){ // and then read until there is no more $response .= preg_replace('/\n/','', fgets($fp)); // remove newlines and add it to the response // Look for the serverdone response $fullpattern = '/<xcatresponse>\s*<serverdone>\s*<\/serverdone>\s*<\/xcatresponse>/'; $mixedpattern = '/<serverdone>\s*<\/serverdone>.*<\/xcatresponse>/'; //$shortpattern = '/<serverdone>\s*<\/serverdone>/'; if(preg_match($mixedpattern,$response)) { // transaction is done, pkg up the xml and return it //echo "<p>", htmlentities($response), "</p>\n"; // remove the serverdone response and put an xcat tag around the rest $count = 0; $response = preg_replace($fullpattern,'', $response, -1, $count); // 1st try to remove the long pattern if (!$count) { $response = preg_replace($mixedpattern,'', $response) . '</xcatresponse>/'; } // if its not there, then remove the short pattern $response = "<xcat>$response</xcat>"; //echo "<p>", htmlentities($response), "</p>\n"; $rsp = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA); //echo '<p>'; print_r($rsp); echo "</p>\n"; $cleanexit = 1; break; } } fclose($fp); }else{ echo "<p>xCAT Submit request socket Error: $errno - $errstr</p>\n"; } if(! $cleanexit){ if (preg_match('/^\s*<xcatresponse>.*<\/xcatresponse>\s*$/',$response)) { // It is probably an error msg, that is why we didn't get serverdone $response = "<xcat>$response</xcat>"; $rsp = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA); } elseif(!$skipVerify){ echo "<p>Error: xCAT response ended prematurely: ", htmlentities($response), "</p>"; $rsp = FALSE; } } return $rsp; } //----------------------------------------------------------------------------- // Use with submit_request() to get the data fields (output that is not node-oriented) function getXmlData(& $xml) { $data = array(); foreach ($xml->children() as $response) foreach ($response->children() as $k => $v) { if ($k == 'data') { $data[] = (string) $v; } } return $data; } //----------------------------------------------------------------------------- // Use with submit_request() to get any errors that might have occurred // Returns the errorcode and adds any error strings to the $error array passed in function getXmlErrors(& $xml, & $errors) { if (!isset($errors)) { $errors = array(); } if (!isset($xml) || $xml===FALSE) { $errors[]='rc = 1'; return 1; } $errorcode = 0; foreach ($xml->children() as $response) foreach ($response->children() as $k => $v) { if ($k == 'error') { $errors[] = (string) $v; } if ($k == 'errorcode') { $errorcode = (string) $v; } } if ($errorcode==0 && count($errors)) { $errorcode = -1 * count($errors); } // the plugin author forgot to set the errorcode return $errorcode; } function getTabHeaders($xml){ foreach ($xml->children() as $response) foreach ($response->children() as $line) { $line = (string) $line; if (ereg("^#", $line)) { $line = preg_replace('/^#/','', $line); $headers = explode(',', $line); return $headers; } } // If we get here, we never found the header line return NULL; } //----------------------------------------------------------------------------- // Parse the columns of 1 line of tabdump output //Todo: the only thing this doesn't handle is escaped double quotes. function splitTableFields($line){ $fields = array(); $line = ",$line"; // prepend a comma. this makes the parsing more consistent for ($rest=$line; !empty($rest); ) { $vals = array(); // either match everything in the 1st pair of quotes, or up to the next comma if (!preg_match('/^,"([^"]*)"(.*)$/', $rest, $vals)) { preg_match('/^,([^,]*)(.*)$/', $rest, $vals); } $fields[] = $vals[1]; $rest = $vals[2]; } return $fields; } //---------------------------------------------------------------------------- // SImilar to docmd(), but also takes in data that is the table contents. function doTabRestore($tab, & $data){ #$headers = getTabHeaders(docmd('tabdump', '', array($tab))); #$headers[0] = "#" . $headers[0]; #$request->addChild('data', implode(",",$headers)); $request = simplexml_load_string('<xcatrequest></xcatrequest>'); $request->addChild('command', 'tabrestore'); $usernode=$request->addChild('becomeuser'); $usernode->addChild('username', $_SESSION["username"]); $usernode->addChild('password',getpassword()); $first = 0; foreach($data as $line){ if($first == 0){ # add this in here because the first one is the # sign # and doesn't need special processing! $linestr = implode(",",$line); $request->addChild('data', $linestr); $first = 1; continue; } foreach($line as &$f){ if(!empty($f) && !preg_match('/^".*"$/', $f)) { $f = '"'.$f.'"'; } } ksort($line, SORT_NUMERIC); $keys = array_keys($line); $maxindex = count($line)-1; if($keys[$maxindex] != $maxindex){ for ($i=0; $i<=$keys[$maxindex]; $i++) { if (!isset($line[$i])) {$line[$i]='';} } ksort($line, SORT_NUMERIC); } $linestr = implode(",",$line); $linestr = str_replace('"', '"',$linestr); //todo: should we use the htmlentities function? $linestr = str_replace("'", ''',$linestr); //echo "<p>addChild:$linestr.</p>\n"; $request->addChild('data', $linestr); } $request->addChild('table', $tab); $resp = submit_request($request,0); return $resp; } // Send the keys and values in the primary global arrays function dumpGlobals() { //trace('<b>$_SERVER:</b>'); //foreach ($_SERVER as $key => $val) { trace("$key=$val."); } //trace('<b>$_ENV:</b>'); //foreach ($_ENV as $key => $val) { trace("$key=$val."); } trace('<b>$_GET:</b>'); foreach ($_GET as $key => $val) { trace("$key=$val."); } trace('<b>$_POST:</b>'); foreach ($_POST as $key => $val) { trace("$key=$val."); } trace('<b>$_COOKIE:</b>'); foreach ($_COOKIE as $key => $val) { trace("$key=$val."); } if (isset($_SESSION)) { trace('<b>$_SESSION:</b>'); foreach ($_SESSION as $key => $val) { trace("$key=$val."); } } trace('<b>$GLOBALS:</b>'); foreach ($GLOBALS as $key => $val) { trace("$key=$val."); } } // Debug output ------------------------------------ define("TRACE", "1"); function trace($str) { if (TRACE) { echo "<p class=Trace>$str</p>\n"; } } // some jbj/bp stuff $xcatcmds = array( "rpower" => array("on","off","reset","stat","state","boot","off","cycle"), "rvitals" => array("all","temp","wattage","voltage","fanspeed","power","leds","state"), "reventlog" => array("all", "clear"), "rinv" => array("all", "model", "serial", "vpd", "mprom", "deviceid", "uuid", "guid", "firm", "bios", "diag", "mprom", "sprom", "mparom", "mac", "mtm"), "resetboot" => array("net", "hd", "cd", "def", "stat") ); // take in the function attributesOfNodes($ht,$meth) { $arr = array(); if($meth == 'rpower'){ $arr[] = 'Power Status'; $arr[] = 'More Actions'; return($arr); }elseif($meth == 'rbeacon'){ $arr[] = 'Beacon Status'; $arr[] = 'More Actions'; return($arr); } foreach($ht->xcatresponse as $v){ foreach($v->node as $va){ $val = (string) $va->data->desc; if($val == ""){ $val = (string) $va->data->contents; } $arr[] = $val; } } $arr = array_unique($arr); return($arr); } function mkNodeHash ($ht,$cmd){ $arr = array(); $name = ""; $desc = ""; $cont = ""; foreach($ht->children() as $response){ foreach($response as $node){ #print_r($response); $name = (string) $node->name; $desc = (string) $node->data->desc; if($cmd == 'rpower'){ $desc = 'Power Status'; }elseif($cmd == 'rbeacon'){ $desc = 'Beacon Status'; } $cont = (string) $node->data->contents; if($cont == ''){ $cont = (string) $node->error; } $arr[$name][$desc] = $cont; } } // add the more fields so we can click in place. if($cmd == 'rpower'){ foreach($arr as $n => $val){ $html = "<center><a href='#' onclick='controlCmd(\"rpoweroff\",\"$n\")'>Power Off</a>"; $html .= " <a href='#' onclick='controlCmd(\"rpoweron\",\"$n\")'>Power On</a>"; $html .= " <a href='#' onclick='controlCmd(\"rpowerboot\",\"$n\")'>Reboot</a>"; $html .= " <a href='#' onclick='controlCmd(\"rpowerstat\",\"$n\")'>Status</a></center>"; $arr[$n]['More Actions'] = $html; } }elseif($cmd == 'rbeacon'){ foreach($arr as $n => $val){ $html = "<center><a href='#' onclick='controlCmd(\"rbeaconstat\",\"$n\")'>Beacon Light Status</a>"; $html .= " <a href='#' onclick='controlCmd(\"rbeaconoff\",\"$n\")'>Beacon Off</a>"; $html .= " <a href='#' onclick='controlCmd(\"rbeaconon\",\"$n\")'>Beacon On</a>"; $arr[$n]['More Actions'] = $html; } } #print_r($arr); return($arr); } // Get the nth to last line from the syslog // use the newlines to go through the syslog starting at the end // function getLastLine($line){ if($line == ''){ $line = 0; }; $f = "/var/log/messages"; $fp = fopen($f, 'r'); if($fp === false){ echo "Couldn't open /var/log/messages. Hint: chmod 666 /var/log/messages might make it work.\n"; return 0; } $pos = -2; $t = " "; // number of new lines we have seen. $count = -1; #while($t != "\n"){ while($count < $line){ if(!fseek($fp, $pos, SEEK_END)) { $t = fgetc($fp); if($t == "\n"){ $count++; } $pos = $pos - 1; }else { rewind($fp); break; } } # got a line $t = fgets($fp); fclose($fp); return ($t); } ?>