function detailStatusHTML($reqid) { $requests = getUserRequests("all"); $found = 0; foreach ($requests as $request) { if ($request['id'] == $reqid) { $found = 1; break; } } if (!$found) { $text = i("The selected reservation is no longer available. You can request a new reservation or select another one that is available."); return $text; } if ($request['currstateid'] == 11 || $request['currstateid'] == 12 && $request['laststateid'] == 11) { return "<br><span class=\"rederrormsg\">" . i("The selected reservation has timed out and is no longer available.") . "</span>"; } if ($request['imageid'] == $request['compimageid']) { $nowreq = 1; } else { $nowreq = 0; } $flow = getCompStateFlow($request['computerid']); # cluster reservations not supported here yet # info on reboots/reinstalls not available yet if (empty($flow) || count($request['reservations']) > 0 || $request['currstateid'] == 14 && $request['laststateid'] == 26 || $request['currstateid'] == 14 && $request['laststateid'] == 24 || $request['currstateid'] == 14 && $request['laststateid'] == 28) { $noinfo = i("No detailed loading information is available for this reservation."); return $noinfo; } $logdata = getCompLoadLog($request['resid']); # determine an estimated load time for the image $imgLoadTime = getImageLoadEstimate($request['imageid']); if ($imgLoadTime == 0) { $images = getImages(0, $request['imageid']); $imgLoadTime = $images[$request['imageid']]['reloadtime'] * 60; } $time = 0; $now = time(); $text = "<table summary=\"displays a list of states the reservation must " . "go through to become ready and how long each state will take or " . "has already taken\" id=resStatusTable>"; $text .= "<colgroup>"; $text .= "<col class=resStatusColState />"; $text .= "<col class=resStatusColEst />"; $text .= "<col class=resStatusColTotal />"; $text .= "</colgroup>"; $text .= "<tr>"; $text .= "<th align=right><br>" . i("State") . "</th>"; $text .= "<th>Est/Act<br>" . i("Time") . "</th>"; $text .= "<th>Total<br>" . i("Time") . "</th>"; $text .= "</tr>"; $slash = "<font color=black>/</font>"; $total = 0; $id = ""; $last = array(); $logstateids = array(); $skippedstates = array(); # loop through all states in the log data foreach ($logdata as $data) { # keep track of the states in the log data array_push($logstateids, $data['loadstateid']); # keep track of any skipped states if (!empty($last) && $last['loadstateid'] != $flow['repeatid'] && $data['loadstateid'] != $flow['data'][$last['loadstateid']]['nextstateid']) { array_push($skippedstates, $flow['data'][$last['loadstateid']]['nextstateid']); } // if we reach a repeat state, include a message about having to go back if ($data['loadstateid'] == $flow['repeatid']) { if (empty($id)) { return $noinfo; } $text .= "<tr>"; $text .= "<td colspan=3><hr>" . i("problem at state"); $text .= " \"{$flow['data'][$id]['nextstate']}\""; $query = "SELECT additionalinfo " . "FROM computerloadlog " . "WHERE loadstateid = {$flow['repeatid']} AND " . "reservationid = {$request['resid']} AND " . "timestamp = '" . unixToDatetime($data['ts']) . "'"; $qh = doQuery($query, 101); if ($row = mysql_fetch_assoc($qh)) { $reason = $row['additionalinfo']; $text .= "<br>" . i("retrying at state") . " \"{$reason}\""; } $text .= "<hr></td></tr>"; $total += $data['time']; $last = $data; continue; } $id = $data['loadstateid']; // if in post config state, compute estimated time for the state if ($flow['data'][$id]['statename'] == 'loadimagecomplete') { $addtime = 0; foreach ($skippedstates as $stateid) { $addtime += $flow['data'][$stateid]['statetime']; } # this state's time is (avg image load time - all other states time + # state time for any skipped states) $tmp = $imgLoadTime - $flow['totaltime'] + $addtime; if ($tmp < 0) { $flow['data'][$id]['statetime'] = 0; } else { $flow['data'][$id]['statetime'] = $tmp; } } $total += $data['time']; $text .= "<tr>"; $text .= "<td nowrap align=right><font color=green>"; $text .= i($flow['data'][$id]['state']) . "({$id})</font></td>"; $text .= "<td nowrap align=center><font color=green>"; $text .= secToMinSec($flow['data'][$id]['statetime']) . $slash; $text .= secToMinSec($data['time']) . "</font></td>"; $text .= "<td nowrap align=center><font color=green>"; $text .= secToMinSec($total) . "</font></td>"; $text .= "</tr>"; $last = $data; } # $id will be set if there was log data, use the first state in the flow // if it isn't set if (!empty($id)) { $id = $flow['nextstates'][$id]; } else { $id = $flow['stateids'][0]; } # determine any skipped states $matchingstates = array(); foreach ($flow['stateids'] as $stateid) { if ($stateid == $id) { break; } array_push($matchingstates, $stateid); } $skippedstates = array_diff($matchingstates, $logstateids); $addtime = 0; foreach ($skippedstates as $stateid) { $addtime += $flow['data'][$stateid]['statetime']; } $first = 1; $count = 0; # loop through the states in the flow that haven't been reached yet # $count is included to protect against an infinite loop while (!is_null($id) && $count < 100) { $count++; // if in post config state, compute estimated time for the state if ($flow['data'][$id]['statename'] == 'loadimagecomplete') { # this state's time is (avg image load time - all other states time + # state time for any skipped states) $tmp = $imgLoadTime - $flow['totaltime'] + $addtime; if ($tmp < 0) { $flow['data'][$id]['statetime'] = 0; } else { $flow['data'][$id]['statetime'] = $tmp; } } // if first time through this loop, this is the current state if ($first) { // if request has failed, it was during this state, get reason if ($request['currstateid'] == 5) { $query = "SELECT additionalInfo, " . "UNIX_TIMESTAMP(timestamp) AS ts " . "FROM computerloadlog " . "WHERE loadstateid = (SELECT id " . "FROM computerloadstate " . "WHERE loadstatename = 'failed') AND " . "reservationid = {$request['resid']} " . "ORDER BY id " . "LIMIT 1"; $qh = doQuery($query, 101); if ($row = mysql_fetch_assoc($qh)) { $reason = $row['additionalInfo']; if (!empty($data)) { $currtime = $row['ts'] - $data['ts']; } else { $currtime = $row['ts'] - datetimeToUnix($request['daterequested']); } } else { $text = i("No detailed information is available for this reservation."); return $text; } $text .= "<tr>"; $text .= "<td nowrap align=right><font color=red>"; $text .= i($flow['data'][$id]['state']) . "({$id})</font></td>"; $text .= "<td nowrap align=center><font color=red>"; $text .= secToMinSec($flow['data'][$id]['statetime']); $text .= $slash . secToMinSec($currtime) . "</font></td>"; $text .= "<td nowrap align=center><font color=red>"; $text .= secToMinSec($total + $currtime) . "</font></td>"; $text .= "</tr>"; $text .= "</table>"; if (strlen($reason)) { $text .= "<br><font color=red>" . i("failed:") . " {$reason}</font>"; } return $text; } else { if (!empty($data)) { $currtime = $now - $data['ts']; } else { $currtime = $now - datetimeToUnix($request['daterequested']); } $text .= "<td nowrap align=right><font color=#CC8500>"; $text .= i($flow['data'][$id]['state']) . "({$id})</font></td>"; $text .= "<td nowrap align=center><font color=#CC8500>"; $text .= secToMinSec($flow['data'][$id]['statetime']); $text .= $slash . secToMinSec($currtime) . "</font></td>"; $text .= "<td nowrap align=center><font color=#CC8500>"; $text .= secToMinSec($total + $currtime) . "</font></td>"; $text .= "</tr>"; $first = 0; } } else { $text .= "<td nowrap align=right>"; $text .= i($flow['data'][$id]['state']) . "({$id})</td>"; $text .= "<td nowrap align=center>"; $text .= secToMinSec($flow['data'][$id]['statetime']) . "</td>"; $text .= "<td></td>"; $text .= "</tr>"; } $id = $flow['nextstates'][$id]; } $text .= "</table>"; return $text; }
function getCompLoadLog($resid) { $query = "SELECT UNIX_TIMESTAMP(rq.start) AS start, " . "UNIX_TIMESTAMP(rq.daterequested) AS reqtime, " . "rs.computerid " . "FROM request rq, " . "reservation rs " . "WHERE rs.id = {$resid} AND " . "rs.requestid = rq.id " . "LIMIT 1"; $qh = doQuery($query, 101); if (!($row = mysql_fetch_assoc($qh))) { abort(113); } if ($row['start'] < $row['reqtime']) { $firststart = $row['reqtime']; } else { $firststart = $row['start']; } $flow = getCompStateFlow($row['computerid']); $instates = implode(',', $flow['stateids']); $query = "SELECT id, " . "computerid, " . "loadstateid, " . "UNIX_TIMESTAMP(timestamp) AS ts " . "FROM computerloadlog " . "WHERE reservationid = {$resid} AND " . "(loadstateid IN ({$instates}) OR " . "loadstateid = {$flow['repeatid']}) " . "ORDER BY id"; $qh = doQuery($query, 101); $last = array(); $data = array(); while ($row = mysql_fetch_assoc($qh)) { $data[$row['id']] = $row; if (empty($last)) { $data[$row['id']]['time'] = $row['ts'] - $firststart; } else { $data[$row['id']]['time'] = $row['ts'] - $last['ts']; } $last = $row; } return $data; }