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); }
function AJvmFromHost() { $hostid = processInputVar('hostid', ARG_NUMERIC); $hostdata = getVMHostData($hostid); $resources = getUserResources(array("computerAdmin"), array("administer")); if (!array_key_exists($hostdata[$hostid]['computerid'], $resources['computer'])) { sendJSON(array('failed' => 'nohostaccess')); return; } $fails = array(); $vmlistids = processInputVar('listids', ARG_STRING); $vmids = explode(',', $vmlistids); $rems = array(); $checks = array(); $vclreloadid = getUserlistID('vclreload@Local'); $imageid = getImageId('noimage'); $imagerevisionid = getProductionRevisionid($imageid); $start = getReloadStartTime(); $end = $start + SECINMONTH; $start = unixToDatetime($start); $end = unixToDatetime($end); foreach ($vmids as $compid) { $compdata = getComputers(0, 0, $compid); if (!array_key_exists($compid, $resources['computer'])) { $fails[] = array('id' => $compid, 'name' => $compdata[$compid]['hostname'], 'reason' => 'noaccess'); continue; } # try to remove reservations off of computer moveReservationsOffComputer($compid); cleanSemaphore(); # check for unmovable or active reservations $query = "SELECT DATE_FORMAT(rq.end, '%l:%i%p %c/%e/%y') AS end, " . "rq.end AS end2 " . "FROM request rq, " . "reservation rs " . "WHERE rs.requestid = rq.id AND " . "rs.computerid = {$compid} AND " . "rq.stateid NOT IN (1,5,12) " . "ORDER BY end DESC " . "LIMIT 1"; $qh = doQuery($query, 101); if ($row = mysql_fetch_assoc($qh)) { $checks[] = array('id' => $compid, 'hostname' => $compdata[$compid]['hostname'], 'end' => strtolower($row['end']), 'end2' => $row['end2']); } else { // if no reservations on computer, submit reload # reservation so vm gets stopped on host $reqid = simpleAddRequest($compid, $imageid, $imagerevisionid, $start, $end, 18, $vclreloadid); if ($reqid == 0) { $fails[] = array('id' => $compid, 'name' => $compdata[$compid]['hostname'], 'reason' => 'nomgtnode'); } else { $rems[] = array('id' => $compid, 'hostname' => $compdata[$compid]['hostname'], 'reqid' => $reqid, 'time' => 'immediately'); } } } if (count($checks)) { $cont = addContinuationsEntry('AJvmFromHostDelayed', $checks, 120, 1, 0); } else { $cont = ''; } $arr = array('vms' => $rems, 'checks' => $checks, 'fails' => $fails, 'addrem' => 0, 'cont' => $cont); sendJSON($arr); }
function AJvmFromHost() { $hostid = processInputVar('hostid', ARG_NUMERIC); $hostdata = getVMHostData($hostid); $resources = getUserResources(array("computerAdmin"), array("administer")); if (!array_key_exists($hostdata[$hostid]['computerid'], $resources['computer'])) { $arr = array('failed' => 'nohostaccess'); header('Content-Type: text/json-comment-filtered; charset=utf-8'); print '/*{"items":' . json_encode($arr) . '}*/'; return; } $fails = array(); $vmlistids = processInputVar('listids', ARG_STRING); $vmids = explode(',', $vmlistids); $rems = array(); $checks = array(); $vclreloadid = getUserlistID('vclreload@Local'); $start = getReloadStartTime(); $end = $start + SECINMONTH; $start = unixToDatetime($start); $end = unixToDatetime($end); foreach ($vmids as $compid) { $compdata = getComputers(0, 0, $compid); if (!array_key_exists($compid, $resources['computer'])) { $fails[] = array('id' => $compid, 'name' => $compdata[$compid]['hostname'], 'reason' => 'noaccess'); continue; } # try to remove reservations off of computer if (($compdata[$compid]['state'] == 'available' || $compdata[$compid]['state'] == 'maintenance' || $compdata[$compid]['state'] == 'failed') && moveReservationsOffComputer($compid)) { // if no reservations on computer, submit reload # reservation so vm gets stopped on host $reqid = simpleAddRequest($compid, 4, 3, $start, $end, 18, $vclreloadid); $rems[] = array('id' => $compid, 'hostname' => $compdata[$compid]['hostname'], 'reqid' => $reqid, 'time' => 'immediately'); } else { # existing reservation on computer, find end time and prompt user # if ok to wait until then to move it $query = "SELECT DATE_FORMAT(rq.end, '%l:%i%p %c/%e/%y') AS end, " . "rq.end AS end2 " . "FROM request rq, " . "reservation rs " . "WHERE rs.requestid = rq.id AND " . "rs.computerid = {$compid} AND " . "rq.stateid NOT IN (1,5,12) " . "ORDER BY end DESC " . "LIMIT 1"; $qh = doQuery($query, 101); if ($row = mysql_fetch_assoc($qh)) { $checks[] = array('id' => $compid, 'hostname' => $compdata[$compid]['hostname'], 'end' => strtolower($row['end']), 'end2' => $row['end2']); } else { $rems[] = array('id' => $compid); } } } if (count($checks)) { $cont = addContinuationsEntry('AJvmFromHostDelayed', $checks, 120, 1, 0); } else { $cont = ''; } header('Content-Type: text/json-comment-filtered; charset=utf-8'); $arr = array('vms' => $rems, 'checks' => $checks, 'fails' => $fails, 'addrem' => 0, 'cont' => $cont); print '/*{"items":' . json_encode($arr) . '}*/'; }
function submitCompStateChange() { global $user; print "<H2>Change State of Computers</H2>\n"; $data = getContinuationVar(); $computers = getComputers(1); # switching to available if ($data['stateid'] == 2) { $compids = implode(',', $data['computerids']); $query = "UPDATE computer " . "SET stateid = 2, " . "notes = '' " . "WHERE id IN ({$compids})"; doQuery($query, 101); print "The following computers were changed to the available state:\n"; print "<TABLE>\n"; foreach ($data['computerids'] as $compid) { print " <TR>\n"; print " <TD>{$computers[$compid]['hostname']}</TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; } elseif ($data['stateid'] == 10) { $data['notes'] = processInputVar('notes', ARG_STRING); if (get_magic_quotes_gpc()) { $data['notes'] = stripslashes($data['notes']); } $data['notes'] = mysql_escape_string($data['notes']); $data["notes"] = $user["unityid"] . " " . unixToDatetime(time()) . "@" . $data["notes"]; $vclreloadid = getUserlistID('vclreload@Local'); // get semaphore lock if (!semLock()) { abort(3); } $noaction = array(); $changenow = array(); $changeasap = array(); $changetimes = array(); foreach ($data['computerids'] as $compid) { if ($computers[$compid]['state'] == 'maintenance') { array_push($noaction, $compid); } else { array_push($changeasap, $compid); } } $passes = array(); $fails = array(); foreach ($changeasap as $compid) { # TODO what about blockComputers? # try to move future reservations off of computer moveReservationsOffComputer($compid); # get end time of last reservation $query = "SELECT rq.end " . "FROM request rq, " . "reservation rs " . "WHERE rs.requestid = rq.id AND " . "rs.computerid = {$compid} AND " . "rq.stateid NOT IN (1,5,12) " . "ORDER BY end DESC " . "LIMIT 1"; $qh = doQuery($query, 101); # create a really long reservation starting at that time in state tomaintenance if ($row = mysql_fetch_assoc($qh)) { $start = $row['end']; $changetimes[$compid] = $start; $end = datetimeToUnix($start) + SECINWEEK; // hopefully keep future reservations off of it $end = unixToDatetime($end); if (simpleAddRequest($compid, 4, 3, $start, $end, 18, $vclreloadid)) { $passes[] = $compid; } else { $fails[] = $compid; } } else { $query = "UPDATE computer " . "SET stateid = 10, " . "notes = '{$data['notes']}' " . "WHERE id = {$compid}"; doQuery($query, 101); unset_by_val($compid, $changeasap); array_push($changenow, $compid); } } // release semaphore lock semUnlock(); if (count($noaction) || count($changeasap)) { $comparr = array_merge($noaction, $changeasap); $compids = implode(',', $comparr); $query = "UPDATE computer " . "SET notes = '{$data['notes']}' " . "WHERE id IN ({$compids})"; doQuery($query, 101); } if (count($changenow)) { print "The following computers were immediately placed into the "; print "maintenance state:\n"; print "<TABLE>\n"; foreach ($changenow as $compid) { print " <TR>\n"; print " <TD><font color=\"#008000\">{$computers[$compid]['hostname']}</font></TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } if (count($passes)) { print "The following computers currently have reservations on them "; print "and will be placed in the maintenance state at the time listed "; print "for each computer:\n"; print "<TABLE>\n"; print " <TR>\n"; print " <TH>Computer</TH>\n"; print " <TH>Maintenance time</TH>\n"; print " </TR>\n"; foreach ($passes as $compid) { print " <TR>\n"; print " <TD align=center><font color=\"ff8c00\">{$computers[$compid]['hostname']}</font></TD>\n"; $time = date('n/j/y g:i a', datetimeToUnix($changetimes[$compid])); print " <TD align=center>{$time}</TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } if (count($fails)) { print "The following computers currently have reservations on them "; print "but no functional management node was found for them. Nothing "; print "be done with them at this time:\n"; print "<TABLE>\n"; print " <TR>\n"; print " <TH>Computer</TH>\n"; print " </TR>\n"; foreach ($passes as $compid) { print " <TR>\n"; print " <TD align=center><font color=\"ff0000\">{$computers[$compid]['hostname']}</font></TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } if (count($noaction)) { print "The following computers were already in the maintenance "; print "state and had their notes on being in the maintenance state "; print "updated:\n"; print "<TABLE>\n"; foreach ($noaction as $compid) { print " <TR>\n"; print " <TD>{$computers[$compid]['hostname']}</TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } } elseif ($data['stateid'] == 20) { $profileid = processInputVar('profileid', ARG_NUMERIC); if (!array_key_exists($profileid, $data['profiles'])) { $keys = array_keys($data['profiles']); $profileid = $keys[0]; } $noaction = array(); $changenow = array(); $changeasap = array(); $changetimes = array(); foreach ($data['computerids'] as $compid) { if ($computers[$compid]['state'] == 'vmhostinuse') { array_push($noaction, $compid); } else { array_push($changeasap, $compid); } } if (!semLock()) { abort(3); } foreach ($changeasap as $compid) { # TODO what about blockComputers? moveReservationsOffComputer($compid); # get end time of last reservation $query = "SELECT rq.end " . "FROM request rq, " . "reservation rs " . "WHERE rs.requestid = rq.id AND " . "rs.computerid = {$compid} AND " . "rq.stateid NOT IN (1,5,12) " . "ORDER BY end DESC " . "LIMIT 1"; $qh = doQuery($query, 101); if ($row = mysql_fetch_assoc($qh)) { // if there is a reservation, leave in $changeasap so we can # notify that we can't change this one } else { # create a reload reservation to load machine with image # corresponding to selected vm profile $start = getReloadStartTime(); $end = $start + SECINYEAR; # don't want anyone making a future reservation for this machine $start = unixToDatetime($start); $end = unixToDatetime($end); $imagerevisionid = getProductionRevisionid($data['profiles'][$profileid]['imageid']); $vclreloadid = getUserlistID('vclreload@Local'); simpleAddRequest($compid, $data['profiles'][$profileid]['imageid'], $imagerevisionid, $start, $end, 21, $vclreloadid); unset_by_val($compid, $changeasap); array_push($changenow, $compid); # check for existing vmhost entry $query = "SELECT id, " . "vmprofileid " . "FROM vmhost " . "WHERE computerid = {$compid}"; $qh = doQuery($query, 101); if ($row = mysql_fetch_assoc($qh)) { if ($row['vmprofileid'] != $profileid) { # update vmprofile $query = "UPDATE vmhost " . "SET vmprofileid = {$profileid} " . "WHERE id = {$row['id']}"; doQuery($query, 101); } } else { # create vmhost entry $query = "INSERT INTO vmhost " . "(computerid, " . "vmlimit, " . "vmprofileid) " . "VALUES ({$compid}, " . "2, " . "{$profileid})"; doQuery($query, 101); } } } // release semaphore lock semUnlock(); if (count($changenow)) { print "The following computers were placed into the "; print "vmhostinuse state:\n"; print "<TABLE>\n"; foreach ($changenow as $compid) { print " <TR>\n"; print " <TD><font color=\"#008000\">{$computers[$compid]['hostname']}</font></TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } if (count($changeasap)) { print "The following computers currently have reservations on them "; print "and cannot be placed in the vmhostinuse state at this time:\n"; print "<TABLE>\n"; foreach ($changeasap as $compid) { print " <TR>\n"; print " <TD><font color=\"ff0000\">{$computers[$compid]['hostname']}</font></TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } if (count($noaction)) { print "The following computers were already in the vmhostinuse "; print "state:\n"; print "<TABLE>\n"; foreach ($noaction as $compid) { print " <TR>\n"; print " <TD>{$computers[$compid]['hostname']}</TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } } elseif ($data['stateid'] == 23) { $noaction = array(); $changenow = array(); $changeasap = array(); $changetimes = array(); foreach ($data['computerids'] as $compid) { if ($computers[$compid]['state'] == 'hpc') { array_push($noaction, $compid); } else { array_push($changeasap, $compid); } } if (!semLock()) { abort(3); } foreach ($changeasap as $compid) { # TODO what about blockComputers? moveReservationsOffComputer($compid); # get end time of last reservation $query = "SELECT rq.end " . "FROM request rq, " . "reservation rs " . "WHERE rs.requestid = rq.id AND " . "rs.computerid = {$compid} AND " . "rq.stateid NOT IN (1,5,12) " . "ORDER BY end DESC " . "LIMIT 1"; $qh = doQuery($query, 101); if ($row = mysql_fetch_assoc($qh)) { // if there is a reservation, leave in $changeasap so we can # notify that we can't change this one } else { $query = "UPDATE computer " . "SET stateid = 23 " . "WHERE id = {$compid}"; doQuery($query, 101); unset_by_val($compid, $changeasap); array_push($changenow, $compid); } } // release semaphore lock semUnlock(); if (count($changenow)) { print "The following computers were placed into the "; print "hpc state:\n"; print "<TABLE>\n"; foreach ($changenow as $compid) { print " <TR>\n"; print " <TD><font color=\"#008000\">{$computers[$compid]['hostname']}</font></TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } if (count($changeasap)) { print "The following computers currently have reservations on them "; print "and cannot be placed in the hpc state at this time:\n"; print "<TABLE>\n"; foreach ($changeasap as $compid) { print " <TR>\n"; print " <TD><font color=\"ff0000\">{$computers[$compid]['hostname']}</font></TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } if (count($noaction)) { print "The following computers were already in the hpc "; print "state:\n"; print "<TABLE>\n"; foreach ($noaction as $compid) { print " <TR>\n"; print " <TD>{$computers[$compid]['hostname']}</TD>\n"; print " </TR>\n"; } print "</TABLE>\n"; print "<br>\n"; } } else { abort(50); } }