diff options
Diffstat (limited to 'modules-available/remoteaccess/inc/remoteaccess.inc.php')
-rw-r--r-- | modules-available/remoteaccess/inc/remoteaccess.inc.php | 79 |
1 files changed, 56 insertions, 23 deletions
diff --git a/modules-available/remoteaccess/inc/remoteaccess.inc.php b/modules-available/remoteaccess/inc/remoteaccess.inc.php index 37d33d45..95ca3821 100644 --- a/modules-available/remoteaccess/inc/remoteaccess.inc.php +++ b/modules-available/remoteaccess/inc/remoteaccess.inc.php @@ -7,14 +7,32 @@ class RemoteAccess const PROP_TRY_VIRT_HANDOVER = 'remoteaccess.virthandover'; - public static function getEnabledLocations($group = 0) + const PROP_VNC_PORT = 'remoteaccess.vncport'; + + const PROP_PLUGIN_VERSION = 'remoteaccess.plugin-version'; + + /** + * Get a list of locationIds where remote access is enabled. If $filterOverridden is true, + * the list will not contain any locations where remote access is disabled via location override. + * @param int $group Group to get locations for, or '0' for all locations + * @param bool $filterOverridden iff true, remove any locations where remote access is currently disabled + */ + public static function getEnabledLocations(int $group = 0, bool $filterOverridden = true): array { if ($group === 0) { - return Database::queryColumnArray("SELECT DISTINCT rxl.locationid FROM remoteaccess_x_location rxl + $list = Database::queryColumnArray("SELECT DISTINCT rxl.locationid FROM remoteaccess_x_location rxl INNER JOIN remoteaccess_group g ON (g.groupid = rxl.groupid AND g.active = 1)"); - } - return Database::queryColumnArray("SELECT DISTINCT locationid FROM remoteaccess_x_location + } else { + $list = Database::queryColumnArray("SELECT DISTINCT locationid FROM remoteaccess_x_location WHERE groupid = :gid", ['gid' => $group]); + } + if (!$filterOverridden || !Module::isAvailable('rebootcontrol')) + return $list; + return array_filter($list, function (int $lid) { + $mode = Scheduler::getLocationOptions($lid)['ra-mode']; + return ($mode !== Scheduler::RA_NEVER + && ($mode !== Scheduler::RA_SELECTIVE || !OpeningTimes::isRoomOpen($lid, 5, 5))); + }); } public static function ensureMachinesRunning() @@ -24,41 +42,58 @@ class RemoteAccess return; } - $res = Database::simpleQuery("SELECT rg.groupid, rg.groupname, rg.wolcount, GROUP_CONCAT(rxl.locationid) AS locs FROM remoteaccess_group rg + $res = Database::simpleQuery("SELECT rg.groupid, rg.groupname, rg.wolcount, + GROUP_CONCAT(rxl.locationid) AS locs + FROM remoteaccess_group rg INNER JOIN remoteaccess_x_location rxl USING (groupid) WHERE rg.active = 1 GROUP BY groupid"); // Consider machines we tried to wake in the past 90 seconds as online $wolDeadline = time() - 90; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if ($row['wolcount'] <= 0) - continue; + foreach ($res as $row) { + $wantNum = $row['wolcount']; // This can't really be anything but a CSV list, but better be safe $locs = preg_replace('/[^0-9,]/', '', $row['locs']); - if (empty($locs)) - continue; - $active = Database::queryFirst("SELECT Count(*) AS cnt FROM machine m + if (!empty($locs)) { + // Filter out locations for which remote-access is disabled + $locArray = explode(',', $locs); + $locArray = array_filter($locArray, function (int $lid) { + $mode = Scheduler::getLocationOptions($lid)['ra-mode']; + return ($mode !== Scheduler::RA_NEVER + && ($mode !== Scheduler::RA_SELECTIVE || !OpeningTimes::isRoomOpen($lid, 5, 5))); + }); + $locs = implode(',', $locArray); + } + if ($wantNum > 0 && !empty($locs)) { + $active = Database::queryFirst("SELECT Count(*) AS cnt FROM machine m INNER JOIN remoteaccess_machine rm USING (machineuuid) WHERE m.locationid IN ($locs) AND (m.state = 'IDLE' OR rm.woltime > $wolDeadline)"); - $active = (isset($active['cnt']) ? $active['cnt'] : 0); - $wantNum = $row['wolcount'] - $active; - if ($wantNum <= 0) - continue; - self::tryWakeMachines($locs, $wantNum); + $active = ($active['cnt'] ?? 0); + $wantNum -= $active; + } + if ($wantNum > 0) { + $numFailed = self::tryWakeMachines($locs, $wantNum); + } else { + $numFailed = 0; + } + Database::exec("UPDATE remoteaccess_group SET unwoken = :num WHERE groupid = :groupid", + ['num' => $numFailed, 'groupid' => $row['groupid']]); } } - private static function tryWakeMachines($locs, $num) + private static function tryWakeMachines(string $locs, int $num): int { - $res = Database::simpleQuery("SELECT m.machineuuid, m.macaddr, m.clientip FROM machine m + if (empty($locs)) + return $num; + $res = Database::simpleQuery("SELECT m.machineuuid, m.macaddr, m.clientip, m.locationid FROM machine m LEFT JOIN remoteaccess_machine rm USING (machineuuid) WHERE m.locationid IN ($locs) AND m.state IN ('OFFLINE', 'STANDBY') ORDER BY rm.woltime ASC"); $NOW = time(); while ($num > 0) { $list = []; - for ($i = 0; $i < $num && $row = $res->fetch(PDO::FETCH_ASSOC); ++$i) { + for ($i = 0; $i < $num && ($row = $res->fetch()); ++$i) { $list[] = $row; Database::exec("INSERT INTO remoteaccess_machine (machineuuid, password, woltime) VALUES (:uuid, NULL, :now) @@ -68,7 +103,7 @@ class RemoteAccess if (empty($list)) break; // No more clients in this location RebootControl::wakeMachines($list, $fails); - $num -= count($list) - count($fails); + $num -= (count($list) - count($fails)); if (!empty($fails)) { $failIds = ArrayUtil::flattenByKey($fails, 'machineuuid'); // Reduce time so they won't be marked as wol_in_progress @@ -76,9 +111,7 @@ class RemoteAccess ['faketime' => $NOW - 95, 'fails' => $failIds]); } } - if ($num > 0) { - error_log("Could not wake $num clients in ($locs)..."); - } + return $num; } } |