summaryrefslogtreecommitdiffstats
path: root/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php')
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php189
1 files changed, 111 insertions, 78 deletions
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php
index f87d15c2..3ffecba1 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php
@@ -3,84 +3,71 @@
class IPxeMenu
{
+ /**
+ * @var int ID of this menu, from DB
+ */
protected $menuid;
- protected $timeoutMs;
- protected $title;
- protected $defaultEntryId;
+ /**
+ * @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[]
*/
- protected $items = [];
+ public $items = [];
- public function __construct($menu)
+ 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]);
+ if ($menu !== false)
+ return new IPxeMenu($menu);
+ if (!$emptyFallback)
+ return null;
+ return new EmptyIPxeMenu();
+ }
+
+ /**
+ * IPxeMenu constructor.
+ *
+ * @param array $menu array for according menu row
+ */
+ public function __construct(array $menu)
{
- if (!is_array($menu)) {
- $menu = Database::queryFirst("SELECT menuid, timeoutms, title, defaultentryid FROM serversetup_menu
- WHERE menuid = :menuid LIMIT 1", ['menuid' => $menu]);
- if (!is_array($menu)) {
- $menu = ['menuid' => 'foo', 'title' => 'Invalid Menu ID: ' . (int)$menu];
- }
- }
$this->menuid = (int)$menu['menuid'];
$this->timeoutMs = (int)$menu['timeoutms'];
- $this->title = $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
+ $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();
- }
- }
-
- public function getMenuDefinition($targetVar, $mode, $slxExtensions)
- {
- $str = "menu -- {$this->title}\n";
- foreach ($this->items as $item) {
- $str .= $item->getMenuItemScript("m_{$this->menuid}", $this->defaultEntryId, $mode, $slxExtensions);
- }
- if ($this->defaultEntryId === null) {
- $defaultLabel = "mx_{$this->menuid}_poweroff";
- } else {
- $defaultLabel = "m_{$this->menuid}_{$this->defaultEntryId}";
- }
- $str .= "choose";
- if ($this->timeoutMs > 0) {
- $str .= " --timeout {$this->timeoutMs}";
+ if ($defaultEntryId === null && !empty($this->items)) {
+ $defaultEntryId = $this->items[0]->menuEntryId();
}
- $str .= " $targetVar || goto $defaultLabel || goto fail\n";
- if ($this->defaultEntryId === null) {
- $str .= "goto skip_{$defaultLabel}\n"
- . ":{$defaultLabel}\n"
- . "poweroff || goto fail\n"
- . ":skip_{$defaultLabel}\n";
- }
- return $str;
- }
-
- public function getItemsCode($mode)
- {
- $str = '';
- foreach ($this->items as $item) {
- $str .= $item->getBootEntryScript("m_{$this->menuid}", 'fail', $mode);
- $str .= "goto slx_menu\n";
- }
- return $str;
+ $this->defaultEntryId = (int)$defaultEntryId;
}
- public function title()
+ public function title(): string
{
return $this->title;
}
- public function timeoutMs()
+ public function timeoutMs(): int
{
return $this->timeoutMs;
}
@@ -88,52 +75,89 @@ class IPxeMenu
/**
* @return int Number of items in this menu
*/
- public function itemCount()
+ public function itemCount(): int
{
return count($this->items);
}
/**
- * @return string|false Return script label of default entry, false if not set
+ * @return MenuEntry|null Return preselected menu entry
*/
- public function getDefaultScriptLabel()
+ public function defaultEntry(): ?MenuEntry
{
- if ($this->defaultEntryId !== null)
- return "m_{$this->menuid}_{$this->defaultEntryId}";
- return false;
+ 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)
+ public static function forLocation(int $locationId): IPxeMenu
{
$chain = null;
if (Module::isAvailable('locations')) {
$chain = Location::getLocationRootChain($locationId);
}
if (!empty($chain)) {
- $res = Database::simpleQuery("SELECT m.menuid, m.timeoutms, m.title, IFNULL(ml.defaultentryid, m.defaultentryid) AS defaultentryid, ml.locationid
- FROM serversetup_menu m
- INNER JOIN serversetup_menu_location ml USING (menuid)
- WHERE ml.locationid IN (:chain)", ['chain' => $chain]);
+ $res = Database::simpleQuery("SELECT m.menuid, m.timeoutms, m.title,
+ IFNULL(ml.defaultentryid, m.defaultentryid) AS defaultentryid, ml.locationid
+ FROM serversetup_menu m
+ INNER JOIN serversetup_menu_location ml USING (menuid)
+ WHERE ml.locationid IN (:chain)", ['chain' => $chain]);
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;
}
@@ -156,13 +180,19 @@ class IPxeMenu
return new IPxeMenu($menu);
}
- public static function forClient($ip, $uuid)
+ 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;
}
}
@@ -170,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'
]);