Author: jfthomps Date: Thu Jun 2 19:45:34 2011 New Revision: 1130769 URL: http://svn.apache.org/viewvc?rev=1130769&view=rev Log: VCL-463 VCL-367
authentication.php: modified checkExpiredDemoUser - added call to checkUpdateServerRequestGroups requests.php: -modified viewRequests - only show connect if request is ready and user account is created; added button and confirmation dialog to remove failed and timed out reservations -modified AJeditRequest - added ability to modify admin or login group for server requests -modified AJsubmitEditRequest - added checking of and updating of submitted admin and login groups -added AJconfirmRemoveRequest -added AJsubmitRemoveRequest -modified connectRequest - if request is timedout or completed, show message to user and do not display connect information serverprofiles.php: -filled in all missing function header documentation -changed occurances of & in html to & -modified deployHTML - added "(optional)" to fixedIP and fixedMAC inputs -fixed several places that were missing a closing quote -made monitored input hidden since it is not supported yet -removed type=text values from date and time inputs that are defined as divs states.php: -added AJconfirmRemoveRequest -added AJsubmitRemoveRequest utils.php: -modified addUserGroupMember - added call to checkUpdateServerRequestGroups -modified deleteUserGroupMember - added call to checkUpdateServerRequestGroups -modified getRequestInfo - added admingroupid and logingroupid to returned array -modified getUserRequests - added useraccountready to returned array for each request - set based on there being an entry in reservationaccounts -modified requestIsReady - added check for servermodified state -modified updateGroups - added call to checkUpdateServerRequestGroups -added checkUpdateServerRequestGroups -modified sendRDPfile - if request is timedout or completed, redirect user to Current Reservations page; removed exit from end of function -modified getDojoHTML - added dijit.form.FilteringSelect to viewRequests requests.js: -added removeReservation -added removeReservationCB -added submitRemoveReservation -modified hideEditResDlg - destroy admingrpsel and logingrpsel if they exist -modified submitEditReservation - submit admingroupid and logingroupid if input for them exists Modified: incubator/vcl/trunk/web/.ht-inc/authentication.php incubator/vcl/trunk/web/.ht-inc/requests.php incubator/vcl/trunk/web/.ht-inc/serverprofiles.php incubator/vcl/trunk/web/.ht-inc/states.php incubator/vcl/trunk/web/.ht-inc/utils.php incubator/vcl/trunk/web/js/requests.js Modified: incubator/vcl/trunk/web/.ht-inc/authentication.php URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/authentication.php?rev=1130769&r1=1130768&r2=1130769&view=diff ============================================================================== --- incubator/vcl/trunk/web/.ht-inc/authentication.php (original) +++ incubator/vcl/trunk/web/.ht-inc/authentication.php Thu Jun 2 19:45:34 2011 @@ -628,6 +628,7 @@ function checkExpiredDemoUser($userid, $ # delete from custom groups doQuery($query, 101); updateGroups(array($nodemoid), $userid); + checkUpdateServerRequestGroups($groupid); if(empty($skin)) { $skin = 'default'; require_once("themes/$skin/page.php"); Modified: incubator/vcl/trunk/web/.ht-inc/requests.php URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/requests.php?rev=1130769&r1=1130768&r2=1130769&view=diff ============================================================================== --- incubator/vcl/trunk/web/.ht-inc/requests.php (original) +++ incubator/vcl/trunk/web/.ht-inc/requests.php Thu Jun 2 19:45:34 2011 @@ -638,6 +638,7 @@ function viewRequests() { if(checkUserHasPerm('View Debug Information')) $nodes = getManagementNodes(); if($count = count($requests)) { + # TODO display admin and login groups somewhere $now = time(); for($i = 0, $failed = 0, $timedout = 0, $text = '', $showcreateimage = 0; $i < $count; @@ -650,7 +651,7 @@ function viewRequests() { $imageid = $requests[$i]["imageid"]; $text .= " <TR valign=top id=reqrow{$requests[$i]['id']}>\n"; # TODO probably should display current status somewhere if checkpointing, rebooting, or reinstalling - if(requestIsReady($requests[$i])) { + if(requestIsReady($requests[$i]) && $requests[$i]['useraccountready']) { $connect = 1; # request is ready, print Connect! and End buttons $text .= " <TD>\n"; @@ -679,8 +680,7 @@ function viewRequests() { } elseif($requests[$i]["currstateid"] == 5) { # request has failed - # TODO add a way for users to remove these entries - $text .= " <TD colspan=2 nowrap>\n"; + $text .= " <TD nowrap>\n"; $text .= " <span class=scriptonly>\n"; $text .= " <span class=compstatelink>"; $text .= "<a onClick=\"showResStatusPane({$requests[$i]['id']}); "; @@ -693,6 +693,19 @@ function viewRequests() { $text .= " </span>\n"; $text .= " </noscript>\n"; $text .= " </TD>\n"; + if($requests[$i]['serveradmin']) { + $text .= " <TD>\n"; + $cont = addContinuationsEntry('AJconfirmRemoveRequest', $cdata, SECINDAY); + $text .= " <button dojoType=\"dijit.form.Button\">\n"; + $text .= " Remove\n"; + $text .= " <script type=\"dojo/method\" event=\"onClick\">\n"; + $text .= " removeReservation('$cont');\n"; + $text .= " </script>\n"; + $text .= " </button>\n"; + $text .= " </TD>\n"; + } + else + $text .= " <TD></TD>\n"; $failed = 1; } elseif(datetimeToUnix($requests[$i]["start"]) < $now) { @@ -703,19 +716,32 @@ function viewRequests() { ($requests[$i]["currstateid"] == 14 && $requests[$i]["laststateid"] == 11)) { # request has timed out - # TODO add a way for users to remove these entries if($requests[$i]['forimaging']) - $text .= " <TD colspan=3>\n"; - else $text .= " <TD colspan=2>\n"; + else + $text .= " <TD>\n"; $text .= " <span class=compstatelink>Reservation has "; $text .= "timed out</span>\n"; $timedout = 1; $text .= " </TD>\n"; + if($requests[$i]['serveradmin']) { + $text .= " <TD>\n"; + $cont = addContinuationsEntry('AJconfirmRemoveRequest', $cdata, SECINDAY); + $text .= " <button dojoType=\"dijit.form.Button\">\n"; + $text .= " Remove\n"; + $text .= " <script type=\"dojo/method\" event=\"onClick\">\n"; + $text .= " removeReservation('$cont');\n"; + $text .= " </script>\n"; + $text .= " </button>\n"; + $text .= " </TD>\n"; + } + else + $text .= " <TD></TD>\n"; } else { # computer is loading, print Pending... and Delete button # TODO figure out a different way to estimate for reboot and reinstall states + # TODO if user account not ready, print accurate information in details $remaining = 1; if(isComputerLoading($requests[$i], $computers)) { if(datetimeToUnix($requests[$i]["daterequested"]) >= @@ -818,9 +844,8 @@ function viewRequests() { $text .= " label=\"End Reservation & Create Image\" disabled>\n"; $text .= " </div>\n"; }*/ - # TODO control which users get to see this - if($requests[$i]['server'] && $requests[$i]['currstateid'] != 24 && - ($requests[$i]['currstateid'] == 8 || $requests[$i]['laststateid'] == 8)) { + if($requests[$i]['server'] && ($requests[$i]['currstateid'] == 8 || + ($requests[$i]['currstateid'] == 14 && $requests[$i]['laststateid'] == 8))) { $cont = addContinuationsEntry('startCheckpoint', $cdata, SECINDAY); $url = BASEURL . SCRIPT . "?continuation=$cont"; $text .= " <div dojoType=\"dijit.MenuItem\"\n"; @@ -1103,6 +1128,30 @@ function viewRequests() { $text .= "</div>\n"; $text .= "<div dojoType=dijit.Dialog\n"; + $text .= " id=\"remResDlg\"\n"; + $text .= " title=\"Remove Reservation\"\n"; + $text .= " duration=250\n"; + $text .= " draggable=true>\n"; + $text .= " <div id=\"remResDlgContent\"></div>\n"; + $text .= " <input type=\"hidden\" id=\"remrescont\">\n"; + $text .= " <div align=\"center\">\n"; + $text .= " <button id=\"remResDlgBtn\" dojoType=\"dijit.form.Button\">\n"; + $text .= " Remove Reservation\n"; + $text .= " <script type=\"dojo/method\" event=\"onClick\">\n"; + $text .= " submitRemoveReservation();\n"; + $text .= " </script>\n"; + $text .= " </button>\n"; + $text .= " <button dojoType=\"dijit.form.Button\">\n"; + $text .= " Cancel\n"; + $text .= " <script type=\"dojo/method\" event=\"onClick\">\n"; + $text .= " dijit.byId('remResDlg').hide();\n"; + $text .= " dojo.byId('remResDlgContent').innerHTML = '';\n"; + $text .= " </script>\n"; + $text .= " </button>\n"; + $text .= " </div>\n"; + $text .= "</div>\n"; + + $text .= "<div dojoType=dijit.Dialog\n"; $text .= " id=\"editResDlg\"\n"; $text .= " title=\"Modify Reservation\"\n"; $text .= " duration=250\n"; @@ -1615,6 +1664,42 @@ function AJeditRequest() { 'openend' => $openend, 'modifystart' => 0, 'allowindefiniteend' => 0); + if($request['serverrequest']) { + if($user['showallgroups']) + $groups = getUserGroups(1); + else + $groups = getUserGroups(1, $user['affiliationid']); + $h .= "Admin User Group: "; + if(USEFILTERINGSELECT && count($groups) < FILTERINGSELECTTHRESHOLD) { + $h .= "<select dojoType=\"dijit.form.FilteringSelect\" id=\"admingrpsel\" "; + $h .= "highlightMatch=\"all\" autoComplete=\"false\">"; + } + else + $h .= "<select id=\"admingrpsel\">"; + $h .= "<option value=\"0\">None</option>\n"; + foreach($groups as $id => $group) { + if($id == $request['admingroupid']) + $h .= "<option value=\"$id\" selected>{$group['name']}</option>"; + else + $h .= "<option value=\"$id\">{$group['name']}</option>"; + } + $h .= "</select><br>"; + $h .= "Access User Group: "; + if(USEFILTERINGSELECT && count($groups) < FILTERINGSELECTTHRESHOLD) { + $h .= "<select dojoType=\"dijit.form.FilteringSelect\" id=\"logingrpsel\" "; + $h .= "highlightMatch=\"all\" autoComplete=\"false\">"; + } + else + $h .= "<select id=\"logingrpsel\">"; + $h .= "<option value=\"0\">None</option>\n"; + foreach($groups as $id => $group) { + if($id == $request['logingroupid']) + $h .= "<option value=\"$id\" selected>{$group['name']}</option>"; + else + $h .= "<option value=\"$id\">{$group['name']}</option>"; + } + $h .= "</select><br><br>"; + } // if future, allow start to be modified if($unixstart > $now) { $cdata['modifystart'] = 1; @@ -2007,6 +2092,27 @@ function AJsubmitEditRequest() { 'cont' => $cont)); return; } + $updategroups = 0; + if($request['serverrequest']) { + if($user['showallgroups']) + $groups = getUserGroups(1); + else + $groups = getUserGroups(1, $user['affiliationid']); + $admingroupid = processInputVar('admingroupid', ARG_NUMERIC); + $logingroupid = processInputVar('logingroupid', ARG_NUMERIC); + if(($admingroupid != 0 && ! array_key_exists($admingroupid, $groups)) || + ($logingroupid != 0 && ! array_key_exists($logingroupid, $groups))) { + $cdata = getContinuationVar(); + $cont = addContinuationsEntry('AJsubmitEditRequest', $cdata, SECINDAY, 1, 0); + sendJSON(array('status' => 'error', + 'errmsg' => "Invalid user group submitted", + 'cont' => $cont)); + return; + } + if($admingroupid != $request['admingroupid'] || + $logingroupid != $request['logingroupid']) + $updategroups = 1; + } // get semaphore lock if(! semLock()) @@ -2053,6 +2159,17 @@ function AJsubmitEditRequest() { } elseif($rc > 0) { updateRequest($requestid); + if($updategroups) { + $query = "UPDATE serverrequest " + . "SET admingroupid = $admingroupid, " + . "logingroupid = $logingroupid " + . "WHERE requestid = $requestid"; + doQuery($query, 101); + $query = "UPDATE request " + . "SET stateid = 29 " + . "WHERE id = $requestid"; + doQuery($query, 101); + } sendJSON(array('status' => 'success')); semUnlock(); return; @@ -2219,6 +2336,80 @@ function AJsubmitDeleteRequest() { //////////////////////////////////////////////////////////////////////////////// /// +/// \fn AJconfirmRemoveRequest() +/// +/// \brief populates a confirmation dialog box +/// +//////////////////////////////////////////////////////////////////////////////// +function AJconfirmRemoveRequest() { + $requestid = getContinuationVar('requestid', 0); + $request = getRequestInfo($requestid, 1); + if(is_null($request)) { + $data = array('error' => 1, + 'msg' => "The specified reservation no longer exists."); + sendJSON($data); + return; + } + if($request['stateid'] != 11 && $request['laststateid'] != 11 && + $request['stateid'] != 12 && $request['laststateid'] != 12 && + $request['stateid'] != 5 && $request['laststateid'] != 5) { + $data = array('error' => 2, + 'msg' => "The reservation is no longer failed or timed out.", + 'url' => BASEURL . SCRIPT . "?mode=viewRequests"); + sendJSON($data); + return; + } + if($request['stateid'] == 11 || $request['stateid'] == 12 || + $request['stateid'] == 12 || $request['laststateid'] == 12) { + $text = "Remove timed out reservation from list of current "; + $text .= "reservations?<br>\n"; + } + else { + $text = "Remove failed reservation from list of current reservations?"; + $text .= "<br>\n"; + } + $cdata = array('requestid' => $requestid); + $cont = addContinuationsEntry('AJsubmitRemoveRequest', $cdata, SECINDAY, 0, 0); + $text = preg_replace("/(.{1,60}[ \n])/", '\1<br>', $text); + $data = array('content' => $text, + 'cont' => $cont); + sendJSON($data); +} + +//////////////////////////////////////////////////////////////////////////////// +/// +/// \fn AJsubmitRemoveRequest() +/// +/// \brief submits deleting a request and prints that it has been deleted +/// +//////////////////////////////////////////////////////////////////////////////// +function AJsubmitRemoveRequest() { + global $mode; + $mode = 'AJviewRequests'; + $requestid = getContinuationVar('requestid', 0); + $request = getRequestInfo($requestid, 1); + if(is_null($requestid)) { + viewRequests(); + return; + } + + if($request['serverrequest']) { + $query = "DELETE FROM serverrequest WHERE requestid = $requestid"; + doQuery($query, 152); + } + + # TODO do these need to set state to complete? + $query = "DELETE FROM request WHERE id = $requestid"; + doQuery($query, 153); + + $query = "DELETE FROM reservation WHERE requestid = $requestid"; + doQuery($query, 154); + + viewRequests(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// /// \fn AJrebootRequest() /// /// \brief sets a reservation to the reboot state and refreshes the Current @@ -2422,6 +2613,14 @@ function connectRequest() { else $requestid = processInputVar("requestid", ARG_NUMERIC); $requestData = getRequestInfo($requestid); + if($requestData['stateid'] == 11 || $requestData['stateid'] == 12 || + ($requestData['stateid'] == 14 && + ($requestData['laststateid'] == 11 || $requestData['laststateid'] == 12))) { + print "<H2 align=center>Connect!</H2>\n"; + print "This reservation has timed out due to lack of user activity and "; + print "is no longer available.<br>\n"; + return; + } if($requestData['reservations'][0]['remoteIP'] != $remoteIP) { $setback = unixToDatetime(time() - 600); $query = "UPDATE reservation " Modified: incubator/vcl/trunk/web/.ht-inc/serverprofiles.php URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/serverprofiles.php?rev=1130769&r1=1130768&r2=1130769&view=diff ============================================================================== --- incubator/vcl/trunk/web/.ht-inc/serverprofiles.php (original) +++ incubator/vcl/trunk/web/.ht-inc/serverprofiles.php Thu Jun 2 19:45:34 2011 @@ -22,13 +22,9 @@ //////////////////////////////////////////////////////////////////////////////// /// -/// \fn +/// \fn serverProfiles() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief prints server profile page /// //////////////////////////////////////////////////////////////////////////////// function serverProfiles() { @@ -36,7 +32,7 @@ function serverProfiles() { print "data=\"profilesstoredata\"></div>\n"; print "<div id=\"mainTabContainer\" dojoType=\"dijit.layout.TabContainer\"\n"; print " style=\"width:630px;height:600px\">\n"; - print "<div id=\"deploytab\" dojoType=\"dijit.layout.ContentPane\" title=\"Shake & Bake\" selected=\"true\">\n"; + print "<div id=\"deploytab\" dojoType=\"dijit.layout.ContentPane\" title=\"Shake & Bake\" selected=\"true\">\n"; $data = deployHTML(); print $data['html']; print "</div>\n"; # deploy tab @@ -58,20 +54,18 @@ function serverProfiles() { /// /// \fn deployHTML() /// -/// \param -/// -/// \return +/// \return an array with one element with a key of 'html' whose value is the +/// html content for the deploy tab /// -/// \brief +/// \brief builds the html for the deploy tab /// //////////////////////////////////////////////////////////////////////////////// function deployHTML() { global $user; $profiles = getServerProfiles(); - // TODO finish making this work correctly if there are no server profiles $h = ''; - $h .= "<h2>Shake & Bake</h2>\n"; + $h .= "<h2>Shake & Bake</h2>\n"; $h .= "<span id=\"deployprofileslist\""; if(! count($profiles)) $h .= " class=\"hidden\""; @@ -90,8 +84,8 @@ function deployHTML() { $h .= " getServerProfileData('$cont', 'deployprofileid', getServerProfileDataDeployCB);\n"; $h .= " </script>\n"; $h .= "</button>"; - $h .= "</span>\n"; # deployprofileslist $h .= "<br><hr><br>\n"; + $h .= "</span>\n"; # deployprofileslist $h .= "<div id=\"deployprofilediv\">\n"; $h .= "<table summary=\"\">\n"; @@ -107,8 +101,10 @@ function deployHTML() { } else $h .= " <select dojoType=\"dijit.form.Select\" id=\"deployimage\">\n"; - foreach($images as $id => $image) + foreach($images as $id => $image) { + $image = preg_replace('/&/', '&', $image); $h .= " <option value=\"$id\">$image</option>\n"; + } $h .= " </select>\n"; $h .= " </td>\n"; $h .= " </tr>\n"; @@ -116,13 +112,13 @@ function deployHTML() { $h .= " <th align=right>Fixed IP Address:</th>\n"; $h .= " <td><input type=\"text\" id=\"deployfixedIP\" "; $h .= "dojoType=\"dijit.form.ValidationTextBox\" "; - $h .= "regExp=\"([0-9]{1,3}\\.){3}([0-9]{1,3})\"></td>\n"; + $h .= "regExp=\"([0-9]{1,3}\\.){3}([0-9]{1,3})\">(optional)</td>\n"; $h .= " </tr>\n"; $h .= " <tr>\n"; $h .= " <th align=right>Fixed MAC Address:</th>\n"; $h .= " <td><input type=\"text\" id=\"deployfixedMAC\" "; $h .= "dojoType=\"dijit.form.ValidationTextBox\" "; - $h .= "regExp=\"([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})\"></td>\n"; + $h .= "regExp=\"([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})\">(optional)</td>\n"; $h .= " </tr>\n"; $h .= " <tr>\n"; $h .= " <th align=right>Admin User Group:</th>\n"; @@ -134,7 +130,7 @@ function deployHTML() { $h .= "highlightMatch=\"all\" autoComplete=\"false\">\n"; } else - $h .= " <select dojoType=\"dijit.form.Select\" id=\"deployadmingroup>\n"; + $h .= " <select dojoType=\"dijit.form.Select\" id=\"deployadmingroup\">\n"; $h .= " <option value=\"0\">None</option>\n"; foreach($usergroups as $id => $group) $h .= " <option value=\"$id\">$group</option>\n"; @@ -150,14 +146,14 @@ function deployHTML() { $h .= "highlightMatch=\"all\" autoComplete=\"false\">\n"; } else - $h .= " <select dojoType=\"dijit.form.Select\" id=\"deploylogingroup>\n"; + $h .= " <select dojoType=\"dijit.form.Select\" id=\"deploylogingroup\">\n"; $h .= " <option value=\"0\">None</option>\n"; foreach($usergroups as $id => $group) $h .= " <option value=\"$id\">$group</option>\n"; $h .= " </select>\n"; $h .= " </td>\n"; $h .= " </tr>\n"; - $h .= " <tr>\n"; + $h .= " <tr class=\"hidden\">\n"; $h .= " <th align=right>Monitored:</th>\n"; $h .= " <td><input type=\"checkbox\" "; $h .= "id=\"deploymonitored\" dojoType=\"dijit.form.CheckBox\"></td>\n"; @@ -172,16 +168,16 @@ function deployHTML() { $h .= "<input type=\"radio\" id=\"startlater\" name=\"deploystart\" "; $h .= "onclick=\"setStartLater();\">\n"; $h .= "<label for=\"startlater\">Later:</label>\n"; - $h .= "<div type=\"text\" dojoType=\"dijit.form.DateTextBox\" "; + $h .= "<div dojoType=\"dijit.form.DateTextBox\" "; $h .= "id=\"deploystartdate\" onChange=\"setStartLater();\" "; $h .= "style=\"width: 78px\"></div>\n"; - $h .= "<div type=\"text\" id=\"deploystarttime\" dojoType=\"dijit.form.TimeTextBox\" "; + $h .= "<div id=\"deploystarttime\" dojoType=\"dijit.form.TimeTextBox\" "; $h .= "style=\"width: 78px\" onChange=\"setStartLater();\"></div>\n"; $h .= "<small>(" . date('T') . ")</small><br><br>\n"; $h .= "Ending for server:<br>\n"; $h .= " "; $h .= "<input type=\"radio\" id=\"endindef\" name=\"deployend\" "; - $h .= "onclick=\"setEndIndef();\" checked>\n"; + $h .= "onclick=\"setEndIndef();\" checked>\n"; # todo should this 'checked' be hard coded? $h .= "<label for=\"endindef\">Indefinite</label><br>\n"; $h .= " "; $h .= "<input type=\"radio\" id=\"endat\" name=\"deployend\" "; @@ -195,13 +191,13 @@ function deployHTML() { $h .= "<small>(" . date('T') . ")</small><br><br>\n"; $cont = addContinuationsEntry('AJdeployServer', array(), SECINDAY, 1, 0); $h .= "<button dojoType=\"dijit.form.Button\">\n"; - $h .= " Shake & Bake Server\n"; + $h .= " Shake & Bake Server\n"; $h .= " <script type=\"dojo/method\" event=onClick>\n"; $h .= " submitDeploy();\n"; $h .= " </script>\n"; $h .= "</button><br><br>\n"; $h .= "<input type=\"hidden\" id=\"deploycont\" value=\"$cont\">\n"; - $h .= "</div>\n"; # serverprofiledata + $h .= "</div>\n"; # serverprofilediv return array('html' => $h); } @@ -209,11 +205,10 @@ function deployHTML() { /// /// \fn manageProfilesHTML() /// -/// \param -/// -/// \return +/// \return an array with one element with a key of 'html' whose value is the +/// html content for the manage tab /// -/// \brief +/// \brief builds the html for the manage tab /// //////////////////////////////////////////////////////////////////////////////// function manageProfilesHTML() { @@ -276,7 +271,7 @@ function manageProfilesHTML() { $h .= "highlightMatch=\"all\" autoComplete=\"false\">\n"; } else - $h .= " <select dojoType=\"dijit.form.Select\" name=\"profileimage\" id=\"profileimage>\n"; + $h .= " <select dojoType=\"dijit.form.Select\" name=\"profileimage\" id=\"profileimage\">\n"; foreach($images as $id => $image) $h .= " <option value=\"$id\">$image</option>\n"; $h .= " </select>\n"; @@ -286,13 +281,13 @@ function manageProfilesHTML() { $h .= " <th align=right>Fixed IP Address:</th>\n"; $h .= " <td><input type=\"text\" name=\"profilefixedIP\" id=\"profilefixedIP\" "; $h .= "dojoType=\"dijit.form.ValidationTextBox\" "; - $h .= "regExp=\"([0-9]{1,3}\\.){3}([0-9]{1,3})\"></td>\n"; + $h .= "regExp=\"([0-9]{1,3}\\.){3}([0-9]{1,3})\">(optional)</td>\n"; $h .= " </tr>\n"; $h .= " <tr>\n"; $h .= " <th align=right>Fixed MAC Address:</th>\n"; $h .= " <td><input type=\"text\" name=\"profilefixedMAC\" id=\"profilefixedMAC\" "; $h .= "dojoType=\"dijit.form.ValidationTextBox\" "; - $h .= "regExp=\"([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})\"></td>\n"; + $h .= "regExp=\"([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})\">(optional)</td>\n"; $h .= " </tr>\n"; $h .= " <tr>\n"; $h .= " <th align=right>Admin User Group:</th>\n"; @@ -304,7 +299,7 @@ function manageProfilesHTML() { $h .= "highlightMatch=\"all\" autoComplete=\"false\">\n"; } else - $h .= " <select dojoType=\"dijit.form.Select\" name=\"profileadmingroup\" id=\"profileadmingroup>\n"; + $h .= " <select dojoType=\"dijit.form.Select\" name=\"profileadmingroup\" id=\"profileadmingroup\">\n"; $h .= " <option value=\"0\">None</option>\n"; foreach($usergroups as $id => $group) $h .= " <option value=\"$id\">$group</option>\n"; @@ -320,14 +315,14 @@ function manageProfilesHTML() { $h .= "highlightMatch=\"all\" autoComplete=\"false\">\n"; } else - $h .= " <select dojoType=\"dijit.form.Select\" name=\"profilelogingroup\" id=\"profilelogingroup>\n"; + $h .= " <select dojoType=\"dijit.form.Select\" name=\"profilelogingroup\" id=\"profilelogingroup\">\n"; $h .= " <option value=\"0\">None</option>\n"; foreach($usergroups as $id => $group) $h .= " <option value=\"$id\">$group</option>\n"; $h .= " </select>\n"; $h .= " </td>\n"; $h .= " </tr>\n"; - $h .= " <tr>\n"; + $h .= " <tr class=\"hidden\">\n"; $h .= " <th align=right>Monitored:</th>\n"; $h .= " <td><input type=\"checkbox\" name=\"profilemonitored\" "; $h .= "id=\"profilemonitored\" dojoType=\"dijit.form.CheckBox\"></td>\n"; @@ -370,11 +365,10 @@ function manageProfilesHTML() { /// /// \fn manageGroupingHTML() /// -/// \param -/// -/// \return +/// \return an array with one element with a key of 'html' whose value is the +/// html content for the grouping tab /// -/// \brief +/// \brief builds the html for the grouping tab /// //////////////////////////////////////////////////////////////////////////////// function manageGroupingHTML() { @@ -382,17 +376,22 @@ function manageGroupingHTML() { $resources = getUserResources(array("serverProfileAdmin"), array("manageGroup")); $h = ''; - if(! count($resources["serverprofile"])) { - $h .= "<H2>Server Profile Grouping</H2>\n"; - $h .= "You don't have access to modify any server profile groups.<br>\n"; - return; - } if($mode == 'submitServerProfileGroups') $gridSelected = "selected=\"true\""; else $gridSelected = ""; $h .= "<H2>Server Profile Grouping</H2>\n"; + $h .= "<span id=\"noprofilegroupsspan\""; + if(count($resources["serverprofile"])) + $h .= " class=\"hidden\""; + $h .= ">\n"; + $h .= "You don't have access to modify any server profile groups.<br>\n"; + $h .= "</span>\n"; + $h .= "<span id=\"groupprofilesspan\""; + if(! count($resources["serverprofile"])) + $h .= " class=\"hidden\""; + $h .= ">\n"; $h .= "<div id=\"groupTabContainer\" dojoType=\"dijit.layout.TabContainer\"\n"; $h .= " style=\"width:600px;height:400px\">\n"; @@ -462,7 +461,7 @@ function manageGroupingHTML() { $h .= "in it. Then,<br>select a server profile in it and click the Remove "; $h .= "button to remove it from the group,<br>or select a server profile that is not "; $h .= "in it and click the Add button to add it to the group.<br><br>\n"; - $h .= "Group:<select dojoType=\"dijit.form.Select\" id=profileGroups "; + $h .= "Group:<select dojoType=\"dijit.form.Select\" id=\"profileGroups\" "; $h .= "onChange=\"dojo.addClass('profilesdiv', 'hidden');\">\n"; # build list of groups $tmp = getUserResources(array('serverProfileAdmin'), array('manageGroup'), 1); @@ -517,6 +516,7 @@ function manageGroupingHTML() { $h .= "</div>\n"; # group $h .= "</div>\n"; # end of main tab container + $h .= "</span>\n"; $cont = addContinuationsEntry('jsonProfileGroupingProfiles'); $h .= "<input type=hidden id=profilecont value=\"$cont\">\n"; $cont = addContinuationsEntry('jsonProfileGroupingGroups'); @@ -528,11 +528,7 @@ function manageGroupingHTML() { /// /// \fn AJserverProfileData() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief sends information about a specified server profile in json format /// //////////////////////////////////////////////////////////////////////////////// function AJserverProfileData() { @@ -565,11 +561,7 @@ function AJserverProfileData() { /// /// \fn AJserverProfileStoreData() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief sends information about server profiles in json format /// //////////////////////////////////////////////////////////////////////////////// function AJserverProfileStoreData() { @@ -588,13 +580,10 @@ function AJserverProfileStoreData() { //////////////////////////////////////////////////////////////////////////////// /// -/// \fn -/// -/// \param +/// \fn AJdeployServer() /// -/// \return -/// -/// \brief +/// \brief processes request information and creates reservation if everything +/// ok /// //////////////////////////////////////////////////////////////////////////////// function AJdeployServer() { @@ -799,11 +788,7 @@ function AJdeployServer() { /// /// \fn AJsaveServerProfile /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief updates server profile information /// //////////////////////////////////////////////////////////////////////////////// function AJsaveServerProfile() { @@ -880,11 +865,7 @@ function AJsaveServerProfile() { /// /// \fn AJdelServerProfile() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief deletes a server profile /// //////////////////////////////////////////////////////////////////////////////// function AJdelServerProfile() { @@ -912,13 +893,20 @@ function AJdelServerProfile() { //////////////////////////////////////////////////////////////////////////////// /// -/// \fn -/// -/// \param +/// \fn processProfileInput() /// -/// \return +/// \return array with these values:\n +/// \b profileid - id of profile\n +/// \b name - name of profile\n +/// \b desc - description of profile\n +/// \b imageid - id associated with profile\n +/// \b fixedIP - IP address to be assigned to profile\n +/// \b fixedMAC - MAC address to be assigned to profile\n +/// \b admingroupid - admin user group associated with profile\n +/// \b logingroupid - login user group associated with profile\n +/// \b monitored - whether or not the profile should be monitored /// -/// \brief +/// \brief process submitted profile information /// //////////////////////////////////////////////////////////////////////////////// function processProfileInput() { @@ -1030,11 +1018,26 @@ function processProfileInput() { /// /// \fn getServerProfiles($id) /// -/// \param +/// \param $id - (optional) if specified, only return data for specified profile /// -/// \return +/// \return an array where each key is a profile id whose value is an array with +/// these values:\n +/// \b name - profile name\n +/// \b description - profile description\n +/// \b imageid - id of image associated with profile\n +/// \b image - pretty name of image associated with profile\n +/// \b ownerid - user id of owner of profile\n +/// \b owner - unityid of owner of profile\n +/// \b fixedIP - IP address to be used with deployed profile\n +/// \b fixedMAC - MAC address to be used with deployed profile\n +/// \b admingroupid - id of admin user group associated with profile\n +/// \b admingroup - name of admin user group associated with profile\n +/// \b logingroupid - id of login user group associated with profile\n +/// \b logingroup - name of login user group associated with profile\n +/// \b monitored - whether or not deployed profile should be monitored\n +/// \b resourceid - resource id of profile /// -/// \brief +/// \brief gets information about server profiles /// //////////////////////////////////////////////////////////////////////////////// function getServerProfiles($id=0) { @@ -1082,11 +1085,7 @@ function getServerProfiles($id=0) { /// /// \fn jsonProfileGroupingGroups() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief sends data about which profile groups are assigned to a profile /// //////////////////////////////////////////////////////////////////////////////// function jsonProfileGroupingGroups() { @@ -1121,11 +1120,7 @@ function jsonProfileGroupingGroups() { /// /// \fn jsonProfileGroupingProfiles() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief sends data about which profiles are assigned to a profile group /// //////////////////////////////////////////////////////////////////////////////// function jsonProfileGroupingProfiles() { @@ -1162,11 +1157,7 @@ function jsonProfileGroupingProfiles() { /// /// \fn AJaddGroupToProfile() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief adds a profile group to a profile /// //////////////////////////////////////////////////////////////////////////////// function AJaddGroupToProfile() { @@ -1213,11 +1204,7 @@ function AJaddGroupToProfile() { /// /// \fn AJremGroupFromProfile() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief removes a profile group from a profile /// //////////////////////////////////////////////////////////////////////////////// function AJremGroupFromProfile() { @@ -1265,11 +1252,7 @@ function AJremGroupFromProfile() { /// /// \fn AJaddProfileToGroup() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief adds a profile to a profile group /// //////////////////////////////////////////////////////////////////////////////// function AJaddProfileToGroup() { @@ -1314,11 +1297,7 @@ function AJaddProfileToGroup() { /// /// \fn AJremProfileFromGroup() /// -/// \param -/// -/// \return -/// -/// \brief +/// \brief removes a profile from a profile group /// //////////////////////////////////////////////////////////////////////////////// function AJremProfileFromGroup() { Modified: incubator/vcl/trunk/web/.ht-inc/states.php URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/states.php?rev=1130769&r1=1130768&r2=1130769&view=diff ============================================================================== --- incubator/vcl/trunk/web/.ht-inc/states.php (original) +++ incubator/vcl/trunk/web/.ht-inc/states.php Thu Jun 2 19:45:34 2011 @@ -167,6 +167,8 @@ $noHTMLwrappers = array('sendRDPfile', 'AJdeployServer', 'AJconfirmDeleteRequest', 'AJsubmitDeleteRequest', + 'AJconfirmRemoveRequest', + 'AJsubmitRemoveRequest', 'AJsetImageProduction', 'AJsubmitSetImageProduction', 'AJeditRequest', @@ -200,6 +202,8 @@ $actions['mode']['AJeditRequest'] = "AJe $actions['mode']['AJsubmitEditRequest'] = "AJsubmitEditRequest"; $actions['mode']['AJconfirmDeleteRequest'] = "AJconfirmDeleteRequest"; $actions['mode']['AJsubmitDeleteRequest'] = "AJsubmitDeleteRequest"; +$actions['mode']['AJconfirmRemoveRequest'] = "AJconfirmRemoveRequest"; +$actions['mode']['AJsubmitRemoveRequest'] = "AJsubmitRemoveRequest"; $actions['mode']['connectRequest'] = "connectRequest"; $actions['mode']['sendRDPfile'] = "sendRDPfile"; #$actions['mode']['connectMindterm'] = "connectMindterm"; @@ -210,6 +214,8 @@ $actions['pages']['AJeditRequest'] = "cu $actions['pages']['AJsubmitEditRequest'] = "currentReservations"; $actions['pages']['AJconfirmDeleteRequest'] = "currentReservations"; $actions['pages']['AJsubmitDeleteRequest'] = "currentReservations"; +$actions['pages']['AJconfirmRemoveRequest'] = "currentReservations"; +$actions['pages']['AJsubmitRemoveRequest'] = "currentReservations"; $actions['pages']['connectRequest'] = "currentReservations"; $actions['pages']['sendRDPfile'] = "currentReservations"; #$actions['pages']['connectMindterm'] = "currentReservations"; Modified: incubator/vcl/trunk/web/.ht-inc/utils.php URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/utils.php?rev=1130769&r1=1130768&r2=1130769&view=diff ============================================================================== --- incubator/vcl/trunk/web/.ht-inc/utils.php (original) +++ incubator/vcl/trunk/web/.ht-inc/utils.php Thu Jun 2 19:45:34 2011 @@ -2669,6 +2669,7 @@ function addUserGroupMember($unityid, $g . "($userid, " . "$groupid)"; doQuery($query, 101); + checkUpdateServerRequestGroups($groupid); } //////////////////////////////////////////////////////////////////////////////// @@ -2686,6 +2687,7 @@ function deleteUserGroupMember($userid, . "WHERE userid = $userid AND " . "usergroupid = $groupid"; doQuery($query, 101); + checkUpdateServerRequestGroups($groupid); } //////////////////////////////////////////////////////////////////////////////// @@ -4465,7 +4467,9 @@ function findManagementNode($compid, $st /// \b logid - id from log table\n /// \b test - test flag\n /// \b forimaging - 0 if request is normal, 1 if it is for imaging\n -/// \b serverrequest - 0 if request is normal, 1 if it is a server request\n\n +/// \b serverrequest - 0 if request is normal, 1 if it is a server request\n +/// \b admingroupid - id of admin user group if server request\n +/// \b logingroupid - id of login user group if server request\n\n /// an array of reservations associated with the request whose key is /// 'reservations', each with the following items:\n /// \b imageid - id of the image\n @@ -4552,10 +4556,17 @@ function getRequestInfo($id, $returnNULL $data["reservations"] = array(); while($row = mysql_fetch_assoc($qh)) array_push($data["reservations"], $row); - $query = "SELECT id FROM serverrequest WHERE requestid = $id"; + $query = "SELECT id, " + . "admingroupid, " + . "logingroupid " + . "FROM serverrequest " + . "WHERE requestid = $id"; $qh = doQuery($query, 101); - if(mysql_num_rows($qh)) + if($row = mysql_fetch_assoc($qh)) { $data['serverrequest'] = 1; + $data['admingroupid'] = $row['admingroupid']; + $data['logingroupid'] = $row['logingroupid']; + } else $data['serverrequest'] = 0; return $data; @@ -4919,9 +4930,10 @@ function getUserRequests($type, $id=0) { . "sp.logingroupid AS serverlogingroupid, " . "ugl.name AS serverlogingroup, " . "sp.monitored, " + . "ra.password, " + . "rs.pw, " . "(UNIX_TIMESTAMP(l.initialend) - UNIX_TIMESTAMP(l.start)) AS initialduration " - . "FROM reservation rs, " - . "image i, " + . "FROM image i, " . "OS o, " . "computer c, " . "request rq " @@ -4929,10 +4941,11 @@ function getUserRequests($type, $id=0) { . "LEFT JOIN usergroup uga ON (uga.id = sp.admingroupid) " . "LEFT JOIN usergroup ugl ON (ugl.id = sp.logingroupid) " . "LEFT JOIN log l ON (l.requestid = rq.id) " + . "LEFT JOIN reservation rs ON (rs.requestid = rq.id) " + . "LEFT JOIN reservationaccounts ra ON (ra.reservationid = rs.id AND ra.userid = $id) " . "WHERE (rq.userid = $id OR " . "sp.admingroupid IN ($ingroupids) OR " . "sp.logingroupid IN ($ingroupids)) AND " - . "rs.requestid = rq.id AND " . "rs.imageid = i.id AND " . "rq.end > NOW() AND " . "i.OSid = o.id AND " @@ -5008,6 +5021,10 @@ function getUserRequests($type, $id=0) { $data[$count]['serverowner'] = 1; $data[$count]['serveradmin'] = 1; } + if(! empty($row['password']) || ($row['userid'] == $id && ! empty($row['pw']))) + $data[$count]['useraccountready'] = 1; + else + $data[$count]['useraccountready'] = 0; $data[$count]["reservations"] = array(); $query2 = sprintf($qbase2, $row['resid'], $row['id']); $qh2 = doQuery($query2, 160); @@ -6937,7 +6954,9 @@ function requestIsReady($request) { $request["computerstateid"] == 3) || // computer reserved ($request["currstateid"] == 8 && // request current state inuse $request["computerstateid"] == 8) || // and computer state inuse - ($request["currstateid"] == 24 && // request current state checkpoint + ($request["currstateid"] == 24 && // request current state checkpoint + $request["computerstateid"] == 8) || // and computer state inuse + ($request["currstateid"] == 29 && // request current state servermodified $request["computerstateid"] == 8) || // and computer state inuse ($request["currstateid"] == 14 && // request current state pending $request["laststateid"] == 8 && // and last state inuse and @@ -7208,6 +7227,7 @@ function updateGroups($newusergroups, $u . "userid = $userid, usergroupid = $id"; doQuery($query, 307); } + checkUpdateServerRequestGroups($groupid); } return $newusergroups; } @@ -7287,6 +7307,28 @@ function getUserGroupName($id, $incAffil //////////////////////////////////////////////////////////////////////////////// /// +/// \fn checkUpdateServerRequestGroups($groupid) +/// +/// \param $groupid = id of a user group +/// +/// \brief checks for any server requests with an admin or login group of +/// $groupid; if any exist, set request stateid to servermodified +/// +//////////////////////////////////////////////////////////////////////////////// +function checkUpdateServerRequestGroups($groupid) { + $query = "UPDATE request " + . "SET stateid = 29 " + . "WHERE stateid IN (3, 7, 8, 14, 16, 24, 25, 26, 27, 28) AND " + . "id IN " + . "(SELECT requestid " + . "FROM serverrequest " + . "WHERE admingroupid = $groupid OR " + . "logingroupid = $groupid)"; + doQuery($query, 101); +} + +//////////////////////////////////////////////////////////////////////////////// +/// /// \fn getMaintItems($id) /// /// \param $id (optional) - if specified, id of maintenance item to get info @@ -7406,6 +7448,13 @@ function sendRDPfile() { $requestid = getContinuationVar("requestid"); $resid = getContinuationVar("resid"); $request = getRequestInfo("$requestid"); + if($request['stateid'] == 11 || $request['stateid'] == 12 || + ($request['stateid'] == 14 && + ($request['laststateid'] == 11 || $request['laststateid'] == 12))) { + $cont = addContinuationsEntry('viewRequests'); + header("Location: " . BASEURL . SCRIPT . "?continuation=$cont"); + return; + } foreach($request["reservations"] as $res) { if($res['reservationid'] == $resid) { $ipaddress = $res["reservedIP"]; @@ -7470,7 +7519,6 @@ function sendRDPfile() { print "disable cursor setting:i:0\r\n"; print "bitmapcachepersistenable:i:1\r\n"; //print "connect to console:i:1\r\n"; - exit(0); } //////////////////////////////////////////////////////////////////////////////// @@ -9365,7 +9413,8 @@ function getDojoHTML($refresh) { 'dijit.form.DropDownButton', 'dijit.Tooltip', 'vcldojo.HoverTooltip', - 'dojox.layout.FloatingPane'); + 'dojox.layout.FloatingPane', + 'dijit.form.FilteringSelect'); break; case 'viewRequestInfo': $dojoRequires = array('dojo.parser', Modified: incubator/vcl/trunk/web/js/requests.js URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/js/requests.js?rev=1130769&r1=1130768&r2=1130769&view=diff ============================================================================== --- incubator/vcl/trunk/web/js/requests.js (original) +++ incubator/vcl/trunk/web/js/requests.js Thu Jun 2 19:45:34 2011 @@ -275,6 +275,30 @@ function submitDeleteReservation() { RPCwrapper(data, generalReqCB); } +function removeReservation(cont) { + RPCwrapper({continuation: cont}, removeReservationCB, 1); +} + +function removeReservationCB(data, ioArgs) { + if(data.items.error) { + alert(data.items.msg); + if(data.items.error == 2) + window.location.href = data.items.url; + return; + } + dojo.byId('remrescont').value = data.items.cont; + dojo.byId('remResDlgContent').innerHTML = data.items.content; + dijit.byId('remResDlg').show(); +} + +function submitRemoveReservation() { + var data = {continuation: dojo.byId('remrescont').value}; + dojo.byId('remResDlgContent').innerHTML = ''; + dijit.byId('remResDlg').hide(); + document.body.style.cursor = 'wait'; + RPCwrapper(data, generalReqCB); +} + function editReservation(cont) { document.body.style.cursor = 'wait'; RPCwrapper({continuation: cont}, editReservationCB, 1); @@ -316,6 +340,10 @@ function hideEditResDlg() { dijit.byId('openenddate').destroy(); if(dijit.byId('openendtime')) dijit.byId('openendtime').destroy(); + if(dijit.byId('admingrpsel')) + dijit.byId('admingrpsel').destroy(); + if(dijit.byId('logingrpsel')) + dijit.byId('logingrpsel').destroy(); dojo.byId('editResDlgErrMsg').innerHTML = ''; dojo.byId('editrescont').value = ''; dojo.byId('editresid').value = ''; @@ -354,6 +382,14 @@ function submitEditReservation() { var tmp = dijit.byId('day').value.match(/([0-9]{4})([0-9]{2})([0-9]{2})/); var teststart = new Date(tmp[1], tmp[2] - 1, tmp[3], t.getHours(), t.getMinutes(), 0, 0); } + if(dijit.byId('admingrpsel')) { + data.admingroupid = dijit.byId('admingrpsel').get('value'); + data.logingroupid = dijit.byId('logingrpsel').get('value'); + } + else if(dojo.byId('admingrpsel')) { + data.admingroupid = dojo.byId('admingrpsel').value; + data.logingroupid = dojo.byId('logingrpsel').value; + } if((! dojo.byId('dateradio') && ! dojo.byId('indefiniteradio') && dijit.byId('length')) || (dojo.byId('lengthradio') && dojo.byId('lengthradio').checked)) { data.length = dijit.byId('length').value;