From fcce4a7cea05df6df7b0cd028c6a4762443b148f Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 27 Mar 2019 00:44:36 +0100 Subject: [serversetup-bwlp-ipxe] Localboot: Individual settings for BIOS/EFI --- .../serversetup-bwlp-ipxe/api.inc.php | 31 +++++------ .../serversetup-bwlp-ipxe/inc/localboot.inc.php | 41 +++++++++++++-- .../serversetup-bwlp-ipxe/install.inc.php | 13 ++++- .../lang/de/template-tags.json | 3 +- .../lang/en/template-tags.json | 3 +- .../serversetup-bwlp-ipxe/page.inc.php | 60 +++++++++++++--------- .../serversetup-bwlp-ipxe/templates/localboot.html | 36 ++++++++++--- 7 files changed, 127 insertions(+), 60 deletions(-) diff --git a/modules-available/serversetup-bwlp-ipxe/api.inc.php b/modules-available/serversetup-bwlp-ipxe/api.inc.php index 9b52f333..0d42a4c3 100644 --- a/modules-available/serversetup-bwlp-ipxe/api.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/api.inc.php @@ -61,8 +61,11 @@ HERE; } // ipxe has it lowercase, but we use uppercase $platform = strtoupper($platform); +if ($platform !== 'PCBIOS' && $platform !== 'EFI') { + $platform = 'PCBIOS'; // Just hope for the best? +} -$BOOT_METHODS = Localboot::BOOT_METHODS; +$BOOT_METHODS = Localboot::BOOT_METHODS[$platform]; $ip = $_SERVER['REMOTE_ADDR']; if (substr($ip, 0, 7) === '::ffff:') { @@ -113,23 +116,24 @@ if ($model === false) { } // Query if ($model !== false) { - $row = Database::queryFirst("SELECT bootmethod FROM serversetup_localboot WHERE systemmodel = :model LIMIT 1", + $e = strtolower($platform); // We made sure $platform is either PCBIOS or EFI, so no injection possible + $row = Database::queryFirst("SELECT $e AS bootmethod FROM serversetup_localboot WHERE systemmodel = :model LIMIT 1", ['model' => $model]); if ($row !== false) { $localboot = $row['bootmethod']; } } if ($localboot === false || !isset($BOOT_METHODS[$localboot])) { - $localboot = Property::get(Localboot::PROPERTY_KEY, 'AUTO'); + $localboot = Localboot::getDefault()[$platform]; if (!isset($BOOT_METHODS[$localboot])) { - $localboot = 'AUTO'; + $localboot = array_keys($BOOT_METHODS)[0]; } } +// Convert to actual ipxe code if (isset($BOOT_METHODS[$localboot])) { - // Move preferred method first - $BOOT_METHODS[] = $BOOT_METHODS[$localboot]; - unset($BOOT_METHODS[$localboot]); - $BOOT_METHODS = array_reverse($BOOT_METHODS); + $localboot = $BOOT_METHODS[$localboot]; +} else { + $localboot = 'prompt Localboot not possible'; } if ($slxExtensions) { @@ -160,18 +164,9 @@ iseq \${slxtmp_pw} \${slx_hash} || goto \${slx_pw_fail} || iseq \${slxtmp_pw} \${slx_hash} && goto \${slx_pw_ok} || goto fail -# local boot with either exit 1 or sanboot :slx_localboot console || - -HERE; - -foreach ($BOOT_METHODS as $line) { - $output .= "$line || goto fail\n"; -} - -$output .= << 'iseq efi ${platform} && exit 1 || sanboot --no-describe', - 'EXIT' => 'exit 1', - 'COMBOOT' => 'chain /tftp/chain.c32 hd0', - 'SANBOOT' => 'sanboot --no-describe', + 'PCBIOS' => [ + 'EXIT' => 'exit 1', + 'COMBOOT' => 'set netX/209:string localboot.cfg || +set netX/210:string http://${serverip}/tftp/sl-bios/ || +chain -ar /tftp/sl-bios/lpxelinux.0', + 'SANBOOT' => 'sanboot --no-describe', + ], + 'EFI' => [ + 'EXIT' => 'exit 1', + 'COMBOOT' => 'set netX/209:string localboot.cfg || +set netX/210:string http://${serverip}/tftp/sl-efi64/ || +chain -ar /tftp/sl-efi64/syslinux.efi', + ], ]; -} \ No newline at end of file + public static function getDefault() + { + $ret = explode(',', Property::get(self::PROPERTY_KEY, 'SANBOOT,EXIT')); + if (empty($ret)) { + $ret = ['SANBOOT', 'EXIT']; + } elseif (count($ret) < 2) { + $ret[] = 'EXIT'; + } + if (!isset(self::BOOT_METHODS['PCBIOS'][$ret[0]])) { + $ret[0] = 'SANBOOT'; + } + if (!isset(self::BOOT_METHODS['EFI'][$ret[1]])) { + $ret[1] = 'EXIT'; + } + return ['PCBIOS' => $ret[0], 'EFI' => $ret[1]]; + } + + public static function setDefault($pcbios, $efi) + { + Property::set(self::PROPERTY_KEY, "$pcbios,$efi"); + } + +} diff --git a/modules-available/serversetup-bwlp-ipxe/install.inc.php b/modules-available/serversetup-bwlp-ipxe/install.inc.php index 2ee4917c..5e7f2440 100644 --- a/modules-available/serversetup-bwlp-ipxe/install.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/install.inc.php @@ -49,7 +49,8 @@ $res[] = tableCreate('serversetup_menu_location', ' $res[] = tableCreate('serversetup_localboot', " `systemmodel` varchar(120) NOT NULL, - `bootmethod` enum('EXIT','COMBOOT','SANBOOT') CHARACTER SET ascii NOT NULL, + `pcbios` varchar(16) CHARACTER SET ascii DEFAULT NULL, + `efi` varchar(16) CHARACTER SET ascii DEFAULT NULL, PRIMARY KEY (`systemmodel`) "); @@ -87,6 +88,16 @@ if (!tableHasColumn('serversetup_menuentry', 'refmenuid')) { } } +// 2019-03-26 Make localboot config distinct for efi and bios +if (!tableHasColumn('serversetup_localboot', 'pcbios')) { + if (Database::exec("ALTER TABLE serversetup_localboot DROP COLUMN `bootmethod`, + ADD COLUMN `pcbios` varchar(16) CHARACTER SET ascii DEFAULT NULL, ADD COLUMN `efi` varchar(16) CHARACTER SET ascii DEFAULT NULL") !== false) { + $res[] = UPDATE_DONE; + } else { + $res[] = UPDATE_FAILED; + } +} + $res[] = tableAddConstraint('serversetup_menuentry', 'refmenuid', 'serversetup_menu', 'menuid', 'ON UPDATE CASCADE ON DELETE SET NULL'); 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 f5356a72..1037df96 100644 --- a/modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json +++ b/modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json @@ -45,7 +45,7 @@ "lang_localBootDefault": "Standardm\u00e4\u00dfig verwendete Methode, um von Festplatte zu booten", "lang_localBootExceptions": "Ausnahmen, pro Rechnermodell definierbar", "lang_localBootHead": "Boot von Festplatte", - "lang_localBootIntro": "Aus dem iPXE Bootmen\u00fc kann auf verschiedene Arten ein Boot von der prim\u00e4ren Festplatte ausgel\u00f6st werden. In den allermeisten F\u00e4llen ist die Einstellung \"AUTO\" ausreichend, bei bestimmten Rechnermodellen kann es allerdings erforderlich sein, eine der alternativen Methoden zu erzwingen. Falls Sie einem solchen Modell begegnen, k\u00f6nnen Sie im unteren Teil dieser Seite eine solche Ausnahme festlegen. In einigen F\u00e4llen l\u00e4sst sich das Problem auch durch ein BIOS-Update auf den entsprechenden Ger\u00e4ten beheben.", + "lang_localBootIntro": "Aus dem iPXE Bootmen\u00fc kann auf verschiedene Arten ein Boot von der prim\u00e4ren Festplatte ausgel\u00f6st werden. In den allermeisten F\u00e4llen ist die Einstellung SANBOOT (BIOS) bzw. EXIT (EFI) ausreichend, bei bestimmten Rechnermodellen kann es allerdings erforderlich sein, eine der alternativen Methoden zu erzwingen. Falls Sie einem solchen Modell begegnen, k\u00f6nnen Sie im unteren Teil dieser Seite eine solche Ausnahme festlegen. In einigen F\u00e4llen l\u00e4sst sich das Problem auch durch ein BIOS-Update auf den entsprechenden Ger\u00e4ten beheben.", "lang_locationCount": "Anzahl Orte", "lang_menuDeleteConfirm": "Sind Sie sicher, dass Sie dieses Men\u00fc l\u00f6schen wollen?", "lang_menuEntryOverride": "Standardeintrag \u00fcberschreiben", @@ -58,7 +58,6 @@ "lang_newMenu": "Neues Men\u00fc", "lang_none": "(keine)", "lang_ok": "OK", - "lang_override": "\u00dcberschreiben", "lang_pxeMenuContent": "pxelinux.cfg\/ Men\u00fcdefinition", "lang_pxelinuxEntriesOnly": "Nur Eintr\u00e4ge importieren, kein Men\u00fc erzeugen", "lang_pxelinuxImport": "PXE-Men\u00fc importieren", diff --git a/modules-available/serversetup-bwlp-ipxe/lang/en/template-tags.json b/modules-available/serversetup-bwlp-ipxe/lang/en/template-tags.json index 4bf78a5d..84c43dd7 100644 --- a/modules-available/serversetup-bwlp-ipxe/lang/en/template-tags.json +++ b/modules-available/serversetup-bwlp-ipxe/lang/en/template-tags.json @@ -45,7 +45,7 @@ "lang_localBootDefault": "Default method to use for booting from disk", "lang_localBootExceptions": "Exceptions to the local boot method, defined per system model", "lang_localBootHead": "Boot from local disk", - "lang_localBootIntro": "There are several methods to trigger a local boot from the iPXE environment. In most cases, the \"AUTO\" setting will work, but with some system models it might be necessary to override the default behavior. In some instances, a BIOS update might resolve the issue as well.", + "lang_localBootIntro": "There are several methods to initiate a boot from the primary hard drive from within the iPXE environment. In most cases, the SANBOOT (BIOS) \/ EXIT (EFI) setting will work, but with some system models it might be necessary to override the default behavior. In some instances, a BIOS update might resolve the issue as well.", "lang_locationCount": "Number of Locations", "lang_menuDeleteConfirm": "Are you sure you want to delete this menu?", "lang_menuEntryOverride": "Override default selection", @@ -58,7 +58,6 @@ "lang_newMenu": "New menu", "lang_none": "(none)", "lang_ok": "OK", - "lang_override": "Override", "lang_pxeMenuContent": "pxelinux.cfg\/ menu definition", "lang_pxelinuxEntriesOnly": "Import menu items only, don't create menu", "lang_pxelinuxImport": "Import PXELinux menu", diff --git a/modules-available/serversetup-bwlp-ipxe/page.inc.php b/modules-available/serversetup-bwlp-ipxe/page.inc.php index 150796a5..3d5e2c15 100644 --- a/modules-available/serversetup-bwlp-ipxe/page.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/page.inc.php @@ -244,14 +244,16 @@ class Page_ServerSetup extends Page Render::addTemplate('download', ['files' => $files]); } - private function makeSelectArray($list, $default) + private function makeSelectArray($list, $defaults) { - $ret = []; - foreach (array_keys($list) as $k) { - $ret[] = [ - 'key' => $k, - 'selected' => ($k === $default ? 'selected' : ''), - ]; + $ret = ['EFI' => [], 'PCBIOS' => []]; + foreach (['PCBIOS', 'EFI'] as $m) { + foreach (array_keys($list[$m]) as $k) { + $ret[$m][] = [ + 'key' => $k, + 'selected' => ($k === $defaults[$m] ? 'selected' : ''), + ]; + } } return $ret; } @@ -259,15 +261,12 @@ class Page_ServerSetup extends Page private function showLocalbootConfig() { // Default setting - $default = Property::get(Localboot::PROPERTY_KEY, 'AUTO'); - if (!array_key_exists($default, Localboot::BOOT_METHODS)) { - $default = 'AUTO'; - } + $default = Localboot::getDefault(); $optionList = $this->makeSelectArray(Localboot::BOOT_METHODS, $default); // Exceptions $cutoff = strtotime('-90 days'); $models = []; - $res = Database::simpleQuery('SELECT m.systemmodel, cnt, sl.bootmethod FROM ( + $res = Database::simpleQuery('SELECT m.systemmodel, cnt, sl.pcbios AS PCBIOS, sl.efi AS EFI FROM ( SELECT m2.systemmodel, Count(*) AS cnt FROM machine m2 WHERE m2.lastseen > :cutoff GROUP BY systemmodel @@ -275,7 +274,7 @@ class Page_ServerSetup extends Page LEFT JOIN serversetup_localboot sl USING (systemmodel) ORDER BY systemmodel', ['cutoff' => $cutoff]); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['options'] = $this->makeSelectArray(Localboot::BOOT_METHODS, $row['bootmethod']); + $row['options'] = $this->makeSelectArray(Localboot::BOOT_METHODS, $row); $models[] = $row; } // Output @@ -893,23 +892,36 @@ class Page_ServerSetup extends Page private function saveLocalboot() { - $default = Request::post('default', 'AUTO', 'string'); - if (!array_key_exists($default, Localboot::BOOT_METHODS)) { - Message::addError('localboot-invalid-method', $default); + $pcbios = Request::post('default-pcbios', 'SANBOOT', 'string'); + $efi = Request::post('default-efi', 'EXIT', 'string'); + if (!array_key_exists($pcbios, Localboot::BOOT_METHODS['PCBIOS'])) { + Message::addError('localboot-invalid-method', $pcbios); + return; + } + if (!array_key_exists($efi, Localboot::BOOT_METHODS['EFI'])) { + Message::addError('localboot-invalid-method', $efi); return; } - Property::set(Localboot::PROPERTY_KEY, $default); + Localboot::setDefault($pcbios, $efi); $overrides = Request::post('override', [], 'array'); Database::exec('TRUNCATE TABLE serversetup_localboot'); - foreach ($overrides as $model => $mode) { - if (empty($mode)) // No override - continue; - if (!array_key_exists($mode, Localboot::BOOT_METHODS)) { - Message::addWarning('localboot-invalid-method', $mode); + foreach ($overrides as $model => $modes) { + if (empty($modes)) // No override continue; + $params = ['model' => $model, 'EFI' => null, 'PCBIOS' => null]; + foreach (['EFI', 'PCBIOS'] as $m) { + if (empty($modes[$m])) + continue; + if (!array_key_exists($modes[$m], Localboot::BOOT_METHODS[$m])) { + Message::addWarning('localboot-invalid-method', $modes[$m]); + continue; + } + $params[$m] = $modes[$m]; } - Database::exec('INSERT INTO serversetup_localboot (systemmodel, bootmethod) - VALUES (:model, :mode)', compact('model', 'mode')); + if ($params['EFI'] === null && $params['PCBIOS'] === null) + continue; + Database::exec('INSERT INTO serversetup_localboot (systemmodel, pcbios, efi) + VALUES (:model, :PCBIOS, :EFI)', $params); } Message::addSuccess('localboot-saved'); Util::redirect('?do=serversetup&show=localboot'); diff --git a/modules-available/serversetup-bwlp-ipxe/templates/localboot.html b/modules-available/serversetup-bwlp-ipxe/templates/localboot.html index 3037de2a..816459e8 100644 --- a/modules-available/serversetup-bwlp-ipxe/templates/localboot.html +++ b/modules-available/serversetup-bwlp-ipxe/templates/localboot.html @@ -9,13 +9,24 @@
-
@@ -27,18 +38,27 @@ {{lang_systemmodel}} {{lang_count}} - {{lang_override}} + PCBIOS + EFI {{#exceptions}} {{systemmodel}} {{cnt}} - + + {{#options.PCBIOS}} + + {{/options.PCBIOS}} + + + + -- cgit v1.2.3-55-g7522