Example #1
0
 function AJsubmitCompStateChange()
 {
     global $user;
     $newstateid = getContinuationVar('newstateid');
     $compids = getContinuationVar('compids');
     $states = getStates();
     $ret = array('status' => 'success', 'title' => "Change State", 'clearselection' => 0, 'newstate' => $states[$newstateid], 'refreshcount' => 1);
     # get ids from getUserResources because that data should already be in cache
     $resources = getUserResources(array("imageAdmin", "imageCheckOut"));
     $tmp = array_keys($resources['image']);
     $semimageid = $tmp[0];
     $semrevid = getProductionRevisionid($semimageid);
     if (!empty($resources['managementnode'])) {
         $tmp = array_keys($resources['managementnode']);
         $semmnid = $tmp[0];
     } else {
         $allmns = array_keys(getManagementNodes('future'));
         if (empty($allmns)) {
             $ret = array('status' => 'error', 'errormsg' => 'No management nodes are available for controlling the submitted computers.');
             sendJSON($ret);
             return;
         }
         $semmnid = $allmns[0];
     }
     if ($newstateid == 2) {
         $fails = array('provnone' => array(), 'reserved' => array(), 'hostfail' => array(), 'hasvms' => array());
         $availablenow = array();
         $checkvms = array();
         $checkhosts = array();
         $noaction = array();
         $computers = $this->getData($this->defaultGetDataArgs);
         $inusecompids = array();
         $allids = implode(',', $compids);
         $query = "SELECT rs.computerid " . "FROM reservation rs, " . "request rq " . "WHERE rs.requestid = rq.id AND " . "rq.end > NOW() AND " . "rq.start < NOW() AND " . "rq.stateid NOT IN (1, 5, 11, 12) AND " . "rs.computerid IN ({$allids})";
         $qh = doQuery($query);
         while ($row = mysql_fetch_assoc($qh)) {
             $inusecompids[$row['computerid']] = 1;
         }
         # check initial conditions
         foreach ($compids as $compid) {
             # already in available
             if ($computers[$compid]['state'] == 'available') {
                 $noaction[] = $compid;
                 continue;
             }
             # no provisioning engine
             if ($computers[$compid]['provisioning'] == 'None') {
                 $fails['provnone'][] = $compid;
                 continue;
             }
             # non-VM in maintenance without a vmhost entry or in hpc
             if ($computers[$compid]['state'] == 'hpc' || $computers[$compid]['state'] == 'maintenance' && is_null($computers[$compid]['vmprofileid']) && $computers[$compid]['type'] != 'virtualmachine') {
                 $availablenow[] = $compid;
                 continue;
             }
             # has active reservation
             if (array_key_exists($compid, $inusecompids)) {
                 $fails['reserved'][] = $compid;
                 continue;
             }
             # in reload, reloading, reserved, inuse, or failed with no active reservation
             if (preg_match('/^(reload|reloading|reserved|inuse|failed|timeout)$/', $computers[$compid]['state'])) {
                 $availablenow[] = $compid;
                 continue;
             }
             # vmhostinuse - check for assigned VMs
             if ($computers[$compid]['state'] == 'vmhostinuse') {
                 $checkvms[] = $compid;
                 continue;
             }
             # VM in maintenance
             if ($computers[$compid]['state'] == 'maintenance' && $computers[$compid]['type'] == 'virtualmachine') {
                 $checkhosts[] = $compid;
                 continue;
             }
             # maintenance - check for previously being a vmhost
             if ($computers[$compid]['state'] == 'maintenance' && !is_null($computers[$compid]['vmprofileid'])) {
                 $checkvms[] = $compid;
                 continue;
             }
         }
         if (count($checkvms)) {
             $ids = implode(',', $checkvms);
             $query = "SELECT h.id, " . "COUNT(vm.id) AS count " . "FROM computer h " . "LEFT JOIN vmhost vh ON (h.id = vh.computerid) " . "LEFT JOIN computer vm ON (vh.id = vm.vmhostid) " . "WHERE h.id IN ({$ids}) " . "GROUP BY vh.computerid";
             $qh = doQuery($query);
             while ($row = mysql_fetch_assoc($qh)) {
                 if ($row['count']) {
                     $fails['hasvms'][] = $row['id'];
                 } else {
                     $availablenow[] = $row['id'];
                 }
             }
         }
         if (count($checkhosts)) {
             $ids = implode(',', $checkhosts);
             $query = "SELECT h.stateid, " . "vm.id " . "FROM computer vm " . "LEFT JOIN vmhost vh ON (vm.vmhostid = vh.id) " . "LEFT JOIN computer h ON (vh.computerid = h.id) " . "WHERE vm.id IN ({$ids})";
             $qh = doQuery($query);
             while ($row = mysql_fetch_assoc($qh)) {
                 if ($row['stateid'] != 20) {
                     $fails['hostfail'][] = $row['id'];
                 } else {
                     $availablenow[] = $row['id'];
                 }
             }
         }
         if (count($availablenow)) {
             $allids = implode(',', $availablenow);
             $query = "UPDATE computer " . "SET stateid = 2, " . "notes = '' " . "WHERE id IN ({$allids})";
             doQuery($query);
         }
         $msg = '';
         if (count($noaction)) {
             $msg .= "The following computers were already in the available ";
             $msg .= "state:<br><br>\n";
             foreach ($noaction as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "<br>\n";
         }
         if (count($availablenow)) {
             $msg .= "The following computers were changed to the available ";
             $msg .= "state:<br><br>\n";
             foreach ($availablenow as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "<br>\n";
         }
         if (count($fails['provnone'])) {
             $msg .= "<span class=\"rederrormsg\">\n";
             $msg .= "The following computers cannot be in the available state ";
             $msg .= "because they have no provisioning engine:</span><br><br>\n";
             foreach ($fails['provnone'] as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "<br>\n";
         }
         if (count($fails['reserved'])) {
             $msg .= "<span class=\"rederrormsg\">\n";
             $msg .= "The following computers are currently in use and could not have ";
             $msg .= "their states changed at this time:</span><br><br>\n";
             foreach ($fails['reserved'] as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "<br>\n";
         }
         if (count($fails['hasvms'])) {
             $msg .= "<span class=\"rederrormsg\">\n";
             $msg .= "The following computers currently have VMs assigned to them ";
             $msg .= "and cannot be moved to available until the VMs are removed:";
             $msg .= "</span><br><br>\n";
             foreach ($fails['hasvms'] as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "<br>\n";
         }
         if (count($fails['hostfail'])) {
             $msg .= "<span class=\"rederrormsg\">\n";
             $msg .= "The following VMs are not currently assigned to a host in ";
             $msg .= "the vmhostinuse state:</span><br><br>\n";
             foreach ($fails['hostfail'] as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "<br>\n";
         }
     } elseif ($newstateid == 10 || $newstateid == 23) {
         if ($newstateid == 10) {
             $notes = processInputVar('notes', ARG_STRING);
             if (get_magic_quotes_gpc()) {
                 $notes = stripslashes($notes);
             }
             $notes = mysql_real_escape_string($notes);
             $notes = $user["unityid"] . " " . unixToDatetime(time()) . "@" . $notes;
         }
         $vclreloadid = getUserlistID('vclreload@Local');
         $computers = $this->getData($this->defaultGetDataArgs);
         $noaction = array();
         $changenow = array();
         $changeasap = array();
         $changetimes = array();
         $vmwithhost = array();
         $fails = array();
         $semstart = unixToDatetime(time());
         $semend = '2038-01-01 00:00:00';
         foreach ($compids as $compid) {
             if ($newstateid == 10 && $computers[$compid]['type'] == 'virtualmachine' && in_array($computers[$compid]['vmhostcomputerid'], $compids)) {
                 $vmwithhost[] = $compid;
             }
             if ($newstateid == 10 && $computers[$compid]['state'] == 'maintenance' || $newstateid == 23 && $computers[$compid]['state'] == 'hpc') {
                 $noaction[] = $compid;
                 continue;
             }
             # try to move future reservations off of computer
             moveReservationsOffComputer($compid);
             cleanSemaphore();
             $reloadstart = getCompFinalReservationTime($compid);
             if ($computers[$compid]['state'] == 'vmhostinuse') {
                 $sem = array('imageid' => $semimageid, 'revid' => $semrevid, 'mnid' => $semmnid, 'start' => $semstart, 'end' => $semend);
                 moveReservationsOffVMs($compid, $sem);
                 cleanSemaphore();
                 $reloadstart = getCompFinalVMReservationTime($compid, 1, 1);
                 if ($reloadstart == -1) {
                     cleanSemaphore();
                     $fails[] = $compid;
                     continue;
                 } elseif ($reloadstart > 0) {
                     if (unixToDatetime($reloadstart) == '2038-01-01 00:00:00') {
                         # host has a VM reserved indefintely
                         $fails[] = $compid;
                         continue;
                     }
                     # schedule tomaintenance/tohpc reservations for VMs and host
                     $noimageid = getImageId('noimage');
                     $revid = getProductionRevisionid($noimageid);
                     $startdt = unixToDatetime($reloadstart);
                     $end = $reloadstart + SECINMONTH;
                     $enddt = unixToDatetime($end);
                     $query = "SELECT vm.id " . "FROM computer vm, " . "vmhost v " . "WHERE v.computerid = {$compid} AND " . "vm.vmhostid = v.id";
                     $qh = doQuery($query);
                     $setnoteids = array();
                     while ($row = mysql_fetch_assoc($qh)) {
                         $checkstart = getExistingChangeStateStartTime($row['id'], 18);
                         if ($checkstart) {
                             if ($checkstart > $reloadstart) {
                                 # update start time of existing tomaintenance reservation
                                 updateExistingToState($row['id'], $startdt, 18);
                             }
                             # leave existing tomaintenance reservation as is
                         } elseif (!simpleAddRequest($row['id'], $noimageid, $revid, $startdt, $enddt, 18, $vclreloadid)) {
                             cleanSemaphore();
                             $fails[] = $compid;
                             continue 2;
                             # jump out of while, continue with foreach loop
                         }
                         $setnoteids[] = $row['id'];
                     }
                     if ($newstateid == 10 && count($setnoteids)) {
                         $inids = implode(',', $setnoteids);
                         $query = "UPDATE computer " . "SET notes = 'maintenance with host {$compid}' " . "WHERE id IN ({$inids})";
                         doQuery($query);
                     }
                     $start = $reloadstart + 300;
                     # allow 5 minutes for VMs to get removed
                     $startdt = unixToDatetime($start);
                     # lock this computer
                     if (!retryGetSemaphore($semimageid, $semrevid, $semmnid, $compid, $startdt, $enddt)) {
                         cleanSemaphore();
                         $fails[] = $compid;
                         continue;
                     }
                     if ($newstateid == 10) {
                         $tostateid = 18;
                     } else {
                         $tostateid = 22;
                     }
                     $checkstart = getExistingChangeStateStartTime($compid, $tostateid);
                     if ($checkstart) {
                         if ($checkstart > $start) {
                             # update start time of existing tomaintenance/tohpc reservation
                             updateExistingToState($compid, $startdt, $tostateid);
                         }
                         # leave existing tomaintenance/tohpc reservation as is
                     } elseif (!simpleAddRequest($compid, $noimageid, $revid, $startdt, $enddt, $tostateid, $vclreloadid)) {
                         cleanSemaphore();
                         $fails[] = $compid;
                         continue;
                     }
                     cleanSemaphore();
                     $changetimes[$compid] = $start;
                     $changeasap[] = $compid;
                     continue;
                 } else {
                     if ($newstateid == 10) {
                         $note = "maintenance with host {$compid}";
                     } else {
                         $note = "maintenance so {$compid} can go to hpc";
                     }
                     # no VMs or no reservations on assigned VMs
                     $query = "UPDATE computer c " . "INNER JOIN vmhost v ON (c.vmhostid = v.id) " . "SET c.stateid = 10, " . "c.notes = '{$note}' " . "WHERE v.computerid = {$compid}";
                     doQuery($query);
                 }
             } elseif ($reloadstart) {
                 if (unixToDatetime($reloadstart) == '2038-01-01 00:00:00') {
                     # node is reserved indefintely
                     $fails[] = $compid;
                     continue;
                 }
                 # computer has reservations, schedule tomaintenance
                 $noimageid = getImageId('noimage');
                 $revid = getProductionRevisionid($noimageid);
                 $startdt = unixToDatetime($reloadstart);
                 $end = $reloadstart + SECINMONTH;
                 $enddt = unixToDatetime($end);
                 # lock this computer
                 if (!retryGetSemaphore($semimageid, $semrevid, $semmnid, $compid, $startdt, $enddt)) {
                     $fails[] = $compid;
                     cleanSemaphore();
                     continue;
                 }
                 if ($newstateid == 10) {
                     $tostateid = 18;
                 } else {
                     $tostateid = 22;
                 }
                 $checkstart = getExistingChangeStateStartTime($compid, $tostateid);
                 if ($checkstart) {
                     if ($checkstart > $reloadstart) {
                         # update start time of existing tomaintenance/tohpc reservation
                         updateExistingToState($compid, $startdt, $tostateid);
                     } else {
                         # leave existing tomaintenance/tohpc reservation as is
                         $reloadstart = $checkstart;
                     }
                 } elseif (!simpleAddRequest($compid, $noimageid, $revid, $startdt, $enddt, $tostateid, $vclreloadid)) {
                     $fails[] = $compid;
                     cleanSemaphore();
                     continue;
                 }
                 cleanSemaphore();
                 $changetimes[$compid] = $reloadstart;
                 $changeasap[] = $compid;
                 continue;
             }
             # change to maintenance/tohpc state and save in $changenow
             // if we wait and put them all in maintenance/hpc at the same time,
             # we may end up moving reservations to the computer later in the
             # loop
             # lock this computer
             if (!retryGetSemaphore($semimageid, $semrevid, $semmnid, $compid, $semstart, $semend)) {
                 $fails[] = $compid;
                 cleanSemaphore();
                 continue;
             }
             $query = "UPDATE computer " . "SET stateid = {$newstateid} " . "WHERE id = {$compid}";
             doQuery($query, 101);
             $changenow[] = $compid;
             cleanSemaphore();
         }
         if ($newstateid == 10 && (count($noaction) || count($changeasap))) {
             $comparr = array_merge($noaction, $changeasap);
             $allids = implode(',', $comparr);
             if (count($vmwithhost)) {
                 $skipids = implode(',', $vmwithhost);
             } else {
                 $skipids = "''";
             }
             $query = "UPDATE computer " . "SET notes = '{$notes}' " . "WHERE id IN ({$allids}) AND " . "id NOT IN ({$skipids})";
             doQuery($query, 101);
             $updatevms = array_intersect($vmwithhost, $comparr);
             if (count($updatevms)) {
                 $inids = implode(',', $updatevms);
                 $query = "UPDATE computer vm " . "INNER JOIN vmhost v ON (vm.vmhostid = v.id) " . "SET vm.notes = CONCAT('maintenance with host ', v.computerid) " . "WHERE vm.id IN ({$inids})";
                 doQuery($query);
             }
         }
         if ($newstateid == 10) {
             $newstate = 'maintenance';
         } else {
             $newstate = 'hpc';
         }
         $msg = '';
         if (count($changenow)) {
             $msg .= "The following computers were immediately placed into the ";
             $msg .= "{$newstate} state:<br><br>\n";
             $msg .= "<span class=\"ready\">\n";
             foreach ($changenow as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "</span><br>\n";
         }
         if (count($changeasap)) {
             $msg .= "The following computers are currently reserved ";
             $msg .= "and will be placed in the {$newstate} state at the time listed ";
             $msg .= "for each computer:\n";
             $msg .= "<table>\n";
             $msg .= "  <tr>\n";
             $msg .= "    <th>Computer</th>\n";
             $msg .= "    <th>Time</th>\n";
             $msg .= "  </tr>\n";
             foreach ($changeasap as $compid) {
                 $msg .= "  <tr>\n";
                 $msg .= "    <td align=center><span class=\"wait\">{$computers[$compid]['hostname']}</span></td>\n";
                 $time = date('n/j/y g:i a', $changetimes[$compid]);
                 $msg .= "    <td align=center>{$time}</td>\n";
                 $msg .= "  </tr>\n";
             }
             $msg .= "</table>\n";
             $msg .= "<br>\n";
         }
         if (count($fails)) {
             $msg .= "The following computers are currently reserved ";
             $msg .= "but could not be scheduled to be moved to the {$newstate} state ";
             $msg .= "at this time:<br><br>\n";
             $msg .= "<span class=\"rederrormsg\">\n";
             foreach ($fails as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "</span><br>\n";
         }
         if (count($noaction)) {
             $msg .= "The following computers were already in the {$newstate} state";
             if ($newstateid == 10) {
                 $msg .= " and had their notes on being in the maintenance state updated";
             }
             $msg .= ":<br><br>\n";
             foreach ($noaction as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "<br>\n";
         }
     } elseif ($newstateid == 20) {
         $profileid = processInputVar('profileid', ARG_NUMERIC);
         $profiles = getContinuationVar('profiles');
         if (!array_key_exists($profileid, $profiles)) {
             $ret = array('status' => 'error', 'errormsg' => 'Invalid profile submitted');
             sendJSON($ret);
             return;
         }
         $vclreloadid = getUserlistID('vclreload@Local');
         $imagerevisionid = getProductionRevisionid($profiles[$profileid]['imageid']);
         $computers = $this->getData($this->defaultGetDataArgs);
         $noaction = array();
         $changenow = array();
         $changenowreload = array();
         $changeasap = array();
         $changetimes = array();
         $fails = array();
         $semstart = unixToDatetime(time());
         $semend = '2038-01-01 00:00:00';
         $maintvmids = array();
         $vmnotallowed = array();
         $allvmids = array();
         $allids = implode(',', $compids);
         $query = "SELECT v.computerid AS compid, " . "vm.id AS vmid, " . "vm.notes, " . "vm.stateid AS vmstateid " . "FROM computer vm, " . "vmhost v " . "WHERE v.computerid IN ({$allids}) AND " . "vm.vmhostid = v.id";
         $qh = doQuery($query);
         while ($row = mysql_fetch_assoc($qh)) {
             if (!array_key_exists($row['compid'], $maintvmids)) {
                 $maintvmids[$row['compid']] = array();
             }
             if ($row['vmstateid'] == 10 && $row['notes'] == "maintenance with host {$row['compid']}") {
                 $maintvmids[$row['compid']][] = $row['vmid'];
             }
             $allvmids[$row['compid']][] = $row['vmid'];
         }
         foreach ($compids as $compid) {
             if ($computers[$compid]['type'] == 'virtualmachine') {
                 $vmnotallowed[] = $compid;
                 continue;
             }
             # try to move future reservations off of computer
             moveReservationsOffComputer($compid);
             cleanSemaphore();
             if ($computers[$compid]['state'] == 'maintenance') {
                 if ($computers[$compid]['provisioning'] != 'None') {
                     # schedule tovmhostinuse
                     $start = getReloadStartTime();
                     # put computer in reload state so vcld will not ignore due to being in maintenance
                     $query = "UPDATE computer " . "SET stateid = 19 " . "WHERE id = {$compid}";
                     doQuery($query);
                     $rc = $this->scheduleTovmhostinuse($compid, $profiles[$profileid]['imageid'], $start, $profileid, $computers[$compid]['vmprofileid']);
                     cleanSemaphore();
                     if (!$rc) {
                         $fails[] = $compid;
                         continue;
                     }
                     if (!is_null($computers[$compid]['vmprofileid']) && array_key_exists($compid, $maintvmids) && count($maintvmids[$compid])) {
                         $noimageid = getImageId('noimage');
                         $revid = getProductionRevisionid($noimageid);
                         $reloadstart = $start + 1800;
                         $reloadstartdt = unixToDatetime($reloadstart);
                         $end = $reloadstart + 3600;
                         $enddt = unixToDatetime($end);
                         foreach ($maintvmids[$compid] as $vmid) {
                             if (!retryGetSemaphore($semimageid, $semrevid, $semmnid, $vmid, $reloadstartdt, $enddt)) {
                                 continue;
                             }
                             simpleAddRequest($vmid, $noimageid, $revid, $reloadstartdt, $enddt, 19, $vclreloadid);
                             # continue even if failed to schedule VM to be reloaded
                         }
                         cleanSemaphore();
                     }
                     $changenowreload[] = $compid;
                 } else {
                     $query = "UPDATE computer " . "SET stateid = 20, " . "notes = '' " . "WHERE id = {$compid}";
                     doQuery($query);
                     $this->updateVmhostProfile($compid, $profileid, $computers[$compid]['vmprofileid']);
                     if (array_key_exists($compid, $maintvmids) && count($maintvmids[$compid])) {
                         $allids = implode(',', $maintvmids[$compid]);
                         $query = "UPDATE computer " . "SET stateid = 2, " . "notes = '' " . "WHERE id in ({$allids})";
                         doQuery($query);
                     }
                     $changenow[] = $compid;
                 }
             } elseif ($computers[$compid]['state'] == 'hpc') {
                 if ($computers[$compid]['provisioning'] != 'None') {
                     # schedule tovmhostinuse
                     $start = getReloadStartTime();
                     # put computer in reload state so vcld will not ignore due to being in maintenance
                     $query = "UPDATE computer " . "SET stateid = 19 " . "WHERE id = {$compid}";
                     doQuery($query);
                     $rc = $this->scheduleTovmhostinuse($compid, $profiles[$profileid]['imageid'], $start, $profileid, $computers[$compid]['vmprofileid']);
                     cleanSemaphore();
                     if (!$rc) {
                         $fails[] = $compid;
                         continue;
                     }
                     $changenowreload[] = $compid;
                 } else {
                     $query = "UPDATE computer " . "SET stateid = 20, " . "notes = '' " . "WHERE id = {$compid}";
                     doQuery($query);
                     $this->updateVmhostProfile($compid, $profileid, $computers[$compid]['vmprofileid']);
                     $changenow[] = $compid;
                 }
             } elseif ($computers[$compid]['state'] == 'vmhostinuse') {
                 if ($profiles[$computers[$compid]['vmprofileid']]['imageid'] != $profiles[$profileid]['imageid']) {
                     if ($computers[$compid]['provisioning'] != 'None') {
                         $sem = array('imageid' => $semimageid, 'revid' => $semrevid, 'mnid' => $semmnid, 'start' => $semstart, 'end' => $semend);
                         moveReservationsOffVMs($compid, $sem);
                         cleanSemaphore();
                         $reloadstart = getCompFinalVMReservationTime($compid, 1);
                         if ($reloadstart < 0) {
                             $fails[] = $compid;
                             cleanSemaphore();
                             continue;
                         }
                         if ($reloadstart == 0) {
                             $start = getReloadStartTime();
                         } else {
                             $start = $reloadstart;
                         }
                         $noimageid = getImageId('noimage');
                         $revid = getProductionRevisionid($noimageid);
                         $startdt = unixToDatetime($start);
                         $end = $start + SECINWEEK;
                         $enddt = unixToDatetime($end);
                         if ($start == $reloadstart) {
                             # check for existing reload reservations for all VMs and host
                             $times = array();
                             $reqids = array();
                             $inids = implode(',', $allvmids[$compid]);
                             $query = "SELECT UNIX_TIMESTAMP(MIN(rq.start)) AS start, " . "rs.computerid, " . "rq.id " . "FROM request rq, " . "reservation rs " . "WHERE rs.requestid = rq.id AND " . "rs.computerid IN ({$inids}) AND " . "rq.stateid = 19 AND " . "rs.imageid = {$noimageid} AND " . "rq.start > NOW() " . "GROUP BY rs.computerid " . "ORDER BY start";
                             $qh = doQuery($query);
                             if (mysql_num_rows($qh) == count($allvmids)) {
                                 while ($row = mysql_fetch_assoc($qh)) {
                                     $times[$row['start']] = 1;
                                     $reqids[] = $row['id'];
                                 }
                                 if (count($times) == 1) {
                                     # found existing reload reservations for all VMs, now check host
                                     $hoststart = $times[0] + 300;
                                     $hoststartdt = unixToDatetime($hoststart);
                                     $hostend = $hoststart + SECINYEAR;
                                     $hostenddt = unixToDatetime($hostend);
                                     $query = "SELECT rq.id, " . "rq.start " . "FROM request rq, " . "reservation rs " . "WHERE rs.requestid = rq.id AND " . "rs.computerid = {$compid} AND " . "rq.start = '{$hoststartdt}' AND " . "rq.end = '{$hostenddt}' AND " . "rs.imageid = '{$profiles[$profileid]['imageid']}' AND " . "rq.stateid = 21";
                                     $qh = doQuery($query);
                                     if ($row = mysql_fetch_assoc($qh)) {
                                         # node was previously scheduled to be reloaded for vmhostinuse
                                         if ($times[0] > $start) {
                                             # update existing reservations
                                             $allreqids = implode(',', $reqids);
                                             $query1 = "UPDATE request " . "SET start = '{$startdt}', " . "end = '{$enddt}' " . "WHERE id IN ({$allreqids})";
                                             # delay host by 5 minutes
                                             $start = $start + 300;
                                             $startdt = unixToDatetime($start);
                                             $end = $start + SECINYEAR;
                                             $enddt = unixToDatetime($end);
                                             # lock this computer
                                             if (!retryGetSemaphore($semimageid, $semrevid, $semmnid, $compid, $startdt, $enddt)) {
                                                 $fails[] = $compid;
                                                 continue;
                                             }
                                             doQuery($query1);
                                             $query2 = "UPDATE request " . "SET start = '{$startdt}', " . "end = '{$enddt}' " . "WHERE id = {$row['id']}";
                                             doQuery($query2);
                                             $changeasap[] = $compid;
                                             $changetimes[$compid] = $start;
                                         } else {
                                             # just leave the existing ones there
                                             $changeasap[] = $compid;
                                             $changetimes[$compid] = $times[0] + 300;
                                         }
                                         cleanSemaphore();
                                         continue;
                                     }
                                 }
                             }
                         }
                         if (array_key_exists($compid, $allvmids)) {
                             foreach ($allvmids[$compid] as $vmid) {
                                 $rc = simpleAddRequest($vmid, $noimageid, $revid, $startdt, $enddt, 19, $vclreloadid);
                                 if (!$rc) {
                                     $fails[] = $compid;
                                     cleanSemaphore();
                                     continue 2;
                                     # jump out of this foreach to the bigger foreach
                                 }
                             }
                         }
                         $start = $start + 300;
                         # give 5 minutes for VMs
                         $rc = $this->scheduleTovmhostinuse($compid, $profiles[$profileid]['imageid'], $start, $profileid, $computers[$compid]['vmprofileid']);
                         if (!$rc) {
                             $fails[] = $compid;
                             continue;
                         }
                         if ($reloadstart) {
                             $changeasap[] = $compid;
                             $changetimes[$compid] = $reloadstart;
                         } else {
                             $changenowreload[] = $compid;
                         }
                     } else {
                         $this->updateVmhostProfile($compid, $profileid, $computers[$compid]['vmprofileid']);
                         $changenow[] = $compid;
                     }
                 } else {
                     $noaction[] = $compid;
                 }
             } elseif (($reloadstart = moveReservationsOffComputer($compid)) == 0) {
                 $start = getCompFinalReservationTime($compid, 21);
                 $rc = $this->scheduleTovmhostinuse($compid, $profiles[$profileid]['imageid'], $start, $profileid, $computers[$compid]['vmprofileid']);
                 if (!$rc) {
                     $fails[] = $compid;
                     continue;
                 }
                 $changeasap[] = $compid;
                 if (isset($this->startchange)) {
                     $start = $this->startchange;
                 }
                 $changetimes[$compid] = $start;
             } else {
                 if ($computers[$compid]['provisioning'] != 'None') {
                     $start = getCompFinalReservationTime($compid, 21);
                     $now = 0;
                     if ($start == 0) {
                         $start = getReloadStartTime();
                         $now = 1;
                     }
                     $rc = $this->scheduleTovmhostinuse($compid, $profiles[$profileid]['imageid'], $start, $profileid, $computers[$compid]['vmprofileid']);
                     if (!$rc) {
                         $fails[] = $compid;
                         continue;
                     }
                     if ($now) {
                         $changenowreload[] = $compid;
                     } else {
                         $changeasap[] = $compid;
                         $changetimes[$compid] = $start;
                     }
                 } else {
                     $query = "UPDATE computer " . "SET stateid = 20, " . "notes = '' " . "WHERE id = {$compid}";
                     doQuery($query);
                     $this->updateVmhostProfile($compid, $profileid, $computers[$compid]['vmprofileid']);
                     $changenow[] = $compid;
                 }
             }
         }
         $msg = '';
         if (count($changenow)) {
             $msg .= "The following computers were placed into the vmhostinuse state ";
             $msg .= "or had their VM Host Profiles updated:<br><br>\n";
             foreach ($changenow as $compid) {
                 $msg .= "<span class=\"ready\">{$computers[$compid]['hostname']}</span><br>\n";
             }
             $msg .= "<br>\n";
             $ret['clearselection'] = 1;
             $ret['refreshcount'] = 5;
         }
         if (count($changenowreload)) {
             $msg .= "The following computers have been scheduled to be immediately reloaded<br>\n";
             $msg .= "and placed into the vmhostinuse state:<br><br>\n";
             foreach ($changenowreload as $compid) {
                 $msg .= "<span class=\"ready\">{$computers[$compid]['hostname']}</span><br>\n";
             }
             $msg .= "<br>\n";
             $ret['clearselection'] = 1;
             $ret['refreshcount'] = 5;
         }
         if (count($changeasap)) {
             $msg .= "The following computers are currently reserved and have been scheduled<br>\n";
             $msg .= "to be reloaded and placed into the vmhostinuse state at the time listed<br>\n";
             $msg .= "for each computers:<br><br>\n";
             $msg .= "<table>\n";
             $msg .= "  <tr>\n";
             $msg .= "    <th>Computer</th>\n";
             $msg .= "    <th>Reload time</th>\n";
             $msg .= "  </tr>\n";
             foreach ($changeasap as $compid) {
                 $msg .= "  <tr>\n";
                 $msg .= "    <td align=center><span class=\"wait\">{$computers[$compid]['hostname']}</span></td>\n";
                 $time = date('n/j/y g:i a', $changetimes[$compid]);
                 $msg .= "    <td align=center>{$time}</td>\n";
                 $msg .= "  </tr>\n";
             }
             $msg .= "</table>\n";
             $msg .= "<br>\n";
         }
         if (count($fails)) {
             $msg .= "Problems were encountered while trying to move the following computers<br>\n";
             $msg .= "to the vmhostinuse state:<br><br>\n";
             foreach ($fails as $compid) {
                 $msg .= "<span class=\"rederrormsg\">{$computers[$compid]['hostname']}</span><br>\n";
             }
             $msg .= "<br>\n";
         }
         if (count($vmnotallowed)) {
             $msg .= "The following computers are VMs which cannot be placed into the ";
             $msg .= "vmhostinuse state:<br><br>\n";
             foreach ($vmnotallowed as $compid) {
                 $msg .= "<span class=\"rederrormsg\">{$computers[$compid]['hostname']}</span><br>\n";
             }
             $msg .= "<br>\n";
         }
         if (count($noaction)) {
             $msg .= "The following computers were already in the vmhostinuse state:<br><br>\n";
             foreach ($noaction as $compid) {
                 $msg .= "{$computers[$compid]['hostname']}<br>\n";
             }
             $msg .= "<br>\n";
         }
     }
     # clear user resource cache for this type
     $key = getKey(array(array($this->restype . "Admin"), array("administer"), 0, 1, 0, 0));
     unset($_SESSION['userresources'][$key]);
     $key = getKey(array(array($this->restype . "Admin"), array("administer"), 0, 0, 0, 0));
     unset($_SESSION['userresources'][$key]);
     $ret['msg'] = $msg;
     sendJSON($ret);
 }
Example #2
0
function AJeditRequest()
{
    global $submitErr, $user;
    $requestid = getContinuationVar('requestid', 0);
    $request = getRequestInfo($requestid, 1);
    # check to see if reservation exists
    if (is_null($request) || $request['stateid'] == 11 || $request['stateid'] == 12 || $request['stateid'] == 14 && ($request['laststateid'] == 11 || $request['laststateid'] == 12)) {
        sendJSON(array('status' => 'resgone'));
        return;
    }
    $unixstart = datetimeToUnix($request["start"]);
    $unixend = datetimeToUnix($request["end"]);
    $duration = $unixend - $unixstart;
    $now = time();
    $maxtimes = getUserMaxTimes();
    $groupid = getUserGroupID('Specify End Time', 1);
    $members = getUserGroupMembers($groupid);
    if (array_key_exists($user['id'], $members) || $request['serverrequest']) {
        $openend = 1;
    } else {
        $openend = 0;
    }
    $groupid = getUserGroupID('Allow No User Check', 1);
    $members = getUserGroupMembers($groupid);
    if (array_key_exists($user['id'], $members)) {
        $nousercheck = 1;
    } else {
        $nousercheck = 0;
    }
    $h = '';
    # determine the current total length of the reservation
    $reslen = ($unixend - unixFloor15($unixstart)) / 60;
    $timeval = getdate($unixstart);
    if ($timeval["minutes"] % 15 != 0) {
        $reslen -= 15;
    }
    $cdata = array('requestid' => $requestid, 'openend' => $openend, 'nousercheck' => $nousercheck, 'modifystart' => 0, 'allowindefiniteend' => 0);
    # generate HTML
    if ($request['serverrequest']) {
        if (empty($request['servername'])) {
            $request['servername'] = $request['reservations'][0]['prettyimage'];
        }
        $h .= i("Name") . ": <input type=\"text\" name=\"servername\" id=\"servername\" ";
        $h .= "dojoType=\"dijit.form.TextBox\" style=\"width: 330px\" ";
        $h .= "value=\"{$request['servername']}\"><br>";
        if ($user['showallgroups']) {
            $groups = getUserGroups();
        } else {
            $groups = getUserGroups(0, $user['affiliationid']);
        }
        $h .= "<div style=\"display: table-row;\">\n";
        $h .= "<div style=\"display: table-cell;\">\n";
        $h .= i("Admin User Group") . ": ";
        $h .= "</div>\n";
        $h .= "<div style=\"display: table-cell;\">\n";
        $disabled = '';
        if ($request['stateid'] == 14 && $request['laststateid'] == 24) {
            $disabled = "disabled=\"true\"";
        }
        if (USEFILTERINGSELECT && count($groups) < FILTERINGSELECTTHRESHOLD) {
            $h .= "<select dojoType=\"dijit.form.FilteringSelect\" id=\"admingrpsel\" ";
            $h .= "{$disabled} highlightMatch=\"all\" autoComplete=\"false\">";
        } else {
            $h .= "<select id=\"admingrpsel\" {$disabled}>";
        }
        if (!empty($request['admingroupid']) && !array_key_exists($request['admingroupid'], $groups)) {
            $id = $request['admingroupid'];
            $name = getUserGroupName($request['admingroupid'], 1);
            $h .= "<option value=\"{$id}\">{$name}</option>\n";
        }
        $h .= "<option value=\"0\">" . i("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>";
        $imageinfo = getImages(0, $request['reservations'][0]['imageid']);
        if ($imageinfo[$request['reservations'][0]['imageid']]['rootaccess'] == 0) {
            $h .= "<div style=\"width: 240px; margin: 3px 0 3px 0; padding: 1px; border: 1px solid;\">";
            $h .= i("Administrative access has been disabled for this image. Users in the Admin User Group will have control of the reservaion on the Reservations page but will not have administrative access within the reservation.");
            $h .= "</div>\n";
        }
        $h .= "</div>\n";
        $h .= "</div>\n";
        $h .= i("Access User Group") . ": ";
        if (USEFILTERINGSELECT && count($groups) < FILTERINGSELECTTHRESHOLD) {
            $h .= "<select dojoType=\"dijit.form.FilteringSelect\" id=\"logingrpsel\" ";
            $h .= "{$disabled} highlightMatch=\"all\" autoComplete=\"false\">";
        } else {
            $h .= "<select id=\"logingrpsel\" {$disabled}>";
        }
        if (!empty($request['logingroupid']) && !array_key_exists($request['logingroupid'], $groups)) {
            $id = $request['logingroupid'];
            $name = getUserGroupName($request['logingroupid'], 1);
            $h .= "<option value=\"{$id}\">{$name}</option>\n";
        }
        $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>";
    } elseif ($nousercheck) {
        $extra = array();
        if ($request['checkuser'] == 0) {
            $extra['checked'] = 'checked';
        }
        $h .= labeledFormItem('newnousercheck', i('Disable timeout for disconnected users'), 'check', '', '', '1', '', '', $extra);
        $h .= "<br>\n";
    }
    // if future, allow start to be modified
    if ($unixstart > $now) {
        $cdata['modifystart'] = 1;
        $txt = i("Modify reservation for") . " <b>{$request['reservations'][0]['prettyimage']}</b> ";
        $txt .= i("starting") . " " . prettyDatetime($request["start"]) . ": <br>";
        $h .= preg_replace("/(.{1,60}([ \n]|\$))/", '\\1<br>', $txt);
        $days = array();
        $startday = date('l', $unixstart);
        for ($cur = time(), $end = $cur + DAYSAHEAD * SECINDAY; $cur < $end; $cur += SECINDAY) {
            $index = date('Ymd', $cur);
            $days[$index] = date('l', $cur);
        }
        $cdata['startdays'] = array_keys($days);
        $h .= i("Start") . ": <select dojoType=\"dijit.form.Select\" id=\"day\" ";
        $h .= "onChange=\"resetEditResBtn();\">";
        foreach ($days as $id => $name) {
            if ($name == $startday) {
                $h .= "<option value=\"{$id}\" selected=\"selected\">{$name}</option>";
            } else {
                $h .= "<option value=\"{$id}\">{$name}</option>";
            }
        }
        $h .= "</select>";
        $h .= i("&nbsp;At&nbsp;");
        $tmp = explode(' ', $request['start']);
        $stime = $tmp[1];
        $h .= "<div type=\"text\" dojoType=\"dijit.form.TimeTextBox\" ";
        $h .= "id=\"editstarttime\" style=\"width: 78px\" value=\"T{$stime}\" ";
        $h .= "onChange=\"resetEditResBtn();\"></div>";
        $h .= "<small>(" . date('T') . ")</small><br><br>";
        $durationmatch = 0;
        if ($request['serverrequest']) {
            $cdata['allowindefiniteend'] = 1;
            if ($request['end'] == '2038-01-01 00:00:00') {
                $h .= "<INPUT type=\"radio\" name=\"ending\" id=\"indefiniteradio\" ";
                $h .= "checked onChange=\"resetEditResBtn();\">";
            } else {
                $h .= "<INPUT type=\"radio\" name=\"ending\" id=\"indefiniteradio\" ";
                $h .= "onChange=\"resetEditResBtn();\">";
            }
            $h .= "<label for=\"indefiniteradio\">" . i("Indefinite Ending") . "</label>";
        } else {
            $durationmin = $duration / 60;
            if ($request['forimaging'] && $maxtimes['initial'] < 720) {
                # make sure at least 12 hours available for imaging reservations
                $maxtimes['initial'] = 720;
            }
            $imgdata = getImages(1, $request['reservations'][0]['imageid']);
            $maxlen = $imgdata[$request['reservations'][0]['imageid']]['maxinitialtime'];
            if ($maxlen > 0 && $maxlen < $maxtimes['initial']) {
                $maxtimes['initial'] = $maxlen;
            }
            $lengths = array();
            if ($maxtimes["initial"] >= 30) {
                $lengths["30"] = "30 " . i("minutes");
                if ($durationmin == 30) {
                    $durationmatch = 1;
                }
            }
            if ($maxtimes["initial"] >= 45) {
                $lengths["45"] = "45 " . i("minutes");
                if ($durationmin == 45) {
                    $durationmatch = 1;
                }
            }
            if ($maxtimes["initial"] >= 60) {
                $lengths["60"] = "1 " . i("hour");
                if ($durationmin == 60) {
                    $durationmatch = 1;
                }
            }
            for ($i = 120; $i <= $maxtimes["initial"] && $i < 2880; $i += 120) {
                $lengths[$i] = $i / 60 . " " . i("hours");
                if ($durationmin == $i) {
                    $durationmatch = 1;
                }
            }
            for ($i = 2880; $i <= $maxtimes["initial"]; $i += 1440) {
                $lengths[$i] = $i / 1440 . " " . i("days");
                if ($durationmin == $i) {
                    $durationmatch = 1;
                }
            }
            if ($openend) {
                if ($durationmatch) {
                    $h .= "<INPUT type=\"radio\" name=\"ending\" id=\"lengthradio\" ";
                    $h .= "onChange=\"resetEditResBtn();\" checked>";
                } else {
                    $h .= "<INPUT type=\"radio\" name=\"ending\" id=\"lengthradio\" ";
                    $h .= "onChange=\"resetEditResBtn();\">";
                }
                $h .= "<label for=\"lengthradio\">";
            }
            $h .= i("Duration") . ':';
            if ($openend) {
                $h .= "</label>";
            }
            $h .= "<select dojoType=\"dijit.form.Select\" id=\"length\" ";
            $h .= "onChange=\"selectLength();\">";
            $cdata['lengths'] = array_keys($lengths);
            foreach ($lengths as $id => $name) {
                if ($id == $duration / 60) {
                    $h .= "<option value=\"{$id}\" selected=\"selected\">{$name}</option>";
                } else {
                    $h .= "<option value=\"{$id}\">{$name}</option>";
                }
            }
            $h .= "</select>";
        }
        if ($openend) {
            if ($request['serverrequest'] && $request['end'] == '2038-01-01 00:00:00') {
                $h .= "<br><INPUT type=\"radio\" name=\"ending\" id=\"dateradio\" ";
                $h .= "onChange=\"resetEditResBtn();\">";
                $edate = '';
                $etime = '';
            } else {
                if (!$request['serverrequest'] && $durationmatch) {
                    $h .= "<br><INPUT type=\"radio\" name=\"ending\" id=\"dateradio\" ";
                    $h .= "onChange=\"resetEditResBtn();\">";
                } else {
                    $h .= "<br><INPUT type=\"radio\" name=\"ending\" id=\"dateradio\" ";
                    $h .= "checked onChange=\"resetEditResBtn();\">";
                }
                $tmp = explode(' ', $request['end']);
                $edate = $tmp[0];
                $etime = $tmp[1];
            }
            $h .= "<label for=\"dateradio\">";
            $h .= i("End:");
            $h .= "</label>";
            $h .= "<div type=\"text\" dojoType=\"dijit.form.DateTextBox\" ";
            $h .= "id=\"openenddate\" style=\"width: 78px\" value=\"{$edate}\" ";
            $h .= "onChange=\"selectEnding();\"></div>";
            $h .= "<div type=\"text\" dojoType=\"dijit.form.TimeTextBox\" ";
            $h .= "id=\"openendtime\" style=\"width: 78px\" value=\"T{$etime}\" ";
            $h .= "onChange=\"selectEnding();\"></div>";
            $h .= "<small>(" . date('T') . ")</small>";
        }
        $h .= "<br><br>";
        $cont = addContinuationsEntry('AJsubmitEditRequest', $cdata, SECINDAY, 1, 0);
        $data = array('status' => 'modify', 'html' => $h, 'requestid' => $requestid, 'cont' => $cont);
        sendJSON($data);
        return;
    }
    # check for max time being reached
    if ($request['forimaging'] && $maxtimes['total'] < 720) {
        $maxcheck = 720;
    } else {
        $maxcheck = $maxtimes['total'];
    }
    if (!$openend && $reslen >= $maxcheck) {
        $h = sprintf(i("You are only allowed to extend your reservation such that it has a total length of %s. "), minToHourMin($maxcheck));
        $h .= i("This reservation already meets that length. Therefore, you are not allowed to extend your reservation any further.");
        $h = preg_replace("/(.{1,60}([ \n]|\$))/", '\\1<br>', $h) . "<br>";
        sendJSON(array('status' => 'nomodify', 'html' => $h));
        return;
    }
    // if started, only allow end to be modified
    # check for following reservations
    $timeToNext = timeToNextReservation($request);
    # check for 30 minutes because need 15 minute buffer and min can
    # extend by is 15 min
    if ($timeToNext < 30) {
        $movedall = 1;
        $lockedall = 1;
        if (count($request['reservations']) > 1) {
            # get semaphore on each existing node in cluster so that nothing
            # can get moved to the nodes during this process
            $resources = getUserResources(array("imageAdmin", "imageCheckOut"));
            $tmp = array_keys($resources['image']);
            $semimageid = $tmp[0];
            $semrevid = getProductionRevisionid($semimageid);
            $checkend = unixToDatetime($unixend + 900);
            foreach ($request["reservations"] as $res) {
                if (!retryGetSemaphore($semimageid, $semrevid, $res['managementnodeid'], $res['computerid'], $request['start'], $checkend, $requestid)) {
                    $lockedall = 0;
                    break;
                }
            }
        }
        if ($lockedall) {
            foreach ($request["reservations"] as $res) {
                if (!moveReservationsOffComputer($res["computerid"], 1)) {
                    $movedall = 0;
                    break;
                }
            }
        }
        cleanSemaphore();
        if (!$request['serverrequest'] && (!$movedall || !$lockedall)) {
            $msg = i("The computer you are using has another reservation immediately following yours. Therefore, you cannot extend your reservation because it would overlap with the next one.");
            $h = preg_replace("/(.{1,60}( |\$))/", '\\1<br>', $msg) . "<br>";
            sendJSON(array('status' => 'nomodify', 'html' => $h));
            return;
        }
        $timeToNext = timeToNextReservation($request);
    }
    if ($timeToNext >= 15) {
        $timeToNext -= 15;
    }
    //if have time left to extend it, create an array of lengths based on maxextend that has a cap
    # so we don't run into another reservation and we can't extend past the totalmax
    $lengths = array();
    if ($request['forimaging'] && $maxtimes['total'] < 720) {
        # make sure at least 12 hours available for imaging reservations
        $maxtimes['total'] = 720;
    }
    if ($timeToNext == -1) {
        // there is no following reservation
        if ($reslen + 15 <= $maxtimes["total"] && 15 <= $maxtimes["extend"]) {
            $lengths["15"] = "15 " . i("minutes");
        }
        if ($reslen + 30 <= $maxtimes["total"] && 30 <= $maxtimes["extend"]) {
            $lengths["30"] = "30 " . i("minutes");
        }
        if ($reslen + 45 <= $maxtimes["total"] && 45 <= $maxtimes["extend"]) {
            $lengths["45"] = "45 " . i("minutes");
        }
        if ($reslen + 60 <= $maxtimes["total"] && 60 <= $maxtimes["extend"]) {
            $lengths["60"] = i("1 hour");
        }
        for ($i = 120; $reslen + $i <= $maxtimes["total"] && $i <= $maxtimes["extend"] && $i < 2880; $i += 120) {
            $lengths[$i] = $i / 60 . " " . i("hours");
        }
        for ($i = 2880; $reslen + $i <= $maxtimes["total"] && $i <= $maxtimes["extend"]; $i += 1440) {
            $lengths[$i] = $i / 1440 . " " . i("days");
        }
    } else {
        if ($timeToNext >= 15 && $reslen + 15 <= $maxtimes["total"] && 15 <= $maxtimes["extend"]) {
            $lengths["15"] = "15 " . i("minutes");
        }
        if ($timeToNext >= 30 && $reslen + 30 <= $maxtimes["total"] && 30 <= $maxtimes["extend"]) {
            $lengths["30"] = "30 " . i("minutes");
        }
        if ($timeToNext >= 45 && $reslen + 45 <= $maxtimes["total"] && 45 <= $maxtimes["extend"]) {
            $lengths["45"] = "45 " . i("minutes");
        }
        if ($timeToNext >= 60 && $reslen + 60 <= $maxtimes["total"] && 60 <= $maxtimes["extend"]) {
            $lengths["60"] = i("1 hour");
        }
        for ($i = 120; $i <= $timeToNext && $reslen + $i <= $maxtimes["total"] && $i <= $maxtimes["extend"] && $i < 2880; $i += 120) {
            $lengths[$i] = $i / 60 . " " . i("hours");
        }
        for ($i = 2880; $i <= $timeToNext && $reslen + $i <= $maxtimes["total"] && $i <= $maxtimes["extend"]; $i += 1440) {
            $lengths[$i] = $i / 1440 . " " . i("days");
        }
    }
    $cdata['lengths'] = array_keys($lengths);
    if ($timeToNext == -1 || $timeToNext >= $maxtimes['total']) {
        if ($openend) {
            if (!empty($lengths)) {
                $m = i("You can extend this reservation by a selected amount or change the end time to a specified date and time.");
                $h .= preg_replace("/(.{1,55}([ \n]|\$))/", '\\1<br>', $m) . "<br>";
            } else {
                $h .= i("Modify the end time for this reservation:") . "<br><br>";
            }
        } else {
            if ($request['forimaging'] && $maxtimes['total'] < 720) {
                $maxcheck = 720;
            } else {
                $maxcheck = $maxtimes['total'];
            }
            $m = sprintf(i("You can extend this reservation by up to %s but not exceeding %s for your total reservation time."), minToHourMin($maxtimes['extend']), minToHourMin($maxcheck));
            $h .= preg_replace("/(.{1,60}([ \n]|\$))/", '\\1<br>', $m) . "<br>";
        }
    } elseif (!$request['serverrequest']) {
        $m = sprintf(i("The computer you are using has another reservation following yours. Therefore, you can only extend this reservation for another %s."), prettyLength($timeToNext));
        $h .= preg_replace("/(.{1,60}( |\$))/", '\\1<br>', $m);
    }
    # extend by drop down
    # extend by specifying end time if $openend
    $noindefinite = 0;
    if ($openend) {
        if ($request['serverrequest']) {
            $cdata['allowindefiniteend'] = 1;
            $endchecked = 0;
            if ($request['end'] == '2038-01-01 00:00:00') {
                $h .= "<INPUT type=\"radio\" name=\"ending\" id=\"indefiniteradio\" ";
                $h .= "checked onChange=\"resetEditResBtn();\">";
                $h .= "<label for=\"indefiniteradio\">" . i("Indefinite Ending") . "</label>";
                $h .= "<br><INPUT type=\"radio\" name=\"ending\" id=\"dateradio\" ";
                $h .= "onChange=\"resetEditResBtn();\">";
            } else {
                $h .= "<INPUT type=\"radio\" name=\"ending\" id=\"indefiniteradio\" ";
                $h .= "onChange=\"resetEditResBtn();\">";
                $h .= "<label id=\"indefinitelabel\" for=\"indefiniteradio\">";
                $h .= i("Indefinite Ending") . "</label>";
                $h .= "<br><INPUT type=\"radio\" name=\"ending\" id=\"dateradio\" ";
                $h .= "checked onChange=\"resetEditResBtn();\">";
                $endchecked = 1;
            }
            $h .= "<label for=\"dateradio\">";
        } elseif (!empty($lengths)) {
            $h .= "<INPUT type=\"radio\" name=\"ending\" id=\"lengthradio\" ";
            $h .= "checked onChange=\"resetEditResBtn();\">";
            $h .= "<label for=\"lengthradio\">" . i("Extend reservation by:") . "</label>";
            $h .= "<select dojoType=\"dijit.form.Select\" id=\"length\" ";
            $h .= "onChange=\"selectLength();\" maxHeight=\"250\">";
            foreach ($lengths as $id => $name) {
                $h .= "<option value=\"{$id}\">{$name}</option>";
            }
            $h .= "</select>";
            $h .= "<br><INPUT type=\"radio\" name=\"ending\" id=\"dateradio\" ";
            $h .= "onChange=\"resetEditResBtn();\">";
            $h .= "<label for=\"dateradio\">";
        }
        if ($request['serverrequest']) {
            $h .= i("End:");
            if ($endchecked) {
                $tmp = explode(' ', $request['end']);
                $edate = $tmp[0];
                $etime = $tmp[1];
            } else {
                $edate = '';
                $etime = '';
            }
        } else {
            $h .= i("Change ending to:");
            $tmp = explode(' ', $request['end']);
            $edate = $tmp[0];
            $etime = $tmp[1];
        }
        if (!empty($lengths) || $request['serverrequest']) {
            $h .= "</label>";
        }
        $h .= "<div type=\"text\" dojoType=\"dijit.form.DateTextBox\" ";
        $h .= "id=\"openenddate\" style=\"width: 78px\" value=\"{$edate}\" ";
        $h .= "onChange=\"selectEnding();\"></div>";
        $h .= "<div type=\"text\" dojoType=\"dijit.form.TimeTextBox\" ";
        $h .= "id=\"openendtime\" style=\"width: 78px\" value=\"T{$etime}\" ";
        $h .= "onChange=\"selectEnding();\"></div>";
        $h .= "<small>(" . date('T') . ")</small>";
        $h .= "<INPUT type=\"hidden\" name=\"enddate\" id=\"enddate\">";
        if ($request['serverrequest'] && $timeToNext == 0) {
            $h .= "<br><br><font color=red>";
            $m = "<strong>" . i("NOTE:") . "</strong> ";
            $m .= i("Due to an upcoming reservation on the same computer, you cannot extend this reservation.");
            $h .= preg_replace("/(.{1,80}([ \n]|\$))/", '\\1<br>', $m);
            $h .= "</font>";
            $noindefinite = 1;
        } elseif ($timeToNext > -1) {
            $extend = $unixend + $timeToNext * 60;
            $extend = date('m/d/Y g:i A', $extend);
            $h .= "<br><br><font color=red>";
            $m = "<strong>" . i("NOTE:") . "</strong> ";
            $m .= sprintf(i("Due to an upcoming reservation on the same computer, you can only extend this reservation until %s."), $extend);
            $h .= preg_replace("/(.{1,80}([ \n]|\$))/", '\\1<br>', $m);
            $h .= "</font>";
            $cdata['maxextend'] = $extend;
            $noindefinite = 1;
        }
    } else {
        $h .= i("Extend reservation by:");
        $h .= "<select dojoType=\"dijit.form.Select\" id=\"length\">";
        foreach ($lengths as $id => $name) {
            $h .= "<option value=\"{$id}\">{$name}</option>";
        }
        $h .= "</select>";
    }
    $h .= "<br>";
    $cont = addContinuationsEntry('AJsubmitEditRequest', $cdata, SECINDAY, 1, 0);
    $data = array('status' => 'modify', 'html' => $h, 'requestid' => $requestid, 'cont' => $cont);
    if ($noindefinite) {
        $data['status'] = 'noindefinite';
    }
    sendJSON($data);
    return;
}
Example #3
0
function XMLRPCsetRequestEnding($requestid, $end)
{
    global $user;
    $requestid = processInputData($requestid, ARG_NUMERIC);
    $userRequests = getUserRequests('all', $user['id']);
    $found = 0;
    foreach ($userRequests as $req) {
        if ($req['id'] == $requestid) {
            $request = getRequestInfo($requestid);
            $found = 1;
            break;
        }
    }
    if (!$found) {
        return array('status' => 'error', 'errorcode' => 1, 'errormsg' => 'unknown requestid');
    }
    // make sure user is a member of the 'Specify End Time' group
    $groupid = getUserGroupID('Specify End Time');
    $members = getUserGroupMembers($groupid);
    if (!$request['serverrequest'] && !array_key_exists($user['id'], $members)) {
        return array('status' => 'error', 'errorcode' => 35, 'errormsg' => "access denied to specify end time");
    }
    $end = processInputData($end, ARG_NUMERIC);
    $maxend = datetimeToUnix("2038-01-01 00:00:00");
    if ($end < 0 || $end > $maxend) {
        return array('status' => 'error', 'errorcode' => 36, 'errormsg' => "received invalid input for end");
    }
    $startts = datetimeToUnix($request['start']);
    if ($end % (15 * 60)) {
        $end = unixFloor15($end) + 15 * 60;
    }
    // check that reservation has started
    if ($startts > time()) {
        return array('status' => 'error', 'errorcode' => 38, 'errormsg' => 'reservation has not started');
    }
    // check for overlap
    $max = getMaxOverlap($user['id']);
    if (checkOverlap($startts, $end, $max, $requestid)) {
        return array('status' => 'error', 'errorcode' => 41, 'errormsg' => 'overlapping reservation restriction', 'maxoverlap' => $max);
    }
    // check for computer being available for extended time?
    $timeToNext = timeToNextReservation($request);
    $movedall = 1;
    if ($timeToNext > -1) {
        $lockedall = 1;
        if (count($request['reservations']) > 1) {
            # get semaphore on each existing node in cluster so that nothing
            # can get moved to the nodes during this process
            $unixend = datetimeToUnix($request['end']);
            $checkend = unixToDatetime($unixend + 900);
            $resources = getUserResources(array("imageAdmin", "imageCheckOut"));
            $tmp = array_keys($resources['image']);
            $semimageid = $tmp[0];
            $semrevid = getProductionRevisionid($semimageid);
            foreach ($request["reservations"] as $res) {
                if (!retryGetSemaphore($semimageid, $semrevid, $res['managementnodeid'], $res['computerid'], $request['start'], $checkend, $requestid)) {
                    $lockedall = 0;
                    break;
                }
            }
        }
        if ($lockedall) {
            foreach ($request["reservations"] as $res) {
                if (!moveReservationsOffComputer($res["computerid"])) {
                    $movedall = 0;
                    break;
                }
            }
        } else {
            cleanSemaphore();
            return array('status' => 'error', 'errorcode' => 42, 'errormsg' => 'cannot extend due to another reservation immediately after this one');
        }
        cleanSemaphore();
    }
    if (!$movedall) {
        $timeToNext = timeToNextReservation($request);
        if ($timeToNext >= 15) {
            $timeToNext -= 15;
        }
        $oldendts = datetimeToUnix($request['end']);
        // reservation immediately after this one, cannot extend
        if ($timeToNext < 15) {
            return array('status' => 'error', 'errorcode' => 42, 'errormsg' => 'cannot extend due to another reservation immediately after this one');
        } elseif (($end - $oldendts) / 60 > $timeToNext) {
            $maxend = $oldendts + $timeToNext * 60;
            return array('status' => 'error', 'errorcode' => 43, 'errormsg' => 'cannot extend by requested amount due to another reservation', 'maxend' => $maxend);
        }
    }
    $rc = isAvailable(getImages(), $request['reservations'][0]["imageid"], $request['reservations'][0]['imagerevisionid'], $startts, $end, 1, $requestid);
    // conflicts with scheduled maintenance
    if ($rc == -2) {
        addChangeLogEntry($request["logid"], NULL, unixToDatetime($end), $request['start'], NULL, NULL, 0);
        return array('status' => 'error', 'errorcode' => 46, 'errormsg' => 'requested time is during a maintenance window');
    } elseif ($rc == -1) {
        addChangeLogEntry($request["logid"], NULL, unixToDatetime($end), $request['start'], NULL, NULL, 0);
        return array('status' => 'error', 'errorcode' => 44, 'errormsg' => 'concurrent license restriction');
    } elseif ($rc == 0) {
        addChangeLogEntry($request["logid"], NULL, unixToDatetime($end), $request['start'], NULL, NULL, 0);
        return array('status' => 'error', 'errorcode' => 45, 'errormsg' => 'cannot extend at this time');
    }
    // success
    updateRequest($requestid);
    cleanSemaphore();
    return array('status' => 'success');
}