summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules-available/serversetup-bwlp/api.inc.php12
-rw-r--r--modules-available/serversetup-bwlp/inc/bootentry.inc.php113
-rw-r--r--modules-available/serversetup-bwlp/inc/ipxemenu.inc.php8
-rw-r--r--modules-available/serversetup-bwlp/inc/menuentry.inc.php10
-rw-r--r--modules-available/serversetup-bwlp/page.inc.php7
-rw-r--r--modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html122
6 files changed, 194 insertions, 78 deletions
diff --git a/modules-available/serversetup-bwlp/api.inc.php b/modules-available/serversetup-bwlp/api.inc.php
index 36f9063c..52f30440 100644
--- a/modules-available/serversetup-bwlp/api.inc.php
+++ b/modules-available/serversetup-bwlp/api.inc.php
@@ -1,5 +1,7 @@
<?php
+// TODO: Check if required arguments are given; if not, spit out according script (identical to what is embedded)
+
$BOOT_METHODS = [
'EXIT' => 'exit 1',
'COMBOOT' => 'chain /tftp/chain.c32 hd0',
@@ -22,12 +24,14 @@ $platform = strtoupper(Request::any('platform', 'PCBIOS', 'string'));
$localboot = false;
$model = false;
if ($uuid !== false && Module::get('statistics') !== false) {
+ // If we have the machine table, we rather try to look up the system model from there, using the UUID
$row = Database::queryFirst('SELECT systemmodel FROM machine WHERE machineuuid = :uuid', ['uuid' => $uuid]);
if ($row !== false && !empty($row['systemmodel'])) {
$model = $row['systemmodel'];
}
}
if ($model === false) {
+ // Otherwise use what iPXE sent us
function modfilt($str)
{
if (empty($str) || preg_match('/product\s+name|be\s+filled|unknown|default\s+string/i', $str))
@@ -70,6 +74,8 @@ if (isset($BOOT_METHODS[$localboot])) {
$BOOT_METHODS = array_reverse($BOOT_METHODS);
}
+// TODO: Feature check for our own iPXE extensions, stay compatible to stock iPXE
+
$output = <<<HERE
#!ipxe
@@ -139,7 +145,7 @@ console --left 55 --top 88 --right 63 --bottom 64 --quick --keep --picture bg-me
HERE;
-$output .= $menu->getMenuDefinition('target');
+$output .= $menu->getMenuDefinition('target', $platform);
$output .= <<<HERE
@@ -151,7 +157,9 @@ goto start
HERE;
-$output .= $menu->getItemsCode();
+$output .= $menu->getItemsCode($platform);
+
+// TODO: Work out memtest stuff. Needs to be put on server (install/update script) -- PCBIOS only? Chain EFI -> BIOS?
/*
:i1
diff --git a/modules-available/serversetup-bwlp/inc/bootentry.inc.php b/modules-available/serversetup-bwlp/inc/bootentry.inc.php
index 930f4413..010b660c 100644
--- a/modules-available/serversetup-bwlp/inc/bootentry.inc.php
+++ b/modules-available/serversetup-bwlp/inc/bootentry.inc.php
@@ -14,7 +14,9 @@ abstract class BootEntry
}
}
- public abstract function toScript($failLabel);
+ public abstract function supportsMode($mode);
+
+ public abstract function toScript($failLabel, $mode);
public abstract function toArray();
@@ -46,9 +48,19 @@ abstract class BootEntry
public static function newStandardBootEntry($initData)
{
- if (empty($initData['executable']))
- return null;
- return new StandardBootEntry($initData);
+ $ret = new StandardBootEntry($initData);
+ $list = [];
+ if ($ret->arch() !== StandardBootEntry::EFI) {
+ $list[] = StandardBootEntry::BIOS;
+ }
+ if ($ret->arch() === StandardBootEntry::EFI || $ret->arch() === StandardBootEntry::BOTH) {
+ $list[] = StandardBootEntry::EFI;
+ }
+ foreach ($list as $mode) {
+ if (empty($initData['executable'][$mode]))
+ return null;
+ }
+ return $ret;
}
public static function newCustomBootEntry($initData)
@@ -83,6 +95,12 @@ class StandardBootEntry extends BootEntry
protected $replace;
protected $autoUnload;
protected $resetConsole;
+ protected $arch; // true == available, false == not available
+
+ 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)
public function __construct($data = false)
{
@@ -109,38 +127,70 @@ class StandardBootEntry extends BootEntry
} else {
parent::__construct($data);
}
+ // Convert legacy DB format
+ foreach (['executable', 'initRd', 'commandLine', 'replace', 'autoUnload', 'resetConsole'] as $key) {
+ if (!is_array($this->{$key})) {
+ $this->{$key} = [ 'PCBIOS' => $this->{$key}, 'EFI' => '' ];
+ }
+ }
+ if ($this->arch === null) {
+ $this->arch = self::AGNOSTIC;
+ }
+ }
+
+ public function arch()
+ {
+ return $this->arch;
+ }
+
+ public function supportsMode($mode)
+ {
+ if ($mode === $this->arch || $this->arch === self::AGNOSTIC)
+ return true;
+ if ($mode === self::BIOS || $mode === self::EFI) {
+ return $this->arch === self::BOTH;
+ }
+ error_log('Unknown iPXE platform: ' . $mode);
+ return false;
}
- public function toScript($failLabel)
+ public function toScript($failLabel, $mode)
{
+ if (!$this->supportsMode($mode)) {
+ return "prompt Entry doesn't have an executable for mode $mode\n";
+ }
+ if ($this->arch === self::AGNOSTIC) {
+ $mode = self::BIOS;
+ }
+
$script = '';
- if ($this->resetConsole) {
+ if ($this->resetConsole[$mode]) {
$script .= "console ||\n";
}
- if (!empty($this->initRd)) {
+ if (!empty($this->initRd[$mode])) {
$script .= "imgfree ||\n";
- if (!is_array($this->initRd)) {
- $script .= "initrd {$this->initRd} || goto $failLabel\n";
+ if (!is_array($this->initRd[$mode])) {
+ $script .= "initrd {$this->initRd[$mode]} || goto $failLabel\n";
} else {
- foreach ($this->initRd as $initrd) {
+ foreach ($this->initRd[$mode] as $initrd) {
$script .= "initrd $initrd || goto $failLabel\n";
}
}
}
$script .= "boot ";
- if ($this->autoUnload) {
+ if ($this->autoUnload[$mode]) {
$script .= "-a ";
}
- if ($this->replace) {
+ if ($this->replace[$mode]) {
$script .= "-r ";
}
- $script .= "{$this->executable}";
- $rdBase = basename($this->initRd);
- if (!empty($this->commandLine)) {
- $script .= " initrd=$rdBase {$this->commandLine}";
+ $script .= $this->executable[$mode];
+ $rdBase = basename($this->initRd[$mode]);
+ if (!empty($this->commandLine[$mode])) {
+ $script .= " initrd=$rdBase {$this->commandLine[$mode]}";
}
$script .= " || goto $failLabel\n";
- if ($this->resetConsole) {
+ if ($this->resetConsole[$mode]) {
$script .= "goto start ||\n";
}
return $script;
@@ -148,14 +198,19 @@ class StandardBootEntry extends BootEntry
public function addFormFields(&$array)
{
- $array['entry'] = [
- 'executable' => $this->executable,
- 'initRd' => $this->initRd,
- 'commandLine' => $this->commandLine,
- 'replace_checked' => $this->replace ? 'checked' : '',
- 'autoUnload_checked' => $this->autoUnload ? 'checked' : '',
- 'resetConsole_checked' => $this->resetConsole ? 'checked' : '',
- ];
+ $array[$this->arch . '_selected'] = 'selected';
+ foreach ([self::BIOS, self::EFI] as $mode) {
+ $array['entries'][] = [
+ 'is' . $mode => true,
+ 'mode' => $mode,
+ 'executable' => $this->executable[$mode],
+ 'initRd' => $this->initRd[$mode],
+ 'commandLine' => $this->commandLine[$mode],
+ 'replace_checked' => $this->replace[$mode] ? 'checked' : '',
+ 'autoUnload_checked' => $this->autoUnload[$mode] ? 'checked' : '',
+ 'resetConsole_checked' => $this->resetConsole[$mode] ? 'checked' : '',
+ ];
+ }
$array['exec_checked'] = 'checked';
}
@@ -168,6 +223,7 @@ class StandardBootEntry extends BootEntry
'replace' => $this->replace,
'autoUnload' => $this->autoUnload,
'resetConsole' => $this->resetConsole,
+ 'arch' => $this->arch,
];
}
}
@@ -176,7 +232,12 @@ class CustomBootEntry extends BootEntry
{
protected $script;
- public function toScript($failLabel)
+ public function supportsMode($mode)
+ {
+ return true;
+ }
+
+ public function toScript($failLabel, $mode)
{
return str_replace('%fail%', $failLabel, $this->script) . "\n";
}
diff --git a/modules-available/serversetup-bwlp/inc/ipxemenu.inc.php b/modules-available/serversetup-bwlp/inc/ipxemenu.inc.php
index ed9f0986..56041c20 100644
--- a/modules-available/serversetup-bwlp/inc/ipxemenu.inc.php
+++ b/modules-available/serversetup-bwlp/inc/ipxemenu.inc.php
@@ -36,11 +36,11 @@ class IPxeMenu
}
}
- public function getMenuDefinition($targetVar)
+ public function getMenuDefinition($targetVar, $mode)
{
$str = "menu {$this->title}\n";
foreach ($this->items as $item) {
- $str .= $item->getMenuItemScript("m_{$this->menuid}", $this->defaultEntryId);
+ $str .= $item->getMenuItemScript("m_{$this->menuid}", $this->defaultEntryId, $mode);
}
if ($this->defaultEntryId === null) {
$defaultLabel = "mx_{$this->menuid}_poweroff";
@@ -61,11 +61,11 @@ class IPxeMenu
return $str;
}
- public function getItemsCode()
+ public function getItemsCode($mode)
{
$str = '';
foreach ($this->items as $item) {
- $str .= $item->getBootEntryScript("m_{$this->menuid}", 'fail');
+ $str .= $item->getBootEntryScript("m_{$this->menuid}", 'fail', $mode);
$str .= "goto slx_menu\n";
}
return $str;
diff --git a/modules-available/serversetup-bwlp/inc/menuentry.inc.php b/modules-available/serversetup-bwlp/inc/menuentry.inc.php
index 9d9d4163..03b860e8 100644
--- a/modules-available/serversetup-bwlp/inc/menuentry.inc.php
+++ b/modules-available/serversetup-bwlp/inc/menuentry.inc.php
@@ -58,8 +58,10 @@ class MenuEntry
settype($this->menuentryid, 'int');
}
- public function getMenuItemScript($lblPrefix, $requestedDefaultId)
+ public function getMenuItemScript($lblPrefix, $requestedDefaultId, $mode)
{
+ if ($this->bootEntry !== null && !$this->bootEntry->supportsMode($mode))
+ return '';
$str = 'item ';
if ($this->gap) {
$str .= '--gap ';
@@ -81,9 +83,9 @@ class MenuEntry
return $str . " || prompt Could not create menu item for {$lblPrefix}_{$this->menuentryid}\n";
}
- public function getBootEntryScript($lblPrefix, $failLabel)
+ public function getBootEntryScript($lblPrefix, $failLabel, $mode)
{
- if ($this->bootEntry === null)
+ if ($this->bootEntry === null || !$this->bootEntry->supportsMode($mode))
return '';
$str = ":{$lblPrefix}_{$this->menuentryid}\n";
if (!empty($this->md5pass)) {
@@ -94,7 +96,7 @@ class MenuEntry
. "goto slx_pass_check || goto $failLabel\n"
. ":{$lblPrefix}_ok\n";
}
- return $str . $this->bootEntry->toScript($failLabel);
+ return $str . $this->bootEntry->toScript($failLabel, $mode);
}
/*
diff --git a/modules-available/serversetup-bwlp/page.inc.php b/modules-available/serversetup-bwlp/page.inc.php
index 25a31f06..ba2e5433 100644
--- a/modules-available/serversetup-bwlp/page.inc.php
+++ b/modules-available/serversetup-bwlp/page.inc.php
@@ -279,6 +279,7 @@ class Page_ServerSetup extends Page
$entry->addFormFields($params);
$params['title'] = $row['title'];
$params['oldentryid'] = $params['entryid'] = $row['entryid'];
+ $params['builtin'] = $row['builtin'];
}
Render::addTemplate('ipxe-new-boot-entry', $params);
}
@@ -543,7 +544,7 @@ class Page_ServerSetup extends Page
}
if ($entry === null) {
Message::addError('main.empty-field');
- return;
+ Util::redirect('?do=serversetup&show=bootentry');
}
$params = [
'entryid' => $newId,
@@ -560,10 +561,10 @@ class Page_ServerSetup extends Page
// Edit existing entry
$params['oldid'] = $oldEntryId;
Database::exec('UPDATE serversetup_bootentry SET entryid = :entryid, title = :title, data = :data
- WHERE entryid = :oldid AND builtin = 0', $params);
- // TODO: Redirect to &show=bootentry
+ WHERE entryid = :oldid', $params);
Message::addSuccess('boot-entry-updated', $newId);
}
+ Util::redirect('?do=serversetup&show=bootentry');
}
}
diff --git a/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html b/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html
index fd9e1d72..33de1ee4 100644
--- a/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html
+++ b/modules-available/serversetup-bwlp/templates/ipxe-new-boot-entry.html
@@ -1,5 +1,11 @@
<h2>{{lang_newBootEntryHead}}</h2>
+{{#builtin}}
+ <div class="alert alert-warning">
+ {{lang_editBuiltinWarn}}
+ </div>
+{{/builtin}}
+
<div class="panel panel-default">
<div class="panel-heading">
{{lang_bootEntryData}}
@@ -33,47 +39,69 @@
</label>
<input id="input-title" class="form-control" name="title" value="{{title}}" maxlength="100">
</div>
+ <div class="form-group">
+ <label for="arch-selector">
+ {{lang_archSelector}}
+ </label>
+ <select id="arch-selector" class="form-control" name="entry[arch]">
+ <option value="agnostic" {{agnostic_selected}}>{{lang_archAgnostic}}</option>
+ <option value="PCBIOS" {{PCBIOS_selected}}>{{lang_biosOnly}}</option>
+ <option value="EFI" {{EFI_selected}}>{{lang_efiOnly}}</option>
+ <option value="PCBIOS-EFI" {{PCBIOS-EFI_selected}}>{{lang_archBoth}}</option>
+ </select>
+ </div>
<div class="type-form" id="form-exec">
- <div class="form-group">
- <label for="input-ex">
- {{lang_imageToLoad}}
- </label>
- <input id="input-ex" class="form-control" name="entry[executable]" value="{{entry.executable}}">
- </div>
- <div class="form-group">
- <label for="input-rd">
- {{lang_initRd}}
- </label>
- <input id="input-rd" class="form-control" name="entry[initRd]" value="{{entry.initRd}}">
- </div>
- <div class="form-group">
- <label for="input-cmd">
- {{lang_commandLine}}
- </label>
- <input id="input-cmd" class="form-control" name="entry[commandLine]"
- value="{{entry.commandLine}}">
- </div>
- <div class="form-group">
- <div class="checkbox checkbox-inline">
- <input id="exec-replace" class="form-control" type="checkbox"
- name="entry[replace]" {{entry.replace_checked}}>
- <label for="exec-replace">{{lang_execReplace}}</label>
- </div>
- </div>
- <div class="form-group">
- <div class="checkbox checkbox-inline">
- <input id="exec-au" class="form-control" type="checkbox"
- name="entry[autoUnload]" {{entry.autoUnload_checked}}>
- <label for="exec-au">{{lang_execAutoUnload}}</label>
- </div>
- </div>
- <div class="form-group">
- <div class="checkbox checkbox-inline">
- <input id="exec-reset" class="form-control" type="checkbox"
- name="entry[resetConsole]" {{entry.resetConsole_checked}}>
- <label for="exec-reset">{{lang_execResetConsole}}</label>
- </div>
+ <div class="row">
+ {{#entries}}
+ <div class="mode-class col-md-6" id="col-{{mode}}">
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <h4 class="arch-heading">{{mode}}</h4>
+ <div class="form-group">
+ <label for="input-ex">
+ {{lang_imageToLoad}}
+ </label>
+ <input id="input-ex" class="form-control" name="entry[executable][{{mode}}]" value="{{executable}}">
+ </div>
+ <div class="form-group">
+ <label for="input-rd">
+ {{lang_initRd}}
+ </label>
+ <input id="input-rd" class="form-control" name="entry[initRd][{{mode}}]" value="{{initRd}}">
+ </div>
+ <div class="form-group">
+ <label for="input-cmd">
+ {{lang_commandLine}}
+ </label>
+ <input id="input-cmd" class="form-control" name="entry[commandLine][{{mode}}]"
+ value="{{commandLine}}">
+ </div>
+ <div class="form-group">
+ <div class="checkbox checkbox-inline">
+ <input id="exec-replace-{{mode}}" class="form-control" type="checkbox"
+ name="entry[replace][{{mode}}]" {{replace_checked}}>
+ <label for="exec-replace-{{mode}}">{{lang_execReplace}}</label>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="checkbox checkbox-inline">
+ <input id="exec-au-{{mode}}" class="form-control" type="checkbox"
+ name="entry[autoUnload][{{mode}}]" {{autoUnload_checked}}>
+ <label for="exec-au-{{mode}}">{{lang_execAutoUnload}}</label>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="checkbox checkbox-inline">
+ <input id="exec-reset-{{mode}}" class="form-control" type="checkbox"
+ name="entry[resetConsole][{{mode}}]" {{resetConsole_checked}}>
+ <label for="exec-reset-{{mode}}">{{lang_execResetConsole}}</label>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ {{/entries}}
</div>
</div>
@@ -104,5 +132,21 @@ document.addEventListener('DOMContentLoaded', function () {
$('#form-' + $(this).val()).show();
});
$('.type-radio[checked]').click();
+ var $as = $('#arch-selector');
+ $as.change(function() {
+ var v = $as.val();
+ if (v === 'agnostic') {
+ v = 'PCBIOS';
+ $('.arch-heading').hide();
+ } else {
+ $('.arch-heading').show();
+ }
+ var vs = v.split('-');
+ var cols = 12 / vs.length;
+ $('.mode-class').hide();
+ for (var i = 0; i < vs.length; ++i) {
+ $('#col-' + vs[i]).attr('class', 'mode-class col-md-' + cols).show();
+ }
+ }).change();
});
// --></script> \ No newline at end of file