blob: 82a16731a9275a0d208158f4373080a2a0e5e15c [file] [log] [blame]
<?php
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* \file
*/
////////////////////////////////////////////////////////////////////////////////
///
/// \fn dashboard()
///
/// \brief prints a page with various information about running system
///
////////////////////////////////////////////////////////////////////////////////
function dashboard() {
$affilid = getDashboardAffilID();
print "<h2>VCL Dashboard</h2>\n";
print "(Times and dates on this page are in " . date('T') . ")<br><br>\n";
if(checkUserHasPerm('View Dashboard (global)')) {
print "View data for:";
$affils = getAffiliations();
$affils = array_reverse($affils, TRUE);
$affils[0] = "All Affiliations";
$affils = array_reverse($affils, TRUE);
printSelectInput('affilid', $affils, -1, 0, 0, 'affilid', 'onChange="updateDashboard();"');
}
print "<div id=\"dashlayout\">\n";
# -------- left column ---------
print "<div id=\"dashleft\">\n";
print addWidget('status', 'Current Status', '(Hover for description)');
print addWidget('topimages', 'Top 5 Images in Use', '(Reservations &lt; 24 hours long)');
print addWidget('toplongimages', 'Top 5 Long Term Images in Use', '(Reservations &gt; 24 hours long)');
print addWidget('toppastimages', 'Top 5 Images From Past Day', '(Reservations with a start<br>time within past 24 hours)');
print addWidget('toppast6moimages', 'Top 5 Images From Past 6 Months', '(Reservations with a start<br>time within past 6 months)', 1);
print addWidget('topfailedcomputers', 'Top Recent Computer Failures', '(Failed in the last 5 days)');
print addWidget('blockallocation', 'Block Allocation Status');
print "</div>\n"; # dashleft
# -------- end left column ---------
# ---------- right column ---------
print "<div id=\"dashright\">\n";
print addWidget('managementnodes', 'Management Nodes', '[ ] denotes node in maintenance state');
print addWidget('topfailed', 'Top Recent Image Failures', '(Failed in the last 5 days)');
print addLineChart('reschart', 'Past 12 Hours of Active Reservations');
print "</div>\n"; # dashright
# -------- end right column --------
print "</div>\n"; # dashlayout
print addWidget('newreservations', 'Notable Reservations', '');
if(checkUserHasPerm('View Dashboard (global)'))
print addWidget('failedimaging', 'Failed Imaging Reservations', '(Imaging Reservations in the maintenance state)');
$cont = addContinuationsEntry('AJupdateDashboard', array('val' => 0), 90, 1, 0);
print "<input type=\"hidden\" id=\"updatecont\" value=\"$cont\">\n";
$cont = addContinuationsEntry('AJdashboardDetail', array('affilid' => $affilid));
print "<input type=\"hidden\" id=\"detailcont\" value=\"$cont\">\n";
# detail dialog
$h = '';
$h .= "<div dojoType=dijit.Dialog\n";
$h .= " id=\"detaildialog\"\n";
$h .= " duration=250\n";
$h .= " autofocus=false\n";
$h .= " draggable=true>\n";
$h .= "<h3><div id=\"detailtitle\"></div></h3>\n";
$h .= "<div id=\"detailcontent\"></div>\n";
$h .= "<input type=\"hidden\" id=\"submitcont\">\n";
$h .= "<div style=\"text-align: center;\"><br>\n";
$h .= dijitButton('canceldetailbtn', 'Close', 'cancelDetail();', 0);
$h .= "</div>\n"; # btn div
$h .= "</div>\n"; # detaildialog
print $h;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn AJupdateDashboard
///
/// \brief gets updated data and returns it in json format
///
////////////////////////////////////////////////////////////////////////////////
function AJupdateDashboard() {
$data = array();
$data['cont'] = addContinuationsEntry('AJupdateDashboard', array(), 90, 1, 0);
$data['status'] = getStatusData();
$data['topimages'] = getTopImageData();
$data['toplongimages'] = getTopLongImageData();
$data['toppastimages'] = getTopPastImageData(5, 'DAY', 1);
$data['toppast6moimages'] = getTopPastImageData(5, 'MONTH', 6);
$data['topfailed'] = getTopFailedData();
$data['topfailedcomputers'] = getTopFailedComputersData();
$data['reschart'] = getActiveResChartData();
$data['blockallocation'] = getBlockAllocationData();
$data['newreservations'] = getNewReservationData();
$data['failedimaging'] = getFailedImagingData();
$data['managementnodes'] = getManagementNodeData();
sendJSON($data);
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn AJdashboardDetail()
///
/// \param id - id of widget type
///
/// \brief gets detailed information for specified type
///
////////////////////////////////////////////////////////////////////////////////
function AJdashboardDetail() {
$id = processInputVar('id', ARG_STRING);
switch($id) {
case 'toppast6moimages':
$data = array('divid' => 'detailcontent');
$data['title'] = "Top Images From Past 6 Months";
$data['result'] = getTopPastImageData(30, 'MONTH', 6);
break;
default:
}
sendJSON($data);
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn addWidget($id, $title, extra)
///
/// \param $id - dom id for div
/// \param $title - title to print at top of box
/// \param $extra (optional, default='') - extra text to be placed below title,
/// but above data
/// \param $clicktitle - (optional, default=0) boolean for title being clickable
/// to display more details
///
/// \return div element for a section of data
///
/// \brief creates HTML for a box of data to be displayed
///
////////////////////////////////////////////////////////////////////////////////
function addWidget($id, $title, $extra='', $clicktitle=0) {
$txt = "<div class=\"dashwidget\">\n";
if($clicktitle)
$txt .= "<h3><a onclick=\"showdetail('$id');\">$title</a></h3>\n";
else
$txt .= "<h3>$title</h3>\n";
if($extra != '')
$txt .= "<div class=\"extra\">$extra</div>\n";
$txt .= "<div id=\"$id\"></div>\n";
$txt .= "</div>\n";
return $txt;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn addLineChart($id, $title)
///
/// \param $id - dom id for chart
/// \param $title - title to print at top of box
///
/// \return div element for a section of data
///
/// \brief creates HTML for a box of data to be displayed containing a dojox
/// chart
///
////////////////////////////////////////////////////////////////////////////////
function addLineChart($id, $title) {
$txt = "<div class=\"dashwidget\">\n";
$txt .= "<h3>$title</h3>\n";
$txt .= "<div dojoType=\"dojox.charting.widget.Chart2D\" id=\"$id\"\n";
$txt .= " theme=\"dojox.charting.themes.ThreeD\"\n";
$txt .= " style=\"width: 300px; height: 300px; text-align: left;\">\n";
$txt .= "<div class=\"axis\"\n";
$txt .= " name=\"x\"\n";
$txt .= " labelFunc=\"timestampToTime\"\n";
$txt .= " maxLabelSize=\"35\"\n";
$txt .= " rotation=\"-90\"\n";
$txt .= " majorTickStep=\"4\"\n";
$txt .= " minorTickStep=\"1\">\n";
$txt .= " </div>\n";
$txt .= "<div class=\"axis\" name=\"y\" vertical=\"true\" includeZero=\"true\"></div>\n";
$txt .= "<div class=\"plot\" name=\"default\" type=\"Lines\" markers=\"true\"></div>\n";
$txt .= "<div class=\"plot\" name=\"grid\" type=\"Grid\" vMajorLines=\"false\"></div>\n";
$txt .= "<div class=\"series\" name=\"Main\" data=\"0\"></div>\n";
$txt .= "<div class=\"action\" type=\"Tooltip\"></div>\n";
$txt .= "<div class=\"action\" type=\"Magnify\"></div>\n";
$txt .= "</div>\n";
$txt .= "</div>\n";
return $txt;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getStatusData()
///
/// \return array of data where element is an array with these keys:\n
/// \b key - name of data to be displayed\n
/// \b val - value of data\n
/// \b tooltip (optional) - text to be displayed when hovering over the key
///
/// \brief gets general status data about VCL system
///
////////////////////////////////////////////////////////////////////////////////
function getStatusData() {
$affilid = getDashboardAffilID();
$data = array();
$data[0] = array('key' => 'Active Reservations', 'val' => 0, 'tooltip' => 'Reservations currently running');
$data[1] = array('key' => 'Active Short Reservations', 'val' => 0, 'tooltip' => 'Reservations with a duration < 24 hours');
$data[2] = array('key' => 'Online Computers', 'val' => 0, 'tooltip' => 'Computers in states available, reserved,<br>reloading, inuse, or timeout');
$data[3] = array('key' => 'In Use Computers', 'val' => 0, 'tooltip' => 'Computers in inuse state');
$data[4] = array('key' => 'Failed Computers', 'val' => 0);
$reloadid = getUserlistID('vclreload@Local');
if($affilid == 0) {
$query = "SELECT COUNT(id) "
. "FROM request "
. "WHERE userid != $reloadid AND "
. "stateid NOT IN (1, 5, 10, 12) AND "
. "start < NOW() AND "
. "end > NOW()";
}
else {
$query = "SELECT COUNT(rq.id) "
. "FROM request rq, "
. "user u "
. "WHERE rq.userid != $reloadid AND "
. "rq.userid = u.id AND "
. "u.affiliationid = $affilid AND "
. "rq.stateid NOT IN (1, 5, 10, 12) AND "
. "rq.start < NOW() AND "
. "rq.end > NOW()";
}
$qh = doQuery($query, 101);
if($row = mysqli_fetch_row($qh))
$data[0]['val'] = $row[0];
if($affilid == 0) {
$query = "SELECT COUNT(id) "
. "FROM request "
. "WHERE userid != $reloadid AND "
. "stateid NOT IN (1, 5, 10, 12) AND "
. "start < NOW() AND "
. "end > NOW() AND "
. "(UNIX_TIMESTAMP(end) - UNIX_TIMESTAMP(start)) < 86400";
}
else {
$query = "SELECT COUNT(rq.id) "
. "FROM request rq, "
. "user u "
. "WHERE rq.userid != $reloadid AND "
. "rq.userid = u.id AND "
. "u.affiliationid = $affilid AND "
. "rq.stateid NOT IN (1, 5, 10, 12) AND "
. "rq.start < NOW() AND "
. "rq.end > NOW() AND "
. "(UNIX_TIMESTAMP(end) - UNIX_TIMESTAMP(start)) < 86400";
}
$qh = doQuery($query, 101);
if($row = mysqli_fetch_row($qh))
$data[1]['val'] = $row[0];
$query = "SELECT COUNT(id) FROM computer WHERE stateid IN (2, 3, 6, 8, 11)";
$qh = doQuery($query, 101);
if($row = mysqli_fetch_row($qh))
$data[2]['val'] = $row[0];
$query = "SELECT COUNT(id) FROM computer WHERE stateid = 8";
$qh = doQuery($query, 101);
if($row = mysqli_fetch_row($qh))
$data[3]['val'] = $row[0];
$query = "SELECT COUNT(id) FROM computer WHERE stateid = 5";
$qh = doQuery($query, 101);
if($row = mysqli_fetch_row($qh))
$data[4]['val'] = $row[0];
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getTopImageData()
///
/// \return array of data with these keys:\n
/// \b prettyname - name of image\n
/// \b count - number of reservations for this image
///
/// \brief gets data about top used images with reservation duration <= 24 hours
///
////////////////////////////////////////////////////////////////////////////////
function getTopImageData() {
$affilid = getDashboardAffilID();
if($affilid == 0) {
$query = "SELECT COUNT(rs.imageid) AS count, "
. "i.prettyname "
. "FROM reservation rs, "
. "request rq, "
. "image i "
. "WHERE rs.imageid = i.id AND "
. "rq.stateid = 8 AND "
. "rs.requestid = rq.id AND "
. "TIMESTAMPDIFF(HOUR, rq.start, rq.end) <= 24 "
. "GROUP BY rs.imageid "
. "ORDER BY count DESC "
. "LIMIT 5";
}
else {
$query = "SELECT COUNT(rs.imageid) AS count, "
. "i.prettyname "
. "FROM reservation rs, "
. "request rq, "
. "image i, "
. "user u "
. "WHERE rq.userid = u.id AND "
. "u.affiliationid = $affilid AND "
. "rs.imageid = i.id AND "
. "rq.stateid = 8 AND "
. "rs.requestid = rq.id AND "
. "TIMESTAMPDIFF(HOUR, rq.start, rq.end) <= 24 "
. "GROUP BY rs.imageid "
. "ORDER BY count DESC "
. "LIMIT 5";
}
$data = array();
$qh = doQuery($query, 101);
while($row = mysqli_fetch_assoc($qh))
$data[] = $row;
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getTopLongImageData()
///
/// \return array of data with these keys:\n
/// \b prettyname - name of image\n
/// \b count - number of reservations for this image
///
/// \brief gets data about top used images with reservation duration > 24 hours
///
////////////////////////////////////////////////////////////////////////////////
function getTopLongImageData() {
$affilid = getDashboardAffilID();
if($affilid == 0) {
$query = "SELECT COUNT(rs.imageid) AS count, "
. "i.prettyname "
. "FROM reservation rs, "
. "request rq, "
. "image i "
. "WHERE rs.imageid = i.id AND "
. "rq.stateid = 8 AND "
. "rs.requestid = rq.id AND "
. "TIMESTAMPDIFF(HOUR, rq.start, rq.end) > 24 "
. "GROUP BY rs.imageid "
. "ORDER BY count DESC "
. "LIMIT 5";
}
else {
$query = "SELECT COUNT(rs.imageid) AS count, "
. "i.prettyname "
. "FROM reservation rs, "
. "request rq, "
. "image i, "
. "user u "
. "WHERE rq.userid = u.id AND "
. "u.affiliationid = $affilid AND "
. "rs.imageid = i.id AND "
. "rq.stateid = 8 AND "
. "rs.requestid = rq.id AND "
. "TIMESTAMPDIFF(HOUR, rq.start, rq.end) > 24 "
. "GROUP BY rs.imageid "
. "ORDER BY count DESC "
. "LIMIT 5";
}
$data = array();
$qh = doQuery($query, 101);
while($row = mysqli_fetch_assoc($qh))
$data[] = $row;
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getTopPastImageData($imagecnt, $intervalunit, $intervalnum)
///
/// \param $imagecnt - number of images to return
/// \param $intervalunit - units of interval for DATE_SUB in query
/// \param $intervalnum - how many interval units to use in query
///
/// \return array of data with these keys:\n
/// \b prettyname - name of image\n
/// \b count - number of reservations for this image
///
/// \brief gets data about top reserved images over past day
///
////////////////////////////////////////////////////////////////////////////////
function getTopPastImageData($imagecnt, $intervalunit, $intervalnum) {
$affilid = getDashboardAffilID();
$reloadid = getUserlistID('vclreload@Local');
if($affilid == 0) {
$query = "SELECT COUNT(l.imageid) AS count, "
. "i.prettyname "
. "FROM log l, "
. "image i "
. "WHERE l.imageid = i.id AND "
. "l.wasavailable = 1 AND "
. "l.userid != $reloadid AND "
. "l.start > DATE_SUB(NOW(), INTERVAL $intervalnum $intervalunit) "
. "GROUP BY l.imageid "
. "ORDER BY count DESC "
. "LIMIT $imagecnt";
}
else {
$query = "SELECT COUNT(l.imageid) AS count, "
. "i.prettyname "
. "FROM log l, "
. "image i, "
. "user u "
. "WHERE l.userid = u.id AND "
. "u.affiliationid = $affilid AND "
. "l.imageid = i.id AND "
. "l.wasavailable = 1 AND "
. "l.userid != $reloadid AND "
. "l.start > DATE_SUB(NOW(), INTERVAL $intervalnum $intervalunit) "
. "GROUP BY l.imageid "
. "ORDER BY count DESC "
. "LIMIT $imagecnt";
}
$data = array();
$qh = doQuery($query, 101);
while($row = mysqli_fetch_assoc($qh))
$data[] = $row;
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getTopFailedData()
///
/// \return array of data with these keys:\n
/// \b prettyname - name of image\n
/// \b count - number of failed reservations for this image
///
/// \brief gets data about images that have failed within the last 5 days
///
////////////////////////////////////////////////////////////////////////////////
function getTopFailedData() {
$affilid = getDashboardAffilID();
if($affilid == 0) {
$query = "SELECT COUNT(l.imageid) AS count, "
. "i.prettyname "
. "FROM log l, "
. "image i "
. "WHERE l.imageid = i.id AND "
. "l.ending = 'failed' AND "
. "l.start > DATE_SUB(NOW(), INTERVAL 5 DAY) "
. "GROUP BY l.imageid "
. "ORDER BY count DESC "
. "LIMIT 5";
}
else {
$query = "SELECT COUNT(l.imageid) AS count, "
. "i.prettyname "
. "FROM log l, "
. "image i, "
. "user u "
. "WHERE l.userid = u.id AND "
. "u.affiliationid = $affilid AND "
. "l.imageid = i.id AND "
. "l.ending = 'failed' AND "
. "l.start > DATE_SUB(NOW(), INTERVAL 5 DAY) "
. "GROUP BY l.imageid "
. "ORDER BY count DESC "
. "LIMIT 5";
}
$data = array();
$qh = doQuery($query, 101);
while($row = mysqli_fetch_assoc($qh))
$data[] = $row;
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getTopFailedComputersData()
///
/// \return array of data with these keys:\n
/// \b hostname - name of image\n
/// \b count - number of failures computer has had
///
/// \brief gets data about computers that have failed within the last 5 days
///
////////////////////////////////////////////////////////////////////////////////
function getTopFailedComputersData() {
$affilid = getDashboardAffilID();
if($affilid == 0) {
$query = "SELECT COUNT(s.computerid) AS count, "
. "c.hostname "
. "FROM log l, "
. "sublog s, "
. "computer c "
. "WHERE s.logid = l.id AND "
. "s.computerid = c.id AND "
. "l.ending = 'failed' AND "
. "l.start > DATE_SUB(NOW(), INTERVAL 5 DAY) "
. "GROUP BY s.computerid "
. "ORDER BY count DESC "
. "LIMIT 5";
}
else {
$query = "SELECT COUNT(s.computerid) AS count, "
. "c.hostname "
. "FROM log l, "
. "sublog s, "
. "computer c, "
. "user u "
. "WHERE l.userid = u.id AND "
. "u.affiliationid = $affilid AND "
. "s.logid = l.id AND "
. "s.computerid = c.id AND "
. "l.ending = 'failed' AND "
. "l.start > DATE_SUB(NOW(), INTERVAL 5 DAY) "
. "GROUP BY s.computerid "
. "ORDER BY count DESC "
. "LIMIT 5";
}
$data = array();
$qh = doQuery($query, 101);
while($row = mysqli_fetch_assoc($qh))
$data[] = $row;
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getActiveResChartData()
///
/// \return array with these keys:\n
/// \b points - array with these keys\n
/// \t\b x - x value for point (1-n)\n
/// \t\b y - number of reservations in this bin\n
/// \t\b value - same as x\n
/// \t\b text - value to be displayed as x label
/// \b maxy - max y value of returned data
///
/// \brief gets data about reservations during last 12 hours divided into bins
/// of 15 minutes
///
////////////////////////////////////////////////////////////////////////////////
function getActiveResChartData() {
$data = array();
$chartstart = unixFloor15(time() - (12 * 3600));
$chartend = $chartstart + (12 * 3600) + 900;
for($time = $chartstart, $i = 0; $time < $chartend; $time += 900, $i++) {
$fmttime = date('g:i a', $time);
$data["points"][$i] = array('x' => $i, 'y' => 0, 'value' => $i, 'text' => $fmttime);
}
$data['maxy'] = 0;
$reloadid = getUserlistID('vclreload@Local');
$affilid = getDashboardAffilID();
if($affilid == 0) {
$query = "SELECT l.id, "
. "UNIX_TIMESTAMP(l.start) AS start, "
. "UNIX_TIMESTAMP(l.finalend) AS end, "
. "rq.stateid, "
. "rq.laststateid "
. "FROM log l "
. "LEFT JOIN request rq ON (l.requestid = rq.id) "
. "WHERE l.start < NOW() AND "
. "l.finalend > DATE_SUB(NOW(), INTERVAL 12 HOUR) AND "
. "l.ending NOT IN ('failed', 'failedtest') AND "
. "l.wasavailable = 1 AND "
. "l.userid != $reloadid";
}
else {
$query = "SELECT l.id, "
. "UNIX_TIMESTAMP(l.start) AS start, "
. "UNIX_TIMESTAMP(l.finalend) AS end, "
. "rq.stateid, "
. "rq.laststateid "
. "FROM user u, "
. "log l "
. "LEFT JOIN request rq ON (l.requestid = rq.id) "
. "WHERE l.userid = u.id AND "
. "u.affiliationid = $affilid AND "
. "l.start < NOW() AND "
. "l.finalend > DATE_SUB(NOW(), INTERVAL 12 HOUR) AND "
. "l.ending NOT IN ('failed', 'failedtest') AND "
. "l.wasavailable = 1 AND "
. "l.userid != $reloadid";
}
$qh = doQuery($query, 101);
while($row = mysqli_fetch_assoc($qh)) {
if($row['stateid'] == 14)
$row['stateid'] = $row['laststateid'];
if($row['end'] > time() &&
(is_null($row['stateid']) || preg_match('/^(1|5|10|11|12|16|17|18|19|21|22)$/', $row['stateid'])))
continue;
for($binstart = $chartstart, $binend = $chartstart + 900, $binindex = 0;
$binend <= $chartend;
$binstart += 900, $binend += 900, $binindex++) {
if($binend <= $row['start'])
continue;
elseif($row['start'] < $binend &&
$row['end'] > $binstart) {
$data["points"][$binindex]['y']++;
}
elseif($binstart >= $row['end'])
break;
}
}
for($time = $chartstart, $i = 0; $time < $chartend; $time += 900, $i++) {
if($data["points"][$i]['y'] > $data['maxy'])
$data['maxy'] = $data['points'][$i]['y'];
$data["points"][$i]['tooltip'] = "{$data['points'][$i]['text']}: {$data['points'][$i]['y']}";
}
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getBlockAllocationData()
///
/// \return array of data where element is an array with these keys:\n
/// \b title - name of data to be displayed\n
/// \b val - value of data\n
///
/// \brief gets information about active block allocations
///
////////////////////////////////////////////////////////////////////////////////
function getBlockAllocationData() {
$affilid = getDashboardAffilID();
# active block allocation
if($affilid == 0) {
$query = "SELECT COUNT(id) "
. "FROM blockTimes "
. "WHERE skip = 0 AND "
. "start < NOW() AND "
. "end > NOW()";
}
else {
$query = "SELECT COUNT(bt.id) "
. "FROM blockTimes bt, "
. "blockRequest br, "
. "user u "
. "WHERE bt.blockRequestid = br.id AND "
. "br.ownerid = u.id AND "
. "u.affiliationid = $affilid AND "
. "bt.skip = 0 AND "
. "bt.start < NOW() AND "
. "bt.end > NOW()";
}
$qh = doQuery($query, 101);
$row = mysqli_fetch_row($qh);
$blockcount = $row[0];
# computers in blockComputers for active allocations
if($affilid == 0) {
$query = "SELECT bc.computerid, "
. "c.stateid "
. "FROM blockComputers bc "
. "LEFT JOIN computer c ON (c.id = bc.computerid) "
. "LEFT JOIN blockTimes bt ON (bt.id = bc.blockTimeid) "
. "WHERE c.stateid IN (2, 3, 6, 8, 19) AND "
. "bt.start < NOW() AND "
. "bt.end > NOW()";
}
else {
$query = "SELECT bc.computerid, "
. "c.stateid "
. "FROM blockComputers bc "
. "LEFT JOIN computer c ON (c.id = bc.computerid) "
. "LEFT JOIN blockTimes bt ON (bt.id = bc.blockTimeid) "
. "LEFT JOIN blockRequest br ON (bt.blockRequestid = br.id) "
. "LEFT JOIN user u ON (br.ownerid = u.id) "
. "WHERE u.affiliationid = $affilid AND "
. "c.stateid IN (2, 3, 6, 8, 19) AND "
. "bt.start < NOW() AND "
. "bt.end > NOW()";
}
$qh = doQuery($query, 101);
$total = 0;
$used = 0;
while($row = mysqli_fetch_assoc($qh)) {
$total++;
if($row['stateid'] == 3 || $row['stateid'] == 8)
$used++;
}
if($total)
$compused = sprintf('%d / %d (%0.2f %%)', $used, $total, ($used / $total * 100));
else
$compused = 0;
# number of computers that should be allocated
if($affilid == 0) {
$query = "SELECT br.numMachines "
. "FROM blockRequest br "
. "LEFT JOIN blockTimes bt ON (bt.blockRequestid = br.id) "
. "WHERE bt.start < NOW() AND "
. "bt.end > NOW() AND "
. "bt.skip = 0";
}
else {
$query = "SELECT br.numMachines "
. "FROM blockRequest br "
. "LEFT JOIN blockTimes bt ON (bt.blockRequestid = br.id) "
. "LEFT JOIN user u ON (br.ownerid = u.id) "
. "WHERE u.affiliationid = $affilid AND "
. "bt.start < NOW() AND "
. "bt.end > NOW() AND "
. "bt.skip = 0";
}
$alloc = 0;
$qh = doQuery($query, 101);
while($row = mysqli_fetch_assoc($qh))
$alloc += $row['numMachines'];
if($alloc)
$failed = sprintf('%d / %d (%0.2f %%)', ($alloc - $total), $alloc, (($alloc - $total) / $alloc * 100));
else
$failed = 0;
$data = array();
$data[] = array('title' => 'Active Block Allocations', 'val' => $blockcount);
$data[] = array('title' => 'Block Computer Usage', 'val' => $compused);
$data[] = array('title' => 'Failed Block Computers', 'val' => $failed);
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getNewReservationData()
///
/// \return array of data with these keys:\n
/// \b computer - hostname of computer (without domain)\n
/// \b image - image being loaded\n
/// \b id - id of request\n
/// \b start - start date\n
/// \b state - current and last state\n
/// \b installtype - install for reservation\n
/// \b managementnode - hostname of mangementnode
///
/// \brief gets information about loading reservations
///
////////////////////////////////////////////////////////////////////////////////
function getNewReservationData() {
$affilid = getDashboardAffilID();
$query = "SELECT c.hostname AS computer, "
. "h.hostname AS vmhost, "
. "i.prettyname AS image, "
. "rq.id, "
. "UNIX_TIMESTAMP(rq.start) AS start, "
. "CONCAT(s1.name, '|', s2.name) AS state, "
. "o.installtype, "
. "m.hostname AS managementnode, "
. "CONCAT(u.unityid, '@', af.name) AS user "
. "FROM request rq "
. "LEFT JOIN reservation rs ON (rs.requestid = rq.id) "
. "LEFT JOIN computer c ON (c.id = rs.computerid) "
. "LEFT JOIN vmhost vh ON (c.vmhostid = vh.id) "
. "LEFT JOIN computer h ON (h.id = vh.computerid) "
. "LEFT JOIN image i ON (i.id = rs.imageid) "
. "LEFT JOIN OS o ON (o.id = i.OSid) "
. "LEFT JOIN state s1 ON (s1.id = rq.stateid) "
. "LEFT JOIN state s2 ON (s2.id = rq.laststateid) "
. "LEFT JOIN managementnode m ON (m.id = rs.managementnodeid) "
. "LEFT JOIN user u ON (u.id = rq.userid) "
. "LEFT JOIN user u2 ON (u2.id = c.ownerid) "
. "LEFT JOIN affiliation af ON (af.id = u.affiliationid) "
. "WHERE ((rq.stateid IN (6, 13, 16, 19, 24) AND rq.start < NOW()) OR "
. "(rq.stateid = 14 AND rq.laststateid IN (6, 13, 16, 19, 24) AND "
. "rq.start < DATE_ADD(NOW(), INTERVAL 1 HOUR))) ";
if($affilid)
$query .= "AND (u.affiliationid = $affilid OR u2.affiliationid = $affilid) ";
$query .= "ORDER BY rq.start";
$qh = doQuery($query, 101);
$data = array();
while($row = mysqli_fetch_assoc($qh)) {
$tmp = explode('.', $row['computer']);
$row['computer'] = $tmp[0];
$tmp = explode('.', $row['vmhost']);
$row['vmhost'] = $tmp[0];
$row['start'] = date('D h:i', $row['start']);
$tmp = explode('.', $row['managementnode']);
$row['managementnode'] = $tmp[0];
$data[] = $row;
}
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getFailedImagingData()
///
/// \return array of data with these keys:\n
/// \b computer - hostname of computer (without domain)\n
/// \b image - image being loaded\n
/// \b id - id of request\n
/// \b start - start date\n
/// \b state - current and last state\n
/// \b installtype - install for reservation\n
/// \b managementnode - hostname of mangementnode
///
/// \brief gets information about loading reservations
///
////////////////////////////////////////////////////////////////////////////////
function getFailedImagingData() {
$affilid = getDashboardAffilID();
$query = "SELECT c.hostname AS computer, "
. "i.prettyname AS image, "
. "ir.comments AS revisioncomments, "
. "rq.id, "
. "rq.start, "
. "o.installtype, "
. "m.hostname AS managementnode, "
. "ch.hostname AS vmhost, "
. "u.unityid AS owner "
. "FROM request rq "
. "LEFT JOIN reservation rs ON (rs.requestid = rq.id) "
. "LEFT JOIN computer c ON (c.id = rs.computerid) "
. "LEFT JOIN image i ON (i.id = rs.imageid) "
. "LEFT JOIN imagerevision ir ON (ir.id = rs.imagerevisionid) "
. "LEFT JOIN OS o ON (o.id = i.OSid) "
. "LEFT JOIN managementnode m ON (m.id = rs.managementnodeid) "
. "LEFT JOIN vmhost vh ON (c.vmhostid = vh.id) "
. "LEFT JOIN computer ch ON (vh.computerid = ch.id) "
. "LEFT JOIN user u ON (rq.userid = u.id) "
. "LEFT JOIN user u2 ON (u2.id = c.ownerid) "
. "LEFT JOIN state s1 ON (s1.id = rq.stateid) "
. "LEFT JOIN state s2 ON (s2.id = rq.laststateid) "
. "WHERE s1.name = 'maintenance' AND "
. "s2.name IN ('image','checkpoint')";
if($affilid)
$query .= "AND (u.affiliationid = $affilid OR u2.affiliationid = $affilid) ";
$query .= "ORDER BY rq.start";
$qh = doQuery($query, 101);
$data = array();
while($row = mysqli_fetch_assoc($qh)) {
if(is_null($row['revisioncomments']))
$row['revisioncomments'] = '(none)';
$tmp = explode('.', $row['computer']);
$row['computer'] = $tmp[0];
$tmp = explode('.', $row['vmhost']);
$row['vmhost'] = $tmp[0];
$tmp = explode(' ', $row['start']);
$row['start'] = "{$tmp[0]}<br>{$tmp[1]}";
$tmp = explode('.', $row['managementnode']);
$row['managementnode'] = $tmp[0];
if($row['vmhost'] == '')
$row['vmhost'] = "N/A";
$row['contid'] = addContinuationsEntry('AJrestartImageCapture', array('requestid' => $row['id']), 120, 1, 0);
$data[] = $row;
}
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getManagementNodeData()
///
/// \return array of data with these keys:\n
/// \b computer - hostname of computer (without domain)\n
/// \b image - image being loaded\n
/// \b id - id of request\n
/// \b start - start date\n
/// \b state - current and last state\n
/// \b installtype - install for reservation\n
/// \b managementnode - hostname of mangementnode
///
/// \brief gets information about management nodes
///
////////////////////////////////////////////////////////////////////////////////
function getManagementNodeData() {
$affilid = getDashboardAffilID();
$query = "SELECT m.hostname, "
. "UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(m.lastcheckin) AS checkin, "
. "COUNT(rs2.id) as processing, "
. "m.stateid "
. "FROM managementnode m "
. "LEFT JOIN reservation rs ON (rs.managementnodeid = m.id) "
. "LEFT JOIN request rq ON (rq.id = rs.requestid) "
. "LEFT JOIN reservation rs2 ON (rs.id = rs2.id AND "
. "rs2.requestid = rq.id AND "
. "rq.start < NOW() AND "
. "rq.end > NOW()) "
. "LEFT JOIN user u ON (u.id = m.ownerid) "
. "WHERE m.stateid IN (2, 10) ";
if($affilid)
$query .= "AND u.affiliationid = $affilid ";
$query .= "GROUP BY m.id "
. "ORDER BY m.stateid, m.hostname";
$qh = doQuery($query);
$current = array();
$old = array();
$never = array();
while($row = mysqli_fetch_assoc($qh)) {
$tmp = explode('.', $row['hostname']);
$row['hostname'] = $tmp[0];
if($row['checkin'] < 0)
$row['checkin'] = 0;
if($row['checkin'] === null)
$never[] = $row;
elseif($row['checkin'] < 86400)
$current[] = $row;
else
$old[] = $row;
}
$data = array_merge($current, $old, $never);
return $data;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn restartImageCapture()
///
/// \return array of data with these keys:\n
/// \b computer - hostname of computer (without domain)\n
/// \b image - image being loaded\n
/// \b id - id of request\n
/// \b start - start date\n
/// \b state - current and last state\n
/// \b installtype - install for reservation\n
/// \b managementnode - hostname of mangementnode
///
/// \brief gets information about loading reservations
///
////////////////////////////////////////////////////////////////////////////////
function AJrestartImageCapture() {
$requestid = getContinuationVar('requestid');
if(! checkUserHasPerm('View Dashboard (global)')) {
sendJSON(array('status' => 'noaccess'));
return;
}
$request = getRequestInfo($requestid);
if($request['stateid'] != 10 ||
($request['laststateid'] != 16 && $request['laststateid'] != 24) ||
count($request['reservations']) > 1) {
sendJSON(array('status' => 'wrongstate'));
return;
}
$compid = $request['reservations'][0]['computerid'];
$query = "UPDATE computer c, "
. "request rq "
. "SET c.stateid = 8, "
. "rq.stateid = {$request['laststateid']}, "
. "rq.laststateid = 10 "
. "WHERE c.id = $compid AND "
. "rq.id = $requestid";
doQuery($query);
sendJSON(array('status' => 'success'));
}
////////////////////////////////////////////////////////////////////////////////
///
/// \fn getDashboardAffilID()
///
/// \return an affiliation id
///
/// \brief if user has access to view the dashboard for any affiliation, returns
/// selected affiliationid; otherwise, returns user's affiliationid
///
////////////////////////////////////////////////////////////////////////////////
function getDashboardAffilID() {
global $user;
if(! checkUserHasPerm('View Dashboard (global)'))
return $user['affiliationid'];
$affilid = getContinuationVar('affilid', processInputVar('affilid', ARG_NUMERIC, 0));
$affils = getAffiliations();
if($affilid != 0 && ! array_key_exists($affilid, $affils))
return 0;
return $affilid;
}
?>