From 672ead2f9d19a1651f5a87e11c1c04db5edacd08 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 2 May 2022 13:09:08 +0200 Subject: [serversetup-bwlp-ipxe] Force default boot entry to MiniLinux for dedicated PVSmgr --- .../minilinux/inc/linuxbootentryhook.inc.php | 2 +- .../serversetup-bwlp-ipxe/inc/bootentry.inc.php | 25 +++++++- .../serversetup-bwlp-ipxe/inc/ipxemenu.inc.php | 73 +++++++++++++++++++--- .../serversetup-bwlp-ipxe/inc/menuentry.inc.php | 5 ++ 4 files changed, 94 insertions(+), 11 deletions(-) diff --git a/modules-available/minilinux/inc/linuxbootentryhook.inc.php b/modules-available/minilinux/inc/linuxbootentryhook.inc.php index 9e10bd6e..abcb0000 100644 --- a/modules-available/minilinux/inc/linuxbootentryhook.inc.php +++ b/modules-available/minilinux/inc/linuxbootentryhook.inc.php @@ -122,7 +122,7 @@ class LinuxBootEntryHook extends BootEntryHook $arch = BootEntry::EFI; } } - return BootEntry::newStandardBootEntry($bios, $efi, $arch); + return BootEntry::newStandardBootEntry($bios, $efi, $arch, 'ml-' . $id); } private function generateExecData($effectiveId, $remoteData, $localData): ExecData diff --git a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php index 08b65ed6..0212e061 100644 --- a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php @@ -12,6 +12,16 @@ abstract class BootEntry /** Supports both via distinct entry */ const BOTH = 'PCBIOS-EFI'; + /** + * @var string Internal ID - set to your liking, e.g. the MiniLinux version identifier + */ + protected $internalId; + + public function __construct(string $internalId) + { + $this->internalId = $internalId; + } + public abstract function supportsMode($mode); /** @@ -24,6 +34,11 @@ abstract class BootEntry public abstract function addFormFields(&$array); + public function internalId(): string + { + return $this->internalId; + } + /* * */ @@ -69,9 +84,9 @@ abstract class BootEntry return new MenuBootEntry($menuId); } - public static function newStandardBootEntry($initData, $efi = false, $arch = false) + public static function newStandardBootEntry($initData, $efi = false, $arch = false, string $internalId = '') { - $ret = new StandardBootEntry($initData, $efi, $arch); + $ret = new StandardBootEntry($initData, $efi, $arch, $internalId); $list = []; if ($ret->arch() !== self::EFI) { $list[] = self::BIOS; @@ -149,8 +164,9 @@ class StandardBootEntry extends BootEntry const KEYS = ['executable', 'initRd', 'commandLine', 'replace', 'imageFree', 'autoUnload', 'resetConsole', 'dhcpOptions']; - public function __construct($data, $efi = false, $arch = false) + public function __construct($data, $efi = false, $arch = false, string $internalId = '') { + parent::__construct($internalId); $this->pcbios = new ExecData(); $this->efi = new ExecData(); if ($data instanceof PxeSection) { @@ -306,6 +322,7 @@ class CustomBootEntry extends BootEntry public function __construct($data) { + parent::__construct('custom'); if (is_array($data)) { $this->ipxe = $data['script'] ?? ''; // LEGACY foreach (['bash', 'grub'] as $key) { @@ -348,6 +365,7 @@ class MenuBootEntry extends BootEntry public function __construct($menuId) { + parent::__construct('menu-' . $menuId); $this->menuId = $menuId; } @@ -379,6 +397,7 @@ class SpecialBootEntry extends BootEntry public function __construct($type) { + parent::__construct('special-' . $type); $this->type = $type['type'] ?? $type; } diff --git a/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php index 587d9200..deaa2fdb 100644 --- a/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php @@ -3,8 +3,17 @@ 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; public $defaultEntryId; /** @@ -35,7 +44,7 @@ class IPxeMenu { $this->menuid = (int)$menu['menuid']; $this->timeoutMs = (int)$menu['timeoutms']; - $this->title = $menu['title']; + $this->title = (string)$menu['title']; $this->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 @@ -52,12 +61,12 @@ class IPxeMenu } } - public function title() + public function title(): string { return $this->title; } - public function timeoutMs() + public function timeoutMs(): int { return $this->timeoutMs; } @@ -65,7 +74,7 @@ class IPxeMenu /** * @return int Number of items in this menu */ - public function itemCount() + public function itemCount(): int { return count($this->items); } @@ -90,11 +99,57 @@ class IPxeMenu 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['modeid'] !== '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; + } + } + } + + /** + * 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. + */ + private function overrideDefaultToMinilinux() + { + foreach ($this->items as $item) { + if (substr($item->internalId(), 0, 3) === 'ml-') { + $this->defaultEntryId = $item->menuEntryId(); + return; + } + } + } + /* * */ - public static function forLocation($locationId) : IPxeMenu + public static function forLocation(int $locationId): IPxeMenu { $chain = null; if (Module::isAvailable('locations')) { @@ -132,13 +187,17 @@ 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); + // Super specialcase hackery: If this is a dedicated PVS, force the default to + // be bwlp/"minilinux" + $menu->maybeOverrideDefault($uuid); + return $menu; } } diff --git a/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php index eb4a98de..3106291e 100644 --- a/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php @@ -98,6 +98,11 @@ class MenuEntry return $this->title; } + public function internalId(): string + { + return $this->bootEntry->internalId(); + } + /* * */ -- cgit v1.2.3-55-g7522