summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2019-10-17 14:41:03 +0200
committerSimon Rettberg2019-10-17 14:41:03 +0200
commit193b765f07543b4824950fe08d337211c2ef8a1c (patch)
tree4cb54d445e53df797bbf69297c8d360068f94fb7
parent[serversetup-bwlp-ipxe/minilinux] Implement minilinux hook for ipxe (diff)
downloadslx-admin-193b765f07543b4824950fe08d337211c2ef8a1c.tar.gz
slx-admin-193b765f07543b4824950fe08d337211c2ef8a1c.tar.xz
slx-admin-193b765f07543b4824950fe08d337211c2ef8a1c.zip
[serversetup-bwlp-ipxe/minilinux] Further improvements
* Distinction between BIOS and EFI for ipxe hook in minilinux * Debug KCL modifier customizable by update meta data * Bugfixes, minor refactoring...
-rw-r--r--modules-available/minilinux/hooks/ipxe-bootentry.inc.php76
-rw-r--r--modules-available/minilinux/inc/minilinux.inc.php10
-rw-r--r--modules-available/minilinux/install.inc.php2
-rw-r--r--modules-available/minilinux/lang/de/module.json2
-rw-r--r--modules-available/minilinux/page.inc.php2
-rw-r--r--modules-available/minilinux/templates/branches.html24
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php63
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php2
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php26
-rw-r--r--modules-available/serversetup-bwlp-ipxe/page.inc.php6
10 files changed, 135 insertions, 78 deletions
diff --git a/modules-available/minilinux/hooks/ipxe-bootentry.inc.php b/modules-available/minilinux/hooks/ipxe-bootentry.inc.php
index 090a14da..944cdfa3 100644
--- a/modules-available/minilinux/hooks/ipxe-bootentry.inc.php
+++ b/modules-available/minilinux/hooks/ipxe-bootentry.inc.php
@@ -59,9 +59,9 @@ class LinuxBootEntryHook extends BootEntryHook
* @param $id
* @return BootEntry the actual boot entry instance for given entry, false if invalid id
*/
- public function getBootEntryInternal($data)
+ public function getBootEntryInternal($localData)
{
- $id = $data['id'];
+ $id = $localData['id'];
if ($id === 'default') { // Special case
$effectiveId = Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT_EFFECTIVE);
} else {
@@ -72,51 +72,67 @@ class LinuxBootEntryHook extends BootEntryHook
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]);
+ return BootEntry::newCustomBootEntry(['script' => 'prompt Selected version not currently installed on server: ' . $effectiveId]);
}
+ $remoteData = json_decode($res['data'], true);
+ $bios = $efi = false;
+ if (!@is_array($remoteData['agnostic']) && !@is_array($remoteData['efi']) && !@is_array($remoteData['bios'])) {
+ $remoteData['agnostic'] = []; // We got nothing at all so fake this entry, resulting in a generic default entry
+ }
+ if (@is_array($remoteData['agnostic'])) {
+ $bios = $this->generateExecData($effectiveId, $remoteData['agnostic'], $localData);
+ $arch = BootEntry::AGNOSTIC;
+ } else {
+ if (@is_array($remoteData['efi'])) {
+ $efi = $this->generateExecData($effectiveId, $remoteData['efi'], $localData);
+ }
+ if (@is_array($remoteData['bios'])) {
+ $bios = $this->generateExecData($effectiveId, $remoteData['bios'], $localData);
+ }
+ if ($bios && $efi) {
+ $arch = BootEntry::BOTH;
+ } elseif ($bios) {
+ $arch = BootEntry::BIOS;
+ } else {
+ $arch = BootEntry::EFI;
+ }
+ }
+ return BootEntry::newStandardBootEntry($bios, $efi, $arch);
+ }
+
+ private function generateExecData($effectiveId, $remoteData, $localData)
+ {
$exec = new ExecData();
// Defaults
- $root = '/boot/' . $id . '/';
+ $root = '/boot/' . $effectiveId . '/';
$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];
- }
+ foreach (['executable', 'commandLine', 'initRd', 'imageFree'] as $key) {
+ if (isset($remoteData[$key])) {
+ $exec->{$key} = $remoteData[$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($localData['debug']) && $localData['debug']) {
+ $exec->commandLine = IPxe::modifyCommandLine($exec->commandLine,
+ isset($remoteData['debugCommandLineModifier'])
+ ? $remoteData['debugCommandLineModifier']
+ : '-vga -quiet -splash -loglevel loglevel=7'
+ );
}
- 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;
- }
- }
+ if (isset($localData['kcl-extra'])) {
+ $exec->commandLine = IPxe::modifyCommandLine($exec->commandLine, $localData['kcl-extra']);
}
- $exec->commandLine = str_replace('%ID%', $id, $exec->commandLine);
+ $exec->commandLine = str_replace('%ID%', $effectiveId, $exec->commandLine);
$exec->executable = $root . $exec->executable;
foreach ($exec->initRd as &$rd) {
$rd = $root . $rd;
}
- return BootEntry::newStandardBootEntry($exec, false, 'agnostic');
+ unset($rd);
+ return $exec;
}
public function isValidId($id)
diff --git a/modules-available/minilinux/inc/minilinux.inc.php b/modules-available/minilinux/inc/minilinux.inc.php
index e940380c..54536096 100644
--- a/modules-available/minilinux/inc/minilinux.inc.php
+++ b/modules-available/minilinux/inc/minilinux.inc.php
@@ -62,7 +62,7 @@ class MiniLinux
EventLog::warning('Cannot download Linux version meta data for ' . $sourceid);
$lastupdate = 'lastupdate';
} else {
- if (isset($data['systems']) && is_array($data['systems'])) {
+ if (@is_array($data['systems'])) {
self::addBranches($sourceid, $data['systems']);
}
$lastupdate = 'UNIX_TIMESTAMP()';
@@ -70,6 +70,12 @@ class MiniLinux
Database::exec("UPDATE minilinux_source SET lastupdate = $lastupdate, taskid = NULL
WHERE sourceid = :sourceid AND taskid = :taskid",
['sourceid' => $sourceid, 'taskid' => $taskId]);
+ // Clean up -- delete orphaned versions that are not installed
+ $orphaned = Database::queryColumnArray('SELECT versionid FROM minilinux_version WHERE orphan > 4 AND installed = 0');
+ if (!empty($orphaned)) {
+ Database::exec('DELETE FROM minilinux_version WHERE versionid IN (:list)', ['list' => $orphaned]);
+ }
+ Database::exec('DELETE FROM minilinux_branch', [], true);
}
private static function addBranches($sourceid, $systems)
@@ -88,7 +94,7 @@ class MiniLinux
'title' => $title,
'description' => $description,
]);
- if (isset($system['versions']) && is_array($system['versions'])) {
+ if (@is_array($system['versions'])) {
self::addVersions($branchid, $system['versions']);
}
}
diff --git a/modules-available/minilinux/install.inc.php b/modules-available/minilinux/install.inc.php
index 5387542e..b859671a 100644
--- a/modules-available/minilinux/install.inc.php
+++ b/modules-available/minilinux/install.inc.php
@@ -34,7 +34,7 @@ $result[] = tableCreate('minilinux_version', "
");
$result[] = tableAddConstraint('minilinux_version', 'branchid', 'minilinux_branch', 'branchid',
- 'ON UPDATE CASCADE ON DELETE CASCADE');
+ 'ON UPDATE CASCADE ON DELETE RESTRICT');
$result[] = tableAddConstraint('minilinux_branch', 'sourceid', 'minilinux_source', 'sourceid',
'ON UPDATE CASCADE ON DELETE SET NULL');
diff --git a/modules-available/minilinux/lang/de/module.json b/modules-available/minilinux/lang/de/module.json
index da6ea4bb..687b4a71 100644
--- a/modules-available/minilinux/lang/de/module.json
+++ b/modules-available/minilinux/lang/de/module.json
@@ -7,7 +7,7 @@
"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",
+ "module_name": "Netboot Grundsystem",
"not_installed_hint": "(nicht installiert)",
"page_title": "Linuxvarianten f\u00fcr Netboot verwalten"
} \ No newline at end of file
diff --git a/modules-available/minilinux/page.inc.php b/modules-available/minilinux/page.inc.php
index 53632699..7c7e3d36 100644
--- a/modules-available/minilinux/page.inc.php
+++ b/modules-available/minilinux/page.inc.php
@@ -80,7 +80,7 @@ class Page_MiniLinux extends Page
$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['orphan'] = ($version['orphan'] > 2);
$version['downloading'] = $version['taskid'] && Taskmanager::isRunning(Taskmanager::status($version['taskid']));
if ($version['installed'] && $version['versionid'] !== $def) {
$version['showsetdefault'] = true;
diff --git a/modules-available/minilinux/templates/branches.html b/modules-available/minilinux/templates/branches.html
index 64adda16..5f3c4e50 100644
--- a/modules-available/minilinux/templates/branches.html
+++ b/modules-available/minilinux/templates/branches.html
@@ -1,18 +1,20 @@
<h3>{{lang_branchesHeading}}</h3>
-{{#branches}}
-<div id="ibm-mainframe" class="panel panel-default">
- <div class="panel-heading">
- <div class="pull-right">
- {{sourceid}} {{branchid}}
+<div id="ibm-mainframe">
+ {{#branches}}
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ <div class="pull-right">
+ {{sourceid}} {{branchid}}
+ </div>
+ <b>{{title}}</b>
</div>
- <b>{{title}}</b>
- </div>
- <div class="panel-body">
- {{description}}
+ <div class="panel-body">
+ {{description}}
+ </div>
+ {{{versionlist}}}
</div>
- {{{versionlist}}}
+ {{/branches}}
</div>
-{{/branches}}
<script>
document.addEventListener('DOMContentLoaded', function () {
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
index 174f4459..dec70528 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
@@ -3,6 +3,15 @@
abstract class BootEntry
{
+ /** Supports both via same entry (stored in PCBIOS entry) */
+ const AGNOSTIC = 'agnostic';
+ /** Only valid for legacy BIOS boot */
+ const BIOS = 'PCBIOS';
+ /** Only valid for EFI boot */
+ const EFI = 'EFI';
+ /** Supports both via distinct entry */
+ const BOTH = 'PCBIOS-EFI';
+
public abstract function supportsMode($mode);
public abstract function toScript($failLabel, $mode);
@@ -57,11 +66,11 @@ abstract class BootEntry
{
$ret = new StandardBootEntry($initData, $efi, $arch);
$list = [];
- if ($ret->arch() !== StandardBootEntry::EFI) {
- $list[] = StandardBootEntry::BIOS;
+ if ($ret->arch() !== self::EFI) {
+ $list[] = self::BIOS;
}
- if ($ret->arch() === StandardBootEntry::EFI || $ret->arch() === StandardBootEntry::BOTH) {
- $list[] = StandardBootEntry::EFI;
+ if ($ret->arch() === self::EFI || $ret->arch() === self::BOTH) {
+ $list[] = self::EFI;
}
$data = $ret->toArray();
foreach ($list as $mode) {
@@ -129,11 +138,6 @@ class StandardBootEntry extends BootEntry
protected $arch; // Constants below
- const BIOS = 'PCBIOS'; // Only valid for legacy BIOS boot
- const EFI = 'EFI'; // Only valid for EFI boot
- const BOTH = 'PCBIOS-EFI'; // Supports both via distinct entry
- const AGNOSTIC = 'agnostic'; // Supports both via same entry (PCBIOS entry)
-
const KEYS = ['executable', 'initRd', 'commandLine', 'replace', 'imageFree', 'autoUnload', 'resetConsole', 'dhcpOptions'];
public function __construct($data, $efi = false, $arch = false)
@@ -157,18 +161,21 @@ class StandardBootEntry extends BootEntry
} else {
$this->arch = $data['arch'];
}
- if (isset($data[self::BIOS]) || isset($data[self::EFI])) {
+ if (isset($data[BootEntry::BIOS]) || isset($data[BootEntry::EFI])) {
// Current format
$this->fromCurrentFormat($data);
} else {
// Convert legacy DB format
$this->fromLegacyFormat($data);
}
+ } elseif ($arch == BootEntry::EFI && $efi instanceof ExecData) {
+ $this->efi = $efi;
+ $this->arch = $arch;
} else {
error_log('Invalid StandardBootEntry constructor call');
}
- if (!in_array($this->arch, [self::BIOS, self::EFI, self::BOTH, self::AGNOSTIC])) {
- $this->arch = self::AGNOSTIC;
+ if (!in_array($this->arch, [BootEntry::BIOS, BootEntry::EFI, BootEntry::BOTH, BootEntry::AGNOSTIC])) {
+ $this->arch = BootEntry::AGNOSTIC;
}
}
@@ -176,12 +183,12 @@ class StandardBootEntry extends BootEntry
{
$ok = false;
foreach (self::KEYS as $key) {
- if (isset($data[$key][self::BIOS])) {
- $this->pcbios->{$key} = $data[$key][self::BIOS];
+ if (isset($data[$key][BootEntry::BIOS])) {
+ $this->pcbios->{$key} = $data[$key][BootEntry::BIOS];
$ok = true;
}
- if (isset($data[$key][self::EFI])) {
- $this->efi->{$key} = $data[$key][self::EFI];
+ if (isset($data[$key][BootEntry::EFI])) {
+ $this->efi->{$key} = $data[$key][BootEntry::EFI];
$ok = true;
}
}
@@ -198,11 +205,11 @@ class StandardBootEntry extends BootEntry
private function fromCurrentFormat($data)
{
foreach (self::KEYS as $key) {
- if (isset($data[self::BIOS][$key])) {
- $this->pcbios->{$key} = $data[self::BIOS][$key];
+ if (isset($data[BootEntry::BIOS][$key])) {
+ $this->pcbios->{$key} = $data[BootEntry::BIOS][$key];
}
- if (isset($data[self::EFI][$key])) {
- $this->efi->{$key} = $data[self::EFI][$key];
+ if (isset($data[BootEntry::EFI][$key])) {
+ $this->efi->{$key} = $data[BootEntry::EFI][$key];
}
}
}
@@ -241,10 +248,10 @@ class StandardBootEntry extends BootEntry
public function supportsMode($mode)
{
- if ($mode === $this->arch || $this->arch === self::AGNOSTIC)
+ if ($mode === $this->arch || $this->arch === BootEntry::AGNOSTIC)
return true;
- if ($mode === self::BIOS || $mode === self::EFI) {
- return $this->arch === self::BOTH;
+ if ($mode === BootEntry::BIOS || $mode === BootEntry::EFI) {
+ return $this->arch === BootEntry::BOTH;
}
error_log('Unknown iPXE platform: ' . $mode);
return false;
@@ -255,7 +262,7 @@ class StandardBootEntry extends BootEntry
if (!$this->supportsMode($mode)) {
return "prompt Entry doesn't have an executable for mode $mode\n";
}
- if ($this->arch === self::AGNOSTIC || $mode == self::BIOS) {
+ if ($this->arch === BootEntry::AGNOSTIC || $mode == BootEntry::BIOS) {
$entry = $this->pcbios;
} else {
$entry = $this->efi;
@@ -319,16 +326,16 @@ class StandardBootEntry extends BootEntry
public function addFormFields(&$array)
{
$array[$this->arch . '_selected'] = 'selected';
- $array['entries'][] = $this->pcbios->toFormFields(self::BIOS);
- $array['entries'][] = $this->efi->toFormFields(self::EFI);
+ $array['entries'][] = $this->pcbios->toFormFields(BootEntry::BIOS);
+ $array['entries'][] = $this->efi->toFormFields(BootEntry::EFI);
$array['exec_checked'] = 'checked';
}
public function toArray()
{
return [
- self::BIOS => $this->pcbios->toArray(),
- self::EFI => $this->efi->toArray(),
+ BootEntry::BIOS => $this->pcbios->toArray(),
+ BootEntry::EFI => $this->efi->toArray(),
'arch' => $this->arch,
];
}
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php
index f89031a3..cf180006 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php
@@ -53,7 +53,7 @@ abstract class BootEntryHook
* @param $id
* @return BootEntry|null the actual boot entry instance for given entry, null if invalid id
*/
- public abstract function getBootEntryInternal($data);
+ public abstract function getBootEntryInternal($localData);
public final function getBootEntry($data)
{
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php
index 6caecc65..4c2a7678 100644
--- a/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php
@@ -527,4 +527,30 @@ boot -a -r /boot/default/kernel initrd=initramfs-stage31 ${slxextra} slxbase=boo
return md5(md5($plainpass) . '-' . $salt);
}
+ /**
+ * Modify a kernel command line. Add or remove items to a given command line. The $modifier
+ * string is a list of space separated arguments. If the argument starts with a '-', all
+ * according occurrences of the given option will be removed from the command line. It is assumed
+ * that options are either of format "option" or "option=value", so a modifier of "-option" will
+ * remove any occurrence of either "option" or "option=something". If the argument starts with a
+ * '+', it will be added to the command line after removing the '+'. If the argument starts with any
+ * other character, it will also be added to the command line.
+ * @param string $cmdLine command line to modify
+ * @param string $modifier modification string of space separated arguments
+ * @return string the modified command line
+ */
+ public static function modifyCommandLine($cmdLine, $modifier)
+ {
+ $items = preg_split('/\s+/', $modifier, -1, PREG_SPLIT_NO_EMPTY);
+ foreach ($items as $item) {
+ if ($item{0} === '-') {
+ $item = preg_quote(substr($item, 1), '/');
+ $cmdLine = preg_replace('/(^|\s)' . $item . '(=\S*)?($|\s)/', ' ', $cmdLine);
+ } else {
+ $cmdLine .= ' ' . $item;
+ }
+ }
+ return $cmdLine;
+ }
+
}
diff --git a/modules-available/serversetup-bwlp-ipxe/page.inc.php b/modules-available/serversetup-bwlp-ipxe/page.inc.php
index f14c1e57..81f15922 100644
--- a/modules-available/serversetup-bwlp-ipxe/page.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/page.inc.php
@@ -434,13 +434,13 @@ class Page_ServerSetup extends Page
if (!array_key_exists('arch', $bootentry['data']))
continue;
// Naming and agnostic
- if ($bootentry['data']['arch'] === StandardBootEntry::BIOS) {
+ if ($bootentry['data']['arch'] === BootEntry::BIOS) {
$bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_biosOnly', true);
unset($bootentry['data']['EFI']);
- } elseif ($bootentry['data']['arch'] === StandardBootEntry::EFI) {
+ } elseif ($bootentry['data']['arch'] === BootEntry::EFI) {
$bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_efiOnly', true);
unset($bootentry['data']['PCBIOS']);
- } elseif ($bootentry['data']['arch'] === StandardBootEntry::AGNOSTIC) {
+ } elseif ($bootentry['data']['arch'] === BootEntry::AGNOSTIC) {
$bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archAgnostic', true);
unset($bootentry['data']['EFI']);
} else {