summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2019-10-16 18:12:17 +0200
committerSimon Rettberg2019-10-16 18:12:17 +0200
commit36e47dcdfb7d19d4c8982a77b4dd3b87d8c4ca31 (patch)
tree1326851106dd111dc1bcd32d0622dda094f1dcae
parent[dozmod] Increase sat DB's launch counter on cache hit (diff)
downloadslx-admin-36e47dcdfb7d19d4c8982a77b4dd3b87d8c4ca31.tar.gz
slx-admin-36e47dcdfb7d19d4c8982a77b4dd3b87d8c4ca31.tar.xz
slx-admin-36e47dcdfb7d19d4c8982a77b4dd3b87d8c4ca31.zip
[serversetup-bwlp-ipxe/minilinux] Implement minilinux hook for ipxe
-rw-r--r--inc/taskmanagercallback.inc.php11
-rw-r--r--modules-available/minilinux/hooks/ipxe-bootentry.inc.php125
-rw-r--r--modules-available/minilinux/hooks/main-warning.inc.php4
-rw-r--r--modules-available/minilinux/inc/minilinux.inc.php138
-rw-r--r--modules-available/minilinux/install.inc.php4
-rw-r--r--modules-available/minilinux/lang/de/messages.json4
-rw-r--r--modules-available/minilinux/lang/de/module.json5
-rw-r--r--modules-available/minilinux/lang/de/template-tags.json5
-rw-r--r--modules-available/minilinux/lang/en/module.json1
-rw-r--r--modules-available/minilinux/page.inc.php92
-rw-r--r--modules-available/minilinux/templates/branches.html20
-rw-r--r--modules-available/minilinux/templates/filelist.html4
-rw-r--r--modules-available/minilinux/templates/page-minilinux.html4
-rw-r--r--modules-available/minilinux/templates/sources.html79
-rw-r--r--modules-available/minilinux/templates/versionlist.html40
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php1
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php134
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/execdata.inc.php2
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json2
-rw-r--r--modules-available/serversetup-bwlp-ipxe/page.inc.php43
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/ipxe-new-boot-entry.html14
21 files changed, 599 insertions, 133 deletions
diff --git a/inc/taskmanagercallback.inc.php b/inc/taskmanagercallback.inc.php
index d1152bfd..0c4b116a 100644
--- a/inc/taskmanagercallback.inc.php
+++ b/inc/taskmanagercallback.inc.php
@@ -184,7 +184,7 @@ class TaskmanagerCallback
}
}
- public static function mlDownload($task, $args)
+ public static function mlGotList($task, $args)
{
$mod = Module::get('minilinux');
if ($mod === false)
@@ -193,6 +193,15 @@ class TaskmanagerCallback
MiniLinux::listDownloadCallback($task, $args);
}
+ public static function mlGotLinux($task, $args)
+ {
+ $mod = Module::get('minilinux');
+ if ($mod === false)
+ return;
+ $mod->activate(1, false);
+ MiniLinux::linuxDownloadCallback($task, $args);
+ }
+
public static function uploadimg($task)
{
//$string=var_export($task, true);
diff --git a/modules-available/minilinux/hooks/ipxe-bootentry.inc.php b/modules-available/minilinux/hooks/ipxe-bootentry.inc.php
index 4e2cbb5e..090a14da 100644
--- a/modules-available/minilinux/hooks/ipxe-bootentry.inc.php
+++ b/modules-available/minilinux/hooks/ipxe-bootentry.inc.php
@@ -1,11 +1,23 @@
<?php
-class Wurst extends BootEntryHook
+class LinuxBootEntryHook extends BootEntryHook
{
public function name()
{
- return 'Wurst';
+ return Dictionary::translateFileModule('minilinux', 'module', 'module_name', true);
+ }
+
+ public function extraFields()
+ {
+ /* For translate module:
+ * Dictionary::translate('ipxe-kcl-extra');
+ * Dictionary::translate('ipxe-debug');
+ */
+ return [
+ new HookExtraField('kcl-extra', 'string', ''),
+ new HookExtraField('debug', 'bool', false),
+ ];
}
/**
@@ -13,30 +25,105 @@ class Wurst extends BootEntryHook
*/
protected function groupsInternal()
{
- return [
- new HookEntryGroup('Senf Gruppe', [
- new HookEntry('senf-1', 'Senf v1'),
- new HookEntry('senf-2', 'Senf v2'),
- ]),
- new HookEntryGroup('Schnecke Gruppe', [
- new HookEntry('s-1', 'Trulla'),
- new HookEntry('s-2', 'Herbert'),
- ]),
- ];
+ /*
+ * Dictionary::translate('default_boot_entry');
+ * Dictionary::translate('not_installed_hint');
+ */
+ $array = [];
+ $array[] = new HookEntryGroup($this->name(), [
+ new HookEntry('default',
+ Dictionary::translateFileModule('minilinux', 'module', 'default_boot_entry', true),
+ MiniLinux::updateCurrentBootSetting())
+ ]);
+ $branches = Database::queryAll('SELECT sourceid, branchid, title FROM minilinux_branch ORDER BY title');
+ $versions = MiniLinux::queryAllVersionsByBranch();
+ // Group by branch for detailed listing
+ foreach ($branches as $branch) {
+ if (isset($versions[$branch['branchid']])) {
+ $group = [];
+ foreach ($versions[$branch['branchid']] as $version) {
+ $valid = $version['installed'] != 0;
+ $title = $version['versionid'] . ' ' . $version['title'];
+ if (!$valid) {
+ $title .= ' ' . Dictionary::translateFileModule('minilinux', 'module', 'not_installed_hint');
+ }
+ $group[] = new HookEntry($version['versionid'], $title, $valid);
+ }
+ $array[] = new HookEntryGroup($branch['title'] ? $branch['title'] : $branch['branchid'], $group);
+ }
+ }
+ return $array;
}
/**
* @param $id
* @return BootEntry the actual boot entry instance for given entry, false if invalid id
*/
- public function getBootEntry($id)
+ public function getBootEntryInternal($data)
+ {
+ $id = $data['id'];
+ if ($id === 'default') { // Special case
+ $effectiveId = Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT_EFFECTIVE);
+ } else {
+ $effectiveId = $id;
+ }
+ $res = Database::queryFirst('SELECT installed, data FROM minilinux_version WHERE versionid = :id', ['id' => $effectiveId]);
+ if ($res === false) {
+ return BootEntry::newCustomBootEntry(['script' => 'prompt Invalid minilinux boot entry id: ' . $id]);
+ }
+ if ($res['installed'] == 0) {
+ return BootEntry::newCustomBootEntry(['script' => 'prompt Selected version not currently installed on server: ' . $id]);
+ }
+ $exec = new ExecData();
+ // Defaults
+ $root = '/boot/' . $id . '/';
+ $exec->executable = 'kernel';
+ $exec->initRd = ['initramfs-stage31'];
+ $exec->imageFree = true;
+ $exec->commandLine = 'slxbase=boot/%ID% slxsrv=${serverip} quiet splash ${ipappend1} ${ipappend2}';
+ // Overrides
+ $remoteData = json_decode($res['data'], true);
+ // TODO: agnostic hard coded, support EFI and PCBIOS
+ if (isset($remoteData['agnostic']) && is_array($remoteData['agnostic'])) {
+ foreach (['executable', 'commandLine', 'initRd', 'imageFree'] as $key) {
+ if (isset($remoteData['agnostic'][$key])) {
+ $exec->{$key} = $remoteData['agnostic'][$key];
+ }
+ }
+ }
+ unset($rd);
+ // KCL hacks
+ if (isset($data['debug']) && $data['debug']) {
+ if (!isset($data['kcl-extra'])) {
+ $data['kcl-extra'] = '';
+ }
+ $data['kcl-extra'] = '-quiet -splash -loglevel loglevel=7 ' . $data['kcl-extra'];
+ }
+ if (isset($data['kcl-extra'])) {
+ $items = preg_split('/\s+/', $data['kcl-extra'], -1, PREG_SPLIT_NO_EMPTY);
+ // TODO: Make this a function, somewhere in serversetup-ipxe, this could be useful for other stuff
+ foreach ($items as $item) {
+ if ($item{0} === '-') {
+ $item = preg_quote(substr($item, 1), '/');
+ $exec->commandLine = preg_replace('/(^|\s)' . $item . '(=\S*)?($|\s)/', ' ', $exec->commandLine);
+ } else {
+ $exec->commandLine .= ' ' . $item;
+ }
+ }
+ }
+ $exec->commandLine = str_replace('%ID%', $id, $exec->commandLine);
+ $exec->executable = $root . $exec->executable;
+ foreach ($exec->initRd as &$rd) {
+ $rd = $root . $rd;
+ }
+ return BootEntry::newStandardBootEntry($exec, false, 'agnostic');
+ }
+
+ public function isValidId($id)
{
- $bios = new ExecData();
- $bios->executable = 'mspaint.exe';
- $bios->initRd = 'www.google.de';
- $bios->commandLine = '-q';
- return BootEntry::newStandardBootEntry($bios, false, 'agnostic');
+ $res = Database::queryFirst('SELECT installed FROM minilinux_version WHERE versionid = :id', ['id' => $id]);
+ return $res !== false && $res['installed'];
}
}
-return new Wurst(); \ No newline at end of file
+return new LinuxBootEntryHook(); \ No newline at end of file
diff --git a/modules-available/minilinux/hooks/main-warning.inc.php b/modules-available/minilinux/hooks/main-warning.inc.php
index 31668e6c..8b052471 100644
--- a/modules-available/minilinux/hooks/main-warning.inc.php
+++ b/modules-available/minilinux/hooks/main-warning.inc.php
@@ -1,6 +1,8 @@
<?php
-if (!file_exists(CONFIG_HTTP_DIR . '/default/kernel') || !file_exists(CONFIG_HTTP_DIR . '/default/initramfs-stage31') || !file_exists(CONFIG_HTTP_DIR . '/default/stage32.sqfs')) {
+if (!is_dir(CONFIG_HTTP_DIR . '/bwlp/default')) {
Message::addError('minilinux.please-download-minilinux', true);
$needSetup = true;
+} else {
+ $needSetup = MiniLinux::generateUpdateNotice();
} \ No newline at end of file
diff --git a/modules-available/minilinux/inc/minilinux.inc.php b/modules-available/minilinux/inc/minilinux.inc.php
index 46c63c94..e940380c 100644
--- a/modules-available/minilinux/inc/minilinux.inc.php
+++ b/modules-available/minilinux/inc/minilinux.inc.php
@@ -5,6 +5,20 @@ class MiniLinux
const PROPERTY_KEY_FETCHTIME = 'ml-list-fetch';
+ const PROPERTY_DEFAULT_BOOT = 'ml-default';
+
+ const PROPERTY_DEFAULT_BOOT_EFFECTIVE = 'ml-default-eff';
+
+ const INVALID = 'invalid';
+
+ /*
+ * Update of available versions by querying sources
+ */
+
+ /**
+ * Query all known sources for meta data
+ * @return int number of sources query was just initialized for
+ */
public static function updateList()
{
$stamp = time();
@@ -27,19 +41,25 @@ class MiniLinux
'id' => $source['taskid'],
'url' => $source['url'],
), true);
- TaskmanagerCallback::addCallback($source['taskid'], 'mlDownload', $source['sourceid']);
+ TaskmanagerCallback::addCallback($source['taskid'], 'mlGotList', $source['sourceid']);
}
Database::exec('UNLOCK TABLES');
return count($list);
}
+ /**
+ * Called when downloading metadata from a specific update source is finished
+ * @param mixed $task task structure
+ * @param string $sourceid see minilinux_source table
+ */
public static function listDownloadCallback($task, $sourceid)
{
+ if ($task['statusCode'] !== 'TASK_FINISHED')
+ return;
$taskId = $task['id'];
$data = json_decode($task['data']['content'], true);
if (!is_array($data)) {
EventLog::warning('Cannot download Linux version meta data for ' . $sourceid);
- error_log(print_r($task, true));
$lastupdate = 'lastupdate';
} else {
if (isset($data['systems']) && is_array($data['systems'])) {
@@ -141,6 +161,10 @@ class MiniLinux
return preg_match('/^[a-z0-9_\-]+$/', $str) > 0;
}
+ /*
+ * Download of specific version
+ */
+
public static function validateDownloadTask($versionid, $taskid)
{
if ($taskid === null)
@@ -193,7 +217,6 @@ class MiniLinux
'gpg' => $file['gpg'],
];
}
- error_log(print_r($list, true));
$uuid = Util::randomUuid();
Database::exec('LOCK TABLES minilinux_version WRITE');
$aff = Database::exec('UPDATE minilinux_version SET taskid = :taskid WHERE versionid = :versionid AND taskid IS NULL',
@@ -206,7 +229,6 @@ class MiniLinux
'files' => $list,
]);
if (Taskmanager::isFailed($task)) {
- error_log(print_r($task, true));
$task = false;
} else {
$task = $task['id'];
@@ -215,6 +237,10 @@ class MiniLinux
$task = false;
}
Database::exec('UNLOCK TABLES');
+ if ($task !== false) {
+ // Callback for db column
+ TaskmanagerCallback::addCallback($task, 'mlGotLinux', $versionid);
+ }
if ($aff === 0)
return self::downloadVersion($versionid);
return $task;
@@ -225,4 +251,108 @@ class MiniLinux
return 'x' . substr(md5($fileName . $versionid), 0, 8);
}
+ /*
+ * Check status, availability of updates
+ */
+
+ /**
+ * Geenrate messages regarding setup und update availability.
+ * @return bool true if severe problems were found, false otherwise
+ */
+ public static function generateUpdateNotice()
+ {
+ // Messages in here are with module name, as required by the
+ // main-warning hook.
+ $default = Property::get(self::PROPERTY_DEFAULT_BOOT);
+ if ($default === false) {
+ Message::addError('minilinux.no-default-set', true);
+ return true;
+ }
+ $installed = self::updateCurrentBootSetting();
+ $effective = Property::get(self::PROPERTY_DEFAULT_BOOT_EFFECTIVE);
+ $slashes = substr_count($default, '/');
+ if ($slashes === 1) {
+ // BrĂ´nche, always latest version
+ $latest = Database::queryFirst('SELECT versionid FROM minilinux_version
+ WHERE branchid = :branchid ORDER BY dateline DESC', ['branchid' => $default]);
+ if ($latest === false) {
+ Message::addError('minilinux.default-is-invalid', true);
+ return true;
+ } elseif ($latest['versionid'] !== $effective) {
+ Message::addInfo('minilinux.default-update-available', true, $default, $latest['versionid']);
+ }
+ } elseif ($slashes === 2) {
+ // Specific version selected
+ if ($effective === self::INVALID) {
+ Message::addError('minilinux.default-is-invalid', true);
+ return true;
+ }
+ }
+ if (!$installed) {
+ Message::addError('minilinux.default-not-installed', true, $default);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Update the effective current default version to boot.
+ * If the version does not exist, it is set to INVALID.
+ * Function returns whether the currently selected version is
+ * actually installed locally.
+ * @return bool true if installed locally, false otherwise
+ */
+ public static function updateCurrentBootSetting()
+ {
+ $default = Property::get(self::PROPERTY_DEFAULT_BOOT);
+ if ($default === false)
+ return false;
+ $slashes = substr_count($default, '/');
+ if ($slashes === 2) {
+ // Specific version
+ $ver = Database::queryFirst('SELECT versionid, installed FROM minilinux_version
+ WHERE versionid = :versionid', ['versionid' => $default]);
+ } elseif ($slashes === 1) {
+ // Latest from branch
+ $ver = Database::queryFirst('SELECT versionid, installed FROM minilinux_version
+ WHERE branchid = :branchid AND installed = 1 ORDER BY dateline DESC', ['branchid' => $default]);
+ } else {
+ // Unknown
+ return false;
+ }
+ // Determine state
+ if ($ver === false) { // Doesn't exist
+ Property::set(self::PROPERTY_DEFAULT_BOOT_EFFECTIVE, self::INVALID);
+ return false;
+ }
+ Property::set(self::PROPERTY_DEFAULT_BOOT_EFFECTIVE, $ver['versionid']);
+ return $ver['installed'] != 0;
+ }
+
+ public static function linuxDownloadCallback($task, $versionid)
+ {
+ self::setInstalledState($versionid, $task['statusCode'] === 'TASK_FINISHED');
+ }
+
+ public static function setInstalledState($versionid, $installed)
+ {
+ settype($installed, 'int');
+ error_log("Setting $versionid to $installed");
+ Database::exec('UPDATE minilinux_version SET installed = :installed WHERE versionid = :versionid', [
+ 'versionid' => $versionid,
+ 'installed' => $installed,
+ ]);
+ }
+
+ public static function queryAllVersionsByBranch()
+ {
+ $list = [];
+ $res = Database::simpleQuery('SELECT branchid, versionid, title, dateline, orphan, taskid, installed
+ FROM minilinux_version ORDER BY branchid, dateline, versionid');
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $list[$row['branchid']][$row['versionid']] = $row;
+ }
+ return $list;
+ }
+
} \ No newline at end of file
diff --git a/modules-available/minilinux/install.inc.php b/modules-available/minilinux/install.inc.php
index 50be13a5..5387542e 100644
--- a/modules-available/minilinux/install.inc.php
+++ b/modules-available/minilinux/install.inc.php
@@ -26,9 +26,11 @@ $result[] = tableCreate('minilinux_version', "
`data` blob NOT NULL,
`orphan` tinyint(3) UNSIGNED NOT NULL,
`taskid` char(36) CHARACTER SET ascii DEFAULT NULL,
+ `installed` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`versionid`),
KEY (`title`),
- KEY (`branchid`, `dateline`, `versionid`)
+ KEY (`branchid`, `dateline`, `versionid`),
+ KEY (`branchid`, `installed`, `dateline`)
");
$result[] = tableAddConstraint('minilinux_version', 'branchid', 'minilinux_branch', 'branchid',
diff --git a/modules-available/minilinux/lang/de/messages.json b/modules-available/minilinux/lang/de/messages.json
index 1c38a8c1..e957ee09 100644
--- a/modules-available/minilinux/lang/de/messages.json
+++ b/modules-available/minilinux/lang/de/messages.json
@@ -1,5 +1,9 @@
{
+ "default-is-invalid": "Gew\u00e4hltes Linux-Standardsystem ist ung\u00fcltig",
+ "default-not-installed": "Gew\u00e4hltes Linux-Standardsystem {{0}} ist nicht (mehr) installiert",
+ "default-update-available": "F\u00fcr das Gew\u00e4hlte Linux-Standardsystem {{0}} ist die Aktualisierung {{1}} verf\u00fcgbar",
"delete-error": "Fehler beim L\u00f6schen der Version {{0}}: {{1}}",
+ "no-default-set": "Kein Linux-Standardsystem festgelegt",
"no-such-version": "Ung\u00fcltige\/Unbekannte Version: {{0}}",
"please-download-minilinux": "Wichtige Dateien der MiniLinux-Installation fehlen",
"version-deleted": "Version {{0}} wurde gel\u00f6scht"
diff --git a/modules-available/minilinux/lang/de/module.json b/modules-available/minilinux/lang/de/module.json
index 3ad539ca..da6ea4bb 100644
--- a/modules-available/minilinux/lang/de/module.json
+++ b/modules-available/minilinux/lang/de/module.json
@@ -1,8 +1,13 @@
{
+ "default_boot_entry": "(Globalen Standard verwenden)",
"file-checksum-bad": "Pr\u00fcfsummenfehler",
"file-missing": "Datei fehlt",
+ "file-not-readable": "Datei nicht lesbar",
"file-ok": "OK",
"file-size-mismatch": "Dateigr\u00f6\u00dfe stimmt nicht",
+ "ipxe-debug": "Debug-Ausgaben statt Bootlogo",
+ "ipxe-kcl-extra": "Modifikation der Kernel-Command-Line",
"module_name": "bwLehrpool MiniLinux",
+ "not_installed_hint": "(nicht installiert)",
"page_title": "Linuxvarianten f\u00fcr Netboot verwalten"
} \ No newline at end of file
diff --git a/modules-available/minilinux/lang/de/template-tags.json b/modules-available/minilinux/lang/de/template-tags.json
index 144887c8..2054896c 100644
--- a/modules-available/minilinux/lang/de/template-tags.json
+++ b/modules-available/minilinux/lang/de/template-tags.json
@@ -1,14 +1,19 @@
{
+ "lang_branchesHeading": "Verf\u00fcgbare Varianten und Versionen",
+ "lang_changelog": "Changelog",
"lang_confirmDeleteVersion": "Diese Version wirklich l\u00f6schen?",
"lang_download": "Herunterladen",
"lang_id": "ID",
+ "lang_installed": "Installiert",
"lang_introText": "Hier gibts MiniLinux.",
"lang_key": "GPG-Key",
"lang_lastUpdate": "Zuletzt \u00fcberpr\u00fcft",
"lang_minilinuxHeading": "Netboot Linux verwalten",
"lang_orphanedVersion": "Verwaiste Version",
"lang_releaseDate": "Ver\u00f6ffentlichungsdatum",
+ "lang_selectedDefaultIs": "Gew\u00e4hltes Standardsystem ist",
"lang_sources": "Quellen",
+ "lang_sourcesIntro": "Liste der Quellen, aus denen Updates bezogen werden k\u00f6nnen.",
"lang_title": "Titel",
"lang_updateSourcesButton": "Nach neuen Updates suchen",
"lang_url": "URL",
diff --git a/modules-available/minilinux/lang/en/module.json b/modules-available/minilinux/lang/en/module.json
index 899435e7..b1526869 100644
--- a/modules-available/minilinux/lang/en/module.json
+++ b/modules-available/minilinux/lang/en/module.json
@@ -1,6 +1,7 @@
{
"file-checksum-bad": "Bad checksum",
"file-missing": "File missing",
+ "file-not-readable": "File not readable",
"file-ok": "OK",
"file-size-mismatch": "File size mismatch",
"module_name": "Minilinux",
diff --git a/modules-available/minilinux/page.inc.php b/modules-available/minilinux/page.inc.php
index b54050bf..53632699 100644
--- a/modules-available/minilinux/page.inc.php
+++ b/modules-available/minilinux/page.inc.php
@@ -18,6 +18,8 @@ class Page_MiniLinux extends Page
$this->deleteVersion();
} elseif ($show === 'updatesources') {
$this->updateSources();
+ } elseif ($show === 'setdefault') {
+ $this->setDefault();
}
Util::redirect('?do=minilinux');
}
@@ -27,15 +29,21 @@ class Page_MiniLinux extends Page
protected function doRender()
{
- Render::addTemplate('page-minilinux');
+ Render::addTemplate('page-minilinux', ['default' => Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT)]);
+ // Warning
+ if (!MiniLinux::updateCurrentBootSetting()) {
+ Message::addError('default-not-installed', Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT));
+ }
// List branches and versions
$branches = Database::queryAll('SELECT sourceid, branchid, title FROM minilinux_branch ORDER BY title ASC');
- $versions = $this->queryAllVersionsByBranch();
+ $versions = MiniLinux::queryAllVersionsByBranch();
+ // Group by branch for detailed listing
foreach ($branches as &$branch) {
if (isset($versions[$branch['branchid']])) {
$branch['versionlist'] = $this->renderVersionList($versions[$branch['branchid']]);
}
}
+ unset($branch);
Render::addTemplate('branches', ['branches' => $branches]);
// List sources
$res = Database::simpleQuery('SELECT sourceid, title, url, lastupdate, pubkey FROM minilinux_source ORDER BY title, sourceid');
@@ -60,35 +68,34 @@ class Page_MiniLinux extends Page
User::load();
$show = Request::post('show', false, 'string');
if ($show === 'version') {
- $this->ajaxVersion();
+ $this->ajaxVersionDetails();
} elseif ($show === 'download') {
$this->ajaxDownload();
}
}
- private function queryAllVersionsByBranch()
- {
- $list = [];
- $res = Database::simpleQuery('SELECT branchid, versionid, title, dateline, orphan, taskid
- FROM minilinux_version ORDER BY branchid, dateline, versionid');
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $list[$row['branchid']][] = $row;
- }
- return $list;
- }
-
private function renderVersionList($versions)
{
+ $def = Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT);
+ $eff = Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT_EFFECTIVE);
foreach ($versions as &$version) {
$version['dateline_s'] = Util::prettyTime($version['dateline']);
$version['orphan'] = ($version['orphan'] > 5);
- $version['installed'] = is_dir(CONFIG_HTTP_DIR . '/' . $version['versionid']);
$version['downloading'] = $version['taskid'] && Taskmanager::isRunning(Taskmanager::status($version['taskid']));
+ if ($version['installed'] && $version['versionid'] !== $def) {
+ $version['showsetdefault'] = true;
+ }
+ if ($version['versionid'] === $def) {
+ $version['isdefault'] = true;
+ if (!$version['installed']) {
+ $version['default_class'] = 'bg-danger';
+ }
+ }
}
- return Render::parse('versionlist', ['versions' => $versions]);
+ return Render::parse('versionlist', ['versions' => array_values($versions)]);
}
- private function ajaxVersion()
+ private function ajaxVersionDetails()
{
User::assertPermission('view');
$verify = Request::post('verify', false, 'bool');
@@ -96,7 +103,7 @@ class Page_MiniLinux extends Page
if ($versionid === false) {
die('What!');
}
- $ver = Database::queryFirst('SELECT versionid, taskid, data FROM minilinux_version WHERE versionid = :versionid',
+ $ver = Database::queryFirst('SELECT versionid, taskid, data, installed FROM minilinux_version WHERE versionid = :versionid',
['versionid' => $versionid]);
if ($ver === false) {
die('No such version');
@@ -110,6 +117,7 @@ class Page_MiniLinux extends Page
$data['dltask'] = MiniLinux::validateDownloadTask($versionid, $ver['taskid']);
$data['verify_button'] = !$verify && $data['dltask'] === false;
if (is_array($data['files'])) {
+ $valid = true;
$sort = [];
foreach ($data['files'] as &$file) {
if (empty($file['name'])) {
@@ -119,8 +127,7 @@ class Page_MiniLinux extends Page
$sort[] = $file['name'];
$s = $this->getFileState($versionid, $file, $verify);
if ($s !== self::FILE_OK) {
- $data['verify_button'] = false;
- $data['download_button'] = !$data['dltask'];
+ $valid = false;
}
if ($s !== self::FILE_MISSING) {
$data['delete_button'] = true;
@@ -138,6 +145,15 @@ class Page_MiniLinux extends Page
}
unset($file);
array_multisort($sort, SORT_ASC, $data['files']);
+ if (!$valid) {
+ $data['verify_button'] = false;
+ $data['download_button'] = !$data['dltask'];
+ if ($ver['installed']) {
+ MiniLinux::setInstalledState($versionid, false);
+ }
+ } elseif (!$ver['installed'] && $verify) {
+ MiniLinux::setInstalledState($versionid, true);
+ }
}
echo Render::parse('filelist', $data);
}
@@ -146,6 +162,7 @@ class Page_MiniLinux extends Page
const FILE_MISSING = 1;
const FILE_SIZE_MISMATCH = 2;
const FILE_CHECKSUM_BAD = 3;
+ const FILE_NOT_READABLE = 4;
private function getFileState($versionid, $file, $verify)
{
@@ -154,11 +171,17 @@ class Page_MiniLinux extends Page
return self::FILE_MISSING;
if (isset($file['size']) && filesize($path) != $file['size'])
return self::FILE_SIZE_MISMATCH;
+ if (!is_readable($path))
+ return self::FILE_NOT_READABLE;
if ($verify) {
- // TODO: Others
- if (isset($file['md5'])) {
- if (md5_file($path) !== $file['md5'])
- return self::FILE_CHECKSUM_BAD;
+ foreach (['sha512', 'sha384', 'sha256', 'sha224', 'sha1', 'md5'] as $algo) {
+ if (isset($file[$algo])) {
+ $calced = hash_file($algo, $path);
+ if ($calced === false)
+ continue; // Algo not supported?
+ if ($calced !== $file['md5'])
+ return self::FILE_CHECKSUM_BAD;
+ }
}
}
return self::FILE_OK;
@@ -173,6 +196,8 @@ class Page_MiniLinux extends Page
return Dictionary::translate('file-size-mismatch', true);
case self::FILE_MISSING:
return Dictionary::translate('file-missing', true);
+ case self::FILE_NOT_READABLE:
+ return Dictionary::translate('file-not-readable', true);
case self::FILE_OK:
return Dictionary::translate('file-ok', true);
}
@@ -191,7 +216,7 @@ class Page_MiniLinux extends Page
Message::addError('no-such-version', $version);
Message::renderList();
} else {
- $this->ajaxVersion();
+ $this->ajaxVersionDetails();
}
}
@@ -209,6 +234,7 @@ class Page_MiniLinux extends Page
Message::addError('no-such-version');
return;
}
+ MiniLinux::setInstalledState($version['versionid'], false);
$path = CONFIG_HTTP_DIR . '/' . $version['versionid'];
$task = Taskmanager::submit('DeleteDirectory', [
'path' => $path,
@@ -233,4 +259,20 @@ class Page_MiniLinux extends Page
}
}
+ private function setDefault()
+ {
+ $versionid = Request::post('version', false, 'string');
+ if ($versionid === false) {
+ Message::addError('main.parameter-missing', 'versionid');
+ return;
+ }
+ $version = Database::queryFirst('SELECT versionid FROM minilinux_version WHERE versionid = :versionid',
+ ['versionid' => $versionid]);
+ if ($version === false) {
+ Message::addError('no-such-version');
+ return;
+ }
+ Property::set(MiniLinux::PROPERTY_DEFAULT_BOOT, $version['versionid']);
+ }
+
}
diff --git a/modules-available/minilinux/templates/branches.html b/modules-available/minilinux/templates/branches.html
index 1ba9497c..64adda16 100644
--- a/modules-available/minilinux/templates/branches.html
+++ b/modules-available/minilinux/templates/branches.html
@@ -1,17 +1,19 @@
+<h3>{{lang_branchesHeading}}</h3>
{{#branches}}
<div id="ibm-mainframe" class="panel panel-default">
<div class="panel-heading">
<div class="pull-right">
{{sourceid}} {{branchid}}
</div>
- {{title}}
+ <b>{{title}}</b>
</div>
<div class="panel-body">
-
+ {{description}}
</div>
{{{versionlist}}}
</div>
{{/branches}}
+
<script>
document.addEventListener('DOMContentLoaded', function () {
var addHandlers = function(parent) {
@@ -44,13 +46,21 @@
};
$('.version-link').click(function(e) {
e.preventDefault();
- $(this).removeClass('version-link').off().removeAttr('href');
- loadDetails($(this).data('version'), { show: "version" });
+ var ver = $(this).data('version');
+ var c = $('.version-container[data-version="' + ver + '"]');
+ if (c.is(':visible')) {
+ c.hide();
+ } else if (c.is(':empty')) {
+ loadDetails(ver, {show: "version"});
+ } else {
+ c.show();
+ }
});
addHandlers($('#ibm-mainframe'));
$('[data-autoclick="true"]').click();
});
var taskDone = {};
+ var wasUnfinished = false;
function dlTmCb(task) {
if (!task.data || !task.data.files)
return;
@@ -69,5 +79,7 @@
taskDone[id] = wasDone ? true : f.progress;
}
}
+ if (wasUnfinished && task.statusCode === 'TASK_FINISHED') location.reload(true);
+ if (task.statusCode !== 'TASK_FINISHED') wasUnfinished = true;
}
</script> \ No newline at end of file
diff --git a/modules-available/minilinux/templates/filelist.html b/modules-available/minilinux/templates/filelist.html
index 2c26edf9..9aa175bd 100644
--- a/modules-available/minilinux/templates/filelist.html
+++ b/modules-available/minilinux/templates/filelist.html
@@ -50,4 +50,8 @@
{{#dltask}}
<div class="hidden" data-tm-id="{{dltask}}" data-tm-callback="dlTmCb"></div>
{{/dltask}}
+{{#changelog}}
+<h4>{{lang_changelog}}</h4>
+{{changelog}}
+{{/changelog}}
<div class="slx-space"></div> \ No newline at end of file
diff --git a/modules-available/minilinux/templates/page-minilinux.html b/modules-available/minilinux/templates/page-minilinux.html
index 2cbde608..3059e827 100644
--- a/modules-available/minilinux/templates/page-minilinux.html
+++ b/modules-available/minilinux/templates/page-minilinux.html
@@ -1,3 +1,5 @@
<h1>{{lang_minilinuxHeading}}</h1>
-<p>{{lang_introText}}</p> \ No newline at end of file
+<p>{{lang_introText}}</p>
+
+{{lang_selectedDefaultIs}}: <b>{{default}}</b> \ No newline at end of file
diff --git a/modules-available/minilinux/templates/sources.html b/modules-available/minilinux/templates/sources.html
index f2e54745..dabc7f4d 100644
--- a/modules-available/minilinux/templates/sources.html
+++ b/modules-available/minilinux/templates/sources.html
@@ -1,42 +1,41 @@
-<div class="panel panel-default">
- <div class="panel-heading">
- {{lang_sources}}
- </div>
- <table class="table table-condensed">
- <thead>
- <tr>
- <th>{{lang_id}}</th>
- <th>{{lang_title}}</th>
- <th>{{lang_url}}</th>
- <th>{{lang_lastUpdate}}</th>
- <th>{{lang_key}}</th>
- </tr>
- </thead>
- <tbody>
- {{#list}}
- <tr>
- <td class="small">{{sourceid}}</td>
- <td>{{title}}</td>
- <td class="small">{{url}}</td>
- <td class="{{update_class}}">{{lastupdate_s}}</td>
- <td class="text-center">
- <button type="button" class="btn btn-default btn-xs" data-confirm="#confirm-{{source}}" data-close="{{lang_close}}">
- <span class="glyphicon glyphicon-eye-open"></span>
- </button>
- <pre id="confirm-{{source}}" class="hidden">{{pubkey}}</pre>
- </td>
- </tr>
- {{/list}}
- </tbody>
- </table>
- <div class="panel-body text-right">
- <form method="post" action="?do=minilinux">
- <input type="hidden" name="token" value="{{token}}">
- <button type="submit" name="show" value="updatesources" class="btn btn-default"
- onclick="$(this).find('.glyphicon').addClass('slx-rotation')" {{^show_refresh}}disabled{{/show_refresh}}>
- <span class="glyphicon glyphicon-refresh"></span>
- {{lang_updateSourcesButton}}
+<h3>{{lang_sources}}</h3>
+
+<p>{{lang_sourcesIntro}}</p>
+
+<table class="table table-condensed">
+ <thead>
+ <tr>
+ <th>{{lang_id}}</th>
+ <th>{{lang_title}}</th>
+ <th>{{lang_url}}</th>
+ <th>{{lang_lastUpdate}}</th>
+ <th>{{lang_key}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#list}}
+ <tr>
+ <td class="small">{{sourceid}}</td>
+ <td>{{title}}</td>
+ <td class="small">{{url}}</td>
+ <td class="{{update_class}}">{{lastupdate_s}}</td>
+ <td class="text-center">
+ <button type="button" class="btn btn-default btn-xs" data-confirm="#confirm-{{source}}" data-close="{{lang_close}}">
+ <span class="glyphicon glyphicon-eye-open"></span>
</button>
- </form>
- </div>
+ <pre id="confirm-{{source}}" class="hidden">{{pubkey}}</pre>
+ </td>
+ </tr>
+ {{/list}}
+ </tbody>
+</table>
+<div class="text-right">
+ <form method="post" action="?do=minilinux">
+ <input type="hidden" name="token" value="{{token}}">
+ <button type="submit" name="show" value="updatesources" class="btn btn-default"
+ onclick="$(this).find('.glyphicon').addClass('slx-rotation')" {{^show_refresh}}disabled{{/show_refresh}}>
+ <span class="glyphicon glyphicon-refresh"></span>
+ {{lang_updateSourcesButton}}
+ </button>
+ </form>
</div> \ No newline at end of file
diff --git a/modules-available/minilinux/templates/versionlist.html b/modules-available/minilinux/templates/versionlist.html
index 1e5c7c96..4ef4e631 100644
--- a/modules-available/minilinux/templates/versionlist.html
+++ b/modules-available/minilinux/templates/versionlist.html
@@ -1,22 +1,45 @@
<table class="table table-striped">
<tr>
- <th>{{lang_version}}</th>
- <th>{{lang_releaseDate}}</th>
+ <th class="slx-smallcol">{{lang_version}}</th>
+ <th class="slx-smallcol">{{lang_releaseDate}}</th>
<th>{{lang_title}}</th>
<th class="slx-smallcol"></th>
<th class="slx-smallcol"></th>
+ <th class="slx-smallcol"></th>
</tr>
{{#versions}}
<tr>
- <td>
+ <td class="text-nowrap">
<a href="#" class="version-link" data-version="{{versionid}}" {{#downloading}}data-autoclick="true"{{/downloading}}>
{{versionid}}
<b class="caret"></b>
</a>
</td>
- <td>{{dateline_s}}</td>
+ <td class="text-nowrap">{{dateline_s}}</td>
<td>{{title}}</td>
- <td>
+ <td class="text-nowrap">
+ {{#orphan}}
+ {{lang_orphanedVersion}}
+ {{/orphan}}
+ </td>
+ <td class="text-nowrap text-center {{default_class}}">
+ {{#showsetdefault}}
+ <form method="post" action="?do=minilinux" style="margin:0;padding:0;display:inline">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="version" value="{{versionid}}">
+ <button type="submit" name="show" value="setdefault" class="btn btn-xs btn-info">
+ <span class="glyphicon glyphicon-flag"></span>
+ </button>
+ </form>
+ {{/showsetdefault}}
+ {{#isdefault}}
+ <span class="glyphicon glyphicon-ok"></span>
+ {{/isdefault}}
+ </td>
+ <td class="text-nowrap text-center">
+ {{#installed}}
+ <span class="btn btn-default btn-xs disabled">{{lang_installed}}</span>
+ {{/installed}}
{{^installed}}
{{^downloading}}
<button type="button" class="btn btn-xs btn-success btn-download" data-version="{{versionid}}">
@@ -26,14 +49,9 @@
{{/downloading}}
{{/installed}}
</td>
- <td>
- {{#orphan}}
- {{lang_orphanedVersion}}
- {{/orphan}}
- </td>
</tr>
<tr>
- <td colspan="5" class="version-container collapse" data-version="{{versionid}}"></td>
+ <td colspan="6" class="version-container collapse" data-version="{{versionid}}"></td>
</tr>
{{/versions}}
</table> \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
index e97d1389..174f4459 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
@@ -260,6 +260,7 @@ class StandardBootEntry extends BootEntry
} else {
$entry = $this->efi;
}
+ $entry->sanitize();
$script = '';
if ($entry->resetConsole) {
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php
index 2e2e5009..f89031a3 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php
@@ -14,18 +14,24 @@ abstract class BootEntryHook
private $selectedId;
+ private $data = [];
+
+ /**
+ * @return string
+ */
public abstract function name();
/**
- * @return HookEntryGroup[]
+ * @return HookExtraField[]
*/
- protected abstract function groupsInternal();
+ public abstract function extraFields();
+
+ public abstract function isValidId($id);
/**
- * @param $id
- * @return BootEntry|null the actual boot entry instance for given entry, null if invalid id
+ * @return HookEntryGroup[]
*/
- public abstract function getBootEntry($id);
+ protected abstract function groupsInternal();
/**
* @return HookEntryGroup[]
@@ -43,11 +49,40 @@ abstract class BootEntryHook
return $groups;
}
+ /**
+ * @param $id
+ * @return BootEntry|null the actual boot entry instance for given entry, null if invalid id
+ */
+ public abstract function getBootEntryInternal($data);
+
+ public final function getBootEntry($data)
+ {
+ if (!is_array($data)) {
+ $data = json_decode($data, true);
+ }
+ return $this->getBootEntryInternal($data);
+ }
+
public function setSelected($id)
{
+ $json = @json_decode($id, true);
+ if (is_array($json)) {
+ $id = $json['id'];
+ $this->data = $json;
+ }
$this->selectedId = $id;
}
+ public function renderExtraFields()
+ {
+ $list = $this->extraFields();
+ foreach ($list as &$entry) {
+ $entry->currentValue = isset($this->data[$entry->name]) ? $this->data[$entry->name] : $entry->default;
+ $entry->hook = $this;
+ }
+ return $list;
+ }
+
}
class HookEntryGroup
@@ -79,13 +114,100 @@ class HookEntry
*/
public $name;
/**
+ * @var bool
+ */
+ public $valid;
+ /**
+ * @var string if !valid, this will be the string 'disabled', empty otherwise
+ */
+ public $disabled;
+ /**
* @var string internal - to be set by ipxe module
*/
public $selected;
- public function __construct($id, $name)
+ /**
+ * HookEntry constructor.
+ *
+ * @param string $id
+ * @param string $name
+ * @param bool $valid
+ */
+ public function __construct($id, $name, $valid)
{
$this->id = $id;
$this->name = $name;
+ $this->valid = $valid;
+ $this->disabled = $valid ? '' : 'disabled';
}
+}
+
+class HookExtraField
+{
+ /**
+ * @var string ID of extra field, [a-z0-9\-] please. Must not be 'id'
+ */
+ public $name;
+ /**
+ * @var string type of field, use string, bool, or an array of predefined options
+ */
+ public $type;
+ /**
+ * @var mixed default value
+ */
+ public $default;
+
+ public $currentValue;
+
+ /**
+ * @var BootEntryHook
+ */
+ public $hook;
+
+ public function __construct($name, $type, $default)
+ {
+ $this->name = $name;
+ $this->type = $type;
+ $this->default = $default;
+ }
+
+ public function fromPost($typePrefix)
+ {
+ if (is_array($this->type)) {
+ $val = Request::post('extra-' . $typePrefix . '-' . $this->name, '', 'array');
+ if (!in_array($val, $this->type)) {
+ $val = $this->default;
+ }
+ } else {
+ $val = Request::post('extra-' . $typePrefix . '-' . $this->name, '', $this->type);
+ settype($val, $this->type);
+ }
+ return $val;
+ }
+
+ public function html()
+ {
+ $fieldId = 'extra-' . $this->hook->moduleId . '-' . $this->name;
+ $fieldText = htmlspecialchars(Dictionary::translateFileModule($this->hook->moduleId, 'module', 'ipxe-' . $this->name, true));
+ if (is_array($this->type)) {
+ $out = '<label for="' . $fieldId . '">' . $fieldText . '</label><select class="form-control" name="' . $fieldId . '" id="' . $fieldId . '">';
+ foreach ($this->type as $entry) {
+ $selected = ($entry === $this->currentValue) ? 'selected' : '';
+ $out .= '<option ' . $selected . '>' . htmlspecialchars($entry) . '</option>';
+ }
+ $out .= '</select>';
+ return $out;
+ }
+ if ($this->type === 'bool') {
+ $checked = $this->currentValue ? 'checked' : '';
+ return '<div class="checkbox"><input type="checkbox" id="' . $fieldId
+ . '" name="' . $fieldId . '" ' . $checked . '><label for="' . $fieldId . '">'
+ . $fieldText . '</label></div>';
+ }
+ // Default
+ return '<label for="' . $fieldId . '">' . $fieldText . '</label>'
+ . '<input class="form-control" type="text" id="' . $fieldId
+ . '" name="' . $fieldId . '" value="' . htmlspecialchars($this->currentValue) . '">';
+ }
+
} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/execdata.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/execdata.inc.php
index b82ce2e7..97f98b94 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/execdata.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/execdata.inc.php
@@ -73,7 +73,7 @@ class ExecData
],
];
- private function sanitize()
+ public function sanitize()
{
settype($this->executable, 'string');
settype($this->initRd, 'array');
diff --git a/modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json b/modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json
index 07cf8fa3..f7a62091 100644
--- a/modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json
+++ b/modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json
@@ -11,6 +11,7 @@
"lang_biosOnly": "Nur BIOS",
"lang_bootAddress": "Boot-Adresse des Servers",
"lang_bootEntryData": "Daten des Men\u00fceintrags",
+ "lang_bootEntryDetailsHeading": "Typspezifische Konfiguration",
"lang_bootentryDeleteConfirm": "Sind Sie sicher, dass Sie diesen Men\u00fceintrag l\u00f6schen wollen?",
"lang_bootentryHead": "Men\u00fceintr\u00e4ge",
"lang_bootentryIntro": "Hier k\u00f6nnen Sie Men\u00fceintr\u00e4ge definieren, die sich sp\u00e4ter einem Men\u00fc zuweisen lassen. Ein Men\u00fceintrag besteht entweder aus einem zu ladenden Kernel\/Image plus optional initrd, oder aus einem iPXE-Skript.",
@@ -38,6 +39,7 @@
"lang_forceRecompile": "Jetzt neu kompilieren",
"lang_generationFailed": "Erzeugen des Bootmen\u00fcs fehlgeschlagen. Der Netzwerkboot von bwLehrpool wird wahrscheinlich nicht funktionieren. Wenn Sie den Fehler nicht selbst beheben k\u00f6nnen, melden Sie bitte die Logausgabe an das bwLehrpool-Projekt.",
"lang_hex": "Hex",
+ "lang_hookExtraOptionHeading": "Weitere Angaben",
"lang_hotkey": "Hotkey",
"lang_idFormatHint": "(Max. 16 Zeichen, nur a-z 0-9 - _)",
"lang_imageToLoad": "Zu ladendes Image (z.B. Kernel)",
diff --git a/modules-available/serversetup-bwlp-ipxe/page.inc.php b/modules-available/serversetup-bwlp-ipxe/page.inc.php
index 40b75dd2..f14c1e57 100644
--- a/modules-available/serversetup-bwlp-ipxe/page.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/page.inc.php
@@ -519,25 +519,25 @@ class Page_ServerSetup extends Page
$params['oldentryid'] = $params['entryid'] = $row['entryid'];
$params['builtin'] = $row['builtin'];
}
- if (!is_array($params['entries'])) {
- $params['entries'] = [];
- }
- $f = [];
- foreach ($params['entries'] as $e) {
- if (isset($e['mode'])) {
- $f[] = $e['mode'];
- }
- }
- if (!in_array('PCBIOS', $f)) {
- $params['entries'][] = ['mode' => 'PCBIOS'];
- }
- if (!in_array('EFI', $f)) {
- $params['entries'][] = ['mode' => 'EFI'];
- }
$params['menus'] = Database::queryAll('SELECT m.menuid, m.title FROM serversetup_menu m
INNER JOIN serversetup_menuentry me ON (me.menuid = m.menuid)
WHERE me.entryid = :entryid', ['entryid' => $row['entryid']]);
}
+ if (!isset($params['entries']) || !is_array($params['entries'])) {
+ $params['entries'] = [];
+ }
+ $f = [];
+ foreach ($params['entries'] as $e) {
+ if (isset($e['mode'])) {
+ $f[] = $e['mode'];
+ }
+ }
+ if (!in_array('PCBIOS', $f)) {
+ $params['entries'][] = ['mode' => 'PCBIOS'];
+ }
+ if (!in_array('EFI', $f)) {
+ $params['entries'][] = ['mode' => 'EFI'];
+ }
$params['disabled'] = User::hasPermission('ipxe.bootentry.edit') ? '' : 'disabled';
Render::addTemplate('ipxe-new-boot-entry', $params);
@@ -823,12 +823,19 @@ class Page_ServerSetup extends Page
}
/** @var BootEntryHook $module */
$module = $hook->run();
- $entryData = Request::post('selection-' . $type, false, 'string');
- $entry = $module->getBootEntry($entryData);
+ $id = Request::post('selection-' . $type, false, 'string');
+ $entry = $module->isValidId($id);
if ($entry === null) {
- Message::addError('invalid-custom-entry-id', $type, $entryData);
+ Message::addError('invalid-custom-entry-id', $type, $id);
return;
}
+ $entryData = ['id' => $id];
+ foreach ($module->extraFields() as $field) {
+ if ($field->name === 'id')
+ continue;
+ $entryData[$field->name] = $field->fromPost($type);
+ }
+ $entryData = json_encode($entryData);
}
$params = [
'entryid' => $newId,
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/ipxe-new-boot-entry.html b/modules-available/serversetup-bwlp-ipxe/templates/ipxe-new-boot-entry.html
index fd76c1d5..5b7e3134 100644
--- a/modules-available/serversetup-bwlp-ipxe/templates/ipxe-new-boot-entry.html
+++ b/modules-available/serversetup-bwlp-ipxe/templates/ipxe-new-boot-entry.html
@@ -52,6 +52,8 @@
<input id="input-title" class="form-control" name="title" value="{{title}}" maxlength="100" {{disabled}}>
</div>
+ <h4>{{lang_bootEntryDetailsHeading}}</h4>
+
<div class="type-form" id="form-exec">
<div class="form-group">
<label for="arch-selector">
@@ -170,12 +172,20 @@
{{#groups}}
<optgroup label="{{groupName}}">
{{#entries}}
- <option value="{{id}}" {{selected}}>{{name}}</option>
+ <option value="{{id}}" {{selected}} {{disabled}}>{{name}}</option>
{{/entries}}
</optgroup>
{{/groups}}
</select>
</div>
+ <div class="form-group">
+ {{#renderExtraFields.0}}
+ <h4>{{lang_hookExtraOptionHeading}}</h4>
+ {{/renderExtraFields.0}}
+ {{#renderExtraFields}}
+ {{{html}}}
+ {{/renderExtraFields}}
+ </div>
</div>
{{/hooks}}
@@ -185,6 +195,8 @@
</div>
{{/builtin}}
+ <hr>
+
<p class="slx-bold">{{lang_referencingMenus}}:</p>
<ul>
{{#menus}}