diff options
Diffstat (limited to 'modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php')
-rw-r--r-- | modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php | 113 |
1 files changed, 85 insertions, 28 deletions
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php index b1e13e87..3ffecba1 100644 --- a/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php @@ -3,19 +3,28 @@ class IPxeMenu { + /** + * @var int ID of this menu, from DB + */ protected $menuid; + /** + * @var int 0 = disabled, otherwise, launch default option after timeout + */ public $timeoutMs; + /** + * @var string title to display above menu + */ public $title; + /** + * @var int menu entry id from DB + */ public $defaultEntryId; /** * @var MenuEntry[] */ public $items = []; - /** - * @param int $menuId - */ - public static function get($menuId, $emptyFallback = false) + public static function get(int $menuId, bool $emptyFallback = false): ?IPxeMenu { $menu = Database::queryFirst("SELECT menuid, timeoutms, title, defaultentryid FROM serversetup_menu WHERE menuid = :menuid LIMIT 1", ['menuid' => $menuId]); @@ -31,33 +40,34 @@ class IPxeMenu * * @param array $menu array for according menu row */ - public function __construct($menu) + public function __construct(array $menu) { $this->menuid = (int)$menu['menuid']; $this->timeoutMs = (int)$menu['timeoutms']; - $this->title = $menu['title']; - $this->defaultEntryId = $menu['defaultentryid']; + $this->title = (string)$menu['title']; + $defaultEntryId = $menu['defaultentryid']; $res = Database::simpleQuery("SELECT e.menuentryid, e.entryid, e.refmenuid, e.hotkey, e.title, e.hidden, e.sortval, e.md5pass, b.module, b.data AS bootentry, b.title AS betitle FROM serversetup_menuentry e LEFT JOIN serversetup_bootentry b USING (entryid) WHERE e.menuid = :menuid ORDER BY e.sortval ASC, e.title ASC", ['menuid' => $menu['menuid']]); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { $this->items[] = new MenuEntry($row); } // Make sure we have a default entry if the menu isn't empty - if ($this->defaultEntryId === null && !empty($this->items)) { - $this->defaultEntryId = $this->items[0]->menuEntryId(); + if ($defaultEntryId === null && !empty($this->items)) { + $defaultEntryId = $this->items[0]->menuEntryId(); } + $this->defaultEntryId = (int)$defaultEntryId; } - public function title() + public function title(): string { return $this->title; } - public function timeoutMs() + public function timeoutMs(): int { return $this->timeoutMs; } @@ -65,36 +75,74 @@ class IPxeMenu /** * @return int Number of items in this menu */ - public function itemCount() + public function itemCount(): int { return count($this->items); } /** - * @return string|null Return script label of default entry, null if not set + * @return MenuEntry|null Return preselected menu entry */ - public function getDefaultEntryId() + public function defaultEntry(): ?MenuEntry { - return $this->defaultEntryId; + foreach ($this->items as $item) { + if ($item->menuEntryId() === $this->defaultEntryId) + return $item; + } + return null; + } + + private function maybeOverrideDefault(string $uuid) + { + $e = $this->defaultEntry(); + // Shortcut - is already bwlp and timeout is reasonable (1-15s), do nothing + $defIsMl = $e !== null && substr($e->internalId(), 0, 3) === 'ml-'; + $timeoutOk = $this->timeoutMs > 0 && $this->timeoutMs <= 15000; + if ($timeoutOk && $defIsMl) + return; + // No runmode module anyways + if (!Module::isAvailable('runmode')) + return; + $rm = RunMode::getRunMode($uuid); + // No runmode for this client, cannot be PVSmgr + if ($rm === false) + return; + // Is not pvsmgr + if ($rm['module'] !== 'roomplanner') + return; + // See if it's a dedicated station, if so make sure it boots into bwLehrpool + $data = json_decode($rm['modedata'], true); + if ($data['dedicatedmgr'] ?? false) { + if (!$defIsMl) { + $this->overrideDefaultToMinilinux(); + } + if (!$timeoutOk) { + $this->timeoutMs = 5000; + } + } } /** - * @return MenuEntry|null Return preselected menu entry + * Patch the menu to make sure bwLehrpool/"MiniLinux" is the default + * boot option, and set timeout to something reasonable. This is used + * for dedicated PVS managers, as they might not have a keyboard + * connected. */ - public function defaultEntry() + private function overrideDefaultToMinilinux() { foreach ($this->items as $item) { - if ($item->menuEntryId() == $this->defaultEntryId) - return $item; + if (substr($item->internalId(), 0, 3) === 'ml-') { + $this->defaultEntryId = $item->menuEntryId(); + return; + } } - return null; } /* * */ - public static function forLocation($locationId) : IPxeMenu + public static function forLocation(int $locationId): IPxeMenu { $chain = null; if (Module::isAvailable('locations')) { @@ -109,7 +157,7 @@ class IPxeMenu if ($res->rowCount() > 0) { // Make the location id key, preserving order (closest location is first) $chain = array_flip($chain); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { // Overwrite the value (numeric ascending values, useless) with menu array of according location $chain[(int)$row['locationid']] = $row; } @@ -132,13 +180,19 @@ class IPxeMenu return new IPxeMenu($menu); } - public static function forClient($ip, $uuid) : IPxeMenu + public static function forClient(string $ip, ?string $uuid): IPxeMenu { $locationId = 0; if (Module::isAvailable('locations')) { $locationId = Location::getFromIpAndUuid($ip, $uuid); } - return self::forLocation($locationId); + $menu = self::forLocation($locationId); + if ($uuid !== null) { + // Super specialcase hackery: If this is a dedicated PVS, force the default to + // be bwlp/"minilinux" + $menu->maybeOverrideDefault($uuid); + } + return $menu; } } @@ -146,11 +200,14 @@ class IPxeMenu class EmptyIPxeMenu extends IPxeMenu { - /** @noinspection PhpMissingParentConstructorInspection */ public function __construct() { - $this->title = 'No menu defined'; - $this->menuid = -1; + parent::__construct([ + 'menuid' => -1, + 'timeoutms' => 120, + 'defaultentryid' => null, + 'title' => 'No menu defined', + ]); $this->items[] = new MenuEntry([ 'title' => 'Please create a menu in Server-Setup first' ]); |