summaryrefslogtreecommitdiffstats
path: root/modules-available/serversetup-bwlp-ipxe
diff options
context:
space:
mode:
authorSimon Rettberg2019-03-19 23:52:11 +0100
committerSimon Rettberg2019-03-19 23:52:11 +0100
commit89e6c1ce7f901a19467fb5cbc18e8a87ea901482 (patch)
tree9b23b7ba486005b3aab53054810a0ab68b0346dd /modules-available/serversetup-bwlp-ipxe
parent[serversetup-bwlp-ipxe] Fix incomplete bootentries, hide arch select (diff)
downloadslx-admin-89e6c1ce7f901a19467fb5cbc18e8a87ea901482.tar.gz
slx-admin-89e6c1ce7f901a19467fb5cbc18e8a87ea901482.tar.xz
slx-admin-89e6c1ce7f901a19467fb5cbc18e8a87ea901482.zip
[serversetup-bwlp-ipxe] Implement cascaded menus
Diffstat (limited to 'modules-available/serversetup-bwlp-ipxe')
-rw-r--r--modules-available/serversetup-bwlp-ipxe/api.inc.php7
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php35
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php4
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php4
-rw-r--r--modules-available/serversetup-bwlp-ipxe/install.inc.php15
-rw-r--r--modules-available/serversetup-bwlp-ipxe/page.inc.php95
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/menu-edit.html11
7 files changed, 121 insertions, 50 deletions
diff --git a/modules-available/serversetup-bwlp-ipxe/api.inc.php b/modules-available/serversetup-bwlp-ipxe/api.inc.php
index 73461901..7a81f430 100644
--- a/modules-available/serversetup-bwlp-ipxe/api.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/api.inc.php
@@ -68,7 +68,12 @@ $ip = $_SERVER['REMOTE_ADDR'];
if (substr($ip, 0, 7) === '::ffff:') {
$ip = substr($ip, 7);
}
-$menu = IPxeMenu::forClient($ip, $uuid);
+$menu = Request::get('menuid', false, 'int');
+if ($menu !== false) {
+ $menu = new IPxeMenu($menu);
+} else {
+ $menu = IPxeMenu::forClient($ip, $uuid);
+}
// Get preferred localboot method, depending on system model
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
index 0248e0ea..ee245e40 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
@@ -46,6 +46,11 @@ abstract class BootEntry
return null;
}
+ public static function forMenu($menuId)
+ {
+ return new MenuBootEntry($menuId);
+ }
+
public static function newStandardBootEntry($initData)
{
$ret = new StandardBootEntry($initData);
@@ -276,3 +281,33 @@ class CustomBootEntry extends BootEntry
return ['script' => $this->script];
}
}
+
+class MenuBootEntry extends BootEntry
+{
+ protected $menuId;
+
+ public function __construct($menuId)
+ {
+ $this->menuId = $menuId;
+ }
+
+ public function supportsMode($mode)
+ {
+ return true;
+ }
+
+ public function toScript($failLabel, $mode)
+ {
+ return 'chain -ar ${self}&menuid=' . $this->menuId . ' || goto ' . $failLabel . "\n";
+ }
+
+ public function toArray()
+ {
+ return [];
+ }
+
+ public function addFormFields(&$array)
+ {
+ }
+}
+
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php
index 6deea7f7..991ee403 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php
@@ -25,7 +25,7 @@ class IPxeMenu
$this->timeoutMs = (int)$menu['timeoutms'];
$this->title = $menu['title'];
$this->defaultEntryId = $menu['defaultentryid'];
- $res = Database::simpleQuery("SELECT e.menuentryid, e.entryid, e.hotkey, e.title, e.hidden, e.sortval, e.md5pass,
+ $res = Database::simpleQuery("SELECT e.menuentryid, e.entryid, e.refmenuid, e.hotkey, e.title, e.hidden, e.sortval, e.md5pass,
b.data AS bootentry
FROM serversetup_menuentry e
LEFT JOIN serversetup_bootentry b USING (entryid)
@@ -139,4 +139,4 @@ class EmptyIPxeMenu extends IPxeMenu
]);
}
-} \ No newline at end of file
+}
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php
index d29995c6..27713b9e 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php
@@ -49,8 +49,10 @@ class MenuEntry
$this->hotkey = self::getKeyCode($row['hotkey']);
if (!empty($row['bootentry'])) {
$this->bootEntry = BootEntry::fromJson($row['bootentry']);
+ } elseif ($row['refmenuid'] !== null) {
+ $this->bootEntry = BootEntry::forMenu($row['refmenuid']);
}
- $this->gap = (array_key_exists('entryid', $row) && $row['entryid'] === null);
+ $this->gap = (array_key_exists('entryid', $row) && $row['entryid'] === null && $row['refmenuid'] === null);
}
settype($this->hidden, 'bool');
settype($this->gap, 'bool');
diff --git a/modules-available/serversetup-bwlp-ipxe/install.inc.php b/modules-available/serversetup-bwlp-ipxe/install.inc.php
index 25579c13..201e0ced 100644
--- a/modules-available/serversetup-bwlp-ipxe/install.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/install.inc.php
@@ -25,7 +25,8 @@ $res[] = tableCreate('serversetup_menu', "
$res[] = tableCreate('serversetup_menuentry', "
`menuentryid` int(11) NOT NULL AUTO_INCREMENT,
`menuid` int(11) NOT NULL,
- `entryid` varchar(16) CHARACTER SET ascii NULL COMMENT 'If NULL, entry is gap',
+ `entryid` varchar(16) CHARACTER SET ascii NULL COMMENT 'If NULL, entry is gap or another menu',
+ `refmenuid` int(11) DEFAULT NULL COMMENT 'If entryid is NULL this can be a ref to another menu',
`hotkey` varchar(8) CHARACTER SET ascii NOT NULL,
`title` varchar(100) NOT NULL COMMENT 'Sanitize this before insert',
`hidden` tinyint(1) NOT NULL,
@@ -77,6 +78,18 @@ $res[] = tableAddConstraint('serversetup_menu_location', 'menuid', 'serversetup_
$res[] = tableAddConstraint('serversetup_menu_location', 'defaultentryid', 'serversetup_menuentry', 'menuentryid',
'ON UPDATE CASCADE ON DELETE SET NULL');
+// 2019-03-19 Add refmenuid to have cascaded menus
+if (!tableHasColumn('serversetup_menuentry', 'refmenuid')) {
+ if (Database::exec("ALTER TABLE serversetup_menuentry ADD COLUMN `refmenuid` int(11) DEFAULT NULL COMMENT 'If entryid is NULL this can be a ref to another menu'") !== false) {
+ $res[] = UPDATE_DONE;
+ } else {
+ $res[] = UPDATE_FAILED;
+ }
+}
+
+$res[] = tableAddConstraint('serversetup_menuentry', 'refmenuid', 'serversetup_menu', 'menuid',
+ 'ON UPDATE CASCADE ON DELETE SET NULL');
+
if (Module::get('location') !== false) {
if (!tableExists('location')) {
$res[] = UPDATE_RETRY;
diff --git a/modules-available/serversetup-bwlp-ipxe/page.inc.php b/modules-available/serversetup-bwlp-ipxe/page.inc.php
index de802da8..8ea782b3 100644
--- a/modules-available/serversetup-bwlp-ipxe/page.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/page.inc.php
@@ -387,7 +387,7 @@ class Page_ServerSetup extends Page
$menu['timeout'] = round($menu['timeoutms'] / 1000);
$menu['entries'] = [];
- $res = Database::simpleQuery("SELECT menuentryid, entryid, hotkey, title, hidden, sortval, plainpass FROM
+ $res = Database::simpleQuery("SELECT menuentryid, entryid, refmenuid, hotkey, title, hidden, sortval, plainpass FROM
serversetup_menuentry WHERE menuid = :id ORDER BY sortval ASC", compact('id'));
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
if ($row['entryid'] == $highlight) {
@@ -396,45 +396,51 @@ class Page_ServerSetup extends Page
$menu['entries'][] = $row;
}
$menu['keys'] = array_map(function ($item) { return ['key' => $item]; }, MenuEntry::getKeyList());
- $menu['entrylist'] = Database::queryAll("SELECT entryid, title, hotkey, data FROM serversetup_bootentry ORDER BY title ASC");
+ $menu['entrylist'] = array_merge(
+ Database::queryAll("SELECT entryid, title, hotkey, data FROM serversetup_bootentry ORDER BY title ASC"),
+ // Add all menus, so we can link
+ Database::queryAll("SELECT Concat('menu=', menuid) AS entryid, title FROM serversetup_menu ORDER BY title ASC")
+ );
class_exists('BootEntry'); // Leave this here for StandardBootEntry
foreach ($menu['entrylist'] as &$bootentry) {
+ if (!isset($bootentry['data']))
+ continue;
$bootentry['data'] = json_decode($bootentry['data'], true);
// Transform stuff suitable for mustache
- if (array_key_exists('arch', $bootentry['data'])) {
- // BIOS/EFI or both
- if ($bootentry['data']['arch'] === StandardBootEntry::BIOS
- || $bootentry['data']['arch'] === StandardBootEntry::BOTH) {
- $bootentry['data']['PCBIOS'] = array('executable' => $bootentry['data']['executable']['PCBIOS'],
- 'initRd' => $bootentry['data']['initRd']['PCBIOS'],
- 'commandLine' => $bootentry['data']['commandLine']['PCBIOS']);
- }
- if ($bootentry['data']['arch'] === StandardBootEntry::EFI
- || $bootentry['data']['arch'] === StandardBootEntry::BOTH) {
- $bootentry['data']['EFI'] = array('executable' => $bootentry['data']['executable']['EFI'],
- 'initRd' => $bootentry['data']['initRd']['EFI'],
- 'commandLine' => $bootentry['data']['commandLine']['EFI']);
- }
- // Naming and agnostic
- if ($bootentry['data']['arch'] === StandardBootEntry::BIOS) {
- $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_biosOnly', true);
- unset($bootentry['data']['EFI']);
- } elseif ($bootentry['data']['arch'] === StandardBootEntry::EFI) {
- $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_efiOnly', true);
- unset($bootentry['data']['PCBIOS']);
- } elseif ($bootentry['data']['arch'] === StandardBootEntry::AGNOSTIC) {
- $bootentry['data']['archAgnostic'] = array('executable' => $bootentry['data']['executable']['PCBIOS'],
- 'initRd' => $bootentry['data']['initRd']['PCBIOS'],
- 'commandLine' => $bootentry['data']['commandLine']['PCBIOS']);
- $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archAgnostic', true);
- unset($bootentry['data']['EFI']);
- } else {
- $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archBoth', true);
- }
- foreach ($bootentry['data'] as &$e) {
- if (isset($e['initRd']) && is_array($e['initRd'])) {
- $e['initRd'] = implode(',', $e['initRd']);
- }
+ if (!array_key_exists('arch', $bootentry['data']))
+ continue;
+ // BIOS/EFI or both
+ if ($bootentry['data']['arch'] === StandardBootEntry::BIOS
+ || $bootentry['data']['arch'] === StandardBootEntry::BOTH) {
+ $bootentry['data']['PCBIOS'] = array('executable' => $bootentry['data']['executable']['PCBIOS'],
+ 'initRd' => $bootentry['data']['initRd']['PCBIOS'],
+ 'commandLine' => $bootentry['data']['commandLine']['PCBIOS']);
+ }
+ if ($bootentry['data']['arch'] === StandardBootEntry::EFI
+ || $bootentry['data']['arch'] === StandardBootEntry::BOTH) {
+ $bootentry['data']['EFI'] = array('executable' => $bootentry['data']['executable']['EFI'],
+ 'initRd' => $bootentry['data']['initRd']['EFI'],
+ 'commandLine' => $bootentry['data']['commandLine']['EFI']);
+ }
+ // Naming and agnostic
+ if ($bootentry['data']['arch'] === StandardBootEntry::BIOS) {
+ $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_biosOnly', true);
+ unset($bootentry['data']['EFI']);
+ } elseif ($bootentry['data']['arch'] === StandardBootEntry::EFI) {
+ $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_efiOnly', true);
+ unset($bootentry['data']['PCBIOS']);
+ } elseif ($bootentry['data']['arch'] === StandardBootEntry::AGNOSTIC) {
+ $bootentry['data']['archAgnostic'] = array('executable' => $bootentry['data']['executable']['PCBIOS'],
+ 'initRd' => $bootentry['data']['initRd']['PCBIOS'],
+ 'commandLine' => $bootentry['data']['commandLine']['PCBIOS']);
+ $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archAgnostic', true);
+ unset($bootentry['data']['EFI']);
+ } else {
+ $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archBoth', true);
+ }
+ foreach ($bootentry['data'] as &$e) {
+ if (isset($e['initRd']) && is_array($e['initRd'])) {
+ $e['initRd'] = implode(',', $e['initRd']);
}
}
}
@@ -613,7 +619,7 @@ class Page_ServerSetup extends Page
if ($entries) {
foreach ($entries as $key => $entry) {
if (!isset($entry['sortval'])) {
- error_log(print_r($entry, true));
+ error_log("Incomplete entry $key with: " . print_r($entry, true));
continue;
}
// Fallback defaults
@@ -624,6 +630,8 @@ class Page_ServerSetup extends Page
'plainpass' => '',
];
$params = [
+ 'entryid' => null,
+ 'refmenuid' => null,
'title' => IPxe::sanitizeIpxeString($entry['title']),
'sortval' => (int)$entry['sortval'],
'menuid' => $menu['menuid'],
@@ -631,18 +639,21 @@ class Page_ServerSetup extends Page
if (empty($entry['entryid'])) {
// Spacer
$params += [
- 'entryid' => null,
'hotkey' => '',
'hidden' => 0, // Doesn't make any sense
'plainpass' => '', // Doesn't make any sense
];
} else {
$params += [
- 'entryid' => $entry['entryid'], // TODO validate?
'hotkey' => MenuEntry::filterKeyName($entry['hotkey']),
'hidden' => (int)$entry['hidden'], // TODO (needs hotkey to make sense)
'plainpass' => $entry['plainpass'],
];
+ if (preg_match('/^menu=(\d+)$/', $entry['entryid'], $out)) {
+ $params['refmenuid'] = $out[1];
+ } else {
+ $params['entryid'] = $entry['entryid'];
+ }
}
if (is_numeric($key)) {
if ((string)$key === $wantedDefaultEntryId) { // Check now that we have generated our key
@@ -652,13 +663,13 @@ class Page_ServerSetup extends Page
$params['menuentryid'] = $key;
$params['md5pass'] = IPxe::makeMd5Pass($entry['plainpass'], $key);
$ret = Database::exec('UPDATE serversetup_menuentry
- SET entryid = :entryid, hotkey = :hotkey, title = :title, hidden = :hidden, sortval = :sortval,
+ SET entryid = :entryid, refmenuid = :refmenuid, hotkey = :hotkey, title = :title, hidden = :hidden, sortval = :sortval,
plainpass = :plainpass, md5pass = :md5pass
WHERE menuid = :menuid AND menuentryid = :menuentryid', $params, true);
} else {
$ret = Database::exec("INSERT INTO serversetup_menuentry
- (menuid, entryid, hotkey, title, hidden, sortval, plainpass, md5pass)
- VALUES (:menuid, :entryid, :hotkey, :title, :hidden, :sortval, :plainpass, '')", $params, true);
+ (menuid, entryid, refmenuid, hotkey, title, hidden, sortval, plainpass, md5pass)
+ VALUES (:menuid, :entryid, :refmenuid, :hotkey, :title, :hidden, :sortval, :plainpass, '')", $params, true);
if ($ret) {
$newKey = Database::lastInsertId();
if ((string)$key === $wantedDefaultEntryId) { // Check now that we have generated our key
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/menu-edit.html b/modules-available/serversetup-bwlp-ipxe/templates/menu-edit.html
index 037cae28..701411bf 100644
--- a/modules-available/serversetup-bwlp-ipxe/templates/menu-edit.html
+++ b/modules-available/serversetup-bwlp-ipxe/templates/menu-edit.html
@@ -74,7 +74,12 @@
{{entryid}}
{{/entryid}}
{{^entryid}}
- {{lang_spacer}}
+ {{^refmenuid}}
+ {{lang_spacer}}
+ {{/refmenuid}}
+ {{#refmenuid}}
+ menu={{refmenuid}}
+ {{/refmenuid}}
{{/entryid}}
</button>
</td>
@@ -132,7 +137,7 @@
<select id="entry-list" class="form-control">
<option value="">{{lang_spacer}}</option>
{{#entrylist}}
- <option value="{{entryid}}">{{entryid}}</option>
+ <option value="{{entryid}}">{{entryid}} // {{title}}</option>
{{/entrylist}}
</select>
</div>
@@ -365,4 +370,4 @@
$title.val(text).data('old', text);
});
});
-</script> \ No newline at end of file
+</script>