From be0f53e0029aff5afdbb49ed4d294c72ee0ccfa2 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 9 Jun 2022 11:49:03 +0200 Subject: [remoteaccess] Track unwakable machines, ignore restricted locations - Locations that are set to "never" or "only outside business hours" will not be considered during WOL, and not delivered to the guacamole proxy. - If we cannot wake as much machines per remote group as configured, we'll display a little number next to the WOL count setting. --- .../remoteaccess/inc/remoteaccess.inc.php | 61 +++++++++++++++------- modules-available/remoteaccess/install.inc.php | 10 ++++ modules-available/remoteaccess/page.inc.php | 2 +- .../remoteaccess/templates/edit-settings.html | 9 +++- 4 files changed, 59 insertions(+), 23 deletions(-) (limited to 'modules-available/remoteaccess') diff --git a/modules-available/remoteaccess/inc/remoteaccess.inc.php b/modules-available/remoteaccess/inc/remoteaccess.inc.php index 1910c595..ce6bf0db 100644 --- a/modules-available/remoteaccess/inc/remoteaccess.inc.php +++ b/modules-available/remoteaccess/inc/remoteaccess.inc.php @@ -11,14 +11,20 @@ class RemoteAccess const PROP_PLUGIN_VERSION = 'remoteaccess.plugin-version'; - public static function getEnabledLocations($group = 0) + public static function getEnabledLocations(int $group = 0) { 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]); + } + 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() @@ -28,7 +34,9 @@ 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"); @@ -36,25 +44,40 @@ class RemoteAccess // Consider machines we tried to wake in the past 90 seconds as online $wolDeadline = time() - 90; foreach ($res as $row) { - if ($row['wolcount'] <= 0) - continue; + $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 { + 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') @@ -72,7 +95,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 @@ -80,9 +103,7 @@ class RemoteAccess ['faketime' => $NOW - 95, 'fails' => $failIds]); } } - if ($num > 0) { - error_log("Could not wake $num clients in ($locs)..."); - } + return $num; } } diff --git a/modules-available/remoteaccess/install.inc.php b/modules-available/remoteaccess/install.inc.php index 2e248282..2a6fec36 100644 --- a/modules-available/remoteaccess/install.inc.php +++ b/modules-available/remoteaccess/install.inc.php @@ -8,6 +8,7 @@ $dbret[] = tableCreate('remoteaccess_group', " `wolcount` smallint(11) NOT NULL, `passwd` varchar(100) NOT NULL, `active` tinyint(1) UNSIGNED NOT NULL DEFAULT '1', + `unwoken` int(10) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (`groupid`) "); @@ -67,4 +68,13 @@ if (!tableHasColumn('remoteaccess_machine', 'vncport')) { $dbret[] = UPDATE_DONE; } +// 2022-06-01 Unwoken machines: Keeps track of how many machines could not be WOLed +if (!tableHasColumn('remoteaccess_group', 'unwoken')) { + $ret = Database::exec("ALTER TABLE remoteaccess_group ADD COLUMN `unwoken` int(10) UNSIGNED NOT NULL DEFAULT '0'"); + if ($ret === false) { + finalResponse(UPDATE_FAILED, Database::lastError()); + } + $dbret[] = UPDATE_DONE; +} + responseFromArray($dbret); diff --git a/modules-available/remoteaccess/page.inc.php b/modules-available/remoteaccess/page.inc.php index 70d34238..05816beb 100644 --- a/modules-available/remoteaccess/page.inc.php +++ b/modules-available/remoteaccess/page.inc.php @@ -92,7 +92,7 @@ class Page_RemoteAccess extends Page if ($groupid === false) { // Edit list of groups and their settings $groups = Database::queryAll("SELECT g.groupid, g.groupname, g.wolcount, g.passwd, - Count(l.locationid) AS locs, If(g.active, 'checked', '') AS checked + Count(l.locationid) AS locs, If(g.active, 'checked', '') AS checked, unwoken FROM remoteaccess_group g LEFT JOIN remoteaccess_x_location l USING (groupid) GROUP BY g.groupid, g.groupname ORDER BY g.groupname ASC"); diff --git a/modules-available/remoteaccess/templates/edit-settings.html b/modules-available/remoteaccess/templates/edit-settings.html index 21ce3b6e..a14bac45 100644 --- a/modules-available/remoteaccess/templates/edit-settings.html +++ b/modules-available/remoteaccess/templates/edit-settings.html @@ -80,9 +80,14 @@ - + + {{#unwoken}} + + {{unwoken}} + + {{/unwoken}}
- \ No newline at end of file + -- cgit v1.2.3-55-g7522